zipl: remove last table / number of tables logic

In order to allow installing only a list-directed ipl entry, remove
the last-table/number-of-tables logic which always required a legacy
program table. With the new code there's no longer a loop in
prepare_bootloader() which requires a certain start index or order
of tables.

Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Eduard Shishkin
2023-04-18 08:29:07 +00:00
committed by Steffen Eiden
parent 10515380e8
commit 7c656faa36
3 changed files with 76 additions and 80 deletions
-1
View File
@@ -61,7 +61,6 @@ struct program_table {
struct install_set {
struct program_table tables[NR_PROGRAM_TABLES];
struct program_component *components[NR_PROGRAM_COMPONENTS];
int nr_tables; /* number of "similar" program tables to be installed */
int nr_menu_entries;
int fd;
char *device;
+67 -66
View File
@@ -543,13 +543,6 @@ check_remaining_filesize(size_t filesize, size_t signature_size,
}
}
static int is_last_table(struct install_set *bis, int table_id)
{
assert(bis->nr_tables > 0 && bis->nr_tables <= NR_PROGRAM_TABLES);
return table_id == bis->nr_tables - 1;
}
static int add_ipl_program(struct install_set *bis, char *filename,
bool add_envblk, struct job_envblk_data *envblk,
struct job_ipl_data *ipl, disk_blockptr_t *program,
@@ -1010,6 +1003,7 @@ static int add_dump_program(struct install_set *bis, struct job_dump_data *dump,
/**
* Build a program table from job data and set pointer to program table
* block upon success
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
*/
static int build_program_table(struct job_data *job,
struct install_set *bis, int program_table_id)
@@ -1428,20 +1422,6 @@ check_dump_device(const struct job_data *job, const struct disk_info *info,
return 0;
}
/**
* Set actual number of "similar" program tables to be installed
*/
static void set_nr_tables(struct job_data *job, struct install_set *bis)
{
assert(bis->nr_tables == 0);
if (bis->info->type == disk_type_eckd_cdl &&
(job->id == job_ipl || job->id == job_menu))
bis->nr_tables = NR_PROGRAM_TABLES;
else
bis->nr_tables = 1;
}
/**
* Prepare resources to build a program table
*/
@@ -1519,19 +1499,26 @@ static int prepare_build_program_table_device(struct job_data *job,
bis->filename);
return -1;
}
set_nr_tables(job, bis);
return 0;
}
static int bootmap_create_device(struct job_data *job, struct install_set *bis,
int program_table_id)
/**
* Called when making a dump on a raw SCSI partition
*/
static int prepare_bootloader_device(struct job_data *job,
struct install_set *bis)
{
if (prepare_build_program_table_device(job, bis))
return -1;
if (build_program_table(job, bis, program_table_id))
/*
* build a single program table at offset 1,
* see comment before install_bootloader() for details
*/
bis->print_details = 1;
if (build_program_table(job, bis, BLKPTR_FORMAT_ID))
return -1;
/* Install stage 2 loader to bootmap if necessary */
if (bootmap_install_stages(job, bis, program_table_id)) {
if (bootmap_install_stages(job, bis, BLKPTR_FORMAT_ID)) {
error_text("Could not install loader stages to bootmap");
return -1;
}
@@ -1598,7 +1585,6 @@ static int prepare_build_program_table_file(struct job_data *job,
error_text("Could not write to file '%s'", bis->filename);
return -1;
}
set_nr_tables(job, bis);
return 0;
}
@@ -1623,8 +1609,11 @@ static int finalize_create_file(char *bootmap_dir, struct install_set *bis)
return 0;
}
static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
struct install_set *bis, int program_table_id)
/*
* PROGRAM_TABLE_ID: offset of the program table in the array (@bis->tables)
*/
static int bootmap_create_file(struct job_data *job, struct install_set *bis,
char *bootmap_dir, int program_table_id)
{
if (prepare_build_program_table_file(job, bootmap_dir, bis))
return -1;
@@ -1636,8 +1625,6 @@ static int bootmap_create_file(struct job_data *job, char *bootmap_dir,
bis->filename);
return -1;
}
if (!dry_run && is_last_table(bis, program_table_id))
return finalize_create_file(bootmap_dir, bis);
return 0;
}
@@ -1675,14 +1662,13 @@ ngdump_create_meta(const char *path)
return 0;
}
static int bootmap_create_device_ngdump(struct job_data *job,
struct install_set *bis,
int program_table_id)
static int prepare_bootloader_ngdump(struct job_data *job,
struct install_set *bis)
{
struct disk_info *info;
char *bootmap_dir;
int rc;
assert(program_table_id == 0);
/* Retrieve target device information */
if (disk_get_info(job->data.dump.device, &job->target, &info))
return -1;
@@ -1735,29 +1721,47 @@ static int bootmap_create_device_ngdump(struct job_data *job,
return -1;
}
bis->dump_mounted = 1;
if (bootmap_create_file(job, bis->dump_mount_point,
bis, program_table_id))
bootmap_dir = bis->dump_mount_point;
/*
* Build a single program table for List-Directed IPL
* See comments before install_bootloader() for details
*/
bis->print_details = 1;
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
return -1;
if (ngdump_create_meta(bis->dump_mount_point))
if (!dry_run && finalize_create_file(bootmap_dir, bis))
return -1;
return 0;
return ngdump_create_meta(bootmap_dir);
}
static int
bootmap_create(struct job_data *job, struct install_set *bis,
int program_table_id)
/**
* Build one or two program tables for CCW-type and(or) for List-Direceted IPL
* at respective offsets in the array BIS->tables. See the comment before
* install_bootloader() for details
*/
static int prepare_bootloader_ipl(struct job_data *job, struct install_set *bis)
{
if (job->id == job_dump_partition) {
if (is_ngdump_enabled(job->data.dump.device, &job->target))
return bootmap_create_device_ngdump(job, bis,
program_table_id);
else
return bootmap_create_device(job, bis,
program_table_id);
} else
return bootmap_create_file(job, job->target.bootmap_dir,
bis, program_table_id);
char *bootmap_dir = job->target.bootmap_dir;
/*
* Build a program table for List-Directed IPL from
* SCSI or ECKD DASD
*/
bis->print_details = 1;
if (bootmap_create_file(job, bis, bootmap_dir, BLKPTR_FORMAT_ID))
return -1;
if (bis->info->type == disk_type_scsi)
/* only one table to be installed per device */
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
/*
* Build one more program table for CCW-type IPL from
* ECKD DASD
*/
bis->skip_prepare = 1;
bis->print_details = 0;
if (bootmap_create_file(job, bis, bootmap_dir, LEGACY_BLKPTR_FORMAT_ID))
return -1;
return dry_run ? 0 : finalize_create_file(bootmap_dir, bis);
}
/**
@@ -1791,22 +1795,19 @@ static int init_bis(struct job_data *job, struct install_set *bis)
*/
int prepare_bootloader(struct job_data *job, struct install_set *bis)
{
int i;
int rc;
secure_boot_supported = check_secure_boot_support();
rc = init_bis(job, bis);
if (rc)
return rc;
for (i = 0;; i++) {
bis->skip_prepare = i > 0;
bis->print_details = i > 0 ? is_last_table(bis, i) : 0;
rc = bootmap_create(job, bis, i);
if (rc || is_last_table(bis, i))
break;
if (init_bis(job, bis))
return -1;
if (job->id == job_dump_partition) {
if (is_ngdump_enabled(job->data.dump.device, &job->target))
return prepare_bootloader_ngdump(job, bis);
else
return prepare_bootloader_device(job, bis);
} else {
return prepare_bootloader_ipl(job, bis);
}
return rc;
return -1;
}
/**
+9 -13
View File
@@ -335,6 +335,7 @@ int install_bootloader_ipl(struct program_table *tables,
switch (info->type) {
case disk_type_scsi:
/* List-Directed IPL */
pt = &tables[BLKPTR_FORMAT_ID];
rc = install_scsi(fd, &pt->table, info, NULL);
break;
case disk_type_fba:
@@ -368,7 +369,7 @@ int install_bootloader_ipl(struct program_table *tables,
return rc;
}
/*
/**
* Install a program table for List-Directed dump
* See the comment before install_bootloader() for details
*/
@@ -402,18 +403,13 @@ static int install_bootloader_dump(struct program_table *tables,
* Install a "compatible" boot record referring one, or two "similar"
* program tables.
*
* The picture below shows which program table is used for IPL
* of specified type from disk of specified type.
* E.g. program table "0" is used for CCW-type IPL from ECKD DASD,
* LD-IPL from DASD FBA is unsupported (respectively, only one program
* table "0" is used), etc.
*
* CCW-IPL LD-IPL
*
* SCSI X 0
* DASD FBA 0 X
* ECKD DASD LDL 0 X
* ECKD DASD CDL 0 1
* For compatibility reasons zIPL installs multiple "similar"
* program tables which differ only in block pointers format.
* Each such table is identified by an offset in the array BIS->tables
* of in-memory program table representations built by prepare_bootloader().
* The common rule is that tables built for CCW-type IPL are placed
* at offset 0, and tables built for List-Directed IPL are placed at
* offset 1. The same works for dumps.
*/
int install_bootloader(struct job_data *job, struct install_set *bis)
{