diff --git a/s390-tools-01-zipl-src-add-basic-support-for-multiple-target-base-disks.patch b/s390-tools-01-zipl-src-add-basic-support-for-multiple-target-base-disks.patch deleted file mode 100644 index aa5a861..0000000 --- a/s390-tools-01-zipl-src-add-basic-support-for-multiple-target-base-disks.patch +++ /dev/null @@ -1,969 +0,0 @@ -From d6b702d5791b47f735960ad1f6986e0a32768df6 Mon Sep 17 00:00:00 2001 -From: Eduard Shishkin -Date: Thu, 11 Jul 2024 10:43:37 +0200 -Subject: [PATCH] zipl/src: add basic support for multiple target base disks - -. Modify disk_get_info() to process multiple sets of target parameters - provided by the helper script and store it in the array of "targets" - of the structure job_target_data; -. Besides the logical device, maintain an array of physical base disks - in the disk_info structure; -. Use the logical target device only to create bootmap (it is - automatically mirrored by the respective linux driver (dm, or md) - managing the mirrored target). In contrast, install bootstrap blocks - to each physical base disk individually, bypassing that driver; -. Report in verbose mode on which base disks the bootstrap - installation was performed; -. Use the following logic of setting @info->device (which is printed - as "Device...:" in verbose mode): - . source_auto - the target base disk is set; - . source_script - the target (logical) device is set; - . source_user - the device specified by user (via --targetbase - option), or config file is set. - -Signed-off-by: Eduard Shishkin -Reviewed-by: Stefan Haberland -Signed-off-by: Steffen Eiden ---- - zipl/include/disk.h | 14 +- - zipl/include/install.h | 2 - zipl/include/job.h | 122 ++++++++++++++++++-- - zipl/include/zipl.h | 1 - zipl/src/bootmap.c | 23 ++- - zipl/src/disk.c | 295 +++++++++++++++++++++++++++++++++++++------------ - zipl/src/install.c | 89 +++++++++----- - zipl/src/job.c | 82 +++++++------ - 8 files changed, 469 insertions(+), 159 deletions(-) - ---- a/zipl/include/disk.h -+++ b/zipl/include/disk.h -@@ -56,13 +56,14 @@ - /* targetbase definition */ - typedef enum { - defined_as_device, -- defined_as_name -+ defined_as_name, -+ undefined - } definition_t; - - /* Disk information type */ - struct disk_info { - disk_type_t type; -- dev_t device; -+ dev_t device; /* logical device for bootmap creation */ - dev_t partition; - int devno; - int partnum; -@@ -72,8 +73,11 @@ - struct hd_geometry geo; - char* name; - char* drv_name; -- definition_t targetbase; -+ definition_t targetbase_def; - int is_nvme; -+ dev_t basedisks[MAX_TARGETS]; /* array of physical disks for -+ * bootstrap blocks recording -+ */ - }; - - struct file_range { -@@ -113,6 +117,9 @@ - struct disk_info *info, int align, - off_t *offset); - void disk_print_devt(dev_t d); -+void disk_print_devname(dev_t d); -+void prepare_footnote_ptr(int source, char *ptr); -+void print_footnote_ref(int source, const char *prefix); - void disk_print_info(struct disk_info *info, int source); - int disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info); - blocknum_t disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count, -@@ -122,7 +129,6 @@ - disk_blockptr_t** blocklist, - struct disk_info* pinfo); - int disk_check_subchannel_set(int devno, dev_t device, char* dev_name); --void disk_print_geo(struct disk_info *data); - int fs_map(int fd, uint64_t offset, blocknum_t *mapped, int fs_block_size); - - #endif /* not DISK_H */ ---- a/zipl/include/install.h -+++ b/zipl/include/install.h -@@ -71,7 +71,7 @@ - struct program_component *components[NR_PROGRAM_COMPONENTS]; - int nr_menu_entries; - int fd; -- char *device; -+ char *basetmp[MAX_TARGETS]; - char *filename; - unsigned int tmp_filename_created:1; - unsigned int skip_prepare:1; ---- a/zipl/include/job.h -+++ b/zipl/include/job.h -@@ -18,7 +18,6 @@ - #include "disk.h" - #include "zipl.h" - -- - enum job_id { - job_print_usage = 1, - job_print_version = 2, -@@ -30,6 +29,21 @@ - job_mvdump = 8, - }; - -+/* -+ * Set of parameters per physical disk, which are provided -+ * either by user, or by helper script -+ */ -+struct target { -+ char *targetbase; -+ disk_type_t targettype; -+ int targetcylinders; -+ int targetheads; -+ int targetsectors; -+ int targetblocksize; -+ blocknum_t targetoffset; -+ int check_params; -+}; -+ - /* target information source */ - typedef enum { - source_unknown = 0, -@@ -39,17 +53,21 @@ - } source_t; - - struct job_target_data { -- char* bootmap_dir; -- char* targetbase; -- disk_type_t targettype; -- int targetcylinders; -- int targetheads; -- int targetsectors; -- int targetblocksize; -- blocknum_t targetoffset; -+ char *bootmap_dir; -+ int nr_targets; -+ struct target targets[MAX_TARGETS]; - source_t source; - }; - -+enum target_params { -+ TARGET_BASE, -+ TARGET_TYPE, -+ TARGET_GEOMETRY, -+ TARGET_BLOCKSIZE, -+ TARGET_OFFSET, -+ LAST_TARGET_PARAM -+}; -+ - struct job_common_ipl_data { - char* image; - char* parmline; -@@ -142,12 +160,94 @@ - int is_ldipl_dump; - }; - -+static inline struct target *target_at(struct job_target_data *data, -+ int index) -+{ -+ return index >= MAX_TARGETS ? NULL : &data->targets[index]; -+} -+ -+static inline char *get_targetbase(struct job_target_data *data, int index) -+{ -+ return target_at(data, index)->targetbase; -+} -+ -+static inline void set_targetbase(struct job_target_data *data, int index, -+ char *value) -+{ -+ target_at(data, index)->targetbase = value; -+} -+ -+static inline disk_type_t get_targettype(struct job_target_data *data, -+ int index) -+{ -+ return target_at(data, index)->targettype; -+} -+ -+int set_targettype(struct job_target_data *data, int index, char *value); -+ -+static inline char *job_get_targetbase(struct job_data *job) -+{ -+ return get_targetbase(&job->target, 0); -+} -+ -+static inline void job_set_targetbase(struct job_data *job, char *value) -+{ -+ set_targetbase(&job->target, 0, value); -+} -+ -+static inline int job_get_nr_targets(struct job_data *job) -+{ -+ return job->target.nr_targets; -+} -+ -+static inline void job_set_nr_targets(struct job_data *job, int value) -+{ -+ job->target.nr_targets = value; -+} -+ -+static inline disk_type_t job_get_targettype(struct job_data *job) -+{ -+ return get_targettype(&job->target, 0); -+} -+ -+int job_set_targettype(struct job_data *job, char *value); -+ -+#define define_target_param_ops(_TYPE_, _PARAM_) \ -+static inline _TYPE_ get_target##_PARAM_(struct job_target_data *data, \ -+ int index) \ -+{ \ -+ return target_at(data, index)->target##_PARAM_; \ -+} \ -+ \ -+static inline void set_target##_PARAM_(struct job_target_data *data, \ -+ int index, _TYPE_ value) \ -+{ \ -+ target_at(data, index)->target##_PARAM_ = value; \ -+} \ -+ \ -+static inline _TYPE_ job_get_target##_PARAM_(struct job_data *job) \ -+{ \ -+ return get_target##_PARAM_(&job->target, 0); \ -+} \ -+ \ -+static inline void job_set_target##_PARAM_(struct job_data *job, \ -+ _TYPE_ value) \ -+{ \ -+ set_target##_PARAM_(&job->target, 0, value); \ -+} -+ -+define_target_param_ops(int, cylinders) -+define_target_param_ops(int, heads) -+define_target_param_ops(int, sectors) -+define_target_param_ops(int, blocksize) -+define_target_param_ops(blocknum_t, offset) -+ - /** -- * Return true, if target parameters for the base disk are set -+ * Return true, if target parameters are set at least for one target base disk - */ - static inline int target_parameters_are_set(struct job_target_data *td) - { -- return td->targetbase != NULL; -+ return get_targetbase(td, 0) != NULL; - } - - int job_get(int argc, char* argv[], struct job_data** data); ---- a/zipl/include/zipl.h -+++ b/zipl/include/zipl.h -@@ -41,6 +41,7 @@ - #define MENU_DEFAULT_TIMEOUT 0 - - #define MAX_DUMP_VOLUMES 32 -+#define MAX_TARGETS 32 - - #define SECURE_BOOT_UNDEFINED -1 - #define SECURE_BOOT_DISABLED 0 ---- a/zipl/src/bootmap.c -+++ b/zipl/src/bootmap.c -@@ -1477,9 +1477,9 @@ - printf("Target device information\n"); - disk_print_info(bis->info, job->target.source); - } -- if (misc_temp_dev(bis->info->device, 1, &bis->device)) -+ if (misc_temp_dev(bis->info->device, 1, &bis->basetmp[0])) - return -1; -- if (check_dump_device(job, bis->info, bis->device)) -+ if (check_dump_device(job, bis->info, bis->basetmp[0])) - return -1; - printf("Building bootmap directly on partition '%s'%s\n", - bis->filename, -@@ -1543,6 +1543,8 @@ - static int prepare_build_program_table_file(struct job_data *job, - struct install_set *bis) - { -+ int i; -+ - if (bis->skip_prepare) - /* skip the preparation work */ - return 0; -@@ -1576,8 +1578,12 @@ - printf("Target device information\n"); - disk_print_info(bis->info, job->target.source); - } -- if (misc_temp_dev(bis->info->device, 1, &bis->device)) -- return -1; -+ for (i = 0; i < job_get_nr_targets(job); i++) { -+ if (misc_temp_dev(bis->info->basedisks[i], -+ 1, -+ &bis->basetmp[i])) -+ return -1; -+ } - /* Check configuration number limits */ - if (job->id == job_menu) { - if (check_menu_positions(&job->data.menu, job->name, -@@ -1692,9 +1698,9 @@ - /* Retrieve target device information */ - if (disk_get_info(job->data.dump.device, &job->target, &info)) - return -1; -- if (misc_temp_dev(info->device, 1, &bis->device)) -+ if (misc_temp_dev(info->device, 1, &bis->basetmp[0])) - return -1; -- if (check_dump_device(job, info, bis->device)) -+ if (check_dump_device(job, info, bis->basetmp[0])) - return -1; - - assert(!job->target.bootmap_dir); -@@ -1844,6 +1850,9 @@ - if (bis->tmp_filename_created) - misc_free_temp_file(bis->filename); - free(bis->filename); -- misc_free_temp_dev(bis->device); -+ for (i = 0; i < MAX_TARGETS; i++) { -+ if (bis->basetmp[i]) -+ misc_free_temp_dev(bis->basetmp[i]); -+ } - disk_free_info(bis->info); - } ---- a/zipl/src/disk.c -+++ b/zipl/src/disk.c -@@ -187,43 +187,134 @@ - return rc; - } - -+/** -+ * Process a script output represented by FH and consisting -+ * of pairs 'key=value' (each such pair is on a separate line). -+ * Check its consistency and set the extracted target parameters -+ * to the array of "targets" at TD. -+ * -+ * NOTE: this function defines specifications on valid output of -+ * zipl helper scripts. See zipl-support-for-mirrored-devices.txt -+ * for details. Before modifying this function, make sure that it -+ * won't lead to format change. -+ */ - static int set_target_parameters(FILE *fh, struct job_target_data *td) - { -- int checkparm = 0; -+ int idx[LAST_TARGET_PARAM] = {0}; -+ struct target *t; - char buffer[80]; - char value[40]; -+ char *error; -+ int i; - -+ /** -+ * Process a stream of 'key=value' pairs and distribute -+ * them into groups. -+ * The i-th occurrence of some "key" in the stream means -+ * that the respective pair belongs to the group #i -+ */ -+ error = "Exceeded the maximum number of base disks"; - while (fgets(buffer, 80, fh)) { - if (sscanf(buffer, "targetbase=%s", value) == 1) { -- td->targetbase = misc_strdup(value); -- checkparm++; -+ t = target_at(td, idx[TARGET_BASE]++); -+ if (!t) -+ goto error; -+ t->targetbase = misc_strdup(value); -+ goto found; - } - if (sscanf(buffer, "targettype=%s", value) == 1) { -- type_from_target(value, &td->targettype); -- checkparm++; -+ t = target_at(td, idx[TARGET_TYPE]++); -+ if (!t) -+ goto error; -+ type_from_target(value, &t->targettype); -+ goto found; - } - if (sscanf(buffer, "targetgeometry=%s", value) == 1) { -- td->targetcylinders = -- atoi(strtok(value, ",")); -- td->targetheads = atoi(strtok(NULL, ",")); -- td->targetsectors = atoi(strtok(NULL, ",")); -- checkparm++; -+ t = target_at(td, idx[TARGET_GEOMETRY]++); -+ if (!t) -+ goto error; -+ t->targetcylinders = atoi(strtok(value, ",")); -+ t->targetheads = atoi(strtok(NULL, ",")); -+ t->targetsectors = atoi(strtok(NULL, ",")); -+ goto found; - } - if (sscanf(buffer, "targetblocksize=%s", value) == 1) { -- td->targetblocksize = atoi(value); -- checkparm++; -+ t = target_at(td, idx[TARGET_BLOCKSIZE]++); -+ if (!t) -+ goto error; -+ t->targetblocksize = atoi(value); -+ goto found; - } - if (sscanf(buffer, "targetoffset=%s", value) == 1) { -- td->targetoffset = atol(value); -- checkparm++; -+ t = target_at(td, idx[TARGET_OFFSET]++); -+ if (!t) -+ goto error; -+ t->targetoffset = atol(value); -+ goto found; - } -+ continue; -+found: -+ t->check_params++; - } -- if ((!disk_is_eckd(td->targettype) && checkparm < 4) || -- (disk_is_eckd(td->targettype) && checkparm != 5)) { -- error_reason("Target parameters missing from script"); -- return -1; -+ /* Check for consistency */ -+ error = "Inconsistent script output"; -+ /* -+ * First, calculate total number of groups -+ */ -+ td->nr_targets = 0; -+ for (i = 0; i < MAX_TARGETS; i++) { -+ t = target_at(td, i); -+ if (t->check_params == 0) -+ break; -+ td->nr_targets++; -+ } -+ if (!td->nr_targets) -+ /* No keywords found in the stream */ -+ goto error; -+ /* -+ * Each group has to include targetbase, targettype, -+ * targetblocksize and targetoffset. -+ */ -+ if (td->nr_targets != idx[TARGET_BASE] || -+ td->nr_targets != idx[TARGET_TYPE] || -+ td->nr_targets != idx[TARGET_BLOCKSIZE] || -+ td->nr_targets != idx[TARGET_OFFSET]) -+ goto error; -+ /* -+ * In addition, any group of "ECKD" type has to include -+ * targetgeometry -+ */ -+ 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) -+ goto error; - } - return 0; -+error: -+ error_reason("%s", error); -+ return -1; -+} -+ -+static void print_base_disk_params(struct job_target_data *td, int index) -+{ -+ disk_type_t type = get_targettype(td, index); -+ -+ if (!verbose) -+ return; -+ { -+ 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)) { -+ 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)); -+ } -+ { -+ fprintf(stderr, " start.........: %lu\n", get_targetoffset(td, index)); -+ fprintf(stderr, " blksize.......: %u\n", get_targetblocksize(td, index)); -+ } - } - - /** -@@ -235,31 +326,57 @@ - { - int majnum, minnum; - struct stat stats; -- -+ int i; -+ /* -+ * Currently multiple base disks with different parameters -+ * are not supported -+ */ - data->devno = -1; -- data->phy_block_size = td->targetblocksize; -- data->type = td->targettype; -- data->partnum = 0; -+ data->phy_block_size = get_targetblocksize(td, 0); -+ data->type = get_targettype(td, 0); - -- if (sscanf(td->targetbase, "%d:%d", &majnum, &minnum) == 2) { -- data->device = makedev(majnum, minnum); -- data->targetbase = defined_as_device; -- data->partnum = minor(stats.st_rdev) - minnum; -- } else { -- if (stat(td->targetbase, &stats)) { -- error_reason(strerror(errno)); -- error_text("Could not get information for " -- "file '%s'", td->targetbase); -+ assert(td->nr_targets != 0); -+ for (i = 1; i < td->nr_targets; i++) { -+ if (data->type != get_targettype(td, i) || -+ data->phy_block_size != get_targetblocksize(td, i)) { -+ print_base_disk_params(td, 0); -+ print_base_disk_params(td, i); -+ error_reason("Inconsistent base disk geometry in target device"); - return -1; - } -- if (!S_ISBLK(stats.st_mode)) { -- error_reason("Target base device '%s' is not " -- "a block device", -- td->targetbase); -+ } -+ data->partnum = 0; -+ data->targetbase_def = undefined; -+ -+ for (i = 0; i < td->nr_targets; i++) { -+ definition_t defined_as; -+ -+ if (sscanf(get_targetbase(td, i), -+ "%d:%d", &majnum, &minnum) == 2) { -+ data->basedisks[i] = makedev(majnum, minnum); -+ defined_as = defined_as_device; -+ } else { -+ if (stat(get_targetbase(td, i), &stats)) { -+ error_reason(strerror(errno)); -+ error_text("Could not get information for " -+ "file '%s'", get_targetbase(td, i)); -+ return -1; -+ } -+ if (!S_ISBLK(stats.st_mode)) { -+ error_reason("Target base device '%s' is not " -+ "a block device", -+ get_targetbase(td, i)); -+ return -1; -+ } -+ data->basedisks[i] = stats.st_rdev; -+ defined_as = defined_as_name; -+ } -+ if (data->targetbase_def != undefined && -+ data->targetbase_def != defined_as) { -+ error_reason("Target base disks are defined by different ways"); - return -1; - } -- data->device = stats.st_rdev; -- data->targetbase = defined_as_name; -+ data->targetbase_def = defined_as; - } - if (data->type == disk_type_scsi && ioctl(fd, NVME_IOCTL_ID) >= 0) - data->is_nvme = 1; -@@ -446,11 +563,28 @@ - static int disk_set_geometry_by_hint(struct job_target_data *td, - struct disk_info *data) - { -- data->geo.heads = td->targetheads; -- data->geo.sectors = td->targetsectors; -- data->geo.cylinders = td->targetcylinders; -- data->geo.start = td->targetoffset; -- -+ int i; -+ /* -+ * Currently multiple base disks with different parameters -+ * are not supported -+ */ -+ data->geo.heads = get_targetheads(td, 0); -+ data->geo.sectors = get_targetsectors(td, 0); -+ data->geo.cylinders = get_targetcylinders(td, 0); -+ data->geo.start = get_targetoffset(td, 0); -+ -+ assert(td->nr_targets != 0); -+ for (i = 1; i < td->nr_targets; i++) { -+ if (data->geo.heads != get_targetheads(td, i) || -+ data->geo.sectors != get_targetsectors(td, i) || -+ data->geo.cylinders != get_targetcylinders(td, i) || -+ data->geo.start != get_targetoffset(td, i)) { -+ print_base_disk_params(td, 0); -+ print_base_disk_params(td, i); -+ error_reason("Inconsistent base disk geometry in target device"); -+ return -1; -+ } -+ } - return 0; - } - -@@ -515,14 +649,16 @@ - } - - /** -- * Prepare INFO required to perform IPL installation on the physical -- * disk where the logical DEVICE is located. -+ * Prepare INFO required to perform IPL installation on physical disks -+ * participating in the logical DEVICE. - * Preparation is performed in 2 steps: - * -- * 1. Find out a physical "base" disk where the logical DEVICE is -- * located. Calculate "target" parameters (type, geometry, physical -- * block size, data offset, etc); -- * 2. Complete INFO by the found base disk and target parameters. -+ * 1. Find out a set of physical "base" disks participating in the -+ * logical DEVICE. For each found disk calculate "target" parameters -+ * (type, geometry, physical block size, data offset, etc) and store -+ * it in the array of "targets" of TD; -+ * 2. Complete INFO using the found base disks and calculated target -+ * parameters. - * - * TD: optionally contains target parameters specified by user via - * config file, or special "target options" of zipl tool. -@@ -566,6 +702,7 @@ - goto error; - if (disk_set_info_by_hint(td, data, fd)) - goto error; -+ data->device = stats.st_rdev; - break; - case source_user: - /* -@@ -578,6 +715,12 @@ - goto error; - if (disk_set_info_by_hint(td, data, fd)) - goto error; -+ /* -+ * multiple base disks are not supported -+ * with this source type -+ */ -+ assert(td->nr_targets == 1); -+ data->device = data->basedisks[0]; - break; - case source_auto: - /* no ready target parameters are available */ -@@ -585,6 +728,12 @@ - goto error; - if (disk_set_info_auto(data, &stats, fd)) - goto error; -+ /* -+ * multiple base disks are not supported -+ * with this source type -+ */ -+ data->basedisks[0] = data->device; -+ td->nr_targets = 1; - break; - default: - assert(0); -@@ -940,6 +1089,33 @@ - printf("%02x:%02x", major(d), minor(d)); - } - -+void disk_print_devname(dev_t dev) -+{ -+ struct util_proc_part_entry part_entry; -+ -+ if (!util_proc_part_get_entry(dev, &part_entry)) { -+ printf("%s", part_entry.name); -+ util_proc_part_free_entry(&part_entry); -+ } else { -+ disk_print_devt(dev); -+ } -+} -+ -+void prepare_footnote_ptr(int source, char *ptr) -+{ -+ if (source == source_user || source == source_script) -+ strcpy(ptr, " *)"); -+ else -+ strcpy(ptr, ""); -+} -+ -+void print_footnote_ref(int source, const char *prefix) -+{ -+ if (source == source_user) -+ printf("%s*) Data provided by user.\n", prefix); -+ else if (source == source_script) -+ printf("%s*) Data provided by script.\n", prefix); -+} - - /* Return a name for a given disk TYPE. */ - char * -@@ -991,12 +1167,11 @@ - void disk_print_info(struct disk_info *info, int source) - { - char footnote[4] = ""; -- if (source == source_user || source == source_script) -- strcpy(footnote, " *)"); - -+ prepare_footnote_ptr(source, footnote); - printf(" Device..........................: "); - disk_print_devt(info->device); -- if (info->targetbase == defined_as_device) -+ if (info->targetbase_def == defined_as_device) - printf("%s", footnote); - printf("\n"); - if (info->partnum != 0) { -@@ -1007,7 +1182,7 @@ - if (info->name) { - printf(" Device name.....................: %s", - info->name); -- if (info->targetbase == defined_as_name) -+ if (info->targetbase_def == defined_as_name) - printf("%s", footnote); - printf("\n"); - } -@@ -1050,21 +1225,7 @@ - info->phy_block_size, footnote); - printf(" Device size in physical blocks..: %ld\n", - (long) info->phy_blocks); -- if (source == source_user) -- printf(" *) Data provided by user.\n"); -- if (source == source_script) -- printf(" *) Data provided by script.\n"); --} -- --/* Print textual representation of geo structure. */ --void --disk_print_geo(struct disk_info *data) --{ -- printf(" geo.heads.........:%u\n", data->geo.heads); -- printf(" geo.sectors.......:%u\n", data->geo.sectors); -- printf(" geo.cylinders.....:%u\n", data->geo.cylinders); -- printf(" geo.start.........:%lu\n", data->geo.start); -- printf(" blksize...........:%u\n", data->phy_block_size); -+ print_footnote_ref(source, " "); - } - - /* Check whether a block is a zero block which identifies a hole in a file. ---- a/zipl/src/install.c -+++ b/zipl/src/install.c -@@ -434,11 +434,14 @@ - { - disk_blockptr_t *scsi_dump_sb_blockptr = &bis->scsi_dump_sb_blockptr; - struct disk_info *info = bis->info; -- char *device = bis->device; -- int fd, rc; -+ char footnote[4]; -+ int rc; -+ int i; - - if (!info) - return 0; -+ -+ prepare_footnote_ptr(job->target.source, footnote); - /* Inform user about what we're up to */ - printf("Preparing boot device for %s%s: ", - disk_get_ipl_type(info->type, -@@ -455,40 +458,58 @@ - disk_print_devt(info->device); - printf(".\n"); - } -- /* Open device file */ -- fd = open(device, O_RDWR); -- if (fd == -1) { -- error_reason(strerror(errno)); -- error_text("Could not open temporary device file '%s'", -- device); -- return -1; -- } -- /* Ensure that potential cache inconsistencies between disk and -- * partition are resolved by flushing the corresponding buffers. */ -- if (!dry_run) { -- if (ioctl(fd, BLKFLSBUF)) { -- fprintf(stderr, "Warning: Could not flush disk " -- "caches.\n"); -+ /* Install independently on each physical target base */ -+ -+ for (i = 0; i < job_get_nr_targets(job); i++) { -+ int fd; -+ -+ if (verbose) { -+ printf("Installing on base disk: "); -+ disk_print_devname(info->basedisks[i]); -+ printf("%s.\n", footnote); - } -+ /* Open device file */ -+ fd = open(bis->basetmp[i], O_RDWR); -+ if (fd == -1) { -+ error_reason(strerror(errno)); -+ error_text("Could not open temporary device file '%s'", -+ bis->basetmp[i]); -+ return -1; -+ } -+ /* Ensure that potential cache inconsistencies between disk and -+ * partition are resolved by flushing the corresponding buffers. -+ */ -+ if (!dry_run) { -+ if (ioctl(fd, BLKFLSBUF)) { -+ fprintf(stderr, "Warning: Could not flush disk " -+ "caches.\n"); -+ } -+ } -+ /* -+ * Depending on disk type, install one or two program tables -+ * for CCW-type IPL and (or) for List-Directed IPL (see the -+ * picture in comments above) -+ */ -+ if (job->id == job_dump_partition) { -+ rc = install_bootloader_dump(bis->tables, info, -+ scsi_dump_sb_blockptr, -+ is_ngdump_enabled(job), -+ fd); -+ } else { -+ rc = install_bootloader_ipl(bis->tables, info, -+ fd); -+ } -+ if (fsync(fd)) -+ error_text("Could not sync device file '%s'", -+ bis->basetmp[i]); -+ if (close(fd)) -+ error_text("Could not close device file '%s'", -+ bis->basetmp[i]); -+ if (rc) -+ break; - } -- /* -- * Depending on disk type, install one or two program tables -- * for CCW-type IPL and (or) for List-Directed IPL (see the -- * picture in comments above) -- */ -- if (job->id == job_dump_partition) { -- rc = install_bootloader_dump(bis->tables, info, -- scsi_dump_sb_blockptr, -- is_ngdump_enabled(job), -- fd); -- } else { -- rc = install_bootloader_ipl(bis->tables, info, fd); -- } -- -- if (fsync(fd)) -- error_text("Could not sync device file '%s'", device); -- if (close(fd)) -- error_text("Could not close device file '%s'", device); -+ if (verbose) -+ print_footnote_ref(job->target.source, ""); - - if (!dry_run && rc == 0) { - if (info->devno >= 0) ---- a/zipl/src/job.c -+++ b/zipl/src/job.c -@@ -1346,6 +1346,27 @@ - } - } - -+int set_targettype(struct job_target_data *data, int index, char *value) -+{ -+ return type_from_target(value, -+ &target_at(data, index)->targettype); -+} -+ -+int job_set_targettype(struct job_data *job, char *value) -+{ -+ return set_targettype(&job->target, 0, value); -+} -+ -+static int job_set_target(struct job_data *job, char *value) -+{ -+ job_set_targetbase(job, value); -+ if (!job_get_targetbase(job)) -+ return -1; -+ job_set_nr_targets(job, 1); -+ job->target.source = source_user; -+ return 0; -+} -+ - static int - get_job_from_section_data(char* data[], struct job_data* job, char* section) - { -@@ -1362,32 +1383,28 @@ - return -1; - /* Fill in target */ - if (data[(int) scan_keyword_targetbase] != NULL) { -- job->target.targetbase = -- misc_strdup(data[(int) -- scan_keyword_targetbase]); -- if (job->target.targetbase == NULL) -+ if (job_set_target(job, misc_strdup(data[(int) -+ scan_keyword_targetbase]))) - return -1; -- job->target.source = source_user; - } - if (data[(int) scan_keyword_targettype] != NULL) { -- if (type_from_target( -- data[(int) scan_keyword_targettype], -- &job->target.targettype)) -+ if (job_set_targettype(job, -+ data[(int) scan_keyword_targettype])) - return -1; - } - if (data[(int) scan_keyword_targetgeometry] != NULL) { -- job->target.targetcylinders = -+ job_set_targetcylinders(job, - atoi(strtok(data[(int) -- scan_keyword_targetgeometry], ",")); -- job->target.targetheads = atoi(strtok(NULL, ",")); -- job->target.targetsectors = atoi(strtok(NULL, ",")); -+ scan_keyword_targetgeometry], ","))); -+ job_set_targetheads(job, atoi(strtok(NULL, ","))); -+ job_set_targetsectors(job, atoi(strtok(NULL, ","))); - } - if (data[(int) scan_keyword_targetblocksize] != NULL) -- job->target.targetblocksize = -- atoi(data[(int) scan_keyword_targetblocksize]); -+ job_set_targetblocksize(job, -+ atoi(data[(int) scan_keyword_targetblocksize])); - if (data[(int) scan_keyword_targetoffset] != NULL) -- job->target.targetoffset = -- atol(data[(int) scan_keyword_targetoffset]); -+ job_set_targetoffset(job, -+ atol(data[(int) scan_keyword_targetoffset])); - /* Fill in name and address of image file */ - - job->data.ipl.common.image = misc_strdup( -@@ -1615,37 +1632,32 @@ - return -1; - break; - case scan_keyword_targetbase: -- job->target.targetbase = misc_strdup( -- scan[i].content.keyword.value); -- if (job->target.targetbase == NULL) -+ if (job_set_target(job, misc_strdup( -+ scan[i].content.keyword.value))) - return -1; -- job->target.source = source_user; - break; - case scan_keyword_targettype: -- if (type_from_target( -- scan[i].content.keyword.value, -- &job->target.targettype)) -+ if (job_set_targettype(job, -+ scan[i].content.keyword.value)) - return -1; - break; - case scan_keyword_targetgeometry: -- job->target.targetcylinders = -+ job_set_targetcylinders(job, - atoi(strtok( - scan[i].content.keyword.value, -- ",")); -- job->target.targetheads = -- atoi(strtok(NULL, ",")); -- job->target.targetsectors = -- atoi(strtok(NULL, ",")); -+ ","))); -+ job_set_targetheads(job, -+ atoi(strtok(NULL, ","))); -+ job_set_targetsectors(job, -+ atoi(strtok(NULL, ","))); - break; - case scan_keyword_targetblocksize: -- job->target.targetblocksize = -- atoi( -- scan[i].content.keyword.value); -+ job_set_targetblocksize(job, atoi( -+ scan[i].content.keyword.value)); - break; - case scan_keyword_targetoffset: -- job->target.targetoffset = -- atol( -- scan[i].content.keyword.value); -+ job_set_targetoffset(job, atol( -+ scan[i].content.keyword.value)); - break; - default: - /* Should not happen */ diff --git a/s390-tools-02-zipl-src-add-basic-support-for-multiple-target-base-disks.patch b/s390-tools-02-zipl-src-add-basic-support-for-multiple-target-base-disks.patch deleted file mode 100644 index bf8dfb1..0000000 --- a/s390-tools-02-zipl-src-add-basic-support-for-multiple-target-base-disks.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/zipl/src/job.c 2024-09-16 14:20:09.321762661 +0200 -+++ b/zipl/src/job.c 2024-09-16 14:29:28.601846724 +0200 -@@ -373,8 +373,11 @@ - static void - free_target_data(struct job_target_data* data) - { -+ int i; -+ - free(data->bootmap_dir); -- free(data->targetbase); -+ for (i = 0; i < data->nr_targets; i++) -+ free(get_targetbase(data, i)); - } - - static void diff --git a/s390-tools-2.34-Fix-Rust-compilation-errors.patch b/s390-tools-2.34-Fix-Rust-compilation-errors.patch deleted file mode 100644 index af89ed0..0000000 --- a/s390-tools-2.34-Fix-Rust-compilation-errors.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 6a55d0c2e57952600164822dd100e8247b4b010f Mon Sep 17 00:00:00 2001 -From: Steffen Eiden -Date: Fri, 23 Aug 2024 09:16:26 +0200 -Subject: [PATCH] rust/pv: Lower most lints to warn -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Lower the lint level to warn for the styling lints. -This avoids compile issues during packaging for newer tooling with -potential more lint findings. -Still deny compiling if a public symbol has no documentation. - -Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/173 -Reviewed-by: Jan Höppner -Signed-off-by: Steffen Eiden ---- - rust/pv/src/lib.rs | 4 ++-- - rust/pv_core/src/lib.rs | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/rust/pv/src/lib.rs b/rust/pv/src/lib.rs -index 9a647617..1084f8e8 100644 ---- a/rust/pv/src/lib.rs -+++ b/rust/pv/src/lib.rs -@@ -2,8 +2,8 @@ - // - // Copyright IBM Corp. 2023, 2024 - --#![deny( -- missing_docs, -+#![deny(missing_docs)] -+#![warn( - missing_debug_implementations, - trivial_numeric_casts, - unstable_features, -diff --git a/rust/pv_core/src/lib.rs b/rust/pv_core/src/lib.rs -index 1356c1b7..b617b8f9 100644 ---- a/rust/pv_core/src/lib.rs -+++ b/rust/pv_core/src/lib.rs -@@ -1,8 +1,8 @@ - // SPDX-License-Identifier: MIT - // - // Copyright IBM Corp. 2023, 2024 --#![deny( -- missing_docs, -+#![deny(missing_docs)] -+#![warn( - missing_debug_implementations, - trivial_numeric_casts, - unstable_features, diff --git a/s390-tools-2.34.0.tar.gz b/s390-tools-2.34.0.tar.gz deleted file mode 100644 index 35a8601..0000000 --- a/s390-tools-2.34.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea4758c4e460d7f7e040e6aedf68b1be32d63fecb733358b08182f6b9b7440a2 -size 2114507 diff --git a/s390-tools-2.35.0.tar.gz b/s390-tools-2.35.0.tar.gz new file mode 100644 index 0000000..99e5cfb --- /dev/null +++ b/s390-tools-2.35.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b00d49d2fd649308ad385a80da4cfdfacc1fa642b6949431adf41689ac4848a +size 2125787 diff --git a/s390-tools.changes b/s390-tools.changes index 2f6c8aa..6383dd8 100644 --- a/s390-tools.changes +++ b/s390-tools.changes @@ -1,3 +1,27 @@ +------------------------------------------------------------------- +Tue Oct 8 10:35:04 UTC 2024 - Nikolay Gueorguiev + +* Upgrade s390-tools to version 2.35 (jsc#PED-9591, jsc#PED-10303) +* Changes of existing tools: + - cpacfstats: Add support for FULL XTS (MSA 10) and HMAC (MSA 11) PAI counter + - cpuplugd: Make cpuplugd compatible with hiperdispatch + - dbginfo.sh: Add network sockstat info + - pvapconfig: s390x exclusive build + - zdev: Add option to select IPL device + - zdump/dfo_s390: Support s390 DFO for vr-kernel dumps + - zipl: Add support of mirror devices +* Bug Fixes: + - (genprotimg|zipl)/boot: discard .note.package ELF section to save memory + - netboot/mk-s390image: Fix size when argument is a symlink + - ziorep_config: Fix warning message when multipath device is not there. + - zipl: Fix problems when target parameters are specified by user + - zipl: Fix segfault when creating device-based dumps with '--dry-run' +* Removed obsolete patches + - s390-tools-2.34-Fix-Rust-compilation-errors.patch + - s390-tools-01-zipl-src-add-basic-support-for-multiple-target-base-disks.patch + - s390-tools-02-zipl-src-add-basic-support-for-multiple-target-base-disks.patch +* Revendored vendor.tar.gz + ------------------------------------------------------------------- Mon Sep 16 12:49:55 UTC 2024 - Nikolay Gueorguiev diff --git a/s390-tools.spec b/s390-tools.spec index 474b690..ef1c8a1 100644 --- a/s390-tools.spec +++ b/s390-tools.spec @@ -33,7 +33,7 @@ %endif Name: s390-tools -Version: 2.34.0 +Version: 2.35.0 Release: 0 Summary: S/390 tools like zipl and dasdfmt for s390x (plus selected tools for x86_64) License: MIT @@ -154,9 +154,6 @@ Patch911: s390-tools-sles15sp5-remove-no-pie-link-arguments.patch Patch912: s390-tools-ALP-zdev-live.patch Patch913: s390-tools-sles15sp6-kdump-initrd-59-zfcp-compat-rules.patch Patch914: s390-tools-slfo-01-parse-ipl-device-for-activation.patch -Patch915: s390-tools-2.34-Fix-Rust-compilation-errors.patch -Patch916: s390-tools-01-zipl-src-add-basic-support-for-multiple-target-base-disks.patch -Patch917: s390-tools-02-zipl-src-add-basic-support-for-multiple-target-base-disks.patch ### BuildRequires: curl-devel @@ -232,7 +229,9 @@ pvattest - create, perform, and verify protected virtualization attestation me pvsecret - manage secrets for IBM Secure Execution guests. pvapconfig - used to automatically set up the AP configuration within an IBM Secure Execution guest. -Note: Auxiliary data package - s390-tools-genprotimg-data +Warning: There is an auxiliary data package - s390-tools-genprotimg-data. + To install s390-tools properly, please use: + 'sudo zypper install s390-tools s390-tools-genprotimg-data' %package -n osasnmpd Summary: OSA-Express SNMP subagent diff --git a/vendor.tar.gz b/vendor.tar.gz index 9c7da0e..4af5458 100644 --- a/vendor.tar.gz +++ b/vendor.tar.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14f5559f64640cf3876d41f0168294afefd444ee28a9a0a5175ca61787a481e9 -size 43464873 +oid sha256:13ce3050d9af81c9d01c73fd54d4932bdcb1d7349336654880a4c9393863e899 +size 43462501