diff --git a/zipl/include/disk.h b/zipl/include/disk.h index 89979418..52c6fe74 100644 --- a/zipl/include/disk.h +++ b/zipl/include/disk.h @@ -53,6 +53,11 @@ typedef enum { disk_type_eckd_cdl, } disk_type_t; +struct disk_ext_type { + disk_type_t type; + bool is_nvme; +}; + /* targetbase definition */ typedef enum { defined_as_device, @@ -87,12 +92,15 @@ struct file_range { struct job_target_data; -int disk_get_info(const char* device, struct job_target_data* target, - struct disk_info** info); -int disk_is_tape(const char* device); -int disk_is_scsi(const char* device, struct job_target_data* target); -int disk_is_eckd_ldl(const char* device, struct job_target_data* target); -int disk_is_nvme(const char* device, struct job_target_data* target); +int disk_get_info(const char *device, struct job_target_data *target, + struct disk_info **info); +int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type); +int disk_is_tape(const char *device); +int disk_type_is_scsi(struct disk_ext_type *ext_type); +int disk_type_is_eckd_ldl(struct disk_ext_type *ext_type); +int disk_type_is_nvme(struct disk_ext_type *ext_type); +int disk_type_is_eckd(disk_type_t type); + int disk_get_info_from_file(const char* filename, struct job_target_data* target, struct disk_info** info); diff --git a/zipl/include/job.h b/zipl/include/job.h index b8ffad87..ccd12a3a 100644 --- a/zipl/include/job.h +++ b/zipl/include/job.h @@ -99,6 +99,7 @@ struct job_dump_data { struct job_common_ipl_data common; char* device; uint64_t mem; + bool is_ngdump; bool no_compress; }; @@ -256,6 +257,8 @@ void free_target_data(struct job_target_data *td); int type_from_target(char *target, disk_type_t *type); int check_job_dump_images(struct job_dump_data* dump, char* name); int check_job_images_ngdump(struct job_dump_data* dump, char* name); -bool is_ngdump_enabled(struct job_data *job); +void job_dump_check_set_ngdump(struct job_data *job, + struct disk_ext_type *ext_type); +bool job_dump_is_ngdump(struct job_data *job); #endif /* not JOB_H */ diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c index 55c29355..3889e500 100644 --- a/zipl/src/bootmap.c +++ b/zipl/src/bootmap.c @@ -1436,7 +1436,7 @@ check_dump_device(struct job_data *job, const struct disk_info *info, if (!disk_is_appropriate(job, info)) return -1; - if (is_ngdump_enabled(job)) + if (job_dump_is_ngdump(job)) return 0; rc = util_part_search(device, info->geo.start, @@ -1827,7 +1827,7 @@ int prepare_bootloader(struct job_data *job, struct install_set *bis) if (init_bis(job, bis)) return -1; if (job->id == job_dump_partition) { - if (is_ngdump_enabled(job)) + if (job_dump_is_ngdump(job)) return prepare_bootloader_ngdump(job, bis); else return prepare_bootloader_device(job, bis); @@ -1843,7 +1843,7 @@ int prepare_bootloader(struct job_data *job, struct install_set *bis) int post_install_bootloader(struct job_data *job, struct install_set *bis) { if (job->id == job_dump_partition) { - if (is_ngdump_enabled(job)) + if (job_dump_is_ngdump(job)) return dry_run ? 0 : finalize_create_file(job, bis); else return 0; diff --git a/zipl/src/disk.c b/zipl/src/disk.c index 60fc8753..b6e66296 100644 --- a/zipl/src/disk.c +++ b/zipl/src/disk.c @@ -92,14 +92,6 @@ disk_determine_dasd_type(struct disk_info *data, return 0; } -/* Return non-zero for ECKD type. */ -static int -disk_is_eckd(disk_type_t type) -{ - return (type == disk_type_eckd_ldl || - type == disk_type_eckd_cdl); -} - static int read_block_by_offset(int fd, int blksize, uint64_t offset, char *buffer) { @@ -287,7 +279,7 @@ found: for (i = 0; i < td->nr_targets; i++) { t = target_at(td, i); assert(t->check_params >= 4); - if (disk_is_eckd(t->targettype) && t->check_params != 5) + if (disk_type_is_eckd(t->targettype) && t->check_params != 5) goto error; } return 0; @@ -306,7 +298,7 @@ static void print_base_disk_params(struct job_target_data *td, int index) fprintf(stderr, "Base disk '%s':\n", get_targetbase(td, index)); fprintf(stderr, " layout........: %s\n", disk_get_type_name(type)); } - if (disk_is_eckd(type)) { + if (disk_type_is_eckd(type)) { fprintf(stderr, " heads.........: %u\n", get_targetheads(td, index)); fprintf(stderr, " sectors.......: %u\n", get_targetsectors(td, index)); fprintf(stderr, " cylinders.....: %u\n", get_targetcylinders(td, index)); @@ -617,7 +609,7 @@ static int disk_set_info_complete(struct job_target_data *td, return -1; } /* Check for valid CHS geometry data. */ - if (disk_is_eckd(data->type) && (data->geo.cylinders == 0 || + if (disk_type_is_eckd(data->type) && (data->geo.cylinders == 0 || data->geo.heads == 0 || data->geo.sectors == 0)) { error_reason("Invalid disk geometry (CHS=%d/%d/%d)", data->geo.cylinders, data->geo.heads, @@ -769,45 +761,48 @@ disk_is_tape(const char* device) return rc; } -int -disk_is_scsi(const char* device, struct job_target_data* target) -{ - struct disk_info* info; - int rc = 0; - - if (disk_get_info(device, target, &info) == -1) - return 0; - if (info->type == disk_type_scsi) - rc = 1; - disk_free_info(info); - return rc; -} - -int disk_is_eckd_ldl(const char *device, struct job_target_data *target) +/** + * Get "extended type" of base disk by logical DEVICE + * + * This function may fail for various reasons. E.g. in case when + * DEVICE is not eligible for boot record installation (not a + * partition, etc). In case of success the resulted disk type is + * stored in EXT_TYPE. + */ +int disk_get_ext_type(const char *device, struct disk_ext_type *ext_type) { + struct job_target_data tmp = {.source = source_unknown}; struct disk_info *info; - int rc = 0; - if (disk_get_info(device, target, &info) == -1) - return 0; - if (info->type == disk_type_eckd_ldl) - rc = 1; + if (disk_get_info(device, &tmp, &info)) + return -1; + ext_type->type = info->type; + ext_type->is_nvme = info->is_nvme; + disk_free_info(info); - return rc; + free_target_data(&tmp); + return 0; } -int -disk_is_nvme(const char* device, struct job_target_data* target) +int disk_type_is_scsi(struct disk_ext_type *ext_type) { - struct disk_info* info; - int rc = 0; + return ext_type->type == disk_type_scsi; +} - if (disk_get_info(device, target, &info) == -1) - return 0; - if (info->type == disk_type_scsi && info->is_nvme) - rc = 1; - disk_free_info(info); - return rc; +int disk_type_is_eckd_ldl(struct disk_ext_type *ext_type) +{ + return ext_type->type == disk_type_eckd_ldl; +} + +int disk_type_is_nvme(struct disk_ext_type *ext_type) +{ + return ext_type->is_nvme; +} + +int disk_type_is_eckd(disk_type_t type) +{ + return (type == disk_type_eckd_ldl || + type == disk_type_eckd_cdl); } int @@ -1205,7 +1200,7 @@ void disk_print_info(struct disk_info *info, int source) (info->partnum != 0) ? "partition" : "device"); printf(" Disk layout.....................: %s%s\n", disk_get_type_name(info->type), footnote); - if (disk_is_eckd(info->type)) { + if (disk_type_is_eckd(info->type)) { printf(" Geometry - heads................: %d%s\n", info->geo.heads, footnote); printf(" Geometry - sectors..............: %d%s\n", diff --git a/zipl/src/install.c b/zipl/src/install.c index e36e82ac..45530377 100644 --- a/zipl/src/install.c +++ b/zipl/src/install.c @@ -493,7 +493,7 @@ int install_bootloader(struct job_data *job, struct install_set *bis) if (job->id == job_dump_partition) { rc = install_bootloader_dump(bis->tables, info, scsi_dump_sb_blockptr, - is_ngdump_enabled(job), + job_dump_is_ngdump(job), fd); } else { rc = install_bootloader_ipl(bis->tables, info, diff --git a/zipl/src/job.c b/zipl/src/job.c index 38035d41..15369a74 100644 --- a/zipl/src/job.c +++ b/zipl/src/job.c @@ -2057,10 +2057,18 @@ job_get(int argc, char* argv[], struct job_data** data) return rc; } -bool -is_ngdump_enabled(struct job_data *job) +void job_dump_check_set_ngdump(struct job_data *job, + struct disk_ext_type *ext_type) { - if (job->is_ldipl_dump) - return true; - return disk_is_nvme(job->data.dump.device, &job->target); + assert(job->id == job_dump_partition); + + if (job->is_ldipl_dump || disk_type_is_nvme(ext_type)) + job->data.dump.is_ngdump = true; +} + +bool job_dump_is_ngdump(struct job_data *job) +{ + assert(job->id == job_dump_partition); + + return job->data.dump.is_ngdump; } diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c index f53bd696..2e0f1678 100644 --- a/zipl/src/zipl.c +++ b/zipl/src/zipl.c @@ -128,6 +128,7 @@ check_for_root(void) int main(int argc, char* argv[]) { + struct disk_ext_type ext_type = {0}; struct install_set bis; struct job_data* job; int rc; @@ -173,9 +174,13 @@ main(int argc, char* argv[]) /* Do it */ switch (job->id) { case job_dump_partition: - if (!is_ngdump_enabled(job) && + rc = disk_get_ext_type(job->data.dump.device, &ext_type); + if (rc) + break; + job_dump_check_set_ngdump(job, &ext_type); + if (!job_dump_is_ngdump(job) && (disk_is_tape(job->data.dump.device) || - !disk_is_scsi(job->data.dump.device, &job->target))) { + !disk_type_is_scsi(&ext_type))) { rc = install_dump(job->data.dump.device, &job->target, job->data.dump.mem, job->data.dump.no_compress); break; @@ -187,8 +192,8 @@ main(int argc, char* argv[]) rc = -1; break; } - if (is_ngdump_enabled(job)) { - if (disk_is_eckd_ldl(job->data.dump.device, &job->target)) { + if (job_dump_is_ngdump(job)) { + if (disk_type_is_eckd_ldl(&ext_type)) { error_reason("List-directed dump on ECKD with LDL not supported"); rc = -1; break;