1284 lines
45 KiB
Diff
1284 lines
45 KiB
Diff
From 11f2ccb9570569a57ac0ef0148efcd9b35d7a6b6 Mon Sep 17 00:00:00 2001
|
|
From: Aswin Karuvally <aswin@linux.ibm.com>
|
|
Date: Sun, 1 Feb 2026 18:39:38 +0530
|
|
Subject: [PATCH] hsci: Automatically set appropriate MTU for HSCI
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
At present, the hsci tool creates HiperSockets Converged Interface
|
|
(HSCI) with MTU of 1500 bytes regardless of the values of MTU for the
|
|
external and HiperSockets interface from which it is formed. This can
|
|
degrade performance or worse, affect network connectivity through the
|
|
converged interface.
|
|
|
|
Update the tool to automatically set MTU of HSCI as the lower of the
|
|
MTU values of external and HiperSockets interface.
|
|
|
|
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
|
|
Signed-off-by: Aswin Karuvally <aswin@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
hsci/hsci | 7 +++++++
|
|
1 file changed, 7 insertions(+)
|
|
|
|
diff --git a/hsci/hsci b/hsci/hsci
|
|
index 5540e82fc..8f884c9ac 100755
|
|
--- a/hsci/hsci
|
|
+++ b/hsci/hsci
|
|
@@ -365,6 +365,13 @@ function add_hsci {
|
|
fi
|
|
fi
|
|
|
|
+ #### Set MTU for the veth pair
|
|
+ ndev_mtu="$(cat /sys/class/net/${ndev}/mtu)"
|
|
+ hsdev_mtu="$(cat /sys/class/net/${hsdev}/mtu)"
|
|
+ hsci_mtu=$(( ndev_mtu < hsdev_mtu ? ndev_mtu : hsdev_mtu ))
|
|
+ ip link set dev $hscibp mtu $hsci_mtu
|
|
+ ip link set dev $hsci mtu $hsci_mtu
|
|
+
|
|
#### Set veth pair to UP
|
|
ip link set dev $hscibp up >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
From 376ddfbd22f3ca6bed4fb80f2a5eb1ee9c89e3d9 Mon Sep 17 00:00:00 2001
|
|
From: Mete Durlu <meted@linux.ibm.com>
|
|
Date: Tue, 17 Feb 2026 09:02:34 +0100
|
|
Subject: [PATCH] hyptop/opts: Replace sort_field option with sort
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Hyptop's "--sort_field" command line option has always been documented
|
|
as "--sort", while the code _only_ explicitly has "--sort_field".
|
|
Specifying the shorter "--sort" happened to work due to an unnoticed
|
|
getopt() behavior.
|
|
|
|
From getopt(3) man page:
|
|
"""
|
|
Long option names may be abbreviated if the abbreviation is unique
|
|
or is an exact match for some defined option.
|
|
"""
|
|
|
|
With the addition of "--sort-field" as another unique identifier via
|
|
commit c5695e43c4cd ("hyptop/opts: Replace long option formats for
|
|
consistency") "--sort" is no longer unique. getopt() won't be able to
|
|
use that as an abbreviation, since there is ambiguity between
|
|
"--sort_field" and new "--sort-field" as they are defined as separate
|
|
options.
|
|
|
|
Replace "--sort-field" and "--sort_field" with plain "--sort" to adhere
|
|
to the documented hyptop command line argument specification and resolve
|
|
the broken behavior.
|
|
|
|
Fixes: c5695e43c4cd ("hyptop/opts: Replace long option formats for consistency")
|
|
Reported-by: Gorkem Kilinc <kilinc@linux.ibm.com>
|
|
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
hyptop/opts.c | 11 ++++-------
|
|
1 file changed, 4 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/hyptop/opts.c b/hyptop/opts.c
|
|
index ca1820691..a88296839 100644
|
|
--- a/hyptop/opts.c
|
|
+++ b/hyptop/opts.c
|
|
@@ -58,9 +58,8 @@ static char HELP_TEXT[] =
|
|
* Options with underscore to keep compatibility
|
|
*/
|
|
#define OPT_BATCH_MODE 257 /* --batch_mode */
|
|
-#define OPT_SORT_FIELD 258 /* --sort | --sort_field */
|
|
-#define OPT_CPU_TYPES 259 /* --cpu_types */
|
|
-#define OPT_SMT_FACTOR 260 /* --smt_factor */
|
|
+#define OPT_CPU_TYPES 258 /* --cpu_types */
|
|
+#define OPT_SMT_FACTOR 259 /* --smt_factor */
|
|
|
|
/*
|
|
* Initialize default settings
|
|
@@ -224,7 +223,7 @@ static void l_fields_set(char *str)
|
|
}
|
|
|
|
/*
|
|
- * Set the "--sort_field" option
|
|
+ * Set the "--sort" option
|
|
*/
|
|
static void l_sort_field_set(char *str)
|
|
{
|
|
@@ -371,8 +370,7 @@ void opts_parse(int argc, char *argv[])
|
|
{ "sys", required_argument, NULL, 's'},
|
|
{ "iterations", required_argument, NULL, 'n'},
|
|
{ "fields", required_argument, NULL, 'f'},
|
|
- { "sort-field", required_argument, NULL, 'S'},
|
|
- { "sort_field", required_argument, NULL, OPT_SORT_FIELD},
|
|
+ { "sort", required_argument, NULL, 'S'},
|
|
{ "cpu-types", required_argument, NULL, 't'},
|
|
{ "cpu_types", required_argument, NULL, OPT_CPU_TYPES},
|
|
{ "format", required_argument, NULL, OPT_FORMAT },
|
|
@@ -420,7 +418,6 @@ void opts_parse(int argc, char *argv[])
|
|
case 'f':
|
|
l_fields_set(optarg);
|
|
break;
|
|
- case OPT_SORT_FIELD:
|
|
case 'S':
|
|
l_sort_field_set(optarg);
|
|
break;
|
|
From 7c75df9e9634548a2513aa1e6dc7f6c100a4f37a Mon Sep 17 00:00:00 2001
|
|
From: Mete Durlu <meted@linux.ibm.com>
|
|
Date: Tue, 17 Feb 2026 09:54:08 +0100
|
|
Subject: [PATCH] hyptop/opts: Fix long command line option abbreviations
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Hyptop should be able to accept abbreviations of the long command line
|
|
options as getopt() is able to match them. Ex;
|
|
|
|
$ hyptop --batch-mode
|
|
|
|
$ hyptop --batch
|
|
|
|
$ hyptop --bat
|
|
|
|
From getopt(3) man page:
|
|
"""
|
|
Long option names may be abbreviated if the abbreviation is unique
|
|
or is an exact match for some defined option.
|
|
"""
|
|
|
|
After the introduction of commit c5695e43c4cd ("hyptop/opts: Replace long
|
|
option formats for consistency") long command line options for hyptop
|
|
received additional definitions to support dash separated option formats.
|
|
Unfortunately these definitions were defined as new and unique options
|
|
and caused an ambiguity for getopt() when abbreviations matched both
|
|
definitions. Ex;
|
|
|
|
$ hyptop --batch
|
|
hyptop: option '--batch' is ambiguous;
|
|
possibilities: '--batch-mode' '--batch_mode'
|
|
|
|
Map both long option formats to the same short option to fix the
|
|
issue and restore the functionality.
|
|
|
|
Fixes: c5695e43c4cd ("hyptop/opts: Replace long option formats for consistency")
|
|
Reported-by: Gorkem Kilinc <kilinc@linux.ibm.com>
|
|
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
hyptop/opts.c | 16 +++-------------
|
|
1 file changed, 3 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/hyptop/opts.c b/hyptop/opts.c
|
|
index a8829683..1a98cd99 100644
|
|
--- a/hyptop/opts.c
|
|
+++ b/hyptop/opts.c
|
|
@@ -54,13 +54,6 @@ static char HELP_TEXT[] =
|
|
#define OPT_FORMAT 256 /* --format */
|
|
#define OPT_FORMAT_ALL 261 /* --all*/
|
|
|
|
-/*
|
|
- * Options with underscore to keep compatibility
|
|
- */
|
|
-#define OPT_BATCH_MODE 257 /* --batch_mode */
|
|
-#define OPT_CPU_TYPES 258 /* --cpu_types */
|
|
-#define OPT_SMT_FACTOR 259 /* --smt_factor */
|
|
-
|
|
/*
|
|
* Initialize default settings
|
|
*/
|
|
@@ -361,18 +354,18 @@ void opts_parse(int argc, char *argv[])
|
|
{ "version", no_argument, NULL, 'v'},
|
|
{ "help", no_argument, NULL, 'h'},
|
|
{ "batch-mode", no_argument, NULL, 'b'},
|
|
- { "batch_mode", no_argument, NULL, OPT_BATCH_MODE},
|
|
+ { "batch_mode", no_argument, NULL, 'b'},
|
|
{ "all", no_argument, NULL, OPT_FORMAT_ALL },
|
|
{ "delay", required_argument, NULL, 'd'},
|
|
{ "smt-factor", required_argument, NULL, 'm'},
|
|
- { "smt_factor", required_argument, NULL, OPT_SMT_FACTOR},
|
|
+ { "smt_factor", required_argument, NULL, 'm'},
|
|
{ "window", required_argument, NULL, 'w'},
|
|
{ "sys", required_argument, NULL, 's'},
|
|
{ "iterations", required_argument, NULL, 'n'},
|
|
{ "fields", required_argument, NULL, 'f'},
|
|
{ "sort", required_argument, NULL, 'S'},
|
|
{ "cpu-types", required_argument, NULL, 't'},
|
|
- { "cpu_types", required_argument, NULL, OPT_CPU_TYPES},
|
|
+ { "cpu_types", required_argument, NULL, 't'},
|
|
{ "format", required_argument, NULL, OPT_FORMAT },
|
|
{ NULL, 0, NULL, 0 }
|
|
};
|
|
@@ -391,14 +384,12 @@ void opts_parse(int argc, char *argv[])
|
|
case 'h':
|
|
l_usage();
|
|
hyptop_exit(0);
|
|
- case OPT_BATCH_MODE:
|
|
case 'b':
|
|
l_batch_mode_set();
|
|
break;
|
|
case 'd':
|
|
l_delay_set(optarg);
|
|
break;
|
|
- case OPT_SMT_FACTOR:
|
|
case 'm':
|
|
l_factor_set(optarg);
|
|
break;
|
|
@@ -411,7 +402,6 @@ void opts_parse(int argc, char *argv[])
|
|
case 'n':
|
|
l_iterations_set(optarg);
|
|
break;
|
|
- case OPT_CPU_TYPES:
|
|
case 't':
|
|
l_cpu_types_set(optarg);
|
|
break;
|
|
From 50f909db8f53011b00c5819e593504264d23bb82 Mon Sep 17 00:00:00 2001
|
|
From: Vasily Gorbik <gor@linux.ibm.com>
|
|
Date: Thu, 12 Mar 2026 18:36:00 +0100
|
|
Subject: [PATCH] zipl/boot: Fix stage3 secure boot trailer placement
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The stage3 linker script places .sb.trailer so that it must end at
|
|
COMMAND_LINE_EXTRA. The current script derives the start address from
|
|
SIZEOF(.sb.trailer) before the section is emitted:
|
|
|
|
. = COMMAND_LINE_EXTRA - SIZEOF(.sb.trailer);
|
|
|
|
With binutils older than 2.39 before commit 648f6099d4dc ("-z relro
|
|
relaxation and ld script SIZEOF") this can result in .sb.trailer being
|
|
placed at COMMAND_LINE_EXTRA instead, moving the trailer into the
|
|
following area and breaking the expected layout.
|
|
|
|
The trailer has a fixed size, so use an explicit constant for the
|
|
placement calculation and keep the ASSERT to verify the final section
|
|
size. This makes the placement deterministic again.
|
|
|
|
Fixes: a1126352ecfa ("zipl/boot: Improve linker scripts")
|
|
Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
|
|
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/boot/stage3.lds.S | 5 +++--
|
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/zipl/boot/stage3.lds.S b/zipl/boot/stage3.lds.S
|
|
index 35ed32d29..cbfaaf0fc 100644
|
|
--- a/zipl/boot/stage3.lds.S
|
|
+++ b/zipl/boot/stage3.lds.S
|
|
@@ -48,15 +48,16 @@ SECTIONS
|
|
.rodata : {*(.rodata .rodata.*) }
|
|
.data : { *(.data .data.*) }
|
|
|
|
+#define SB_TRAILER_SIZE 32
|
|
/* Trailer needed for Secure Boot */
|
|
- . = COMMAND_LINE_EXTRA - SIZEOF(.sb.trailer);
|
|
+ . = COMMAND_LINE_EXTRA - SB_TRAILER_SIZE;
|
|
.sb.trailer : {
|
|
QUAD(0x0000c00000000000)
|
|
QUAD(STAGE3_ENTRY + PSW_LOAD)
|
|
QUAD(STAGE3_ENTRY)
|
|
QUAD(0x000000207a49504c)
|
|
}
|
|
- ASSERT(SIZEOF(.sb.trailer) == 32, "Invalid .sb.trailer size")
|
|
+ ASSERT(SIZEOF(.sb.trailer) == SB_TRAILER_SIZE, "Invalid .sb.trailer size")
|
|
|
|
. = COMMAND_LINE_EXTRA;
|
|
.cmdline_extra : {
|
|
From fcfee1aa84d3d3afef6a30b3657b2a2ea99edfce Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Mon, 16 Mar 2026 17:31:33 +0100
|
|
Subject: [PATCH] zipl/src: Fix a bug in building replicated program tables
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
When installing IPL on mirrored targets, zipl builds multiple program
|
|
tables (one such table per each mirror). If the option "--add-files"
|
|
was specified, then zipl uses the in-bootmap files, that was written
|
|
at the prevoius iteration (for the mirror ID #0) to build program
|
|
tables for mirrors with ID #1 (and larger). The in-bootmap files
|
|
already don't contain trailers. Despite this, the building process
|
|
cuts off the tail of trailer size, which results in corrupted boot
|
|
data.
|
|
|
|
This bug may result in crashing the kernel when booting from mirrors
|
|
with ID #1 (and larger) and manifests only if the boot components are
|
|
signed and the option "--add-files" is specified for the installation
|
|
session.
|
|
|
|
Don't count the trailer, when building program tables using in-bootmap
|
|
files written at the previous iteration.
|
|
|
|
Fixes: 431e4542ca9c ("zipl/src: Reuse data of file components in bootmap")
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/src/bootmap.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c
|
|
index 7d75b608..14a30c34 100644
|
|
--- a/zipl/src/bootmap.c
|
|
+++ b/zipl/src/bootmap.c
|
|
@@ -441,12 +441,14 @@ static int add_component_file(struct install_set *bis, const char *filename,
|
|
|
|
if (add_files && comp_reg->offset > 0) {
|
|
/*
|
|
- * The file has been already written to the bootmap.
|
|
+ * The file has been already written to the bootmap,
|
|
+ * and that in-bootmap file doesn't contain a trailer.
|
|
* Use the respective region in the bootmap file to
|
|
* add the component
|
|
*/
|
|
filename = bis->filename;
|
|
add_files = 0;
|
|
+ trailer = 0;
|
|
} else {
|
|
comp_reg = NULL;
|
|
}
|
|
From 984e008127985172bdfe90262d5dc705cc5149a1 Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Mon, 23 Mar 2026 16:31:50 +0100
|
|
Subject: [PATCH] zipl/src: Indicate in a verbose output if a component is
|
|
signed
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Regardless of secure boot support, indicate in the verbose zipl(8)
|
|
output if a component is signed.
|
|
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/src/bootmap.c | 13 +++++++------
|
|
1 file changed, 7 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c
|
|
index 14a30c34..6a72d28c 100644
|
|
--- a/zipl/src/bootmap.c
|
|
+++ b/zipl/src/bootmap.c
|
|
@@ -704,9 +704,6 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk,
|
|
/* initiate values for ramdisk */
|
|
stats.st_size = 0;
|
|
if (ipl->common.ramdisk != NULL) {
|
|
- /* Add ramdisk */
|
|
- if (verbose && bis->mirrors[mirror_id].print_details)
|
|
- printf(" initial ramdisk...: %s\n", ipl->common.ramdisk);
|
|
/* Get ramdisk file size */
|
|
if (stat(ipl->common.ramdisk, &stats)) {
|
|
error_reason(strerror(errno));
|
|
@@ -834,10 +831,10 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk,
|
|
offset += sizeof(struct component_entry);
|
|
|
|
/* Add kernel image */
|
|
- if (verbose && bis->mirrors[mirror_id].print_details)
|
|
- printf(" kernel image......: %s\n", ipl->common.image);
|
|
-
|
|
signature_size = extract_signature(ipl->common.image, &signature, &sig_head);
|
|
+ if (verbose && bis->mirrors[mirror_id].print_details)
|
|
+ printf(" kernel image......: %s%s\n",
|
|
+ ipl->common.image, signature_size ? " (signed)" : "");
|
|
if (signature_size &&
|
|
(is_secure == SECURE_BOOT_ENABLED ||
|
|
(is_secure == SECURE_BOOT_AUTO && secure_boot_supported))) {
|
|
@@ -906,6 +903,10 @@ static int add_ipl_program(struct install_set *bis, bool add_envblk,
|
|
if (ipl->common.ramdisk != NULL) {
|
|
signature_size = extract_signature(ipl->common.ramdisk, &signature,
|
|
&sig_head);
|
|
+ if (verbose && bis->mirrors[mirror_id].print_details)
|
|
+ printf(" initial ramdisk...: %s%s\n",
|
|
+ ipl->common.ramdisk,
|
|
+ signature_size ? " (signed)" : "");
|
|
if (signature_size &&
|
|
(is_secure == SECURE_BOOT_ENABLED ||
|
|
(is_secure == SECURE_BOOT_AUTO &&
|
|
From 9882aabe4434594cd055b95ad8427338207a8763 Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Mon, 8 Jun 2026 17:12:05 +0200
|
|
Subject: [PATCH] zipl/src: Update format of zipl helpers output
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Change the format of zipl helpers output to support hybrid mirrors
|
|
(i.e. composed of disks of different types and geometry).
|
|
The new format imposes an additional requirement that any key-value
|
|
pair "targetbase=X:Y" titles a new section with a set of target
|
|
parmeters for the base disk identified by that pair.
|
|
|
|
Without this change, zipl reports "Inconsistent script output".
|
|
To reproduce the problem, build a mixed mirrored setup with first
|
|
SCSI disk and second DASD disk, and prepare it for IPL.
|
|
|
|
Fixes: 731f00202c53 ("zipl/src: Enable heterogeneous mirrors support")
|
|
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/include/job.h | 2 +-
|
|
zipl/src/disk.c | 81 ++++++++++++++++++----------------------------
|
|
2 files changed, 32 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/zipl/include/job.h b/zipl/include/job.h
|
|
index 0acea592..3e93a323 100644
|
|
--- a/zipl/include/job.h
|
|
+++ b/zipl/include/job.h
|
|
@@ -167,7 +167,7 @@ struct job_data {
|
|
static inline struct target *target_at(struct job_target_data *data,
|
|
int index)
|
|
{
|
|
- return index >= MAX_TARGETS ? NULL : &data->targets[index];
|
|
+ return index < 0 || index >= MAX_TARGETS ? NULL : &data->targets[index];
|
|
}
|
|
|
|
static inline char *get_targetbase(struct job_target_data *data, int index)
|
|
diff --git a/zipl/src/disk.c b/zipl/src/disk.c
|
|
index 86ec6bc7..673224fb 100644
|
|
--- a/zipl/src/disk.c
|
|
+++ b/zipl/src/disk.c
|
|
@@ -176,6 +176,15 @@ static int determine_virtblk_type(struct device_info *dev_info,
|
|
return rc;
|
|
}
|
|
|
|
+#define GET_TARGET_OR_GOTO_ERR() \
|
|
+ do { \
|
|
+ if (target_id < 0) \
|
|
+ goto err_inc; \
|
|
+ t = target_at(td, target_id); \
|
|
+ if (!t) \
|
|
+ goto err_exc; \
|
|
+ } while (0)
|
|
+
|
|
/**
|
|
* Process a script output represented by FH and consisting
|
|
* of pairs 'key=value' (each such pair is on a separate line).
|
|
@@ -189,57 +198,46 @@ static int determine_virtblk_type(struct device_info *dev_info,
|
|
*/
|
|
static int set_target_parameters(FILE *fh, struct job_target_data *td)
|
|
{
|
|
- int idx[LAST_TARGET_PARAM] = {0};
|
|
+ int target_id = -1;
|
|
struct target *t;
|
|
char buffer[80];
|
|
char value[40];
|
|
- char *error;
|
|
int i;
|
|
|
|
/* reset array of target parameters */
|
|
memset(td->targets, 0, sizeof(td->targets));
|
|
- /**
|
|
- * 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
|
|
+ /*
|
|
+ * Process a stream of key-value pairs and complete the array of
|
|
+ * target parameters.
|
|
+ * Each key-value pair "targetbase=foo" title a group of parameters
|
|
+ * for a new target.
|
|
*/
|
|
- error = "Exceeded the maximum number of base disks";
|
|
while (fgets(buffer, 80, fh)) {
|
|
if (sscanf(buffer, "targetbase=%s", value) == 1) {
|
|
- t = target_at(td, idx[TARGET_BASE]++);
|
|
- if (!t)
|
|
- goto error;
|
|
+ target_id++; /* new title */
|
|
+ GET_TARGET_OR_GOTO_ERR();
|
|
t->targetbase = misc_strdup(value);
|
|
goto found;
|
|
}
|
|
if (sscanf(buffer, "targettype=%s", value) == 1) {
|
|
- t = target_at(td, idx[TARGET_TYPE]++);
|
|
- if (!t)
|
|
- goto error;
|
|
+ GET_TARGET_OR_GOTO_ERR();
|
|
type_from_target(value, &t->targettype);
|
|
goto found;
|
|
}
|
|
if (sscanf(buffer, "targetgeometry=%s", value) == 1) {
|
|
- t = target_at(td, idx[TARGET_GEOMETRY]++);
|
|
- if (!t)
|
|
- goto error;
|
|
+ GET_TARGET_OR_GOTO_ERR();
|
|
t->targetcylinders = atoi(strtok(value, ","));
|
|
t->targetheads = atoi(strtok(NULL, ","));
|
|
t->targetsectors = atoi(strtok(NULL, ","));
|
|
goto found;
|
|
}
|
|
if (sscanf(buffer, "targetblocksize=%s", value) == 1) {
|
|
- t = target_at(td, idx[TARGET_BLOCKSIZE]++);
|
|
- if (!t)
|
|
- goto error;
|
|
+ GET_TARGET_OR_GOTO_ERR();
|
|
t->targetblocksize = atoi(value);
|
|
goto found;
|
|
}
|
|
if (sscanf(buffer, "targetoffset=%s", value) == 1) {
|
|
- t = target_at(td, idx[TARGET_OFFSET]++);
|
|
- if (!t)
|
|
- goto error;
|
|
+ GET_TARGET_OR_GOTO_ERR();
|
|
t->targetoffset = atol(value);
|
|
goto found;
|
|
}
|
|
@@ -247,43 +245,26 @@ static int set_target_parameters(FILE *fh, struct job_target_data *td)
|
|
found:
|
|
t->check_params++;
|
|
}
|
|
+ td->nr_targets = target_id + 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;
|
|
+ /* Missed a title pair "targetbase=foo" in the stream */
|
|
+ goto err_inc;
|
|
/*
|
|
- * In addition, any group of "ECKD" type has to include
|
|
- * targetgeometry
|
|
+ * 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_type_is_eckd(t->targettype) && t->check_params != 5)
|
|
- goto error;
|
|
+ goto err_inc;
|
|
}
|
|
return 0;
|
|
-error:
|
|
- error_reason("%s", error);
|
|
+err_inc:
|
|
+ error_reason("%s", "Inconsistent script output");
|
|
+ return -1;
|
|
+err_exc:
|
|
+ error_reason("%s", "Exceeded the maximum number of base disks");
|
|
return -1;
|
|
}
|
|
|
|
From f2902a1990783159a8358ead99b4dd19009183a1 Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Wed, 10 Jun 2026 18:05:55 +0200
|
|
Subject: [PATCH] zipl/src: Fix alignment of componets location in bootmap file
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Calculate the alignment value as maximum of physical block sizes of
|
|
disks participating in the mirrored setup. Earlier the alignment was
|
|
calculated as a physical block size of the first disk of a mirrored
|
|
setup.
|
|
|
|
Without this change, the assertion in disk_get_blocklist_from_file()
|
|
'assert(reg->offset % info->phy_block_size == 0)' is triggered in case
|
|
when blocksize of base disk #J > blocksize of base disk #I && (J>I).
|
|
To reproduce the problem, build a mixed mirrored setup with first SCSI
|
|
disk, second DASD disk and prepare it for IPL.
|
|
|
|
Fixes: 731f00202c53 ("zipl/src: Enable heterogeneous mirrors support")
|
|
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/include/disk.h | 9 ++++----
|
|
zipl/include/install.h | 4 ++--
|
|
zipl/src/bootmap.c | 21 ++++++++++-------
|
|
zipl/src/disk.c | 27 +++++++++++++++++-----
|
|
zipl/src/install.c | 52 +++++++++++++++++++++++-------------------
|
|
5 files changed, 69 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/zipl/include/disk.h b/zipl/include/disk.h
|
|
index cce69f73a..ff64fda75 100644
|
|
--- a/zipl/include/disk.h
|
|
+++ b/zipl/include/disk.h
|
|
@@ -93,6 +93,7 @@ struct device_info {
|
|
* as retrieved from "/proc/devices", or evaluated
|
|
*/
|
|
int fs_block_size;
|
|
+ int align; /* alignment of component location in bootmap */
|
|
struct disk_info base[MAX_TARGETS]; /* array of physical disks for
|
|
* bootstrap blocks recording
|
|
*/
|
|
@@ -133,13 +134,13 @@ int disk_write_block_aligned(struct misc_fd *mfd, const void *data,
|
|
blocknum_t disk_write_block_buffer(struct misc_fd *fd, int fd_is_basedisk,
|
|
const void* buffer, size_t bytecount,
|
|
disk_blockptr_t** blocklist,
|
|
- int fs_block_size, struct disk_info *info);
|
|
+ int fs_block_size, int align,
|
|
+ struct disk_info *info);
|
|
blocknum_t disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk,
|
|
const void *buffer, size_t bytecount,
|
|
disk_blockptr_t **blocklist,
|
|
- int fs_block_size,
|
|
- struct disk_info *info, int align,
|
|
- off_t *offset);
|
|
+ int fs_block_size, int align,
|
|
+ struct disk_info *info, 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);
|
|
diff --git a/zipl/include/install.h b/zipl/include/install.h
|
|
index 71dc33d97..cc1f39b7f 100644
|
|
--- a/zipl/include/install.h
|
|
+++ b/zipl/include/install.h
|
|
@@ -160,13 +160,13 @@ int install_mvdump(char* const device[], struct job_target_data* target,
|
|
|
|
int install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
blocknum_t *stage1b_count, disk_blockptr_t *stage2_list,
|
|
- blocknum_t stage2_count, int fs_block_size,
|
|
+ blocknum_t stage2_count, int fs_block_size, int align,
|
|
struct disk_info *info);
|
|
int install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
blocknum_t *stage1b_count,
|
|
disk_blockptr_t *stage2_list,
|
|
blocknum_t stage2_count, int fs_block_size,
|
|
- struct disk_info *info);
|
|
+ int align, struct disk_info *info);
|
|
int rewind_tape(int fd);
|
|
|
|
#endif /* INSTALL_H */
|
|
diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c
|
|
index 6a72d28cb..9b5d2a12f 100644
|
|
--- a/zipl/src/bootmap.c
|
|
+++ b/zipl/src/bootmap.c
|
|
@@ -383,8 +383,8 @@ static int add_component_file_range(struct install_set *bis,
|
|
0 /* not a base disk */,
|
|
buffer, size, list,
|
|
bis->info->fs_block_size,
|
|
+ bis->info->align,
|
|
info,
|
|
- info->phy_block_size,
|
|
/*
|
|
* save component offset
|
|
*/
|
|
@@ -478,7 +478,7 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer,
|
|
|
|
align = fs_block_aligned_by_id(comp_id) ?
|
|
bis->info->fs_block_size :
|
|
- info->phy_block_size;
|
|
+ bis->info->align;
|
|
|
|
if (bis->skip_prepare_device &&
|
|
bis->mirrors[mirror_id].skip_prepare_blocklist)
|
|
@@ -486,8 +486,8 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer,
|
|
goto write_segment_table;
|
|
/* Write buffer */
|
|
*count = disk_write_block_buffer_align(&bis->mfd, 0, buffer, size, list,
|
|
- bis->info->fs_block_size,
|
|
- info, align, &offset);
|
|
+ bis->info->fs_block_size, align,
|
|
+ info, &offset);
|
|
if (*count == 0) {
|
|
error_text("Could not write to bootmap file");
|
|
return -1;
|
|
@@ -1265,7 +1265,7 @@ write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block,
|
|
|
|
static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
|
struct job_data *job,
|
|
- int fs_block_size,
|
|
+ int fs_block_size, int align,
|
|
struct disk_info *info,
|
|
disk_blockptr_t **stage1b_list,
|
|
blocknum_t *stage1b_count,
|
|
@@ -1289,6 +1289,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
|
stage2_size,
|
|
&stage2_list,
|
|
fs_block_size,
|
|
+ align,
|
|
info);
|
|
free(stage2_data);
|
|
if (stage2_count == 0) {
|
|
@@ -1297,7 +1298,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
|
}
|
|
if (install_fba_stage1b(mfd, stage1b_list, stage1b_count,
|
|
stage2_list, stage2_count,
|
|
- fs_block_size, info))
|
|
+ fs_block_size, align, info))
|
|
return -1;
|
|
free(stage2_list);
|
|
break;
|
|
@@ -1317,7 +1318,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename,
|
|
|
|
static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
|
struct job_data *job,
|
|
- int fs_block_size,
|
|
+ int fs_block_size, int align,
|
|
struct disk_info *info,
|
|
disk_blockptr_t *program_table,
|
|
disk_blockptr_t **stage1b_list,
|
|
@@ -1341,6 +1342,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
|
stage2b_size,
|
|
&stage2b_list,
|
|
fs_block_size,
|
|
+ align,
|
|
info);
|
|
free(stage2b_data);
|
|
if (stage2b_count == 0) {
|
|
@@ -1349,7 +1351,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
|
}
|
|
if (install_eckd_stage1b(mfd, stage1b_list, stage1b_count,
|
|
stage2b_list, stage2b_count,
|
|
- fs_block_size, info))
|
|
+ fs_block_size, align, info))
|
|
return -1;
|
|
free(stage2b_list);
|
|
break;
|
|
@@ -1367,6 +1369,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename,
|
|
stage2b_size,
|
|
stage1b_list,
|
|
fs_block_size,
|
|
+ align,
|
|
info);
|
|
free(stage2b_data);
|
|
if (stage2b_count == 0) {
|
|
@@ -1395,6 +1398,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis,
|
|
case disk_type_fba:
|
|
rc = install_stages_dasd_fba(&bis->mfd, bis->filename, job,
|
|
bis->info->fs_block_size,
|
|
+ bis->info->align,
|
|
info,
|
|
&pt->stage1b_list,
|
|
&pt->stage1b_count,
|
|
@@ -1404,6 +1408,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis,
|
|
case disk_type_eckd_cdl:
|
|
rc = install_stages_eckd_dasd(&bis->mfd, bis->filename, job,
|
|
bis->info->fs_block_size,
|
|
+ bis->info->align,
|
|
info,
|
|
&pt->table,
|
|
&pt->stage1b_list,
|
|
diff --git a/zipl/src/disk.c b/zipl/src/disk.c
|
|
index 673224fb9..b2f2561da 100644
|
|
--- a/zipl/src/disk.c
|
|
+++ b/zipl/src/disk.c
|
|
@@ -575,7 +575,21 @@ static int disk_set_info_complete(struct job_target_data *td,
|
|
return 0;
|
|
}
|
|
|
|
-static int device_set_info_complete(struct device_info *dev_info)
|
|
+static void device_get_alignment(struct device_info *dev_info,
|
|
+ struct job_target_data *td)
|
|
+{
|
|
+ struct disk_info *base;
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < td->nr_targets; i++) {
|
|
+ base = &dev_info->base[i];
|
|
+ if (dev_info->align < base->phy_block_size)
|
|
+ dev_info->align = base->phy_block_size;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int device_set_info_complete(struct device_info *dev_info,
|
|
+ struct job_target_data *td)
|
|
{
|
|
struct util_proc_part_entry part_entry;
|
|
|
|
@@ -588,6 +602,7 @@ static int device_set_info_complete(struct device_info *dev_info)
|
|
}
|
|
/* Initialize file system block size with invalid value */
|
|
dev_info->fs_block_size = -1;
|
|
+ device_get_alignment(dev_info, td);
|
|
return 0;
|
|
}
|
|
|
|
@@ -689,7 +704,7 @@ int device_get_info(const char *device, struct job_target_data *td,
|
|
if (disk_set_info_complete(td, &data->base[i], &stats, fd))
|
|
goto error;
|
|
}
|
|
- if (device_set_info_complete(data))
|
|
+ if (device_set_info_complete(data, td))
|
|
goto error;
|
|
free(script_file);
|
|
close(fd);
|
|
@@ -1017,7 +1032,7 @@ blocknum_t
|
|
disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk,
|
|
const void *buffer, size_t bytecount,
|
|
disk_blockptr_t **blocklist, int fs_block_size,
|
|
- struct disk_info *info, int align, off_t *offset)
|
|
+ int align, struct disk_info *info, off_t *offset)
|
|
{
|
|
blocknum_t count;
|
|
blocknum_t i;
|
|
@@ -1058,12 +1073,12 @@ blocknum_t
|
|
disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk,
|
|
const void *buffer, size_t bytecount,
|
|
disk_blockptr_t **blocklist, int fs_block_size,
|
|
- struct disk_info *info)
|
|
+ int align, struct disk_info *info)
|
|
{
|
|
return disk_write_block_buffer_align(mfd, fd_is_basedisk, buffer,
|
|
bytecount, blocklist,
|
|
- fs_block_size, info,
|
|
- info->phy_block_size, NULL);
|
|
+ fs_block_size, align, info,
|
|
+ NULL);
|
|
}
|
|
|
|
/* Print device node. */
|
|
diff --git a/zipl/src/install.c b/zipl/src/install.c
|
|
index 176a00437..1baf153fa 100644
|
|
--- a/zipl/src/install.c
|
|
+++ b/zipl/src/install.c
|
|
@@ -172,7 +172,7 @@ install_fba_ccw(int fd, disk_blockptr_t *program_table,
|
|
int
|
|
install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
blocknum_t *stage1b_count, disk_blockptr_t *stage2_list,
|
|
- blocknum_t stage2_count, int fs_block_size,
|
|
+ blocknum_t stage2_count, int fs_block_size, int align,
|
|
struct disk_info *info)
|
|
{
|
|
struct boot_eckd_stage1b *stage1b;
|
|
@@ -189,7 +189,7 @@ install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
goto out_free_stage1b;
|
|
*stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size,
|
|
stage1b_list, fs_block_size,
|
|
- info);
|
|
+ align, info);
|
|
if (*stage1b_count == 0)
|
|
goto out_free_stage1b;
|
|
rc = 0;
|
|
@@ -855,7 +855,7 @@ static void eckd_dump_store_param(struct eckd_dump_param *param,
|
|
|
|
static int
|
|
install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size,
|
|
- struct disk_info *info,
|
|
+ int align, struct disk_info *info,
|
|
const struct stage2dump_parm_tail *stage2dump_parms)
|
|
{
|
|
disk_blockptr_t *stage2_list, *stage1b_list;
|
|
@@ -879,13 +879,13 @@ install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size,
|
|
if (misc_seek(mfd->fd, info->geo.start * info->phy_block_size))
|
|
goto out_free_stage2;
|
|
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
|
- &stage2_list,
|
|
- fs_block_size, info);
|
|
+ &stage2_list, fs_block_size,
|
|
+ align, info);
|
|
if (stage2_count == 0)
|
|
goto out_free_stage2_list;
|
|
if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count,
|
|
stage2_list, stage2_count, fs_block_size,
|
|
- info))
|
|
+ align, info))
|
|
goto out_free_stage2_list;
|
|
/* Install stage 0 - afterwards we are at stage 1 position*/
|
|
boot_init_eckd_ldl_stage0(&stage0);
|
|
@@ -913,8 +913,8 @@ install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size,
|
|
}
|
|
|
|
static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
- struct disk_info *info, void *stage2,
|
|
- size_t stage2_size, int mvdump,
|
|
+ int align, struct disk_info *info,
|
|
+ void *stage2, size_t stage2_size, int mvdump,
|
|
int force)
|
|
{
|
|
blocknum_t count, stage2_count, stage1b_count;
|
|
@@ -939,13 +939,13 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
goto out;
|
|
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
|
&stage2_list, fs_block_size,
|
|
- info);
|
|
+ align, info);
|
|
if (stage2_count == 0)
|
|
goto out;
|
|
/* Install stage 1b behind stage 2*/
|
|
if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count,
|
|
stage2_list, stage2_count, fs_block_size,
|
|
- info))
|
|
+ align, info))
|
|
goto out_free_stage2_list;
|
|
/* Install stage 0 */
|
|
boot_init_eckd_cdl_stage0(&stage0_cdl);
|
|
@@ -973,7 +973,7 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
|
|
static int
|
|
install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
- struct disk_info *info,
|
|
+ int align, struct disk_info *info,
|
|
const struct stage2dump_parm_tail *stage2dump_parms)
|
|
{
|
|
size_t stage2_size;
|
|
@@ -982,7 +982,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
|
|
if (boot_get_eckd_dump_stage2(&stage2, &stage2_size, stage2dump_parms))
|
|
return -1;
|
|
- rc = install_dump_eckd_cdl(mfd, fs_block_size,
|
|
+ rc = install_dump_eckd_cdl(mfd, fs_block_size, align,
|
|
info, stage2, stage2_size, 0, 0);
|
|
free(stage2);
|
|
return rc;
|
|
@@ -990,7 +990,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
|
|
static int
|
|
install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
- struct disk_info *info,
|
|
+ int align, struct disk_info *info,
|
|
const struct stage2dump_parm_tail *stage2dump_parms,
|
|
const struct mvdump_parm_table *mv_parm_table)
|
|
{
|
|
@@ -1002,7 +1002,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
if (boot_get_eckd_mvdump_stage2(&stage2, &stage2_size, stage2dump_parms,
|
|
mv_parm_table))
|
|
return -1;
|
|
- rc = install_dump_eckd_cdl(mfd, fs_block_size, info, stage2,
|
|
+ rc = install_dump_eckd_cdl(mfd, fs_block_size, align, info, stage2,
|
|
stage2_size, 1,
|
|
stage2dump_parms->mvdump_force);
|
|
free(stage2);
|
|
@@ -1012,7 +1012,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size,
|
|
int
|
|
install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
blocknum_t *stage1b_count, disk_blockptr_t *stage2_list,
|
|
- blocknum_t stage2_count, int fs_block_size,
|
|
+ blocknum_t stage2_count, int fs_block_size, int align,
|
|
struct disk_info *info)
|
|
{
|
|
struct boot_fba_stage1b *stage1b;
|
|
@@ -1029,7 +1029,7 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
goto out_free_stage1b;
|
|
*stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size,
|
|
stage1b_list, fs_block_size,
|
|
- info);
|
|
+ align, info);
|
|
if (*stage1b_count == 0)
|
|
goto out_free_stage1b;
|
|
rc = 0;
|
|
@@ -1041,7 +1041,7 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list,
|
|
|
|
static int
|
|
install_svdump_fba(struct misc_fd *mfd, int fs_block_size,
|
|
- struct disk_info *info,
|
|
+ int align, struct disk_info *info,
|
|
const struct stage2dump_parm_tail *stage2dump_parms)
|
|
{
|
|
blocknum_t stage1b_count, stage2_count, blk;
|
|
@@ -1067,7 +1067,7 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size,
|
|
goto out_free_stage2;
|
|
stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size,
|
|
&stage2_list, fs_block_size,
|
|
- info);
|
|
+ align, info);
|
|
if (stage2_count == 0)
|
|
goto out_free_stage2;
|
|
/* Install stage 1b in front of stage 2 */
|
|
@@ -1075,7 +1075,8 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size,
|
|
if (misc_seek(mfd->fd, blk * info->phy_block_size))
|
|
goto out_free_stage2_list;
|
|
if (install_fba_stage1b(mfd, &stage1b_list, &stage1b_count,
|
|
- stage2_list, stage2_count, fs_block_size, info))
|
|
+ stage2_list, stage2_count, fs_block_size,
|
|
+ align, info))
|
|
goto out_free_stage2_list;
|
|
/* Install stage 0/1 fill in dump partition parameter */
|
|
if (boot_init_fba_stage0(&stage0, stage1b_list, stage1b_count))
|
|
@@ -1219,14 +1220,17 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem,
|
|
if (info->type == disk_type_eckd_ldl)
|
|
rc = install_svdump_eckd_ldl(&mfd,
|
|
dev_info->fs_block_size,
|
|
- info, &stage2dump_parms);
|
|
+ dev_info->align, info,
|
|
+ &stage2dump_parms);
|
|
else if (info->type == disk_type_eckd_cdl)
|
|
rc = install_svdump_eckd_cdl(&mfd,
|
|
dev_info->fs_block_size,
|
|
- info, &stage2dump_parms);
|
|
+ dev_info->align, info,
|
|
+ &stage2dump_parms);
|
|
else
|
|
rc = install_svdump_fba(&mfd, dev_info->fs_block_size,
|
|
- info, &stage2dump_parms);
|
|
+ dev_info->align, info,
|
|
+ &stage2dump_parms);
|
|
break;
|
|
case disk_type_scsi:
|
|
error_reason("%s: Unsupported disk type '%s' (try --dumptofs)",
|
|
@@ -1382,8 +1386,8 @@ install_mvdump(char* const device[], struct job_target_data* target, int count,
|
|
printf("Installing dump record on target partition "
|
|
"'%s'\n", device[i]);
|
|
rc = install_mvdump_eckd_cdl(&mfd, dev_info[i]->fs_block_size,
|
|
- info[i], &stage2dump_parms,
|
|
- &mvdump_parms);
|
|
+ dev_info[i]->align, info[i],
|
|
+ &stage2dump_parms, &mvdump_parms);
|
|
misc_free_temp_dev(tempdev);
|
|
|
|
if (fsync(mfd.fd))
|
|
From 4f622325efa2e433254ea01d3eabf472dcc6f757 Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Thu, 11 Jun 2026 12:21:09 +0200
|
|
Subject: [PATCH] zipl/src: Fix add_component_file_range()
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Fix add_component_file_range() to process components of all types
|
|
(not only of COMPONENT_TYPE_LOAD), similar to how it is going in
|
|
add_component_buffer().
|
|
|
|
Earlier components of COMPONENT_TYPE_SIGNATURE were processed only
|
|
by add_component_buffer(). Starting from 60bc1e3, signatures for
|
|
mirrors (i.e. base disks of #1 and larger ID) are processed also by
|
|
the function add_component_file_range(), which works incorrectly for
|
|
such type of components.
|
|
|
|
Fixes: 60bc1e38d058 ("zipl/src: Reuse data of buffer components in bootmap")
|
|
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/src/bootmap.c | 9 +++++++--
|
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c
|
|
index 9b5d2a12..0d6df2d2 100644
|
|
--- a/zipl/src/bootmap.c
|
|
+++ b/zipl/src/bootmap.c
|
|
@@ -413,8 +413,13 @@ static int add_component_file_range(struct install_set *bis,
|
|
*count -= DIV_ROUND_UP(trailer, info->phy_block_size);
|
|
}
|
|
/* Fill in component location */
|
|
- location->addr = load_address;
|
|
- location->size = *count * info->phy_block_size;
|
|
+ if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) {
|
|
+ location->addr = load_address;
|
|
+ location->size = *count * info->phy_block_size;
|
|
+ } else {
|
|
+ location->addr = 0;
|
|
+ location->size = 0;
|
|
+ }
|
|
/* Try to compact list */
|
|
*count = disk_compact_blocklist(*list, *count, info);
|
|
write_segment_table:
|
|
From ee8897f9db5b93bc16799d0b534cc13c36719785 Mon Sep 17 00:00:00 2001
|
|
From: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Date: Thu, 11 Jun 2026 15:43:20 +0200
|
|
Subject: [PATCH] zipl/src: Add ->set_location() private method of program
|
|
component
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add/use ->set_location() private method of struct component_footer
|
|
instead of checking component types every time when operating with
|
|
program components.
|
|
|
|
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
|
|
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
|
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
|
---
|
|
zipl/include/install.h | 9 +++++++
|
|
zipl/src/bootmap.c | 21 +++++-----------
|
|
zipl/src/zipl.c | 54 ++++++++++++++++++++++++++++++++----------
|
|
3 files changed, 57 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/zipl/include/install.h b/zipl/include/install.h
|
|
index cc1f39b7..874068ef 100644
|
|
--- a/zipl/include/install.h
|
|
+++ b/zipl/include/install.h
|
|
@@ -58,6 +58,9 @@ struct component_footer {
|
|
* in the bootmap file. Otherwise, to
|
|
* phy_block_size boundary.
|
|
*/
|
|
+ void (*set_location)(struct component_loc *location,
|
|
+ address_t load_address, blocknum_t count,
|
|
+ int block_size);
|
|
};
|
|
|
|
struct program_component {
|
|
@@ -109,6 +112,12 @@ static inline enum scsi_layout get_scsi_layout(unsigned char *bootblock)
|
|
return scsi_layout_unknown;
|
|
}
|
|
|
|
+static inline struct component_footer *
|
|
+component_footer_by_id(enum program_component_id id)
|
|
+{
|
|
+ return &component_footers[id];
|
|
+}
|
|
+
|
|
static inline component_type component_type_by_id(enum program_component_id id)
|
|
{
|
|
return component_footers[id].type;
|
|
diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c
|
|
index 0d6df2d2..78ff73aa 100644
|
|
--- a/zipl/src/bootmap.c
|
|
+++ b/zipl/src/bootmap.c
|
|
@@ -353,6 +353,7 @@ static int add_component_file_range(struct install_set *bis,
|
|
{
|
|
struct program_component *pc = get_component(bis, mirror_id,
|
|
comp_id, menu_idx);
|
|
+ struct component_footer *cf = component_footer_by_id(comp_id);
|
|
struct disk_info *info = &bis->info->base[mirror_id];
|
|
struct component_loc *location = &pc->loc;
|
|
disk_blockptr_t **list = &pc->list;
|
|
@@ -413,13 +414,7 @@ static int add_component_file_range(struct install_set *bis,
|
|
*count -= DIV_ROUND_UP(trailer, info->phy_block_size);
|
|
}
|
|
/* Fill in component location */
|
|
- if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) {
|
|
- location->addr = load_address;
|
|
- location->size = *count * info->phy_block_size;
|
|
- } else {
|
|
- location->addr = 0;
|
|
- location->size = 0;
|
|
- }
|
|
+ cf->set_location(location, load_address, *count, info->phy_block_size);
|
|
/* Try to compact list */
|
|
*count = disk_compact_blocklist(*list, *count, info);
|
|
write_segment_table:
|
|
@@ -472,6 +467,7 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer,
|
|
comp_id, menu_idx);
|
|
struct file_range *comp_reg = get_component_range(bis, comp_id,
|
|
menu_idx);
|
|
+ struct component_footer *cf = component_footer_by_id(comp_id);
|
|
struct disk_info *info = &bis->info->base[mirror_id];
|
|
struct component_loc *location = &pc->loc;
|
|
disk_blockptr_t **list = &pc->list;
|
|
@@ -506,14 +502,9 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer,
|
|
comp_reg->offset = offset;
|
|
comp_reg->len = size;
|
|
}
|
|
- if (component_type_by_id(comp_id) == COMPONENT_TYPE_LOAD) {
|
|
- /* Fill in component location */
|
|
- location->addr = data.load_address;
|
|
- location->size = *count * info->phy_block_size;
|
|
- } else {
|
|
- location->addr = 0;
|
|
- location->size = 0;
|
|
- }
|
|
+ /* Fill in component location */
|
|
+ cf->set_location(location, data.load_address, *count,
|
|
+ info->phy_block_size);
|
|
/* Try to compact list */
|
|
*count = disk_compact_blocklist(*list, *count, info);
|
|
write_segment_table:
|
|
diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c
|
|
index 21f6eb0a..faf5b118 100644
|
|
--- a/zipl/src/zipl.c
|
|
+++ b/zipl/src/zipl.c
|
|
@@ -257,57 +257,87 @@ main(int argc, char* argv[])
|
|
return abs(rc);
|
|
}
|
|
|
|
+static void set_location_common(struct component_loc *location,
|
|
+ address_t load_address,
|
|
+ blocknum_t count,
|
|
+ int block_size)
|
|
+{
|
|
+ location->addr = load_address;
|
|
+ location->size = count * block_size;
|
|
+}
|
|
+
|
|
+static void set_location_noop(struct component_loc *location,
|
|
+ __attribute__((unused)) address_t load_address,
|
|
+ __attribute__((unused)) blocknum_t count,
|
|
+ __attribute__((unused)) int block_size)
|
|
+{
|
|
+ location->addr = 0;
|
|
+ location->size = 0;
|
|
+}
|
|
+
|
|
/**
|
|
* Program Component Footers
|
|
*/
|
|
struct component_footer component_footers[NR_PROGRAM_COMPONENTS] = {
|
|
[COMPONENT_ID_HEAP_AREA] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "heap area"
|
|
+ .desc = "heap area",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_STACK_AREA] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "stack area"
|
|
+ .desc = "stack area",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_LOADER_SIGNATURE] = {
|
|
.type = COMPONENT_TYPE_SIGNATURE,
|
|
- .desc = "loader signature"
|
|
+ .desc = "loader signature",
|
|
+ .set_location = set_location_noop
|
|
},
|
|
[COMPONENT_ID_LOADER] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "internal loader"
|
|
+ .desc = "internal loader",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_PARAMETERS] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "parameters"
|
|
+ .desc = "parameters",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_IMAGE_SIGNATURE] = {
|
|
.type = COMPONENT_TYPE_SIGNATURE,
|
|
- .desc = "image signature"
|
|
+ .desc = "image signature",
|
|
+ .set_location = set_location_noop,
|
|
},
|
|
[COMPONENT_ID_KERNEL_IMAGE] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "kernel image"
|
|
+ .desc = "kernel image",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_PARMLINE] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "parmline"
|
|
+ .desc = "parmline",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_RAMDISK_SIGNATURE] = {
|
|
.type = COMPONENT_TYPE_SIGNATURE,
|
|
- .desc = "ramdisk signature"
|
|
+ .desc = "ramdisk signature",
|
|
+ .set_location = set_location_noop
|
|
},
|
|
[COMPONENT_ID_RAMDISK] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
- .desc = "initial ramdisk"
|
|
+ .desc = "initial ramdisk",
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_ENVBLK] = {
|
|
.type = COMPONENT_TYPE_LOAD,
|
|
.desc = "environment blk",
|
|
- .fs_block_aligned = 1
|
|
+ .fs_block_aligned = 1,
|
|
+ .set_location = set_location_common
|
|
},
|
|
[COMPONENT_ID_SEGMENT_FILE] = {
|
|
.type = COMPONENT_TYPE_EXECUTE,
|
|
- .desc = "segment file"
|
|
+ .desc = "segment file",
|
|
+ .set_location = set_location_noop
|
|
}
|
|
};
|