diff --git a/.gitignore b/.gitignore index 5635722..aa86236 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/mdadm-4.2.tar.xz +SOURCES/mdadm-4.3.tar.xz diff --git a/.mdadm.metadata b/.mdadm.metadata index 56ea749..de33b58 100644 --- a/.mdadm.metadata +++ b/.mdadm.metadata @@ -1 +1 @@ -27f240cff200e00c28a486a028bcdb14f67f8790 SOURCES/mdadm-4.2.tar.xz +fb0bace919325b42a005372b5a5cfa999da6567a SOURCES/mdadm-4.3.tar.xz diff --git a/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch b/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch new file mode 100644 index 0000000..c797842 --- /dev/null +++ b/SOURCES/0001-Remove-hardcoded-checkpoint-interval-checking.patch @@ -0,0 +1,64 @@ +From aec3b907de48be54106600a1ecb69d1231f4801d Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:15 +0100 +Subject: [PATCH 01/41] Remove hardcoded checkpoint interval checking + +Mdmon assumes that kernel marks checkpoint every 1/16 of the volume size +and that the checkpoints are equal in size. This is not true, kernel may +mark checkpoints more frequently depending on several factors, including +sync speed. This results in checkpoints reported by mdadm --examine +falling behind the one reported by kernel. + +Remove hardcoded checkpoint interval checking. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + monitor.c | 22 ++++++---------------- + 1 file changed, 6 insertions(+), 16 deletions(-) + +diff --git a/monitor.c b/monitor.c +index 4acec678..b8d9e881 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -564,22 +564,10 @@ static int read_and_act(struct active_array *a, fd_set *fds) + } + } + +- /* Check for recovery checkpoint notifications. We need to be a +- * minimum distance away from the last checkpoint to prevent +- * over checkpointing. Note reshape checkpointing is handled +- * in the second branch. ++ /* Handle reshape checkpointing + */ +- if (sync_completed > a->last_checkpoint && +- sync_completed - a->last_checkpoint > a->info.component_size >> 4 && +- a->curr_action > reshape) { +- /* A (non-reshape) sync_action has reached a checkpoint. +- * Record the updated position in the metadata +- */ +- a->last_checkpoint = sync_completed; +- a->container->ss->set_array_state(a, a->curr_state <= clean); +- } else if ((a->curr_action == idle && a->prev_action == reshape) || +- (a->curr_action == reshape && +- sync_completed > a->last_checkpoint)) { ++ if ((a->curr_action == idle && a->prev_action == reshape) || ++ (a->curr_action == reshape && sync_completed > a->last_checkpoint)) { + /* Reshape has progressed or completed so we need to + * update the array state - and possibly the array size + */ +@@ -607,8 +595,10 @@ static int read_and_act(struct active_array *a, fd_set *fds) + a->last_checkpoint = sync_completed; + } + +- if (sync_completed > a->last_checkpoint) ++ if (sync_completed > a->last_checkpoint) { + a->last_checkpoint = sync_completed; ++ a->container->ss->set_array_state(a, a->curr_state <= clean); ++ } + + if (sync_completed >= a->info.component_size) + a->last_checkpoint = 0; +-- +2.40.1 + diff --git a/SOURCES/0001-Unify-error-message.patch b/SOURCES/0001-Unify-error-message.patch deleted file mode 100644 index 14dc69c..0000000 --- a/SOURCES/0001-Unify-error-message.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Tue, 15 Mar 2022 09:30:30 +0100 -Subject: [PATCH 01/83] Unify error message. - -Provide the same error message for the same error that can occur in Grow.c and super-intel.c. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - super-intel.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9c6fc95e..9a947204 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1001,8 +1001,8 @@ int remove_disks_for_takeover(struct supertype *st, - rv = 1; - sysfs_free(arrays); - if (rv) { -- pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm); -- pr_err("For this operation it MUST be single array in container\n"); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", st->devnm); - return rv; - } - } -diff --git a/super-intel.c b/super-intel.c -index d5fad102..5ffa7636 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - struct imsm_super *mpb = super->anchor; - - if (mpb->num_raid_devs > 1) { -- pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n", -- geo->dev_name); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", geo->dev_name); - change = -1; - } - } --- -2.38.1 - diff --git a/SOURCES/0002-mdadm-Fix-double-free.patch b/SOURCES/0002-mdadm-Fix-double-free.patch deleted file mode 100644 index e6b7d37..0000000 --- a/SOURCES/0002-mdadm-Fix-double-free.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 25 Mar 2022 12:48:59 +0100 -Subject: [PATCH 02/83] mdadm: Fix double free - -If there was a size mismatch after creation it would get fixed on grow -in imsm_fix_size_mismatch(), but due to double free "double free or corruption (fasttop)" -error occurs and grow cannot proceed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5ffa7636..6ff336ee 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - st->update_tail = &st->updates; - } else { - imsm_sync_metadata(st); -+ free(update); - } -- -- free(update); - } - ret_val = 0; - exit: --- -2.38.1 - diff --git a/SOURCES/0002-monitor-refactor-checkpoint-update.patch b/SOURCES/0002-monitor-refactor-checkpoint-update.patch new file mode 100644 index 0000000..236be98 --- /dev/null +++ b/SOURCES/0002-monitor-refactor-checkpoint-update.patch @@ -0,0 +1,96 @@ +From cf87fe75fd83dac008ea116c2c52ec69783fdf6a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:16 +0100 +Subject: [PATCH 02/41] monitor: refactor checkpoint update + +"if" statements of checkpoint updates have too many responsibilties. +This results in unclear code flow and duplicated code. + +Refactor checkpoint update code and simplify "if" statements. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + monitor.c | 51 +++++++++++++++++++++++++-------------------------- + 1 file changed, 25 insertions(+), 26 deletions(-) + +diff --git a/monitor.c b/monitor.c +index b8d9e881..be0bec78 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -412,6 +412,7 @@ static int read_and_act(struct active_array *a, fd_set *fds) + int ret = 0; + int count = 0; + struct timeval tv; ++ bool write_checkpoint = false; + + a->next_state = bad_word; + a->next_action = bad_action; +@@ -564,40 +565,38 @@ static int read_and_act(struct active_array *a, fd_set *fds) + } + } + +- /* Handle reshape checkpointing +- */ +- if ((a->curr_action == idle && a->prev_action == reshape) || +- (a->curr_action == reshape && sync_completed > a->last_checkpoint)) { +- /* Reshape has progressed or completed so we need to +- * update the array state - and possibly the array size +- */ ++ /* Update reshape checkpoint, depending if it finished or progressed */ ++ if (a->curr_action == idle && a->prev_action == reshape) { ++ char buf[SYSFS_MAX_BUF_SIZE]; ++ + if (sync_completed != 0) + a->last_checkpoint = sync_completed; +- /* We might need to update last_checkpoint depending on +- * the reason that reshape finished. +- * if array reshape is really finished: +- * set check point to the end, this allows +- * set_array_state() to finalize reshape in metadata +- * if reshape if broken: do not set checkpoint to the end +- * this allows for reshape restart from checkpoint ++ ++ /* ++ * If reshape really finished, set checkpoint to the end to finalize it. ++ * Do not set checkpoint if reshape is broken. ++ * Reshape will restart from last checkpoint. + */ +- if ((a->curr_action != reshape) && +- (a->prev_action == reshape)) { +- char buf[SYSFS_MAX_BUF_SIZE]; +- if ((sysfs_get_str(&a->info, NULL, +- "reshape_position", +- buf, +- sizeof(buf)) >= 0) && +- str_is_none(buf) == true) ++ if (sysfs_get_str(&a->info, NULL, "reshape_position", buf, sizeof(buf)) >= 0) ++ if (str_is_none(buf) == true) + a->last_checkpoint = a->info.component_size; +- } +- a->container->ss->set_array_state(a, a->curr_state <= clean); +- a->last_checkpoint = sync_completed; ++ ++ write_checkpoint = true; + } + +- if (sync_completed > a->last_checkpoint) { ++ if (a->curr_action >= reshape && sync_completed > a->last_checkpoint) { ++ /* Update checkpoint if neither reshape nor idle action */ + a->last_checkpoint = sync_completed; ++ ++ write_checkpoint = true; ++ } ++ ++ /* Save checkpoint */ ++ if (write_checkpoint) { + a->container->ss->set_array_state(a, a->curr_state <= clean); ++ ++ if (a->curr_action <= reshape) ++ a->last_checkpoint = sync_completed; + } + + if (sync_completed >= a->info.component_size) +-- +2.40.1 + diff --git a/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch b/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch deleted file mode 100644 index e43cdaa..0000000 --- a/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch +++ /dev/null @@ -1,83 +0,0 @@ -From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Wed, 23 Mar 2022 15:05:19 +0100 -Subject: [PATCH 03/83] Grow_reshape: Add r0 grow size error message and update - man - -Grow size on r0 is not supported for imsm and native metadata. -Add proper error message. -Update man for proper use of --size. -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 6 ++++++ - mdadm.8.in | 19 ++++++++++++------- - 2 files changed, 18 insertions(+), 7 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9a947204..aa72490b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1998,6 +1998,12 @@ int Grow_reshape(char *devname, int fd, - goto release; - } - -+ if (array.level == 0) { -+ pr_err("Component size change is not supported for RAID0\n"); -+ rv = 1; -+ goto release; -+ } -+ - if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, - devname, APPLY_METADATA_CHANGES, - c->verbose > 0)) { -diff --git a/mdadm.8.in b/mdadm.8.in -index be902dba..e2a42425 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -459,7 +459,8 @@ number of spare devices. - - .TP - .BR \-z ", " \-\-size= --Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6. -+Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10 -+and for RAID 0 on external metadata. - This must be a multiple of the chunk size, and must leave about 128Kb - of space at the end of the drive for the RAID superblock. - If this is not specified -@@ -478,10 +479,19 @@ To guard against this it can be useful to set the initial size - slightly smaller than the smaller device with the aim that it will - still be larger than any replacement. - -+This option can be used with -+.B \-\-create -+for determining initial size of an array. For external metadata, -+it can be used on a volume, but not on a container itself. -+Setting initial size of -+.B RAID 0 -+array is only valid for external metadata. -+ - This value can be set with - .B \-\-grow --for RAID level 1/4/5/6 though -+for RAID level 1/4/5/6/10 though - DDF arrays may not be able to support this. -+RAID 0 array size cannot be changed. - If the array was created with a size smaller than the currently - active drives, the extra space can be accessed using - .BR \-\-grow . -@@ -501,11 +511,6 @@ problems the array can be made bigger again with no loss with another - .B "\-\-grow \-\-size=" - command. - --This value cannot be used when creating a --.B CONTAINER --such as with DDF and IMSM metadata, though it perfectly valid when --creating an array inside a container. -- - .TP - .BR \-Z ", " \-\-array\-size= - This is only meaningful with --- -2.38.1 - diff --git a/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch b/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch new file mode 100644 index 0000000..0a347ea --- /dev/null +++ b/SOURCES/0003-Super-intel-Fix-first-checkpoint-restart.patch @@ -0,0 +1,47 @@ +From fdb7e802f4cf64d067c3abaafa35056e2bc1ed43 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:17 +0100 +Subject: [PATCH 03/41] Super-intel: Fix first checkpoint restart + +When imsm based array is stopped after reaching first checkpoint and +then assembled, first checkpoint is reported as 0. + +This behaviour is valid only for initial checkpoint, if the array was +stopped while performing some action. + +Last checkpoint value is not taken from metadata but always starts +with 0 and it's incremented when sync_completed in sysfs changes. + +In simplification, read_and_act() is responsible for checkpoint updates +and is executed each time sysfs checkpoint update happens. For first +checkpoint it is executed twice and due to marking checkpoint before +triggering any action on the array, it is impossible to read +sync_completed from sysfs in just two iterations. + +The workaround to this is not marking any checkpoint for first +sysfs checkpoint after RAID assembly, to preserve checkpoint value +stored in metadata. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index dbea235d..e61f3f6f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8771,6 +8771,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent) + super->updates_pending++; + } + ++ if (a->prev_action == idle) ++ goto skip_mark_checkpoint; ++ + mark_checkpoint: + /* skip checkpointing for general migration, + * it is controlled in mdadm +-- +2.40.1 + diff --git a/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch b/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch new file mode 100644 index 0000000..3ccc2ae --- /dev/null +++ b/SOURCES/0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch @@ -0,0 +1,61 @@ +From ea2ca7ed3dbbf881ce08d80fe371f2aaf05011c3 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:18 +0100 +Subject: [PATCH 04/41] Grow: Move update_tail assign to Grow_reshape() + +Due to e919fb0af245 ("FIX: Enable metadata updates for raid0") code +can't enter super-intel.c:3415, resulting in checkpoint not being +saved to metadata for second volume in matrix raid array. +This results in checkpoint being stuck at last value for the +first volume. + +Move st->update_tail to Grow_reshape() so it is assigned for each +volume. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/Grow.c b/Grow.c +index f95dae82..5498e54f 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2085,9 +2085,10 @@ int Grow_reshape(char *devname, int fd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(container); +- if (mdmon_running(st->container_devnm) && +- st->update_tail == NULL) +- st->update_tail = &st->updates; ++ if (mdmon_running(st->container_devnm) == false) { ++ pr_err("No mdmon found. Grow cannot continue.\n"); ++ goto release; ++ } + } + + if (s->size == MAX_SIZE) +@@ -3048,6 +3049,8 @@ static int reshape_array(char *container, int fd, char *devname, + dprintf("Cannot get array information.\n"); + goto release; + } ++ if (st->update_tail == NULL) ++ st->update_tail = &st->updates; + if (array.level == 0 && info->component_size == 0) { + get_dev_size(fd, NULL, &array_size); + info->component_size = array_size / array.raid_disks; +@@ -5152,9 +5155,7 @@ int Grow_continue_command(char *devname, int fd, + start_mdmon(container); + ping_monitor(container); + +- if (mdmon_running(container)) +- st->update_tail = &st->updates; +- else { ++ if (mdmon_running(container) == false) { + pr_err("No mdmon found. Grow cannot continue.\n"); + ret_val = 1; + goto Grow_continue_command_exit; +-- +2.40.1 + diff --git a/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch b/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch deleted file mode 100644 index a755c53..0000000 --- a/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 14 Jan 2022 16:44:33 +0100 -Subject: [PATCH 04/83] udev: adapt rules to systemd v247 - -New events have been added in kernel 4.14 ("bind" and "unbind"). -Systemd maintainer suggests to modify "add|change" branches. -This patches implements their suggestions. There is no issue yet because -new event types are not used in md. - -Please see systemd announcement for details[1]. - -[1] https://lists.freedesktop.org/archives/systemd-devel/2020-November/045646.html - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - udev-md-raid-arrays.rules | 2 +- - udev-md-raid-assembly.rules | 5 +++-- - udev-md-raid-safe-timeouts.rules | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 13c9076e..2967ace1 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -3,7 +3,7 @@ - SUBSYSTEM!="block", GOTO="md_end" - - # handle md arrays --ACTION!="add|change", GOTO="md_end" -+ACTION=="remove", GOTO="md_end" - KERNEL!="md*", GOTO="md_end" - - # partitions have no md/{array_state,metadata_version}, but should not -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index d668cddd..39b4344b 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -30,8 +30,9 @@ LABEL="md_inc" - - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' --ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" -+ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ - ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" - ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" - -diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules -index 12bdcaa8..2e185cee 100644 ---- a/udev-md-raid-safe-timeouts.rules -+++ b/udev-md-raid-safe-timeouts.rules -@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end" - - IMPORT{program}="/sbin/mdadm --examine --export $devnode" - --ACTION=="add|change", \ -+ACTION!="remove", \ - ENV{ID_FS_TYPE}=="linux_raid_member", \ - ENV{MD_LEVEL}=="raid[1-9]*", \ - TEST=="/sys/block/$parent/device/timeout", \ --- -2.38.1 - diff --git a/SOURCES/0005-Add-understanding-output-section-in-man.patch b/SOURCES/0005-Add-understanding-output-section-in-man.patch new file mode 100644 index 0000000..fa4fd55 --- /dev/null +++ b/SOURCES/0005-Add-understanding-output-section-in-man.patch @@ -0,0 +1,56 @@ +From 37eeae381a8ed07a1fabb64184fe45d95a861496 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Jan 2024 11:30:19 +0100 +Subject: [PATCH 05/41] Add understanding output section in man + +Add new section in man for explaining mdadm outputs. +Describe checkpoint entry. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.8.in | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 96a4a08e..9ba66825 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -3179,7 +3179,7 @@ environment. This can be useful for testing or for disaster + recovery. You should be aware that interoperability may be + compromised by setting this value. + +-These change can also be suppressed by adding ++These change can also be suppressed by adding + .B mdadm.imsm.test=1 + to the kernel command line. This makes it easy to test IMSM + code in a virtual machine that doesn't have IMSM virtual hardware. +@@ -3454,6 +3454,25 @@ is any string. These names are supported by + since version 3.3 provided they are enabled in + .IR mdadm.conf . + ++.SH UNDERSTANDING OUTPUT ++ ++.TP ++EXAMINE ++ ++.TP ++.B checkpoint ++Checkpoint value is reported when array is performing some action including ++resync, recovery or reshape. Checkpoints allow resuming action from certain ++point if it was interrupted. ++ ++Checkpoint is reported as combination of two values: current migration unit ++and number of blocks per unit. By multiplying those values and dividing by ++array size checkpoint progress percentage can be obtained in relation to ++current progress reported in /proc/mdstat. Checkpoint is also related to (and ++sometimes based on) sysfs entry sync_completed but depending on action units ++may differ. Even if units are the same, it should not be expected that ++checkpoint and sync_completed will be exact match nor updated simultaneously. ++ + .SH NOTE + .I mdadm + was previously known as +-- +2.40.1 + diff --git a/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch b/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch deleted file mode 100644 index dd04b8c..0000000 --- a/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Mon, 21 Feb 2022 13:05:20 +0100 -Subject: [PATCH 05/83] Replace error prone signal() with sigaction() - -Up to this date signal() was used which implementation could vary [1]. -Sigaction() call is preferred. This commit introduces replacement -from signal() to sigaction() by the use of signal_s() wrapper. -Also remove redundant signal.h header includes. - -[1] https://man7.org/linux/man-pages/man2/signal.2.html - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - Monitor.c | 5 +++-- - managemon.c | 1 - - mdadm.h | 22 ++++++++++++++++++++++ - mdmon.c | 1 - - monitor.c | 1 - - probe_roms.c | 6 +++--- - raid6check.c | 25 +++++++++++++++---------- - util.c | 1 - - 9 files changed, 45 insertions(+), 21 deletions(-) - -diff --git a/Grow.c b/Grow.c -index aa72490b..18c5719b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -26,7 +26,6 @@ - #include - #include - #include --#include - #include - - #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) -@@ -3566,7 +3565,8 @@ started: - fd = -1; - mlockall(MCL_FUTURE); - -- signal(SIGTERM, catch_term); -+ if (signal_s(SIGTERM, catch_term) == SIG_ERR) -+ goto release; - - if (st->ss->external) { - /* metadata handler takes it from here */ -diff --git a/Monitor.c b/Monitor.c -index 30c031a2..c0ab5412 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -26,7 +26,6 @@ - #include "md_p.h" - #include "md_u.h" - #include --#include - #include - #include - #ifndef NO_LIBUDEV -@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) - if (mp) { - FILE *mdstat; - char hname[256]; -+ - gethostname(hname, sizeof(hname)); -- signal(SIGPIPE, SIG_IGN); -+ signal_s(SIGPIPE, SIG_IGN); -+ - if (info->mailfrom) - fprintf(mp, "From: %s\n", info->mailfrom); - else -diff --git a/managemon.c b/managemon.c -index bb7334cf..0e9bdf00 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -106,7 +106,6 @@ - #include "mdmon.h" - #include - #include --#include - - static void close_aa(struct active_array *aa) - { -diff --git a/mdadm.h b/mdadm.h -index c7268a71..26e7e5cd 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - #include - #include - #include -+#include - /* Newer glibc requires sys/sysmacros.h directly for makedev() */ - #include - #ifdef __dietlibc__ -@@ -1729,6 +1730,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) - return &ent->metadata_version[10+strlen(container)+1]; - } - -+/** -+ * signal_s() - Wrapper for sigaction() with signal()-like interface. -+ * @sig: The signal to set the signal handler to. -+ * @handler: The signal handler. -+ * -+ * Return: previous handler or SIG_ERR on failure. -+ */ -+static inline sighandler_t signal_s(int sig, sighandler_t handler) -+{ -+ struct sigaction new_act; -+ struct sigaction old_act; -+ -+ new_act.sa_handler = handler; -+ new_act.sa_flags = 0; -+ -+ if (sigaction(sig, &new_act, &old_act) == 0) -+ return old_act.sa_handler; -+ -+ return SIG_ERR; -+} -+ - #ifdef DEBUG - #define dprintf(fmt, arg...) \ - fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) -diff --git a/mdmon.c b/mdmon.c -index c71e62c6..5570574b 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -56,7 +56,6 @@ - #include - #include - #include --#include - #include - #ifdef USE_PTHREADS - #include -diff --git a/monitor.c b/monitor.c -index e0d3be67..b877e595 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -22,7 +22,6 @@ - #include "mdmon.h" - #include - #include --#include - - static char *array_states[] = { - "clear", "inactive", "suspended", "readonly", "read-auto", -diff --git a/probe_roms.c b/probe_roms.c -index 7ea04c7a..94c80c2c 100644 ---- a/probe_roms.c -+++ b/probe_roms.c -@@ -22,7 +22,6 @@ - #include "probe_roms.h" - #include "mdadm.h" - #include --#include - #include - #include - #include -@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val) - - void probe_roms_exit(void) - { -- signal(SIGBUS, SIG_DFL); -+ signal_s(SIGBUS, SIG_DFL); -+ - if (rom_fd >= 0) { - close(rom_fd); - rom_fd = -1; -@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align) - if (roms_init()) - return -1; - -- if (signal(SIGBUS, sigbus) == SIG_ERR) -+ if (signal_s(SIGBUS, sigbus) == SIG_ERR) - rc = -1; - if (rc == 0) { - fd = open("/dev/mem", O_RDONLY); -diff --git a/raid6check.c b/raid6check.c -index a8e6005b..99477761 100644 ---- a/raid6check.c -+++ b/raid6check.c -@@ -24,7 +24,6 @@ - - #include "mdadm.h" - #include --#include - #include - - #define CHECK_PAGE_BITS (12) -@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size) - } - - int lock_stripe(struct mdinfo *info, unsigned long long start, -- int chunk_size, int data_disks, sighandler_t *sig) { -+ int chunk_size, int data_disks, sighandler_t *sig) -+{ - int rv; -+ -+ sig[0] = signal_s(SIGTERM, SIG_IGN); -+ sig[1] = signal_s(SIGINT, SIG_IGN); -+ sig[2] = signal_s(SIGQUIT, SIG_IGN); -+ -+ if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR) -+ return 1; -+ - if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - return 2; - } - -- sig[0] = signal(SIGTERM, SIG_IGN); -- sig[1] = signal(SIGINT, SIG_IGN); -- sig[2] = signal(SIGQUIT, SIG_IGN); -- - rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks); - rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks); - return rv * 256; - } - --int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) { -+int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) -+{ - int rv; - rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL); - rv |= sysfs_set_num(info, NULL, "suspend_hi", 0); - rv |= sysfs_set_num(info, NULL, "suspend_lo", 0); - -- signal(SIGQUIT, sig[2]); -- signal(SIGINT, sig[1]); -- signal(SIGTERM, sig[0]); -+ signal_s(SIGQUIT, sig[2]); -+ signal_s(SIGINT, sig[1]); -+ signal_s(SIGTERM, sig[0]); - - if(munlockall() != 0) - return 3; -diff --git a/util.c b/util.c -index 3d05d074..cc94f96e 100644 ---- a/util.c -+++ b/util.c -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - #include - - --- -2.38.1 - diff --git a/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch b/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch new file mode 100644 index 0000000..13eb094 --- /dev/null +++ b/SOURCES/0006-Create-add_disk_to_super-fix-resource-leak.patch @@ -0,0 +1,48 @@ +From b8f5523a795b8f7e56dfbc139ce7f64728b67726 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:07 +0100 +Subject: [PATCH 06/41] Create: add_disk_to_super() fix resource leak + +Fixes resource leak in add_disk_to_super(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/Create.c b/Create.c +index 8082f54a..7e9170b6 100644 +--- a/Create.c ++++ b/Create.c +@@ -279,8 +279,10 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + dv->devname); + return 1; + } +- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) ++ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) { ++ close(fd); + return 1; ++ } + info->disk.major = major(rdev); + info->disk.minor = minor(rdev); + } +@@ -289,6 +291,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, + dv->data_offset)) { + ioctl(mdfd, STOP_ARRAY, NULL); ++ close(fd); + return 1; + } + st->ss->getinfo_super(st, info, NULL); +@@ -297,6 +300,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, + *zero_pid = write_zeroes_fork(fd, s, st, dv); + if (*zero_pid <= 0) { + ioctl(mdfd, STOP_ARRAY, NULL); ++ close(fd); + return 1; + } + } +-- +2.40.1 + diff --git a/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch b/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch deleted file mode 100644 index bee28ac..0000000 --- a/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch +++ /dev/null @@ -1,1533 +0,0 @@ -From e9dd5644843e2013a7dd1a8a5da2b9fa35837416 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:04 +0100 -Subject: [PATCH 06/83] mdadm: Respect config file location in man - -Default config file location could differ depending on OS (e.g. Debian family). -This patch takes default config file into consideration when creating mdadm.man -file as well as mdadm.conf.man. - -Rename mdadm.conf.5 to mdadm.conf.5.in. Now mdadm.conf.5 is generated automatically. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - .gitignore | 1 + - Makefile | 7 +- - mdadm.8.in | 16 +- - mdadm.conf.5 | 706 ------------------------------------------------ - mdadm.conf.5.in | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 721 insertions(+), 715 deletions(-) - delete mode 100644 mdadm.conf.5 - create mode 100644 mdadm.conf.5.in - -diff --git a/.gitignore b/.gitignore -index 217fe76d..8d791c6f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -3,6 +3,7 @@ - /*-stamp - /mdadm - /mdadm.8 -+/mdadm.conf.5 - /mdadm.udeb - /mdassemble - /mdmon -diff --git a/Makefile b/Makefile -index 2a51d813..bf126033 100644 ---- a/Makefile -+++ b/Makefile -@@ -227,7 +227,12 @@ raid6check : raid6check.o mdadm.h $(CHECK_OBJS) - - mdadm.8 : mdadm.8.in - sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \ -- -e 's,{MAP_PATH},$(MAP_PATH),g' mdadm.8.in > mdadm.8 -+ -e 's,{MAP_PATH},$(MAP_PATH),g' -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.8.in > mdadm.8 -+ -+mdadm.conf.5 : mdadm.conf.5.in -+ sed -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.conf.5.in > mdadm.conf.5 - - mdadm.man : mdadm.8 - man -l mdadm.8 > mdadm.man -diff --git a/mdadm.8.in b/mdadm.8.in -index e2a42425..8b21ffd4 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -267,13 +267,13 @@ the exact meaning of this option in different contexts. - .TP - .BR \-c ", " \-\-config= - Specify the config file or directory. Default is to use --.B /etc/mdadm.conf -+.B {CONFFILE} - and --.BR /etc/mdadm.conf.d , -+.BR {CONFFILE}.d , - or if those are missing then --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - and --.BR /etc/mdadm/mdadm.conf.d . -+.BR {CONFFILE2}.d . - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2014,9 +2014,9 @@ The config file is only used if explicitly named with - or requested with (a possibly implicit) - .BR \-\-scan . - In the later case, --.B /etc/mdadm.conf -+.B {CONFFILE} - or --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - is used. - - If -@@ -3344,7 +3344,7 @@ uses this to find arrays when - is given in Misc mode, and to monitor array reconstruction - on Monitor mode. - --.SS /etc/mdadm.conf -+.SS {CONFFILE} (or {CONFFILE2}) - - The config file lists which devices may be scanned to see if - they contain MD super block, and gives identifying information -@@ -3352,7 +3352,7 @@ they contain MD super block, and gives identifying information - .BR mdadm.conf (5) - for more details. - --.SS /etc/mdadm.conf.d -+.SS {CONFFILE}.d (or {CONFFILE2}.d) - - A directory containing configuration files which are read in lexical - order. -diff --git a/mdadm.conf.5 b/mdadm.conf.5 -deleted file mode 100644 -index 74a21c5f..00000000 ---- a/mdadm.conf.5 -+++ /dev/null -@@ -1,706 +0,0 @@ --.\" Copyright Neil Brown and others. --.\" This program is free software; you can redistribute it and/or modify --.\" it under the terms of the GNU General Public License as published by --.\" the Free Software Foundation; either version 2 of the License, or --.\" (at your option) any later version. --.\" See file COPYING in distribution for details. --.TH MDADM.CONF 5 --.SH NAME --mdadm.conf \- configuration for management of Software RAID with mdadm --.SH SYNOPSIS --/etc/mdadm.conf --.SH DESCRIPTION --.PP --.I mdadm --is a tool for creating, managing, and monitoring RAID devices using the --.B md --driver in Linux. --.PP --Some common tasks, such as assembling all arrays, can be simplified --by describing the devices and arrays in this configuration file. -- --.SS SYNTAX --The file should be seen as a collection of words separated by white --space (space, tab, or newline). --Any word that beings with a hash sign (#) starts a comment and that --word together with the remainder of the line is ignored. -- --Spaces can be included in a word using quotation characters. Either --single quotes --.RB ( ' ) --or double quotes (\fB"\fP) --may be used. All the characters from one quotation character to --next identical character are protected and will not be used to --separate words to start new quoted strings. To include a single quote --it must be between double quotes. To include a double quote it must --be between single quotes. -- --Any line that starts with white space (space or tab) is treated as --though it were a continuation of the previous line. -- --Empty lines are ignored, but otherwise each (non continuation) line --must start with a keyword as listed below. The keywords are case --insensitive and can be abbreviated to 3 characters. -- --The keywords are: --.TP --.B DEVICE --A --.B device --line lists the devices (whole devices or partitions) that might contain --a component of an MD array. When looking for the components of an --array, --.I mdadm --will scan these devices (or any devices listed on the command line). -- --The --.B device --line may contain a number of different devices (separated by spaces) --and each device name can contain wild cards as defined by --.BR glob (7). -- --Also, there may be several device lines present in the file. -- --Alternatively, a --.B device --line can contain either or both of the words --.B containers --and --.BR partitions . --The word --.B containers --will cause --.I mdadm --to look for assembled CONTAINER arrays and included them as a source --for assembling further arrays. -- --The word --.I partitions --will cause --.I mdadm --to read --.I /proc/partitions --and include all devices and partitions found therein. --.I mdadm --does not use the names from --.I /proc/partitions --but only the major and minor device numbers. It scans --.I /dev --to find the name that matches the numbers. -- --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -- --For example: --.IP --DEVICE /dev/hda* /dev/hdc* --.br --DEV /dev/sd* --.br --DEVICE /dev/disk/by-path/pci* --.br --DEVICE partitions -- --.TP --.B ARRAY --The ARRAY lines identify actual arrays. The second word on the line --may be the name of the device where the array is normally --assembled, such as --.B /dev/md1 --or --.BR /dev/md/backup . --If the name does not start with a slash --.RB (' / '), --it is treated as being in --.BR /dev/md/ . --Alternately the word --.B --(complete with angle brackets) can be given in which case any array --which matches the rest of the line will never be automatically assembled. --If no device name is given, --.I mdadm --will use various heuristics to determine an appropriate name. -- --Subsequent words identify the array, or identify the array as a member --of a group. If multiple identities are given, --then a component device must match ALL identities to be considered a --match. Each identity word has a tag, and equals sign, and some value. --The tags are: --.RS 4 --.TP --.B uuid= --The value should be a 128 bit uuid in hexadecimal, with punctuation --interspersed if desired. This must match the uuid stored in the --superblock. --.TP --.B name= --The value should be a simple textual name as was given to --.I mdadm --when the array was created. This must match the name stored in the --superblock on a device for that device to be included in the array. --Not all superblock formats support names. --.TP --.B super\-minor= --The value is an integer which indicates the minor number that was --stored in the superblock when the array was created. When an array is --created as /dev/mdX, then the minor number X is stored. --.TP --.B devices= --The value is a comma separated list of device names or device name --patterns. --Only devices with names which match one entry in the list will be used --to assemble the array. Note that the devices --listed there must also be listed on a DEVICE line. --.TP --.B level= --The value is a RAID level. This is not normally used to --identify an array, but is supported so that the output of -- --.B "mdadm \-\-examine \-\-scan" -- --can be use directly in the configuration file. --.TP --.B num\-devices= --The value is the number of devices in a complete active array. As with --.B level= --this is mainly for compatibility with the output of -- --.BR "mdadm \-\-examine \-\-scan" . -- --.TP --.B spares= --The value is a number of spare devices to expect the array to have. --The sole use of this keyword and value is as follows: --.B mdadm \-\-monitor --will report an array if it is found to have fewer than this number of --spares when --.B \-\-monitor --starts or when --.B \-\-oneshot --is used. -- --.TP --.B spare\-group= --The value is a textual name for a group of arrays. All arrays with --the same --.B spare\-group --name are considered to be part of the same group. The significance of --a group of arrays is that --.I mdadm --will, when monitoring the arrays, move a spare drive from one array in --a group to another array in that group if the first array had a failed --or missing drive but no spare. -- --.TP --.B auto= --This option is rarely needed with mdadm-3.0, particularly if use with --the Linux kernel v2.6.28 or later. --It tells --.I mdadm --whether to use partitionable array or non-partitionable arrays and, --in the absence of --.IR udev , --how many partition devices to create. From 2.6.28 all md array --devices are partitionable, hence this option is not needed. -- --The value of this option can be "yes" or "md" to indicate that a --traditional, non-partitionable md array should be created, or "mdp", --"part" or "partition" to indicate that a partitionable md array (only --available in linux 2.6 and later) should be used. This later set can --also have a number appended to indicate how many partitions to create --device files for, e.g. --.BR auto=mdp5 . --The default is 4. -- --.TP --.B bitmap= --The option specifies a file in which a write-intent bitmap should be --found. When assembling the array, --.I mdadm --will provide this file to the --.B md --driver as the bitmap file. This has the same function as the --.B \-\-bitmap\-file --option to --.BR \-\-assemble . -- --.TP --.B metadata= --Specify the metadata format that the array has. This is mainly --recognised for comparability with the output of --.BR "mdadm \-Es" . -- --.TP --.B container= --Specify that this array is a member array of some container. The --value given can be either a path name in /dev, or a UUID of the --container array. -- --.TP --.B member= --Specify that this array is a member array of some container. Each --type of container has some way to enumerate member arrays, often a --simple sequence number. The value identifies which member of a --container the array is. It will usually accompany a "container=" word. --.RE -- --.TP --.B MAILADDR --The --.B mailaddr --line gives an E-mail address that alerts should be --sent to when --.I mdadm --is running in --.B \-\-monitor --mode (and was given the --.B \-\-scan --option). There should only be one --.B MAILADDR --line and it should have only one address. Any subsequent addresses --are silently ignored. -- --.TP --.B MAILFROM --The --.B mailfrom --line (which can only be abbreviated to at least 5 characters) gives an --address to appear in the "From" address for alert mails. This can be --useful if you want to explicitly set a domain, as the default from --address is "root" with no domain. All words on this line are --catenated with spaces to form the address. -- --Note that this value cannot be set via the --.I mdadm --commandline. It is only settable via the config file. -- --.TP --.B PROGRAM --The --.B program --line gives the name of a program to be run when --.B "mdadm \-\-monitor" --detects potentially interesting events on any of the arrays that it --is monitoring. This program gets run with two or three arguments, they --being the Event, the md device, and possibly the related component --device. -- --There should only be one --.B program --line and it should be give only one program. -- -- --.TP --.B CREATE --The --.B create --line gives default values to be used when creating arrays, new members --of arrays, and device entries for arrays. --These include: -- --.RS 4 --.TP --.B owner= --.TP --.B group= --These can give user/group ids or names to use instead of system --defaults (root/wheel or root/disk). --.TP --.B mode= --An octal file mode such as 0660 can be given to override the default --of 0600. --.TP --.B auto= --This corresponds to the --.B \-\-auto --flag to mdadm. Give --.BR yes , --.BR md , --.BR mdp , --.B part --\(em possibly followed by a number of partitions \(em to indicate how --missing device entries should be created. -- --.TP --.B metadata= --The name of the metadata format to use if none is explicitly given. --This can be useful to impose a system-wide default of version-1 superblocks. -- --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- --.TP --.B names=yes --Since Linux 2.6.29 it has been possible to create --.B md --devices with a name like --.B md_home --rather than just a number, like --.BR md3 . --.I mdadm --will use the numeric alternative by default as other tools that interact --with md arrays may expect only numbers. --If --.B names=yes --is given in --.I mdadm.conf --then --.I mdadm --will use a name when appropriate. --If --.B names=no --is given, then non-numeric --.I md --device names will not be used even if the default changes in a future --release of --.IR mdadm . -- --.TP --.B bbl=no --By default, --.I mdadm --will reserve space for a bad block list (bbl) on all devices --included in or added to any array that supports them. Setting --.B bbl=no --will prevent this, so newly added devices will not have a bad --block log. --.RE -- --.TP --.B HOMEHOST --The --.B homehost --line gives a default value for the --.B \-\-homehost= --option to mdadm. There should normally be only one other word on the line. --It should either be a host name, or one of the special words --.BR , --.B --and --.BR . --If --.B --is given, then the --.BR gethostname ( 2 ) --systemcall is used to get the host name. This is the default. -- --If --.B --is given, then a flag is set so that when arrays are being --auto-assembled the checking of the recorded --.I homehost --is disabled. --If --.B --is given it is also possible to give an explicit name which will be --used when creating arrays. This is the only case when there can be --more that one other word on the --.B HOMEHOST --line. If there are other words, or other --.B HOMEHOST --lines, they are silently ignored. -- --If --.B --is given, then the default of using --.BR gethostname ( 2 ) --is over-ridden and no homehost name is assumed. -- --When arrays are created, this host name will be stored in the --metadata. When arrays are assembled using auto-assembly, arrays which --do not record the correct homehost name in their metadata will be --assembled using a "foreign" name. A "foreign" name alway ends with a --digit string preceded by an underscore to differentiate it --from any possible local name. e.g. --.B /dev/md/1_1 --or --.BR /dev/md/home_0 . --.TP --.B AUTO --A list of names of metadata format can be given, each preceded by a --plus or minus sign. Also the word --.I homehost --is allowed as is --.I all --preceded by plus or minus sign. --.I all --is usually last. -- --When --.I mdadm --is auto-assembling an array, either via --.I \-\-assemble --or --.I \-\-incremental --and it finds metadata of a given type, it checks that metadata type --against those listed in this line. The first match wins, where --.I all --matches anything. --If a match is found that was preceded by a plus sign, the auto --assembly is allowed. If the match was preceded by a minus sign, the --auto assembly is disallowed. If no match is found, the auto assembly --is allowed. -- --If the metadata indicates that the array was created for --.I this --host, and the word --.I homehost --appears before any other match, then the array is treated as a valid --candidate for auto-assembly. -- --This can be used to disable all auto-assembly (so that only arrays --explicitly listed in mdadm.conf or on the command line are assembled), --or to disable assembly of certain metadata types which might be --handled by other software. It can also be used to disable assembly of --all foreign arrays - normally such arrays are assembled but given a --non-deterministic name in --.BR /dev/md/ . -- --The known metadata types are --.BR 0.90 , --.BR 1.x , --.BR ddf , --.BR imsm . -- --.B AUTO --should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -- --.TP --.B POLICY --This is used to specify what automatic behavior is allowed on devices --newly appearing in the system and provides a way of marking spares that can --be moved to other arrays as well as the migration domains. --.I Domain --can be defined through --.I policy --line by specifying a domain name for a number of paths from --.BR /dev/disk/by-path/ . --A device may belong to several domains. The domain of an array is a union --of domains of all devices in that array. A spare can be automatically --moved from one array to another if the set of the destination array's --.I domains --contains all the --.I domains --of the new disk or if both arrays have the same --.IR spare-group . -- --To update hot plug configuration it is necessary to execute --.B mdadm \-\-udev\-rules --command after changing the config file -- --Keywords used in the --.I POLICY --line and supported values are: -- --.RS 4 --.TP --.B domain= --any arbitrary string --.TP --.B metadata= --0.9 1.x ddf or imsm --.TP --.B path= --file glob matching anything from --.B /dev/disk/by-path --.TP --.B type= --either --.B disk --or --.BR part . --.TP --.B action= --include, re-add, spare, spare-same-slot, or force-spare --.TP --.B auto= --yes, no, or homehost. -- --.P --The --.I action --item determines the automatic behavior allowed for devices matching the --.I path --and --.I type --in the same line. If a device matches several lines with different --.I actions --then the most permissive will apply. The ordering of policy lines --is irrelevant to the end result. --.TP --.B include --allows adding a disk to an array if metadata on that disk matches that array --.TP --.B re\-add --will include the device in the array if it appears to be a current member --or a member that was recently removed and the array has a --write-intent-bitmap to allow the --.B re\-add --functionality. --.TP --.B spare --as above and additionally: if the device is bare it can --become a spare if there is any array that it is a candidate for based --on domains and metadata. --.TP --.B spare\-same\-slot --as above and additionally if given slot was used by an array that went --degraded recently and the device plugged in has no metadata then it will --be automatically added to that array (or it's container) --.TP --.B force\-spare --as above and the disk will become a spare in remaining cases --.RE -- --.TP --.B PART-POLICY --This is similar to --.B POLICY --and accepts the same keyword assignments. It allows a consistent set --of policies to applied to each of the partitions of a device. -- --A --.B PART-POLICY --line should set --.I type=disk --and identify the path to one or more disk devices. Each partition on --these disks will be treated according to the --.I action= --setting from this line. If a --.I domain --is set in the line, then the domain associated with each patition will --be based on the domain, but with --.RB \(dq -part N\(dq --appended, when N is the partition number for the partition that was --found. -- --.TP --.B SYSFS --The --.B SYSFS --line lists custom values of MD device's sysfs attributes which will be --stored in sysfs after the array is assembled. Multiple lines are allowed and each --line has to contain the uuid or the name of the device to which it relates. --.RS 4 --.TP --.B uuid= --hexadecimal identifier of MD device. This has to match the uuid stored in the --superblock. --.TP --.B name= --name of the MD device as was given to --.I mdadm --when the array was created. It will be ignored if --.B uuid --is not empty. --.RE -- --.TP --.B MONITORDELAY --The --.B monitordelay --line gives a delay in seconds --.I mdadm --shall wait before pooling md arrays --when --.I mdadm --is running in --.B \-\-monitor --mode. --.B \-d/\-\-delay --command line argument takes precedence over the config file -- --.SH EXAMPLE --DEVICE /dev/sd[bcdjkl]1 --.br --DEVICE /dev/hda1 /dev/hdb1 -- --# /dev/md0 is known by its UUID. --.br --ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 --.br --# /dev/md1 contains all devices with a minor number of --.br --# 1 in the superblock. --.br --ARRAY /dev/md1 superminor=1 --.br --# /dev/md2 is made from precisely these two devices --.br --ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -- --# /dev/md4 and /dev/md5 are a spare-group and spares --.br --# can be moved between them --.br --ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df --.br -- spare\-group=group1 --.br --ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 --.br -- spare\-group=group1 --.br --# /dev/md/home is created if need to be a partitionable md array --.br --# any spare device number is allocated. --.br --ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b --.br -- auto=part --.br --# The name of this array contains a space. --.br --ARRAY /dev/md9 name='Data Storage' --.sp --POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* --.br -- action=spare --.br --POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* --.br -- action=include --.br --# One domain comprising of devices attached to specified paths is defined. --.br --# Bare device matching first path will be made an imsm spare on hot plug. --.br --# If more than one array is created on devices belonging to domain1 and --.br --# one of them becomes degraded, then any imsm spare matching any path for --.br --# given domain name can be migrated. --.br --MAILADDR root@mydomain.tld --.br --PROGRAM /usr/sbin/handle\-mdadm\-events --.br --CREATE group=system mode=0640 auto=part\-8 --.br --HOMEHOST --.br --AUTO +1.x homehost \-all --.br --SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 --.br --SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 --sync_speed_max=1000000 --.br --MONITORDELAY 60 -- --.SH SEE ALSO --.BR mdadm (8), --.BR md (4). -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -new file mode 100644 -index 00000000..83edd008 ---- /dev/null -+++ b/mdadm.conf.5.in -@@ -0,0 +1,706 @@ -+.\" Copyright Neil Brown and others. -+.\" This program is free software; you can redistribute it and/or modify -+.\" it under the terms of the GNU General Public License as published by -+.\" the Free Software Foundation; either version 2 of the License, or -+.\" (at your option) any later version. -+.\" See file COPYING in distribution for details. -+.TH MDADM.CONF 5 -+.SH NAME -+mdadm.conf \- configuration for management of Software RAID with mdadm -+.SH SYNOPSIS -+{CONFFILE} -+.SH DESCRIPTION -+.PP -+.I mdadm -+is a tool for creating, managing, and monitoring RAID devices using the -+.B md -+driver in Linux. -+.PP -+Some common tasks, such as assembling all arrays, can be simplified -+by describing the devices and arrays in this configuration file. -+ -+.SS SYNTAX -+The file should be seen as a collection of words separated by white -+space (space, tab, or newline). -+Any word that beings with a hash sign (#) starts a comment and that -+word together with the remainder of the line is ignored. -+ -+Spaces can be included in a word using quotation characters. Either -+single quotes -+.RB ( ' ) -+or double quotes (\fB"\fP) -+may be used. All the characters from one quotation character to -+next identical character are protected and will not be used to -+separate words to start new quoted strings. To include a single quote -+it must be between double quotes. To include a double quote it must -+be between single quotes. -+ -+Any line that starts with white space (space or tab) is treated as -+though it were a continuation of the previous line. -+ -+Empty lines are ignored, but otherwise each (non continuation) line -+must start with a keyword as listed below. The keywords are case -+insensitive and can be abbreviated to 3 characters. -+ -+The keywords are: -+.TP -+.B DEVICE -+A -+.B device -+line lists the devices (whole devices or partitions) that might contain -+a component of an MD array. When looking for the components of an -+array, -+.I mdadm -+will scan these devices (or any devices listed on the command line). -+ -+The -+.B device -+line may contain a number of different devices (separated by spaces) -+and each device name can contain wild cards as defined by -+.BR glob (7). -+ -+Also, there may be several device lines present in the file. -+ -+Alternatively, a -+.B device -+line can contain either or both of the words -+.B containers -+and -+.BR partitions . -+The word -+.B containers -+will cause -+.I mdadm -+to look for assembled CONTAINER arrays and included them as a source -+for assembling further arrays. -+ -+The word -+.I partitions -+will cause -+.I mdadm -+to read -+.I /proc/partitions -+and include all devices and partitions found therein. -+.I mdadm -+does not use the names from -+.I /proc/partitions -+but only the major and minor device numbers. It scans -+.I /dev -+to find the name that matches the numbers. -+ -+If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+ -+For example: -+.IP -+DEVICE /dev/hda* /dev/hdc* -+.br -+DEV /dev/sd* -+.br -+DEVICE /dev/disk/by-path/pci* -+.br -+DEVICE partitions -+ -+.TP -+.B ARRAY -+The ARRAY lines identify actual arrays. The second word on the line -+may be the name of the device where the array is normally -+assembled, such as -+.B /dev/md1 -+or -+.BR /dev/md/backup . -+If the name does not start with a slash -+.RB (' / '), -+it is treated as being in -+.BR /dev/md/ . -+Alternately the word -+.B -+(complete with angle brackets) can be given in which case any array -+which matches the rest of the line will never be automatically assembled. -+If no device name is given, -+.I mdadm -+will use various heuristics to determine an appropriate name. -+ -+Subsequent words identify the array, or identify the array as a member -+of a group. If multiple identities are given, -+then a component device must match ALL identities to be considered a -+match. Each identity word has a tag, and equals sign, and some value. -+The tags are: -+.RS 4 -+.TP -+.B uuid= -+The value should be a 128 bit uuid in hexadecimal, with punctuation -+interspersed if desired. This must match the uuid stored in the -+superblock. -+.TP -+.B name= -+The value should be a simple textual name as was given to -+.I mdadm -+when the array was created. This must match the name stored in the -+superblock on a device for that device to be included in the array. -+Not all superblock formats support names. -+.TP -+.B super\-minor= -+The value is an integer which indicates the minor number that was -+stored in the superblock when the array was created. When an array is -+created as /dev/mdX, then the minor number X is stored. -+.TP -+.B devices= -+The value is a comma separated list of device names or device name -+patterns. -+Only devices with names which match one entry in the list will be used -+to assemble the array. Note that the devices -+listed there must also be listed on a DEVICE line. -+.TP -+.B level= -+The value is a RAID level. This is not normally used to -+identify an array, but is supported so that the output of -+ -+.B "mdadm \-\-examine \-\-scan" -+ -+can be use directly in the configuration file. -+.TP -+.B num\-devices= -+The value is the number of devices in a complete active array. As with -+.B level= -+this is mainly for compatibility with the output of -+ -+.BR "mdadm \-\-examine \-\-scan" . -+ -+.TP -+.B spares= -+The value is a number of spare devices to expect the array to have. -+The sole use of this keyword and value is as follows: -+.B mdadm \-\-monitor -+will report an array if it is found to have fewer than this number of -+spares when -+.B \-\-monitor -+starts or when -+.B \-\-oneshot -+is used. -+ -+.TP -+.B spare\-group= -+The value is a textual name for a group of arrays. All arrays with -+the same -+.B spare\-group -+name are considered to be part of the same group. The significance of -+a group of arrays is that -+.I mdadm -+will, when monitoring the arrays, move a spare drive from one array in -+a group to another array in that group if the first array had a failed -+or missing drive but no spare. -+ -+.TP -+.B auto= -+This option is rarely needed with mdadm-3.0, particularly if use with -+the Linux kernel v2.6.28 or later. -+It tells -+.I mdadm -+whether to use partitionable array or non-partitionable arrays and, -+in the absence of -+.IR udev , -+how many partition devices to create. From 2.6.28 all md array -+devices are partitionable, hence this option is not needed. -+ -+The value of this option can be "yes" or "md" to indicate that a -+traditional, non-partitionable md array should be created, or "mdp", -+"part" or "partition" to indicate that a partitionable md array (only -+available in linux 2.6 and later) should be used. This later set can -+also have a number appended to indicate how many partitions to create -+device files for, e.g. -+.BR auto=mdp5 . -+The default is 4. -+ -+.TP -+.B bitmap= -+The option specifies a file in which a write-intent bitmap should be -+found. When assembling the array, -+.I mdadm -+will provide this file to the -+.B md -+driver as the bitmap file. This has the same function as the -+.B \-\-bitmap\-file -+option to -+.BR \-\-assemble . -+ -+.TP -+.B metadata= -+Specify the metadata format that the array has. This is mainly -+recognised for comparability with the output of -+.BR "mdadm \-Es" . -+ -+.TP -+.B container= -+Specify that this array is a member array of some container. The -+value given can be either a path name in /dev, or a UUID of the -+container array. -+ -+.TP -+.B member= -+Specify that this array is a member array of some container. Each -+type of container has some way to enumerate member arrays, often a -+simple sequence number. The value identifies which member of a -+container the array is. It will usually accompany a "container=" word. -+.RE -+ -+.TP -+.B MAILADDR -+The -+.B mailaddr -+line gives an E-mail address that alerts should be -+sent to when -+.I mdadm -+is running in -+.B \-\-monitor -+mode (and was given the -+.B \-\-scan -+option). There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. -+ -+.TP -+.B MAILFROM -+The -+.B mailfrom -+line (which can only be abbreviated to at least 5 characters) gives an -+address to appear in the "From" address for alert mails. This can be -+useful if you want to explicitly set a domain, as the default from -+address is "root" with no domain. All words on this line are -+catenated with spaces to form the address. -+ -+Note that this value cannot be set via the -+.I mdadm -+commandline. It is only settable via the config file. -+ -+.TP -+.B PROGRAM -+The -+.B program -+line gives the name of a program to be run when -+.B "mdadm \-\-monitor" -+detects potentially interesting events on any of the arrays that it -+is monitoring. This program gets run with two or three arguments, they -+being the Event, the md device, and possibly the related component -+device. -+ -+There should only be one -+.B program -+line and it should be give only one program. -+ -+ -+.TP -+.B CREATE -+The -+.B create -+line gives default values to be used when creating arrays, new members -+of arrays, and device entries for arrays. -+These include: -+ -+.RS 4 -+.TP -+.B owner= -+.TP -+.B group= -+These can give user/group ids or names to use instead of system -+defaults (root/wheel or root/disk). -+.TP -+.B mode= -+An octal file mode such as 0660 can be given to override the default -+of 0600. -+.TP -+.B auto= -+This corresponds to the -+.B \-\-auto -+flag to mdadm. Give -+.BR yes , -+.BR md , -+.BR mdp , -+.B part -+\(em possibly followed by a number of partitions \(em to indicate how -+missing device entries should be created. -+ -+.TP -+.B metadata= -+The name of the metadata format to use if none is explicitly given. -+This can be useful to impose a system-wide default of version-1 superblocks. -+ -+.TP -+.B symlinks=no -+Normally when creating devices in -+.B /dev/md/ -+.I mdadm -+will create a matching symlink from -+.B /dev/ -+with a name starting -+.B md -+or -+.BR md_ . -+Give -+.B symlinks=no -+to suppress this symlink creation. -+ -+.TP -+.B names=yes -+Since Linux 2.6.29 it has been possible to create -+.B md -+devices with a name like -+.B md_home -+rather than just a number, like -+.BR md3 . -+.I mdadm -+will use the numeric alternative by default as other tools that interact -+with md arrays may expect only numbers. -+If -+.B names=yes -+is given in -+.I mdadm.conf -+then -+.I mdadm -+will use a name when appropriate. -+If -+.B names=no -+is given, then non-numeric -+.I md -+device names will not be used even if the default changes in a future -+release of -+.IR mdadm . -+ -+.TP -+.B bbl=no -+By default, -+.I mdadm -+will reserve space for a bad block list (bbl) on all devices -+included in or added to any array that supports them. Setting -+.B bbl=no -+will prevent this, so newly added devices will not have a bad -+block log. -+.RE -+ -+.TP -+.B HOMEHOST -+The -+.B homehost -+line gives a default value for the -+.B \-\-homehost= -+option to mdadm. There should normally be only one other word on the line. -+It should either be a host name, or one of the special words -+.BR , -+.B -+and -+.BR . -+If -+.B -+is given, then the -+.BR gethostname ( 2 ) -+systemcall is used to get the host name. This is the default. -+ -+If -+.B -+is given, then a flag is set so that when arrays are being -+auto-assembled the checking of the recorded -+.I homehost -+is disabled. -+If -+.B -+is given it is also possible to give an explicit name which will be -+used when creating arrays. This is the only case when there can be -+more that one other word on the -+.B HOMEHOST -+line. If there are other words, or other -+.B HOMEHOST -+lines, they are silently ignored. -+ -+If -+.B -+is given, then the default of using -+.BR gethostname ( 2 ) -+is over-ridden and no homehost name is assumed. -+ -+When arrays are created, this host name will be stored in the -+metadata. When arrays are assembled using auto-assembly, arrays which -+do not record the correct homehost name in their metadata will be -+assembled using a "foreign" name. A "foreign" name alway ends with a -+digit string preceded by an underscore to differentiate it -+from any possible local name. e.g. -+.B /dev/md/1_1 -+or -+.BR /dev/md/home_0 . -+.TP -+.B AUTO -+A list of names of metadata format can be given, each preceded by a -+plus or minus sign. Also the word -+.I homehost -+is allowed as is -+.I all -+preceded by plus or minus sign. -+.I all -+is usually last. -+ -+When -+.I mdadm -+is auto-assembling an array, either via -+.I \-\-assemble -+or -+.I \-\-incremental -+and it finds metadata of a given type, it checks that metadata type -+against those listed in this line. The first match wins, where -+.I all -+matches anything. -+If a match is found that was preceded by a plus sign, the auto -+assembly is allowed. If the match was preceded by a minus sign, the -+auto assembly is disallowed. If no match is found, the auto assembly -+is allowed. -+ -+If the metadata indicates that the array was created for -+.I this -+host, and the word -+.I homehost -+appears before any other match, then the array is treated as a valid -+candidate for auto-assembly. -+ -+This can be used to disable all auto-assembly (so that only arrays -+explicitly listed in mdadm.conf or on the command line are assembled), -+or to disable assembly of certain metadata types which might be -+handled by other software. It can also be used to disable assembly of -+all foreign arrays - normally such arrays are assembled but given a -+non-deterministic name in -+.BR /dev/md/ . -+ -+The known metadata types are -+.BR 0.90 , -+.BR 1.x , -+.BR ddf , -+.BR imsm . -+ -+.B AUTO -+should be given at most once. Subsequent lines are silently ignored. -+Thus an earlier config file in a config directory will over-ride -+the setting in a later config file. -+ -+.TP -+.B POLICY -+This is used to specify what automatic behavior is allowed on devices -+newly appearing in the system and provides a way of marking spares that can -+be moved to other arrays as well as the migration domains. -+.I Domain -+can be defined through -+.I policy -+line by specifying a domain name for a number of paths from -+.BR /dev/disk/by-path/ . -+A device may belong to several domains. The domain of an array is a union -+of domains of all devices in that array. A spare can be automatically -+moved from one array to another if the set of the destination array's -+.I domains -+contains all the -+.I domains -+of the new disk or if both arrays have the same -+.IR spare-group . -+ -+To update hot plug configuration it is necessary to execute -+.B mdadm \-\-udev\-rules -+command after changing the config file -+ -+Keywords used in the -+.I POLICY -+line and supported values are: -+ -+.RS 4 -+.TP -+.B domain= -+any arbitrary string -+.TP -+.B metadata= -+0.9 1.x ddf or imsm -+.TP -+.B path= -+file glob matching anything from -+.B /dev/disk/by-path -+.TP -+.B type= -+either -+.B disk -+or -+.BR part . -+.TP -+.B action= -+include, re-add, spare, spare-same-slot, or force-spare -+.TP -+.B auto= -+yes, no, or homehost. -+ -+.P -+The -+.I action -+item determines the automatic behavior allowed for devices matching the -+.I path -+and -+.I type -+in the same line. If a device matches several lines with different -+.I actions -+then the most permissive will apply. The ordering of policy lines -+is irrelevant to the end result. -+.TP -+.B include -+allows adding a disk to an array if metadata on that disk matches that array -+.TP -+.B re\-add -+will include the device in the array if it appears to be a current member -+or a member that was recently removed and the array has a -+write-intent-bitmap to allow the -+.B re\-add -+functionality. -+.TP -+.B spare -+as above and additionally: if the device is bare it can -+become a spare if there is any array that it is a candidate for based -+on domains and metadata. -+.TP -+.B spare\-same\-slot -+as above and additionally if given slot was used by an array that went -+degraded recently and the device plugged in has no metadata then it will -+be automatically added to that array (or it's container) -+.TP -+.B force\-spare -+as above and the disk will become a spare in remaining cases -+.RE -+ -+.TP -+.B PART-POLICY -+This is similar to -+.B POLICY -+and accepts the same keyword assignments. It allows a consistent set -+of policies to applied to each of the partitions of a device. -+ -+A -+.B PART-POLICY -+line should set -+.I type=disk -+and identify the path to one or more disk devices. Each partition on -+these disks will be treated according to the -+.I action= -+setting from this line. If a -+.I domain -+is set in the line, then the domain associated with each patition will -+be based on the domain, but with -+.RB \(dq -part N\(dq -+appended, when N is the partition number for the partition that was -+found. -+ -+.TP -+.B SYSFS -+The -+.B SYSFS -+line lists custom values of MD device's sysfs attributes which will be -+stored in sysfs after the array is assembled. Multiple lines are allowed and each -+line has to contain the uuid or the name of the device to which it relates. -+.RS 4 -+.TP -+.B uuid= -+hexadecimal identifier of MD device. This has to match the uuid stored in the -+superblock. -+.TP -+.B name= -+name of the MD device as was given to -+.I mdadm -+when the array was created. It will be ignored if -+.B uuid -+is not empty. -+.RE -+ -+.TP -+.B MONITORDELAY -+The -+.B monitordelay -+line gives a delay in seconds -+.I mdadm -+shall wait before pooling md arrays -+when -+.I mdadm -+is running in -+.B \-\-monitor -+mode. -+.B \-d/\-\-delay -+command line argument takes precedence over the config file -+ -+.SH EXAMPLE -+DEVICE /dev/sd[bcdjkl]1 -+.br -+DEVICE /dev/hda1 /dev/hdb1 -+ -+# /dev/md0 is known by its UUID. -+.br -+ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 -+.br -+# /dev/md1 contains all devices with a minor number of -+.br -+# 1 in the superblock. -+.br -+ARRAY /dev/md1 superminor=1 -+.br -+# /dev/md2 is made from precisely these two devices -+.br -+ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -+ -+# /dev/md4 and /dev/md5 are a spare-group and spares -+.br -+# can be moved between them -+.br -+ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df -+.br -+ spare\-group=group1 -+.br -+ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 -+.br -+ spare\-group=group1 -+.br -+# /dev/md/home is created if need to be a partitionable md array -+.br -+# any spare device number is allocated. -+.br -+ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b -+.br -+ auto=part -+.br -+# The name of this array contains a space. -+.br -+ARRAY /dev/md9 name='Data Storage' -+.sp -+POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* -+.br -+ action=spare -+.br -+POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* -+.br -+ action=include -+.br -+# One domain comprising of devices attached to specified paths is defined. -+.br -+# Bare device matching first path will be made an imsm spare on hot plug. -+.br -+# If more than one array is created on devices belonging to domain1 and -+.br -+# one of them becomes degraded, then any imsm spare matching any path for -+.br -+# given domain name can be migrated. -+.br -+MAILADDR root@mydomain.tld -+.br -+PROGRAM /usr/sbin/handle\-mdadm\-events -+.br -+CREATE group=system mode=0640 auto=part\-8 -+.br -+HOMEHOST -+.br -+AUTO +1.x homehost \-all -+.br -+SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 -+.br -+SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 -+sync_speed_max=1000000 -+.br -+MONITORDELAY 60 -+ -+.SH SEE ALSO -+.BR mdadm (8), -+.BR md (4). --- -2.38.1 - diff --git a/SOURCES/0007-mdadm-Update-ReadMe.patch b/SOURCES/0007-mdadm-Update-ReadMe.patch deleted file mode 100644 index a143a22..0000000 --- a/SOURCES/0007-mdadm-Update-ReadMe.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:05 +0100 -Subject: [PATCH 07/83] mdadm: Update ReadMe - -Instead of hardcoded config file path give reference to config manual. - -Add missing monitordelay and homecluster parameters. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 81399765..8f873c48 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -613,7 +613,6 @@ char Help_incr[] = - ; - - char Help_config[] = --"The /etc/mdadm.conf config file:\n\n" - " The config file contains, apart from blank lines and comment lines that\n" - " start with a hash(#), array lines, device lines, and various\n" - " configuration lines.\n" -@@ -636,10 +635,12 @@ char Help_config[] = - " than a device must match all of them to be considered.\n" - "\n" - " Other configuration lines include:\n" --" mailaddr, mailfrom, program used for --monitor mode\n" --" create, auto used when creating device names in /dev\n" --" homehost, policy, part-policy used to guide policy in various\n" --" situations\n" -+" mailaddr, mailfrom, program, monitordelay used for --monitor mode\n" -+" create, auto used when creating device names in /dev\n" -+" homehost, homecluster, policy, part-policy used to guide policy in various\n" -+" situations\n" -+"\n" -+"For more details see mdadm.conf(5).\n" - "\n" - ; - --- -2.38.1 - diff --git a/SOURCES/0007-mdadm-signal_s-init-variables.patch b/SOURCES/0007-mdadm-signal_s-init-variables.patch new file mode 100644 index 0000000..6be72c2 --- /dev/null +++ b/SOURCES/0007-mdadm-signal_s-init-variables.patch @@ -0,0 +1,35 @@ +From 38cb95dd28fa790ae6d90b169f1fd2b1d09a02f2 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:08 +0100 +Subject: [PATCH 07/41] mdadm: signal_s() init variables + +Init sigaction structs in signal_s(). +This approach might throw warnings for GCC 4.x and lower. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 1f28b3e7..75c887e4 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1856,11 +1856,10 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) + */ + static inline sighandler_t signal_s(int sig, sighandler_t handler) + { +- struct sigaction new_act; +- struct sigaction old_act; ++ struct sigaction new_act = {0}; ++ struct sigaction old_act = {0}; + + new_act.sa_handler = handler; +- new_act.sa_flags = 0; + + if (sigaction(sig, &new_act, &old_act) == 0) + return old_act.sa_handler; +-- +2.40.1 + diff --git a/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch b/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch new file mode 100644 index 0000000..2ca98c4 --- /dev/null +++ b/SOURCES/0008-Monitor-open-file-before-check-in-check_one_sharer.patch @@ -0,0 +1,48 @@ +From b7d7837128e90c8b496ebc3d88eda1a8ff477392 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:09 +0100 +Subject: [PATCH 08/41] Monitor: open file before check in check_one_sharer() + +Open file before performing checks in check_one_sharer() to avoid +file tampering. +Remove redundant access check. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Monitor.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 824a69fc..7cee95d4 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -451,20 +451,17 @@ static int check_one_sharer(int scan) + return 2; + } + +- if (access(AUTOREBUILD_PID_PATH, F_OK) != 0) +- return 0; +- +- if (!is_file(AUTOREBUILD_PID_PATH)) { +- pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); +- return 2; +- } +- + fp = fopen(AUTOREBUILD_PID_PATH, "r"); + if (!fp) { + pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); + return 2; + } + ++ if (!is_file(AUTOREBUILD_PID_PATH)) { ++ pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); ++ return 2; ++ } ++ + if (fscanf(fp, "%d", &pid) != 1) { + pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); + fclose(fp); +-- +2.40.1 + diff --git a/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch b/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch deleted file mode 100644 index 0109e9a..0000000 --- a/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:06 +0100 -Subject: [PATCH 08/83] mdadm: Update config man regarding default files and - multi-keyword behavior - -Simplify default and alternative config file and directory location references -from mdadm(8) as references to mdadm.conf(5). Add FILE section in config man -and explain order and conditions in which default and alternative config files -and directories are used. - -Update config man behavior regarding parsing order when multiple keywords/config -files are involved. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 30 +++++++++-------------- - mdadm.conf.5.in | 65 ++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 71 insertions(+), 24 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 8b21ffd4..0be02e4a 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. Default is to use --.B {CONFFILE} --and --.BR {CONFFILE}.d , --or if those are missing then --.B {CONFFILE2} --and --.BR {CONFFILE2}.d . -+Specify the config file or directory. If not specified, default config file -+and default conf.d directory will be used. See -+.BR mdadm.conf (5) -+for more details. -+ - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2013,11 +2010,9 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, --.B {CONFFILE} --or --.B {CONFFILE2} --is used. -+In the later case, default config file is used. See -+.BR mdadm.conf (5) -+for more details. - - If - .B \-\-scan -@@ -3346,16 +3341,15 @@ on Monitor mode. - - .SS {CONFFILE} (or {CONFFILE2}) - --The config file lists which devices may be scanned to see if --they contain MD super block, and gives identifying information --(e.g. UUID) about known MD arrays. See -+Default config file. See - .BR mdadm.conf (5) - for more details. - - .SS {CONFFILE}.d (or {CONFFILE2}.d) - --A directory containing configuration files which are read in lexical --order. -+Default directory containing configuration files. See -+.BR mdadm.conf (5) -+for more details. - - .SS {MAP_PATH} - When -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index 83edd008..dd331a6a 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -88,7 +88,8 @@ but only the major and minor device numbers. It scans - .I /dev - to find the name that matches the numbers. - --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+If no DEVICE line is present in any config file, -+then "DEVICE partitions containers" is assumed. - - For example: - .IP -@@ -272,6 +273,10 @@ catenated with spaces to form the address. - Note that this value cannot be set via the - .I mdadm - commandline. It is only settable via the config file. -+There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. - - .TP - .B PROGRAM -@@ -286,7 +291,8 @@ device. - - There should only be one - .B program --line and it should be give only one program. -+line and it should be given only one program. Any subsequent programs -+are silently ignored. - - - .TP -@@ -295,7 +301,14 @@ The - .B create - line gives default values to be used when creating arrays, new members - of arrays, and device entries for arrays. --These include: -+ -+There should only be one -+.B create -+line. Any subsequent lines will override the previous settings. -+ -+Keywords used in the -+.I CREATE -+line and supported values are: - - .RS 4 - .TP -@@ -475,8 +488,8 @@ The known metadata types are - - .B AUTO - should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -+Thus a later config file in a config directory will not overwrite -+the setting in an earlier config file. - - .TP - .B POLICY -@@ -594,6 +607,7 @@ The - line lists custom values of MD device's sysfs attributes which will be - stored in sysfs after the array is assembled. Multiple lines are allowed and each - line has to contain the uuid or the name of the device to which it relates. -+Lines are applied in reverse order. - .RS 4 - .TP - .B uuid= -@@ -621,7 +635,46 @@ is running in - .B \-\-monitor - mode. - .B \-d/\-\-delay --command line argument takes precedence over the config file -+command line argument takes precedence over the config file. -+ -+If multiple -+.B MINITORDELAY -+lines are provided, only first non-zero value is considered. -+ -+.SH FILES -+ -+.SS {CONFFILE} -+ -+The default config file location, used when -+.I mdadm -+is running without --config option. -+ -+.SS {CONFFILE}.d -+ -+The default directory with config files. Used when -+.I mdadm -+is running without --config option, after successful reading of the -+.B {CONFFILE} -+default config file. Files in that directory -+are read in lexical order. -+ -+ -+.SS {CONFFILE2} -+ -+Alternative config file that is read, when -+.I mdadm -+is running without --config option and the -+.B {CONFFILE} -+default config file was not opened successfully. -+ -+.SS {CONFFILE2}.d -+ -+The alternative directory with config files. Used when -+.I mdadm -+is runninng without --config option, after reading the -+.B {CONFFILE2} -+alternative config file whether it was successful or not. Files in -+that directory are read in lexical order. - - .SH EXAMPLE - DEVICE /dev/sd[bcdjkl]1 --- -2.38.1 - diff --git a/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch b/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch new file mode 100644 index 0000000..437143e --- /dev/null +++ b/SOURCES/0009-Grow-remove-dead-condition-in-Grow_reshape.patch @@ -0,0 +1,34 @@ +From e44d13f466e30c018887cd5aaf1212ed9f510813 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:10 +0100 +Subject: [PATCH 09/41] Grow: remove dead condition in Grow_reshape() + +Remove dead "if" condition from Grow_reshape(). Sysfs read check is +performed earlier in the code. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 5498e54f..c69a342d 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2098,11 +2098,7 @@ int Grow_reshape(char *devname, int fd, + /* got truncated to 32bit, write to + * component_size instead + */ +- if (sra) +- rv = sysfs_set_num(sra, NULL, +- "component_size", s->size); +- else +- rv = -1; ++ rv = sysfs_set_num(sra, NULL, "component_size", s->size); + } else { + rv = md_set_array_info(fd, &array); + +-- +2.40.1 + diff --git a/SOURCES/0009-mdadm-Update-config-manual.patch b/SOURCES/0009-mdadm-Update-config-manual.patch deleted file mode 100644 index 08599d5..0000000 --- a/SOURCES/0009-mdadm-Update-config-manual.patch +++ /dev/null @@ -1,45 +0,0 @@ -From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:07 +0100 -Subject: [PATCH 09/83] mdadm: Update config manual - -Add missing HOMECLUSTER keyword description. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.conf.5.in | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index dd331a6a..cd4e6a9d 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -439,6 +439,23 @@ from any possible local name. e.g. - .B /dev/md/1_1 - or - .BR /dev/md/home_0 . -+ -+.TP -+.B HOMECLUSTER -+The -+.B homcluster -+line gives a default value for the -+.B \-\-homecluster= -+option to mdadm. It specifies the cluster name for the md device. -+The md device can be assembled only on the cluster which matches -+the name specified. If -+.B homcluster -+is not provided, mdadm tries to detect the cluster name automatically. -+ -+There should only be one -+.B homecluster -+line. Any subsequent lines will be silently ignored. -+ - .TP - .B AUTO - A list of names of metadata format can be given, each preceded by a --- -2.38.1 - diff --git a/SOURCES/0010-Create-Build-use-default_layout.patch b/SOURCES/0010-Create-Build-use-default_layout.patch deleted file mode 100644 index 7f9791b..0000000 --- a/SOURCES/0010-Create-Build-use-default_layout.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:32 +0100 -Subject: [PATCH 10/83] Create, Build: use default_layout() - -This code is duplicated for Build mode so make default_layout() extern -and use it. Simplify the function structure. - -It introduced change for Build mode, now for raid0 RAID0_ORIG_LAYOUT -will be returned same as for Create. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Build.c | 23 +------------------ - Create.c | 67 ++++++++++++++++++++++++++++++++++---------------------- - mdadm.h | 1 + - 3 files changed, 43 insertions(+), 48 deletions(-) - -diff --git a/Build.c b/Build.c -index 962c2e37..8d6f6f58 100644 ---- a/Build.c -+++ b/Build.c -@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - - if (s->layout == UnSet) -- switch(s->level) { -- default: /* no layout */ -- s->layout = 0; -- break; -- case 10: -- s->layout = 0x102; /* near=2, far=1 */ -- if (c->verbose > 0) -- pr_err("layout defaults to n1\n"); -- break; -- case 5: -- case 6: -- s->layout = map_name(r5layout, "default"); -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, s->layout)); -- break; -- case LEVEL_FAULTY: -- s->layout = map_name(faultylayout, "default"); -- -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout)); -- break; -- } -+ s->layout = default_layout(NULL, s->level, c->verbose); - - /* We need to create the device. It can have no name. */ - map_lock(&map); -diff --git a/Create.c b/Create.c -index 0ff1922d..9ea19de0 100644 ---- a/Create.c -+++ b/Create.c -@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk) - return 0; - } - --static int default_layout(struct supertype *st, int level, int verbose) -+/** -+ * default_layout() - Get default layout for level. -+ * @st: metadata requested, could be NULL. -+ * @level: raid level requested. -+ * @verbose: verbose level. -+ * -+ * Try to ask metadata handler first, otherwise use global defaults. -+ * -+ * Return: Layout or &UnSet, return value meaning depends of level used. -+ */ -+int default_layout(struct supertype *st, int level, int verbose) - { - int layout = UnSet; -+ mapping_t *layout_map = NULL; -+ char *layout_name = NULL; - - if (st && st->ss->default_geometry) - st->ss->default_geometry(st, &level, &layout, NULL); - -- if (layout == UnSet) -- switch(level) { -- default: /* no layout */ -- layout = 0; -- break; -- case 0: -- layout = RAID0_ORIG_LAYOUT; -- break; -- case 10: -- layout = 0x102; /* near=2, far=1 */ -- if (verbose > 0) -- pr_err("layout defaults to n2\n"); -- break; -- case 5: -- case 6: -- layout = map_name(r5layout, "default"); -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, layout)); -- break; -- case LEVEL_FAULTY: -- layout = map_name(faultylayout, "default"); -+ if (layout != UnSet) -+ return layout; - -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, layout)); -- break; -- } -+ switch (level) { -+ default: /* no layout */ -+ layout = 0; -+ break; -+ case 0: -+ layout = RAID0_ORIG_LAYOUT; -+ break; -+ case 10: -+ layout = 0x102; /* near=2, far=1 */ -+ layout_name = "n2"; -+ break; -+ case 5: -+ case 6: -+ layout_map = r5layout; -+ break; -+ case LEVEL_FAULTY: -+ layout_map = faultylayout; -+ break; -+ } -+ -+ if (layout_map) { -+ layout = map_name(layout_map, "default"); -+ layout_name = map_num(layout_map, layout); -+ } -+ if (layout_name && verbose > 0) -+ pr_err("layout defaults to %s\n", layout_name); - - return layout; - } -diff --git a/mdadm.h b/mdadm.h -index 26e7e5cd..cd72e711 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1512,6 +1512,7 @@ extern int get_linux_version(void); - extern int mdadm_version(char *version); - extern unsigned long long parse_size(char *size); - extern int parse_uuid(char *str, int uuid[4]); -+int default_layout(struct supertype *st, int level, int verbose); - extern int is_near_layout_10(int layout); - extern int parse_layout_10(char *layout); - extern int parse_layout_faulty(char *layout); --- -2.38.1 - diff --git a/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch b/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch new file mode 100644 index 0000000..256b233 --- /dev/null +++ b/SOURCES/0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch @@ -0,0 +1,34 @@ +From 7ccf947eb595c1bb729c32ba18ce171dada76a68 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:11 +0100 +Subject: [PATCH 10/41] super1: check fd before passing to get_dev_size() in + add_to_super1() + +Check if file descriptor is valid before passing it to get_dev_size() in +add_to_super(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super1.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/super1.c b/super1.c +index 871d19f0..5439b7bb 100644 +--- a/super1.c ++++ b/super1.c +@@ -1752,7 +1752,10 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + di->devname = devname; + di->disk = *dk; + di->data_offset = data_offset; +- get_dev_size(fd, NULL, &di->dev_size); ++ ++ if (is_fd_valid(fd)) ++ get_dev_size(fd, NULL, &di->dev_size); ++ + di->next = NULL; + *dip = di; + +-- +2.40.1 + diff --git a/SOURCES/0011-mdadm-add-map_num_s.patch b/SOURCES/0011-mdadm-add-map_num_s.patch deleted file mode 100644 index ee2c755..0000000 --- a/SOURCES/0011-mdadm-add-map_num_s.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:33 +0100 -Subject: [PATCH 11/83] mdadm: add map_num_s() - -map_num() returns NULL if key is not defined. This patch adds -alternative, non NULL version for cases where NULL is not expected. - -There are many printf() calls where map_num() is called on variable -without NULL verification. It works, even if NULL is passed because -gcc is able to ignore NULL argument quietly but the behavior is -undefined. For safety reasons such usages will use map_num_s() now. -It is a potential point of regression. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Assemble.c | 6 ++---- - Create.c | 2 +- - Detail.c | 4 ++-- - Grow.c | 16 ++++++++-------- - Query.c | 4 ++-- - maps.c | 24 ++++++++++++++++++++++++ - mdadm.c | 20 ++++++++++---------- - mdadm.h | 2 +- - super-ddf.c | 6 +++--- - super-intel.c | 2 +- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 9 +++++---- - 13 files changed, 61 insertions(+), 38 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 704b8293..9eac9ce0 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c, - struct assembly_array_info *arr) - { - int raid_disks = arr->preexist_cnt + arr->new_cnt; -- char *status_msg = map_num(assemble_statuses, status); -+ char *status_msg = map_num_s(assemble_statuses, status); - - if (c->export && result) - *result |= status; -@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c, - fprintf(stderr, " (%d new)", arr->new_cnt); - if (arr->exp_cnt) - fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt); -- if (status_msg) -- fprintf(stderr, " %s", status_msg); -- fprintf(stderr, ".\n"); -+ fprintf(stderr, " %s.\n", status_msg); - } - - static int name_matches(char *found, char *required, char *homehost, int require_homehost) -diff --git a/Create.c b/Create.c -index 9ea19de0..c84c1ac8 100644 ---- a/Create.c -+++ b/Create.c -@@ -83,7 +83,7 @@ int default_layout(struct supertype *st, int level, int verbose) - - if (layout_map) { - layout = map_name(layout_map, "default"); -- layout_name = map_num(layout_map, layout); -+ layout_name = map_num_s(layout_map, layout); - } - if (layout_name && verbose > 0) - pr_err("layout defaults to %s\n", layout_name); -diff --git a/Detail.c b/Detail.c -index 95d4cc70..ce7a8445 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c) - if (array.state & (1 << MD_SB_CLEAN)) { - if ((array.level == 0) || - (array.level == LEVEL_LINEAR)) -- arrayst = map_num(sysfs_array_states, -- sra->array_state); -+ arrayst = map_num_s(sysfs_array_states, -+ sra->array_state); - else - arrayst = "clean"; - } else { -diff --git a/Grow.c b/Grow.c -index 18c5719b..8a242b0f 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -547,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && - s->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Operation not supported for consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 1; - } - -@@ -578,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - - if (sra->consistency_policy == (unsigned)s->consistency_policy) { - pr_err("Consistency policy is already %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC && - sra->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Current consistency policy is %s, cannot change to %s\n", -- map_num(consistency_policies, sra->consistency_policy), -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, sra->consistency_policy), -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } -@@ -704,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - ret = sysfs_set_str(sra, NULL, "consistency_policy", -- map_num(consistency_policies, -- s->consistency_policy)); -+ map_num_s(consistency_policies, -+ s->consistency_policy)); - if (ret) - pr_err("Failed to change array consistency policy\n"); - -@@ -2241,7 +2241,7 @@ size_change_error: - info.new_layout = UnSet; - if (info.array.level == 6 && info.new_level == UnSet) { - char l[40], *h; -- strcpy(l, map_num(r6layout, info.array.layout)); -+ strcpy(l, map_num_s(r6layout, info.array.layout)); - h = strrchr(l, '-'); - if (h && strcmp(h, "-6") == 0) { - *h = 0; -@@ -2266,7 +2266,7 @@ size_change_error: - info.new_layout = info.array.layout; - else if (info.array.level == 5 && info.new_level == 6) { - char l[40]; -- strcpy(l, map_num(r5layout, info.array.layout)); -+ strcpy(l, map_num_s(r5layout, info.array.layout)); - strcat(l, "-6"); - info.new_layout = map_name(r6layout, l); - } else { -diff --git a/Query.c b/Query.c -index 23fbf8aa..adcd231e 100644 ---- a/Query.c -+++ b/Query.c -@@ -93,7 +93,7 @@ int Query(char *dev) - else { - printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n", - dev, human_size_brief(larray_size,IEC), -- map_num(pers, level), raid_disks, -+ map_num_s(pers, level), raid_disks, - spare_disks, spare_disks == 1 ? "" : "s"); - } - st = guess_super(fd); -@@ -131,7 +131,7 @@ int Query(char *dev) - dev, - info.disk.number, info.array.raid_disks, - activity, -- map_num(pers, info.array.level), -+ map_num_s(pers, info.array.level), - mddev); - if (st->ss == &super0) - put_md_name(mddev); -diff --git a/maps.c b/maps.c -index a4fd2797..20fcf719 100644 ---- a/maps.c -+++ b/maps.c -@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = { - { NULL, ARRAY_UNKNOWN_STATE } - }; - -+/** -+ * map_num_s() - Safer alternative of map_num() function. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Shall be used only if key existence is quaranted. -+ * -+ * Return: Pointer to name of the element. -+ */ -+char *map_num_s(mapping_t *map, int num) -+{ -+ char *ret = map_num(map, num); -+ -+ assert(ret); -+ return ret; -+} -+ -+/** -+ * map_num() - get element name by key. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Return: Pointer to name of the element or NULL. -+ */ - char *map_num(mapping_t *map, int num) - { - while (map->name) { -diff --git a/mdadm.c b/mdadm.c -index 26299b2e..be40686c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -280,8 +280,8 @@ int main(int argc, char *argv[]) - else - fprintf(stderr, "-%c", opt); - fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n", -- map_num(modes, newmode), -- map_num(modes, mode)); -+ map_num_s(modes, newmode), -+ map_num_s(modes, mode)); - exit(2); - } else if (!mode && newmode) { - mode = newmode; -@@ -544,7 +544,7 @@ int main(int argc, char *argv[]) - switch(s.level) { - default: - pr_err("layout not meaningful for %s arrays.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - case UnSet: - pr_err("raid level must be given before layout.\n"); -@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[]) - if (option_index > 0) - pr_err(":option --%s not valid in %s mode\n", - long_options[option_index].name, -- map_num(modes, mode)); -+ map_num_s(modes, mode)); - else - pr_err("option -%c not valid in %s mode\n", -- opt, map_num(modes, mode)); -+ opt, map_num_s(modes, mode)); - exit(2); - - } -@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[]) - if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--write-journal is not supported with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[]) - s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - if (s.level <= 0) { - pr_err("--consistency-policy not meaningful with level %s.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL && - !s.journaldisks) { - pr_err("--write-journal is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL && - s.level != 5) { -@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[]) - (!s.bitmap_file || - strcmp(s.bitmap_file, "none") == 0)) { - pr_err("--bitmap is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.bitmap_file && - strcmp(s.bitmap_file, "none") != 0 && - s.consistency_policy != CONSISTENCY_POLICY_BITMAP && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--bitmap is not compatible with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -diff --git a/mdadm.h b/mdadm.h -index cd72e711..09915a00 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -770,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, - #endif - - #define SYSLOG_FACILITY LOG_DAEMON -- -+extern char *map_num_s(mapping_t *map, int num); - extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], -diff --git a/super-ddf.c b/super-ddf.c -index 3f304cdc..8cda23a7 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb) - printf("\n"); - printf(" unit[%d] : %d\n", i, be16_to_cpu(ve->unit)); - printf(" state[%d] : %s, %s%s\n", i, -- map_num(ddf_state, ve->state & 7), -+ map_num_s(ddf_state, ve->state & 7), - (ve->state & DDF_state_morphing) ? "Morphing, ": "", - (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent"); - printf(" init state[%d] : %s\n", i, -- map_num(ddf_init_state, ve->init_state&DDF_initstate_mask)); -+ map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask)); - printf(" access[%d] : %s\n", i, -- map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); -+ map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); - printf(" Name[%d] : %.16s\n", i, ve->name); - examine_vd(i, sb, ve->guid); - } -diff --git a/super-intel.c b/super-intel.c -index 6ff336ee..ba3bd41f 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, - free(dev); - free(dv); - pr_err("imsm does not support consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 0; - } - -diff --git a/super0.c b/super0.c -index b79b97a9..61c9ec1d 100644 ---- a/super0.c -+++ b/super0.c -@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st) - { - mdp_super_t *sb = st->sb; - -- printf("MD_LEVEL=%s\n", map_num(pers, sb->level)); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level)); - printf("MD_DEVICES=%d\n", sb->raid_disks); - if (sb->minor_version >= 90) - printf("MD_UUID=%08x:%08x:%08x:%08x\n", -diff --git a/super1.c b/super1.c -index a12a5bc8..e3e2f954 100644 ---- a/super1.c -+++ b/super1.c -@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st) - int len = 32; - int layout; - -- printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level))); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level))); - printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks)); - for (i = 0; i < 32; i++) - if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { -diff --git a/sysfs.c b/sysfs.c -index 2995713d..0d98a65f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) - if (info->array.level < 0) - return 0; /* FIXME */ - rv |= sysfs_set_str(info, NULL, "level", -- map_num(pers, info->array.level)); -+ map_num_s(pers, info->array.level)); - if (info->reshape_active && info->delta_disks != UnSet) - raid_disks -= info->delta_disks; - rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks); -@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers) - } - - if (info->consistency_policy == CONSISTENCY_POLICY_PPL) { -- if (sysfs_set_str(info, NULL, "consistency_policy", -- map_num(consistency_policies, -- info->consistency_policy))) { -+ char *policy = map_num_s(consistency_policies, -+ info->consistency_policy); -+ -+ if (sysfs_set_str(info, NULL, "consistency_policy", policy)) { - pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n"); - info->consistency_policy = CONSISTENCY_POLICY_RESYNC; - } --- -2.38.1 - diff --git a/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch b/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch new file mode 100644 index 0000000..7038b2d --- /dev/null +++ b/SOURCES/0011-mdmon-refactor-md-device-name-check-in-main.patch @@ -0,0 +1,66 @@ +From c8772da4b53307546a9a374507bcec3398fc82c4 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 11:56:12 +0100 +Subject: [PATCH 11/41] mdmon: refactor md device name check in main() + +Refactor mdmon main function to verify if fd is valid prior to checking +device name. This is due to static code analysis complaining after +change b938519e7719 ("util: remove obsolete code from get_md_name"). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + mdmon.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index a2038fe6..5fdb5cdb 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -302,12 +302,12 @@ static int mdmon(char *devnm, int must_fork, int takeover); + int main(int argc, char *argv[]) + { + char *container_name = NULL; +- char *devnm = NULL; + int status = 0; + int opt; + int all = 0; + int takeover = 0; + int dofork = 1; ++ int mdfd = -1; + bool help = false; + static struct option options[] = { + {"all", 0, NULL, 'a'}, +@@ -410,19 +410,20 @@ int main(int argc, char *argv[]) + free_mdstat(mdstat); + + return status; +- } else { +- int mdfd = open_mddev(container_name, 0); +- devnm = fd2devnm(mdfd); ++ } ++ ++ mdfd = open_mddev(container_name, 0); ++ if (is_fd_valid(mdfd)) { ++ char *devnm = fd2devnm(mdfd); + + close(mdfd); +- } + +- if (!devnm) { +- pr_err("%s is not a valid md device name\n", +- container_name); +- return 1; ++ if (devnm) ++ return mdmon(devnm, dofork && do_fork(), takeover); + } +- return mdmon(devnm, dofork && do_fork(), takeover); ++ ++ pr_err("%s is not a valid md device name\n", container_name); ++ return 1; + } + + static int mdmon(char *devnm, int must_fork, int takeover) +-- +2.40.1 + diff --git a/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch b/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch deleted file mode 100644 index 088b803..0000000 --- a/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Tue, 15 Feb 2022 21:34:15 +0800 -Subject: [PATCH 012/125] mdadm/systemd: remove KillMode=none from service file - -For mdadm's systemd configuration, current systemd KillMode is "none" in -following service files, -- mdadm-grow-continue@.service -- mdmon@.service - -This "none" mode is strongly againsted by systemd developers (see man 5 -systemd.kill for "KillMode=" section), and is considering to remove in -future systemd version. - -As systemd developer explained in disuccsion, the systemd kill process -is, -1. send the signal specified by KillSignal= to the list of processes (if - any), TERM is the default -2. wait until either the target of process(es) exit or a timeout expires -3. if the timeout expires send the signal specified by FinalKillSignal=, - KILL is the default - -For "control-group", all remaining processes will receive the SIGTERM -signal (by default) and if there are still processes after a period f -time, they will get the SIGKILL signal. - -For "mixed", only the main process will receive the SIGTERM signal, and -if there are still processes after a period of time, all remaining -processes (including the main one) will receive the SIGKILL signal. - -From the above comment, currently KillMode=control-group is a proper -kill mode. Since control-gropu is the default kill mode, the fix can be -simply removing KillMode=none line from the service file, then the -default mode will take effect. - -Signed-off-by: Coly Li -Cc: Benjamin Brunner -Cc: Franck Bui -Cc: Jes Sorensen -Cc: Mariusz Tkaczyk -Cc: Neil Brown -Cc: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - systemd/mdmon@.service | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 5c667d2a..9fdc8ec7 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 85a3a7c5..77533958 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -25,4 +25,3 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none --- -2.38.1 - diff --git a/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch b/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch new file mode 100644 index 0000000..8dea720 --- /dev/null +++ b/SOURCES/0012-test-run-tests-on-system-level-mdadm.patch @@ -0,0 +1,138 @@ +From 4c12714d1ca06533fe7a887966df2558fd2f96b2 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 20 Feb 2024 17:04:44 +0100 +Subject: [PATCH 12/41] test: run tests on system level mdadm + +The tests run with MDADM_NO_SYSTEMCTL flag by default, however it has +no effect on udev. In case of external metadata, even if flag is set, +udev will trigger systemd to launch mdmon. + +This commit changes test execution level, so the tests are run on system +level mdadm, meaning local build must be installed prior to running +tests. + +Add warning that the tests are run on system level mdadm and local +build must be installed first. + +Do not call mdadm with "quiet" as it makes it not display critical +messages necessary for debug. + +Remove forcing speed_limit and add restoring system speed_limit_max +after test execution. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + test | 27 ++++++++++++++++++--------- + tests/func.sh | 1 - + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/test b/test +index 49a36c3b..338c2db4 100755 +--- a/test ++++ b/test +@@ -1,11 +1,12 @@ + #!/bin/bash + # + # run test suite for mdadm +-mdadm=$PWD/mdadm ++mdadm=`which mdadm` + targetdir="/var/tmp" + logdir="$targetdir" + config=/tmp/mdadm.conf + testdir=$PWD/tests ++system_speed_limit=`cat /proc/sys/dev/raid/speed_limit_max` + devlist= + + savelogs=0 +@@ -20,9 +21,6 @@ DEVTYPE=loop + INTEGRITY=yes + LVM_VOLGROUP=mdtest + +-# make sure to test local mdmon, not system one +-export MDADM_NO_SYSTEMCTL=1 +- + # assume md0, md1, md2 exist in /dev + md0=/dev/md0 + md1=/dev/md1 +@@ -41,7 +39,10 @@ ctrl_c() { + ctrl_c_error=1 + } + +-# mdadm always adds --quiet, and we want to see any unexpected messages ++restore_system_speed_limit() { ++ echo $system_speed_limit > /proc/sys/dev/raid/speed_limit_max ++} ++ + mdadm() { + rm -f $targetdir/stderr + case $* in +@@ -63,10 +64,10 @@ mdadm() { + $mdadm --zero $args > /dev/null + } + done +- $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes ++ $mdadm 2> $targetdir/stderr "$@" --auto=yes + ;; + * ) +- $mdadm 2> $targetdir/stderr --quiet "$@" ++ $mdadm 2> $targetdir/stderr "$@" + ;; + esac + rv=$? +@@ -99,8 +100,6 @@ do_test() { + fi + + rm -f $targetdir/stderr +- # this might have been reset: restore the default. +- echo 2000 > /proc/sys/dev/raid/speed_limit_max + do_clean + # source script in a subshell, so it has access to our + # namespace, but cannot change it. +@@ -122,6 +121,7 @@ do_test() { + echo " (KNOWN BROKEN TEST: $_broken_msg)" + fi + fi ++ restore_system_speed_limit + [ "$savelogs" == "1" ] && + mv -f $targetdir/log $logdir/$_basename.log + [ "$ctrl_c_error" == "1" ] && exit 1 +@@ -299,7 +299,15 @@ parse_args() { + done + } + ++print_warning() { ++ cat <<-EOF ++ Warning! Tests are performed on system level mdadm! ++ If you want to test local build, you need to install it first! ++ EOF ++} ++ + main() { ++ print_warning + do_setup + + echo "Testing on linux-$(uname -r) kernel" +@@ -329,6 +337,7 @@ main() { + break + fi + done ++ + exit 0 + } + +diff --git a/tests/func.sh b/tests/func.sh +index 1c1a28a2..b474442b 100644 +--- a/tests/func.sh ++++ b/tests/func.sh +@@ -213,7 +213,6 @@ do_setup() { + path1=$dev7 + ulimit -c unlimited + [ -f /proc/mdstat ] || modprobe md_mod +- echo 2000 > /proc/sys/dev/raid/speed_limit_max + echo 0 > /sys/module/md_mod/parameters/start_ro + } + +-- +2.40.1 + diff --git a/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch b/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch new file mode 100644 index 0000000..78650d7 --- /dev/null +++ b/SOURCES/0013-Monitor-Allow-no-PID-in-check_one_sharer.patch @@ -0,0 +1,43 @@ +From 3c3ddeeccc1eb4accb62ce9920de430a564be806 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 28 Feb 2024 16:37:20 +0100 +Subject: [PATCH 13/41] Monitor: Allow no PID in check_one_sharer() + +Commit 5fb5479ad100 ("Monitor: open file before check in +check_one_sharer()") introduced a regression that prohibits monitor +from starting if PID file does not exist. + +Add check for no PID file. +Add missing fclose(). + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Monitor.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Monitor.c b/Monitor.c +index 7cee95d4..9be2b528 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -453,12 +453,17 @@ static int check_one_sharer(int scan) + + fp = fopen(AUTOREBUILD_PID_PATH, "r"); + if (!fp) { ++ /* PID file does not exist */ ++ if (errno == ENOENT) ++ return 0; ++ + pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); + return 2; + } + + if (!is_file(AUTOREBUILD_PID_PATH)) { + pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); ++ fclose(fp); + return 2; + } + +-- +2.40.1 + diff --git a/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch b/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch deleted file mode 100644 index 77324cf..0000000 --- a/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 13 May 2022 09:19:42 +0200 -Subject: [PATCH 13/83] mdmon: Stop parsing duplicate options - -Introduce new function is_duplicate_opt() to check if given option -was already used and prevent setting it again along with an error -message. - -Move parsing above in_initrd() check to be able to detect --offroot -option duplicates. - -Now help option is executed after parsing to prevent executing commands -like: 'mdmon --help --ndlksnlksajndfjksndafasj'. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 44 +++++++++++++++++++++++++++++++++++--------- - 1 file changed, 35 insertions(+), 9 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 5570574b..c057da63 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -288,6 +288,15 @@ void usage(void) - exit(2); - } - -+static bool is_duplicate_opt(const int opt, const int set_val, const char *long_name) -+{ -+ if (opt == set_val) { -+ pr_err("--%s option duplicated!\n", long_name); -+ return true; -+ } -+ return false; -+} -+ - static int mdmon(char *devnm, int must_fork, int takeover); - - int main(int argc, char *argv[]) -@@ -299,6 +308,7 @@ int main(int argc, char *argv[]) - int all = 0; - int takeover = 0; - int dofork = 1; -+ bool help = false; - static struct option options[] = { - {"all", 0, NULL, 'a'}, - {"takeover", 0, NULL, 't'}, -@@ -308,37 +318,50 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -- if (in_initrd()) { -- /* -- * set first char of argv[0] to @. This is used by -- * systemd to signal that the task was launched from -- * initrd/initramfs and should be preserved during shutdown -- */ -- argv[0][0] = '@'; -- } -- - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -+ if (is_duplicate_opt(all, 1, "all")) -+ exit(1); - container_name = argv[optind-1]; - all = 1; - break; - case 't': -+ if (is_duplicate_opt(takeover, 1, "takeover")) -+ exit(1); - takeover = 1; - break; - case 'F': -+ if (is_duplicate_opt(dofork, 0, "foreground")) -+ exit(1); - dofork = 0; - break; - case OffRootOpt: -+ if (is_duplicate_opt(argv[0][0], '@', "offroot")) -+ exit(1); - argv[0][0] = '@'; - break; - case 'h': -+ if (is_duplicate_opt(help, true, "help")) -+ exit(1); -+ help = true; -+ break; - default: - usage(); - break; - } - } - -+ -+ if (in_initrd()) { -+ /* -+ * set first char of argv[0] to @. This is used by -+ * systemd to signal that the task was launched from -+ * initrd/initramfs and should be preserved during shutdown -+ */ -+ argv[0][0] = '@'; -+ } -+ - if (all == 0 && container_name == NULL) { - if (argv[optind]) - container_name = argv[optind]; -@@ -353,6 +376,9 @@ int main(int argc, char *argv[]) - if (strcmp(container_name, "/proc/mdstat") == 0) - all = 1; - -+ if (help) -+ usage(); -+ - if (all) { - struct mdstat_ent *mdstat, *e; - int container_len = strlen(container_name); --- -2.38.1 - diff --git a/SOURCES/0014-Grow-block-n-on-external-volumes.patch b/SOURCES/0014-Grow-block-n-on-external-volumes.patch deleted file mode 100644 index 4e6a874..0000000 --- a/SOURCES/0014-Grow-block-n-on-external-volumes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 19 May 2022 09:16:08 +0200 -Subject: [PATCH 14/83] Grow: block -n on external volumes. - -Performing --raid-devices on external metadata volume should be blocked -as it causes unwanted behaviour. - -Eg. Performing -mdadm -G /dev/md/volume -l10 -n4 -on r0_d2 inside 4 disk container, returns -mdadm: Need 2 spares to avoid degraded array, only have 0. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/Grow.c b/Grow.c -index 8a242b0f..f6efbc48 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1892,6 +1892,14 @@ int Grow_reshape(char *devname, int fd, - - if (retval) { - pr_err("Cannot read superblock for %s\n", devname); -+ close(cfd); -+ free(subarray); -+ return 1; -+ } -+ -+ if (s->raiddisks && subarray) { -+ pr_err("--raid-devices operation can be performed on a container only\n"); -+ close(cfd); - free(subarray); - return 1; - } --- -2.38.1 - diff --git a/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch b/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch new file mode 100644 index 0000000..5047232 --- /dev/null +++ b/SOURCES/0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch @@ -0,0 +1,47 @@ +From d1cd231ae41d98b2555dbff08d0c79876b5059fe Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Feb 2024 07:36:39 +0100 +Subject: [PATCH 14/41] super-intel: respect IMSM_DEVNAME_AS_SERIAL flag + +IMSM_DEVNAME_AS_SERIAL flag was respected only when searching +serial using nvme or scsi device wasn't successful. This +flag shall be applied first, to have user settings with +the highest priority. + +Signed-off-by: Kinga Tanska +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index e61f3f6f..4babec9f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4174,17 +4174,17 @@ static int imsm_read_serial(int fd, char *devname, + + memset(buf, 0, sizeof(buf)); + ++ if (check_env("IMSM_DEVNAME_AS_SERIAL")) { ++ memset(serial, 0, serial_buf_len); ++ fd2devname(fd, (char *) serial); ++ return 0; ++ } ++ + rv = nvme_get_serial(fd, buf, sizeof(buf)); + + if (rv) + rv = scsi_get_serial(fd, buf, sizeof(buf)); + +- if (rv && check_env("IMSM_DEVNAME_AS_SERIAL")) { +- memset(serial, 0, MAX_RAID_SERIAL_LEN); +- fd2devname(fd, (char *) serial); +- return 0; +- } +- + if (rv != 0) { + if (devname) + pr_err("Failed to retrieve serial for %s\n", +-- +2.40.1 + diff --git a/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch b/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch deleted file mode 100644 index 51a9e0f..0000000 --- a/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch +++ /dev/null @@ -1,90 +0,0 @@ -From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:11:25 +0200 -Subject: [PATCH 15/83] Incremental: Fix possible memory and resource leaks - -map allocated through map_by_uuid() is not freed if mdfd is invalid. -In addition mdfd is not closed, and mdinfo list is not freed too. - -Signed-off-by: Mateusz Grzonka -Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc -Signed-off-by: Jes Sorensen ---- - Incremental.c | 32 +++++++++++++++++++++++--------- - 1 file changed, 23 insertions(+), 9 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index a57fc323..4d0cd9d6 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1499,7 +1499,7 @@ static int Incremental_container(struct supertype *st, char *devname, - return 0; - } - for (ra = list ; ra ; ra = ra->next) { -- int mdfd; -+ int mdfd = -1; - char chosen_name[1024]; - struct map_ent *mp; - struct mddev_ident *match = NULL; -@@ -1514,6 +1514,12 @@ static int Incremental_container(struct supertype *st, char *devname, - - if (mp) { - mdfd = open_dev(mp->devnm); -+ if (!is_fd_valid(mdfd)) { -+ pr_err("failed to open %s: %s.\n", -+ mp->devnm, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - if (mp->path) - strcpy(chosen_name, mp->path); - else -@@ -1573,21 +1579,25 @@ static int Incremental_container(struct supertype *st, char *devname, - c->autof, - trustworthy, - chosen_name, 0); -+ -+ if (!is_fd_valid(mdfd)) { -+ pr_err("create_mddev failed with chosen name %s: %s.\n", -+ chosen_name, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - } -- if (only && (!mp || strcmp(mp->devnm, only) != 0)) -- continue; - -- if (mdfd < 0) { -- pr_err("failed to open %s: %s.\n", -- chosen_name, strerror(errno)); -- return 2; -+ if (only && (!mp || strcmp(mp->devnm, only) != 0)) { -+ close_fd(&mdfd); -+ continue; - } - - assemble_container_content(st, mdfd, ra, c, - chosen_name, &result); - map_free(map); - map = NULL; -- close(mdfd); -+ close_fd(&mdfd); - } - if (c->export && result) { - char sep = '='; -@@ -1610,7 +1620,11 @@ static int Incremental_container(struct supertype *st, char *devname, - } - printf("\n"); - } -- return 0; -+ -+release: -+ map_free(map); -+ sysfs_free(list); -+ return rv; - } - - static void run_udisks(char *arg1, char *arg2) --- -2.38.1 - diff --git a/SOURCES/0015-mdadm-remove-TODO.patch b/SOURCES/0015-mdadm-remove-TODO.patch new file mode 100644 index 0000000..7c3e1c8 --- /dev/null +++ b/SOURCES/0015-mdadm-remove-TODO.patch @@ -0,0 +1,236 @@ +From a944da4e1a56cd926e6b21f5aaebc13198265419 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:42 +0100 +Subject: [PATCH 15/41] mdadm: remove TODO + +This file is not updated in 16 years. +No reasons to keep it. Remove it. + +Signed-off-by: Mariusz Tkaczyk +--- + TODO | 213 ----------------------------------------------------------- + 1 file changed, 213 deletions(-) + delete mode 100644 TODO + +diff --git a/TODO b/TODO +deleted file mode 100644 +index 279d20db..00000000 +--- a/TODO ++++ /dev/null +@@ -1,213 +0,0 @@ +- - add 'name' field to metadata type and use it. +- - use validate_geometry more +- - metadata should be able to check/reject bitmap stuff. +- +-DDF: +- Three new metadata types: +- ddf - used only to create a container. +- ddf-bvd - used to create an array in a container +- ddf-svd - used to create a secondary array from bvds. +- +- Usage: +- mdadm -C /dev/ddf1 /dev/sd[abcdef] +- mdadm -C /dev/md1 -e ddf /dev/sd[a-f] +- mdadm -C /dev/md1 -l container /dev/sd[a-f] +- +- Each of these create a new ddf container using all those +- devices. The name 'ddf*' signals that ddf metadata should be used. +- '-e ddf' only supports one level - 'container'. 'container' is only +- supported by ddf. +- +- mdadm -C /dev/md1 -l0 -n4 /dev/ddf1 # or maybe not ??? +- mdadm -C /dev/md1 -l1 -n2 /dev/sda /dev/sdb +- If exactly one device is given, and it is a container, we select +- devices from that container. +- If devices are given that are already in use, they must be in use by +- a container, and the array is created in the container. +- If devices given are bvds, we slip under the hood to make +- the svd arrays. +- +- mdadm -A /dev/ddf ...... +- base drives make a container. Anything in that container is started +- auto-read-only. +- if /dev/ddf is already assembled, we assemble bvds and svds inside it. +- +- +-2005-dec-20 +- Want an incremental assembly mode to work nicely with udev. +- Core usage would be something like +- mdadm --incr-assemble /dev/newdevice +- This would +- - examine the device to determine uuid etc. +- - look for a match in /etc/mdadm.conf, abort if not found +- - find that device and collect current contents +- - perform an 'assemble' analysis to make sure we have the best set of devices. +- - remove or add devices as appropriate +- - possibly start the array if it was complete +- +- Other usages could involve +- - specify which array to auto-add to. +- This requires an existing array for uuid matching... is there any point? +- +- - +- +- +-2004-june-02 +- * Don't print 'errors' flag, it is meaningless. DONE +- * Handle new superblock format +- * create device file on demand, particularly partitionable devices. DONE +- BUT figure a way to create the partition devices. +- auto=partN +- * Use Event: interface to listen for events. DONE, untested +- * Make sure mdadm -As can assemble multi-level RAIDs ok. +- * --build to build raid1 or multipath arrays +- clean or not ??? +- +----------------------------------------------------------------------------- +-* mdadm --monitor to monitor failed multipath paths and re-instate them. +- +-* Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE +- +- +-* maybe "missing" instead of missing in doco DONE +-* possibly wait for resync to start, or even finish while assembling.- NO +- +-* -Db should have a devices= entry if possible. - DONE +-* when assembling multipath arrays, ignore any error indicators. - DONE +-* rationalise --monitor usage: +- mdadm --monitor +- doesn't do as expected. DONE +- +-* --assemble could have a --update option. - DONE +- following word can be: +- sparc2.2 +- super-minor +- +-* mdadm /dev/md11, where md11 is raid0 can segfault, particularly when looking in the +- [UU_UUU] string ... which doesn't exist ! +-It should be more sensible. DONE +- +-Example: +- +-from Raimund Sacherer +- +-mke2fs -m0 -q /dev/ram1 300 +-mount -n -t ext2 /dev/ram1 /tmp +-echo DEVICE /dev/[sh]* >> /tmp/mdadm.conf +-mdadm -Esb /dev/[sh]* 2>/dev/null >> /tmp/mdadm.conf +-mdadm -ARsc /tmp/mdadm.conf +-umount /tmp +- +- +-?? Allow -S /dev/md? - current complains subsequent not a/d/r - DONE +- +-* new "Query" mode to subsume --detail and --examine. +- --query or -Q, takes a device and tells if it is an MD device, +- and also tells in a raid superblock is found. +- DONE +- +-* write mdstat.c to parse /proc/mdstat file +- Build list of arrays: name, rebuild-percent +- DONE +- +-* parse /proc/partitions and map major/minor into /dev/* names, +- and use that for default DEVICE list ???? +- +-* --detail --scan to read /proc/mdstat, and then iterate over these, +- but assume --brief. --verbose can override +- check each subdevice to see if it is in conf_get_devs. +- Warn if not. +- DONE, but don't warn yet... +- +-* Support multipath ... maybe... +- maybe DONE +- +-* --follow to syslog +- +-* --follow to move spares around DONE +- +-* --follow to notice other events: DONE +- rebuild started +- spare activated +- spare removed +- spare added +- +------------------------------------- +-- --examine --scan scans all drives and build an mdadm.conf file DONE +- +-- check superblock checksum in examine DONE +-- report "chunk" or "rounding" depending on raid level DONE +-- report "linear" instead of "-1" for raid level DONE +-- decode ayout depending on raid level DONE +-- --verbose and --force flags. DONE +- +-- set md_minor, *_disks for Create - DONE +-- for create raid5, how to choose between +- all working, but not insync +- one missing, one spare, insync DONE (--force) +-- and for raid1 - some failed drives... (missing) +- +-- when RUN_ARRAY, make sure *_disks counts are right +- +-- get --detail to extract extra stuff from superblock, +- like uuid DONE +-- --detail --brief to give a config file line DONE +-- parse config file. DONE +-- test... +- +-- when --assemble --scan, if an underlying device is an md device, +- then try to assemble that device first. +- +- +-- mdadm -S /dev/md0 /dev/md1 gives internal error FIXED +- +-- mdadm --detail --scan print summary of what it can find? DONE +- +- +---------- +-Assemble doesn't add spares. - DONE +-Create to allow "missing" name for devices. +-Create to accept "--force" for do exactly what is requested +-- get Assemble to upgrade devices if force flag. +-ARRAY lines in config file to have super_minor=n +-ARRAY lines in config file to have device=pattern, and only accept +- those devices +- If UUID given, insist on that +- If not, but super_minor given, require all found with that minor +- to have same uuid +- If only device given, all valid supers on those devices must have +- same uuid +-allow /dev/mdX as first argument before any options +-Possible --dry-run option for create and assemble--force +- +-Assemble to check that all devices mentioned in superblock +- are present. +- +-New mode: --Monitor (or --Follow) +- Periodically check status of all arrays (listed in config file). +- Log every event and apparent cause - or differences +- Email and alert - or run a program - for important events +- Move spares around if necessary. +- +- An Array line can have a spare-group= field that indicates that +- the array shares spares with other arrays with the same +- spare-group name. +- If an array has a failed and no spares, then check all other +- arrays in the spare group. If one has no failures and a spare, +- then consider that spare. +- Choose the smallest considered spare that is large enough. +- If there is one, then hot-remove it from it's home, and +- hot-add it to the array in question. +- +- --mail-to address +- --alert-handler program +- +- Will also extract information from /proc/mdstat if present, +- and consider 20% marks in rebuild as events. +- +- Events are: +- drive fails - causes mail to be sent +- rebuild started +- spare activated +- spare removed +- spare added +-- +2.40.1 + diff --git a/SOURCES/0016-Mdmonitor-Fix-segfault.patch b/SOURCES/0016-Mdmonitor-Fix-segfault.patch deleted file mode 100644 index 61c64ab..0000000 --- a/SOURCES/0016-Mdmonitor-Fix-segfault.patch +++ /dev/null @@ -1,98 +0,0 @@ -From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:12 +0200 -Subject: [PATCH 16/83] Mdmonitor: Fix segfault - -Mdadm with "--monitor" parameter requires md device -as an argument to be monitored. If given argument is -not a md device, error shall be returned. Previously -it was not checked and invalid argument caused -segmentation fault. This commit adds checking -that devices passed to mdmonitor are md devices. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 10 +++++++++- - mdadm.h | 1 + - mdopen.c | 17 +++++++++++++++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index c0ab5412..4e5802b5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -182,6 +182,7 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ - st = xcalloc(1, sizeof *st); - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); -@@ -190,6 +191,8 @@ int Monitor(struct mddev_dev *devlist, - strcpy(strcpy(st->devname, "/dev/md/"), - mdlist->devname); - } -+ if (!is_mddev(mdlist->devname)) -+ return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -203,7 +206,12 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_dev *dv; - - for (dv = devlist; dv; dv = dv->next) { -- struct state *st = xcalloc(1, sizeof *st); -+ struct state *st; -+ -+ if (!is_mddev(dv->devname)) -+ return 1; -+ -+ st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); - st->devname = xstrdup(dv->devname); - st->next = statelist; -diff --git a/mdadm.h b/mdadm.h -index 09915a00..d53df169 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1636,6 +1636,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy, - #define FOREIGN 2 - #define METADATA 3 - extern int open_mddev(char *dev, int report_errors); -+extern int is_mddev(char *dev); - extern int open_container(int fd); - extern int metadata_container_matches(char *metadata, char *devnm); - extern int metadata_subdev_matches(char *metadata, char *devnm); -diff --git a/mdopen.c b/mdopen.c -index 245be537..d18c9319 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -475,6 +475,23 @@ int open_mddev(char *dev, int report_errors) - return mdfd; - } - -+/** -+ * is_mddev() - check that file name passed is an md device. -+ * @dev: file name that has to be checked. -+ * Return: 1 if file passed is an md device, 0 if not. -+ */ -+int is_mddev(char *dev) -+{ -+ int fd = open_mddev(dev, 1); -+ -+ if (fd >= 0) { -+ close(fd); -+ return 1; -+ } -+ -+ return 0; -+} -+ - char *find_free_devnm(int use_partitions) - { - static char devnm[32]; --- -2.38.1 - diff --git a/SOURCES/0016-mdadm-remove-makedist.patch b/SOURCES/0016-mdadm-remove-makedist.patch new file mode 100644 index 0000000..5905472 --- /dev/null +++ b/SOURCES/0016-mdadm-remove-makedist.patch @@ -0,0 +1,119 @@ +From 84d5e05d6fa6bbe6f4a3bdbdb1165dcc463b5207 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:43 +0100 +Subject: [PATCH 16/41] mdadm: remove makedist + +Archives are generated kernel.org automation, no need to submit +them manually, so remove legacy solution. + +Signed-off-by: Mariusz Tkaczyk +--- + makedist | 96 -------------------------------------------------------- + 1 file changed, 96 deletions(-) + delete mode 100755 makedist + +diff --git a/makedist b/makedist +deleted file mode 100755 +index 0c4b39eb..00000000 +--- a/makedist ++++ /dev/null +@@ -1,96 +0,0 @@ +-#!/bin/sh +-# avoid silly sorting +-export LANG=C +-arg=$1 +-target=~/public_html/source/mdadm +-if [ " $arg" = " test" ] +-then +- target=/tmp/mdadm-test +- rm -rf $target +- mkdir -p $target +-fi +-if [ -d $target ] +-then : +-else echo $target is not a directory +- exit 2 +-fi +-set `grep '^#define VERSION' ReadMe.c ` +-version=`echo $3 | sed -e 's/"//g'` +-grep "^.TH MDADM 8 .. v$version" mdadm.8.in > /dev/null 2>&1 || +- { +- echo mdadm.8.in does not mention version $version. +- exit 1 +- } +-grep "^.TH MDMON 8 .. v$version" mdmon.8 > /dev/null 2>&1 || +- { +- echo mdmon.8 does not mention version $version. +- exit 1 +- } +-rpmv=`echo $version | tr - _` +-grep "^Version: *$rpmv$" mdadm.spec > /dev/null 2>&1 || +- { +- echo mdadm.spec does not mention version $version. +- exit 1 +- } +-if [ -f ANNOUNCE-$version ] +-then : +-else +- echo ANNOUNCE-$version does not exist +- exit 1 +-fi +-if grep "^ANNOUNCE-$version\$" inventory +-then : +-else { cat inventory ; echo ANNOUNCE-$version ; } | sort -o inventory +-fi +- +-echo version = $version +-base=mdadm-$rpmv.tar.gz +-if [ " $arg" != " diff" ] +-then +- if [ -f $target/$base ] +- then +- echo $target/$base exists. +- exit 1 +- fi +- trap "rm $target/$base; exit" 1 2 3 +- git archive --prefix=mdadm-$rpmv/ HEAD | gzip --best > $target/$base +- chmod a+r $target/$base +- ls -l $target/$base +- if tar tzf $target/$base | sed 's,[^/]*/,,' | sort | diff -u inventory - +- then : correct files found +- else echo "Extra files, or inventory is out-of-date" +- rm $target/$base +- exit 1 +- fi +- rpmbuild -ta $target/$base || exit 1 +- find ~/rpmbuild/RPMS -name "*mdadm-$version-*" \ +- -exec cp {} $target/RPM \; +- cp ANNOUNCE-$version $target/ANNOUNCE +- cp ChangeLog $target/ChangeLog +- if [ " $arg" != " test" ] +- then +- echo -n "Confirm signing this release? " +- read a +- if [ " $a" != " y" ]; then echo OK - bye. ; exit 1; fi +- if zcat $target/$base | gpg -ba > $target/$base.sign && gpg -ba $target/ANNOUNCE +- then +- kup put $target/$base $target/$base.sign \ +- /pub/linux/utils/raid/mdadm/mdadm-$version.tar.gz +- kup put $target/ANNOUNCE $target/ANNOUNCE.asc /pub/linux/utils/raid/mdadm/ANNOUNCE +- else +- echo signing failed +- exit 1 +- fi +- fi +-else +- if [ ! -f $target/$base ] +- then +- echo $target/$base does not exist. +- exit 1 +- fi +- ( cd .. ; ln -s mdadm.v2 mdadm-$version ; tar chf - --exclude=.git --exclude="TAGS" --exclude='*,v' --exclude='*~' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz +- mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - ) +- mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - ) +- diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new +- rm -rf /var/tmp/mdadm-old /var/tmp/mdadm-new /var/tmp/mdadm-new.tgz +-fi +-- +2.40.1 + diff --git a/SOURCES/0017-Mdmonitor-Improve-logging-method.patch b/SOURCES/0017-Mdmonitor-Improve-logging-method.patch deleted file mode 100644 index 3c7eed2..0000000 --- a/SOURCES/0017-Mdmonitor-Improve-logging-method.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:13 +0200 -Subject: [PATCH 17/83] Mdmonitor: Improve logging method - -Change logging, and as a result, mdmonitor in verbose -mode will report its configuration. - -Signed-off-by: Kinga Tanska -Signed-off-by: Oleksandr Shchirskyi -Signed-off-by: Jes Sorensen ---- - Monitor.c | 25 ++++++++++++++----------- - 1 file changed, 14 insertions(+), 11 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 4e5802b5..6ca1ebe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -136,24 +136,27 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -- if (!mailaddr) { -+ if (!mailaddr) - mailaddr = conf_get_mailaddr(); -- if (mailaddr && ! c->scan) -- pr_err("Monitor using email address \"%s\" from config file\n", -- mailaddr); -- } -- mailfrom = conf_get_mailfrom(); - -- if (!alert_cmd) { -+ if (!alert_cmd) - alert_cmd = conf_get_program(); -- if (alert_cmd && !c->scan) -- pr_err("Monitor using program \"%s\" from config file\n", -- alert_cmd); -- } -+ -+ mailfrom = conf_get_mailfrom(); -+ - if (c->scan && !mailaddr && !alert_cmd && !dosyslog) { - pr_err("No mail address or alert command - not monitoring.\n"); - return 1; - } -+ -+ if (c->verbose) { -+ pr_err("Monitor is started with delay %ds\n", c->delay); -+ if (mailaddr) -+ pr_err("Monitor using email address %s\n", mailaddr); -+ if (alert_cmd) -+ pr_err("Monitor using program %s\n", alert_cmd); -+ } -+ - info.alert_cmd = alert_cmd; - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; --- -2.38.1 - diff --git a/SOURCES/0017-mdadm-remove-mdadm.spec.patch b/SOURCES/0017-mdadm-remove-mdadm.spec.patch new file mode 100644 index 0000000..7e1de14 --- /dev/null +++ b/SOURCES/0017-mdadm-remove-mdadm.spec.patch @@ -0,0 +1,69 @@ +From 9cdcc193cec92c624841d5b70f1b96daafdc4314 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:44 +0100 +Subject: [PATCH 17/41] mdadm: remove mdadm.spec + +This file is outdated, distributions have their own specs. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.spec | 47 ----------------------------------------------- + 1 file changed, 47 deletions(-) + delete mode 100644 mdadm.spec + +diff --git a/mdadm.spec b/mdadm.spec +deleted file mode 100644 +index 12e7859a..00000000 +--- a/mdadm.spec ++++ /dev/null +@@ -1,47 +0,0 @@ +-Summary: mdadm is used for controlling Linux md devices (aka RAID arrays) +-Name: mdadm +-Version: 4.3 +-Release: 1 +-Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz +-URL: https://neil.brown.name/blog/mdadm +-License: GPL +-Group: Utilities/System +-BuildRoot: %{_tmppath}/%{name}-root +-Obsoletes: mdctl +- +-%description +-mdadm is a program that can be used to create, manage, and monitor +-Linux MD (Software RAID) devices. +- +-%prep +-%setup -q +-# we want to install in /sbin, not /usr/sbin... +-%define _exec_prefix %{nil} +- +-%build +-# This is a debatable issue. The author of this RPM spec file feels that +-# people who install RPMs (especially given that the default RPM options +-# will strip the binary) are not going to be running gdb against the +-# program. +-make CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}" +- +-%install +-make DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} BINDIR=%{_sbindir} install +-install -D -m644 mdadm.conf-example $RPM_BUILD_ROOT/%{_sysconfdir}/mdadm.conf +- +-%clean +-rm -rf $RPM_BUILD_ROOT +- +-%files +-%defattr(-,root,root) +-%doc TODO ChangeLog mdadm.conf-example COPYING +-%{_sbindir}/mdadm +-%{_sbindir}/mdmon +-/usr/lib/udev/rules.d/01-md-raid-creating.rules +-/usr/lib/udev/rules.d/63-md-raid-arrays.rules +-/usr/lib/udev/rules.d/64-md-raid-assembly.rules +-/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules +-%config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf +-%{_mandir}/man*/md* +- +-%changelog +-- +2.40.1 + diff --git a/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch deleted file mode 100644 index 24db49f..0000000 --- a/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 11:59:34 +0200 -Subject: [PATCH 18/83] Fix possible NULL ptr dereferences and memory leaks - -In Assemble there was a NULL check for sra variable, -which effectively didn't stop the execution in every case. -That might have resulted in a NULL pointer dereference. - -Also in super-ddf, mu variable was set to NULL for some condition, -and then immidiately dereferenced. -Additionally some memory wasn't freed as well. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 ++++++- - super-ddf.c | 9 +++++++-- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 9eac9ce0..4b213560 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1982,7 +1982,12 @@ int assemble_container_content(struct supertype *st, int mdfd, - } - - sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); -- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { -+ if (sra == NULL) { -+ pr_err("Failed to read sysfs parameters\n"); -+ return 1; -+ } -+ -+ if (strcmp(sra->text_version, content->text_version) != 0) { - if (content->array.major_version == -1 && - content->array.minor_version == -2 && - c->readonly && -diff --git a/super-ddf.c b/super-ddf.c -index 8cda23a7..abbc8b09 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -5125,13 +5125,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - */ - vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk, - &n_bvd, &vcl); -- if (vc == NULL) -+ if (vc == NULL) { -+ free(rv); - return NULL; -+ } - - mu = xmalloc(sizeof(*mu)); - if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) { - free(mu); -- mu = NULL; -+ free(rv); -+ return NULL; - } - - mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count; -@@ -5161,6 +5164,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - pr_err("BUG: can't find disk %d (%d/%d)\n", - di->disk.raid_disk, - di->disk.major, di->disk.minor); -+ free(mu); -+ free(rv); - return NULL; - } - vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum; --- -2.38.1 - diff --git a/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch b/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch new file mode 100644 index 0000000..4c32496 --- /dev/null +++ b/SOURCES/0018-mdadm-remove-mkinitramfs-stuff.patch @@ -0,0 +1,209 @@ +From 9282e1169f19676553a82dd49f780285a16e3b9a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:45 +0100 +Subject: [PATCH 18/41] mdadm: remove mkinitramfs stuff + +This script uses mdadm.static which is known to not be abandoned +(probably not working) from years. Mdadm is integrated with dracut +and mkinitramfs these days. + +Signed-off-by: Mariusz Tkaczyk +--- + README.initramfs | 122 ----------------------------------------------- + mkinitramfs | 55 --------------------- + 2 files changed, 177 deletions(-) + delete mode 100644 README.initramfs + delete mode 100644 mkinitramfs + +diff --git a/README.initramfs b/README.initramfs +deleted file mode 100644 +index c5fa6680..00000000 +--- a/README.initramfs ++++ /dev/null +@@ -1,122 +0,0 @@ +-Assembling md arrays at boot time. +---------------------------------- +-December 2005 +- +-These notes apply to 2.6 kernels only and, in some cases, +-to 2.6.15 or later. +- +-Md arrays can be assembled at boot time using the 'autodetect' functionality +-which is triggered by storing components of an array in partitions of type +-'fd' - Linux Raid Autodetect. +-They can also be assembled by specifying the component devices in a +-kernel parameter such as +- md=0,/dev/sda,/dev/sdb +-In this case, /dev/md0 will be assembled (because of the 0) from the listed +-devices. +- +-These mechanisms, while useful, do not provide complete functionality +-and are unlikely to be extended. The preferred way to assemble md +-arrays at boot time is using 'mdadm'. To assemble an array which +-contains the root filesystem, mdadm needs to be run before that +-filesystem is mounted, and so needs to be run from an initial-ram-fs. +-It is how this can work that is the primary focus of this document. +- +-It should be noted up front that only the array containing the root +-filesystem should be assembled from the initramfs. Any other arrays +-should be assembled under the control of files on the main filesystem +-as this enhanced flexibility and maintainability. +- +-A minimal initramfs for assembling md arrays can be created using 3 +-files and one directory. These are: +- +-/bin Directory +-/bin/mdadm statically linked mdadm binary +-/bin/busybox statically linked busybox binary +-/bin/sh hard link to /bin/busybox +-/init a shell script which call mdadm appropriately. +- +-An example init script is: +- +-============================================== +-#!/bin/sh +- +-echo 'Auto-assembling boot md array' +-mkdir /proc +-mount -t proc proc /proc +-if [ -n "$rootuuid" ] +-then arg=--uuid=$rootuuid +-elif [ -n "$mdminor" ] +-then arg=--super-minor=$mdminor +-else arg=--super-minor=0 +-fi +-echo "Using $arg" +-mdadm -Acpartitions $arg --auto=part /dev/mda +-cd / +-mount /dev/mda1 /root || mount /dev/mda /root +-umount /proc +-cd /root +-exec chroot . /sbin/init < /dev/console > /dev/console 2>&1 +-============================================= +- +-This could certainly be extended, or merged into a larger init script. +-Though tested and in production use, it is not presented here as +-"The Right Way" to do it, but as a useful example. +-Some key points are: +- +- /proc needs to be mounted so that /proc/partitions can be accessed +- by mdadm, and so that /proc/filesystems can be accessed by mount. +- +- The uuid of the array can be passed in as a kernel parameter +- (rootuuid). As the kernel doesn't use this value, it is made available +- in the environment for /init +- +- If no uuid is given, we default to md0, (--super-minor=0) which is a +- commonly used to store the root filesystem. This may not work in +- all situations. +- +- We assemble the array as a partitionable array (/dev/mda) even if we +- end up using the whole array. There is no cost in using the partitionable +- interface, and in this context it is simpler. +- +- We try mounting both /dev/mda1 and /dev/mda as they are the most like +- part of the array to contain the root filesystem. +- +- The --auto flag is given to mdadm so that it will create /dev/md* +- files automatically. This is needed as /dev will not contain +- and md files, and udev will not create them (as udev only created device +- files after the device exists, and mdadm need the device file to create +- the device). Note that the created md files may not exist in /dev +- of the mounted root filesystem. This needs to be deal with separately +- from mdadm - possibly using udev. +- +- We do not need to create device files for the components which will +- be assembled into /dev/mda. mdadm finds the major/minor numbers from +- /proc/partitions and creates a temporary /dev file if one doesn't already +- exist. +- +-The script "mkinitramfs" which is included with the mdadm distribution +-can be used to create a minimal initramfs. It creates a file called +-'init.cpio.gz' which can be specified as an 'initrd' to lilo or grub +-(or whatever boot loader is being used). +- +- +- +- +-Resume from an md array +------------------------ +- +-If you want to make use of the suspend-to-disk/resume functionality in Linux, +-and want to have swap on an md array, you will need to assemble the array +-before resume is possible. +-However, because the array is active in the resumed image, you do not want +-anything written to any drives during the resume process, such as superblock +-updates or array resync. +- +-This can be achieved in 2.6.15-rc1 and later kernels using the +-'start_readonly' module parameter. +-Simply include the command +- echo 1 > /sys/module/md_mod/parameters/start_ro +-before assembling the array with 'mdadm'. +-You can then echo +- 9:0 +-or whatever is appropriate to /sys/power/resume to trigger the resume. +diff --git a/mkinitramfs b/mkinitramfs +deleted file mode 100644 +index c6275ddb..00000000 +--- a/mkinitramfs ++++ /dev/null +@@ -1,55 +0,0 @@ +-#!/bin/sh +- +-# make sure we are being run in the right directory... +-if [ -f mkinitramfs ] +-then : +-else +- echo >&2 mkinitramfs must be run from the mdadm source directory. +- exit 1 +-fi +-if [ -f /bin/busybox ] +-then : good, it exists +- case `file /bin/busybox` in +- *statically* ) : good ;; +- * ) echo >&2 mkinitramfs: /bin/busybox is not statically linked: cannot proceed. +- exit 1 +- esac +-else +- echo >&2 "mkinitramfs: /bin/busybox doesn't exist - please install it statically linked." +- exit 1 +-fi +- +-rm -rf initramfs +-mkdir initramfs +-mkdir initramfs/bin +-make mdadm.static +-cp mdadm.static initramfs/bin/mdadm +-cp /bin/busybox initramfs/bin/busybox +-ln initramfs/bin/busybox initramfs/bin/sh +-cat <<- END > initramfs/init +- #!/bin/sh +- +- echo 'Auto-assembling boot md array' +- mkdir /proc +- mount -t proc proc /proc +- if [ -n "$rootuuid" ] +- then arg=--uuid=$rootuuid +- elif [ -n "$mdminor" ] +- then arg=--super-minor=$mdminor +- else arg=--super-minor=0 +- fi +- echo "Using $arg" +- mdadm -Acpartitions $arg --auto=part /dev/mda +- cd / +- mount /dev/mda1 /root || mount /dev/mda /root +- umount /proc +- cd /root +- exec chroot . /sbin/init < /dev/console > /dev/console 2>&1 +-END +-chmod +x initramfs/init +- +-(cd initramfs +- find init bin | cpio -o -H newc | gzip --best +-) > init.cpio.gz +-rm -rf initramfs +-ls -l init.cpio.gz +-- +2.40.1 + diff --git a/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch b/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch deleted file mode 100644 index 12dd070..0000000 --- a/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:00:09 +0200 -Subject: [PATCH 19/83] imsm: Remove possibility for get_imsm_dev to return - NULL - -Returning NULL from get_imsm_dev or __get_imsm_dev will cause segfault. -Guarantee that it never happens. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - super-intel.c | 153 +++++++++++++++++++++++++------------------------- - 1 file changed, 78 insertions(+), 75 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index ba3bd41f..3788feb9 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -851,6 +851,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update) - return inf; - } - -+/** -+ * __get_imsm_dev() - Get device with index from imsm_super. -+ * @mpb: &imsm_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - { - int offset; -@@ -858,30 +873,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - void *_mpb = mpb; - - if (index >= mpb->num_raid_devs) -- return NULL; -+ goto error; - - /* devices start after all disks */ - offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb; - -- for (i = 0; i <= index; i++) -+ for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0)) - if (i == index) - return _mpb + offset; -- else -- offset += sizeof_imsm_dev(_mpb + offset, 0); -- -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in imsm_super\n", index); -+ abort(); - } - -+/** -+ * get_imsm_dev() - Get device with index from intel_super. -+ * @super: &intel_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index) - { - struct intel_dev *dv; - - if (index >= super->anchor->num_raid_devs) -- return NULL; -+ goto error; -+ - for (dv = super->devlist; dv; dv = dv->next) - if (dv->index == index) - return dv->dev; -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in intel_super\n", index); -+ abort(); - } - - static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr -@@ -4364,8 +4396,7 @@ int check_mpb_migr_compatibility(struct intel_super *super) - for (i = 0; i < super->anchor->num_raid_devs; i++) { - struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i); - -- if (dev_iter && -- dev_iter->vol.migr_state == 1 && -+ if (dev_iter->vol.migr_state == 1 && - dev_iter->vol.migr_type == MIGR_GEN_MIGR) { - /* This device is migrating */ - map0 = get_imsm_map(dev_iter, MAP_0); -@@ -4514,8 +4545,6 @@ static void clear_hi(struct intel_super *super) - } - for (i = 0; i < mpb->num_raid_devs; ++i) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- if (!dev) -- return; - for (n = 0; n < 2; ++n) { - struct imsm_map *map = get_imsm_map(dev, n); - if (!map) -@@ -5836,7 +5865,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_dev *_dev = __get_imsm_dev(mpb, 0); - - _disk = __get_imsm_disk(mpb, dl->index); -- if (!_dev || !_disk) { -+ if (!_disk) { - pr_err("BUG mpb setup error\n"); - return 1; - } -@@ -6171,10 +6200,10 @@ static int write_super_imsm(struct supertype *st, int doclose) - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = __get_imsm_dev(mpb, i); - struct imsm_dev *dev2 = get_imsm_dev(super, i); -- if (dev && dev2) { -- imsm_copy_dev(dev, dev2); -- mpb_size += sizeof_imsm_dev(dev, 0); -- } -+ -+ imsm_copy_dev(dev, dev2); -+ mpb_size += sizeof_imsm_dev(dev, 0); -+ - if (is_gen_migration(dev2)) - clear_migration_record = 0; - } -@@ -9033,29 +9062,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed) - __u8 state; - - dev2 = get_imsm_dev(cont->sb, dev_idx); -- if (dev2) { -- state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -- if (state == IMSM_T_STATE_FAILED) { -- map = get_imsm_map(dev2, MAP_0); -- if (!map) -- return 1; -- for (slot = 0; slot < map->num_members; slot++) { -- /* -- * Check if failed disks are deleted from intel -- * disk list or are marked to be deleted -- */ -- idx = get_imsm_disk_idx(dev2, slot, MAP_X); -- idisk = get_imsm_dl_disk(cont->sb, idx); -- /* -- * Do not rebuild the array if failed disks -- * from failed sub-array are not removed from -- * container. -- */ -- if (idisk && -- is_failed(&idisk->disk) && -- (idisk->action != DISK_REMOVE)) -- return 0; -- } -+ -+ state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -+ if (state == IMSM_T_STATE_FAILED) { -+ map = get_imsm_map(dev2, MAP_0); -+ for (slot = 0; slot < map->num_members; slot++) { -+ /* -+ * Check if failed disks are deleted from intel -+ * disk list or are marked to be deleted -+ */ -+ idx = get_imsm_disk_idx(dev2, slot, MAP_X); -+ idisk = get_imsm_dl_disk(cont->sb, idx); -+ /* -+ * Do not rebuild the array if failed disks -+ * from failed sub-array are not removed from -+ * container. -+ */ -+ if (idisk && -+ is_failed(&idisk->disk) && -+ (idisk->action != DISK_REMOVE)) -+ return 0; - } - } - return 1; -@@ -10089,7 +10115,6 @@ static void imsm_process_update(struct supertype *st, - int victim = u->dev_idx; - struct active_array *a; - struct intel_dev **dp; -- struct imsm_dev *dev; - - /* sanity check that we are not affecting the uuid of - * active arrays, or deleting an active array -@@ -10105,8 +10130,7 @@ static void imsm_process_update(struct supertype *st, - * is active in the container, so checking - * mpb->num_raid_devs is just extra paranoia - */ -- dev = get_imsm_dev(super, victim); -- if (a || !dev || mpb->num_raid_devs == 1) { -+ if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) { - dprintf("failed to delete subarray-%d\n", victim); - break; - } -@@ -10140,7 +10164,7 @@ static void imsm_process_update(struct supertype *st, - if (a->info.container_member == target) - break; - dev = get_imsm_dev(super, u->dev_idx); -- if (a || !dev || !check_name(super, name, 1)) { -+ if (a || !check_name(super, name, 1)) { - dprintf("failed to rename subarray-%d\n", target); - break; - } -@@ -10169,10 +10193,6 @@ static void imsm_process_update(struct supertype *st, - struct imsm_update_rwh_policy *u = (void *)update->buf; - int target = u->dev_idx; - struct imsm_dev *dev = get_imsm_dev(super, target); -- if (!dev) { -- dprintf("could not find subarray-%d\n", target); -- break; -- } - - if (dev->rwh_policy != u->new_policy) { - dev->rwh_policy = u->new_policy; -@@ -11397,8 +11417,10 @@ static int imsm_create_metadata_update_for_migration( - { - struct intel_super *super = st->sb; - int update_memory_size; -+ int current_chunk_size; - struct imsm_update_reshape_migration *u; -- struct imsm_dev *dev; -+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); - int previous_level = -1; - - dprintf("(enter) New Level = %i\n", geo->level); -@@ -11415,23 +11437,15 @@ static int imsm_create_metadata_update_for_migration( - u->new_disks[0] = -1; - u->new_chunksize = -1; - -- dev = get_imsm_dev(super, u->subdev); -- if (dev) { -- struct imsm_map *map; -+ current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2; - -- map = get_imsm_map(dev, MAP_0); -- if (map) { -- int current_chunk_size = -- __le16_to_cpu(map->blocks_per_strip) / 2; -- -- if (geo->chunksize != current_chunk_size) { -- u->new_chunksize = geo->chunksize / 1024; -- dprintf("imsm: chunk size change from %i to %i\n", -- current_chunk_size, u->new_chunksize); -- } -- previous_level = map->raid_level; -- } -+ if (geo->chunksize != current_chunk_size) { -+ u->new_chunksize = geo->chunksize / 1024; -+ dprintf("imsm: chunk size change from %i to %i\n", -+ current_chunk_size, u->new_chunksize); - } -+ previous_level = map->raid_level; -+ - if (geo->level == 5 && previous_level == 0) { - struct mdinfo *spares = NULL; - -@@ -12519,9 +12533,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st) - unsigned long long offset; - struct dl *d; - -- if (!dev) -- return -1; -- - if (dev->rwh_policy != RWH_BITMAP) - return 0; - -@@ -12567,16 +12578,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp, - return -1; - - dev = get_imsm_dev(super, vol_idx); -- -- if (!dev) { -- dprintf("cannot find the device for volume index %d\n", -- vol_idx); -- return -1; -- } - dev->rwh_policy = RWH_BITMAP; -- - *chunkp = calculate_bitmap_chunksize(st, dev); -- - return 0; - } - --- -2.38.1 - diff --git a/SOURCES/0019-mdadm-move-documentation-to-folder.patch b/SOURCES/0019-mdadm-move-documentation-to-folder.patch new file mode 100644 index 0000000..dc9bcc8 --- /dev/null +++ b/SOURCES/0019-mdadm-move-documentation-to-folder.patch @@ -0,0 +1,1044 @@ +From 3aa5bb0af1051432a83b2f7a9fd5c2763444c937 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 23 Feb 2024 15:51:46 +0100 +Subject: [PATCH 19/41] mdadm: move documentation to folder + +Move documentation text files to directory. + +Signed-off-by: Mariusz Tkaczyk +--- + documentation/external-reshape-design.txt | 280 ++++++++++++++++++++++ + documentation/mdadm.conf-example | 65 +++++ + documentation/mdmon-design.txt | 146 +++++++++++ + external-reshape-design.txt | 280 ---------------------- + mdadm.conf-example | 65 ----- + mdmon-design.txt | 146 ----------- + 6 files changed, 491 insertions(+), 491 deletions(-) + create mode 100644 documentation/external-reshape-design.txt + create mode 100644 documentation/mdadm.conf-example + create mode 100644 documentation/mdmon-design.txt + delete mode 100644 external-reshape-design.txt + delete mode 100644 mdadm.conf-example + delete mode 100644 mdmon-design.txt + +diff --git a/documentation/external-reshape-design.txt b/documentation/external-reshape-design.txt +new file mode 100644 +index 00000000..e4cf4e16 +--- /dev/null ++++ b/documentation/external-reshape-design.txt +@@ -0,0 +1,280 @@ ++External Reshape ++ ++1 Problem statement ++ ++External (third-party metadata) reshape differs from native-metadata ++reshape in three key ways: ++ ++1.1 Format specific constraints ++ ++In the native case reshape is limited by what is implemented in the ++generic reshape routine (Grow_reshape()) and what is supported by the ++kernel. There are exceptional cases where Grow_reshape() may block ++operations when it knows that the kernel implementation is broken, but ++otherwise the kernel is relied upon to be the final arbiter of what ++reshape operations are supported. ++ ++In the external case the kernel, and the generic checks in ++Grow_reshape(), become the super-set of what reshapes are possible. The ++metadata format may not support, or have yet to implement a given ++reshape type. The implication for Grow_reshape() is that it must query ++the metadata handler and effect changes in the metadata before the new ++geometry is posted to the kernel. The ->reshape_super method allows ++Grow_reshape() to validate the requested operation and post the metadata ++update. ++ ++1.2 Scope of reshape ++ ++Native metadata reshape is always performed at the array scope (no ++metadata relationship with sibling arrays on the same disks). External ++reshape, depending on the format, may not allow the number of member ++disks to be changed in a subarray unless the change is simultaneously ++applied to all subarrays in the container. For example the imsm format ++requires all member disks to be a member of all subarrays, so a 4-disk ++raid5 in a container that also houses a 4-disk raid10 array could not be ++reshaped to 5 disks as the imsm format does not support a 5-disk raid10 ++representation. This requires the ->reshape_super method to check the ++contents of the array and ask the user to run the reshape at container ++scope (if all subarrays are agreeable to the change), or report an ++error in the case where one subarray cannot support the change. ++ ++1.3 Monitoring / checkpointing ++ ++Reshape, unlike rebuild/resync, requires strict checkpointing to survive ++interrupted reshape operations. For example when expanding a raid5 ++array the first few stripes of the array will be overwritten in a ++destructive manner. When restarting the reshape process we need to know ++the exact location of the last successfully written stripe, and we need ++to restore the data in any partially overwritten stripe. Native ++metadata stores this backup data in the unused portion of spares that ++are being promoted to array members, or in an external backup file ++(located on a non-involved block device). ++ ++The kernel is in charge of recording checkpoints of reshape progress, ++but mdadm is delegated the task of managing the backup space which ++involves: ++1/ Identifying what data will be overwritten in the next unit of reshape ++ operation ++2/ Suspending access to that region so that a snapshot of the data can ++ be transferred to the backup space. ++3/ Allowing the kernel to reshape the saved region and setting the ++ boundary for the next backup. ++ ++In the external reshape case we want to preserve this mdadm ++'reshape-manager' arrangement, but have a third actor, mdmon, to ++consider. It is tempting to give the role of managing reshape to mdmon, ++but that is counter to its role as a monitor, and conflicts with the ++existing capabilities and role of mdadm to manage the progress of ++reshape. For clarity the external reshape implementation maintains the ++role of mdmon as a (mostly) passive recorder of raid events, and mdadm ++treats it as it would the kernel in the native reshape case (modulo ++needing to send explicit metadata update messages and checking that ++mdmon took the expected action). ++ ++External reshape can use the generic md backup file as a fallback, but in the ++optimal/firmware-compatible case the reshape-manager will use the metadata ++specific areas for managing reshape. The implementation also needs to spawn a ++reshape-manager per subarray when the reshape is being carried out at the ++container level. For these two reasons the ->manage_reshape() method is ++introduced. This method in addition to base tasks mentioned above: ++1/ Processed each subarray one at a time in series - where appropriate. ++2/ Uses either generic routines in Grow.c for md-style backup file ++ support, or uses the metadata-format specific location for storing ++ recovery data. ++This aims to avoid a "midlayer mistake"[1] and lets the metadata handler ++optionally take advantage of generic infrastructure in Grow.c ++ ++2 Details for specific reshape requests ++ ++There are quite a few moving pieces spread out across md, mdadm, and mdmon for ++the support of external reshape, and there are several different types of ++reshape that need to be comprehended by the implementation. A rundown of ++these details follows. ++ ++2.0 General provisions: ++ ++Obtain an exclusive open on the container to make sure we are not ++running concurrently with a Create() event. ++ ++2.1 Freezing sync_action ++ ++ Before making any attempt at a reshape we 'freeze' every array in ++ the container to ensure no spare assignment or recovery happens. ++ This involves writing 'frozen' to sync_action and changing the '/' ++ after 'external:' in metadata_version to a '-'. mdmon knows that ++ this means not to perform any management. ++ ++ Before doing this we check that all sync_actions are 'idle', which ++ is racy but still useful. ++ Afterwards we check that all member arrays have no spares ++ or partial spares (recovery_start != 'none') which would indicate a ++ race. If they do, we unfreeze again. ++ ++ Once this completes we know all the arrays are stable. They may ++ still have failed devices as devices can fail at any time. However ++ we treat those like failures that happen during the reshape. ++ ++2.2 Reshape size ++ ++ 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally ++ initializes st->update_tail ++ 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the size change ++ is allowed (being performed at subarray scope / enough room) prepares a ++ metadata update ++ 3/ mdadm::Grow_reshape(): flushes the metadata update (via ++ flush_metadata_update(), or ->sync_metadata()) ++ 4/ mdadm::Grow_reshape(): post the new size to the kernel ++ ++ ++2.3 Reshape level (simple-takeover) ++ ++"simple-takeover" implies the level change can be satisfied without touching ++sync_action ++ ++ 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally ++ initializes st->update_tail ++ 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the level change ++ is allowed (being performed at subarray scope) prepares a ++ metadata update ++ 2a/ raid10 --> raid0: degrade all mirror legs prior to calling ++ ->reshape_super ++ 3/ mdadm::Grow_reshape(): flushes the metadata update (via ++ flush_metadata_update(), or ->sync_metadata()) ++ 4/ mdadm::Grow_reshape(): post the new level to the kernel ++ ++2.4 Reshape chunk, layout ++ ++2.5 Reshape raid disks (grow) ++ ++ 1/ mdadm::Grow_reshape(): unconditionally initializes st->update_tail ++ because only redundant raid levels can modify the number of raid disks ++ 2/ mdadm::Grow_reshape(): calls ->reshape_super() to check that the level ++ change is allowed (being performed at proper scope / permissible ++ geometry / proper spares available in the container), chooses ++ the spares to use, and prepares a metadata update. ++ 3/ mdadm::Grow_reshape(): Converts each subarray in the container to the ++ raid level that can perform the reshape and starts mdmon. ++ 4/ mdadm::Grow_reshape(): Pushes the update to mdmon. ++ 5/ mdadm::Grow_reshape(): uses container_content to find details of ++ the spares and passes them to the kernel. ++ 6/ mdadm::Grow_reshape(): gives raid_disks update to the kernel, ++ sets sync_max, sync_min, suspend_lo, suspend_hi all to zero, ++ and starts the reshape by writing 'reshape' to sync_action. ++ 7/ mdmon::monitor notices the sync_action change and tells ++ managemon to check for new devices. managemon notices the new ++ devices, opens relevant sysfs file, and passes them all to ++ monitor. ++ 8/ mdadm::Grow_reshape() calls ->manage_reshape to oversee the ++ rest of the reshape. ++ ++ 9/ mdadm::->manage_reshape(): saves data that will be overwritten by ++ the kernel to either the backup file or the metadata specific location, ++ advances sync_max, waits for reshape, ping mdmon, repeat. ++ Meanwhile mdmon::read_and_act(): records checkpoints. ++ Specifically. ++ ++ 9a/ if the 'next' stripe to be reshaped will over-write ++ itself during reshape then: ++ 9a.1/ increase suspend_hi to cover a suitable number of ++ stripes. ++ 9a.2/ backup those stripes safely. ++ 9a.3/ advance sync_max to allow those stripes to be backed up ++ 9a.4/ when sync_completed indicates that those stripes have ++ been reshaped, manage_reshape must ping_manager ++ 9a.5/ when mdmon notices that sync_completed has been updated, ++ it records the new checkpoint in the metadata ++ 9a.6/ after the ping_manager, manage_reshape will increase ++ suspend_lo to allow access to those stripes again ++ ++ 9b/ if the 'next' stripe to be reshaped will over-write unused ++ space during reshape then we apply same process as above, ++ except that there is no need to back anything up. ++ Note that we *do* need to keep suspend_hi progressing as ++ it is not safe to write to the area-under-reshape. For ++ kernel-managed-metadata this protection is provided by ++ ->reshape_safe, but that does not protect us in the case ++ of user-space-managed-metadata. ++ ++ 10/ mdadm::->manage_reshape(): Once reshape completes changes the raid ++ level back to the nominal raid level (if necessary) ++ ++ FIXME: native metadata does not have the capability to record the original ++ raid level in reshape-restart case because the kernel always records current ++ raid level to the metadata, whereas external metadata can masquerade at an ++ alternate level based on the reshape state. ++ ++2.6 Reshape raid disks (shrink) ++ ++3 Interaction with metadata handle. ++ ++ The following calls are made into the metadata handler to assist ++ with initiating and monitoring a 'reshape'. ++ ++ 1/ ->reshape_super is called quite early (after only minimial ++ checks) to make sure that the metadata can record the new shape ++ and any necessary transitions. It may be passed a 'container' ++ or an individual array within a container, and it should notice ++ the difference and act accordingly. ++ When a reshape is requested against a container it is expected ++ that it should be applied to every array in the container, ++ however it is up to the metadata handler to determine final ++ policy. ++ ++ If the reshape is supportable, the internal copy of the metadata ++ should be updated, and a metadata update suitable for sending ++ to mdmon should be queued. ++ ++ If the reshape will involve converting spares into array members, ++ this must be recorded in the metadata too. ++ ++ 2/ ->container_content will be called to find out the new state ++ of all the array, or all arrays in the container. Any newly ++ added devices (with state==0 and raid_disk >= 0) will be added ++ to the array as spares with the relevant slot number. ++ ++ It is likely that the info returned by ->container_content will ++ have ->reshape_active set, ->reshape_progress set to e.g. 0, and ++ new_* set appropriately. mdadm will use this information to ++ cause the correct reshape to start at an appropriate time. ++ ++ 3/ ->set_array_state will be called by mdmon when reshape has ++ started and again periodically as it progresses. This should ++ record the ->last_checkpoint as the point where reshape has ++ progressed to. When the reshape finished this will be called ++ again and it should notice that ->curr_action is no longer ++ 'reshape' and so should record that the reshape has finished ++ providing 'last_checkpoint' has progressed suitably. ++ ++ 4/ ->manage_reshape will be called once the reshape has been set ++ up in the kernel but before sync_max has been moved from 0, so ++ no actual reshape will have happened. ++ ++ ->manage_reshape should call progress_reshape() to allow the ++ reshape to progress, and should back-up any data as indicated ++ by the return value. See the documentation of that function ++ for more details. ++ ->manage_reshape will be called multiple times when a ++ container is being reshaped, once for each member array in ++ the container. ++ ++ ++ The progress of the metadata is as follows: ++ 1/ mdadm sends a metadata update to mdmon which marks the array ++ as undergoing a reshape. This is set up by ++ ->reshape_super and applied by ->process_update ++ For container-wide reshape, this happens once for the whole ++ container. ++ 2/ mdmon notices progress via the sysfs files and calls ++ ->set_array_state to update the state periodically ++ For container-wide reshape, this happens repeatedly for ++ one array, then repeatedly for the next, etc. ++ 3/ mdmon notices when reshape has finished and call ++ ->set_array_state to record the the reshape is complete. ++ For container-wide reshape, this happens once for each ++ member array. ++ ++ ++ ++... ++ ++[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/ +diff --git a/documentation/mdadm.conf-example b/documentation/mdadm.conf-example +new file mode 100644 +index 00000000..35a75d12 +--- /dev/null ++++ b/documentation/mdadm.conf-example +@@ -0,0 +1,65 @@ ++# mdadm configuration file ++# ++# mdadm will function properly without the use of a configuration file, ++# but this file is useful for keeping track of arrays and member disks. ++# In general, a mdadm.conf file is created, and updated, after arrays ++# are created. This is the opposite behavior of /etc/raidtab which is ++# created prior to array construction. ++# ++# ++# the config file takes two types of lines: ++# ++# DEVICE lines specify a list of devices of where to look for ++# potential member disks ++# ++# ARRAY lines specify information about how to identify arrays so ++# so that they can be activated ++# ++# You can have more than one device line and use wild cards. The first ++# example includes SCSI the first partition of SCSI disks /dev/sdb, ++# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second ++# line looks for array slices on IDE disks. ++# ++#DEVICE /dev/sd[bcdjkl]1 ++#DEVICE /dev/hda1 /dev/hdb1 ++# ++# If you mount devfs on /dev, then a suitable way to list all devices is: ++#DEVICE /dev/discs/*/* ++# ++# ++# The AUTO line can control which arrays get assembled by auto-assembly, ++# meaing either "mdadm -As" when there are no 'ARRAY' lines in this file, ++# or "mdadm --incremental" when the array found is not listed in this file. ++# By default, all arrays that are found are assembled. ++# If you want to ignore all DDF arrays (maybe they are managed by dmraid), ++# and only assemble 1.x arrays if which are marked for 'this' homehost, ++# but assemble all others, then use ++#AUTO -ddf homehost -1.x +all ++# ++# ARRAY lines specify an array to assemble and a method of identification. ++# Arrays can currently be identified by using a UUID, superblock minor number, ++# or a listing of devices. ++# ++# super-minor is usually the minor number of the metadevice ++# UUID is the Universally Unique Identifier for the array ++# Each can be obtained using ++# ++# mdadm -D ++# ++#ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 ++#ARRAY /dev/md1 super-minor=1 ++#ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 ++# ++# ARRAY lines can also specify a "spare-group" for each array. mdadm --monitor ++# will then move a spare between arrays in a spare-group if one array has a failed ++# drive but no spare ++#ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df spare-group=group1 ++#ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 spare-group=group1 ++# ++# When used in --follow (aka --monitor) mode, mdadm needs a ++# mail address and/or a program. This can be given with "mailaddr" ++# and "program" lines to that monitoring can be started using ++# mdadm --follow --scan & echo $! > /run/mdadm/mon.pid ++# If the lines are not found, mdadm will exit quietly ++#MAILADDR root@mydomain.tld ++#PROGRAM /usr/sbin/handle-mdadm-events +diff --git a/documentation/mdmon-design.txt b/documentation/mdmon-design.txt +new file mode 100644 +index 00000000..f09184a9 +--- /dev/null ++++ b/documentation/mdmon-design.txt +@@ -0,0 +1,146 @@ ++ ++When managing a RAID1 array which uses metadata other than the ++"native" metadata understood by the kernel, mdadm makes use of a ++partner program named 'mdmon' to manage some aspects of updating ++that metadata and synchronising the metadata with the array state. ++ ++This document provides some details on how mdmon works. ++ ++Containers ++---------- ++ ++As background: mdadm makes a distinction between an 'array' and a ++'container'. Other sources sometimes use the term 'volume' or ++'device' for an 'array', and may use the term 'array' for a ++'container'. ++ ++For our purposes: ++ - a 'container' is a collection of devices which are described by a ++ single set of metadata. The metadata may be stored equally ++ on all devices, or different devices may have quite different ++ subsets of the total metadata. But there is conceptually one set ++ of metadata that unifies the devices. ++ ++ - an 'array' is a set of datablock from various devices which ++ together are used to present the abstraction of a single linear ++ sequence of block, which may provide data redundancy or enhanced ++ performance. ++ ++So a container has some metadata and provides a number of arrays which ++are described by that metadata. ++ ++Sometimes this model doesn't work perfectly. For example, global ++spares may have their own metadata which is quite different from the ++metadata from any device that participates in one or more arrays. ++Such a global spare might still need to belong to some container so ++that it is available to be used should a failure arise. In that case ++we consider the 'metadata' to be the union of the metadata on the ++active devices which describes the arrays, and the metadata on the ++global spares which only describes the spares. In this case different ++devices in the one container will have quite different metadata. ++ ++ ++Purpose ++------- ++ ++The main purpose of mdmon is to update the metadata in response to ++changes to the array which need to be reflected in the metadata before ++futures writes to the array can safely be performed. ++These include: ++ - transitions from 'clean' to 'dirty'. ++ - recording the devices have failed. ++ - recording the progress of a 'reshape' ++ ++This requires mdmon to be running at any time that the array is ++writable (a read-only array does not require mdmon to be running). ++ ++Because mdmon must be able to process these metadata updates at any ++time, it must (when running) have exclusive write access to the ++metadata. Any other changes (e.g. reconfiguration of the array) must ++go through mdmon. ++ ++A secondary role for mdmon is to activate spares when a device fails. ++This role is much less time-critical than the other metadata updates, ++so it could be performed by a separate process, possibly ++"mdadm --monitor" which has a related role of moving devices between ++arrays. A main reason for including this functionality in mdmon is ++that in the native-metadata case this function is handled in the ++kernel, and mdmon's reason for existence to provide functionality ++which is otherwise handled by the kernel. ++ ++ ++Design overview ++--------------- ++ ++mdmon is structured as two threads with a common address space and ++common data structures. These threads are know as the 'monitor' and ++the 'manager'. ++ ++The 'monitor' has the primary role of monitoring the array for ++important state changes and updating the metadata accordingly. As ++writes to the array can be blocked until 'monitor' completes and ++acknowledges the update, it much be very careful not to block itself. ++In particular it must not block waiting for any write to complete else ++it could deadlock. This means that it must not allocate memory as ++doing this can require dirty memory to be written out and if the ++system choose to write to the array that mdmon is monitoring, the ++memory allocation could deadlock. ++ ++So 'monitor' must never allocate memory and must limit the number of ++other system call it performs. It may: ++ - use select (or poll) to wait for activity on a file descriptor ++ - read from a sysfs file descriptor ++ - write to a sysfs file descriptor ++ - write the metadata out to the block devices using O_DIRECT ++ - send a signal (kill) to the manager thread ++ ++It must not e.g. open files or do anything similar that might allocate ++resources. ++ ++The 'manager' thread does everything else that is needed. If any ++files are to be opened (e.g. because a device has been added to the ++array), the manager does that. If any memory needs to be allocated ++(e.g. to hold data about a new array as can happen when one set of ++metadata describes several arrays), the manager performs that ++allocation. ++ ++The 'manager' is also responsible for communicating with mdadm and ++assigning spares to replace failed devices. ++ ++ ++Handling metadata updates ++------------------------- ++ ++There are a number of cases in which mdadm needs to update the ++metdata which mdmon is managing. These include: ++ - creating a new array in an active container ++ - adding a device to a container ++ - reconfiguring an array ++etc. ++ ++To complete these updates, mdadm must send a message to mdmon which ++will merge the update into the metadata as it is at that moment. ++ ++To achieve this, mdmon creates a Unix Domain Socket which the manager ++thread listens on. mdadm sends a message over this socket. The ++manager thread examines the message to see if it will require ++allocating any memory and allocates it. This is done in the ++'prepare_update' metadata method. ++ ++The update message is then queued for handling by the monitor thread ++which it will do when convenient. The monitor thread calls ++->process_update which should atomically make the required changes to ++the metadata, making use of the pre-allocate memory as required. Any ++memory the is no-longer needed can be placed back in the request and ++the manager thread will free it. ++ ++The exact format of a metadata update is up to the implementer of the ++metadata handlers. It will simply describe a change that needs to be ++made. It will sometimes contain fragments of the metadata to be ++copied in to place. However the ->process_update routine must make ++sure not to over-write any field that the monitor thread might have ++updated, such as a 'device failed' or 'array is dirty' state. ++ ++When the monitor thread has completed the update and written it to the ++devices, an acknowledgement message is sent back over the socket so ++that mdadm knows it is complete. +diff --git a/external-reshape-design.txt b/external-reshape-design.txt +deleted file mode 100644 +index e4cf4e16..00000000 +--- a/external-reshape-design.txt ++++ /dev/null +@@ -1,280 +0,0 @@ +-External Reshape +- +-1 Problem statement +- +-External (third-party metadata) reshape differs from native-metadata +-reshape in three key ways: +- +-1.1 Format specific constraints +- +-In the native case reshape is limited by what is implemented in the +-generic reshape routine (Grow_reshape()) and what is supported by the +-kernel. There are exceptional cases where Grow_reshape() may block +-operations when it knows that the kernel implementation is broken, but +-otherwise the kernel is relied upon to be the final arbiter of what +-reshape operations are supported. +- +-In the external case the kernel, and the generic checks in +-Grow_reshape(), become the super-set of what reshapes are possible. The +-metadata format may not support, or have yet to implement a given +-reshape type. The implication for Grow_reshape() is that it must query +-the metadata handler and effect changes in the metadata before the new +-geometry is posted to the kernel. The ->reshape_super method allows +-Grow_reshape() to validate the requested operation and post the metadata +-update. +- +-1.2 Scope of reshape +- +-Native metadata reshape is always performed at the array scope (no +-metadata relationship with sibling arrays on the same disks). External +-reshape, depending on the format, may not allow the number of member +-disks to be changed in a subarray unless the change is simultaneously +-applied to all subarrays in the container. For example the imsm format +-requires all member disks to be a member of all subarrays, so a 4-disk +-raid5 in a container that also houses a 4-disk raid10 array could not be +-reshaped to 5 disks as the imsm format does not support a 5-disk raid10 +-representation. This requires the ->reshape_super method to check the +-contents of the array and ask the user to run the reshape at container +-scope (if all subarrays are agreeable to the change), or report an +-error in the case where one subarray cannot support the change. +- +-1.3 Monitoring / checkpointing +- +-Reshape, unlike rebuild/resync, requires strict checkpointing to survive +-interrupted reshape operations. For example when expanding a raid5 +-array the first few stripes of the array will be overwritten in a +-destructive manner. When restarting the reshape process we need to know +-the exact location of the last successfully written stripe, and we need +-to restore the data in any partially overwritten stripe. Native +-metadata stores this backup data in the unused portion of spares that +-are being promoted to array members, or in an external backup file +-(located on a non-involved block device). +- +-The kernel is in charge of recording checkpoints of reshape progress, +-but mdadm is delegated the task of managing the backup space which +-involves: +-1/ Identifying what data will be overwritten in the next unit of reshape +- operation +-2/ Suspending access to that region so that a snapshot of the data can +- be transferred to the backup space. +-3/ Allowing the kernel to reshape the saved region and setting the +- boundary for the next backup. +- +-In the external reshape case we want to preserve this mdadm +-'reshape-manager' arrangement, but have a third actor, mdmon, to +-consider. It is tempting to give the role of managing reshape to mdmon, +-but that is counter to its role as a monitor, and conflicts with the +-existing capabilities and role of mdadm to manage the progress of +-reshape. For clarity the external reshape implementation maintains the +-role of mdmon as a (mostly) passive recorder of raid events, and mdadm +-treats it as it would the kernel in the native reshape case (modulo +-needing to send explicit metadata update messages and checking that +-mdmon took the expected action). +- +-External reshape can use the generic md backup file as a fallback, but in the +-optimal/firmware-compatible case the reshape-manager will use the metadata +-specific areas for managing reshape. The implementation also needs to spawn a +-reshape-manager per subarray when the reshape is being carried out at the +-container level. For these two reasons the ->manage_reshape() method is +-introduced. This method in addition to base tasks mentioned above: +-1/ Processed each subarray one at a time in series - where appropriate. +-2/ Uses either generic routines in Grow.c for md-style backup file +- support, or uses the metadata-format specific location for storing +- recovery data. +-This aims to avoid a "midlayer mistake"[1] and lets the metadata handler +-optionally take advantage of generic infrastructure in Grow.c +- +-2 Details for specific reshape requests +- +-There are quite a few moving pieces spread out across md, mdadm, and mdmon for +-the support of external reshape, and there are several different types of +-reshape that need to be comprehended by the implementation. A rundown of +-these details follows. +- +-2.0 General provisions: +- +-Obtain an exclusive open on the container to make sure we are not +-running concurrently with a Create() event. +- +-2.1 Freezing sync_action +- +- Before making any attempt at a reshape we 'freeze' every array in +- the container to ensure no spare assignment or recovery happens. +- This involves writing 'frozen' to sync_action and changing the '/' +- after 'external:' in metadata_version to a '-'. mdmon knows that +- this means not to perform any management. +- +- Before doing this we check that all sync_actions are 'idle', which +- is racy but still useful. +- Afterwards we check that all member arrays have no spares +- or partial spares (recovery_start != 'none') which would indicate a +- race. If they do, we unfreeze again. +- +- Once this completes we know all the arrays are stable. They may +- still have failed devices as devices can fail at any time. However +- we treat those like failures that happen during the reshape. +- +-2.2 Reshape size +- +- 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally +- initializes st->update_tail +- 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the size change +- is allowed (being performed at subarray scope / enough room) prepares a +- metadata update +- 3/ mdadm::Grow_reshape(): flushes the metadata update (via +- flush_metadata_update(), or ->sync_metadata()) +- 4/ mdadm::Grow_reshape(): post the new size to the kernel +- +- +-2.3 Reshape level (simple-takeover) +- +-"simple-takeover" implies the level change can be satisfied without touching +-sync_action +- +- 1/ mdadm::Grow_reshape(): checks if mdmon is running and optionally +- initializes st->update_tail +- 2/ mdadm::Grow_reshape() calls ->reshape_super() to check that the level change +- is allowed (being performed at subarray scope) prepares a +- metadata update +- 2a/ raid10 --> raid0: degrade all mirror legs prior to calling +- ->reshape_super +- 3/ mdadm::Grow_reshape(): flushes the metadata update (via +- flush_metadata_update(), or ->sync_metadata()) +- 4/ mdadm::Grow_reshape(): post the new level to the kernel +- +-2.4 Reshape chunk, layout +- +-2.5 Reshape raid disks (grow) +- +- 1/ mdadm::Grow_reshape(): unconditionally initializes st->update_tail +- because only redundant raid levels can modify the number of raid disks +- 2/ mdadm::Grow_reshape(): calls ->reshape_super() to check that the level +- change is allowed (being performed at proper scope / permissible +- geometry / proper spares available in the container), chooses +- the spares to use, and prepares a metadata update. +- 3/ mdadm::Grow_reshape(): Converts each subarray in the container to the +- raid level that can perform the reshape and starts mdmon. +- 4/ mdadm::Grow_reshape(): Pushes the update to mdmon. +- 5/ mdadm::Grow_reshape(): uses container_content to find details of +- the spares and passes them to the kernel. +- 6/ mdadm::Grow_reshape(): gives raid_disks update to the kernel, +- sets sync_max, sync_min, suspend_lo, suspend_hi all to zero, +- and starts the reshape by writing 'reshape' to sync_action. +- 7/ mdmon::monitor notices the sync_action change and tells +- managemon to check for new devices. managemon notices the new +- devices, opens relevant sysfs file, and passes them all to +- monitor. +- 8/ mdadm::Grow_reshape() calls ->manage_reshape to oversee the +- rest of the reshape. +- +- 9/ mdadm::->manage_reshape(): saves data that will be overwritten by +- the kernel to either the backup file or the metadata specific location, +- advances sync_max, waits for reshape, ping mdmon, repeat. +- Meanwhile mdmon::read_and_act(): records checkpoints. +- Specifically. +- +- 9a/ if the 'next' stripe to be reshaped will over-write +- itself during reshape then: +- 9a.1/ increase suspend_hi to cover a suitable number of +- stripes. +- 9a.2/ backup those stripes safely. +- 9a.3/ advance sync_max to allow those stripes to be backed up +- 9a.4/ when sync_completed indicates that those stripes have +- been reshaped, manage_reshape must ping_manager +- 9a.5/ when mdmon notices that sync_completed has been updated, +- it records the new checkpoint in the metadata +- 9a.6/ after the ping_manager, manage_reshape will increase +- suspend_lo to allow access to those stripes again +- +- 9b/ if the 'next' stripe to be reshaped will over-write unused +- space during reshape then we apply same process as above, +- except that there is no need to back anything up. +- Note that we *do* need to keep suspend_hi progressing as +- it is not safe to write to the area-under-reshape. For +- kernel-managed-metadata this protection is provided by +- ->reshape_safe, but that does not protect us in the case +- of user-space-managed-metadata. +- +- 10/ mdadm::->manage_reshape(): Once reshape completes changes the raid +- level back to the nominal raid level (if necessary) +- +- FIXME: native metadata does not have the capability to record the original +- raid level in reshape-restart case because the kernel always records current +- raid level to the metadata, whereas external metadata can masquerade at an +- alternate level based on the reshape state. +- +-2.6 Reshape raid disks (shrink) +- +-3 Interaction with metadata handle. +- +- The following calls are made into the metadata handler to assist +- with initiating and monitoring a 'reshape'. +- +- 1/ ->reshape_super is called quite early (after only minimial +- checks) to make sure that the metadata can record the new shape +- and any necessary transitions. It may be passed a 'container' +- or an individual array within a container, and it should notice +- the difference and act accordingly. +- When a reshape is requested against a container it is expected +- that it should be applied to every array in the container, +- however it is up to the metadata handler to determine final +- policy. +- +- If the reshape is supportable, the internal copy of the metadata +- should be updated, and a metadata update suitable for sending +- to mdmon should be queued. +- +- If the reshape will involve converting spares into array members, +- this must be recorded in the metadata too. +- +- 2/ ->container_content will be called to find out the new state +- of all the array, or all arrays in the container. Any newly +- added devices (with state==0 and raid_disk >= 0) will be added +- to the array as spares with the relevant slot number. +- +- It is likely that the info returned by ->container_content will +- have ->reshape_active set, ->reshape_progress set to e.g. 0, and +- new_* set appropriately. mdadm will use this information to +- cause the correct reshape to start at an appropriate time. +- +- 3/ ->set_array_state will be called by mdmon when reshape has +- started and again periodically as it progresses. This should +- record the ->last_checkpoint as the point where reshape has +- progressed to. When the reshape finished this will be called +- again and it should notice that ->curr_action is no longer +- 'reshape' and so should record that the reshape has finished +- providing 'last_checkpoint' has progressed suitably. +- +- 4/ ->manage_reshape will be called once the reshape has been set +- up in the kernel but before sync_max has been moved from 0, so +- no actual reshape will have happened. +- +- ->manage_reshape should call progress_reshape() to allow the +- reshape to progress, and should back-up any data as indicated +- by the return value. See the documentation of that function +- for more details. +- ->manage_reshape will be called multiple times when a +- container is being reshaped, once for each member array in +- the container. +- +- +- The progress of the metadata is as follows: +- 1/ mdadm sends a metadata update to mdmon which marks the array +- as undergoing a reshape. This is set up by +- ->reshape_super and applied by ->process_update +- For container-wide reshape, this happens once for the whole +- container. +- 2/ mdmon notices progress via the sysfs files and calls +- ->set_array_state to update the state periodically +- For container-wide reshape, this happens repeatedly for +- one array, then repeatedly for the next, etc. +- 3/ mdmon notices when reshape has finished and call +- ->set_array_state to record the the reshape is complete. +- For container-wide reshape, this happens once for each +- member array. +- +- +- +-... +- +-[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/ +diff --git a/mdadm.conf-example b/mdadm.conf-example +deleted file mode 100644 +index 35a75d12..00000000 +--- a/mdadm.conf-example ++++ /dev/null +@@ -1,65 +0,0 @@ +-# mdadm configuration file +-# +-# mdadm will function properly without the use of a configuration file, +-# but this file is useful for keeping track of arrays and member disks. +-# In general, a mdadm.conf file is created, and updated, after arrays +-# are created. This is the opposite behavior of /etc/raidtab which is +-# created prior to array construction. +-# +-# +-# the config file takes two types of lines: +-# +-# DEVICE lines specify a list of devices of where to look for +-# potential member disks +-# +-# ARRAY lines specify information about how to identify arrays so +-# so that they can be activated +-# +-# You can have more than one device line and use wild cards. The first +-# example includes SCSI the first partition of SCSI disks /dev/sdb, +-# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second +-# line looks for array slices on IDE disks. +-# +-#DEVICE /dev/sd[bcdjkl]1 +-#DEVICE /dev/hda1 /dev/hdb1 +-# +-# If you mount devfs on /dev, then a suitable way to list all devices is: +-#DEVICE /dev/discs/*/* +-# +-# +-# The AUTO line can control which arrays get assembled by auto-assembly, +-# meaing either "mdadm -As" when there are no 'ARRAY' lines in this file, +-# or "mdadm --incremental" when the array found is not listed in this file. +-# By default, all arrays that are found are assembled. +-# If you want to ignore all DDF arrays (maybe they are managed by dmraid), +-# and only assemble 1.x arrays if which are marked for 'this' homehost, +-# but assemble all others, then use +-#AUTO -ddf homehost -1.x +all +-# +-# ARRAY lines specify an array to assemble and a method of identification. +-# Arrays can currently be identified by using a UUID, superblock minor number, +-# or a listing of devices. +-# +-# super-minor is usually the minor number of the metadevice +-# UUID is the Universally Unique Identifier for the array +-# Each can be obtained using +-# +-# mdadm -D +-# +-#ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 +-#ARRAY /dev/md1 super-minor=1 +-#ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 +-# +-# ARRAY lines can also specify a "spare-group" for each array. mdadm --monitor +-# will then move a spare between arrays in a spare-group if one array has a failed +-# drive but no spare +-#ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df spare-group=group1 +-#ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 spare-group=group1 +-# +-# When used in --follow (aka --monitor) mode, mdadm needs a +-# mail address and/or a program. This can be given with "mailaddr" +-# and "program" lines to that monitoring can be started using +-# mdadm --follow --scan & echo $! > /run/mdadm/mon.pid +-# If the lines are not found, mdadm will exit quietly +-#MAILADDR root@mydomain.tld +-#PROGRAM /usr/sbin/handle-mdadm-events +diff --git a/mdmon-design.txt b/mdmon-design.txt +deleted file mode 100644 +index f09184a9..00000000 +--- a/mdmon-design.txt ++++ /dev/null +@@ -1,146 +0,0 @@ +- +-When managing a RAID1 array which uses metadata other than the +-"native" metadata understood by the kernel, mdadm makes use of a +-partner program named 'mdmon' to manage some aspects of updating +-that metadata and synchronising the metadata with the array state. +- +-This document provides some details on how mdmon works. +- +-Containers +----------- +- +-As background: mdadm makes a distinction between an 'array' and a +-'container'. Other sources sometimes use the term 'volume' or +-'device' for an 'array', and may use the term 'array' for a +-'container'. +- +-For our purposes: +- - a 'container' is a collection of devices which are described by a +- single set of metadata. The metadata may be stored equally +- on all devices, or different devices may have quite different +- subsets of the total metadata. But there is conceptually one set +- of metadata that unifies the devices. +- +- - an 'array' is a set of datablock from various devices which +- together are used to present the abstraction of a single linear +- sequence of block, which may provide data redundancy or enhanced +- performance. +- +-So a container has some metadata and provides a number of arrays which +-are described by that metadata. +- +-Sometimes this model doesn't work perfectly. For example, global +-spares may have their own metadata which is quite different from the +-metadata from any device that participates in one or more arrays. +-Such a global spare might still need to belong to some container so +-that it is available to be used should a failure arise. In that case +-we consider the 'metadata' to be the union of the metadata on the +-active devices which describes the arrays, and the metadata on the +-global spares which only describes the spares. In this case different +-devices in the one container will have quite different metadata. +- +- +-Purpose +-------- +- +-The main purpose of mdmon is to update the metadata in response to +-changes to the array which need to be reflected in the metadata before +-futures writes to the array can safely be performed. +-These include: +- - transitions from 'clean' to 'dirty'. +- - recording the devices have failed. +- - recording the progress of a 'reshape' +- +-This requires mdmon to be running at any time that the array is +-writable (a read-only array does not require mdmon to be running). +- +-Because mdmon must be able to process these metadata updates at any +-time, it must (when running) have exclusive write access to the +-metadata. Any other changes (e.g. reconfiguration of the array) must +-go through mdmon. +- +-A secondary role for mdmon is to activate spares when a device fails. +-This role is much less time-critical than the other metadata updates, +-so it could be performed by a separate process, possibly +-"mdadm --monitor" which has a related role of moving devices between +-arrays. A main reason for including this functionality in mdmon is +-that in the native-metadata case this function is handled in the +-kernel, and mdmon's reason for existence to provide functionality +-which is otherwise handled by the kernel. +- +- +-Design overview +---------------- +- +-mdmon is structured as two threads with a common address space and +-common data structures. These threads are know as the 'monitor' and +-the 'manager'. +- +-The 'monitor' has the primary role of monitoring the array for +-important state changes and updating the metadata accordingly. As +-writes to the array can be blocked until 'monitor' completes and +-acknowledges the update, it much be very careful not to block itself. +-In particular it must not block waiting for any write to complete else +-it could deadlock. This means that it must not allocate memory as +-doing this can require dirty memory to be written out and if the +-system choose to write to the array that mdmon is monitoring, the +-memory allocation could deadlock. +- +-So 'monitor' must never allocate memory and must limit the number of +-other system call it performs. It may: +- - use select (or poll) to wait for activity on a file descriptor +- - read from a sysfs file descriptor +- - write to a sysfs file descriptor +- - write the metadata out to the block devices using O_DIRECT +- - send a signal (kill) to the manager thread +- +-It must not e.g. open files or do anything similar that might allocate +-resources. +- +-The 'manager' thread does everything else that is needed. If any +-files are to be opened (e.g. because a device has been added to the +-array), the manager does that. If any memory needs to be allocated +-(e.g. to hold data about a new array as can happen when one set of +-metadata describes several arrays), the manager performs that +-allocation. +- +-The 'manager' is also responsible for communicating with mdadm and +-assigning spares to replace failed devices. +- +- +-Handling metadata updates +-------------------------- +- +-There are a number of cases in which mdadm needs to update the +-metdata which mdmon is managing. These include: +- - creating a new array in an active container +- - adding a device to a container +- - reconfiguring an array +-etc. +- +-To complete these updates, mdadm must send a message to mdmon which +-will merge the update into the metadata as it is at that moment. +- +-To achieve this, mdmon creates a Unix Domain Socket which the manager +-thread listens on. mdadm sends a message over this socket. The +-manager thread examines the message to see if it will require +-allocating any memory and allocates it. This is done in the +-'prepare_update' metadata method. +- +-The update message is then queued for handling by the monitor thread +-which it will do when convenient. The monitor thread calls +-->process_update which should atomically make the required changes to +-the metadata, making use of the pre-allocate memory as required. Any +-memory the is no-longer needed can be placed back in the request and +-the manager thread will free it. +- +-The exact format of a metadata update is up to the implementer of the +-metadata handlers. It will simply describe a change that needs to be +-made. It will sometimes contain fragments of the metadata to be +-copied in to place. However the ->process_update routine must make +-sure not to over-write any field that the monitor thread might have +-updated, such as a 'device failed' or 'array is dirty' state. +- +-When the monitor thread has completed the update and written it to the +-devices, an acknowledgement message is sent back over the socket so +-that mdadm knows it is complete. +-- +2.40.1 + diff --git a/SOURCES/0020-Detail-remove-duplicated-code.patch b/SOURCES/0020-Detail-remove-duplicated-code.patch new file mode 100644 index 0000000..17db9ae --- /dev/null +++ b/SOURCES/0020-Detail-remove-duplicated-code.patch @@ -0,0 +1,75 @@ +From 60c19530dd7cc6b38a75695a0a3d004bbe60d430 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Feb 2024 03:36:14 +0100 +Subject: [PATCH 20/41] Detail: remove duplicated code + +Remove duplicated code from Detail(), where MD_UUID and MD_DEVNAME +are being set. Superblock is no longer required to print system +properties. Now it tries to obtain map in two ways. + +Signed-off-by: Kinga Tanska +Signed-off-by: Mariusz Tkaczyk +--- + Detail.c | 33 +++++++++++++-------------------- + 1 file changed, 13 insertions(+), 20 deletions(-) + +diff --git a/Detail.c b/Detail.c +index aaa3dd6e..f23ec16f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -226,6 +226,9 @@ int Detail(char *dev, struct context *c) + str = map_num(pers, array.level); + + if (c->export) { ++ char nbuf[64]; ++ struct map_ent *mp = NULL, *map = NULL; ++ + if (array.raid_disks) { + if (str) + printf("MD_LEVEL=%s\n", str); +@@ -247,32 +250,22 @@ int Detail(char *dev, struct context *c) + array.minor_version); + } + +- if (st && st->sb && info) { +- char nbuf[64]; +- struct map_ent *mp, *map = NULL; +- +- fname_from_uuid(st, info, nbuf, ':'); +- printf("MD_UUID=%s\n", nbuf + 5); ++ if (info) + mp = map_by_uuid(&map, info->uuid); ++ if (!mp) ++ mp = map_by_devnm(&map, fd2devnm(fd)); + +- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) ++ if (mp) { ++ __fname_from_uuid(mp->uuid, 0, nbuf, ':'); ++ printf("MD_UUID=%s\n", nbuf + 5); ++ if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) + printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); ++ } + ++ map_free(map); ++ if (st && st->sb) { + if (st->ss->export_detail_super) + st->ss->export_detail_super(st); +- map_free(map); +- } else { +- struct map_ent *mp, *map = NULL; +- char nbuf[64]; +- mp = map_by_devnm(&map, fd2devnm(fd)); +- if (mp) { +- __fname_from_uuid(mp->uuid, 0, nbuf, ':'); +- printf("MD_UUID=%s\n", nbuf+5); +- } +- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) +- printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); +- +- map_free(map); + } + if (!c->no_devices && sra) { + struct mdinfo *mdi; +-- +2.40.1 + diff --git a/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch b/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch deleted file mode 100644 index f51c730..0000000 --- a/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001 -From: Nigel Croxon -Date: Mon, 18 Apr 2022 13:44:23 -0400 -Subject: [PATCH 20/83] Revert "mdadm: fix coredump of mdadm --monitor -r" - -This reverts commit 546047688e1c64638f462147c755b58119cabdc8. - -The change from commit mdadm: fix coredump of mdadm ---monitor -r broke the printing of the return message when -passing -r to mdadm --manage, the removal of a device from -an array. - -If the current code reverts this commit, both issues are -still fixed. - -The original problem reported that the fix tried to address -was: The --monitor -r option requires a parameter, -otherwise a null pointer will be manipulated when -converting to integer data, and a core dump will appear. - -The original problem was really fixed with: -60815698c0a Refactor parse_num and use it to parse optarg. -Which added a check for NULL in 'optarg' before moving it -to the 'increments' variable. - -New issue: When trying to remove a device using the short -argument -r, instead of the long argument --remove, the -output is empty. The problem started when commit -546047688e1c was added. - -Steps to Reproduce: -1. create/assemble /dev/md0 device -2. mdadm --manage /dev/md0 -r /dev/vdxx - -Actual results: -Nothing, empty output, nothing happens, the device is still -connected to the array. - -The output should have stated "mdadm: hot remove failed -for /dev/vdxx: Device or resource busy", if the device was -still active. Or it should remove the device and print -a message: - -mdadm: set /dev/vdd faulty in /dev/md0 -mdadm: hot removed /dev/vdd from /dev/md0 - -The following commit should be reverted as it breaks -mdadm --manage -r. - -commit 546047688e1c64638f462147c755b58119cabdc8 -Author: Wu Guanghao -Date: Mon Aug 16 15:24:51 2021 +0800 -mdadm: fix coredump of mdadm --monitor -r - --Nigel - -Signed-off-by: Nigel Croxon -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 8f873c48..bec1be9a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -81,11 +81,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - * found, it is started. - */ - --char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k"; -+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; - - struct option long_options[] = { - {"manage", 0, 0, ManageOpt}, --- -2.38.1 - diff --git a/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch b/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch new file mode 100644 index 0000000..97f8115 --- /dev/null +++ b/SOURCES/0021-mdadm-Add-functions-for-spare-criteria-verification.patch @@ -0,0 +1,286 @@ +From 0c0f09cb035b6a27a1d11c54836742a9945a5014 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:05 +0100 +Subject: [PATCH 21/41] mdadm: Add functions for spare criteria verification + +It is done similar way in few places. As a result, two almost identical +functions (dev_size_from_id() and dev_sector_size_from_id()) are +removed. Now, it uses same file descriptor to send two ioctls. + +Two extern functions are added, in next patches +disk_fd_matches_criteria() is used. + +Next optimization is inline zeroing struct spare_criteria. With that, +we don't need to reset values in get_spare_criteria_imsm(). + +Dedicated boolean field for checking if criteria are filled is added. +We don't need to execute the code if it is not set. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 2 +- + Monitor.c | 14 +------ + mdadm.h | 6 ++- + super-intel.c | 4 +- + util.c | 112 ++++++++++++++++++++++++++------------------------ + 5 files changed, 67 insertions(+), 71 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 30c07c03..2b5a5859 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -874,7 +874,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct domainlist *dl = NULL; + struct mdinfo *sra; + unsigned long long devsize, freesize = 0; +- struct spare_criteria sc = {0, 0}; ++ struct spare_criteria sc = {0}; + + if (is_subarray(mp->metadata)) + continue; +diff --git a/Monitor.c b/Monitor.c +index 9be2b528..1ece8712 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1070,22 +1070,12 @@ static dev_t choose_spare(struct state *from, struct state *to, + for (d = from->raid; !dev && d < MAX_DISKS; d++) { + if (from->devid[d] > 0 && from->devstate[d] == 0) { + struct dev_policy *pol; +- unsigned long long dev_size; +- unsigned int dev_sector_size; + + if (to->metadata->ss->external && + test_partition_from_id(from->devid[d])) + continue; + +- if (sc->min_size && +- dev_size_from_id(from->devid[d], &dev_size) && +- dev_size < sc->min_size) +- continue; +- +- if (sc->sector_size && +- dev_sector_size_from_id(from->devid[d], +- &dev_sector_size) && +- sc->sector_size != dev_sector_size) ++ if (devid_matches_criteria(from->devid[d], sc) == false) + continue; + + pol = devid_policy(from->devid[d]); +@@ -1170,12 +1160,12 @@ static void try_spare_migration(struct state *statelist) + { + struct state *from; + struct state *st; +- struct spare_criteria sc; + + link_containers_with_subarrays(statelist); + for (st = statelist; st; st = st->next) + if (st->active < st->raid && st->spare == 0 && !st->err) { + struct domainlist *domlist = NULL; ++ struct spare_criteria sc = {0}; + int d; + struct state *to = st; + +diff --git a/mdadm.h b/mdadm.h +index 75c887e4..e8abd730 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -430,6 +430,7 @@ struct createinfo { + }; + + struct spare_criteria { ++ bool criteria_set; + unsigned long long min_size; + unsigned int sector_size; + }; +@@ -1368,8 +1369,6 @@ extern struct supertype *dup_super(struct supertype *st); + extern int get_dev_size(int fd, char *dname, unsigned long long *sizep); + extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep); + extern int must_be_container(int fd); +-extern int dev_size_from_id(dev_t id, unsigned long long *size); +-extern int dev_sector_size_from_id(dev_t id, unsigned int *size); + void wait_for(char *dev, int fd); + + /* +@@ -1708,6 +1707,9 @@ extern int assemble_container_content(struct supertype *st, int mdfd, + #define INCR_UNSAFE 2 + #define INCR_ALREADY 4 + #define INCR_YES 8 ++ ++extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc); ++extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc); + extern struct mdinfo *container_choose_spares(struct supertype *st, + struct spare_criteria *criteria, + struct domainlist *domlist, +diff --git a/super-intel.c b/super-intel.c +index 4babec9f..39ec4754 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1748,9 +1748,6 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) + int i; + unsigned long long size = 0; + +- c->min_size = 0; +- c->sector_size = 0; +- + if (!super) + return -EINVAL; + /* find first active disk in array */ +@@ -1774,6 +1771,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) + + c->min_size = size * 512; + c->sector_size = super->sector_size; ++ c->criteria_set = true; + + return 0; + } +diff --git a/util.c b/util.c +index b1454473..041e78cf 100644 +--- a/util.c ++++ b/util.c +@@ -1266,40 +1266,6 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + return st; + } + +-int dev_size_from_id(dev_t id, unsigned long long *size) +-{ +- char buf[20]; +- int fd; +- +- sprintf(buf, "%d:%d", major(id), minor(id)); +- fd = dev_open(buf, O_RDONLY); +- if (fd < 0) +- return 0; +- if (get_dev_size(fd, NULL, size)) { +- close(fd); +- return 1; +- } +- close(fd); +- return 0; +-} +- +-int dev_sector_size_from_id(dev_t id, unsigned int *size) +-{ +- char buf[20]; +- int fd; +- +- sprintf(buf, "%d:%d", major(id), minor(id)); +- fd = dev_open(buf, O_RDONLY); +- if (fd < 0) +- return 0; +- if (get_dev_sector_size(fd, NULL, size)) { +- close(fd); +- return 1; +- } +- close(fd); +- return 0; +-} +- + struct supertype *dup_super(struct supertype *orig) + { + struct supertype *st; +@@ -2088,6 +2054,60 @@ void append_metadata_update(struct supertype *st, void *buf, int len) + unsigned int __invalid_size_argument_for_IOC = 0; + #endif + ++/** ++ * disk_fd_matches_criteria() - check if device matches spare criteria. ++ * @disk_fd: file descriptor of the disk. ++ * @sc: criteria to test. ++ * ++ * Return: true if disk matches criteria, false otherwise. ++ */ ++bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) ++{ ++ unsigned int dev_sector_size = 0; ++ unsigned long long dev_size = 0; ++ ++ if (!sc->criteria_set) ++ return true; ++ ++ if (!get_dev_size(disk_fd, NULL, &dev_size) || dev_size < sc->min_size) ++ return false; ++ ++ if (!get_dev_sector_size(disk_fd, NULL, &dev_sector_size) || ++ sc->sector_size != dev_sector_size) ++ return false; ++ ++ return true; ++} ++ ++/** ++ * devid_matches_criteria() - check if device referenced by devid matches spare criteria. ++ * @devid: devid of the device to check. ++ * @sc: criteria to test. ++ * ++ * Return: true if disk matches criteria, false otherwise. ++ */ ++bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) ++{ ++ char buf[NAME_MAX]; ++ bool ret; ++ int fd; ++ ++ if (!sc->criteria_set) ++ return true; ++ ++ snprintf(buf, NAME_MAX, "%d:%d", major(devid), minor(devid)); ++ ++ fd = dev_open(buf, O_RDONLY); ++ if (!is_fd_valid(fd)) ++ return false; ++ ++ /* Error code inherited */ ++ ret = disk_fd_matches_criteria(fd, sc); ++ ++ close(fd); ++ return ret; ++} ++ + /* Pick all spares matching given criteria from a container + * if min_size == 0 do not check size + * if domlist == NULL do not check domains +@@ -2111,28 +2131,13 @@ struct mdinfo *container_choose_spares(struct supertype *st, + dp = &disks->devs; + disks->array.spare_disks = 0; + while (*dp) { +- int found = 0; ++ bool found = false; ++ + d = *dp; + if (d->disk.state == 0) { +- /* check if size is acceptable */ +- unsigned long long dev_size; +- unsigned int dev_sector_size; +- int size_valid = 0; +- int sector_size_valid = 0; +- + dev_t dev = makedev(d->disk.major,d->disk.minor); + +- if (!criteria->min_size || +- (dev_size_from_id(dev, &dev_size) && +- dev_size >= criteria->min_size)) +- size_valid = 1; +- +- if (!criteria->sector_size || +- (dev_sector_size_from_id(dev, &dev_sector_size) && +- criteria->sector_size == dev_sector_size)) +- sector_size_valid = 1; +- +- found = size_valid && sector_size_valid; ++ found = devid_matches_criteria(dev, criteria); + + /* check if domain matches */ + if (found && domlist) { +@@ -2141,7 +2146,8 @@ struct mdinfo *container_choose_spares(struct supertype *st, + pol_add(&pol, pol_domain, + spare_group, NULL); + if (domain_test(domlist, pol, metadata) != 1) +- found = 0; ++ found = false; ++ + dev_policy_free(pol); + } + } +-- +2.40.1 + diff --git a/SOURCES/0021-util-replace-ioctl-use-with-function.patch b/SOURCES/0021-util-replace-ioctl-use-with-function.patch deleted file mode 100644 index 56ee5e8..0000000 --- a/SOURCES/0021-util-replace-ioctl-use-with-function.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 21 Jun 2022 00:10:39 +0800 -Subject: [PATCH 21/83] util: replace ioctl use with function - -Replace using of ioctl calling to get md array info with -special function prepared to it. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util.c b/util.c -index cc94f96e..38f0420e 100644 ---- a/util.c -+++ b/util.c -@@ -267,7 +267,7 @@ int md_array_active(int fd) - * GET_ARRAY_INFO doesn't provide access to the proper state - * information, so fallback to a basic check for raid_disks != 0 - */ -- ret = ioctl(fd, GET_ARRAY_INFO, &array); -+ ret = md_get_array_info(fd, &array); - } - - return !ret; --- -2.38.1 - diff --git a/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch b/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch new file mode 100644 index 0000000..b3ebb67 --- /dev/null +++ b/SOURCES/0022-mdadm-drop-get_required_spare_criteria.patch @@ -0,0 +1,357 @@ +From f656201188d73cdc2726265f1348f8ffbf7587be Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:06 +0100 +Subject: [PATCH 22/41] mdadm: drop get_required_spare_criteria() + +Only IMSM implements get_spare_criteria, so load_super() in +get_required_spare_criteria() is dead code. It is moved inside +metadata handler, because only IMSM implements it. + +Give possibility to provide devnode to be opened. With that we can hide +load_container() used only to fill spare criteria inside handler +and simplify implementation in generic code. + +Add helper function for testing spare criteria in Incremental and +error messages. + +File descriptor in get_spare_criteria_imsm() is always opened on purpose. +New functionality added in next patches will require it. For the same +reason, function is moved to other place. + +No functional changes. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 77 ++++++++++++++++++++++---------- + Monitor.c | 35 +++------------ + mdadm.h | 5 +-- + super-intel.c | 120 +++++++++++++++++++++++++++++++++----------------- + 4 files changed, 140 insertions(+), 97 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 2b5a5859..66c2cc86 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -833,6 +833,53 @@ container_members_max_degradation(struct map_ent *map, struct map_ent *me) + return max_degraded; + } + ++/** ++ * incremental_external_test_spare_criteria() - helper to test spare criteria. ++ * @st: supertype, must be not NULL, it is duplicated here. ++ * @container_devnm: devnm of the container. ++ * @disk_fd: file descriptor of device to tested. ++ * @verbose: verbose flag. ++ * ++ * The function is used on new drive verification path to check if it can be added to external ++ * container. To test spare criteria, metadata must be loaded. It duplicates super to not mess in ++ * original one. ++ * Function is executed if superblock supports get_spare_criteria(), otherwise success is returned. ++ */ ++mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, char *container_devnm, ++ int disk_fd, int verbose) ++{ ++ mdadm_status_t rv = MDADM_STATUS_ERROR; ++ char container_devname[PATH_MAX]; ++ struct spare_criteria sc = {0}; ++ struct supertype *dup; ++ ++ if (!st->ss->get_spare_criteria) ++ return MDADM_STATUS_SUCCESS; ++ ++ dup = dup_super(st); ++ snprintf(container_devname, PATH_MAX, "/dev/%s", container_devnm); ++ ++ if (dup->ss->get_spare_criteria(dup, container_devname, &sc) != 0) { ++ if (verbose > 1) ++ pr_err("Failed to get spare criteria for %s\n", container_devname); ++ goto out; ++ } ++ ++ if (!disk_fd_matches_criteria(disk_fd, &sc)) { ++ if (verbose > 1) ++ pr_err("Disk does not match spare criteria for %s\n", container_devname); ++ goto out; ++ } ++ ++ rv = MDADM_STATUS_SUCCESS; ++ ++out: ++ dup->ss->free_super(dup); ++ free(dup); ++ ++ return rv; ++} ++ + static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct map_ent *target, int bare, + struct supertype *st, int verbose) +@@ -873,8 +920,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct supertype *st2; + struct domainlist *dl = NULL; + struct mdinfo *sra; +- unsigned long long devsize, freesize = 0; +- struct spare_criteria sc = {0}; ++ unsigned long long freesize = 0; + + if (is_subarray(mp->metadata)) + continue; +@@ -925,34 +971,19 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + if (sra->array.failed_disks == -1) + sra->array.failed_disks = container_members_max_degradation(map, mp); + +- get_dev_size(dfd, NULL, &devsize); + if (sra->component_size == 0) { +- /* true for containers, here we must read superblock +- * to obtain minimum spare size */ +- struct supertype *st3 = dup_super(st2); +- int mdfd = open_dev(mp->devnm); +- if (mdfd < 0) { +- free(st3); ++ /* true for containers */ ++ if (incremental_external_test_spare_criteria(st2, mp->devnm, dfd, verbose)) + goto next; +- } +- if (st3->ss->load_container && +- !st3->ss->load_container(st3, mdfd, mp->path)) { +- if (st3->ss->get_spare_criteria) +- st3->ss->get_spare_criteria(st3, &sc); +- st3->ss->free_super(st3); +- } +- free(st3); +- close(mdfd); + } +- if ((sra->component_size > 0 && +- st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout, ++ ++ if (sra->component_size > 0 && ++ st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout, + sra->array.raid_disks, &sra->array.chunk_size, + sra->component_size, + sra->devs ? sra->devs->data_offset : INVALID_SECTORS, + devname, &freesize, sra->consistency_policy, +- 0) && +- freesize < sra->component_size) || +- (sra->component_size == 0 && devsize < sc.min_size)) { ++ 0) && freesize < sra->component_size) { + if (verbose > 1) + pr_err("not adding %s to %s as it is too small\n", + devname, mp->path); +diff --git a/Monitor.c b/Monitor.c +index 1ece8712..6b4560ae 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1008,34 +1008,6 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) + return new_found; + } + +-static int get_required_spare_criteria(struct state *st, +- struct spare_criteria *sc) +-{ +- int fd; +- +- if (!st->metadata || !st->metadata->ss->get_spare_criteria) { +- sc->min_size = 0; +- sc->sector_size = 0; +- return 0; +- } +- +- fd = open(st->devname, O_RDONLY); +- if (fd < 0) +- return 1; +- if (st->metadata->ss->external) +- st->metadata->ss->load_container(st->metadata, fd, st->devname); +- else +- st->metadata->ss->load_super(st->metadata, fd, st->devname); +- close(fd); +- if (!st->metadata->sb) +- return 1; +- +- st->metadata->ss->get_spare_criteria(st->metadata, sc); +- st->metadata->ss->free_super(st->metadata); +- +- return 0; +-} +- + static int check_donor(struct state *from, struct state *to) + { + struct state *sub; +@@ -1178,8 +1150,11 @@ static void try_spare_migration(struct state *statelist) + /* member of a container */ + to = to->parent; + +- if (get_required_spare_criteria(to, &sc)) +- continue; ++ if (to->metadata->ss->get_spare_criteria) ++ if (to->metadata->ss->get_spare_criteria(to->metadata, to->devname, ++ &sc)) ++ continue; ++ + if (to->metadata->ss->external) { + /* We must make sure there is + * no suitable spare in container already. +diff --git a/mdadm.h b/mdadm.h +index e8abd730..cbc586f5 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1116,10 +1116,9 @@ extern struct superswitch { + * Return spare criteria for array: + * - minimum disk size can be used in array; + * - sector size can be used in array. +- * Return values: 0 - for success and -EINVAL on error. + */ +- int (*get_spare_criteria)(struct supertype *st, +- struct spare_criteria *sc); ++ mdadm_status_t (*get_spare_criteria)(struct supertype *st, char *mddev_path, ++ struct spare_criteria *sc); + /* Find somewhere to put a bitmap - possibly auto-size it - and + * update the metadata to record this. The array may be newly + * created, in which case data_size may be updated, or it might +diff --git a/super-intel.c b/super-intel.c +index 39ec4754..7ad391ac 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1736,46 +1736,6 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super) + return (remainder < rv) ? remainder : rv; + } + +-/* +- * Return minimum size of a spare and sector size +- * that can be used in this array +- */ +-int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) +-{ +- struct intel_super *super = st->sb; +- struct dl *dl; +- struct extent *e; +- int i; +- unsigned long long size = 0; +- +- if (!super) +- return -EINVAL; +- /* find first active disk in array */ +- dl = super->disks; +- while (dl && (is_failed(&dl->disk) || dl->index == -1)) +- dl = dl->next; +- if (!dl) +- return -EINVAL; +- /* find last lba used by subarrays */ +- e = get_extents(super, dl, 0); +- if (!e) +- return -EINVAL; +- for (i = 0; e[i].size; i++) +- continue; +- if (i > 0) +- size = e[i-1].start + e[i-1].size; +- free(e); +- +- /* add the amount of space needed for metadata */ +- size += imsm_min_reserved_sectors(super); +- +- c->min_size = size * 512; +- c->sector_size = super->sector_size; +- c->criteria_set = true; +- +- return 0; +-} +- + static bool is_gen_migration(struct imsm_dev *dev); + + #define IMSM_4K_DIV 8 +@@ -11295,6 +11255,84 @@ static const char *imsm_get_disk_controller_domain(const char *path) + return drv; + } + ++/** ++ * get_spare_criteria_imsm() - set spare criteria. ++ * @st: supertype. ++ * @mddev_path: path to md device devnode, it must be container. ++ * @c: spare_criteria struct to fill, not NULL. ++ * ++ * If superblock is not loaded, use mddev_path to load_container. It must be given in this case. ++ * Filles size and sector size accordingly to superblock. ++ */ ++mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, ++ struct spare_criteria *c) ++{ ++ mdadm_status_t ret = MDADM_STATUS_ERROR; ++ bool free_superblock = false; ++ unsigned long long size = 0; ++ struct intel_super *super; ++ struct extent *e; ++ struct dl *dl; ++ int i; ++ ++ /* If no superblock and no mddev_path, we cannot load superblock. */ ++ assert(st->sb || mddev_path); ++ ++ if (mddev_path) { ++ int fd = open(mddev_path, O_RDONLY); ++ ++ if (!is_fd_valid(fd)) ++ return MDADM_STATUS_ERROR; ++ ++ if (!st->sb) { ++ if (load_container_imsm(st, fd, st->devnm)) { ++ close(fd); ++ return MDADM_STATUS_ERROR; ++ } ++ free_superblock = true; ++ } ++ close(fd); ++ } ++ ++ super = st->sb; ++ ++ /* find first active disk in array */ ++ dl = super->disks; ++ while (dl && (is_failed(&dl->disk) || dl->index == -1)) ++ dl = dl->next; ++ ++ if (!dl) ++ goto out; ++ ++ /* find last lba used by subarrays */ ++ e = get_extents(super, dl, 0); ++ if (!e) ++ goto out; ++ ++ for (i = 0; e[i].size; i++) ++ continue; ++ if (i > 0) ++ size = e[i - 1].start + e[i - 1].size; ++ free(e); ++ ++ /* add the amount of space needed for metadata */ ++ size += imsm_min_reserved_sectors(super); ++ ++ c->min_size = size * 512; ++ c->sector_size = super->sector_size; ++ c->criteria_set = true; ++ ret = MDADM_STATUS_SUCCESS; ++ ++out: ++ if (free_superblock) ++ free_super_imsm(st); ++ ++ if (ret != MDADM_STATUS_SUCCESS) ++ c->criteria_set = false; ++ ++ return ret; ++} ++ + static char *imsm_find_array_devnm_by_subdev(int subdev, char *container) + { + static char devnm[32]; +@@ -11425,7 +11463,7 @@ static struct mdinfo *get_spares_for_grow(struct supertype *st) + { + struct spare_criteria sc; + +- get_spare_criteria_imsm(st, &sc); ++ get_spare_criteria_imsm(st, NULL, &sc); + return container_choose_spares(st, &sc, NULL, NULL, NULL, 0); + } + +-- +2.40.1 + diff --git a/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch b/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch deleted file mode 100644 index 88bba83..0000000 --- a/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Tue, 21 Jun 2022 00:10:40 +0800 -Subject: [PATCH 22/83] mdadm/super1: restore commit 45a87c2f31335 to fix - clustered slot issue - -Commit 9d67f6496c71 ("mdadm:check the nodes when operate clustered -array") modified assignment logic for st->nodes in write_bitmap1(), -which introduced bitmap slot issue: - -load_super1 didn't set up supertype.nodes, which made spare disk only -have one slot info. Then it triggered kernel md_bitmap_load_sb to get -wrong bitmap slot data. - -For fixing this issue, there are two methods: - -1> revert the related code of commit 9d67f6496c71. and restore the code - from former commit 45a87c2f31335 ("super1: add more checks for - NodeNumUpdate option"). - st->nodes value would be 0 & 1 under current code logic. i.e. - When adding a spare disk, there is no place to init st->nodes, and - the value is ZERO. - -2> keep 9d67f6496c71, add additional ->nodes handling in load_super1(), - let load_super1 to set st->nodes when bitmap is BITMAP_MAJOR_CLUSTERED. - Under current mdadm code logic, load_super1 will be called many - times, any new code in load_super1 will cost mdadm running more time. - And more reason is I prefer as much as possible to limit clustered - code spreading in every corner. - -So I used method <1> to fix this issue. - -How to trigger: - -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdc -mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb -mdadm -a /dev/md0 /dev/sdc -mdadm /dev/md0 --fail /dev/sda -mdadm /dev/md0 --remove /dev/sda -mdadm -Ss -mdadm -A /dev/md0 /dev/sdb /dev/sdc - -the output of current "mdadm -X /dev/sdc": -(there should be (by default) 4 slot info for correct output) -``` - Filename : /dev/sdc - Magic : 6d746962 - Version : 5 - UUID : a74642f8:a6b1fba8:58e1f8db:cfe7b082 - Events : 29 - Events Cleared : 0 - State : OK - Chunksize : 64 MB - Daemon : 5s flush period - Write Mode : Normal - Sync Size : 306176 (299.00 MiB 313.52 MB) - Bitmap : 5 bits (chunks), 5 dirty (100.0%) -``` - -And mdadm later operations will trigger kernel output error message: -(triggered by "mdadm -A /dev/md0 /dev/sdb /dev/sdc") -``` -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 1 -kernel: md-cluster: Could not gather bitmaps from slot 1 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2 -kernel: md-cluster: Could not gather bitmaps from slot 2 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 3 -kernel: md-cluster: Could not gather bitmaps from slot 3 -kernel: md-cluster: failed to gather all resyn infos -kernel: md0: detected capacity change from 0 to 612352 -``` - -Acked-by: Coly Li -Signed-off-by: Heming Zhao -Signed-off-by: Jes Sorensen ---- - super1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/super1.c b/super1.c -index e3e2f954..3a0c69fd 100644 ---- a/super1.c -+++ b/super1.c -@@ -2674,7 +2674,17 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update - } - - if (bms->version == BITMAP_MAJOR_CLUSTERED) { -- if (__cpu_to_le32(st->nodes) < bms->nodes) { -+ if (st->nodes == 1) { -+ /* the parameter for nodes is not valid */ -+ pr_err("Warning: cluster-md at least needs two nodes\n"); -+ return -EINVAL; -+ } else if (st->nodes == 0) { -+ /* -+ * parameter "--nodes" is not specified, (eg, add a disk to -+ * clustered raid) -+ */ -+ break; -+ } else if (__cpu_to_le32(st->nodes) < bms->nodes) { - /* - * Since the nodes num is not increased, no - * need to check the space enough or not, --- -2.38.1 - diff --git a/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch b/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch new file mode 100644 index 0000000..eec558c --- /dev/null +++ b/SOURCES/0023-Manage-fix-check-after-dereference-issue.patch @@ -0,0 +1,64 @@ +From e97ca3583c96591af0e4863c12c394074a51c84d Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:07 +0100 +Subject: [PATCH 23/41] Manage: fix check after dereference issue + +The code dereferences dev_st earlier without checking, it gives SAST +problem. + +dev_st is needed for attempt_re_add(), but it is executed only if +dv->disposition != 'S', so move disposition check up. + +tst is a must to reach this place, dup_super() have to return valid +pointer, all it needs to check is if load_super() returns superblock. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 30302ac8..77b79cf5 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -794,25 +794,23 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + * simply re-add it. + */ + +- if (array->not_persistent == 0) { ++ if (array->not_persistent == 0 && dv->disposition != 'S') { ++ int rv = 0; ++ + dev_st = dup_super(tst); + dev_st->ss->load_super(dev_st, tfd, NULL); +- if (dev_st->sb && dv->disposition != 'S') { +- int rv; + +- rv = attempt_re_add(fd, tfd, dv, dev_st, tst, +- rdev, update, devname, +- verbose, array); +- dev_st->ss->free_super(dev_st); +- if (rv) { +- free(dev_st); +- return rv; +- } +- } +- if (dev_st) { ++ if (dev_st->sb) { ++ rv = attempt_re_add(fd, tfd, dv, dev_st, tst, rdev, update, ++ devname, verbose, array); ++ + dev_st->ss->free_super(dev_st); +- free(dev_st); + } ++ ++ free(dev_st); ++ ++ if (rv) ++ return rv; + } + if (dv->disposition == 'M') { + if (verbose > 0) +-- +2.40.1 + diff --git a/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch b/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch deleted file mode 100644 index ca1d015..0000000 --- a/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:41 +0800 -Subject: [PATCH 23/83] imsm: introduce get_disk_slot_in_dev() - -The routine was added to remove unnecessary get_imsm_dev() and -get_imsm_map() calls, used only to determine disk slot. - -Additionally, enum for IMSM return statues was added for further usage. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 47 ++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 36 insertions(+), 11 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 3788feb9..cd1f1e3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -366,6 +366,18 @@ struct migr_record { - }; - ASSERT_SIZE(migr_record, 128) - -+/** -+ * enum imsm_status - internal IMSM return values representation. -+ * @STATUS_OK: function succeeded. -+ * @STATUS_ERROR: General error ocurred (not specified). -+ * -+ * Typedefed to imsm_status_t. -+ */ -+typedef enum imsm_status { -+ IMSM_STATUS_ERROR = -1, -+ IMSM_STATUS_OK = 0, -+} imsm_status_t; -+ - struct md_list { - /* usage marker: - * 1: load metadata -@@ -1183,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord) - map->disk_ord_tbl[slot] = __cpu_to_le32(ord); - } - --static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) -+static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) - { - int slot; - __u32 ord; -@@ -1194,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) - return slot; - } - -- return -1; -+ return IMSM_STATUS_ERROR; - } - - static int get_imsm_raid_level(struct imsm_map *map) -@@ -1209,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map) - return map->raid_level; - } - -+/** -+ * get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev. -+ * @super: &intel_super pointer, not NULL. -+ * @dev_idx: imsm device index. -+ * @idx: disk index. -+ * -+ * Return: Slot on success, IMSM_STATUS_ERROR otherwise. -+ */ -+static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx, -+ const unsigned int idx) -+{ -+ struct imsm_dev *dev = get_imsm_dev(super, dev_idx); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); -+ -+ return get_imsm_disk_slot(map, idx); -+} -+ - static int cmp_extent(const void *av, const void *bv) - { - const struct extent *a = av; -@@ -1225,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super) - int memberships = 0; - int i; - -- for (i = 0; i < super->anchor->num_raid_devs; i++) { -- struct imsm_dev *dev = get_imsm_dev(super, i); -- struct imsm_map *map = get_imsm_map(dev, MAP_0); -- -- if (get_imsm_disk_slot(map, dl->index) >= 0) -+ for (i = 0; i < super->anchor->num_raid_devs; i++) -+ if (get_disk_slot_in_dev(super, i, dl->index) >= 0) - memberships++; -- } - - return memberships; - } -@@ -1941,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super) - - /* first map under migration */ - map = get_imsm_map(dev, MAP_0); -+ - if (map) - slot = get_imsm_disk_slot(map, super->disks->index); - if (map == NULL || slot > 1 || slot < 0) { -@@ -9655,10 +9681,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u, - /* count arrays using the victim in the metadata */ - found = 0; - for (a = active_array; a ; a = a->next) { -- dev = get_imsm_dev(super, a->info.container_member); -- map = get_imsm_map(dev, MAP_0); -+ int dev_idx = a->info.container_member; - -- if (get_imsm_disk_slot(map, victim) >= 0) -+ if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0) - found++; - } - --- -2.38.1 - diff --git a/SOURCES/0024-Manage-implement-manage_add_external.patch b/SOURCES/0024-Manage-implement-manage_add_external.patch new file mode 100644 index 0000000..9aa3d68 --- /dev/null +++ b/SOURCES/0024-Manage-implement-manage_add_external.patch @@ -0,0 +1,184 @@ +From 29273f606542d915a3ddf37bb084f4eff54fcc3b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:08 +0100 +Subject: [PATCH 24/41] Manage: implement manage_add_external() + +Move external add code to separate function. It is easier to control +error path now. Error messages are adjusted. + +No functional changes. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 147 ++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 86 insertions(+), 61 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 77b79cf5..b3e216cb 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -695,6 +695,91 @@ skip_re_add: + return 0; + } + ++/** ++ * manage_add_external() - Add disk to external container. ++ * @st: external supertype pointer, must not be NULL, superblock is released here. ++ * @fd: container file descriptor, must not have O_EXCL mode. ++ * @disk_fd: device to add file descriptor. ++ * @disk_name: name of the device to add. ++ * @disc: disk info. ++ * ++ * Superblock is released here because any open fd with O_EXCL will block sysfs_add_disk(). ++ */ ++mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name, ++ mdu_disk_info_t *disc) ++{ ++ mdadm_status_t rv = MDADM_STATUS_ERROR; ++ char container_devpath[MD_NAME_MAX]; ++ struct mdinfo new_mdi; ++ struct mdinfo *sra = NULL; ++ int container_fd; ++ int disk_fd = -1; ++ ++ snprintf(container_devpath, MD_NAME_MAX, "%s", fd2devnm(fd)); ++ ++ container_fd = open_dev_excl(container_devpath); ++ if (!is_fd_valid(container_fd)) { ++ pr_err("Failed to get exclusive access to container %s\n", container_devpath); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* Check if metadata handler is able to accept the drive */ ++ if (!st->ss->validate_geometry(st, LEVEL_CONTAINER, 0, 1, NULL, 0, 0, disk_name, NULL, ++ 0, 1)) ++ goto out; ++ ++ Kill(disk_name, NULL, 0, -1, 0); ++ ++ disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT); ++ if (!is_fd_valid(disk_fd)) { ++ pr_err("Failed to exclusively open %s\n", disk_name); ++ goto out; ++ } ++ ++ if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS)) ++ goto out; ++ ++ if (!mdmon_running(st->container_devnm)) ++ st->ss->sync_metadata(st); ++ ++ sra = sysfs_read(container_fd, NULL, 0); ++ if (!sra) { ++ pr_err("Failed to read sysfs for %s\n", disk_name); ++ goto out; ++ } ++ ++ sra->array.level = LEVEL_CONTAINER; ++ /* Need to set data_offset and component_size */ ++ st->ss->getinfo_super(st, &new_mdi, NULL); ++ new_mdi.disk.major = disc->major; ++ new_mdi.disk.minor = disc->minor; ++ new_mdi.recovery_start = 0; ++ ++ st->ss->free_super(st); ++ ++ if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { ++ pr_err("Failed to add %s to container %s\n", disk_name, container_devpath); ++ goto out; ++ } ++ ping_monitor(container_devpath); ++ rv = MDADM_STATUS_SUCCESS; ++ ++out: ++ close(container_fd); ++ ++ if (sra) ++ sysfs_free(sra); ++ ++ if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd)) ++ /* Metadata handler records this descriptor, so release it only on failure. */ ++ close(disk_fd); ++ ++ if (st->sb) ++ st->ss->free_super(st); ++ ++ return rv; ++} ++ + int Manage_add(int fd, int tfd, struct mddev_dev *dv, + struct supertype *tst, mdu_array_info_t *array, + int force, int verbose, char *devname, +@@ -966,68 +1051,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + if (dv->failfast == FlagSet) + disc.state |= (1 << MD_DISK_FAILFAST); + if (tst->ss->external) { +- /* add a disk +- * to an external metadata container */ +- struct mdinfo new_mdi; +- struct mdinfo *sra; +- int container_fd; +- char devnm[32]; +- int dfd; +- +- strcpy(devnm, fd2devnm(fd)); +- +- container_fd = open_dev_excl(devnm); +- if (container_fd < 0) { +- pr_err("add failed for %s: could not get exclusive access to container\n", +- dv->devname); +- tst->ss->free_super(tst); ++ if (manage_add_external(tst, fd, dv->devname, &disc) != MDADM_STATUS_SUCCESS) + goto unlock; +- } +- +- /* Check if metadata handler is able to accept the drive */ +- if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL, +- 0, 0, dv->devname, NULL, 0, 1)) { +- close(container_fd); +- goto unlock; +- } +- +- Kill(dv->devname, NULL, 0, -1, 0); +- dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); +- if (tst->ss->add_to_super(tst, &disc, dfd, +- dv->devname, INVALID_SECTORS)) { +- close(dfd); +- close(container_fd); +- goto unlock; +- } +- if (!mdmon_running(tst->container_devnm)) +- tst->ss->sync_metadata(tst); +- +- sra = sysfs_read(container_fd, NULL, 0); +- if (!sra) { +- pr_err("add failed for %s: sysfs_read failed\n", +- dv->devname); +- close(container_fd); +- tst->ss->free_super(tst); +- goto unlock; +- } +- sra->array.level = LEVEL_CONTAINER; +- /* Need to set data_offset and component_size */ +- tst->ss->getinfo_super(tst, &new_mdi, NULL); +- new_mdi.disk.major = disc.major; +- new_mdi.disk.minor = disc.minor; +- new_mdi.recovery_start = 0; +- /* Make sure fds are closed as they are O_EXCL which +- * would block add_disk */ +- tst->ss->free_super(tst); +- if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { +- pr_err("add new device to external metadata failed for %s\n", dv->devname); +- close(container_fd); +- sysfs_free(sra); +- goto unlock; +- } +- ping_monitor(devnm); +- sysfs_free(sra); +- close(container_fd); + } else { + tst->ss->free_super(tst); + if (ioctl(fd, ADD_NEW_DISK, &disc)) { +-- +2.40.1 + diff --git a/SOURCES/0024-imsm-use-same-slot-across-container.patch b/SOURCES/0024-imsm-use-same-slot-across-container.patch deleted file mode 100644 index dc23b3c..0000000 --- a/SOURCES/0024-imsm-use-same-slot-across-container.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:42 +0800 -Subject: [PATCH 24/83] imsm: use same slot across container - -Autolayout relies on drives order on super->disks list, but -it is not quaranted by readdir() in sysfs_read(). As a result -drive could be put in different slot in second volume. - -Make it consistent by reffering to first volume, if exists. - -Use enum imsm_status to unify error handling. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 169 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 108 insertions(+), 61 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index cd1f1e3d..deef7c87 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7522,11 +7522,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 1; - } - --static int imsm_get_free_size(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * imsm_get_free_size() - get the biggest, common free space from members. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. -+ * -+ * @freesize is set to meaningful value, this can be @size, or calculated -+ * max free size. -+ * super->create_offset value is modified and set appropriately in -+ * merge_extends() for further creation. -+ */ -+static imsm_status_t imsm_get_free_size(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, -+ const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - struct dl *dl; - int i; -@@ -7570,12 +7586,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - /* chunk is in K */ - minsize = chunk * 2; - -- if (cnt < raiddisks || -- (super->orom && used && used != raiddisks) || -- maxsize < minsize || -- maxsize == 0) { -+ if (cnt < raiddisks || (super->orom && used && used != raiddisks) || -+ maxsize < minsize || maxsize == 0) { - pr_err("not enough devices with space to create array.\n"); -- return 0; /* No enough free spaces large enough */ -+ return IMSM_STATUS_ERROR; - } - - if (size == 0) { -@@ -7588,37 +7602,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - } - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- - *freesize = size; - - dprintf("imsm: imsm_get_free_size() returns : %llu\n", size); - -- return 1; -+ return IMSM_STATUS_OK; - } - --static int reserve_space(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * autolayout_imsm() - automatically layout a new volume. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * We are being asked to automatically layout a new volume based on the current -+ * contents of the container. If the parameters can be satisfied autolayout_imsm -+ * will record the disks, start offset, and will return size of the volume to -+ * be created. See imsm_get_free_size() for details. -+ * add_to_super() and getinfo_super() detect when autolayout is in progress. -+ * If first volume exists, slots are set consistently to it. -+ * -+ * Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise. -+ * -+ * Disks are marked for creation via dl->raiddisk. -+ */ -+static imsm_status_t autolayout_imsm(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; -- struct dl *dl; -- int cnt; -- int rv = 0; -+ int curr_slot = 0; -+ struct dl *disk; -+ int vol_cnt = super->anchor->num_raid_devs; -+ imsm_status_t rv; - -- rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize); -- if (rv) { -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- rv = 1; -+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); -+ if (rv != IMSM_STATUS_OK) -+ return IMSM_STATUS_ERROR; -+ -+ for (disk = super->disks; disk; disk = disk->next) { -+ if (!disk->e) -+ continue; -+ -+ if (curr_slot == raiddisks) -+ break; -+ -+ if (vol_cnt == 0) { -+ disk->raiddisk = curr_slot; -+ } else { -+ int _slot = get_disk_slot_in_dev(super, 0, disk->index); -+ -+ if (_slot == -1) { -+ pr_err("Disk %s is not used in first volume, aborting\n", -+ disk->devname); -+ return IMSM_STATUS_ERROR; -+ } -+ disk->raiddisk = _slot; -+ } -+ curr_slot++; - } - -- return rv; -+ return IMSM_STATUS_OK; - } - - static int validate_geometry_imsm(struct supertype *st, int level, int layout, -@@ -7654,35 +7700,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - } - - if (!dev) { -- if (st->sb) { -- struct intel_super *super = st->sb; -- if (!validate_geometry_imsm_orom(st->sb, level, layout, -- raiddisks, chunk, size, -- verbose)) -+ struct intel_super *super = st->sb; -+ -+ /* -+ * Autolayout mode, st->sb and freesize must be set. -+ */ -+ if (!super || !freesize) { -+ pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -+ return 1; -+ } -+ -+ if (!validate_geometry_imsm_orom(st->sb, level, layout, -+ raiddisks, chunk, size, -+ verbose)) -+ return 0; -+ -+ if (super->orom) { -+ imsm_status_t rv; -+ int count = count_volumes(super->hba, super->orom->dpa, -+ verbose); -+ if (super->orom->vphba <= count) { -+ pr_vrb("platform does not support more than %d raid volumes.\n", -+ super->orom->vphba); - return 0; -- /* we are being asked to automatically layout a -- * new volume based on the current contents of -- * the container. If the the parameters can be -- * satisfied reserve_space will record the disks, -- * start offset, and size of the volume to be -- * created. add_to_super and getinfo_super -- * detect when autolayout is in progress. -- */ -- /* assuming that freesize is always given when array is -- created */ -- if (super->orom && freesize) { -- int count; -- count = count_volumes(super->hba, -- super->orom->dpa, verbose); -- if (super->orom->vphba <= count) { -- pr_vrb("platform does not support more than %d raid volumes.\n", -- super->orom->vphba); -- return 0; -- } - } -- if (freesize) -- return reserve_space(st, raiddisks, size, -- *chunk, freesize); -+ -+ rv = autolayout_imsm(super, raiddisks, size, *chunk, -+ freesize); -+ if (rv != IMSM_STATUS_OK) -+ return 0; - } - return 1; - } -@@ -11538,7 +11584,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - unsigned long long current_size; - unsigned long long free_size; - unsigned long long max_size; -- int rv; -+ imsm_status_t rv; - - getinfo_super_imsm_volume(st, &info, NULL); - if (geo->level != info.array.level && geo->level >= 0 && -@@ -11657,9 +11703,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - } - /* check the maximum available size - */ -- rv = imsm_get_free_size(st, dev->vol.map->num_members, -- 0, chunk, &free_size); -- if (rv == 0) -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, -+ 0, chunk, &free_size); -+ -+ if (rv != IMSM_STATUS_OK) - /* Cannot find maximum available space - */ - max_size = 0; --- -2.38.1 - diff --git a/SOURCES/0025-imsm-block-changing-slots-during-creation.patch b/SOURCES/0025-imsm-block-changing-slots-during-creation.patch deleted file mode 100644 index 4c3b918..0000000 --- a/SOURCES/0025-imsm-block-changing-slots-during-creation.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:43 +0800 -Subject: [PATCH 25/83] imsm: block changing slots during creation - -If user specifies drives for array creation, then slot order across -volumes is not preserved. -Ideally, it should be checked in validate_geometry() but it is not -possible in current implementation (order is determined later). -Add verification in add_to_super_imsm_volume() and throw error if -mismatch is detected. -IMSM allows to use only same members within container. -This is not hardware dependency but metadata limitation. -Therefore, 09-imsm-overlap test is removed. Testing it is pointless. -After this patch, creation in this scenario is blocked. Offset -verification is covered in other tests. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 33 ++++++++++++++++++++++----------- - tests/09imsm-overlap | 28 ---------------------------- - 2 files changed, 22 insertions(+), 39 deletions(-) - delete mode 100644 tests/09imsm-overlap - -diff --git a/super-intel.c b/super-intel.c -index deef7c87..8ffe485c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_map *map; - struct dl *dl, *df; - int slot; -+ int autolayout = 0; -+ -+ if (!is_fd_valid(fd)) -+ autolayout = 1; - - dev = get_imsm_dev(super, super->current_vol); - map = get_imsm_map(dev, MAP_0); -@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - return 1; - } - -- if (!is_fd_valid(fd)) { -- /* we're doing autolayout so grab the pre-marked (in -- * validate_geometry) raid_disk -- */ -- for (dl = super->disks; dl; dl = dl->next) -+ for (dl = super->disks; dl ; dl = dl->next) { -+ if (autolayout) { - if (dl->raiddisk == dk->raid_disk) - break; -- } else { -- for (dl = super->disks; dl ; dl = dl->next) -- if (dl->major == dk->major && -- dl->minor == dk->minor) -- break; -+ } else if (dl->major == dk->major && dl->minor == dk->minor) -+ break; - } - - if (!dl) { -- pr_err("%s is not a member of the same container\n", devname); -+ if (!autolayout) -+ pr_err("%s is not a member of the same container.\n", -+ devname); - return 1; - } - -+ if (!autolayout && super->current_vol > 0) { -+ int _slot = get_disk_slot_in_dev(super, 0, dl->index); -+ -+ if (_slot != dk->raid_disk) { -+ pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n", -+ dl->devname, _slot, dk->raid_disk); -+ pr_err("Raid members are in different order than for the first volume, aborting.\n"); -+ return 1; -+ } -+ } -+ - if (mpb->num_disks == 0) - if (!get_dev_sector_size(dl->fd, dl->devname, - &super->sector_size)) -diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap -deleted file mode 100644 -index ff5d2093..00000000 ---- a/tests/09imsm-overlap -+++ /dev/null -@@ -1,28 +0,0 @@ -- --. tests/env-imsm-template -- --# create raid arrays with varying degress of overlap --mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5 --imsm_check container 6 -- --size=1024 --level=1 --num_disks=2 --mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size --mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size --mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size --mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size --mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size -- --udevadm settle -- --offset=0 --imsm_check member $member0 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member1 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member2 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member3 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member4 $num_disks $level $size 1024 $offset --- -2.38.1 - diff --git a/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch b/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch new file mode 100644 index 0000000..acd0f84 --- /dev/null +++ b/SOURCES/0025-mdadm-introduce-sysfs_get_container_devnm.patch @@ -0,0 +1,138 @@ +From 14a8657940be34a781222b4b715bd09eb80d1057 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:09 +0100 +Subject: [PATCH 25/41] mdadm: introduce sysfs_get_container_devnm() + +There at least two places where it is done directly, so replace them +with function. Print message about creating external array, add "/dev/" +prefix to refer directly to devnode. + +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 21 ++++++++++----------- + Manage.c | 14 ++++---------- + mdadm.h | 2 ++ + sysfs.c | 23 +++++++++++++++++++++++ + 4 files changed, 39 insertions(+), 21 deletions(-) + +diff --git a/Create.c b/Create.c +index 7e9170b6..0b776266 100644 +--- a/Create.c ++++ b/Create.c +@@ -1142,24 +1142,23 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (did_default && c->verbose >= 0) { + if (is_subarray(info.text_version)) { +- char devnm[32]; +- char *ep; ++ char devnm[MD_NAME_MAX]; + struct mdinfo *mdi; + +- strncpy(devnm, info.text_version+1, 32); +- devnm[31] = 0; +- ep = strchr(devnm, '/'); +- if (ep) +- *ep = 0; ++ sysfs_get_container_devnm(&info, devnm); + + mdi = sysfs_read(-1, devnm, GET_VERSION); ++ if (!mdi) { ++ pr_err("Cannot open sysfs for container %s\n", devnm); ++ goto abort_locked; ++ } ++ ++ pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version, ++ devnm); + +- pr_info("Creating array inside %s container %s\n", +- mdi?mdi->text_version:"managed", devnm); + sysfs_free(mdi); + } else +- pr_info("Defaulting to version %s metadata\n", +- info.text_version); ++ pr_info("Defaulting to version %s metadata\n", info.text_version); + } + + map_update(&map, fd2devnm(mdfd), info.text_version, +diff --git a/Manage.c b/Manage.c +index b3e216cb..969d0ea9 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -178,7 +178,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + struct map_ent *map = NULL; + struct mdinfo *mdi; + char devnm[32]; +- char container[32]; ++ char container[MD_NAME_MAX] = {0}; + int err; + int count; + char buf[SYSFS_MAX_BUF_SIZE]; +@@ -192,15 +192,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + * to stop is probably a bad idea. + */ + mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_COMPONENT|GET_VERSION); +- if (mdi && is_subarray(mdi->text_version)) { +- char *sl; +- strncpy(container, mdi->text_version+1, sizeof(container)); +- container[sizeof(container)-1] = 0; +- sl = strchr(container, '/'); +- if (sl) +- *sl = 0; +- } else +- container[0] = 0; ++ if (mdi && is_subarray(mdi->text_version)) ++ sysfs_get_container_devnm(mdi, container); ++ + close(fd); + count = 5; + while (((fd = ((devname[0] == '/') +diff --git a/mdadm.h b/mdadm.h +index cbc586f5..39b86bd0 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -777,6 +777,8 @@ enum sysfs_read_flags { + + #define SYSFS_MAX_BUF_SIZE 64 + ++extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf); ++ + /* If fd >= 0, get the array it is open on, + * else use devnm. + */ +diff --git a/sysfs.c b/sysfs.c +index f95ef701..230b842e 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -74,6 +74,29 @@ void sysfs_free(struct mdinfo *sra) + } + } + ++/** ++ * sysfs_get_container_devnm() - extract container device name. ++ * @mdi: md_info describes member array, with GET_VERSION option. ++ * @buf: buf to fill, must be MD_NAME_MAX. ++ * ++ * External array version is in format {/,-}/ ++ * Extract container_devnm from it and safe it in @buf. ++ */ ++void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf) ++{ ++ char *p; ++ ++ assert(is_subarray(mdi->text_version)); ++ ++ /* Skip first special sign */ ++ snprintf(buf, MD_NAME_MAX, "%s", mdi->text_version + 1); ++ ++ /* Remove array index */ ++ p = strchr(buf, '/'); ++ if (p) ++ *p = 0; ++} ++ + int sysfs_open(char *devnm, char *devname, char *attr) + { + char fname[MAX_SYSFS_PATH_LEN]; +-- +2.40.1 + diff --git a/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch b/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch deleted file mode 100644 index d593669..0000000 --- a/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Wed, 15 Jun 2022 14:28:39 +0200 -Subject: [PATCH 26/83] mdadm: block update=ppl for non raid456 levels - -Option ppl should be used only for raid levels 4, 5 and 6. Cancel update -for other levels. - -Applied globally for imsm and ddf format. - -Additionally introduce is_level456() helper function. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 11 +++++------ - Grow.c | 2 +- - Manage.c | 14 ++++++++++++-- - mdadm.h | 11 +++++++++++ - super0.c | 2 +- - super1.c | 3 +-- - 6 files changed, 31 insertions(+), 12 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 4b213560..6df6bfbc 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content, - * devices in RAID4 or last devices in RAID4/5/6. - */ - delta = devices[j].i.delta_disks; -- if (devices[j].i.array.level >= 4 && -- devices[j].i.array.level <= 6 && -+ if (is_level456(devices[j].i.array.level) && - i/2 >= content->array.raid_disks - delta) - /* OK */; - else if (devices[j].i.array.level == 4 && -@@ -1226,8 +1225,7 @@ static int start_array(int mdfd, - fprintf(stderr, ".\n"); - } - if (content->reshape_active && -- content->array.level >= 4 && -- content->array.level <= 6) { -+ is_level456(content->array.level)) { - /* might need to increase the size - * of the stripe cache - default is 256 - */ -@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd, - int start_reshape; - char *avail; - int err; -- int is_raid456, is_clean, all_disks; -+ int is_clean, all_disks; -+ bool is_raid456; - - if (sysfs_init(content, mdfd, NULL)) { - pr_err("Unable to initialize sysfs\n"); -@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd, - content->array.state |= 1; - } - -- is_raid456 = (content->array.level >= 4 && content->array.level <= 6); -+ is_raid456 = is_level456(content->array.level); - is_clean = content->array.state & 1; - - if (enough(content->array.level, content->array.raid_disks, -diff --git a/Grow.c b/Grow.c -index f6efbc48..8c520d42 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) - } - - md_get_array_info(fd, &array); -- if (level == 0 && (array.level >= 4 && array.level <= 6)) { -+ if (level == 0 && is_level456(array.level)) { - /* To convert to RAID0 we need to fail and - * remove any non-data devices. */ - int found = 0; -diff --git a/Manage.c b/Manage.c -index f789e0c1..e5e6abe4 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * - unfreeze reshape - * - wait on 'sync_completed' for that point to be reached. - */ -- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) && -+ if (mdi && is_level456(mdi->array.level) && - sysfs_attribute_available(mdi, NULL, "sync_action") && - sysfs_attribute_available(mdi, NULL, "reshape_direction") && - sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 && -@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; -+ struct mdinfo *info = NULL; - - memset(st, 0, sizeof(*st)); - -@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -+ info = st->ss->container_content(st, subarray); -+ -+ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); -+ goto free_super; -+ } -+ - rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { -@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -- free_super: -+free_super: -+ if (info) -+ free(info); - st->ss->free_super(st); - close(fd); - -diff --git a/mdadm.h b/mdadm.h -index d53df169..974415b9 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -796,6 +796,17 @@ static inline int is_fd_valid(int fd) - return (fd > -1); - } - -+/** -+ * is_level456() - check whether given level is between inclusive 4 and 6. -+ * @level: level to check. -+ * -+ * Return: true if condition is met, false otherwise -+ */ -+static inline bool is_level456(int level) -+{ -+ return (level >= 4 && level <= 6); -+} -+ - /** - * close_fd() - verify, close and unset file descriptor. - * @fd: pointer to file descriptor. -diff --git a/super0.c b/super0.c -index 61c9ec1d..37f595ed 100644 ---- a/super0.c -+++ b/super0.c -@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int parity = sb->level == 6 ? 2 : 1; - rv = 0; - -- if (sb->level >= 4 && sb->level <= 6 && -+ if (is_level456(sb->level) && - sb->reshape_position % ( - sb->new_chunk/512 * - (sb->raid_disks - sb->delta_disks - parity))) { -diff --git a/super1.c b/super1.c -index 3a0c69fd..71af860c 100644 ---- a/super1.c -+++ b/super1.c -@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * So we reject a revert-reshape unless the - * alignment is good. - */ -- if (__le32_to_cpu(sb->level) >= 4 && -- __le32_to_cpu(sb->level) <= 6) { -+ if (is_level456(__le32_to_cpu(sb->level))) { - reshape_sectors = - __le64_to_cpu(sb->reshape_position); - reshape_chunk = __le32_to_cpu(sb->new_chunk); --- -2.38.1 - diff --git a/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch b/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch new file mode 100644 index 0000000..ed4caee --- /dev/null +++ b/SOURCES/0026-mdadm.h-Introduce-custom-device-policies.patch @@ -0,0 +1,115 @@ +From 1fef0c6ff54c2710f75a239dd8a5e0ffb0068e86 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:10 +0100 +Subject: [PATCH 26/41] mdadm.h: Introduce custom device policies + +The approach proposed here is to test drive policies outside +validate_geometry() separately per every drive and add determined +policies to list. The implementation reuses dev_policy we have in +mdadm. + +This concept addresses following problems: +- test drives if they fit together to criteria required by metadata + handler, +- test all drives assigned to the container even if some of them are not + target of the request, mdmon is free to use any drive in the same + container, +- extensibility, new policies can be added to handler easy, +- fix issues related to imsm controller domain verifying. + +Add superswitch function. It is used in next patches. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 54 ++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 36 insertions(+), 18 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 39b86bd0..889f4a0f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -940,6 +940,23 @@ struct reshape { + unsigned long long new_size; /* New size of array in sectors */ + }; + ++/** ++ * struct dev_policy - Data structure for policy management. ++ * @next: pointer to next dev_policy. ++ * @name: policy name, category. ++ * @metadata: the metadata type it affects. ++ * @value: value of the policy. ++ * ++ * The functions to manipulate dev_policy lists do not free elements, so they must be statically ++ * allocated. @name and @metadata can be compared by address. ++ */ ++typedef struct dev_policy { ++ struct dev_policy *next; ++ char *name; ++ const char *metadata; ++ const char *value; ++} dev_policy_t; ++ + /* A superswitch provides entry point to a metadata handler. + * + * The superswitch primarily operates on some "metadata" that +@@ -1168,6 +1185,25 @@ extern struct superswitch { + char *subdev, unsigned long long *freesize, + int consistency_policy, int verbose); + ++ /** ++ * test_and_add_drive_policies() - test new and add custom policies from metadata handler. ++ * @pols: list of currently recorded policies. ++ * @disk_fd: file descriptor of the device to check. ++ * @verbose: verbose flag. ++ * ++ * Used by IMSM to verify all drives in container/array, against requirements not recored ++ * in superblock, like controller type for IMSM. It should check all drives even if ++ * they are not actually used, because mdmon or kernel are free to use any drive assigned to ++ * container automatically. ++ * ++ * Generating and comparison methods belong to metadata handler. It is not mandatory to be ++ * implemented. ++ * ++ * Return: MDADM_STATUS_SUCCESS is expected on success. ++ */ ++ mdadm_status_t (*test_and_add_drive_policies)(dev_policy_t **pols, int disk_fd, ++ const int verbose); ++ + /* Return a linked list of 'mdinfo' structures for all arrays + * in the container. For non-containers, it is like + * getinfo_super with an allocated mdinfo.*/ +@@ -1372,23 +1408,6 @@ extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep); + extern int must_be_container(int fd); + void wait_for(char *dev, int fd); + +-/* +- * Data structures for policy management. +- * Each device can have a policy structure that lists +- * various name/value pairs each possibly with a metadata associated. +- * The policy list is sorted by name/value/metadata +- */ +-struct dev_policy { +- struct dev_policy *next; +- char *name; /* None of these strings are allocated. They are +- * all just references to strings which are known +- * to exist elsewhere. +- * name and metadata can be compared by address equality. +- */ +- const char *metadata; +- const char *value; +-}; +- + extern char pol_act[], pol_domain[], pol_metadata[], pol_auto[]; + + /* iterate over the sublist starting at list, having the same +@@ -1430,7 +1449,6 @@ extern struct dev_policy *disk_policy(struct mdinfo *disk); + extern struct dev_policy *devid_policy(int devid); + extern void dev_policy_free(struct dev_policy *p); + +-//extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata); + extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata); + extern struct dev_policy *pol_find(struct dev_policy *pol, char *name); + +-- +2.40.1 + diff --git a/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch b/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch deleted file mode 100644 index 02bdf9c..0000000 --- a/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:47 +0200 -Subject: [PATCH 27/83] mdadm: Fix array size mismatch after grow - -imsm_fix_size_mismatch() is invoked to fix the problem, but it couldn't -proceed due to migration check. This patch allows for intended behavior. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/super-intel.c b/super-intel.c -index 8ffe485c..76b947f5 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11854,7 +11854,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - unsigned long long d_size = imsm_dev_size(dev); - int u_size; - -- if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR) -+ if (calc_size == d_size) - continue; - - /* There is a difference, confirm that imsm_dev_size is --- -2.38.1 - diff --git a/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch b/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch new file mode 100644 index 0000000..b7bc9ce --- /dev/null +++ b/SOURCES/0027-mdadm-test_and_add-device-policies-implementation.patch @@ -0,0 +1,144 @@ +From 5a2e194cb31569880a26356b8594ddca6e3b3828 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:11 +0100 +Subject: [PATCH 27/41] mdadm: test_and_add device policies implementation + +Add support for three scenarios: +- obtaining array wide policies via fd, +- obtaining array wide policies via struct mdinfo, +- getting policies for particular drive from the request. + +Add proper functions and make them extern. These functions are used +in next patches. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 7 +++++ + policy.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 100 insertions(+) + +diff --git a/mdadm.h b/mdadm.h +index 889f4a0f..af2bc714 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1452,6 +1452,13 @@ extern void dev_policy_free(struct dev_policy *p); + extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata); + extern struct dev_policy *pol_find(struct dev_policy *pol, char *name); + ++extern mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, ++ int fd, const int verbose); ++extern mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ struct mdinfo *mdi, const int verbose); ++extern mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ int array_fd, const int verbose); ++ + enum policy_action { + act_default, + act_include, +diff --git a/policy.c b/policy.c +index eee9ef63..4b85f62d 100644 +--- a/policy.c ++++ b/policy.c +@@ -397,6 +397,99 @@ struct dev_policy *path_policy(char **paths, char *type) + return pol; + } + ++/** ++ * drive_test_and_add_policies() - get policies for drive and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @fd: device descriptor. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. Use metadata handler to get ++ * policies. ++ */ ++mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, int fd, ++ const int verbose) ++{ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (st->ss->test_and_add_drive_policies(pols, fd, verbose) == MDADM_STATUS_SUCCESS) { ++ /* After successful call list cannot be empty */ ++ assert(*pols); ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ return MDADM_STATUS_ERROR; ++} ++ ++/** ++ * sysfs_test_and_add_policies() - get policies for mddev and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @mdi: mdinfo describes the MD array, must have GET_DISKS option. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. To get policies, all disks ++ * connected to mddev are analyzed. ++ */ ++mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ struct mdinfo *mdi, const int verbose) ++{ ++ struct mdinfo *sd; ++ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ for (sd = mdi->devs; sd; sd = sd->next) { ++ char *devpath = map_dev(sd->disk.major, sd->disk.minor, 0); ++ int fd = dev_open(devpath, O_RDONLY); ++ int rv; ++ ++ if (!is_fd_valid(fd)) { ++ pr_err("Cannot open fd for %s\n", devpath); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ rv = drive_test_and_add_policies(st, pols, fd, verbose); ++ close(fd); ++ ++ if (rv) ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * mddev_test_and_add_policies() - get policies for mddev and add them to pols. ++ * @st: supertype. ++ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL. ++ * @array_fd: MD device descriptor. ++ * @verbose: verbose flag. ++ * ++ * If supertype doesn't support this functionality return success. Use fd to extract disks. ++ */ ++mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols, ++ int array_fd, const int verbose) ++{ ++ struct mdinfo *sra; ++ int ret; ++ ++ if (!st->ss->test_and_add_drive_policies) ++ return MDADM_STATUS_SUCCESS; ++ ++ sra = sysfs_read(array_fd, NULL, GET_DEVS); ++ if (!sra) { ++ pr_err("Cannot load sysfs for %s\n", fd2devnm(array_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ ret = sysfs_test_and_add_drive_policies(st, pols, sra, verbose); ++ ++ sysfs_free(sra); ++ return ret; ++} ++ + void pol_add(struct dev_policy **pol, + char *name, char *val, + char *metadata) +-- +2.40.1 + diff --git a/SOURCES/0028-Create-Use-device-policies.patch b/SOURCES/0028-Create-Use-device-policies.patch new file mode 100644 index 0000000..e49fea9 --- /dev/null +++ b/SOURCES/0028-Create-Use-device-policies.patch @@ -0,0 +1,124 @@ +From f5a39b66f794322f30828389ddd488d17f578ad5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:12 +0100 +Subject: [PATCH 28/41] Create: Use device policies + +Generate and compare policies, abort if policies do not match. +It is tested for both create modes, with container and disk list +specified directly. It is used if supertype supports it. + +For a case when disk list is specified, container may contain more +devices, so additional check on container is done to analyze all disks. + +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 31 +++++++++++++++++++++++++------ + 1 file changed, 25 insertions(+), 6 deletions(-) + +diff --git a/Create.c b/Create.c +index 0b776266..4397ff49 100644 +--- a/Create.c ++++ b/Create.c +@@ -497,6 +497,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + */ + int mdfd; + unsigned long long minsize = 0, maxsize = 0; ++ dev_policy_t *custom_pols = NULL; + char *mindisc = NULL; + char *maxdisc = NULL; + char *name = ident->name; +@@ -588,6 +589,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + first_missing = subdevs * 2; + second_missing = subdevs * 2; + insert_point = subdevs * 2; ++ ++ if (mddev_test_and_add_drive_policies(st, &custom_pols, fd, 1)) ++ exit(1); + } + } + if (fd >= 0) +@@ -739,7 +743,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + close(dfd); + exit(2); + } +- close(dfd); ++ + info.array.working_disks++; + if (dnum < s->raiddisks && dv->disposition != 'j') + info.array.active_disks++; +@@ -812,6 +816,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + } + } + ++ if (drive_test_and_add_policies(st, &custom_pols, dfd, 1)) ++ exit(1); ++ ++ close(dfd); ++ + if (dv->disposition == 'j') + goto skip_size_check; /* skip write journal for size check */ + +@@ -886,6 +895,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + close(fd); + } + } ++ + if (missing_disks == dnum && !have_container) { + pr_err("Subdevs can't be all missing\n"); + return 1; +@@ -1140,25 +1150,30 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + goto abort_locked; + } + +- if (did_default && c->verbose >= 0) { ++ if (did_default) { + if (is_subarray(info.text_version)) { + char devnm[MD_NAME_MAX]; + struct mdinfo *mdi; + + sysfs_get_container_devnm(&info, devnm); + +- mdi = sysfs_read(-1, devnm, GET_VERSION); ++ mdi = sysfs_read(-1, devnm, GET_VERSION | GET_DEVS); + if (!mdi) { + pr_err("Cannot open sysfs for container %s\n", devnm); + goto abort_locked; + } + +- pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version, +- devnm); ++ if (sysfs_test_and_add_drive_policies(st, &custom_pols, mdi, 1)) ++ goto abort_locked; ++ ++ if (c->verbose >= 0) ++ pr_info("Creating array inside %s container /dev/%s\n", ++ mdi->text_version, devnm); + + sysfs_free(mdi); +- } else ++ } else if (c->verbose >= 0) { + pr_info("Defaulting to version %s metadata\n", info.text_version); ++ } + } + + map_update(&map, fd2devnm(mdfd), info.text_version, +@@ -1328,6 +1343,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + udev_unblock(); + close(mdfd); + sysfs_uevent(&info, "change"); ++ dev_policy_free(custom_pols); ++ + return 0; + + abort: +@@ -1339,5 +1356,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (mdfd >= 0) + close(mdfd); ++ ++ dev_policy_free(custom_pols); + return 1; + } +-- +2.40.1 + diff --git a/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch b/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch deleted file mode 100644 index 08688dd..0000000 --- a/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:48 +0200 -Subject: [PATCH 28/83] mdadm: Remove dead code in imsm_fix_size_mismatch - -imsm_create_metadata_update_for_size_change() that returns u_size value -could return 0 in the past. As its behavior changed, and returned value -is always the size of imsm_update_size_change structure, check for -u_size is no longer needed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 76b947f5..4ddfcf94 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11869,10 +11869,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - geo.size = d_size; - u_size = imsm_create_metadata_update_for_size_change(st, &geo, - &update); -- if (u_size < 1) { -- dprintf("imsm: Cannot prepare size change update\n"); -- goto exit; -- } - imsm_update_metadata_locally(st, update, u_size); - if (st->update_tail) { - append_metadata_update(st, update, u_size); --- -2.38.1 - diff --git a/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch b/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch new file mode 100644 index 0000000..061f77c --- /dev/null +++ b/SOURCES/0029-Manage-check-device-policies-in-manage_add_external.patch @@ -0,0 +1,60 @@ +From 1251db34616bf4890d86664abc5186e9106e9073 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:13 +0100 +Subject: [PATCH 29/41] Manage: check device policies in manage_add_external() + +Only IMSM is going to use device policies so it is added to +manage_add_external(). Test policies before adding the drive to +container. + +The change blocks adding new device to the container which already +contains not matching devices + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/Manage.c b/Manage.c +index 969d0ea9..96e5ee54 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -704,6 +704,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + { + mdadm_status_t rv = MDADM_STATUS_ERROR; + char container_devpath[MD_NAME_MAX]; ++ struct dev_policy *pols = NULL; + struct mdinfo new_mdi; + struct mdinfo *sra = NULL; + int container_fd; +@@ -722,6 +723,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + 0, 1)) + goto out; + ++ if (mddev_test_and_add_drive_policies(st, &pols, container_fd, 1)) ++ goto out; ++ + Kill(disk_name, NULL, 0, -1, 0); + + disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT); +@@ -730,6 +734,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + goto out; + } + ++ if (drive_test_and_add_policies(st, &pols, disk_fd, 1)) ++ goto out; ++ + if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS)) + goto out; + +@@ -760,6 +767,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name + + out: + close(container_fd); ++ dev_policy_free(pols); + + if (sra) + sysfs_free(sra); +-- +2.40.1 + diff --git a/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch b/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch deleted file mode 100644 index f337ff0..0000000 --- a/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch +++ /dev/null @@ -1,40 +0,0 @@ -From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:10 +0200 -Subject: [PATCH 29/83] Monitor: use devname as char array instead of pointer - -Device name wasn't filled properly due to incorrect use of strcpy. -Strcpy was used twice. Firstly to fill devname with "/dev/md/" -and then to add chosen name. First strcpy result was overwritten by -second one (as a result instead of "/dev/md/" -was assigned). This commit changes this implementation to use snprintf -and devname with fixed size. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 6ca1ebe5..a5b11ae2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -190,9 +190,11 @@ int Monitor(struct mddev_dev *devlist, - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); - else { -- st->devname = xmalloc(8+strlen(mdlist->devname)+1); -- strcpy(strcpy(st->devname, "/dev/md/"), -- mdlist->devname); -+ /* length of "/dev/md/" + device name + terminating byte */ -+ size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -+ -+ st->devname = xcalloc(_len, sizeof(char)); -+ snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); - } - if (!is_mddev(mdlist->devname)) - return 1; --- -2.38.1 - diff --git a/SOURCES/0030-Monitor-Incremental-use-device-policies.patch b/SOURCES/0030-Monitor-Incremental-use-device-policies.patch new file mode 100644 index 0000000..753ee8f --- /dev/null +++ b/SOURCES/0030-Monitor-Incremental-use-device-policies.patch @@ -0,0 +1,142 @@ +From 51a9f2fc5e982f3bcbf88fe1bf30c0bf55bfd49c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:14 +0100 +Subject: [PATCH 30/41] Monitor, Incremental: use device policies + +spare_criteria is expanded to contain policies which will be generated +by handler's get_spare_criteria() function. It provides a way to +test device for metadata specific policies earlier than during +add_do_super(), when device is already removed from previous +array/container for Monitor. + +For Incremental, it ensures that all criteria are tested when trying +spare. It is not tested when device contains valid metadata. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 2 +- + Monitor.c | 3 ++- + mdadm.h | 5 +++-- + util.c | 13 +++++++++---- + 4 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 66c2cc86..958ba9ba 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -865,7 +865,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch + goto out; + } + +- if (!disk_fd_matches_criteria(disk_fd, &sc)) { ++ if (!disk_fd_matches_criteria(dup, disk_fd, &sc)) { + if (verbose > 1) + pr_err("Disk does not match spare criteria for %s\n", container_devname); + goto out; +diff --git a/Monitor.c b/Monitor.c +index 6b4560ae..9b016bc3 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1047,7 +1047,7 @@ static dev_t choose_spare(struct state *from, struct state *to, + test_partition_from_id(from->devid[d])) + continue; + +- if (devid_matches_criteria(from->devid[d], sc) == false) ++ if (devid_matches_criteria(to->metadata, from->devid[d], sc) == false) + continue; + + pol = devid_policy(from->devid[d]); +@@ -1195,6 +1195,7 @@ static void try_spare_migration(struct state *statelist) + } + } + domain_free(domlist); ++ dev_policy_free(sc.pols); + } + } + +diff --git a/mdadm.h b/mdadm.h +index af2bc714..cfa11391 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -433,6 +433,7 @@ struct spare_criteria { + bool criteria_set; + unsigned long long min_size; + unsigned int sector_size; ++ struct dev_policy *pols; + }; + + typedef enum mdadm_status { +@@ -1734,8 +1735,8 @@ extern int assemble_container_content(struct supertype *st, int mdfd, + #define INCR_ALREADY 4 + #define INCR_YES 8 + +-extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc); +-extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc); ++extern bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc); ++extern bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc); + extern struct mdinfo *container_choose_spares(struct supertype *st, + struct spare_criteria *criteria, + struct domainlist *domlist, +diff --git a/util.c b/util.c +index 041e78cf..05ad3343 100644 +--- a/util.c ++++ b/util.c +@@ -2056,12 +2056,13 @@ unsigned int __invalid_size_argument_for_IOC = 0; + + /** + * disk_fd_matches_criteria() - check if device matches spare criteria. ++ * @st: supertype, not NULL. + * @disk_fd: file descriptor of the disk. + * @sc: criteria to test. + * + * Return: true if disk matches criteria, false otherwise. + */ +-bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) ++bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc) + { + unsigned int dev_sector_size = 0; + unsigned long long dev_size = 0; +@@ -2076,17 +2077,21 @@ bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc) + sc->sector_size != dev_sector_size) + return false; + ++ if (drive_test_and_add_policies(st, &sc->pols, disk_fd, 0)) ++ return false; ++ + return true; + } + + /** + * devid_matches_criteria() - check if device referenced by devid matches spare criteria. ++ * @st: supertype, not NULL. + * @devid: devid of the device to check. + * @sc: criteria to test. + * + * Return: true if disk matches criteria, false otherwise. + */ +-bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) ++bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc) + { + char buf[NAME_MAX]; + bool ret; +@@ -2102,7 +2107,7 @@ bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc) + return false; + + /* Error code inherited */ +- ret = disk_fd_matches_criteria(fd, sc); ++ ret = disk_fd_matches_criteria(st, fd, sc); + + close(fd); + return ret; +@@ -2137,7 +2142,7 @@ struct mdinfo *container_choose_spares(struct supertype *st, + if (d->disk.state == 0) { + dev_t dev = makedev(d->disk.major,d->disk.minor); + +- found = devid_matches_criteria(dev, criteria); ++ found = devid_matches_criteria(st, dev, criteria); + + /* check if domain matches */ + if (found && domlist) { +-- +2.40.1 + diff --git a/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch b/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch deleted file mode 100644 index 7d3b4bc..0000000 --- a/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:11 +0200 -Subject: [PATCH 30/83] Monitor: use snprintf to fill device name - -Safe string functions are propagated in Monitor.c. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 37 ++++++++++++++----------------------- - 1 file changed, 14 insertions(+), 23 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index a5b11ae2..93f36ac0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,8 +33,8 @@ - #endif - - struct state { -- char *devname; -- char devnm[32]; /* to sync with mdstat info */ -+ char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -+ char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ - unsigned int utime; - int err; - char *spare_group; -@@ -45,9 +45,9 @@ struct state { - int devstate[MAX_DISKS]; - dev_t devid[MAX_DISKS]; - int percent; -- char parent_devnm[32]; /* For subarray, devnm of parent. -- * For others, "" -- */ -+ char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. -+ * For others, "" -+ */ - struct supertype *metadata; - struct state *subarray;/* for a container it is a link to first subarray - * for a subarray it is a link to next subarray -@@ -187,15 +187,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - - st = xcalloc(1, sizeof *st); -- if (mdlist->devname[0] == '/') -- st->devname = xstrdup(mdlist->devname); -- else { -- /* length of "/dev/md/" + device name + terminating byte */ -- size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -- -- st->devname = xcalloc(_len, sizeof(char)); -- snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); -- } -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -+ "/dev/md/%s", basename(mdlist->devname)); - if (!is_mddev(mdlist->devname)) - return 1; - st->next = statelist; -@@ -218,7 +211,7 @@ int Monitor(struct mddev_dev *devlist, - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -- st->devname = xstrdup(dv->devname); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -301,7 +294,6 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->devname); - free(st->spare_group); - free(st); - } else -@@ -554,7 +546,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - goto disappeared; - - if (st->devnm[0] == 0) -- strcpy(st->devnm, fd2devnm(fd)); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", fd2devnm(fd)); - - for (mse2 = mdstat; mse2; mse2 = mse2->next) - if (strcmp(mse2->devnm, st->devnm) == 0) { -@@ -684,7 +676,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - strncmp(mse->metadata_version, "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, mse->metadata_version + 10); -+ snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10); - sl = strchr(st->parent_devnm, '/'); - if (sl) - *sl = 0; -@@ -772,14 +764,13 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - continue; - } - -- st->devname = xstrdup(name); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); - if ((fd = open(st->devname, O_RDONLY)) < 0 || - md_get_array_info(fd, &array) < 0) { - /* no such array */ - if (fd >= 0) - close(fd); - put_md_name(st->devname); -- free(st->devname); - if (st->metadata) { - st->metadata->ss->free_super(st->metadata); - free(st->metadata); -@@ -791,7 +782,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - st->next = *statelist; - st->err = 1; - st->from_auto = 1; -- strcpy(st->devnm, mse->devnm); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm); - st->percent = RESYNC_UNKNOWN; - st->expected_spares = -1; - if (mse->metadata_version && -@@ -799,8 +790,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, -- mse->metadata_version+10); -+ snprintf(st->parent_devnm, MD_NAME_MAX, -+ "%s", mse->metadata_version + 10); - sl = strchr(st->parent_devnm, '/'); - *sl = 0; - } else --- -2.38.1 - diff --git a/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch b/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch deleted file mode 100644 index de5e49e..0000000 --- a/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:06 -0600 -Subject: [PATCH 31/83] Makefile: Don't build static build with everything and - everything-test - -Running the test suite requires building everything, but it seems to be -difficult to build the static version of mdadm now seeing there -is no readily available static udev library. - -The test suite doesn't need the static binary so just don't build it -with the everything or everything-test targets. - -Leave the mdadm.static and install-static targets in place in case -someone still has a use case for the static binary. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index bf126033..ec1f99ed 100644 ---- a/Makefile -+++ b/Makefile -@@ -182,9 +182,9 @@ check_rundir: - echo "***** or set CHECK_RUN_DIR=0"; exit 1; \ - fi - --everything: all mdadm.static swap_super test_stripe raid6check \ -+everything: all swap_super test_stripe raid6check \ - mdadm.Os mdadm.O2 man --everything-test: all mdadm.static swap_super test_stripe \ -+everything-test: all swap_super test_stripe \ - mdadm.Os mdadm.O2 man - # mdadm.uclibc doesn't work on x86-64 - # mdadm.tcc doesn't work.. --- -2.38.1 - diff --git a/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch b/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch new file mode 100644 index 0000000..86161d4 --- /dev/null +++ b/SOURCES/0031-imsm-test_and_add_device_policies-implementation.patch @@ -0,0 +1,187 @@ +From e21aea08eb706939a38f7dc5cf9509a9afd45f8a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:15 +0100 +Subject: [PATCH 31/41] imsm: test_and_add_device_policies() implementation + +This patch removes get_disk_controller_domain_imsm() in favour of +test_and_add_device_policies_imsm(). It is used by +create, add and mdmonitor. + +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.h | 1 - + super-intel.c | 123 ++++++++++++++++++++++++++++++++++------------- + 2 files changed, 90 insertions(+), 34 deletions(-) + +diff --git a/platform-intel.h b/platform-intel.h +index ce29d3da..3c2bc595 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -262,7 +262,6 @@ int disk_attached_to_hba(int fd, const char *hba_path); + int devt_attached_to_hba(dev_t dev, const char *hba_path); + char *devt_to_devpath(dev_t dev, int dev_level, char *buf); + int path_attached_to_hba(const char *disk_path, const char *hba_path); +-const char *get_sys_dev_type(enum sys_dev_type); + const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id); + const struct imsm_orom *get_orom_by_device_id(__u16 device_id); + struct sys_dev *device_by_id(__u16 device_id); +diff --git a/super-intel.c b/super-intel.c +index 7ad391ac..77140455 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11220,39 +11220,90 @@ abort: + return retval; + } + +-static char disk_by_path[] = "/dev/disk/by-path/"; +- +-static const char *imsm_get_disk_controller_domain(const char *path) +-{ +- char disk_path[PATH_MAX]; +- char *drv=NULL; +- struct stat st; +- +- strncpy(disk_path, disk_by_path, PATH_MAX); +- strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1); +- if (stat(disk_path, &st) == 0) { +- struct sys_dev* hba; +- char *path; +- +- path = devt_to_devpath(st.st_rdev, 1, NULL); +- if (path == NULL) +- return "unknown"; +- hba = find_disk_attached_hba(-1, path); +- if (hba && hba->type == SYS_DEV_SAS) +- drv = "isci"; +- else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD)) +- drv = "ahci"; +- else if (hba && hba->type == SYS_DEV_VMD) +- drv = "vmd"; +- else if (hba && hba->type == SYS_DEV_NVME) +- drv = "nvme"; +- else +- drv = "unknown"; +- dprintf("path: %s hba: %s attached: %s\n", +- path, (hba) ? hba->path : "NULL", drv); +- free(path); ++/** ++ * test_and_add_drive_controller_policy_imsm() - add disk controller to policies list. ++ * @type: Policy type to search on list. ++ * @pols: List of currently recorded policies. ++ * @disk_fd: File descriptor of the device to check. ++ * @hba: The hba disk is attached, could be NULL if verification is disabled. ++ * @verbose: verbose flag. ++ * ++ * IMSM cares about drive physical placement. If @hba is not set, it adds unknown policy. ++ * If there is no controller policy on pols we are free to add first one. If there is a policy then, ++ * new must be the same - no controller mixing allowed. ++ */ ++static mdadm_status_t ++test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose) ++{ ++ const char *controller_policy = get_sys_dev_type(SYS_DEV_UNKNOWN); ++ struct dev_policy *pol = pol_find(*pols, (char *)type); ++ char devname[MAX_RAID_SERIAL_LEN]; ++ ++ if (hba) ++ controller_policy = get_sys_dev_type(hba->type); ++ ++ if (!pol) { ++ pol_add(pols, (char *)type, (char *)controller_policy, "imsm"); ++ return MDADM_STATUS_SUCCESS; + } +- return drv; ++ ++ if (strcmp(pol->value, controller_policy) == 0) ++ return MDADM_STATUS_SUCCESS; ++ ++ fd2devname(disk_fd, devname); ++ pr_vrb("Intel(R) raid controller \"%s\" found for %s, but \"%s\" was detected earlier\n", ++ controller_policy, devname, pol->value); ++ pr_vrb("Disks under different controllers cannot be used, aborting\n"); ++ ++ return MDADM_STATUS_ERROR; ++} ++ ++struct imsm_drive_policy { ++ char *type; ++ mdadm_status_t (*test_and_add_drive_policy)(const char * const type, ++ struct dev_policy **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose); ++}; ++ ++struct imsm_drive_policy imsm_policies[] = { ++ {"controller", test_and_add_drive_controller_policy_imsm}, ++}; ++ ++mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd, ++ const int verbose) ++{ ++ struct imsm_drive_policy *imsm_pol; ++ struct sys_dev *hba = NULL; ++ char path[PATH_MAX]; ++ mdadm_status_t ret; ++ unsigned int i; ++ ++ /* If imsm platform verification is disabled, do not search for hba. */ ++ if (check_no_platform() != 1) { ++ if (!diskfd_to_devpath(disk_fd, 1, path)) { ++ pr_vrb("IMSM: Failed to retrieve device path by file descriptor.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ hba = find_disk_attached_hba(disk_fd, path); ++ if (!hba) { ++ pr_vrb("IMSM: Failed to find hba for %s\n", path); ++ return MDADM_STATUS_ERROR; ++ } ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(imsm_policies); i++) { ++ imsm_pol = &imsm_policies[i]; ++ ++ ret = imsm_pol->test_and_add_drive_policy(imsm_pol->type, pols, disk_fd, hba, ++ verbose); ++ if (ret != MDADM_STATUS_SUCCESS) ++ /* Inherit error code */ ++ return ret; ++ } ++ ++ return MDADM_STATUS_SUCCESS; + } + + /** +@@ -11280,6 +11331,7 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, + + if (mddev_path) { + int fd = open(mddev_path, O_RDONLY); ++ mdadm_status_t rv; + + if (!is_fd_valid(fd)) + return MDADM_STATUS_ERROR; +@@ -11291,7 +11343,12 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path, + } + free_superblock = true; + } ++ ++ rv = mddev_test_and_add_drive_policies(st, &c->pols, fd, 0); + close(fd); ++ ++ if (rv != MDADM_STATUS_SUCCESS) ++ goto out; + } + + super = st->sb; +@@ -13026,7 +13083,7 @@ struct superswitch super_imsm = { + .update_subarray = update_subarray_imsm, + .load_container = load_container_imsm, + .default_geometry = default_geometry_imsm, +- .get_disk_controller_domain = imsm_get_disk_controller_domain, ++ .test_and_add_drive_policies = test_and_add_drive_policies_imsm, + .reshape_super = imsm_reshape_super, + .manage_reshape = imsm_manage_reshape, + .recover_backup = recover_backup_imsm, +-- +2.40.1 + diff --git a/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch b/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch deleted file mode 100644 index ec2954d..0000000 --- a/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:07 -0600 -Subject: [PATCH 32/83] DDF: Cleanup validate_geometry_ddf_container() - -Move the function up so that the function declaration is not necessary -and remove the unused arguments to the function. - -No functional changes are intended but will help with a bug fix in the -next patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 88 ++++++++++++++++++++++++----------------------------- - 1 file changed, 39 insertions(+), 49 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index abbc8b09..9d867f69 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -503,13 +503,6 @@ struct ddf_super { - static int load_super_ddf_all(struct supertype *st, int fd, - void **sbp, char *devname); - static int get_svd_state(const struct ddf_super *, const struct vcl *); --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose); - - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, -@@ -3322,6 +3315,42 @@ static int reserve_space(struct supertype *st, int raiddisks, - return 1; - } - -+static int -+validate_geometry_ddf_container(struct supertype *st, -+ int level, int raiddisks, -+ unsigned long long data_offset, -+ char *dev, unsigned long long *freesize, -+ int verbose) -+{ -+ int fd; -+ unsigned long long ldsize; -+ -+ if (level != LEVEL_CONTAINER) -+ return 0; -+ if (!dev) -+ return 1; -+ -+ fd = dev_open(dev, O_RDONLY|O_EXCL); -+ if (fd < 0) { -+ if (verbose) -+ pr_err("ddf: Cannot open %s: %s\n", -+ dev, strerror(errno)); -+ return 0; -+ } -+ if (!get_dev_size(fd, dev, &ldsize)) { -+ close(fd); -+ return 0; -+ } -+ close(fd); -+ if (freesize) { -+ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -+ if (*freesize == 0) -+ return 0; -+ } -+ -+ return 1; -+} -+ - static int validate_geometry_ddf(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, -@@ -3347,11 +3376,9 @@ static int validate_geometry_ddf(struct supertype *st, - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { - /* Must be a fresh device to add to a container */ -- return validate_geometry_ddf_container(st, level, layout, -- raiddisks, *chunk, -- size, data_offset, dev, -- freesize, -- verbose); -+ return validate_geometry_ddf_container(st, level, raiddisks, -+ data_offset, dev, -+ freesize, verbose); - } - - if (!dev) { -@@ -3449,43 +3476,6 @@ static int validate_geometry_ddf(struct supertype *st, - return 1; - } - --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose) --{ -- int fd; -- unsigned long long ldsize; -- -- if (level != LEVEL_CONTAINER) -- return 0; -- if (!dev) -- return 1; -- -- fd = dev_open(dev, O_RDONLY|O_EXCL); -- if (fd < 0) { -- if (verbose) -- pr_err("ddf: Cannot open %s: %s\n", -- dev, strerror(errno)); -- return 0; -- } -- if (!get_dev_size(fd, dev, &ldsize)) { -- close(fd); -- return 0; -- } -- close(fd); -- if (freesize) { -- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -- if (*freesize == 0) -- return 0; -- } -- -- return 1; --} -- - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, --- -2.38.1 - diff --git a/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch b/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch new file mode 100644 index 0000000..be22fdf --- /dev/null +++ b/SOURCES/0032-mdadm-drop-get_disk_controller_domain.patch @@ -0,0 +1,75 @@ +From e492d2ac143e7f02d6c262130d42a4422e8295d5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:16 +0100 +Subject: [PATCH 32/41] mdadm: drop get_disk_controller_domain() + +This function is unused now. Drop it. +Controller for IMSM is a device policy and is separated from user defined +domains. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 15 --------------- + policy.c | 13 ------------- + 2 files changed, 28 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index cfa11391..3fedca48 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1286,21 +1286,6 @@ extern struct superswitch { + */ + struct mdinfo *(*activate_spare)(struct active_array *a, + struct metadata_update **updates); +- /* +- * Return statically allocated string that represents metadata specific +- * controller domain of the disk. The domain is used in disk domain +- * matching functions. Disks belong to the same domain if the they have +- * the same domain from mdadm.conf and belong the same metadata domain. +- * Returning NULL or not providing this handler means that metadata +- * does not distinguish the differences between disks that belong to +- * different controllers. They are in the domain specified by +- * configuration file (mdadm.conf). +- * In case when the metadata has the notion of domains based on disk +- * it shall return NULL for disks that do not belong to the controller +- * the supported domains. Such disks will form another domain and won't +- * be mixed with supported ones. +- */ +- const char *(*get_disk_controller_domain)(const char *path); + + /* for external backup area */ + int (*recover_backup)(struct supertype *st, struct mdinfo *info); +diff --git a/policy.c b/policy.c +index 4b85f62d..404f9b5d 100644 +--- a/policy.c ++++ b/policy.c +@@ -365,7 +365,6 @@ struct dev_policy *path_policy(char **paths, char *type) + { + struct pol_rule *rules; + struct dev_policy *pol = NULL; +- int i; + + rules = config_rules; + +@@ -380,18 +379,6 @@ struct dev_policy *path_policy(char **paths, char *type) + rules = rules->next; + } + +- /* Now add any metadata-specific internal knowledge +- * about this path +- */ +- for (i=0; paths && paths[0] && superlist[i]; i++) +- if (superlist[i]->get_disk_controller_domain) { +- const char *d = +- superlist[i]->get_disk_controller_domain( +- paths[0]); +- if (d) +- pol_new(&pol, pol_domain, d, superlist[i]->name); +- } +- + pol_sort(&pol); + pol_dedup(pol); + return pol; +-- +2.40.1 + diff --git a/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch b/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch deleted file mode 100644 index 3a53577..0000000 --- a/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:08 -0600 -Subject: [PATCH 33/83] DDF: Fix NULL pointer dereference in - validate_geometry_ddf() - -A relatively recent patch added a call to validate_geometry() in -Manage_add() that has level=LEVEL_CONTAINER and chunk=NULL. - -This causes some ddf tests to segfault which aborts the test suite. - -To fix this, avoid dereferencing chunk when the level is -LEVEL_CONTAINER or LEVEL_NONE. - -Fixes: 1f5d54a06df0 ("Manage: Call validate_geometry when adding drive to external container") -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d867f69..949e7d15 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3369,9 +3369,6 @@ static int validate_geometry_ddf(struct supertype *st, - * If given BVDs, we make an SVD, changing all the GUIDs in the process. - */ - -- if (*chunk == UnSet) -- *chunk = DEFAULT_CHUNK; -- - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { -@@ -3381,6 +3378,9 @@ static int validate_geometry_ddf(struct supertype *st, - freesize, verbose); - } - -+ if (*chunk == UnSet) -+ *chunk = DEFAULT_CHUNK; -+ - if (!dev) { - mdu_array_info_t array = { - .level = level, --- -2.38.1 - diff --git a/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch b/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch new file mode 100644 index 0000000..b38a1da --- /dev/null +++ b/SOURCES/0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch @@ -0,0 +1,42 @@ +From 933bb500b80cca6f4e9237382f7d8ac852978471 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 29 Feb 2024 12:52:17 +0100 +Subject: [PATCH 33/41] Revert "policy.c: Avoid to take spare without defined + domain by imsm" + +This reverts commit 3bf9495270d7 ("policy.c: Avoid to take spare without +defined domain by imsm"). + +IMSM does not require to be special now because it doesn't create disk +controller domain. + +Signed-off-by: Mariusz Tkaczyk +--- + policy.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/policy.c b/policy.c +index 404f9b5d..dfaafdc0 100644 +--- a/policy.c ++++ b/policy.c +@@ -759,7 +759,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + * 1: has domains, all match + */ + int found_any = -1; +- int has_one_domain = 1; + struct dev_policy *p; + + pol = pol_find(pol, pol_domain); +@@ -769,9 +768,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + dom = dom->next; + if (!dom || strcmp(dom->dom, p->value) != 0) + return 0; +- if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0) +- found_any = -1; +- has_one_domain = 0; + } + return found_any; + } +-- +2.40.1 + diff --git a/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch b/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch deleted file mode 100644 index 2695f67..0000000 --- a/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:09 -0600 -Subject: [PATCH 34/83] mdadm/Grow: Fix use after close bug by closing after - fork - -The test 07reshape-grow fails most of the time. But it succeeds around -1 in 5 times. When it does succeed, it causes the tests to die because -mdadm has segfaulted. - -The segfault was caused by mdadm attempting to repoen a file -descriptor that was already closed. The backtrace of the segfault -was: - - #0 __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:101 - #1 0x000056146e31d44b in devnm2devid (devnm=0x0) at util.c:956 - #2 0x000056146e31dab4 in open_dev_flags (devnm=0x0, flags=0) - at util.c:1072 - #3 0x000056146e31db22 in open_dev (devnm=0x0) at util.c:1079 - #4 0x000056146e3202e8 in reopen_mddev (mdfd=4) at util.c:2244 - #5 0x000056146e329f36 in start_array (mdfd=4, - mddev=0x7ffc55342450 "/dev/md0", content=0x7ffc55342860, - st=0x56146fc78660, ident=0x7ffc55342f70, best=0x56146fc6f5d0, - bestcnt=10, chosen_drive=0, devices=0x56146fc706b0, okcnt=5, - sparecnt=0, rebuilding_cnt=0, journalcnt=0, c=0x7ffc55342e90, - clean=1, avail=0x56146fc78720 "\001\001\001\001\001", - start_partial_ok=0, err_ok=0, was_forced=0) - at Assemble.c:1206 - #6 0x000056146e32c36e in Assemble (st=0x56146fc78660, - mddev=0x7ffc55342450 "/dev/md0", ident=0x7ffc55342f70, - devlist=0x56146fc6e2d0, c=0x7ffc55342e90) - at Assemble.c:1914 - #7 0x000056146e312ac9 in main (argc=11, argv=0x7ffc55343238) - at mdadm.c:1510 - -The file descriptor was closed early in Grow_continue(). The noted commit -moved the close() call to close the fd above the fork which caused the -parent process to return with a closed fd. - -This meant reshape_array() and Grow_continue() would return in the parent -with the fd forked. The fd would eventually be passed to reopen_mddev() -which returned an unhandled NULL from fd2devnm() which would then be -dereferenced in devnm2devid. - -Fix this by moving the close() call below the fork. This appears to -fix the 07revert-grow test. While we're at it, switch to using -close_fd() to invalidate the file descriptor. - -Fixes: 77b72fa82813 ("mdadm/Grow: prevent md's fd from being occupied during delayed time") -Cc: Alex Wu -Cc: BingJing Chang -Cc: Danny Shih -Cc: ChangSyun Peng -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8c520d42..97f22c75 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3514,7 +3514,6 @@ started: - return 0; - } - -- close(fd); - /* Now we just need to kick off the reshape and watch, while - * handling backups of the data... - * This is all done by a forked background process. -@@ -3535,6 +3534,9 @@ started: - break; - } - -+ /* Close unused file descriptor in the forked process */ -+ close_fd(&fd); -+ - /* If another array on the same devices is busy, the - * reshape will wait for them. This would mean that - * the first section that we suspend will stay suspended --- -2.38.1 - diff --git a/SOURCES/0034-mdadm-remove-inventory-file.patch b/SOURCES/0034-mdadm-remove-inventory-file.patch new file mode 100644 index 0000000..ee9bb97 --- /dev/null +++ b/SOURCES/0034-mdadm-remove-inventory-file.patch @@ -0,0 +1,307 @@ +From 9c63130e8974033969569fb9d0b373d1d1478cf7 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 6 Mar 2024 13:45:53 +0100 +Subject: [PATCH 34/41] mdadm: remove inventory file + +It is a file with repo content list. It is outdated already. +Remove it. + +Signed-off-by: Mariusz Tkaczyk +--- + inventory | 284 ------------------------------------------------------ + 1 file changed, 284 deletions(-) + delete mode 100755 inventory + +diff --git a/inventory b/inventory +deleted file mode 100755 +index c4801b49..00000000 +--- a/inventory ++++ /dev/null +@@ -1,284 +0,0 @@ +- +-.gitignore +-ANNOUNCE-3.0 +-ANNOUNCE-3.0.1 +-ANNOUNCE-3.0.2 +-ANNOUNCE-3.0.3 +-ANNOUNCE-3.1 +-ANNOUNCE-3.1.1 +-ANNOUNCE-3.1.2 +-ANNOUNCE-3.1.3 +-ANNOUNCE-3.1.4 +-ANNOUNCE-3.1.5 +-ANNOUNCE-3.2 +-ANNOUNCE-3.2.1 +-ANNOUNCE-3.2.2 +-ANNOUNCE-3.2.3 +-ANNOUNCE-3.2.4 +-ANNOUNCE-3.2.5 +-ANNOUNCE-3.2.6 +-ANNOUNCE-3.3 +-ANNOUNCE-3.3.1 +-ANNOUNCE-3.3.2 +-ANNOUNCE-3.3.3 +-ANNOUNCE-3.3.4 +-ANNOUNCE-3.4 +-ANNOUNCE-4.0 +-ANNOUNCE-4.1 +-ANNOUNCE-4.2 +-Assemble.c +-Build.c +-COPYING +-ChangeLog +-Create.c +-Detail.c +-Dump.c +-Examine.c +-Grow.c +-INSTALL +-Incremental.c +-Kill.c +-Makefile +-Manage.c +-Monitor.c +-Query.c +-README.initramfs +-ReadMe.c +-TODO +-bitmap.c +-bitmap.h +-clustermd_tests/ +-clustermd_tests/00r10_Create +-clustermd_tests/00r1_Create +-clustermd_tests/01r10_Grow_bitmap-switch +-clustermd_tests/01r10_Grow_resize +-clustermd_tests/01r1_Grow_add +-clustermd_tests/01r1_Grow_bitmap-switch +-clustermd_tests/01r1_Grow_resize +-clustermd_tests/02r10_Manage_add +-clustermd_tests/02r10_Manage_add-spare +-clustermd_tests/02r10_Manage_re-add +-clustermd_tests/02r1_Manage_add +-clustermd_tests/02r1_Manage_add-spare +-clustermd_tests/02r1_Manage_re-add +-clustermd_tests/03r10_switch-recovery +-clustermd_tests/03r10_switch-resync +-clustermd_tests/03r1_switch-recovery +-clustermd_tests/03r1_switch-resync +-clustermd_tests/cluster_conf +-clustermd_tests/func.sh +-config.c +-coverity-gcc-hack.h +-crc32.c +-crc32.h +-crc32c.c +-dlink.c +-dlink.h +-external-reshape-design.txt +-inventory +-lib.c +-makedist +-managemon.c +-mapfile.c +-maps.c +-md.4 +-md5.h +-md_p.h +-md_u.h +-mdadm.8.in +-mdadm.c +-mdadm.conf-example +-mdadm.conf.5 +-mdadm.h +-mdadm.spec +-mdmon-design.txt +-mdmon.8 +-mdmon.c +-mdmon.h +-mdopen.c +-mdstat.c +-misc/ +-misc/mdcheck +-misc/syslog-events +-mkinitramfs +-monitor.c +-msg.c +-msg.h +-part.h +-platform-intel.c +-platform-intel.h +-policy.c +-probe_roms.c +-probe_roms.h +-pwgr.c +-raid5extend.c +-raid6check.8 +-raid6check.c +-restripe.c +-sg_io.c +-sha1.c +-sha1.h +-super-ddf.c +-super-gpt.c +-super-intel.c +-super-mbr.c +-super0.c +-super1.c +-swap_super.c +-sysfs.c +-systemd/ +-systemd/SUSE-mdadm_env.sh +-systemd/mdadm-grow-continue@.service +-systemd/mdadm-last-resort@.service +-systemd/mdadm-last-resort@.timer +-systemd/mdadm.shutdown +-systemd/mdcheck_continue.service +-systemd/mdcheck_continue.timer +-systemd/mdcheck_start.service +-systemd/mdcheck_start.timer +-systemd/mdmon@.service +-systemd/mdmonitor-oneshot.service +-systemd/mdmonitor-oneshot.timer +-systemd/mdmonitor.service +-test +-tests/ +-tests/00linear +-tests/00multipath +-tests/00names +-tests/00raid0 +-tests/00raid1 +-tests/00raid10 +-tests/00raid4 +-tests/00raid5 +-tests/00raid6 +-tests/00readonly +-tests/01r1fail +-tests/01r5fail +-tests/01r5integ +-tests/01raid6integ +-tests/01replace +-tests/02lineargrow +-tests/02r1add +-tests/02r1grow +-tests/02r5grow +-tests/02r6grow +-tests/03assem-incr +-tests/03r0assem +-tests/03r5assem +-tests/03r5assem-failed +-tests/03r5assemV1 +-tests/04r0update +-tests/04r1update +-tests/04r5swap +-tests/04update-metadata +-tests/04update-uuid +-tests/05r1-add-internalbitmap +-tests/05r1-add-internalbitmap-v1a +-tests/05r1-add-internalbitmap-v1b +-tests/05r1-add-internalbitmap-v1c +-tests/05r1-bitmapfile +-tests/05r1-failfast +-tests/05r1-grow-external +-tests/05r1-grow-internal +-tests/05r1-grow-internal-1 +-tests/05r1-internalbitmap +-tests/05r1-internalbitmap-v1a +-tests/05r1-internalbitmap-v1b +-tests/05r1-internalbitmap-v1c +-tests/05r1-n3-bitmapfile +-tests/05r1-re-add +-tests/05r1-re-add-nosuper +-tests/05r1-remove-internalbitmap +-tests/05r1-remove-internalbitmap-v1a +-tests/05r1-remove-internalbitmap-v1b +-tests/05r1-remove-internalbitmap-v1c +-tests/05r5-bitmapfile +-tests/05r5-internalbitmap +-tests/05r6-bitmapfile +-tests/05r6tor0 +-tests/06name +-tests/06sysfs +-tests/06wrmostly +-tests/07autoassemble +-tests/07autodetect +-tests/07changelevelintr +-tests/07changelevels +-tests/07layouts +-tests/07reshape5intr +-tests/07revert-grow +-tests/07revert-inplace +-tests/07revert-shrink +-tests/07testreshape5 +-tests/09imsm-assemble +-tests/09imsm-create-fail-rebuild +-tests/09imsm-overlap +-tests/10ddf-assemble-missing +-tests/10ddf-create +-tests/10ddf-create-fail-rebuild +-tests/10ddf-fail-create-race +-tests/10ddf-fail-readd +-tests/10ddf-fail-readd-readonly +-tests/10ddf-fail-spare +-tests/10ddf-fail-stop-readd +-tests/10ddf-fail-twice +-tests/10ddf-fail-two-spares +-tests/10ddf-geometry +-tests/10ddf-incremental-wrong-order +-tests/10ddf-sudden-degraded +-tests/11spare-migration +-tests/12imsm-r0_2d-grow-r0_3d +-tests/12imsm-r0_2d-grow-r0_4d +-tests/12imsm-r0_2d-grow-r0_5d +-tests/12imsm-r0_3d-grow-r0_4d +-tests/12imsm-r5_3d-grow-r5_4d +-tests/12imsm-r5_3d-grow-r5_5d +-tests/13imsm-r0_r0_2d-grow-r0_r0_4d +-tests/13imsm-r0_r0_2d-grow-r0_r0_5d +-tests/13imsm-r0_r0_3d-grow-r0_r0_4d +-tests/13imsm-r0_r5_3d-grow-r0_r5_4d +-tests/13imsm-r0_r5_3d-grow-r0_r5_5d +-tests/13imsm-r5_r0_3d-grow-r5_r0_4d +-tests/13imsm-r5_r0_3d-grow-r5_r0_5d +-tests/14imsm-r0_3d-r5_3d-migrate-r5_4d-r5_4d +-tests/14imsm-r0_3d_no_spares-migrate-r5_3d +-tests/14imsm-r0_r0_2d-takeover-r10_4d +-tests/14imsm-r10_4d-grow-r10_5d +-tests/14imsm-r10_r5_4d-takeover-r0_2d +-tests/14imsm-r1_2d-grow-r1_3d +-tests/14imsm-r1_2d-takeover-r0_2d +-tests/14imsm-r5_3d-grow-r5_5d-no-spares +-tests/14imsm-r5_3d-migrate-r4_3d +-tests/15imsm-r0_3d_64k-migrate-r0_3d_256k +-tests/15imsm-r5_3d_4k-migrate-r5_3d_256k +-tests/15imsm-r5_3d_64k-migrate-r5_3d_256k +-tests/15imsm-r5_6d_4k-migrate-r5_6d_256k +-tests/15imsm-r5_r0_3d_64k-migrate-r5_r0_3d_256k +-tests/16imsm-r0_3d-migrate-r5_4d +-tests/16imsm-r0_5d-migrate-r5_6d +-tests/16imsm-r5_3d-migrate-r0_3d +-tests/16imsm-r5_5d-migrate-r0_5d +-tests/18imsm-1d-takeover-r0_1d +-tests/18imsm-1d-takeover-r1_2d +-tests/18imsm-r0_2d-takeover-r10_4d +-tests/18imsm-r10_4d-takeover-r0_2d +-tests/18imsm-r1_2d-takeover-r0_1d +-tests/19raid6auto-repair +-tests/19raid6check +-tests/19raid6repair +-tests/19repair-does-not-destroy +-tests/20raid5journal +-tests/21raid5cache +-tests/ToTest +-tests/env-ddf-template +-tests/env-imsm-template +-tests/func.sh +-tests/imsm-grow-template +-tests/utils +-udev-md-clustered-confirm-device.rules +-udev-md-raid-arrays.rules +-udev-md-raid-assembly.rules +-udev-md-raid-creating.rules +-udev-md-raid-safe-timeouts.rules +-util.c +-uuid.c +-xmalloc.c +-- +2.40.1 + diff --git a/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch b/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch deleted file mode 100644 index ed09288..0000000 --- a/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:10 -0600 -Subject: [PATCH 35/83] monitor: Avoid segfault when calling NULL - get_bad_blocks - -Not all struct superswitch implement a get_bad_blocks() function, -yet mdmon seems to call it without checking for NULL and thus -occasionally segfaults in the test 10ddf-geometry. - -Fix this by checking for NULL before calling it. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - monitor.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/monitor.c b/monitor.c -index b877e595..820a93d0 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -311,6 +311,9 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi) - struct md_bb *bb; - int i; - -+ if (!ss->get_bad_blocks) -+ return -1; -+ - /* - * Get a list of bad blocks for an array, then read list of - * acknowledged bad blocks from kernel and compare it against metadata --- -2.38.1 - diff --git a/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch b/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch new file mode 100644 index 0000000..084bbc4 --- /dev/null +++ b/SOURCES/0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch @@ -0,0 +1,31 @@ +From 1750758c7ff526e3560433f6235e5cfa35cf646a Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 6 Mar 2024 15:50:55 +0100 +Subject: [PATCH 35/41] udev.c: Do not require libudev.h if DNO_LIBUDEV + +libudev may not be presented at all, do not require it. + +Reported-by: Boian Bonev +Signed-off-by: Mariusz Tkaczyk +--- + udev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/udev.c b/udev.c +index bc4722b0..066e6ab1 100644 +--- a/udev.c ++++ b/udev.c +@@ -26,7 +26,10 @@ + #include + #include + #include ++ ++#ifndef NO_LIBUDEV + #include ++#endif + + static char *unblock_path; + +-- +2.40.1 + diff --git a/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch b/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch deleted file mode 100644 index f091c64..0000000 --- a/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:11 -0600 -Subject: [PATCH 36/83] mdadm: Fix mdadm -r remove option regression - -The commit noted below globally adds a parameter to the -r option but missed -the fact that -r is used for another purpose: --remove. - -After that commit, a command such as: - - mdadm /dev/md0 -r /dev/loop0 - -will do nothing seeing the device parameter will be consumed as a -argument to the -r option; thus, there will only be one device -seen one the command line, devs_found will only be 1 and nothing will -happen. - -This caused the 01r5integ and 01raid6integ tests to hang indefinitely -as mdadm did not remove the failed device. With the device not removed, -it would not be readded. Then the loop waiting for the array status to -change would loop forever. - -This commit was recently reverted, but the legitimate fix for the -monitor operations was still not fixed. So add specific monitor -short ops to re-fix the --monitor -r option. - -Fixes: 546047688e1c ("mdadm: fix coredump of mdadm --monitor -r") -Fixes: 190dc029b141 ("Revert "mdadm: fix coredump of mdadm --monitor -r"") -Cc: Wu Guanghao -Cc: Mariusz Tkaczyk -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 + - mdadm.c | 1 + - mdadm.h | 1 + - 3 files changed, 3 insertions(+) - -diff --git a/ReadMe.c b/ReadMe.c -index bec1be9a..7518a32a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -82,6 +82,7 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - */ - - char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+char short_monitor_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k:"; - char short_bitmap_options[]= - "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -diff --git a/mdadm.c b/mdadm.c -index be40686c..d0c5e6de 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -227,6 +227,7 @@ int main(int argc, char *argv[]) - shortopt = short_bitmap_auto_options; - break; - case 'F': newmode = MONITOR; -+ shortopt = short_monitor_options; - break; - case 'G': newmode = GROW; - shortopt = short_bitmap_options; -diff --git a/mdadm.h b/mdadm.h -index 974415b9..163f4a49 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -419,6 +419,7 @@ enum mode { - }; - - extern char short_options[]; -+extern char short_monitor_options[]; - extern char short_bitmap_options[]; - extern char short_bitmap_auto_options[]; - extern struct option long_options[]; --- -2.38.1 - diff --git a/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch b/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch new file mode 100644 index 0000000..c3c0ced --- /dev/null +++ b/SOURCES/0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch @@ -0,0 +1,29 @@ +From 8bda86099089b44129ef6206764f9de47a45f0db Mon Sep 17 00:00:00 2001 +From: Alexander Kanavin +Date: Tue, 12 Mar 2024 11:01:50 +0100 +Subject: [PATCH 36/41] util.c: add limits.h include for NAME_MAX definition + +Add limits.h include for NAME_MAX definition. + +Signed-off-by: Alexander Kanavin +Signed-off-by: Mariusz Tkaczyk +--- + util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util.c b/util.c +index 05ad3343..49a9c6e2 100644 +--- a/util.c ++++ b/util.c +@@ -36,7 +36,7 @@ + #include + #include + #include +- ++#include + + /* + * following taken from linux/blkpg.h because they aren't +-- +2.40.1 + diff --git a/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch b/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch deleted file mode 100644 index 60cafdb..0000000 --- a/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:12 -0600 -Subject: [PATCH 37/83] mdadm: Fix optional --write-behind parameter - -The commit noted below changed the behaviour of --write-behind to -require an argument. This broke the 06wrmostly test with the error: - - mdadm: Invalid value for maximum outstanding write-behind writes: (null). - Must be between 0 and 16383. - -To fix this, check if optarg is NULL before parising it, as the origial -code did. - -Fixes: 60815698c0ac ("Refactor parse_num and use it to parse optarg.") -Cc: Mateusz Grzonka -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdadm.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/mdadm.c b/mdadm.c -index d0c5e6de..56722ed9 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1201,8 +1201,9 @@ int main(int argc, char *argv[]) - case O(BUILD, WriteBehind): - case O(CREATE, WriteBehind): - s.write_behind = DEFAULT_MAX_WRITE_BEHIND; -- if (parse_num(&s.write_behind, optarg) != 0 || -- s.write_behind < 0 || s.write_behind > 16383) { -+ if (optarg && -+ (parse_num(&s.write_behind, optarg) != 0 || -+ s.write_behind < 0 || s.write_behind > 16383)) { - pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", - optarg); - exit(2); --- -2.38.1 - diff --git a/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch b/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch new file mode 100644 index 0000000..b8c77e8 --- /dev/null +++ b/SOURCES/0037-mdadm-set-swapuuid-in-all-handlers.patch @@ -0,0 +1,59 @@ +From 1c8327950566449e206e613c11c8232032f26787 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 16:19:29 +0100 +Subject: [PATCH 37/41] mdadm: set swapuuid in all handlers + +It is not set, so it should be 0 but it may vary on compilation +settings. Set it always to 0. + +metadata should care to set UUID and read in proper endianness so it +doesn't follow super1 concept of swapuuid to depend on endianness. + +It is not an attempt to fix endianness issues. + +Signed-off-by: Mariusz Tkaczyk +--- + super-ddf.c | 1 + + super-intel.c | 1 + + super0.c | 2 ++ + 3 files changed, 4 insertions(+) + +diff --git a/super-ddf.c b/super-ddf.c +index 7571e3b7..94ac5ff3 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -5162,6 +5162,7 @@ struct superswitch super_ddf = { + .default_geometry = default_geometry_ddf, + + .external = 1, ++ .swapuuid = 0, + + /* for mdmon */ + .open_new = ddf_open_new, +diff --git a/super-intel.c b/super-intel.c +index 77140455..e1754f29 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -13116,6 +13116,7 @@ struct superswitch super_imsm = { + .validate_ppl = validate_ppl_imsm, + + .external = 1, ++ .swapuuid = 0, + .name = "imsm", + + /* for mdmon */ +diff --git a/super0.c b/super0.c +index a7c5f813..9b8a1bd6 100644 +--- a/super0.c ++++ b/super0.c +@@ -1369,5 +1369,7 @@ struct superswitch super0 = { + .locate_bitmap = locate_bitmap0, + .write_bitmap = write_bitmap0, + .free_super = free_super0, ++ ++ .swapuuid = 0, + .name = "0.90", + }; +-- +2.40.1 + diff --git a/SOURCES/0038-mdadm-Fix-native-detail-export.patch b/SOURCES/0038-mdadm-Fix-native-detail-export.patch new file mode 100644 index 0000000..74d7084 --- /dev/null +++ b/SOURCES/0038-mdadm-Fix-native-detail-export.patch @@ -0,0 +1,247 @@ +From ba65d917d121dfb9876053e6f62dbd4ebf2e028c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 16:19:30 +0100 +Subject: [PATCH 38/41] mdadm: Fix native --detail --export + +Mentioned commit (see Fixes) causes that UUID is not swapped as expected +for native superblock. Fix this problem. + +For detail, we should avoid superblock calls, we can have information +about supertype from map, use that. + +Simplify fname_from_uuid() by removing dependencies to metadata +handler, it is not needed. Decision is taken at compile time, expect +super1 but this function is not used by super1. Add warning about that. +Remove separator, it is always ':'. + +Fixes: 60c19530dd7c ("Detail: remove duplicated code") +Signed-off-by: Mariusz Tkaczyk +--- + Detail.c | 26 +++++++++++++++++++++++++- + mdadm.h | 3 +-- + super-ddf.c | 10 +++++----- + super-intel.c | 16 ++++++++-------- + util.c | 24 +++++++++++++----------- + 5 files changed, 52 insertions(+), 27 deletions(-) + +diff --git a/Detail.c b/Detail.c +index f23ec16f..55a086d3 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -49,6 +49,30 @@ static int add_device(const char *dev, char ***p_devices, + return n_devices + 1; + } + ++/** ++ * detail_fname_from_uuid() - generate uuid string with special super1 handling. ++ * @mp: map entry to parse. ++ * @buf: buf to write. ++ * ++ * Hack to workaround an issue with super1 superblocks. It swapuuid set in order for assembly ++ * to work, but can't have it set if we want this printout to match all the other uuid printouts ++ * in super1.c, so we force swapuuid to 1 to make our printout match the rest of super1. ++ * ++ * Always convert uuid if host is big endian. ++ */ ++char *detail_fname_from_uuid(struct map_ent *mp, char *buf) ++{ ++#if __BYTE_ORDER == BIG_ENDIAN ++ bool swap = true; ++#else ++ bool swap = false; ++#endif ++ if (strncmp(mp->metadata, "1.", 2) == 0) ++ swap = true; ++ ++ return __fname_from_uuid(mp->uuid, swap, buf, ':'); ++} ++ + int Detail(char *dev, struct context *c) + { + /* +@@ -256,7 +280,7 @@ int Detail(char *dev, struct context *c) + mp = map_by_devnm(&map, fd2devnm(fd)); + + if (mp) { +- __fname_from_uuid(mp->uuid, 0, nbuf, ':'); ++ detail_fname_from_uuid(mp, nbuf); + printf("MD_UUID=%s\n", nbuf + 5); + if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) + printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); +diff --git a/mdadm.h b/mdadm.h +index 3fedca48..a363708a 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1696,8 +1696,7 @@ extern const int uuid_zero[4]; + extern int same_uuid(int a[4], int b[4], int swapuuid); + extern void copy_uuid(void *a, int b[4], int swapuuid); + extern char *__fname_from_uuid(int id[4], int swap, char *buf, char sep); +-extern char *fname_from_uuid(struct supertype *st, +- struct mdinfo *info, char *buf, char sep); ++extern char *fname_from_uuid(struct mdinfo *info, char *buf); + extern unsigned long calc_csum(void *super, int bytes); + extern int enough(int level, int raid_disks, int layout, int clean, + char *avail); +diff --git a/super-ddf.c b/super-ddf.c +index 94ac5ff3..21426c75 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1617,7 +1617,7 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose) + struct mdinfo info; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + + printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5); + } +@@ -1632,7 +1632,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + unsigned int i; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + + for (i = 0; i < be16_to_cpu(ddf->virt->max_vdes); i++) { + struct virtual_entry *ve = &ddf->virt->entries[i]; +@@ -1645,7 +1645,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) + ddf->currentconf =&vcl; + vcl.vcnum = i; + uuid_from_super_ddf(st, info.uuid); +- fname_from_uuid(st, &info, nbuf1, ':'); ++ fname_from_uuid(&info, nbuf1); + _ddf_array_name(namebuf, ddf, i); + printf("ARRAY%s%s container=%s member=%d UUID=%s\n", + namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf, +@@ -1658,7 +1658,7 @@ static void export_examine_super_ddf(struct supertype *st) + struct mdinfo info; + char nbuf[64]; + getinfo_super_ddf(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("MD_METADATA=ddf\n"); + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); +@@ -1798,7 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st, char *subarray) + return; + else + uuid_of_ddf_subarray(ddf, vcnum, info.uuid); +- fname_from_uuid(st, &info, nbuf,':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID=%s", nbuf + 5); + } + +diff --git a/super-intel.c b/super-intel.c +index e1754f29..ff2590fe 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2217,7 +2217,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + else + printf("not supported\n"); + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID : %s\n", nbuf + 5); + sum = __le32_to_cpu(mpb->check_sum); + printf(" Checksum : %08x %s\n", sum, +@@ -2242,7 +2242,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + + super->current_vol = i; + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + print_imsm_dev(super, dev, nbuf + 5, super->disks->index); + } + for (i = 0; i < mpb->num_disks; i++) { +@@ -2267,7 +2267,7 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose) + char nbuf[64]; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("ARRAY metadata=imsm UUID=%s\n", nbuf + 5); + } + +@@ -2284,13 +2284,13 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose) + return; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + for (i = 0; i < super->anchor->num_raid_devs; i++) { + struct imsm_dev *dev = get_imsm_dev(super, i); + + super->current_vol = i; + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf1, ':'); ++ fname_from_uuid(&info, nbuf1); + printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n", + dev->volume, nbuf + 5, i, nbuf1 + 5); + } +@@ -2304,7 +2304,7 @@ static void export_examine_super_imsm(struct supertype *st) + char nbuf[64]; + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("MD_METADATA=imsm\n"); + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); +@@ -2324,7 +2324,7 @@ static void detail_super_imsm(struct supertype *st, char *homehost, + super->current_vol = strtoul(subarray, NULL, 10); + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf("\n UUID : %s\n", nbuf + 5); + + super->current_vol = temp_vol; +@@ -2341,7 +2341,7 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray) + super->current_vol = strtoul(subarray, NULL, 10); + + getinfo_super_imsm(st, &info, NULL); +- fname_from_uuid(st, &info, nbuf, ':'); ++ fname_from_uuid(&info, nbuf); + printf(" UUID=%s", nbuf + 5); + + super->current_vol = temp_vol; +diff --git a/util.c b/util.c +index 49a9c6e2..03336d6f 100644 +--- a/util.c ++++ b/util.c +@@ -589,19 +589,21 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep) + + } + +-char *fname_from_uuid(struct supertype *st, struct mdinfo *info, +- char *buf, char sep) +-{ +- // dirty hack to work around an issue with super1 superblocks... +- // super1 superblocks need swapuuid set in order for assembly to +- // work, but can't have it set if we want this printout to match +- // all the other uuid printouts in super1.c, so we force swapuuid +- // to 1 to make our printout match the rest of super1 ++/** ++ * fname_from_uuid() - generate uuid string. Should not be used with super1. ++ * @info: info with uuid ++ * @buf: buf to fill. ++ * ++ * This routine should not be used with super1. See detail_fname_from_uuid() for details. It does ++ * not use superswitch swapuuid as it should be 0 but it has to do UUID conversion if host is big ++ * endian- left for backward compatibility. ++ */ ++char *fname_from_uuid(struct mdinfo *info, char *buf) ++{ + #if __BYTE_ORDER == BIG_ENDIAN +- return __fname_from_uuid(info->uuid, 1, buf, sep); ++ return __fname_from_uuid(info->uuid, true, buf, ':'); + #else +- return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : +- st->ss->swapuuid, buf, sep); ++ return __fname_from_uuid(info->uuid, false, buf, ':'); + #endif + } + +-- +2.40.1 + diff --git a/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch b/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch deleted file mode 100644 index 7794e18..0000000 --- a/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7539254342bc591717b0051734cc6c09c1b88640 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:13 -0600 -Subject: [PATCH 38/83] tests/00raid0: add a test that validates raid0 with - layout fails for 0.9 - -329dfc28debb disallows the creation of raid0 with layouts for 0.9 -metadata. This test confirms the new behavior. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index 8bc18985..e6b21cc4 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -6,11 +6,9 @@ check raid0 - testdev $md0 3 $mdsize2_l 512 - mdadm -S $md0 - --# now with version-0.90 superblock -+# verify raid0 with layouts fail for 0.90 - mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 --check raid0 --testdev $md0 4 $mdsize0 512 --mdadm -S $md0 -+check opposite_result - - # now with no superblock - mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --- -2.38.1 - diff --git a/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch b/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch new file mode 100644 index 0000000..c84146e --- /dev/null +++ b/SOURCES/0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch @@ -0,0 +1,87 @@ +From de23e12a39cfc94575e1173293fe9e15337ee999 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 18 Mar 2024 16:53:31 +0100 +Subject: [PATCH 39/41] sysfs: remove vers parameter from sysfs_set_array + +9003 was passed directly to sysfs_set_array() since md_get_version() +always returned this value. md_get_version() was removed long ago. + +Remove dead version check from sysfs_set_array(). +Remove "vers" argument and fix function calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 2 +- + mdadm.h | 2 +- + sysfs.c | 6 ++---- + util.c | 3 +-- + 4 files changed, 5 insertions(+), 8 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9d042055..f6c5b99e 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1988,7 +1988,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + * and ignoring special character on the first place. + */ + if (strcmp(sra->text_version + 1, content->text_version + 1) != 0) { +- if (sysfs_set_array(content, 9003) != 0) { ++ if (sysfs_set_array(content) != 0) { + sysfs_free(sra); + return 1; + } +diff --git a/mdadm.h b/mdadm.h +index a363708a..ae2106a2 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -811,7 +811,7 @@ extern int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev, + extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev, + char *name, char *val, int size); + extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms); +-extern int sysfs_set_array(struct mdinfo *info, int vers); ++extern int sysfs_set_array(struct mdinfo *info); + extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume); + extern int sysfs_disk_to_scsi_id(int fd, __u32 *id); + extern int sysfs_unique_holder(char *devnm, long rdev); +diff --git a/sysfs.c b/sysfs.c +index 230b842e..4ded1672 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -678,7 +678,7 @@ int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms) + return sysfs_set_str(sra, NULL, "safe_mode_delay", delay); + } + +-int sysfs_set_array(struct mdinfo *info, int vers) ++int sysfs_set_array(struct mdinfo *info) + { + int rv = 0; + char ver[100]; +@@ -702,9 +702,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) + if (strlen(buf) >= 9 && buf[9] == '-') + ver[9] = '-'; + +- if ((vers % 100) < 2 || +- sysfs_set_str(info, NULL, "metadata_version", +- ver) < 0) { ++ if (sysfs_set_str(info, NULL, "metadata_version", ver) < 0) { + pr_err("This kernel does not support external metadata.\n"); + return 1; + } +diff --git a/util.c b/util.c +index 03336d6f..9e837045 100644 +--- a/util.c ++++ b/util.c +@@ -1867,8 +1867,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + int rv; + + if (st->ss->external) +- return sysfs_set_array(info, 9003); +- ++ return sysfs_set_array(info); + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; + inf.minor_version = info->array.minor_version; +-- +2.40.1 + diff --git a/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch b/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch deleted file mode 100644 index d897fb1..0000000 --- a/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 14c2161edb77d7294199e8aa7daa9f9d1d0ad5d7 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:14 -0600 -Subject: [PATCH 39/83] tests: fix raid0 tests for 0.90 metadata - -Some of the test cases fail because raid0 creation fails with the error, -"0.90 metadata does not support layouts for RAID0" added by commit, -329dfc28debb. Fix some of the test cases by switching from raid0 to -linear level for 0.9 metadata where possible. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 4 ++-- - tests/00readonly | 4 ++++ - tests/03r0assem | 6 +++--- - tests/04r0update | 4 ++-- - tests/04update-metadata | 2 +- - 5 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index e6b21cc4..9b8896cb 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -20,8 +20,8 @@ mdadm -S $md0 - # now same again with different chunk size - for chunk in 4 32 256 - do -- mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 -- check raid0 -+ mdadm -CR $md0 -e0.90 -l linear --chunk $chunk -n3 $dev0 $dev1 $dev2 -+ check linear - testdev $md0 3 $mdsize0 $chunk - mdadm -S $md0 - -diff --git a/tests/00readonly b/tests/00readonly -index 28b0fa13..39202487 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -4,6 +4,10 @@ for metadata in 0.9 1.0 1.1 1.2 - do - for level in linear raid0 raid1 raid4 raid5 raid6 raid10 - do -+ if [[ $metadata == "0.9" && $level == "raid0" ]]; -+ then -+ continue -+ fi - mdadm -CR $md0 -l $level -n 4 --metadata=$metadata \ - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync -diff --git a/tests/03r0assem b/tests/03r0assem -index 6744e322..44df0645 100644 ---- a/tests/03r0assem -+++ b/tests/03r0assem -@@ -68,9 +68,9 @@ mdadm -S $md2 - ### Now for version 0... - - mdadm --zero-superblock $dev0 $dev1 $dev2 --mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 --check raid0 --tst="testdev $md2 3 $mdsize0 512" -+mdadm -CR $md2 -llinear --metadata=0.90 -n3 $dev0 $dev1 $dev2 -+check linear -+tst="testdev $md2 3 $mdsize0 1" - $tst - - uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` -diff --git a/tests/04r0update b/tests/04r0update -index 73ee3b9f..b95efb06 100644 ---- a/tests/04r0update -+++ b/tests/04r0update -@@ -1,7 +1,7 @@ - - # create a raid0, re-assemble with a different super-minor --mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 --testdev $md0 3 $mdsize0 512 -+mdadm -CR -e 0.90 $md0 -llinear -n3 $dev0 $dev1 $dev2 -+testdev $md0 3 $mdsize0 1 - minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` - mdadm -S /dev/md0 - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 232fc1ff..08c14af7 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -8,7 +8,7 @@ set -xe - - dlist="$dev0 $dev1 $dev2 $dev3" - --for ls in raid0/4 linear/4 raid1/1 raid5/3 raid6/2 -+for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} - mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist --- -2.38.1 - diff --git a/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch b/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch new file mode 100644 index 0000000..80df278 --- /dev/null +++ b/SOURCES/0040-mdadm-fix-grow-segfault-for-IMSM.patch @@ -0,0 +1,55 @@ +From ae996e81232b8ba991e763dfa15577a0af358358 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 18 Mar 2024 17:28:42 +0100 +Subject: [PATCH 40/41] mdadm: fix grow segfault for IMSM + +If sc is not initialized, there is possibility that sc.pols is not zeroed +and it causes segfault. + +Add missing initialization. +Add missing dev_policy_free() in two places. + +Fixes: f656201188d7 ("mdadm: drop get_required_spare_criteria()") +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 1 + + super-intel.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 958ba9ba..83db0712 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -874,6 +874,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch + rv = MDADM_STATUS_SUCCESS; + + out: ++ dev_policy_free(sc.pols); + dup->ss->free_super(dup); + free(dup); + +diff --git a/super-intel.c b/super-intel.c +index ff2590fe..70f3c4ef 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11518,10 +11518,15 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, + */ + static struct mdinfo *get_spares_for_grow(struct supertype *st) + { +- struct spare_criteria sc; ++ struct spare_criteria sc = {0}; ++ struct mdinfo *spares; + + get_spare_criteria_imsm(st, NULL, &sc); +- return container_choose_spares(st, &sc, NULL, NULL, NULL, 0); ++ spares = container_choose_spares(st, &sc, NULL, NULL, NULL, 0); ++ ++ dev_policy_free(sc.pols); ++ ++ return spares; + } + + /****************************************************************************** +-- +2.40.1 + diff --git a/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch b/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch deleted file mode 100644 index 12b291b..0000000 --- a/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From de045db607b1ac4b70fc2a8878463e029c2ab1dc Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:15 -0600 -Subject: [PATCH 40/83] tests/04update-metadata: avoid passing chunk size to - raid1 - -'04update-metadata' test fails with error, "specifying chunk size is -forbidden for this level" added by commit, 5b30a34aa4b5e. Hence, -correcting the test to ignore passing chunk size to raid1. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -[logang@deltatee.com: fix if/then style and dropped unrelated hunk] -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/04update-metadata | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 08c14af7..2b72a303 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -11,7 +11,11 @@ dlist="$dev0 $dev1 $dev2 $dev3" - for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} -- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist -+ if [[ $l == 'raid1' ]]; then -+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist -+ else -+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist -+ fi - testdev $md0 $s 19904 64 - mdadm -S $md0 - mdadm -A $md0 --update=metadata $dlist --- -2.38.1 - diff --git a/SOURCES/0041-Remove-all-if-zeros-pt.2.patch b/SOURCES/0041-Remove-all-if-zeros-pt.2.patch new file mode 100644 index 0000000..8fc44e8 --- /dev/null +++ b/SOURCES/0041-Remove-all-if-zeros-pt.2.patch @@ -0,0 +1,85 @@ +From da4d58b6d01ed8b0149b777eba7818861fde8c80 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Tue, 19 Mar 2024 11:15:29 +0100 +Subject: [PATCH 41/41] Remove all "if zeros" pt.2 + +Commit e15e8b00cbce ("Remove all "if zeros"") did not remove all "if 0" +code blocks. + +This commit is cleanup for that commit. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Build.c | 6 ------ + Grow.c | 13 +------------ + super1.c | 11 ----------- + 3 files changed, 1 insertion(+), 29 deletions(-) + +diff --git a/Build.c b/Build.c +index 1fbf8596..1be90e41 100644 +--- a/Build.c ++++ b/Build.c +@@ -156,12 +156,6 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, + bitmap_fd = open(s->bitmap_file, O_RDWR); + if (bitmap_fd < 0) { + int major = BITMAP_MAJOR_HI; +-#if 0 +- if (s->bitmap_chunk == UnSet) { +- pr_err("%s cannot be opened.\n", s->bitmap_file); +- goto abort; +- } +-#endif + bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */ + if (CreateBitmap(s->bitmap_file, 1, NULL, + s->bitmap_chunk, c->delay, +diff --git a/Grow.c b/Grow.c +index c69a342d..074f1995 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -4413,19 +4413,8 @@ static void validate(int afd, int bfd, unsigned long long offset) + lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0); + if ((unsigned long long)read(afd, abuf, len) != len) + fail("read first from array failed"); +- if (memcmp(bbuf, abuf, len) != 0) { +-#if 0 +- int i; +- printf("offset=%llu len=%llu\n", +- (unsigned long long)__le64_to_cpu(bsb2.arraystart)*512, len); +- for (i=0; imax_dev); i++) { +- int role = __le16_to_cpu(sb->dev_roles[i]); +- if (role == MD_DISK_ROLE_FAULTY) +- faulty++; +- } +- if (faulty) +- printf(" %d failed", faulty); +-#endif + printf(" ('A' == active, '.' == missing, 'R' == replacing)"); + printf("\n"); + for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) { +-- +2.40.1 + diff --git a/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch b/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch deleted file mode 100644 index e6b9bba..0000000 --- a/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a2c832465fc75202e244327b2081231dfa974617 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:16 -0600 -Subject: [PATCH 41/83] tests/02lineargrow: clear the superblock at every - iteration - -This fixes 02lineargrow test as prior metadata causes --add operation -to misbehave. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/02lineargrow | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/tests/02lineargrow b/tests/02lineargrow -index e05c219d..595bf9f2 100644 ---- a/tests/02lineargrow -+++ b/tests/02lineargrow -@@ -20,4 +20,6 @@ do - testdev $md0 3 $sz 1 - - mdadm -S $md0 -+ mdadm --zero /dev/loop2 -+ mdadm --zero /dev/loop3 - done --- -2.38.1 - diff --git a/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch b/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch new file mode 100644 index 0000000..932b0c8 --- /dev/null +++ b/SOURCES/0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch @@ -0,0 +1,44 @@ +From cc75b0faaa016e54d569486c9a7abe6c39cb883a Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:15 +0100 +Subject: [PATCH 42/69] mdadm: Move pr_vrb define to mdadm.h + +Move pr_vrb define from super-intel.c to mdadm.h to make it widely +available. This change will be used in the next patches. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 2 ++ + super-intel.c | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index ae2106a2..fbb161ba 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1911,6 +1911,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { + + #define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) + ++#define pr_vrb(fmt, arg...) ((void)(verbose && pr_err(fmt, ##arg))) ++ + void *xmalloc(size_t len); + void *xrealloc(void *ptr, size_t len); + void *xcalloc(size_t num, size_t size); +diff --git a/super-intel.c b/super-intel.c +index 70f3c4ef..212387ec 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -393,8 +393,6 @@ struct md_list { + struct md_list *next; + }; + +-#define pr_vrb(fmt, arg...) (void) (verbose && pr_err(fmt, ##arg)) +- + static __u8 migr_type(struct imsm_dev *dev) + { + if (dev->vol.migr_type == MIGR_VERIFY && +-- +2.41.0 + diff --git a/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch b/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch deleted file mode 100644 index 63f72dc..0000000 --- a/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch +++ /dev/null @@ -1,88 +0,0 @@ -From a7bfcc716e235664dfb3b6c5a9590273e611ac72 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:17 -0600 -Subject: [PATCH 42/83] mdadm/test: Add a mode to repeat specified tests - -Many tests fail infrequently or rarely. To help find these, add -an option to run the tests multiple times by specifying --loop=N. - -If --loop=0 is specified, the test will be looped forever. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 36 ++++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 12 deletions(-) - -diff --git a/test b/test -index 711a3c7a..da6db5e0 100755 ---- a/test -+++ b/test -@@ -10,6 +10,7 @@ devlist= - - savelogs=0 - exitonerror=1 -+loop=1 - prefix='[0-9][0-9]' - - # use loop devices by default if doesn't specify --dev -@@ -117,6 +118,7 @@ do_help() { - --logdir=directory Directory to save all logfiles in - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests -+ --loop=N Run tests N times (0 to run forever) - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -211,6 +213,9 @@ parse_args() { - --keep-going | --no-error ) - exitonerror=0 - ;; -+ --loop=* ) -+ loop="${i##*=}" -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -263,19 +268,26 @@ main() { - echo "Testing on linux-$(uname -r) kernel" - [ "$savelogs" == "1" ] && - echo "Saving logs to $logdir" -- if [ "x$TESTLIST" != "x" ] -- then -- for script in ${TESTLIST[@]} -- do -- do_test $testdir/$script -- done -- else -- for script in $testdir/$prefix $testdir/$prefix*[^~] -- do -- do_test $script -- done -- fi - -+ while true; do -+ if [ "x$TESTLIST" != "x" ] -+ then -+ for script in ${TESTLIST[@]} -+ do -+ do_test $testdir/$script -+ done -+ else -+ for script in $testdir/$prefix $testdir/$prefix*[^~] -+ do -+ do_test $script -+ done -+ fi -+ -+ let loop=$loop-1 -+ if [ "$loop" == "0" ]; then -+ break -+ fi -+ done - exit 0 - } - --- -2.38.1 - diff --git a/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch b/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch new file mode 100644 index 0000000..a795a62 --- /dev/null +++ b/SOURCES/0043-Add-reading-Opal-NVMe-encryption-information.patch @@ -0,0 +1,463 @@ +From cc48406887b3bc439e3462e8e4d20f992e81b87e Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:16 +0100 +Subject: [PATCH 43/69] Add reading Opal NVMe encryption information + +For NVMe devices with Opal support, encryption information, status and +ability are determined based on Opal Level 0 discovery response. Technical +documentation used is given in the implementation. + +Ability in general describes what type of encryption is supported, Status +describes in what state the disk with encryption support is. The current +patch includes only the implementation of reading encryption information, +functions will be used in one of the next patches. + +Motivation for adding this functionality is to block mixing of disks in +IMSM arrays with encryption enabled and disabled. The main goal is to not +allow stealing data by rebuilding array to not encrypted drive which can be +read elsewhere. + +Value ENA_OTHER from enum encryption_ability will be used in the next +patch. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + Makefile | 4 +- + drive_encryption.c | 362 +++++++++++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 32 ++++ + 3 files changed, 396 insertions(+), 2 deletions(-) + create mode 100644 drive_encryption.c + create mode 100644 drive_encryption.h + +diff --git a/Makefile b/Makefile +index cbdba49a..7c221a89 100644 +--- a/Makefile ++++ b/Makefile +@@ -170,7 +170,7 @@ OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o u + mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \ + super-mbr.o super-gpt.o \ + restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \ +- platform-intel.o probe_roms.o crc32c.o ++ platform-intel.o probe_roms.o crc32c.o drive_encryption.o + + CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o + +@@ -183,7 +183,7 @@ MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o c + Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ + super-mbr.o super-gpt.o \ + super-ddf.o sha1.o crc32.o msg.o bitmap.o xmalloc.o \ +- platform-intel.o probe_roms.o crc32c.o ++ platform-intel.o probe_roms.o crc32c.o drive_encryption.o + + MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS)) + +diff --git a/drive_encryption.c b/drive_encryption.c +new file mode 100644 +index 00000000..b44585a7 +--- /dev/null ++++ b/drive_encryption.c +@@ -0,0 +1,362 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Read encryption information for Opal and ATA devices. ++ * ++ * Copyright (C) 2024 Intel Corporation ++ * Author: Blazej Kucman ++ */ ++ ++#include "mdadm.h" ++ ++#include ++#include ++#include "drive_encryption.h" ++ ++/* ++ * Opal defines ++ * TCG Storage Opal SSC 2.01 chapter 3.3.3 ++ * NVM ExpressTM Revision 1.4c, chapter 5 ++ */ ++#define TCG_SECP_01 (0x01) ++#define TCG_SECP_00 (0x00) ++#define OPAL_DISCOVERY_COMID (0x0001) ++#define OPAL_LOCKING_FEATURE (0x0002) ++#define OPAL_IO_BUFFER_LEN 2048 ++#define OPAL_DISCOVERY_FEATURE_HEADER_LEN (4) ++ ++/* ++ * NVMe defines ++ * NVM ExpressTM Revision 1.4c, chapter 5 ++ */ ++#define NVME_SECURITY_RECV (0x82) ++#define NVME_IDENTIFY (0x06) ++#define NVME_IDENTIFY_RESPONSE_LEN 4096 ++#define NVME_OACS_BYTE_POSITION (256) ++#define NVME_IDENTIFY_CONTROLLER_DATA (1) ++ ++typedef enum drive_feature_support_status { ++ /* Drive feature is supported. */ ++ DRIVE_FEAT_SUP_ST = 0, ++ /* Drive feature is not supported. */ ++ DRIVE_FEAT_NOT_SUP_ST, ++ /* Drive feature support check failed. */ ++ DRIVE_FEAT_CHECK_FAILED_ST ++} drive_feat_sup_st; ++ ++/* TCG Storage Opal SSC 2.01 chapter 3.1.1.3 */ ++typedef struct opal_locking_feature { ++ /* feature header */ ++ __u16 feature_code; ++ __u8 reserved : 4; ++ __u8 version : 4; ++ __u8 description_length; ++ /* feature description */ ++ __u8 locking_supported : 1; ++ __u8 locking_enabled : 1; ++ __u8 locked : 1; ++ __u8 media_encryption : 1; ++ __u8 mbr_enabled : 1; ++ __u8 mbr_done : 1; ++ __u8 mbr_shadowing_not_supported : 1; ++ __u8 hw_reset_for_dor_supported : 1; ++ __u8 reserved1[11]; ++} __attribute__((__packed__)) opal_locking_feature_t; ++ ++/* TCG Storage Opal SSC 2.01 chapter 3.1.1.1 */ ++typedef struct opal_level0_header { ++ __u32 length; ++ __u32 version; ++ __u64 reserved; ++ __u8 vendor_specific[32]; ++} opal_level0_header_t; ++ ++/** ++ * NVM ExpressTM Revision 1.4c, Figure 249 ++ * Structure specifies only OACS filed, which is needed in the current use case. ++ */ ++typedef struct nvme_identify_ctrl { ++ __u8 reserved[255]; ++ __u16 oacs; ++ __u8 reserved2[3839]; ++} nvme_identify_ctrl_t; ++ ++/* SCSI Primary Commands - 4 (SPC-4), Table 512 */ ++typedef struct supported_security_protocols { ++ __u8 reserved[6]; ++ __u16 list_length; ++ __u8 list[504]; ++} supported_security_protocols_t; ++ ++/** ++ * get_opal_locking_feature_description() - get opal locking feature description. ++ * @response: response from Opal Discovery Level 0. ++ * ++ * Based on the documentation TCG Storage Opal SSC 2.01 chapter 3.1.1, ++ * a Locking feature is searched for in Opal Level 0 Discovery response. ++ * ++ * Return: if locking feature is found, pointer to struct %opal_locking_feature_t, NULL otherwise. ++ */ ++static opal_locking_feature_t *get_opal_locking_feature_description(__u8 *response) ++{ ++ opal_level0_header_t *response_header = (opal_level0_header_t *)response; ++ int features_length = __be32_to_cpu(response_header->length); ++ int current_position = sizeof(*response_header); ++ ++ while (current_position < features_length) { ++ opal_locking_feature_t *feature; ++ ++ feature = (opal_locking_feature_t *)(response + current_position); ++ ++ if (__be16_to_cpu(feature->feature_code) == OPAL_LOCKING_FEATURE) ++ return feature; ++ ++ current_position += feature->description_length + OPAL_DISCOVERY_FEATURE_HEADER_LEN; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * nvme_security_recv_ioctl() - nvme security receive ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @sec_protocol: security protocol. ++ * @comm_id: command id. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and ++ * NVM ExpressTM Revision 1.4c, chapter 5.25, ++ * read security receive command via ioctl(). ++ * On success, @response_buffer is completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t ++nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *response_buffer, ++ size_t buf_size, const int verbose) ++{ ++ struct nvme_admin_cmd nvme_cmd = {0}; ++ int status; ++ ++ nvme_cmd.opcode = NVME_SECURITY_RECV; ++ nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8; ++ nvme_cmd.cdw11 = buf_size; ++ nvme_cmd.data_len = buf_size; ++ nvme_cmd.addr = (__u64)response_buffer; ++ ++ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); ++ if (status != 0) { ++ pr_vrb("Failed to read NVMe security receive ioctl() for device /dev/%s, status: %d\n", ++ fd2kname(disk_fd), status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * nvme_identify_ioctl() - NVMe identify ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and ++ * NVM ExpressTM Revision 1.4c, chapter 5.25, ++ * read NVMe identify via ioctl(). ++ * On success, @response_buffer will be completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t ++nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const int verbose) ++{ ++ struct nvme_admin_cmd nvme_cmd = {0}; ++ int status; ++ ++ nvme_cmd.opcode = NVME_IDENTIFY; ++ nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA; ++ nvme_cmd.data_len = buf_size; ++ nvme_cmd.addr = (__u64)response_buffer; ++ ++ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); ++ if (status != 0) { ++ pr_vrb("Failed to read NVMe identify ioctl() for device /dev/%s, status: %d\n", ++ fd2kname(disk_fd), status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_sec_prot_01h_supported() - check if security protocol 01h supported. ++ * @security_protocols: struct with response from disk (NVMe, SATA) describing supported ++ * security protocols. ++ * ++ * Return: true if TCG_SECP_01 found, false otherwise. ++ */ ++static bool is_sec_prot_01h_supported(supported_security_protocols_t *security_protocols) ++{ ++ int list_length = be16toh(security_protocols->list_length); ++ int index; ++ ++ for (index = 0 ; index < list_length; index++) { ++ if (security_protocols->list[index] == TCG_SECP_01) ++ return true; ++ } ++ ++ return false; ++} ++ ++/** ++ * is_sec_prot_01h_supported_nvme() - check if security protocol 01h supported for given NVMe disk. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check. ++ */ ++static drive_feat_sup_st is_sec_prot_01h_supported_nvme(int disk_fd, const int verbose) ++{ ++ supported_security_protocols_t security_protocols = {0}; ++ ++ /* security_protocol: TCG_SECP_00, comm_id: not applicable */ ++ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_00, 0x0, &security_protocols, ++ sizeof(security_protocols), verbose)) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if (is_sec_prot_01h_supported(&security_protocols)) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * is_nvme_sec_send_recv_supported() - check if Security Send and Security Receive is supported. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Check if "Optional Admin Command Support" bit 0 is set in NVMe identify. ++ * Bit 0 set to 1 means controller supports the Security Send and Security Receive commands. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if security send/receive supported, ++ * %DRIVE_FEAT_NOT_SUP_ST if not supported, %DRIVE_FEAT_CHECK_FAILED_ST if check failed. ++ */ ++static drive_feat_sup_st is_nvme_sec_send_recv_supported(int disk_fd, const int verbose) ++{ ++ nvme_identify_ctrl_t nvme_identify = {0}; ++ int status = 0; ++ ++ status = nvme_identify_ioctl(disk_fd, &nvme_identify, sizeof(nvme_identify), verbose); ++ if (status) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if ((__le16_to_cpu(nvme_identify.oacs) & 0x1) == 0x1) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * get_opal_encryption_information() - get Opal encryption information. ++ * @buffer: buffer with Opal Level 0 Discovery response. ++ * @information: struct to fill out, describing encryption status of disk. ++ * ++ * If Locking feature frame is in response from Opal Level 0 discovery, &encryption_information_t ++ * structure is completed with status and ability otherwise the status is set to &None. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++static mdadm_status_t get_opal_encryption_information(__u8 *buffer, ++ encryption_information_t *information) ++{ ++ opal_locking_feature_t *opal_locking_feature = ++ get_opal_locking_feature_description(buffer); ++ ++ if (!opal_locking_feature) ++ return MDADM_STATUS_ERROR; ++ ++ if (opal_locking_feature->locking_supported == 1) { ++ information->ability = ENC_ABILITY_SED; ++ ++ if (opal_locking_feature->locking_enabled == 0) ++ information->status = ENC_STATUS_UNENCRYPTED; ++ else if (opal_locking_feature->locked == 1) ++ information->status = ENC_STATUS_LOCKED; ++ else ++ information->status = ENC_STATUS_UNLOCKED; ++ } else { ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * get_nvme_opal_encryption_information() - get NVMe Opal encryption information. ++ * @disk_fd: a disk file descriptor. ++ * @information: struct to fill out, describing encryption status of disk. ++ * @verbose: verbose flag. ++ * ++ * In case the disk supports Opal Level 0 discovery, &encryption_information_t structure ++ * is completed with status and ability based on ioctl response, ++ * otherwise the ability is set to %ENC_ABILITY_NONE and &status to %ENC_STATUS_UNENCRYPTED. ++ * As the current use case does not need the knowledge of Opal support, if there is no support, ++ * %MDADM_STATUS_SUCCESS will be returned, with the values described above. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise. ++ */ ++mdadm_status_t ++get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *information, ++ const int verbose) ++{ ++ __u8 buffer[OPAL_IO_BUFFER_LEN]; ++ int sec_send_recv_supported = 0; ++ int protocol_01h_supported = 0; ++ mdadm_status_t status; ++ ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ ++ sec_send_recv_supported = is_nvme_sec_send_recv_supported(disk_fd, verbose); ++ if (sec_send_recv_supported == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ /* Opal not supported */ ++ if (sec_send_recv_supported == DRIVE_FEAT_NOT_SUP_ST) ++ return MDADM_STATUS_SUCCESS; ++ ++ /** ++ * sec_send_recv_supported determine that it should be possible to read ++ * supported sec protocols ++ */ ++ protocol_01h_supported = is_sec_prot_01h_supported_nvme(disk_fd, verbose); ++ if (protocol_01h_supported == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ /* Opal not supported */ ++ if (sec_send_recv_supported == DRIVE_FEAT_SUP_ST && ++ protocol_01h_supported == DRIVE_FEAT_NOT_SUP_ST) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_01, OPAL_DISCOVERY_COMID, (void *)&buffer, ++ OPAL_IO_BUFFER_LEN, verbose)) ++ return MDADM_STATUS_ERROR; ++ ++ status = get_opal_encryption_information((__u8 *)&buffer, information); ++ if (status) ++ pr_vrb("Locking feature description not found in Level 0 discovery response. Device /dev/%s.\n", ++ fd2kname(disk_fd)); ++ ++ if (information->ability == ENC_ABILITY_NONE) ++ assert(information->status == ENC_STATUS_UNENCRYPTED); ++ ++ return status; ++} +diff --git a/drive_encryption.h b/drive_encryption.h +new file mode 100644 +index 00000000..82c2c624 +--- /dev/null ++++ b/drive_encryption.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Read encryption information for Opal and ATA devices. ++ * ++ * Copyright (C) 2024 Intel Corporation ++ * Author: Blazej Kucman ++ */ ++ ++typedef enum encryption_status { ++ /* The drive is not currently encrypted. */ ++ ENC_STATUS_UNENCRYPTED = 0, ++ /* The drive is encrypted and the data is not accessible. */ ++ ENC_STATUS_LOCKED, ++ /* The drive is encrypted but the data is accessible in unencrypted form. */ ++ ENC_STATUS_UNLOCKED ++} encryption_status_t; ++ ++typedef enum encryption_ability { ++ ENC_ABILITY_NONE = 0, ++ ENC_ABILITY_OTHER, ++ /* Self encrypted drive */ ++ ENC_ABILITY_SED ++} encryption_ability_t; ++ ++typedef struct encryption_information { ++ encryption_ability_t ability; ++ encryption_status_t status; ++} encryption_information_t; ++ ++mdadm_status_t ++get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose); +-- +2.41.0 + diff --git a/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch b/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch deleted file mode 100644 index 52fd3e9..0000000 --- a/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 28520bf114b3b0515a48ff44fff4ecbe9ed6dfad Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:18 -0600 -Subject: [PATCH 43/83] mdadm/test: Mark and ignore broken test failures - -Add functionality to continue if a test marked as broken fails. - -To mark a test as broken, a file with the same name but with the suffix -'.broken' should exist. The first line in the file will be printed with -a KNOWN BROKEN message; the rest of the file can describe the how the -test is broken. - -Also adds --skip-broken and --skip-always-broken to skip all the tests -that have a .broken file or to skip all tests whose .broken file's first -line contains the keyword always. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 37 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/test b/test -index da6db5e0..61d9ee83 100755 ---- a/test -+++ b/test -@@ -10,6 +10,8 @@ devlist= - - savelogs=0 - exitonerror=1 -+ctrl_c_error=0 -+skipbroken=0 - loop=1 - prefix='[0-9][0-9]' - -@@ -36,6 +38,7 @@ die() { - - ctrl_c() { - exitonerror=1 -+ ctrl_c_error=1 - } - - # mdadm always adds --quiet, and we want to see any unexpected messages -@@ -80,8 +83,21 @@ mdadm() { - do_test() { - _script=$1 - _basename=`basename $_script` -+ _broken=0 -+ - if [ -f "$_script" ] - then -+ if [ -f "${_script}.broken" ]; then -+ _broken=1 -+ _broken_msg=$(head -n1 "${_script}.broken" | tr -d '\n') -+ if [ "$skipbroken" == "all" ]; then -+ return -+ elif [ "$skipbroken" == "always" ] && -+ [[ "$_broken_msg" == *always* ]]; then -+ return -+ fi -+ fi -+ - rm -f $targetdir/stderr - # this might have been reset: restore the default. - echo 2000 > /proc/sys/dev/raid/speed_limit_max -@@ -98,10 +114,15 @@ do_test() { - else - save_log fail - _fail=1 -+ if [ "$_broken" == "1" ]; then -+ echo " (KNOWN BROKEN TEST: $_broken_msg)" -+ fi - fi - [ "$savelogs" == "1" ] && - mv -f $targetdir/log $logdir/$_basename.log -- [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1 -+ [ "$ctrl_c_error" == "1" ] && exit 1 -+ [ "$_fail" == "1" -a "$exitonerror" == "1" \ -+ -a "$_broken" == "0" ] && exit 1 - fi - } - -@@ -119,6 +140,8 @@ do_help() { - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests - --loop=N Run tests N times (0 to run forever) -+ --skip-broken Skip tests that are known to be broken -+ --skip-always-broken Skip tests that are known to always fail - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -216,6 +239,12 @@ parse_args() { - --loop=* ) - loop="${i##*=}" - ;; -+ --skip-broken ) -+ skipbroken=all -+ ;; -+ --skip-always-broken ) -+ skipbroken=always -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -279,7 +308,11 @@ main() { - else - for script in $testdir/$prefix $testdir/$prefix*[^~] - do -- do_test $script -+ case $script in -+ *.broken) ;; -+ *) -+ do_test $script -+ esac - done - fi - --- -2.38.1 - diff --git a/SOURCES/0044-Add-reading-SATA-encryption-information.patch b/SOURCES/0044-Add-reading-SATA-encryption-information.patch new file mode 100644 index 0000000..f15fb84 --- /dev/null +++ b/SOURCES/0044-Add-reading-SATA-encryption-information.patch @@ -0,0 +1,459 @@ +From df38df3052c3386c0fd076e0d534b4f688b5c8a4 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:17 +0100 +Subject: [PATCH 44/69] Add reading SATA encryption information + +Functionality reads information about SATA disk encryption. Technical +documentation used is given in the implementation. + +The implementation is able to recognized two encryption standards for SATA +drives, OPAL and ATA security. + +If the SATA drive supports OPAL, encryption status and ability are +determined based on Opal Level 0 discovery response, for ATA security, +based on ATA identify response. If SATA supports OPAL, ability is set to +"SED", for ATA security to "Other". + +SED(Self-Encrypting Drive) is commonly used to describe drive which using +OPAL or Enterprise standards developed by Trusted Computing Group. Ability +"Other" is used for ATA security because we rely only on information from +ATA identify which describe the overall state of encryption. + +It is allowed to mix disks with different encryption ability such as "SED" +and "Other" and it is not security gap. + +Motivation for adding this functionality is to block mixing of disks in +IMSM arrays with encryption enabled and disabled. The main goal is to not +allow stealing data by rebuilding array to not encrypted drive which can be +read elsewhere. + +For SATA Opal drives, libata allow_tmp parameter enabled is required, which +is necessary for Opal Security commands to work, therefore, if the +parameter is not enabled, SATA Opal disk cannot be used in case the +encryption will be checked by metadata. + +Implemented functions will be used in one of the next patches. In one of +the next patches, a flag will be added to enable disabling SATA Opal +encryption checking due to allow_tpm kernel setting dependency. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + drive_encryption.c | 318 +++++++++++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 3 + + mdadm.h | 1 + + sysfs.c | 29 +++++ + 4 files changed, 351 insertions(+) + +diff --git a/drive_encryption.c b/drive_encryption.c +index b44585a7..d520f0c7 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -10,8 +10,12 @@ + + #include + #include ++#include ++#include + #include "drive_encryption.h" + ++#define DEFAULT_SECTOR_SIZE (512) ++ + /* + * Opal defines + * TCG Storage Opal SSC 2.01 chapter 3.3.3 +@@ -34,6 +38,35 @@ + #define NVME_OACS_BYTE_POSITION (256) + #define NVME_IDENTIFY_CONTROLLER_DATA (1) + ++/* ++ * ATA defines ++ * ATA/ATAPI Command Set ATA8-ACS ++ * SCSI / ATA Translation - 3 (SAT-3) ++ * SCSI Primary Commands - 4 (SPC-4) ++ * AT Attachment-8 - ATA Serial Transport (ATA8-AST) ++ * ATA Command Pass-Through ++ */ ++#define ATA_IDENTIFY (0xec) ++#define ATA_TRUSTED_RECEIVE (0x5c) ++#define ATA_SECURITY_WORD_POSITION (128) ++#define HDIO_DRIVE_CMD (0x031f) ++#define ATA_TRUSTED_COMPUTING_POS (48) ++#define ATA_PASS_THROUGH_12 (0xa1) ++#define ATA_IDENTIFY_RESPONSE_LEN (512) ++#define ATA_PIO_DATA_IN (4) ++#define SG_CHECK_CONDITION (0x02) ++#define ATA_STATUS_RETURN_DESCRIPTOR (0x09) ++#define ATA_PT_INFORMATION_AVAILABLE_ASCQ (0x1d) ++#define ATA_PT_INFORMATION_AVAILABLE_ASC (0x00) ++#define ATA_INQUIRY_LENGTH (0x0c) ++#define SG_INTERFACE_ID 'S' ++#define SG_IO_TIMEOUT (60000) ++#define SG_SENSE_SIZE (32) ++#define SENSE_DATA_CURRENT_FIXED (0x70) ++#define SENSE_DATA_CURRENT_DESC (0x72) ++#define SENSE_CURRENT_RES_DESC_POS (8) ++#define SG_DRIVER_SENSE (0x08) ++ + typedef enum drive_feature_support_status { + /* Drive feature is supported. */ + DRIVE_FEAT_SUP_ST = 0, +@@ -87,6 +120,27 @@ typedef struct supported_security_protocols { + __u8 list[504]; + } supported_security_protocols_t; + ++/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */ ++typedef struct ata_security_status { ++ __u16 security_supported : 1; ++ __u16 security_enabled : 1; ++ __u16 security_locked : 1; ++ __u16 security_frozen : 1; ++ __u16 security_count_expired : 1; ++ __u16 enhanced_security_erase_supported : 1; ++ __u16 reserved1 : 2; ++ __u16 security_level : 1; ++ __u16 reserved2 : 7; ++} __attribute__((__packed__)) ata_security_status_t; ++ ++/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */ ++typedef struct ata_trusted_computing { ++ __u16 tc_feature :1; ++ __u16 reserved : 13; ++ __u16 var1 : 1; ++ __u16 var2 : 1; ++} __attribute__((__packed__)) ata_trusted_computing_t; ++ + /** + * get_opal_locking_feature_description() - get opal locking feature description. + * @response: response from Opal Discovery Level 0. +@@ -360,3 +414,267 @@ get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *info + + return status; + } ++ ++/** ++ * ata_pass_through12_ioctl() - ata pass through12 ioctl. ++ * @disk_fd: a disk file descriptor. ++ * @ata_command: ata command. ++ * @sec_protocol: security protocol. ++ * @comm_id: additional command id. ++ * @response_buffer: response buffer to fill out. ++ * @buf_size: response buffer size. ++ * @verbose: verbose flag. ++ * ++ * Based on the documentations ATA Command Pass-Through, chapter 13.2.2 and ++ * ATA Translation - 3 (SAT-3), send read ata pass through 12 command via ioctl(). ++ * On success, @response_buffer will be completed. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++static mdadm_status_t ++ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u16 comm_id, ++ void *response_buffer, size_t buf_size, const int verbose) ++{ ++ __u8 cdb[ATA_INQUIRY_LENGTH] = {0}; ++ __u8 sense[SG_SENSE_SIZE] = {0}; ++ __u8 *sense_desc = NULL; ++ sg_io_hdr_t sg = {0}; ++ ++ /* ++ * ATA Command Pass-Through, chapter 13.2.2 ++ * SCSI Primary Commands - 4 (SPC-4) ++ * ATA Translation - 3 (SAT-3) ++ */ ++ cdb[0] = ATA_PASS_THROUGH_12; ++ /* protocol, bits 1-4 */ ++ cdb[1] = ATA_PIO_DATA_IN << 1; ++ /* Bytes: CK_COND=1, T_DIR = 1, BYTE_BLOCK = 1, Length in Sector Count = 2 */ ++ cdb[2] = 0x2E; ++ cdb[3] = sec_protocol; ++ /* Sector count */ ++ cdb[4] = buf_size / DEFAULT_SECTOR_SIZE; ++ cdb[6] = (comm_id) & 0xFF; ++ cdb[7] = (comm_id >> 8) & 0xFF; ++ cdb[9] = ata_command; ++ ++ sg.interface_id = SG_INTERFACE_ID; ++ sg.cmd_len = sizeof(cdb); ++ sg.mx_sb_len = sizeof(sense); ++ sg.dxfer_direction = SG_DXFER_FROM_DEV; ++ sg.dxfer_len = buf_size; ++ sg.dxferp = response_buffer; ++ sg.cmdp = cdb; ++ sg.sbp = sense; ++ sg.timeout = SG_IO_TIMEOUT; ++ sg.usr_ptr = NULL; ++ ++ if (ioctl(disk_fd, SG_IO, &sg) < 0) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if ((sg.status && sg.status != SG_CHECK_CONDITION) || sg.host_status || ++ (sg.driver_status && sg.driver_status != SG_DRIVER_SENSE)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ pr_vrb("SG_IO error: ATA_12 Status: %d Host Status: %d, Driver Status: %d\n", ++ sg.status, sg.host_status, sg.driver_status); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* verify expected sense response code */ ++ if (!(sense[0] == SENSE_DATA_CURRENT_DESC || sense[0] == SENSE_DATA_CURRENT_FIXED)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd)); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ sense_desc = sense + SENSE_CURRENT_RES_DESC_POS; ++ /* verify sense data current response with descriptor format */ ++ if (sense[0] == SENSE_DATA_CURRENT_DESC && ++ !(sense_desc[0] == ATA_STATUS_RETURN_DESCRIPTOR && ++ sense_desc[1] == ATA_INQUIRY_LENGTH)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", ++ fd2kname(disk_fd), sense[2], sense[3]); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ /* verify sense data current response with fixed format */ ++ if (sense[0] == SENSE_DATA_CURRENT_FIXED && ++ !(sense[12] == ATA_PT_INFORMATION_AVAILABLE_ASC && ++ sense[13] == ATA_PT_INFORMATION_AVAILABLE_ASCQ)) { ++ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n", ++ fd2kname(disk_fd), sense[12], sense[13]); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_sec_prot_01h_supported_ata() - check if security protocol 01h supported for given SATA disk. ++ * @disk_fd: a disk file descriptor. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed. ++ */ ++static drive_feat_sup_st is_sec_prot_01h_supported_ata(int disk_fd, const int verbose) ++{ ++ supported_security_protocols_t security_protocols; ++ ++ mdadm_status_t result = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_00, ++ 0x0, &security_protocols, ++ sizeof(security_protocols), verbose); ++ if (result) ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ ++ if (is_sec_prot_01h_supported(&security_protocols)) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * is_ata_trusted_computing_supported() - check if ata trusted computing supported. ++ * @buffer: buffer with ATA identify response, not NULL. ++ * ++ * Return: true if trusted computing bit set, false otherwise. ++ */ ++bool is_ata_trusted_computing_supported(__u16 *buffer) ++{ ++ /* Added due to warnings from the compiler about a possible uninitialized variable below. */ ++ assert(buffer); ++ ++ __u16 security_tc_frame = __le16_to_cpu(buffer[ATA_TRUSTED_COMPUTING_POS]); ++ ata_trusted_computing_t *security_tc = (ata_trusted_computing_t *)&security_tc_frame; ++ ++ if (security_tc->tc_feature == 1) ++ return true; ++ ++ return false; ++} ++ ++/** ++ * get_ata_standard_security_status() - get ATA disk encryption information from ATA identify. ++ * @buffer: buffer with response from ATA identify, not NULL. ++ * @information: struct to fill out, describing encryption status of disk. ++ * ++ * The function based on the Security status frame from ATA identify, ++ * completed encryption information. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++static mdadm_status_t get_ata_standard_security_status(__u16 *buffer, ++ struct encryption_information *information) ++{ ++ /* Added due to warnings from the compiler about a possible uninitialized variable below. */ ++ assert(buffer); ++ ++ __u16 security_status_frame = __le16_to_cpu(buffer[ATA_SECURITY_WORD_POSITION]); ++ ata_security_status_t *security_status = (ata_security_status_t *)&security_status_frame; ++ ++ if (!security_status->security_supported) { ++ information->ability = ENC_ABILITY_NONE; ++ information->status = ENC_STATUS_UNENCRYPTED; ++ ++ return MDADM_STATUS_SUCCESS; ++ } ++ ++ information->ability = ENC_ABILITY_OTHER; ++ ++ if (security_status->security_enabled == 0) ++ information->status = ENC_STATUS_UNENCRYPTED; ++ else if (security_status->security_locked == 1) ++ information->status = ENC_STATUS_LOCKED; ++ else ++ information->status = ENC_STATUS_UNLOCKED; ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ ++/** ++ * is_ata_opal() - check if SATA disk support Opal. ++ * @disk_fd: a disk file descriptor. ++ * @buffer: buffer with ATA identify response. ++ * @verbose: verbose flag. ++ * ++ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported, ++ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check. ++ */ ++static drive_feat_sup_st is_ata_opal(int disk_fd, __u16 *buffer_identify, const int verbose) ++{ ++ bool tc_status = is_ata_trusted_computing_supported(buffer_identify); ++ drive_feat_sup_st tcg_sec_prot_status; ++ ++ if (!tc_status) ++ return DRIVE_FEAT_NOT_SUP_ST; ++ ++ tcg_sec_prot_status = is_sec_prot_01h_supported_ata(disk_fd, verbose); ++ ++ if (tcg_sec_prot_status == DRIVE_FEAT_CHECK_FAILED_ST) { ++ pr_vrb("Failed to verify if security protocol 01h supported. Device /dev/%s.\n", ++ fd2kname(disk_fd)); ++ return DRIVE_FEAT_CHECK_FAILED_ST; ++ } ++ ++ if (tc_status && tcg_sec_prot_status == DRIVE_FEAT_SUP_ST) ++ return DRIVE_FEAT_SUP_ST; ++ ++ return DRIVE_FEAT_NOT_SUP_ST; ++} ++ ++/** ++ * get_ata_encryption_information() - get ATA disk encryption information. ++ * @disk_fd: a disk file descriptor. ++ * @information: struct to fill out, describing encryption status of disk. ++ * @verbose: verbose flag. ++ * ++ * The function reads information about encryption, if the disk supports Opal, ++ * the information is completed based on Opal Level 0 discovery, otherwise, ++ * based on ATA security status frame from ATA identification response. ++ * For possible encryption statuses and abilities, ++ * please refer to enums &encryption_status and &encryption_ability. ++ * ++ * Based on the documentations ATA/ATAPI Command Set ATA8-ACS and ++ * AT Attachment-8 - ATA Serial Transport (ATA8-AST). ++ * ++ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail. ++ */ ++mdadm_status_t ++get_ata_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose) ++{ ++ __u8 buffer_opal_level0_discovery[OPAL_IO_BUFFER_LEN] = {0}; ++ __u16 buffer_identify[ATA_IDENTIFY_RESPONSE_LEN] = {0}; ++ drive_feat_sup_st ata_opal_status; ++ mdadm_status_t status; ++ ++ /* Get disk ATA identification */ ++ status = ata_pass_through12_ioctl(disk_fd, ATA_IDENTIFY, 0x0, 0x0, buffer_identify, ++ sizeof(buffer_identify), verbose); ++ if (status == MDADM_STATUS_ERROR) ++ return MDADM_STATUS_ERROR; ++ ++ if (is_ata_trusted_computing_supported(buffer_identify) && ++ !sysfs_is_libata_allow_tpm_enabled(verbose)) { ++ pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose); ++ if (ata_opal_status == DRIVE_FEAT_CHECK_FAILED_ST) ++ return MDADM_STATUS_ERROR; ++ ++ if (ata_opal_status == DRIVE_FEAT_NOT_SUP_ST) ++ return get_ata_standard_security_status(buffer_identify, information); ++ ++ /* SATA Opal */ ++ status = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_01, ++ OPAL_DISCOVERY_COMID, buffer_opal_level0_discovery, ++ OPAL_IO_BUFFER_LEN, verbose); ++ if (status != MDADM_STATUS_SUCCESS) ++ return MDADM_STATUS_ERROR; ++ ++ return get_opal_encryption_information(buffer_opal_level0_discovery, information); ++} +diff --git a/drive_encryption.h b/drive_encryption.h +index 82c2c624..77c7f10f 100644 +--- a/drive_encryption.h ++++ b/drive_encryption.h +@@ -30,3 +30,6 @@ typedef struct encryption_information { + mdadm_status_t + get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information, + const int verbose); ++mdadm_status_t ++get_ata_encryption_information(int disk_fd, struct encryption_information *information, ++ const int verbose); +diff --git a/mdadm.h b/mdadm.h +index fbb161ba..52a66b9a 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -853,6 +853,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, + int source, unsigned long long read_offset, + unsigned long long start, unsigned long long length, + char *src_buf); ++extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose); + + #ifndef Sendmail + #define Sendmail "/usr/lib/sendmail -t" +diff --git a/sysfs.c b/sysfs.c +index 4ded1672..20fe1e9e 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -1121,3 +1121,32 @@ void sysfsline(char *line) + sr->next = sysfs_rules; + sysfs_rules = sr; + } ++ ++/** ++ * sysfs_is_libata_allow_tpm_enabled() - check if libata allow_tmp is enabled. ++ * @verbose: verbose flag. ++ * ++ * Check if libata allow_tmp flag is set, this is required for SATA Opal Security commands to work. ++ * ++ * Return: true if allow_tpm enable, false otherwise. ++ */ ++bool sysfs_is_libata_allow_tpm_enabled(const int verbose) ++{ ++ const char *path = "/sys/module/libata/parameters/allow_tpm"; ++ const char *expected_value = "1"; ++ int fd = open(path, O_RDONLY); ++ char buf[3]; ++ ++ if (!is_fd_valid(fd)) { ++ pr_vrb("Failed open file descriptor to %s. Cannot check libata allow_tpm param.\n", ++ path); ++ return false; ++ } ++ ++ sysfs_fd_get_str(fd, buf, sizeof(buf)); ++ close(fd); ++ ++ if (strncmp(buf, expected_value, 1) == 0) ++ return true; ++ return false; ++} +-- +2.41.0 + diff --git a/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch b/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch deleted file mode 100644 index 2484e1b..0000000 --- a/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch +++ /dev/null @@ -1,447 +0,0 @@ -From daa86d6634761796ada1f535c13e47fdd3cc95eb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:19 -0600 -Subject: [PATCH 44/83] tests: Add broken files for all broken tests - -Each broken file contains the rough frequency of brokeness as well -as a brief explanation of what happens when it breaks. Estimates -of failure rates are not statistically significant and can vary -run to run. - -This is really just a view from my window. Tests were done on a -small VM with the default loop devices, not real hardware. We've -seen different kernel configurations can cause bugs to appear as well -(ie. different block schedulers). It may also be that different race -conditions will be seen on machines with different performance -characteristics. - -These annotations were done with the kernel currently in md/md-next: - - facef3b96c5b ("md: Notify sysfs sync_completed in md_reap_sync_thread()") - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/01r5integ.broken | 7 ++++ - tests/01raid6integ.broken | 7 ++++ - tests/04r5swap.broken | 7 ++++ - tests/07autoassemble.broken | 8 ++++ - tests/07autodetect.broken | 5 +++ - tests/07changelevelintr.broken | 9 +++++ - tests/07changelevels.broken | 9 +++++ - tests/07reshape5intr.broken | 45 ++++++++++++++++++++++ - tests/07revert-grow.broken | 31 +++++++++++++++ - tests/07revert-shrink.broken | 9 +++++ - tests/07testreshape5.broken | 12 ++++++ - tests/09imsm-assemble.broken | 6 +++ - tests/09imsm-create-fail-rebuild.broken | 5 +++ - tests/09imsm-overlap.broken | 7 ++++ - tests/10ddf-assemble-missing.broken | 6 +++ - tests/10ddf-fail-create-race.broken | 7 ++++ - tests/10ddf-fail-two-spares.broken | 5 +++ - tests/10ddf-incremental-wrong-order.broken | 9 +++++ - tests/14imsm-r1_2d-grow-r1_3d.broken | 5 +++ - tests/14imsm-r1_2d-takeover-r0_2d.broken | 6 +++ - tests/18imsm-r10_4d-takeover-r0_2d.broken | 5 +++ - tests/18imsm-r1_2d-takeover-r0_1d.broken | 6 +++ - tests/19raid6auto-repair.broken | 5 +++ - tests/19raid6repair.broken | 5 +++ - 24 files changed, 226 insertions(+) - create mode 100644 tests/01r5integ.broken - create mode 100644 tests/01raid6integ.broken - create mode 100644 tests/04r5swap.broken - create mode 100644 tests/07autoassemble.broken - create mode 100644 tests/07autodetect.broken - create mode 100644 tests/07changelevelintr.broken - create mode 100644 tests/07changelevels.broken - create mode 100644 tests/07reshape5intr.broken - create mode 100644 tests/07revert-grow.broken - create mode 100644 tests/07revert-shrink.broken - create mode 100644 tests/07testreshape5.broken - create mode 100644 tests/09imsm-assemble.broken - create mode 100644 tests/09imsm-create-fail-rebuild.broken - create mode 100644 tests/09imsm-overlap.broken - create mode 100644 tests/10ddf-assemble-missing.broken - create mode 100644 tests/10ddf-fail-create-race.broken - create mode 100644 tests/10ddf-fail-two-spares.broken - create mode 100644 tests/10ddf-incremental-wrong-order.broken - create mode 100644 tests/14imsm-r1_2d-grow-r1_3d.broken - create mode 100644 tests/14imsm-r1_2d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r10_4d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r1_2d-takeover-r0_1d.broken - create mode 100644 tests/19raid6auto-repair.broken - create mode 100644 tests/19raid6repair.broken - -diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken -new file mode 100644 -index 00000000..20737637 ---- /dev/null -+++ b/tests/01r5integ.broken -@@ -0,0 +1,7 @@ -+fails rarely -+ -+Fails about 1 in every 30 runs with a sha mismatch error: -+ -+ c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match -+ 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3 -+ missing -diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken -new file mode 100644 -index 00000000..1df735f0 ---- /dev/null -+++ b/tests/01raid6integ.broken -@@ -0,0 +1,7 @@ -+fails infrequently -+ -+Fails about 1 in 5 with a sha mismatch: -+ -+ 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match -+ a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and -+ /dev/loop3 missing -diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken -new file mode 100644 -index 00000000..e38987db ---- /dev/null -+++ b/tests/04r5swap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 has no superblock - assembly aborted -+ -+ ERROR: no recovery happening -diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken -new file mode 100644 -index 00000000..8be09407 ---- /dev/null -+++ b/tests/07autoassemble.broken -@@ -0,0 +1,8 @@ -+always fails -+ -+Prints lots of messages, but the array doesn't assemble. Error -+possibly related to: -+ -+ mdadm: /dev/md/1 is busy - skipping -+ mdadm: no recogniseable superblock on /dev/md/testing:0 -+ mdadm: /dev/md/2 is busy - skipping -diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken -new file mode 100644 -index 00000000..294954a1 ---- /dev/null -+++ b/tests/07autodetect.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ ERROR: no resync happening -diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken -new file mode 100644 -index 00000000..284b4906 ---- /dev/null -+++ b/tests/07changelevelintr.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: this change will reduce the size of the array. -+ use --grow --array-size first to truncate array. -+ e.g. mdadm --grow /dev/md0 --array-size 56832 -+ -+ ERROR: no reshape happening -diff --git a/tests/07changelevels.broken b/tests/07changelevels.broken -new file mode 100644 -index 00000000..9b930d93 ---- /dev/null -+++ b/tests/07changelevels.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop1 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop2 is smaller than given size. 18976K < 19968K + metadata -+ -+ ERROR: /dev/md0 isn't a block device. -diff --git a/tests/07reshape5intr.broken b/tests/07reshape5intr.broken -new file mode 100644 -index 00000000..efe52a66 ---- /dev/null -+++ b/tests/07reshape5intr.broken -@@ -0,0 +1,45 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex -+held") -+ -+The new error is simply: -+ -+ ERROR: no reshape happening -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails infrequently -+ -+Fails roughly 1 in 4 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: cannot re-read metadata from /dev/loop6 - aborting -+ -+ ERROR: no reshape happening -+ -+Also have seen a random deadlock: -+ -+ INFO: task mdadm:109702 blocked for more than 30 seconds. -+ Not tainted 5.18.0-rc3-eid-vmlocalyes-dbg-00095-g3c2b5427979d #2040 -+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. -+ task:mdadm state:D stack: 0 pid:109702 ppid: 1 flags:0x00004000 -+ Call Trace: -+ -+ __schedule+0x67e/0x13b0 -+ schedule+0x82/0x110 -+ mddev_suspend+0x2e1/0x330 -+ suspend_lo_store+0xbd/0x140 -+ md_attr_store+0xcb/0x130 -+ sysfs_kf_write+0x89/0xb0 -+ kernfs_fop_write_iter+0x202/0x2c0 -+ new_sync_write+0x222/0x330 -+ vfs_write+0x3bc/0x4d0 -+ ksys_write+0xd9/0x180 -+ __x64_sys_write+0x43/0x50 -+ do_syscall_64+0x3b/0x90 -+ entry_SYSCALL_64_after_hwframe+0x44/0xae -diff --git a/tests/07revert-grow.broken b/tests/07revert-grow.broken -new file mode 100644 -index 00000000..9b6db86f ---- /dev/null -+++ b/tests/07revert-grow.broken -@@ -0,0 +1,31 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex held") -+ -+The errors are: -+ -+ mdadm: No active reshape to revert on /dev/loop0 -+ ERROR: active raid5 not found -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails rarely -+ -+Fails about 1 in every 30 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: backup file /tmp/md-backup inaccessible: No such file or directory -+ mdadm: failed to add /dev/loop1 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop2 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop3 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop0 to /dev/md/0: Invalid argument -+ mdadm: /dev/md/0 assembled from 1 drive - need all 5 to start it -+ (use --run to insist). -+ -+ grep: /sys/block/md*/md/sync_action: No such file or directory -+ -+ ERROR: active raid5 not found -diff --git a/tests/07revert-shrink.broken b/tests/07revert-shrink.broken -new file mode 100644 -index 00000000..c33c39ec ---- /dev/null -+++ b/tests/07revert-shrink.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: this change will reduce the size of the array. -+ use --grow --array-size first to truncate array. -+ e.g. mdadm --grow /dev/md0 --array-size 53760 -+ -+ ERROR: active raid5 not found -diff --git a/tests/07testreshape5.broken b/tests/07testreshape5.broken -new file mode 100644 -index 00000000..a8ce03e4 ---- /dev/null -+++ b/tests/07testreshape5.broken -@@ -0,0 +1,12 @@ -+always fails -+ -+Test seems to run 'test_stripe' at $dir directory, but $dir is never -+set. If $dir is adjusted to $PWD, the test still fails with: -+ -+ mdadm: /dev/loop2 is not suitable for this array. -+ mdadm: create aborted -+ ++ return 1 -+ ++ cmp -s -n 8192 /dev/md0 /tmp/RandFile -+ ++ echo cmp failed -+ cmp failed -+ ++ exit 2 -diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken -new file mode 100644 -index 00000000..a6d4d5cf ---- /dev/null -+++ b/tests/09imsm-assemble.broken -@@ -0,0 +1,6 @@ -+fails infrequently -+ -+Fails roughly 1 in 10 runs with errors: -+ -+ mdadm: /dev/loop2 is still in use, cannot remove. -+ /dev/loop2 removal from /dev/md/container should have succeeded -diff --git a/tests/09imsm-create-fail-rebuild.broken b/tests/09imsm-create-fail-rebuild.broken -new file mode 100644 -index 00000000..40c4b294 ---- /dev/null -+++ b/tests/09imsm-create-fail-rebuild.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ **Error**: Array size mismatch - expected 3072, actual 16384 -diff --git a/tests/09imsm-overlap.broken b/tests/09imsm-overlap.broken -new file mode 100644 -index 00000000..e7ccab76 ---- /dev/null -+++ b/tests/09imsm-overlap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ /dev/md/vol3 failed check -diff --git a/tests/10ddf-assemble-missing.broken b/tests/10ddf-assemble-missing.broken -new file mode 100644 -index 00000000..bfd8d103 ---- /dev/null -+++ b/tests/10ddf-assemble-missing.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with errors: -+ -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -diff --git a/tests/10ddf-fail-create-race.broken b/tests/10ddf-fail-create-race.broken -new file mode 100644 -index 00000000..6c0df023 ---- /dev/null -+++ b/tests/10ddf-fail-create-race.broken -@@ -0,0 +1,7 @@ -+usually fails -+ -+Fails about 9 out of 10 times with many errors: -+ -+ mdadm: cannot open MISSING: No such file or directory -+ ERROR: non-degraded array found -+ ERROR: disk 0 not marked as failed in meta data -diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken -new file mode 100644 -index 00000000..eeea56d9 ---- /dev/null -+++ b/tests/10ddf-fail-two-spares.broken -@@ -0,0 +1,5 @@ -+fails infrequently -+ -+Fails roughly 1 in 3 with error: -+ -+ ERROR: /dev/md/vol1 should be optimal in meta data -diff --git a/tests/10ddf-incremental-wrong-order.broken b/tests/10ddf-incremental-wrong-order.broken -new file mode 100644 -index 00000000..a5af3bab ---- /dev/null -+++ b/tests/10ddf-incremental-wrong-order.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ ERROR: sha1sum of /dev/md/vol0 has changed -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop8 -+ ERROR: unexpected number of online disks on /dev/loop8 -+ ERROR: sha1sum of /dev/md/vol0 has changed -diff --git a/tests/14imsm-r1_2d-grow-r1_3d.broken b/tests/14imsm-r1_2d-grow-r1_3d.broken -new file mode 100644 -index 00000000..4ef1d406 ---- /dev/null -+++ b/tests/14imsm-r1_2d-grow-r1_3d.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ mdadm/tests/func.sh: line 325: dvsize/chunk: division by 0 (error token is "chunk") -diff --git a/tests/14imsm-r1_2d-takeover-r0_2d.broken b/tests/14imsm-r1_2d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..89cd4e57 ---- /dev/null -+++ b/tests/14imsm-r1_2d-takeover-r0_2d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/18imsm-r10_4d-takeover-r0_2d.broken b/tests/18imsm-r10_4d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..a27399f5 ---- /dev/null -+++ b/tests/18imsm-r10_4d-takeover-r0_2d.broken -@@ -0,0 +1,5 @@ -+fails rarely -+ -+Fails about 1 run in 100 with message: -+ -+ ERROR: size is wrong for /dev/md/vol0: 2 * 5120 (chunk=128) = 20480, not 0 -diff --git a/tests/18imsm-r1_2d-takeover-r0_1d.broken b/tests/18imsm-r1_2d-takeover-r0_1d.broken -new file mode 100644 -index 00000000..aa1982e6 ---- /dev/null -+++ b/tests/18imsm-r1_2d-takeover-r0_1d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/19raid6auto-repair.broken b/tests/19raid6auto-repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6auto-repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" -diff --git a/tests/19raid6repair.broken b/tests/19raid6repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" --- -2.38.1 - diff --git a/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch b/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch new file mode 100644 index 0000000..13ea340 --- /dev/null +++ b/SOURCES/0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch @@ -0,0 +1,163 @@ +From 336e13fc5ef43bc5b4633a9dadac5f7208e6c241 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:18 +0100 +Subject: [PATCH 45/69] Add key ENCRYPTION_NO_VERIFY to conf + +Add ENCRYPTION_NO_VERIFY config key and allow to disable checking +encryption status for given type of drives. + +The key is introduced because of SATA Opal disks for which TPM commands +must be enabled in libata kernel module, (libata.allow_tpm=1), otherwise +it is impossible to verify encryption status. TPM commands are disabled by +default. + +Currently the key only supports the "sata_opal" value, if necessary, +the functionality is ready to support more types of disks. This +functionality will be used in the next patches. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + config.c | 25 ++++++++++++++++++++++++- + drive_encryption.c | 16 ++++++++++++---- + mdadm.conf.5.in | 13 +++++++++++++ + mdadm.h | 1 + + 4 files changed, 50 insertions(+), 5 deletions(-) + +diff --git a/config.c b/config.c +index 44f7dd2f..b46d71cb 100644 +--- a/config.c ++++ b/config.c +@@ -81,7 +81,7 @@ char DefaultAltConfDir[] = CONFFILE2 ".d"; + + enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev, + Homehost, HomeCluster, AutoMode, Policy, PartPolicy, Sysfs, +- MonitorDelay, LTEnd }; ++ MonitorDelay, EncryptionNoVerify, LTEnd }; + char *keywords[] = { + [Devices] = "devices", + [Array] = "array", +@@ -96,6 +96,7 @@ char *keywords[] = { + [PartPolicy]="part-policy", + [Sysfs] = "sysfs", + [MonitorDelay] = "monitordelay", ++ [EncryptionNoVerify] = "ENCRYPTION_NO_VERIFY", + [LTEnd] = NULL + }; + +@@ -729,6 +730,19 @@ void monitordelayline(char *line) + } + } + ++static bool sata_opal_encryption_no_verify; ++void encryption_no_verify_line(char *line) ++{ ++ char *word; ++ ++ for (word = dl_next(line); word != line; word = dl_next(word)) { ++ if (strcasecmp(word, "sata_opal") == 0) ++ sata_opal_encryption_no_verify = true; ++ else ++ pr_err("unrecognised word on ENCRYPTION_NO_VERIFY line: %s\n", word); ++ } ++} ++ + char auto_yes[] = "yes"; + char auto_no[] = "no"; + char auto_homehost[] = "homehost"; +@@ -913,6 +927,9 @@ void conf_file(FILE *f) + case MonitorDelay: + monitordelayline(line); + break; ++ case EncryptionNoVerify: ++ encryption_no_verify_line(line); ++ break; + default: + pr_err("Unknown keyword %s\n", line); + } +@@ -1075,6 +1092,12 @@ int conf_get_monitor_delay(void) + return monitor_delay; + } + ++bool conf_get_sata_opal_encryption_no_verify(void) ++{ ++ load_conffile(); ++ return sata_opal_encryption_no_verify; ++} ++ + struct createinfo *conf_get_create_info(void) + { + load_conffile(); +diff --git a/drive_encryption.c b/drive_encryption.c +index d520f0c7..6b2bd358 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -656,10 +656,18 @@ get_ata_encryption_information(int disk_fd, struct encryption_information *infor + if (status == MDADM_STATUS_ERROR) + return MDADM_STATUS_ERROR; + +- if (is_ata_trusted_computing_supported(buffer_identify) && +- !sysfs_is_libata_allow_tpm_enabled(verbose)) { +- pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n"); +- return MDADM_STATUS_ERROR; ++ /* Possible OPAL support, further checks require tpm_enabled.*/ ++ if (is_ata_trusted_computing_supported(buffer_identify)) { ++ /* OPAL SATA encryption checking disabled. */ ++ if (conf_get_sata_opal_encryption_no_verify()) ++ return MDADM_STATUS_SUCCESS; ++ ++ if (!sysfs_is_libata_allow_tpm_enabled(verbose)) { ++ pr_vrb("Detected SATA drive /dev/%s with Trusted Computing support.\n", ++ fd2kname(disk_fd)); ++ pr_vrb("Cannot verify encryption state. Requires libata.tpm_enabled=1.\n"); ++ return MDADM_STATUS_ERROR; ++ } + } + + ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose); +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index 787e51e9..afb0a296 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -636,6 +636,17 @@ If multiple + .B MINITORDELAY + lines are provided, only first non-zero value is considered. + ++.TP ++.B ENCRYPTION_NO_VERIFY ++The ++.B ENCRYPTION_NO_VERIFY ++disables encryption verification for devices with particular encryption support detected. ++Currently, only verification of SATA OPAL encryption can be disabled. ++It does not disable ATA security encryption verification. ++Available parameter ++.I "sata_opal". ++ ++ + .SH FILES + + .SS {CONFFILE} +@@ -744,6 +755,8 @@ SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 + sync_speed_max=1000000 + .br + MONITORDELAY 60 ++.br ++ENCRYPTION_NO_VERIFY sata_opal + + .SH SEE ALSO + .BR mdadm (8), +diff --git a/mdadm.h b/mdadm.h +index 52a66b9a..2640b396 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1673,6 +1673,7 @@ extern char *conf_get_program(void); + extern char *conf_get_homehost(int *require_homehostp); + extern char *conf_get_homecluster(void); + extern int conf_get_monitor_delay(void); ++extern bool conf_get_sata_opal_encryption_no_verify(void); + extern char *conf_line(FILE *file); + extern char *conf_word(FILE *file, int allow_key); + extern void print_quoted(char *str); +-- +2.41.0 + diff --git a/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch b/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch deleted file mode 100644 index 74bf834..0000000 --- a/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +++ /dev/null @@ -1,316 +0,0 @@ -From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:36:02 +0200 -Subject: [PATCH 45/83] mdadm: Replace obsolete usleep with nanosleep - -According to POSIX.1-2001, usleep is considered obsolete. -Replace it with a wrapper that uses nanosleep, as recommended in man. -Add handy macros for conversions between msec, usec and nsec. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 2 +- - Grow.c | 4 ++-- - Manage.c | 10 +++++----- - managemon.c | 8 ++++---- - mdadm.h | 4 ++++ - mdmon.c | 4 ++-- - super-intel.c | 6 +++--- - util.c | 42 +++++++++++++++++++++++++++++++++--------- - 8 files changed, 54 insertions(+), 26 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 6df6bfbc..be2160b4 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1947,7 +1947,7 @@ out: - break; - close(mdfd); - } -- usleep(usecs); -+ sleep_for(0, USEC_TO_NSEC(usecs), true); - usecs <<= 1; - } - } -diff --git a/Grow.c b/Grow.c -index 97f22c75..5780635a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -954,7 +954,7 @@ int start_reshape(struct mdinfo *sra, int already_running, - err = sysfs_set_str(sra, NULL, "sync_action", - "reshape"); - if (err) -- sleep(1); -+ sleep_for(1, 0, true); - } while (err && errno == EBUSY && cnt-- > 0); - } - return err; -@@ -5058,7 +5058,7 @@ int Grow_continue_command(char *devname, int fd, - } - st->ss->getinfo_super(st, content, NULL); - if (!content->reshape_active) -- sleep(3); -+ sleep_for(3, 0, true); - else - break; - } while (cnt-- > 0); -diff --git a/Manage.c b/Manage.c -index e5e6abe4..a142f8bd 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -244,7 +244,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - "array_state", - "inactive")) < 0 && - errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count--; - } - if (err) { -@@ -328,7 +328,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) { - /* must be in the critical section - wait a bit */ - delay -= 1; -- usleep(100000); -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } - - if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0) -@@ -405,7 +405,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * quite started yet. Wait a bit and - * check 'sync_action' to see. - */ -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf)); - if (strncmp(buf, "reshape", 7) != 0) - break; -@@ -447,7 +447,7 @@ done: - count = 25; err = 0; - while (count && fd >= 0 && - (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count --; - } - if (fd >= 0 && err) { -@@ -1105,7 +1105,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, - ret = sysfs_unique_holder(devnm, rdev); - if (ret < 2) - break; -- usleep(100 * 1000); /* 100ms */ -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } while (--count > 0); - - if (ret == 0) { -diff --git a/managemon.c b/managemon.c -index 0e9bdf00..a7bfa8f6 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -207,7 +207,7 @@ static void replace_array(struct supertype *container, - remove_old(); - while (pending_discard) { - while (discard_this == NULL) -- sleep(1); -+ sleep_for(1, 0, true); - remove_old(); - } - pending_discard = old; -@@ -568,7 +568,7 @@ static void manage_member(struct mdstat_ent *mdstat, - updates = NULL; - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - replace_array(container, a, newa); - if (sysfs_set_str(&a->info, NULL, -@@ -822,7 +822,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - if (msg->len <= 0) - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - - if (msg->len == 0) { /* ping_monitor */ -@@ -836,7 +836,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - wakeup_monitor(); - - while (monitor_loop_cnt - cnt < 0) -- usleep(10 * 1000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - } else if (msg->len == -1) { /* ping_manager */ - struct mdstat_ent *mdstat = mdstat_read(1, 0); - -diff --git a/mdadm.h b/mdadm.h -index 163f4a49..add9c0b6 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1720,6 +1720,10 @@ extern int cluster_get_dlmlock(void); - extern int cluster_release_dlmlock(void); - extern void set_dlm_hooks(void); - -+#define MSEC_TO_NSEC(msec) ((msec) * 1000000) -+#define USEC_TO_NSEC(usec) ((usec) * 1000) -+extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+ - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) - #define ROUND_UP_PTR(ptr, base) ((typeof(ptr)) \ -diff --git a/mdmon.c b/mdmon.c -index c057da63..e9d035eb 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -99,7 +99,7 @@ static int clone_monitor(struct supertype *container) - if (rc) - return rc; - while (mon_tid == -1) -- usleep(10); -+ sleep_for(0, USEC_TO_NSEC(10), true); - pthread_attr_destroy(&attr); - - mgr_tid = syscall(SYS_gettid); -@@ -209,7 +209,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) - rv = kill(pid, SIGUSR1); - if (rv < 0) - break; -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - } - } - -diff --git a/super-intel.c b/super-intel.c -index 4ddfcf94..4d82af3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5275,7 +5275,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d - /* retry the load if we might have raced against mdmon */ - if (err == 3 && devnm && mdmon_running(devnm)) - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - err = load_and_parse_mpb(dfd, s, NULL, keep_fd); - if (err != 3) - break; -@@ -5377,7 +5377,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) - - if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) { - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - rv = load_and_parse_mpb(fd, super, devname, 0); - if (rv != 3) - break; -@@ -12084,7 +12084,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) - close(fd); - return 1; - } -- usleep(30000); -+ sleep_for(0, MSEC_TO_NSEC(30), true); - } else - break; - } while (retry--); -diff --git a/util.c b/util.c -index 38f0420e..ca48d976 100644 ---- a/util.c -+++ b/util.c -@@ -166,7 +166,7 @@ retry: - pr_err("error %d when get PW mode on lock %s\n", errno, str); - /* let's try several times if EAGAIN happened */ - if (dlm_lock_res->lksb.sb_status == EAGAIN && retry_count < 10) { -- sleep(10); -+ sleep_for(10, 0, true); - retry_count++; - goto retry; - } -@@ -1085,7 +1085,7 @@ int open_dev_excl(char *devnm) - int i; - int flags = O_RDWR; - dev_t devid = devnm2devid(devnm); -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - sprintf(buf, "%d:%d", major(devid), minor(devid)); - for (i = 0; i < 25; i++) { -@@ -1098,8 +1098,8 @@ int open_dev_excl(char *devnm) - } - if (errno != EBUSY) - return fd; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - return -1; -@@ -1123,7 +1123,7 @@ void wait_for(char *dev, int fd) - { - int i; - struct stat stb_want; -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - if (fstat(fd, &stb_want) != 0 || - (stb_want.st_mode & S_IFMT) != S_IFBLK) -@@ -1135,8 +1135,8 @@ void wait_for(char *dev, int fd) - (stb.st_mode & S_IFMT) == S_IFBLK && - (stb.st_rdev == stb_want.st_rdev)) - return; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - if (i == 25) -@@ -1821,7 +1821,7 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force) - while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - - return ret; - } -@@ -1834,7 +1834,7 @@ int sys_hot_remove_disk(int statefd, int force) - while ((ret = write(statefd, "remove", 6)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - return ret == 6 ? 0 : -1; - } - -@@ -2375,3 +2375,27 @@ out: - close(fd_zero); - return ret; - } -+ -+/** -+ * sleep_for() - Sleeps for specified time. -+ * @sec: Seconds to sleep for. -+ * @nsec: Nanoseconds to sleep for, has to be less than one second. -+ * @wake_after_interrupt: If set, wake up if interrupted. -+ * -+ * Function immediately returns if error different than EINTR occurs. -+ */ -+void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) -+{ -+ struct timespec delay = {.tv_sec = sec, .tv_nsec = nsec}; -+ -+ assert(nsec < MSEC_TO_NSEC(1000)); -+ -+ do { -+ errno = 0; -+ nanosleep(&delay, &delay); -+ if (errno != 0 && errno != EINTR) { -+ pr_err("Error sleeping for %us %ldns: %s\n", sec, nsec, strerror(errno)); -+ return; -+ } -+ } while (!wake_after_interrupt && errno == EINTR); -+} --- -2.38.1 - diff --git a/SOURCES/0046-imsm-print-disk-encryption-information.patch b/SOURCES/0046-imsm-print-disk-encryption-information.patch new file mode 100644 index 0000000..3d7767d --- /dev/null +++ b/SOURCES/0046-imsm-print-disk-encryption-information.patch @@ -0,0 +1,217 @@ +From bf62ed5d9642aa60abf4ac2d1d89f173bd66ae48 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:19 +0100 +Subject: [PATCH 46/69] imsm: print disk encryption information + +Print SATA/NVMe disk encryption information in --detail-platform. +Encryption Ability and Status will be printed for each disk. + +There is one exception, Opal SATA drives encryption is not checked when +ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this +reason such drives are treated as without encryption support. + +To test this feature, drives SATA/NVMe with Opal support or SATA drives +with encryption support have to be used. + +Example outputs of --detail-platform: + +Non Opal, encryption enabled, SATA drive: +Port0 : /dev/sdc (CVPR050600G3120LGN) + Encryption(Ability|Status): Other|Unlocked + +NVMe drive without Opal support: +NVMe under VMD : /dev/nvme2n1 (PHLF737302GB1P0GGN) + Encryption(Ability|Status): None|Unencrypted + +Unencrypted SATA drive with OPAL support: + +- default allow_tpm, we will get an error from mdadm: + Port6 : /dev/sdi (CVTS4246015V180IGN) +mdadm: Detected SATA drive /dev/sdi with Trusted Computing support. +mdadm: Cannot verify encryption state. Requires libata.tpm_enabled=1. +mdadm: Failed to get drive encrytpion information. + +- default "allow_tpm" and config entry "ENCRYPTION_NO_VERIFY sata_opal": +Port6 : /dev/sdi (CVTS4246015V180IGN) + Encryption(Ability|Status): None|Unencrypted + +- added "libata.allow_tpm=1" to boot parameters(requires reboot), +the status will be read correctly: +Port6 : /dev/sdi (CVTS4246015V180IGN) + Encryption(Ability|Status): SED|Unencrypted + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + drive_encryption.c | 36 ++++++++++++++++++++++++++++++++++++ + drive_encryption.h | 2 ++ + mdadm.conf.5.in | 3 +++ + super-intel.c | 42 ++++++++++++++++++++++++++++++++++++++---- + 4 files changed, 79 insertions(+), 4 deletions(-) + +diff --git a/drive_encryption.c b/drive_encryption.c +index 6b2bd358..27da9621 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -141,6 +141,42 @@ typedef struct ata_trusted_computing { + __u16 var2 : 1; + } __attribute__((__packed__)) ata_trusted_computing_t; + ++mapping_t encryption_ability_map[] = { ++ { "None", ENC_ABILITY_NONE }, ++ { "Other", ENC_ABILITY_OTHER }, ++ { "SED", ENC_ABILITY_SED }, ++ { NULL, UnSet } ++}; ++ ++mapping_t encryption_status_map[] = { ++ { "Unencrypted", ENC_STATUS_UNENCRYPTED }, ++ { "Locked", ENC_STATUS_LOCKED }, ++ { "Unlocked", ENC_STATUS_UNLOCKED }, ++ { NULL, UnSet } ++}; ++ ++/** ++ * get_encryption_ability_string() - get encryption ability name string. ++ * @ability: encryption ability enum. ++ * ++ * Return: encryption ability string. ++ */ ++const char *get_encryption_ability_string(enum encryption_ability ability) ++{ ++ return map_num_s(encryption_ability_map, ability); ++} ++ ++/** ++ * get_encryption_status_string() - get encryption status name string. ++ * @ability: encryption status enum. ++ * ++ * Return: encryption status string. ++ */ ++const char *get_encryption_status_string(enum encryption_status status) ++{ ++ return map_num_s(encryption_status_map, status); ++} ++ + /** + * get_opal_locking_feature_description() - get opal locking feature description. + * @response: response from Opal Discovery Level 0. +diff --git a/drive_encryption.h b/drive_encryption.h +index 77c7f10f..0cb8ff1b 100644 +--- a/drive_encryption.h ++++ b/drive_encryption.h +@@ -33,3 +33,5 @@ get_nvme_opal_encryption_information(int disk_fd, struct encryption_information + mdadm_status_t + get_ata_encryption_information(int disk_fd, struct encryption_information *information, + const int verbose); ++const char *get_encryption_ability_string(enum encryption_ability ability); ++const char *get_encryption_status_string(enum encryption_status status); +diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in +index afb0a296..14302a91 100644 +--- a/mdadm.conf.5.in ++++ b/mdadm.conf.5.in +@@ -643,6 +643,9 @@ The + disables encryption verification for devices with particular encryption support detected. + Currently, only verification of SATA OPAL encryption can be disabled. + It does not disable ATA security encryption verification. ++Currently effective only for ++.I IMSM ++metadata. + Available parameter + .I "sata_opal". + +diff --git a/super-intel.c b/super-intel.c +index 212387ec..fbd1c11f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include "drive_encryption.h" + + /* MPB == Metadata Parameter Block */ + #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " +@@ -2349,12 +2350,41 @@ static int imsm_read_serial(int fd, char *devname, __u8 *serial, + size_t serial_buf_len); + static void fd2devname(int fd, char *name); + +-static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose) ++void print_encryption_information(int disk_fd, enum sys_dev_type hba_type) ++{ ++ struct encryption_information information = {0}; ++ mdadm_status_t status = MDADM_STATUS_SUCCESS; ++ const char *indent = " "; ++ ++ switch (hba_type) { ++ case SYS_DEV_VMD: ++ case SYS_DEV_NVME: ++ status = get_nvme_opal_encryption_information(disk_fd, &information, 1); ++ break; ++ case SYS_DEV_SATA: ++ case SYS_DEV_SATA_VMD: ++ status = get_ata_encryption_information(disk_fd, &information, 1); ++ break; ++ default: ++ return; ++ } ++ ++ if (status) { ++ pr_err("Failed to get drive encryption information.\n"); ++ return; ++ } ++ ++ printf("%sEncryption(Ability|Status): %s|%s\n", indent, ++ get_encryption_ability_string(information.ability), ++ get_encryption_status_string(information.status)); ++} ++ ++static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_base, int verbose) + { + /* dump an unsorted list of devices attached to AHCI Intel storage + * controller, as well as non-connected ports + */ +- int hba_len = strlen(hba_path) + 1; ++ int hba_len = strlen(hba->path) + 1; + struct dirent *ent; + DIR *dir; + char *path = NULL; +@@ -2390,7 +2420,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + path = devt_to_devpath(makedev(major, minor), 1, NULL); + if (!path) + continue; +- if (!path_attached_to_hba(path, hba_path)) { ++ if (!path_attached_to_hba(path, hba->path)) { + free(path); + path = NULL; + continue; +@@ -2493,6 +2523,8 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + printf(" (%s)\n", buf); + else + printf(" ()\n"); ++ ++ print_encryption_information(fd, hba->type); + close(fd); + } + free(path); +@@ -2557,6 +2589,8 @@ static int print_nvme_info(struct sys_dev *hba) + else + printf("()\n"); + ++ print_encryption_information(fd, hba->type); ++ + skip: + close_fd(&fd); + } +@@ -2812,7 +2846,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle + hba->path, get_sys_dev_type(hba->type)); + if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) { + host_base = ahci_get_port_count(hba->path, &port_count); +- if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { ++ if (ahci_enumerate_ports(hba, port_count, host_base, verbose)) { + if (verbose > 0) + pr_err("failed to enumerate ports on %s controller at %s.\n", + get_sys_dev_type(hba->type), hba->pci_id); +-- +2.41.0 + diff --git a/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch b/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch deleted file mode 100644 index 5872416..0000000 --- a/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 39b381252c32275079344d30de18b76fda4bba26 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:45 -0600 -Subject: [PATCH 46/83] tests/00readonly: Run udevadm settle before setting ro - -In some recent kernel versions, 00readonly fails with: - - mdadm: failed to set readonly for /dev/md0: Device or resource busy - ERROR: array is not read-only! - -This was traced down to a race condition with udev holding a reference -to the block device at the same time as trying to set it read only. - -To fix this, call udevadm settle before setting the array read only. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00readonly | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/00readonly b/tests/00readonly -index 39202487..afe243b3 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -12,6 +12,7 @@ do - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync - check $level -+ udevadm settle - mdadm -ro $md0 - check readonly - state=$(cat /sys/block/md0/md/array_state) --- -2.38.1 - diff --git a/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch b/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch new file mode 100644 index 0000000..91d3292 --- /dev/null +++ b/SOURCES/0047-imsm-drive-encryption-policy-implementation.patch @@ -0,0 +1,114 @@ +From acb8f13be88c224eb1e01f72c1e1fda955bc80ba Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 22 Mar 2024 12:51:20 +0100 +Subject: [PATCH 47/69] imsm: drive encryption policy implementation + +IMSM cares about drive encryption state. It is not allowed to mix disks +with different encryption state within one md device. This policy will +verify that attempt to use disks with different encryption states will +fail. Verification is performed for devices NVMe/SATA Opal and SATA. + +There is one exception, Opal SATA drives encryption is not checked when +ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this +reason such drives are treated as without encryption support. + +Signed-off-by: Blazej Kucman +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index fbd1c11f..1faab607 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -11291,6 +11291,78 @@ test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t + return MDADM_STATUS_ERROR; + } + ++/** ++ * test_and_add_drive_encryption_policy_imsm() - add disk encryption to policies list. ++ * @type: policy type to search in the list. ++ * @pols: list of currently recorded policies. ++ * @disk_fd: file descriptor of the device to check. ++ * @hba: The hba to which the drive is attached, could be NULL if verification is disabled. ++ * @verbose: verbose flag. ++ * ++ * IMSM cares about drive encryption state. It is not allowed to mix disks with different ++ * encryption state within one md device. ++ * If there is no encryption policy on pols we are free to add first one. ++ * If there is a policy then, new must be the same. ++ */ ++static mdadm_status_t ++test_and_add_drive_encryption_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd, ++ struct sys_dev *hba, const int verbose) ++{ ++ struct dev_policy *expected_policy = pol_find(*pols, (char *)type); ++ struct encryption_information information = {0}; ++ char *encryption_state = "Unknown"; ++ int status = MDADM_STATUS_SUCCESS; ++ bool encryption_checked = true; ++ char devname[PATH_MAX]; ++ ++ if (!hba) ++ goto check_policy; ++ ++ switch (hba->type) { ++ case SYS_DEV_NVME: ++ case SYS_DEV_VMD: ++ status = get_nvme_opal_encryption_information(disk_fd, &information, verbose); ++ break; ++ case SYS_DEV_SATA: ++ case SYS_DEV_SATA_VMD: ++ status = get_ata_encryption_information(disk_fd, &information, verbose); ++ break; ++ default: ++ encryption_checked = false; ++ } ++ ++ if (status) { ++ fd2devname(disk_fd, devname); ++ pr_vrb("Failed to read encryption information of device %s\n", devname); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ if (encryption_checked) { ++ if (information.status == ENC_STATUS_LOCKED) { ++ fd2devname(disk_fd, devname); ++ pr_vrb("Device %s is in Locked state, cannot use. Aborting.\n", devname); ++ return MDADM_STATUS_ERROR; ++ } ++ encryption_state = (char *)get_encryption_status_string(information.status); ++ } ++ ++check_policy: ++ if (expected_policy) { ++ if (strcmp(expected_policy->value, encryption_state) == 0) ++ return MDADM_STATUS_SUCCESS; ++ ++ fd2devname(disk_fd, devname); ++ pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected eariler.\n", ++ encryption_state, devname, expected_policy->value); ++ pr_vrb("Disks with different encryption status cannot be used.\n"); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ pol_add(pols, (char *)type, encryption_state, "imsm"); ++ ++ return MDADM_STATUS_SUCCESS; ++} ++ + struct imsm_drive_policy { + char *type; + mdadm_status_t (*test_and_add_drive_policy)(const char * const type, +@@ -11300,6 +11372,7 @@ struct imsm_drive_policy { + + struct imsm_drive_policy imsm_policies[] = { + {"controller", test_and_add_drive_controller_policy_imsm}, ++ {"encryption", test_and_add_drive_encryption_policy_imsm} + }; + + mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd, +-- +2.41.0 + diff --git a/SOURCES/0047-tests-add-test-for-names.patch b/SOURCES/0047-tests-add-test-for-names.patch deleted file mode 100644 index 03aee00..0000000 --- a/SOURCES/0047-tests-add-test-for-names.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b7671c82010ffc04dfaecff2dd19ef8b2283e2b6 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:21 +0200 -Subject: [PATCH 47/83] tests: add test for names - -Current behavior is not documented and tested. This test is a base for -future improvements. It is enough to test it only with native metadata, -because it is generic code. Generated properties are passed to metadata -handler. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00createnames | 93 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 93 insertions(+) - create mode 100644 tests/00createnames - -diff --git a/tests/00createnames b/tests/00createnames -new file mode 100644 -index 00000000..64b81b92 ---- /dev/null -+++ b/tests/00createnames -@@ -0,0 +1,93 @@ -+set -x -e -+ -+# Test how and --name= are handled for create mode. -+# We need to check three properties, generated from those parameters: -+# - devnode name -+# - link in /dev/md/ (MD_DEVNAME property from --detail --export) -+# - name in metadata (MD_NAME property from --examine --export) -+ -+function _verify() { -+ local DEVNODE_NAME="$1" -+ local WANTED_LINK="$2" -+ local WANTED_NAME="$3" -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -+ exit 1 -+ fi -+ -+ if [[ "$WANTED_LINK" != "empty" ]]; then -+ local EXPECTED="MD_DEVNAME=$WANTED_LINK" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+ fi -+ -+ -+ local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get metadata from $dev0." -+ exit 1 -+ fi -+ -+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+} -+ -+function _create() { -+ local DEVNAME=$1 -+ local NAME=$2 -+ -+ if [[ -z "$NAME" ]]; then -+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -+ else -+ mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force -+ fi -+ -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot create device." -+ exit 1 -+ fi -+} -+ -+# The most trivial case. -+_create "/dev/md/name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+_create "name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# Use 'mdX' as name. -+_create "/dev/md/md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+_create "md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+# is used to create MD_DEVNAME but, name is used to create MD_NAME. -+_create "/dev/md/devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+_create "devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. -+_create "/dev/md0" -+_verify "/dev/md0" "empty" "0" -+mdadm -S "/dev/md0" -+ -+# Devnode points to /dev/ directory and name is set. -+_create "/dev/md0" "name" -+_verify "/dev/md0" "empty" "name" -+mdadm -S "/dev/md0" --- -2.38.1 - diff --git a/SOURCES/0048-mdadm-add-CHANGELOG.md.patch b/SOURCES/0048-mdadm-add-CHANGELOG.md.patch new file mode 100644 index 0000000..1432c1e --- /dev/null +++ b/SOURCES/0048-mdadm-add-CHANGELOG.md.patch @@ -0,0 +1,2010 @@ +From 275e5d2fe316202cce5cb1319a83c3cd8fb22dd3 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:10 +0100 +Subject: [PATCH 48/69] mdadm: add CHANGELOG.md + +Bring changelog back to life. Remove ANNOUCEs. It will use markdown +format, to have one style. All releases are migrated to new +changelog. It was a exercise I have taken, to familiarize with the +mdadm history. + +Signed-off-by: Mariusz Tkaczyk +--- + ANNOUNCE-3.0 | 98 ------------- + ANNOUNCE-3.0.1 | 22 --- + ANNOUNCE-3.0.2 | 21 --- + ANNOUNCE-3.0.3 | 29 ---- + ANNOUNCE-3.1 | 33 ----- + ANNOUNCE-3.1.1 | 39 ------ + ANNOUNCE-3.1.2 | 46 ------- + ANNOUNCE-3.1.3 | 46 ------- + ANNOUNCE-3.1.4 | 37 ----- + ANNOUNCE-3.1.5 | 42 ------ + ANNOUNCE-3.2 | 77 ----------- + ANNOUNCE-3.2.1 | 75 ---------- + ANNOUNCE-3.2.2 | 36 ----- + ANNOUNCE-3.2.3 | 24 ---- + ANNOUNCE-3.2.4 | 144 ------------------- + ANNOUNCE-3.2.5 | 31 ----- + ANNOUNCE-3.2.6 | 57 -------- + ANNOUNCE-3.3 | 63 --------- + ANNOUNCE-3.3.1 | 23 ---- + ANNOUNCE-3.3.2 | 16 --- + ANNOUNCE-3.3.3 | 18 --- + ANNOUNCE-3.3.4 | 37 ----- + ANNOUNCE-3.4 | 24 ---- + ANNOUNCE-4.0 | 22 --- + ANNOUNCE-4.1 | 16 --- + ANNOUNCE-4.2 | 19 --- + CHANGELOG.md | 368 +++++++++++++++++++++++++++++++++++++++++++++++++ + ChangeLog | 306 ---------------------------------------- + 28 files changed, 368 insertions(+), 1401 deletions(-) + delete mode 100644 ANNOUNCE-3.0 + delete mode 100644 ANNOUNCE-3.0.1 + delete mode 100644 ANNOUNCE-3.0.2 + delete mode 100644 ANNOUNCE-3.0.3 + delete mode 100644 ANNOUNCE-3.1 + delete mode 100644 ANNOUNCE-3.1.1 + delete mode 100644 ANNOUNCE-3.1.2 + delete mode 100644 ANNOUNCE-3.1.3 + delete mode 100644 ANNOUNCE-3.1.4 + delete mode 100644 ANNOUNCE-3.1.5 + delete mode 100644 ANNOUNCE-3.2 + delete mode 100644 ANNOUNCE-3.2.1 + delete mode 100644 ANNOUNCE-3.2.2 + delete mode 100644 ANNOUNCE-3.2.3 + delete mode 100644 ANNOUNCE-3.2.4 + delete mode 100644 ANNOUNCE-3.2.5 + delete mode 100644 ANNOUNCE-3.2.6 + delete mode 100644 ANNOUNCE-3.3 + delete mode 100644 ANNOUNCE-3.3.1 + delete mode 100644 ANNOUNCE-3.3.2 + delete mode 100644 ANNOUNCE-3.3.3 + delete mode 100644 ANNOUNCE-3.3.4 + delete mode 100644 ANNOUNCE-3.4 + delete mode 100644 ANNOUNCE-4.0 + delete mode 100644 ANNOUNCE-4.1 + delete mode 100644 ANNOUNCE-4.2 + create mode 100644 CHANGELOG.md + delete mode 100644 ChangeLog + +diff --git a/ANNOUNCE-3.0 b/ANNOUNCE-3.0 +deleted file mode 100644 +index f2d4f847..00000000 +--- a/ANNOUNCE-3.0 ++++ /dev/null +@@ -1,98 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0 - A tool for managing Soft RAID under Linux +- +-I am pleased to (finally) announce the availability of +- mdadm version 3.0 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This is a major new version and as such should be treated with some +-caution. However it has seen substantial testing and is considerred +-to be ready for wide use. +- +- +-The significant change which justifies the new major version number is +-that mdadm can now handle metadata updates entirely in userspace. +-This allows mdadm to support metadata formats that the kernel knows +-nothing about. +- +-Currently two such metadata formats are supported: +- - DDF - The SNIA standard format +- - Intel Matrix - The metadata used by recent Intel ICH controlers. +- +-Also the approach to device names has changed significantly. +- +-If udev is installed on the system, mdadm will not create any devices +-in /dev. Rather it allows udev to manage those devices. For this to work +-as expected, the included udev rules file should be installed. +- +-If udev is not installed, mdadm will still create devices and symlinks +-as required, and will also remove them when the array is stopped. +- +-mdadm now requires all devices which do not have a standard name (mdX +-or md_dX) to live in the directory /dev/md/. Names in this directory +-will always be created as symlinks back to the standard name in /dev. +- +-The man pages contain some information about the new externally managed +-metadata. However see below for a more condensed overview. +- +-Externally managed metadata introduces the concept of a 'container'. +-A container is a collection of (normally) physical devices which have +-a common set of metadata. A container is assembled as an md array, but +-is left 'inactive'. +- +-A container can contain one or more data arrays. These are composed from +-slices (partitions?) of various devices in the container. +- +-For example, a 5 devices DDF set can container a RAID1 using the first +-half of two devices, a RAID0 using the first half of the remain 3 devices, +-and a RAID5 over thte second half of all 5 devices. +- +-A container can be created with +- +- mdadm --create /dev/md0 -e ddf -n5 /dev/sd[abcde] +- +-or "-e imsm" to use the Intel Matrix Storage Manager. +- +-An array can be created within a container either by giving the +-container name and the only member: +- +- mdadm -C /dev/md1 --level raid1 -n 2 /dev/md0 +- +-or by listing the component devices +- +- mdadm -C /dev/md2 --level raid0 -n 3 /dev/sd[cde] +- +-To assemble a container, it is easiest just to pass each device in turn to +-mdadm -I +- +- for i in /dev/sd[abcde] +- do mdadm -I $i +- done +- +-This will assemble the container and the components. +- +-Alternately the container can be assembled explicitly +- +- mdadm -A /dev/md0 /dev/sd[abcde] +- +-Then the components can all be assembled with +- +- mdadm -I /dev/md0 +- +-For each container, mdadm will start a program called "mdmon" which will +-monitor the array and effect any metadata updates needed. The array is +-initially assembled readonly. It is up to "mdmon" to mark the metadata +-as 'dirty' and which the array to 'read-write'. +- +-The version 0.90 and 1.x metadata formats supported by previous +-versions for mdadm are still supported and the kernel still performs +-the same updates it use to. The new 'mdmon' approach is only used for +-newly introduced metadata types. +- +-NeilBrown 2nd June 2009 +diff --git a/ANNOUNCE-3.0.1 b/ANNOUNCE-3.0.1 +deleted file mode 100644 +index 91b44284..00000000 +--- a/ANNOUNCE-3.0.1 ++++ /dev/null +@@ -1,22 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.1 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This contains only minor bug fixes over 3.0. If you are using +-3.0, you could consider upgrading. +- +-The brief change log is: +- - Fix various segfaults +- - Fixed for --examine with containers +- - Lots of other little fixes. +- +-NeilBrown 25th September 2009 +diff --git a/ANNOUNCE-3.0.2 b/ANNOUNCE-3.0.2 +deleted file mode 100644 +index 93643d17..00000000 +--- a/ANNOUNCE-3.0.2 ++++ /dev/null +@@ -1,21 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This just contains one bugfix over 3.0.1 - I was obviously a bit hasty +-in releasing that one. +- +-The brief change log is: +- - Fix crash when hosthost is not set, as often happens in +- early boot. +- +-NeilBrown 25th September 2009 +diff --git a/ANNOUNCE-3.0.3 b/ANNOUNCE-3.0.3 +deleted file mode 100644 +index d6117a1d..00000000 +--- a/ANNOUNCE-3.0.3 ++++ /dev/null +@@ -1,29 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.0.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.0.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-This contains a collection of bug fixes and minor enhancements over +-3.0.1. +- +-The brief change log is: +- - Improvements for creating arrays giving just a name, like 'foo', +- rather than the full '/dev/md/foo'. +- - Improvements for assembling member arrays of containers. +- - Improvements to test suite +- - Add option to change increment for RebuildNN messages reported +- by "mdadm --monitor" +- - Improvements to mdmon 'hand-over' from initrd to final root. +- - Handle merging of devices that have left an IMSM array and are +- being re-incorporated. +- - Add missing space in "--detail --brief" output. +- +-NeilBrown 22nd October 2009 +diff --git a/ANNOUNCE-3.1 b/ANNOUNCE-3.1 +deleted file mode 100644 +index 343b85da..00000000 +--- a/ANNOUNCE-3.1 ++++ /dev/null +@@ -1,33 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1 - A tool for managing Soft RAID under Linux +- +-Hot on the heals of 3.0.3 I am pleased to announce the availability of +- mdadm version 3.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +- +-It contains significant feature enhancements over 3.0.x +- +-The brief change log is: +- - Support --grow to change the layout of RAID4/5/6 +- - Support --grow to change the chunksize of raid 4/5/6 +- - Support --grow to change level from RAID1 -> RAID5 -> RAID6 and +- back. +- - Support --grow to reduce the number of devices in RAID4/5/6. +- - Support restart of these grow options which assembling an array +- which is partially grown. +- - Assorted tests of this code, and of different RAID6 layouts. +- +-Note that a 2.6.31 or later is needed to have access to these. +-Reducing devices in a RAID4/5/6 requires 2.6.32. +-Changing RAID5 to RAID1 requires 2.6.33. +- +-You should only upgrade if you need to use, or which to test, these +-features. +- +-NeilBrown 22nd October 2009 +diff --git a/ANNOUNCE-3.1.1 b/ANNOUNCE-3.1.1 +deleted file mode 100644 +index 9e480dc0..00000000 +--- a/ANNOUNCE-3.1.1 ++++ /dev/null +@@ -1,39 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.1 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix release over 3.1, which was withdrawn due to serious +-bugs. So it might be best to ignore 3.1 and say that this is a significant +-feature release over 3.0.x +- +-Significant changes are: +- - RAID level conversion between RAID1, RAID5, and RAID6 are +- possible were the kernel supports it (2.6.32 at least) +- - online chunksize and layout changing for RAID5 and RAID6 +- where the kernel supports it. +- - reduce the number of devices in a RAID4/5/6 array. +- +- - The default metadata is not v1.1. This metadata is stored at the +- start of the device so is safer in many ways but could interfere with +- boot loaded. The old default (0.90) is still available and fully +- supported. +- +- - The default chunksize is now 512K rather than 64K. This seems more +- appropriate for modern devices. +- +- - The default bitmap chunksize for internal bitmaps is now at least +- 64Meg as fine grained bitmaps tend to impact performance more for +- little extra gain. +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.1. +- +-NeilBrown 19th November 2009 +diff --git a/ANNOUNCE-3.1.2 b/ANNOUNCE-3.1.2 +deleted file mode 100644 +index 321b8bef..00000000 +--- a/ANNOUNCE-3.1.2 ++++ /dev/null +@@ -1,46 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.1. +- +-Significant changes are: +- - The default metadata has change again (sorry about that). +- It is now v1.2 and will hopefully stay that way. It turned +- out there with boot-block issues with v1.1 which make it +- unsuitable for a default, though in many cases it is still +- suitable to use. +- - Stopping a container is not permitted when members are still +- active +- - Add 'homehost' to the valid words for the "AUTO" config file +- line. When followed by "-all", this causes mdadm to +- auto-assemble any array belonging to this host, but not +- auto-assemble anything else. +- - Fix some bugs with "--grow --chunksize=" for changing chunksize. +- - VAR_RUN can be easily changed at compile time just like ALT_RUN. +- This gives distros more flexability in how to manage the +- pid and sock files that mdmon needs. +- - Various mdmon fixes +- - Alway make bitmap 4K-aligned if at all possible. +- - If mdadm.conf lists arrays which have inter-dependencies, +- the previously had to be listed in the "right" order. Now +- any order should work. +- - Fix --force assembly of v1.x arrays which are in the process +- of recovering. +- - Add section on 'scrubbing' to 'md' man page. +- - Various command-line-option parsing improvements. +- - ... and lots of other bug fixes. +- +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.2 +- +-NeilBrown 10th March 2010 +diff --git a/ANNOUNCE-3.1.3 b/ANNOUNCE-3.1.3 +deleted file mode 100644 +index 95b2b6c1..00000000 +--- a/ANNOUNCE-3.1.3 ++++ /dev/null +@@ -1,46 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.2 +- +-Significant changes are: +- - mapfile now lives in a fixed location which default to +- /dev/.mdadm/map but can be changed at compile time. This +- location is choses and most distros provide it during early +- boot and preserve it through. As long a /dev exists and is +- writable, /dev/.mdadm will be created. +- Other files file communication with mdmon live here too. +- This fixes a bug reported by Debian and Gentoo users where +- udev would spin in early-boot. +- - IMSM and DDF metadata will not be recognised on partitions +- as they should only be used on whole-disks. +- - Various overflows causes by 2G drives have been addressed. +- - A subarray of an IMSM contain can now be killed with +- --kill-subarray. Also subarrays can be renamed with +- --update-subarray +- - -If (or --incremental --fail) can be used from udev to +- fail and remove from all arrays a device which has been +- unplugged from the system. i.e. hot-unplug-support. +- - "mdadm /dev/mdX --re-add missing" will look for any device +- that looks like it should be a member of /dev/mdX but isn't +- and will automatically --re-add it +- - Now compile with -Wextra to get extra warnings. +- - Lots of minor bug fixes, documentation improvements, etcc +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.3 +- +-It is expected that the next release will be 3.2 with a number of new +-features. 3.1.4 will only happen if important bugs show up before 3.2 +-is stable. +- +-NeilBrown 6th August 2010 +diff --git a/ANNOUNCE-3.1.4 b/ANNOUNCE-3.1.4 +deleted file mode 100644 +index c157a36a..00000000 +--- a/ANNOUNCE-3.1.4 ++++ /dev/null +@@ -1,37 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.4 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.4 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.3. +-3.1.3 had a couple of embarrasing regressions and a couple of other +-issues surfaces which had easy fixes so I decided to make a 3.1.4 +-release after all. +- +-Two fixes related to configs that aren't using udev: +- - Don't remove md devices which 'standard' names on --stop +- - Allow dev_open to work on read-only /dev +-And fixed regressions: +- - Allow --incremental to add spares to an array +- - Accept --no-degraded as a deprecated option rather than +- throwing an error +- - Return correct success status when --incrmental assembling +- a container which does not yet have enough devices. +- - Don't link mdadm with pthreads, only mdmon needs it. +- - Fix compiler warning due to bad use of snprintf +- - Fix spare migration +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.4 +- +-It is expected that the next release will be 3.2 with a number of new +-features. +- +-NeilBrown 31st August 2010 +diff --git a/ANNOUNCE-3.1.5 b/ANNOUNCE-3.1.5 +deleted file mode 100644 +index baa1f921..00000000 +--- a/ANNOUNCE-3.1.5 ++++ /dev/null +@@ -1,42 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.1.5 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.1.5 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git?p=mdadm +- +-This is a bugfix/stability release over 3.1.4. It contains all the +-important bugfixes found while working on 3.2 and 3.2.1. It will be +-the last 3.1.x release - 3.2.1 is expected to be released in a few days. +- +-Changes include: +- - Fixes for v1.x metadata on big-endian machines. +- - man page improvements +- - Improve '--detail --export' when run on partitions of an md array. +- - Fix regression with removing 'failed' or 'detached' devices. +- - Fixes for "--assemble --force" in various unusual cases. +- - Allow '-Y' to mean --export. This was documented but not implemented. +- - Various fixed for handling 'ddf' metadata. This is now more reliable +- but could benefit from more interoperability testing. +- - Correctly list subarrays of a container in "--detail" output. +- - Improve checks on whether the requested number of devices is supported +- by the metadata - both for --create and --grow. +- - Don't remove partitions from a device that is being included in an +- array until we are fully committed to including it. +- - Allow "--assemble --update=no-bitmap" so an array with a corrupt +- bitmap can still be assembled. +- - Don't allow --add to succeed if it looks like a "--re-add" is probably +- wanted, but cannot succeed. This avoids inadvertently turning +- devices into spares when an array is failed. +- +-This release is believed to be stable and you should feel free to +-upgrade to 3.1.5 +- +- +-NeilBrown 23rd March 2011 +- +diff --git a/ANNOUNCE-3.2 b/ANNOUNCE-3.2 +deleted file mode 100644 +index 9e282bc6..00000000 +--- a/ANNOUNCE-3.2 ++++ /dev/null +@@ -1,77 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2 - A tool for managing Soft RAID under Linux (DEVEL ONLY) +- +-I am pleased to announce the availability of +- mdadm version 3.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm devel-3.2 +- http://neil.brown.name/git?p=mdadm +- +-This is a "Developers only" release. Please don't consider using it +-or making it available to others without reading the following. +- +- +-By far the most significant change in this release related to the +-management of reshaping arrays. This code has been substantially +-re-written so that it can work with 'externally managed metadata' - +-Intel's IMSM in particular. We now support level migration and +-OnLine Capacity Expansion on these arrays. +- +-However, while the code largely works it has not been tested +-exhaustively so there are likely to be problems. As the reshape code +-for native metadata arrays was changed as part of this rewrite these +-problems could also result in regressions for reshape of native +-metadata. +- +-It is partly to encourage greater testing that this release is being +-made. Any reports of problem - particular reproducible recipes for +-triggering the problems - will be gratefully received. +- +-It is hopped that a "3.2.1" release will be available in early March +-which will be a bugfix release over this and can be considered +-suitable for general use. +- +-Other changes of note: +- +- - Policy framework. +- Various policy statements can be made in the mdadm.conf to guide +- the behaviour of mdadm, particular with regards to how new devices +- are treated by "mdadm -I". +- Depending on the 'action' associated with a device (identified by +- its 'path') such need devices can be automatically re-added to and +- existing array that they previously fell out off, or automatically +- added as a spare if they appear to contain no data. +- +- - mdadm now has a limited understanding of partition tables. This +- allows the policy framework to make decisions about partitioned +- devices as well. +- +- - --incremental --remove can be told what --path the device was on, +- and this info will be recorded so that another device appearing at +- the same physical location can be preferentially added to the same +- array (provides the spare-same-slot action policy applied to the +- path). +- +- - A new flags "--invalid-backup" flag is available in --assemble +- mode. This can be used to re-assemble an array which was stopping +- in the middle of a reshape, and for which the 'backup file' is no +- longer available or is corrupted. The array may have some +- corruption in it at the point where reshape was up to, but at least +- the rest of the array will become available. +- +- +- - Various internal restructuring - more is needed. +- +- +-Any feed back and bug reports are always welcomed at: +- linux-raid@vger.kernel.org +- +-And please: don't use this in production - particularly not the +---grow functionality. +- +-NeilBrown 1st February 2011 +- +- +diff --git a/ANNOUNCE-3.2.1 b/ANNOUNCE-3.2.1 +deleted file mode 100644 +index 0e7826ca..00000000 +--- a/ANNOUNCE-3.2.1 ++++ /dev/null +@@ -1,75 +0,0 @@ +- +- +-I am pleased to announce the availability of +- mdadm version 3.2.1 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-Many of the changes in this release are of internal interest only, +-restructuring and refactoring code and so forth. +- +-Most of the bugs found and fixed during development for 3.2.1 have been +-back-ported for the recently-release 3.1.5 so this release primarily +-provides a few new features over 3.1.5. +- +-They include: +- - policy framework +- Policy can be expressed for moving spare devices between arrays, and +- for how to handle hot-plugged devices. This policy can be different +- for devices plugged in to different controllers etc. +- This, for example, allows a configuration where when a device is plugged +- in it is immediately included in an md array as a hot spare and +- possibly starts recovery immediately if an array is degraded. +- +- - some understanding of mbr and gpt paritition tables +- This is primarly to support the new hot-plug support. If a +- device is plugged in and policy suggests it should have a partition table, +- the partition table will be copied from a suitably similar device, and +- then the partitions will hot-plug and can then be added to md arrays. +- +- - "--incremental --remove" can remember where a device was removed from +- so if a device gets plugged back in the same place, special policy applies +- to it, allowing it to be included in an array even if a general hotplug +- will not be included. +- +- - enhanced reshape options, including growing a RAID0 by converting to RAID4, +- restriping, and converting back. Also convertions between RAID0 and +- RAID10 and between RAID1 and RAID10 are possible (with a suitably recent +- kernel). +- +- - spare migration for IMSM arrays. +- Spare migration can now work across 'containers' using non-native metadata +- and specifically Intel's IMSM arrays support spare migrations. +- +- - OLCE and level migration for Intel IMSM arrays. +- OnLine Capacity Expansion and level migration (e.g. RAID0 -> RAID5) is +- supported for Intel Matrix Storage Manager arrays. +- This support is currently 'experimental' for technical reasons. It can +- be enabled with "export MDADM_EXPERIMENTAL=1" +- +- - avoid including wayward devices +- If you split a RAID1, mount the two halves as two separate degraded RAID1s, +- and then later bring the two back together, it is possible that the md +- metadata won't properly show that one must over-ride the other. +- mdadm now does extra checking to detect this possibilty and avoid +- potentially corrupting data. +- +- - remove any possible confusion between similar options. +- e.g. --brief and --bitmap were mapped to 'b' and mdadm wouldn't +- notice if one was used where the other was expected. +- +- - allow K,M,G suffixes on chunk sizes +- +- +-While mdadm-3.2.1 is considered to be reasonably stable, you should +-only use it if you want to try out the new features, or if you +-generally like to be on the bleeding edge. If the new features are not +-important to you, then 3.1.5 is probably the appropriate version to be using +-until 3.2.2 comes out. +- +-NeilBrown 28th March 2011 +diff --git a/ANNOUNCE-3.2.2 b/ANNOUNCE-3.2.2 +deleted file mode 100644 +index b70d18b9..00000000 +--- a/ANNOUNCE-3.2.2 ++++ /dev/null +@@ -1,36 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.2 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.2 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a stablising release for the 3.2 series. +-Many of the changes just fix bugs introduces in 3.2 or 3.2.1. +- +-There are some new features. They are: +- - reshaping IMSM (Intel metadata) arrays is no longer 'experimental', +- it should work properly and be largely compatible with IMSM drivers in +- other platforms. +- - --assume-clean can be used with --grow --size to avoid resyncing the +- new part of the array. This is only support with very new kernels. +- - RAID0 arrays can have chunksize which is not a power of 2. This has been +- supported in the kernel for a while but is only now supprted by +- mdadm. +- +- - A new tool 'raid6check' is available which can check a RAID6 array, +- or part of it, and report which device is most inconsistent with the +- others if any stripe is inconsistent. This is still under development +- and does not have a man page yet. If anyone tries it out and has any +- questions or experience to report, they would be most welcome on +- linux-raid@vger.kernel.org. +- +-Future releases in the 3.2 series will only be made if bugfixes are needed. +-The next release to add features is expected to be 3.3. +- +-NeilBrown 17th June 2011 +diff --git a/ANNOUNCE-3.2.3 b/ANNOUNCE-3.2.3 +deleted file mode 100644 +index 8a8dba46..00000000 +--- a/ANNOUNCE-3.2.3 ++++ /dev/null +@@ -1,24 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.3 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.3 +- +-It is available at the usual places: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a bugfix release for the 3.2 series with many +-minor fixes with little or no impact. +- +-The largest single area of change is support for reshape of Intel +-IMSM arrays (OnLine Capacity Explansion and Level Migtration). +-Among other fixes, this now has a better chance of surviving if a +-device fails during reshape. +- +-Upgrading is recommended - particularly if you use mdadm for IMSM +-arrays - but not essential. +- +-NeilBrown 23rd December 2011 +diff --git a/ANNOUNCE-3.2.4 b/ANNOUNCE-3.2.4 +deleted file mode 100644 +index e3216786..00000000 +--- a/ANNOUNCE-3.2.4 ++++ /dev/null +@@ -1,144 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.4 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.4 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release is largely a bugfix release for the 3.2 series with many +-minor fixes with little or no impact. +- +-"--oneline" log of changes is below. Some notable ones are: +- +- - --offroot argument to improve interactions between mdmon and initrd +- - --prefer argument to select which /dev names to display in some +- circumstances. +- - relax restructions on when "--add" will be allowed +- - Fix bug with adding write-intent-bitmap to active array +- - Now defaults to "/run/mdadm" for storing run-time files. +- +-Upgrading is encouraged. +- +-The next mdadm release is expected to be 3.3 with a number of new +-features. +- +-NeilBrown 9th May 2012 +- +-77b3ac8 monitor: make return from read_and_act more symbolic. +-68226a8 monitor: ensure we retry soon when 'remove' fails. +-8453f8d fix: Monitor sometimes crashes +-90fa1a2 Work around gcc-4.7's strict aliasing checks +-0c4304c fix: container creation with --incremental used. +-5d1c7cd FIX: External metadata sometimes is not updated +-3c20f98 FIX: mdmon check in reshape_container() can cause a problem +-59ab9f5 FIX: Typo error in fprint command +-9587c37 imsm: load_super_imsm_all function refactoring +-ec50f7b imsm: load_imsm_super_all supports loading metadata from the device list +-ca9de18 imsm: validate the number of imsm volumes per controller +-30602f5 imsm: display fd in error trace when when store_imsm_mpb failes +-eb155f6 mdmon: Use getopt_long() to parse command line options +-08ca2ad Add --offroot argument to mdadm +-da82751 Add --offroot argument to mdmon +-a0963a8 Spawn mdmon with --offroot if mdadm was launched with --offroot +-f878b24 imsm: fix, the second array need to have the whole available space on devices +-d597705 getinfo_super1: Use MaxSector in place of sb->size +-6ef8905 super1: make aread/awrite always use an aligned buffer. +-de5a472 Remove avail_disks arg from 'enough'. +-da8fe5a Assemble: fix --force assemble during reshape. +-b10c663 config: fix handing of 'homehost' in AUTO line. +-92d49ec FIX: NULL pointer to strdup() can be passed +-d2bde6d imsm: FIX: No new missing disks are allowed during general migration +-111e9fd FIX: Array is not run when expansion disks are added +-bf5cf7c imsm: FIX: imsm_get_allowed_degradation() doesn't count degradation for raid1 +-50927b1 Fix: Sometimes mdmon throws core dump during reshape +-78340e2 Flush mdmon before next reshape step during container operation +-e174219 imsm: FIX: Chunk size migration problem +-f93346e FIX: use md position to reshape restart +-6a75c8c imsm: FIX: use md position to reshape restart +-51d83f5 imsm: FIX: Clear migration record when migration switches to next volume. +-e1dd332 FIX: restart reshape when reshape process is stopped just between 2 reshapes +-1ca90aa FIX: Do not try to (continue) reshape using inactive array +-9f1b0f0 config: conf_match should ignore devname when not set. +-d669228 Use posix_memalign() for memory used to write bitmaps +-178950e FIX: Changes in '0' case for reshape position verification +-9200d41 avoid double-free upon "old buggy kernel" sysfs_read failure +-4011421 Print error message if failing to write super for 1.x metadata +-0011874 Use MDMON_DIR for pid files created in Monitor.c +-56d1885 Assemble: don't use O_EXCL until we have checked device content. +-b720636 Assemble: support assembling of a RAID0 being reshaped. +-c69ffac Manage: allow --re-add to failed array. +-52f07f5 Reset bad flag on map update +-911cead super1: support superblocks up to 4K. +-ad6db3c Create: reduce the verbosity of 'default_layout'. +-b2bfdfa super1.c don't keep recalculating bitmap pointer +-4122675 Define and use SUPER1_SIZE for allocations +-1afa930 init_super1() memset full buffer allocated for superblock +-2de0b8a match_metadata_desc1(): Use calloc instead of malloc+memset +-3c0bcd4 Use 4K buffer alignment for superblock allocations +-308340a Use struct align_fd to cache fd's block size for aligned reads/writes +-65ed615 match_metadata_desc0(): Use calloc instead of malloc+memset +-de89706 Generalize ROUND_UP() macro and introduce matching ROUND_UP_PTR() +-0a2f189 super1.c: use ROUND_UP/ROUND_UP_PTR +-654a381 super-intel.c: Use ROUND_UP() instead of manually coding it +-42d5dfd __write_init_super_ddf(): Use posix_memalign() instead of static aligned buffer +-d4633e0 Examine: fix array size calculation for RAID10. +-e62b778 Assemble: improve verbose logging when including old devices. +-0073a6e Remove possible crash during RAID6 -> RAID5 reshape. +-69fe207 Incremental: fix adding devices with --incremental +-bcbb311 Manage: replace 'return 1' with 'goto abort'. +-9f58469 Manage: freeze recovery while adding multiple devices. +-ae6c05a Create: round off size for RAID1 arrays. +-5ca3a90 Grow: print useful error when converting RAID1->RAID5 will fail. +-c07d640 Fix tests/05r1-re-add-nosupper +-2d762ad Fix the new ROUND_UP macro. +-fd324b0 sysfs: fixed sysfs_freeze_array array to work properly with Manage_subdevs. +-5551b11 imsm: avoid overflows for disks over 1TB +-97f81ee clear hi bits if not used after loading metadata from disk +-e03640b simplify calculating array_blocks +-29cd082 show 2TB volumes/disks support in --detail-platform +-2cc699a check volume size in validate_geometry_imsm_orom +-9126b9a check that no disk over 2TB is used to create container when no support +-027c374 imsm: set 2tb disk attribute for spare +-3556c2f Fix typo: wan -> want +-15632a9 parse_size: distinguish between 0 and error. +-fbdef49 Bitmap_offset is a signed number +-508a7f1 super1: leave more space in front of data by default. +-40110b9 Fix two typos in fprintf messages +-342460c mdadm man page: fix typo +-0e7f69a imsm: display maximum volumes per controller and array +-36fd8cc imsm: FIX: Update function imsm_num_data_members() for Raid1/10 +-7abc987 imsm: FIX: Add volume size expand support to imsm_analyze_change() +-f3871fd imsm: Add new metadata update for volume size expansion +-54397ed imsm: Execute size change for external metatdata +-016e00f FIX: Support metadata changes rollback +-fbf3d20 imsm: FIX: Support metadata changes rollback +-44f6f18 FIX: Extend size of raid0 array +-7e7e9a4 FIX: Respect metadata size limitations +-65a9798 FIX: Detect error and rollback metadata +-13bcac9 imsm: Add function imsm_get_free_size() +-b130333 imsm: Support setting max size for size change operation +-c41e00b imsm: FIX: Component size alignment check +-58d26a2 FIX: Size change is possible as standalone change only +-4aecb54 FIX: Assembled second array is in read only state during reshape +-ae2416e FIX: resolve make everything compilation error +-480f356 Raid limit of 1024 when scanning for devices. +-c2ecf5f Add --prefer option for --detail and --monitor +-0a99975 Relax restrictions on when --add is permitted. +-7ce0570 imsm: fix: rebuild does not continue after reboot +-b51702b fix: correct extending size of raid0 array +-34a1395 Fix sign extension of bitmap_offset in super1.c +-012a864 Introduce sysfs_set_num_signed() and use it to set bitmap/offset +-5d7b407 imsm: fix: thunderdome may drop 2tb attribute +-5ffdc2d Update test for "is udev active". +-96fd06e Adjust to new standard of /run +-974e039 test: don't worry too much about array size. +-b0a658f Grow: failing the set the per-device size is not an error. +-36614e9 super-intel.c: Don't try to close negative fd +-562aa10 super-intel.c: Fix resource leak from opendir() +- +diff --git a/ANNOUNCE-3.2.5 b/ANNOUNCE-3.2.5 +deleted file mode 100644 +index 396da12a..00000000 +--- a/ANNOUNCE-3.2.5 ++++ /dev/null +@@ -1,31 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.5 - A tool for managing Soft RAID under Linux +- +-I am somewhat disappointed to have to announce the availability of +- mdadm version 3.2.5 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This release primarily fixes a serious regression in 3.2.4. +-This regression does *not* cause any risk to data. It simply +-means that adding a device with "--add" would sometime fail +-when it should not. +- +-The fix also includes a couple of minor fixes such as making +-the "--layout=preserve" option to "--grow" work again. +- +-A reminder that the default location for runtime files is now +-"/run/mdadm". If you compile this for a distro that does not +-have "/run", you will need to compile with an alternate setting for +-MAP_DIR. e.g. +- make MAP_DIR=/var/run/mdadm +-or +- make MAP_DIR=/dev/.mdadm +- +-NeilBrown 18th May 2012 +- +diff --git a/ANNOUNCE-3.2.6 b/ANNOUNCE-3.2.6 +deleted file mode 100644 +index f5cfd492..00000000 +--- a/ANNOUNCE-3.2.6 ++++ /dev/null +@@ -1,57 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.2.6 - A tool for managing Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.2.6 +- +-It is available at the usual places, now including github: +- countrycode=xx. +- http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://neil.brown.name/git/mdadm +- +-This is a stablity release which adds a number of bugfixs to 3.2.5. +-There are no real stand-out fixes, just lots of little bits and pieces. +- +-Below is the "git log --oneline --reverse" list of changes since +-3.2.5. +- +-NeilBrown 25th October 2012 +- +-b7e05d2 udev-rules: prevent systemd from mount devices before they are ready. +-0d478e2 mdadm: Fix Segmentation fault. +-42f0ca1 imsm: fix: correct checking volume's degradation +-fcf2195 Monitor: fix inconsistencies in values for ->percent +-5f862fb Monitor: Report NewArray when an array the disappeared, reappears. +-6f51b1c Monitor: fix reporting for Fail vs FailSpare etc. +-68ad53b mdmon: fix arg parsing. +-517f135 Assemble: don't leak memory with fdlist. +-090900c udev-rules: prevent systemd from mount devices before they are ready. +-446e000 sha1.h: remove ansidecl.h header inclusion +-ec894f5 Manage: zero metadata before adding to 'external' array. +-3a84db5 ddf: allow a non-spare to be used to recovery a missing device. +-c5d61ca ddf: hack to fix container recognition. +-23084aa mdmon: fix arg processing for -a +-c4e96a3 mdmon: allow --takeover when original was started with --offroot +-80841df find_free_devnum: avoid auto-using names in /etc/mdadm.conf +-c5c56d6 mapfile: fix mapfile rebuild for containers +-aec89f6 fix segfaults in Detail() +-2117ad1 Fix 'enough' function for RAID10. +-0bc300d Use --offroot flag when assembling md arrays via --incrmental +-ac78f24 Grow: make warning about old metadata more explicit. +-14026ab Replace sha1.h with slightly older version. +-6f6809f Add zlib license to crc32.c +-5267ba0 Handles spaces in array names better. +-c51f288 imsm: allow --assume-clean to work. +-acf7076 Grow: allow --grow --continue to work for native metadata. +-335d2a6 Grow: fix a couple of typos with --assume-clean usage +-9ff1427 Fix open_container +-3713633 mdadm: super0: do not override uuid with homehost +-31bff58 Trivial bugfix and spelling fixes. +-e1e539f Detail: don't report a faulty device as 'spare' or 'rebuilding'. +-22a6461 super0: allow creation of array on 2TB+ devices. +-a5d47a2 Create new md devices consistently +-eb48676 Monitor: don't complain about non-monitorable arrays in mdadm.conf +-ecdf2d7 Query: don't be confused by partition tables. +-f7b75c1 Query: allow member of non-0.90 arrays to be better reported. +diff --git a/ANNOUNCE-3.3 b/ANNOUNCE-3.3 +deleted file mode 100644 +index f770aa13..00000000 +--- a/ANNOUNCE-3.3 ++++ /dev/null +@@ -1,63 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3 - A tools for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm +- +-This is a major new release so don't be too surprised if there are a +-few issues. If I hear about them they will be fixed in 3.3.1. +-git log reports nearly 500 changes since 3.2.6 so I won't list them +-all. +- +-Some highlights are: +- +-- Some array reshapes can proceed without needing backup file. +- This is done by changing the 'data_offset' so we never need to write +- any data back over where it was before. If there is no "head space" +- or "tail space" to allow data_offset to change, the old mechanism +- with a backup file can still be used. +-- RAID10 arrays can be reshaped to change the number of devices, +- change the chunk size, or change the layout between 'near' +- and 'offset'. +- This will always change data_offset, and will fail if there is no +- room for data_offset to be moved. +-- "--assemble --update=metadata" can convert a 0.90 array to a 1.0 array. +-- bad-block-logs are supported (but not heavily tested yet) +-- "--assemble --update=revert-reshape" can be used to undo a reshape +- that has just been started but isn't really wanted. This is very +- new and while it passes basic tests it cannot be guaranteed. +-- improved locking between --incremental and --assemble +-- uses systemd to run "mdmon" if systemd is configured to do that. +-- kernel names of md devices can be non-numeric. e.g. "md_home" rather than +- "md0". This will probably confuse lots of other tools, so you need to +- echo CREATE names=yes >> /etc/mdadm.conf +- or the feature will not be used. (you also need a reasonably new kernel). +-- "--stop" can be given a kernel name instead of a device name. i.e +- mdadm --stop md4 +- will work even if /dev/md4 doesn't exist. +-- "--detail --export" has some information about the devices in the array +-- --dump and --restore can be used to backup and restore the metadata on an +- array. +-- Hot-replace is supported with +- mdadm /dev/mdX --replace /dev/foo +- and +- mdadm /dev/mdX --replace /dev/foo --with /dev/bar +-- Config file can be a directory in which case all "*.conf" files are +- read in lexical order. +- Default is to read /etc/mdadm.conf and then /etc/mdadm.conf.d +- Thus +- echo CREATE name=yes > /etc/mdadm.conf.d/names.conf +- will also enable the use of named md devices. +- +-- Lots of improvements to DDF support including adding support for +- RAID10 (thanks Martin Wilck). +- +-and lots of bugfixes and other little changes. +- +-NeilBrown 3rd September 2013 +diff --git a/ANNOUNCE-3.3.1 b/ANNOUNCE-3.3.1 +deleted file mode 100644 +index 7d5e666e..00000000 +--- a/ANNOUNCE-3.3.1 ++++ /dev/null +@@ -1,23 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.1 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.1 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-The main changes are: +- - lots of work on "DDF" support. Hopefully it will be more stable +- now. Bug reports are always welcome. +- - improved interactions with 'systemd'. Where possible, background +- tasks are run from systemd (if it is present) rather then forking +- disassociationg from the session. This is important because udev +- doesn't really let you disassociate. +- +-though there are a number of other little bug fixes too. +- +-NeilBrown 5th June 2014 +diff --git a/ANNOUNCE-3.3.2 b/ANNOUNCE-3.3.2 +deleted file mode 100644 +index 6b549611..00000000 +--- a/ANNOUNCE-3.3.2 ++++ /dev/null +@@ -1,16 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.2 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.2 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-Changes since 3.3.1 are mostly little bugfixes and some man-page +-updates. +- +-NeilBrown 21st August 2014 +diff --git a/ANNOUNCE-3.3.3 b/ANNOUNCE-3.3.3 +deleted file mode 100644 +index ac1b2173..00000000 +--- a/ANNOUNCE-3.3.3 ++++ /dev/null +@@ -1,18 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.3 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.3.3 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-The 100 changes since 3.3.3 are mostly little bugfixes and some improvements +-to the selftests. +-raid6check now handle all RAID6 layouts including DDF correctly. +-See git log for the rest. +- +-NeilBrown 24th July 2015 +diff --git a/ANNOUNCE-3.3.4 b/ANNOUNCE-3.3.4 +deleted file mode 100644 +index 52b94562..00000000 +--- a/ANNOUNCE-3.3.4 ++++ /dev/null +@@ -1,37 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.3.4 - A tool for managing md Soft RAID under Linux +- +-I am somewhat disappointed to have to announce the availability of +- mdadm version 3.3.4 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm.git +- +-In mdadm-3.3 a change was made to how IMSM (Intel Matrix Storage +-Manager) metadata was handled. Previously an IMSM array would only +-be assembled if it was attached to an IMSM controller. +- +-In 3.3 this was relaxed as there are circumstances where the +-controller is not properly detected. Unfortunately this has negative +-consequences which have only just come to light. +- +-If you have an IMSM RAID1 configured and then disable RAID in the +-BIOS, the metadata will remain on the devices. If you then install +-some other OS on one device and then install Linux on the other, Linux +-might eventually start noticing the IMSM metadata (depending a bit on whether +-mdadm is included in the initramfs) and might start up the RAID1. This could +-copy one device over the other, thus trashing one of the installations. +- +-Not good. +- +-So with this release IMSM arrays will only be assembled if attached to +-an IMSM controller, or if "--force" is given to --assemble, or if the +-environment variable IMSM_NO_PLATFORM is set (used primarily for +-testing). +- +-I strongly recommend upgrading to 3.3.4 if you are using 3.3 or later. +- +-NeilBrown 3rd August 2015. +diff --git a/ANNOUNCE-3.4 b/ANNOUNCE-3.4 +deleted file mode 100644 +index 2689732d..00000000 +--- a/ANNOUNCE-3.4 ++++ /dev/null +@@ -1,24 +0,0 @@ +-Subject: ANNOUNCE: mdadm 3.4 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 3.4 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://github.com/neilbrown/mdadm +- git://neil.brown.name/mdadm +- http://git.neil.brown.name/git/mdadm +- +-The new second-level version number reflects significant new +-functionality, particular support for journalled RAID5/6 and clustered +-RAID1. This new support is probably still buggy. Please report bugs. +- +-There are also a number of fixes for Intel's IMSM metadata support, +-and an assortment of minor bug fixes. +- +-I plan for this to be the last release of mdadm that I provide as I am +-retiring from MD and mdadm maintenance. Jes Sorensen has volunteered +-to oversee mdadm for the next while. Thanks Jes! +- +-NeilBrown 28th January 2016 +diff --git a/ANNOUNCE-4.0 b/ANNOUNCE-4.0 +deleted file mode 100644 +index f79c5408..00000000 +--- a/ANNOUNCE-4.0 ++++ /dev/null +@@ -1,22 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.0 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 4.0 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The update in major version number primarily indicates this is a +-release by it's new maintainer. In addition it contains a large number +-of fixes in particular for IMSM RAID and clustered RAID support. In +-addition this release includes support for IMSM 4k sector drives, +-failfast and better documentation for journaled RAID. +- +-This is my first release of mdadm. Please thank Neil Brown for his +-previous work as maintainer and blame me for all the bugs I caused +-since taking over. +- +-Jes Sorensen, 2017-01-09 +diff --git a/ANNOUNCE-4.1 b/ANNOUNCE-4.1 +deleted file mode 100644 +index a273b9a0..00000000 +--- a/ANNOUNCE-4.1 ++++ /dev/null +@@ -1,16 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.1 - A tool for managing md Soft RAID under Linux +- +-I am pleased to announce the availability of +- mdadm version 4.1 +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The update constitutes more than one year of enhancements and bug fixes +-including for IMSM RAID, Partial Parity Log, clustered RAID support, +-improved testing, and gcc-8 support. +- +-Jes Sorensen, 2018-10-01 +diff --git a/ANNOUNCE-4.2 b/ANNOUNCE-4.2 +deleted file mode 100644 +index 8b22d09f..00000000 +--- a/ANNOUNCE-4.2 ++++ /dev/null +@@ -1,19 +0,0 @@ +-Subject: ANNOUNCE: mdadm 4.2 - A tool for managing md Soft RAID under Linux +- +-I am pleased to finally announce the availability of mdadm-4.2. +-get 4.2 out the door soon. +- +-It is available at the usual places: +- http://www.kernel.org/pub/linux/utils/raid/mdadm/ +-and via git at +- git://git.kernel.org/pub/scm/utils/mdadm/mdadm.git +- http://git.kernel.org/cgit/utils/mdadm/ +- +-The release includes more than two years of development and bugfixes, +-so it is difficult to remember everything. Highlights include +-enhancements and bug fixes including for IMSM RAID, Partial Parity +-Log, clustered RAID support, improved testing, and gcc-9 support. +- +-Thank you everyone who contributed to this release! +- +-Jes Sorensen, 2021-12-30 +diff --git a/CHANGELOG.md b/CHANGELOG.md +new file mode 100644 +index 00000000..c1997ba7 +--- /dev/null ++++ b/CHANGELOG.md +@@ -0,0 +1,368 @@ ++# Release [mdadm-4.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.3) ++ ++Features: ++- **IMSM_NO_PLATFORM** boot parameter support from Neil Brown. ++- **--write-zeros** option support by Logan Gunthorpe. ++- **IMSM** monetization by VMD register from Mateusz Grzonka. ++- RST SATA under VMD support from Kevin Friedberg. ++- Strong name rules from Mariusz Tkaczyk. ++ ++Fixes: ++- Unify failed raid behavior from Coly Li. ++- Rework of **--update** options from Mateusz Kusiak. ++- **mdmon-initrd** service from Neil Brown. ++- **IMSM** expand functionality rework from Mariusz Tkaczyk. ++- Mdmonitor improvements from Mateusz Grzonka. ++- Failed state verification from Mateusz Kusiak and Kinga Tanska. ++ ++# Release [mdadm-4.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.2) ++ ++The release includes more than two years of development and bugfixes, so it is difficult to ++remember everything. Highlights include enhancements and bug fixes including for **IMSM** RAID, ++Partial Parity Log, clustered RAID support, improved testing, and gcc-9 support. ++ ++# Release [mdadm-4.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.1) ++ ++The update constitutes more than one year of enhancements and bug fixes including for **IMSM** ++RAID, Partial Parity Log, clustered RAID support, improved testing, and gcc-8 support. ++ ++# Release [mdadm-4.0](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-4.0) ++ ++The update in major version number primarily indicates this is a release by it's new maintainer. ++In addition it contains a large number of fixes in particular for IMSM RAID and clustered RAID ++support. In addition, this release includes support for IMSM 4k sector drives, failfast and better ++documentation for journaled RAID. ++ ++This is my first release of mdadm. Please thank Neil Brown for his previous work as maintainer and ++blame me for all the bugs I caused since taking over. ++ ++# Release [mdadm-3.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.4) ++ ++- Support for journalled RAID5/6 and clustered RAID1. This new support is probably still buggy. ++ Please report bugs. ++ ++- There are also a number of fixes for **IMSM** support and an assortment of minor bug fixes. ++ ++- I plan for this to be the last release of mdadm that I provide as I am retiring from MD and mdadm ++ maintenance. Jes Sorensen has volunteered to oversee mdadm for the next while. Thanks Jes! ++ ++# Release [mdadm-3.3.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.4) ++ ++**I strongly recommend upgrading to 3.3.4 if you are using 3.3 or later with IMSM.** ++ ++- **IMSM** metadata assemble fixes. ++ ++ In mdadm-3.3 a change was made to how **IMSM** metadata was handled. Previously an **IMSM** array ++ would only be assembled if it was attached to an **IMSM** controller. In 3.3 this was relaxed as ++ there are circumstances where the controller is not properly detected. Unfortunately, this has ++ negative consequences which have only just come to light. ++ ++ If you have an IMSM RAID1 configured and then disable RAID in the BIOS, the metadata will remain ++ on the devices. If you then install some other OS on one device and then install Linux on the ++ other, Linux might eventually start noticing the IMSM metadata (depending a bit on whether ++ mdadm is included in the initramfs) and might start up the RAID1. This could copy one device over ++ the other, thus trashing one of the installations. ++ ++ So, with this release IMSM arrays will only be assembled if attached to an **IMSM** controller, ++ or if **--force** is given to **--assemble**, or if the environment variable ++ **IMSM_NO_PLATFORM=1** is set (used primarily for testing). ++ ++# Release [mdadm-3.3.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.3) ++ ++- The 100 changes since 3.3.3 are mostly little bugfixes and some improvements to the self-tests. ++- raid6check now handle all RAID6 layouts including **DDF** correctly. See git log for the rest. ++ ++# Release [mdadm-3.3.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.2) ++ ++- Little bugfixes and some man-page updates. ++ ++# Release [mdadm-3.3.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3.1) ++ ++- lots of work on **DDF** support. ++- Improved interactions with **systemd**. Where possible, background tasks are run from systemd ++ rather than forking. ++- Number of other little bug fixes too. ++ ++# Release [mdadm-3.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.3) ++ ++- Some array reshapes can proceed without needing backup file. This is done by changing the ++ data_offset* so we never need to write any data back over where it was before. If there is no ++ 'head space' or 'tail space' to allow *data_offset* to change, the old mechanism with a backup ++ file can still be used. ++ ++- RAID10 arrays can be reshaped to change the number of devices, change the chunk size, or change ++ the layout between *near* and *offset*. ++ This will always change *data_offset*, and will fail if there is no room for *data_offset* to be ++ moved. ++ ++- **--assemble --update=metadata** can convert a **0.90** array to a **1.0** array. ++ ++- **bad-block-logs** are supported (but not heavily tested yet). ++ ++- **--assemble --update=revert-reshape** can be used to undo a reshape that has just been started ++ but isn't really wanted. This is very new and while it passes basic tests it cannot be ++ guaranteed. ++ ++- improved locking between **--incremental** and **--assemble**. ++ ++- uses systemd to run **mdmon** if systemd is configured to do that. ++- kernel names of md devices can be non-numeric. e.g. "md_home" rather than ++ "md0". This will probably confuse lots of other tools, so you need to ++ **echo CREATE names=yes >> /etc/mdadm.conf** or the feature will not be used (you also need a ++ reasonably new kernel). ++ ++- **--stop** can be given a kernel name instead of a device name. i.e. **mdadm --stop md4** will ++ work even if /dev/md4 doesn't exist. ++ ++- **--detail --export** has some information about the devices in the array. ++- **--dump** and **--restore** can be used to backup and restore the metadata on an array. ++- Hot-replace is supported with **mdadm /dev/mdX --replace /dev/foo** and ++ **mdadm /dev/mdX --replace /dev/foo --with /dev/bar**. ++ ++- Config file can be a directory in which case all "*.conf" files are read in lexical order. ++ Default is to read **/etc/mdadm.conf** and then **/etc/mdadm.conf.d**. Thus ++ **echo CREATE name=yes > /etc/mdadm.conf.d/names.conf** will also enable the use of named md ++ devices. ++ ++- Lots of improvements to **DDF** support including adding support for RAID10 (thanks Martin Wilck). ++ ++# Release [mdadm-3.2.6](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.6) ++ ++- There are no real stand-out fixes, just lots of little bits and pieces. ++ ++# Release [mdadm-3.2.5](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.5) ++ ++- This release primarily fixes a serious regression in 3.2.4. This regression does *not* cause ++ any risk to data. It simply means that adding a device with **--add** would sometime fail ++ when it should not. ++- The fix also includes a couple of minor fixes such as making the **--layout=preserve** option to ++ **--grow** work again. ++ ++# Release [mdadm-3.2.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.4) ++ ++ - **--offroot** argument to improve interactions between mdmon and initrd. ++ - **--prefer** argument to select which */dev* names to display in some circumstances. ++ - relax restrictions on when **--add** will be allowed. ++ - Fix bug with adding write-intent-bitmap to active array. ++ - Now defaults to */run/mdadm* for storing run-time files. ++ ++# Release [mdadm-3.2.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.3) ++ ++- The largest single area of change is support for reshape of Intel IMSM arrays (OnLine Capacity ++ Expansion and Level Migration). ++- Among other fixes, this now has a better chance of surviving if a device fails during reshape. ++ ++# Release [mdadm-3.2.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.2) ++ ++- reshaping IMSM (Intel metadata) arrays is no longer 'experimental', it should work properly and be ++ largely compatible with IMSM drivers in other platforms. ++- **--assume-clean** can be used with **--grow --size** to avoid resyncing the new part of the ++ array. This is only support with very new kernels. ++- RAID0 arrays can have chunksize which is not a power of 2. This has been supported in the kernel ++ for a while but is only now supported by mdadm. ++ ++- A new tool **raid6check** is available, which can check a RAID6 array, or part of it and report ++ which device is most inconsistent with the others if any stripe is inconsistent. This is still ++ under development and does not have a man page yet. If anyone tries it out and has any questions ++ or experience to report, they would be most welcome on linux-raid@vger.kernel.org. ++ ++# Release [mdadm-3.2.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2.1) ++ ++- Policy framework ++ ++ Policy can be expressed for moving spare devices between arrays, and for how to handle hot-plugged ++ devices. This policy can be different for devices plugged in to different controllers etc. This, ++ for example, allows a configuration where when a device is plugged in it is immediately included ++ in an md array as a hot spare and possibly starts recovery immediately if an array is degraded. ++ ++- Some understanding of mbr and gpt paritition tables. This is primarily to support the new ++ hot-plug support. If a device is plugged in and policy suggests it should have a partition table, ++ the partition table will be copied from a suitably similar device, and then the partitions will ++ hot-plug and can then be added to md arrays. ++ ++- **--incremental --remove** can remember where a device was removed from so if a device gets ++ plugged back in the same place, special policy applies to it, allowing it to be included in an ++ array even if a general hotplug will not be included. ++ ++- Enhanced reshape options, including growing a RAID0 by converting to RAID4, restriping, and ++ converting back. Also convertions between RAID0 and RAID10 and between RAID1 and RAID10 are ++ possible (with a suitably recent kernel). ++ ++- Spare migration for IMSM arrays. Spare migration can now work across 'containers' using ++ non-native metadata and specifically Intel's IMSM arrays support spare migrations. ++ ++- OLCE and level migration for Intel IMSM arrays. OnLine Capacity Expansion and level migration ++ (e.g. RAID0 -> RAID5) is supported for Intel Matrix Storage Manager arrays. This support is ++ currently *experimental* for technical reasons. It can be enabled with ++ **export MDADM_EXPERIMENTAL=1**. ++ ++- avoid including wayward devices. ++ ++ If you split a RAID1, mount the two halves as two separate degraded RAID1s, and then later bring ++ the two back together, it is possible that the md metadata won't properly show that one must ++ over-ride the other. Mdadm now does extra checking to detect this possibility and avoid ++ potentially corrupting data. ++ ++- Remove any possible confusion between similar options. e.g. **--brief** and **--bitmap** were ++ mapped to 'b' and mdadm wouldn't notice if one was used where the other was expected. ++ ++- Allow K,M,G suffixes on chunk sizes. ++ ++# Release [mdadm-3.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.2) ++ ++- By far the most significant change in this release related to the management of reshaping arrays. ++ This code has been substantially re-written so that it can work with **externally managed ++ metadata** -Intel's IMSM in particular. We now support level migration and OnLine Capacity ++ Expansion on these arrays. ++ ++- Various policy statements can be made in the *mdadm.conf* to guide the behavior of mdadm, ++ particular with regards to how new devices are treated by **--incremental**. Depending on the ++ *action* associated with a device (identified by its *path*) such need devices can be ++ automatically re-added to and existing array that they previously fell out off, or automatically ++ added as a spare if they appear to contain no data. ++ ++- mdadm now has a limited understanding of partition tables. This allows the policy framework to ++ make decisions about partitioned devices as well. ++ ++- **--incremental --remove** can be told what **--path** the device was on, and this info will be ++ recorded so that another device appearing at the same physical location can be preferentially ++ added to the same array (provides the spare-same-slot action policy applied to the path). ++ ++- A new flags **--invalid-backup** flag is available in **--assemble** mode. This can be used to ++ re-assemble an array which was stopping in the middle of a reshape, and for which the ++ *backup file* is no longer available or is corrupted. The array may have some corruption in it ++ at the point where reshape was up to, but at least the rest of the array will become available. ++ ++- Policy framework. ++- Various internal restructuring - more is needed. ++ ++# Release [mdadm-3.1.5](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.5) ++ ++- Fixes for **v1.x** metadata on big-endian machines. ++- man page improvements. ++- Improve **--detail --export** when run on partitions of an md array. ++- Fix regression with removing *failed* or *detached* devices. ++- Fixes for **--assemble --force** in various unusual cases. ++- Allow **-Y** to mean **--export**. This was documented but not implemented. ++- Various fixes for handling **ddf** metadata. This is now more reliable but could benefit from ++ more interoperability testing. ++- Correctly list subarrays of a container in **--detail** output. ++- Improve checks on whether the requested number of devices is supported by the metadata, both for ++ **--create** and **--grow**. ++- Don't remove partitions from a device that is being included in an array until we are fully ++ committed to including it. ++- Allow **--assemble --update=no-bitmap** so an array with a corrupt bitmap can still be assembled. ++- Don't allow **--add** to succeed if it looks like a **--re-add** is probably wanted, but cannot ++ succeed. This avoids inadvertently turning devices into spares when an array is failed. ++ ++# Release [mdadm-3.1.4](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.4) ++ ++Two fixes related to configs that aren't using udev: ++- Don't remove md devices which 'standard' names on **--stop**. ++- Allow dev_open to work on read-only */dev*. ++ ++And fixed regressions: ++- Allow **--incremental** to add spares to an array. ++- Accept **--no-degraded** as a deprecated option rather than throwing an error. ++- Return correct success status when **--incremental** assembling a container which does not yet ++ have enough devices. ++- Don't link mdadm with pthreads, only mdmon needs it. ++- Fix compiler warning due to bad use of snprintf. ++ ++# Release [mdadm-3.1.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.3) ++ ++- mapfile now lives in a fixed location which default to */dev/.mdadm/map*, but can be changed at ++ compile time. This location is chosen and most distros provide it during early boot and preserve ++ it through. As long a */dev* exists and is writable, */dev/.mdadm* will be created. Other files ++ communication with mdmon live here too. This fixes a bug reported by Debian and Gentoo users where ++ udev would spin in early-boot. ++ ++- IMSM and DDF metadata will not be recognized on partitions as they should only be used on ++ whole-disks. ++ ++- Various overflows causes by 2G drives have been addressed. ++ ++- A subarray of an IMSM contain can now be killed with **--kill-subarray**. Also, subarrays can be ++ renamed with **--update-subarray --update=name**. ++ ++- **-If** (or **--incremental --fail**) can be used from udev to fail and remove from all arrays ++ a device which has been unplugged from the system i.e. hot-unplug-support. ++ ++- **/dev/mdX --re-add missing** will look for any device that looks like it should be a member of ++ */dev/mdX* but isn't and will automatically **--re-add** it. ++ ++- Now compile with *-Wextra* to get extra warnings. ++- Lots of minor bug fixes, documentation improvements, etc. ++ ++# Release [mdadm-3.1.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.2) ++ ++- The default metadata has change again (sorry about that). It is now **v1.2** and will hopefully ++ stay that way. It turned out there with boot-block issues with **v1.1** which make it unsuitable ++ for a default, though in many cases it is still suitable to use. ++ ++- Add *homehost* to the valid words for the **AUTO** config file line. When followed by *-all*, ++ this causes mdadm to auto-assemble any array belonging to this host, but not auto-assemble ++ anything else. ++ ++- VAR_RUN can be easily changed at compile time just like ALT_RUN. This gives distros more ++ flexibility in how to manage the pid and sock files that mdmon needs. ++ ++- If mdadm.conf lists arrays which have inter-dependencies, the previously had to be listed in the ++ "right" order. Now, any order should work. ++ ++- Fix some bugs with **--grow --chunksize=**. ++- Stopping a container is not permitted when members are still active. ++- Various mdmon fixes. ++- Alway make bitmap 4K-aligned if at all possible. ++- Fix **--force** assembly of **v1.x** arrays which are in the process of recovering. ++- Add section on 'scrubbing' to 'md' man page. ++- Various command-line-option parsing improvements. ++- ... and lots of other bug fixes. ++ ++# Release [mdadm-3.1.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1.1) ++ ++- Multiple fixes for new **--grow** levels including fixes for serious data corruption ++ problems. ++- Change default metadata to **v1.1**. ++- Change default chunk size to 512K. ++- Change default bitmap chunk size to 64MB. ++- When **--re-add** is used, don't fall back to **--add** as this can destroy data. ++ ++# Release [mdadm-3.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.1) ++ ++- Support **--grow** to change the layout of RAID 4/5/6. ++- Support **--grow** to change the chunk size of RAID 4/5/6. ++- Support **--grow** to change level from RAID1 -> RAID5 -> RAID6 and back. ++- Support **--grow** to reduce the number of devices in RAID 4/5/6. ++- Support restart of these grow options which assembling an array which is partially grown. ++- Assorted tests of this code, and of different RAID6 layouts. ++ ++# Release [mdadm-3.0.3](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.3) ++ ++- Improvements for creating arrays giving just a name, like *foo*, rather than the full ++ */dev/md/foo*. ++- Improvements for assembling member arrays of containers. ++- Improvements to test suite. ++- Add option to change increment for *RebuildNN* messages reported by **--monitor**. ++- Improvements to **mdmon** hand-over from initrd to final root. ++- Handle merging of devices that have left an IMSM array and are being re-incorporated. ++- Add missing space in **--detail --brief** output. ++ ++# Release [mdadm-3.0.2](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.2) ++ ++- Fix crash when **homehost** is not set, as often happens in early boot. ++ ++# Release [mdadm-3.0.1](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0.1) ++ ++- Fix various segfaults. ++- Fixed for **--examine** with containers. ++- Lots of other little fixes. ++ ++# Release [mdadm-3.0](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/log/?h=mdadm-3.0) ++ ++- Support for **externally managed metadata**, specifically DDF and IMSM. ++- Depend on udev to create entries in */dev*, rather than creating them ourselves. ++- Remove **--auto-update-home-hosts**. ++- New config file line **auto**. ++- New *ignore* and *any* options for **homehost**. ++- Numerous bug fixes and minor enhancements. +diff --git a/ChangeLog b/ChangeLog +deleted file mode 100644 +index a3bf7007..00000000 +--- a/ChangeLog ++++ /dev/null +@@ -1,306 +0,0 @@ +-Please see git logs for detailed change log. +-This file just contains highlight. +- +-Changes Prior to release 3.3 +-- Some array reshapes can proceed without needing backup file. +- This is done by changing the 'data_offset' so we never need to write +- any data back over where it was before. If there is no "head space" +- or "tail space" to allow data_offset to change, the old mechanism +- with a backup file can still be used. +-- RAID10 arrays can be reshaped to change the number of devices, +- change the chunk size, or change the layout between 'near' +- and 'offset'. +- This will always change data_offset, and will fail if there is no +- room for data_offset to be moved. +-- "--assemble --update=metadata" can convert a 0.90 array to a 1.0 array. +-- bad-block-logs are supported (but not heavily tested yet) +-- "--assemble --update=revert-reshape" can be used to undo a reshape +- that has just been started but isn't really wanted. This is very +- new and while it passes basic tests it cannot be guaranteed. +-- improved locking between --incremental and --assemble +-- uses systemd to run "mdmon" if systemd is configured to do that. +-- kernel names of md devices can be non-numeric. e.g. "md_home" rather than +- "md0". This will probably confuse lots of other tools, so you need to +- echo CREATE names=yes >> /etc/mdadm.conf +- or the feature will not be used. (you also need a reasonably new kernel). +-- "--stop" can be given a kernel name instead of a device name. i.e +- mdadm --stop md4 +- will work even if /dev/md4 doesn't exist. +-- "--detail --export" has some information about the devices in the array +-- --dump and --restore can be used to backup and restore the metadata on an +- array. +-- Hot-replace is supported with +- mdadm /dev/mdX --replace /dev/foo +- and +- mdadm /dev/mdX --replace /dev/foo --with /dev/bar +-- Config file can be a directory in which case all "*.conf" files are +- read in lexical order. +- Default is to read /etc/mdadm.conf and then /etc/mdadm.conf.d +- Thus +- echo CREATE name=yes > /etc/mdadm.conf.d/names.conf +- will also enable the use of named md devices. +- +-- Lots of improvements to DDF support including adding support for +- RAID10 (thanks Martin Wilck). +- +-Changes Prior to release 3.2.6 +- - There are no real stand-out fixes, just lots of little bits and pieces. +- +-Changes Prior to release 3.2.5 +- - This release primarily fixes a serious regression in 3.2.4. +- This regression does *not* cause any risk to data. It simply +- means that adding a device with "--add" would sometime fail +- when it should not. +- +- - The fix also includes a couple of minor fixes such as making +- the "--layout=preserve" option to "--grow" work again. +- +- +-Changes Prior to release 3.2.4 +-"--oneline" log of changes is below. Some notable ones are: +- +- - --offroot argument to improve interactions between mdmon and initrd +- - --prefer argument to select which /dev names to display in some +- circumstances. +- - relax restructions on when "--add" will be allowed +- - Fix bug with adding write-intent-bitmap to active array +- - Now defaults to "/run/mdadm" for storing run-time files. +- +-Changes Prior to release 3.2.3 +- - The largest single area of change is support for reshape of Intel +- IMSM arrays (OnLine Capacity Explansion and Level Migration). +- - Among other fixes, this now has a better chance of surviving if a +- device fails during reshape. +- +-Changes Prior to release 3.2.2 +- - reshaping IMSM (Intel metadata) arrays is no longer 'experimental', +- it should work properly and be largely compatible with IMSM drivers in +- other platforms. +- - --assume-clean can be used with --grow --size to avoid resyncing the +- new part of the array. This is only support with very new kernels. +- - RAID0 arrays can have chunksize which is not a power of 2. This has been +- supported in the kernel for a while but is only now supprted by +- mdadm. +- +- - A new tool 'raid6check' is available which can check a RAID6 array, +- or part of it, and report which device is most inconsistent with the +- others if any stripe is inconsistent. This is still under development +- and does not have a man page yet. If anyone tries it out and has any +- questions or experience to report, they would be most welcome on +- linux-raid@vger.kernel.org. +- +-Changes Prior to release 3.2.1 +- - policy framework +- Policy can be expressed for moving spare devices between arrays, and +- for how to handle hot-plugged devices. This policy can be different +- for devices plugged in to different controllers etc. +- This, for example, allows a configuration where when a device is plugged +- in it is immediately included in an md array as a hot spare and +- possibly starts recovery immediately if an array is degraded. +- +- - some understanding of mbr and gpt paritition tables +- This is primarly to support the new hot-plug support. If a +- device is plugged in and policy suggests it should have a partition table, +- the partition table will be copied from a suitably similar device, and +- then the partitions will hot-plug and can then be added to md arrays. +- +- - "--incremental --remove" can remember where a device was removed from +- so if a device gets plugged back in the same place, special policy applies +- to it, allowing it to be included in an array even if a general hotplug +- will not be included. +- +- - enhanced reshape options, including growing a RAID0 by converting to RAID4, +- restriping, and converting back. Also convertions between RAID0 and +- RAID10 and between RAID1 and RAID10 are possible (with a suitably recent +- kernel). +- +- - spare migration for IMSM arrays. +- Spare migration can now work across 'containers' using non-native metadata +- and specifically Intel's IMSM arrays support spare migrations. +- +- - OLCE and level migration for Intel IMSM arrays. +- OnLine Capacity Expansion and level migration (e.g. RAID0 -> RAID5) is +- supported for Intel Matrix Storage Manager arrays. +- This support is currently 'experimental' for technical reasons. It can +- be enabled with "export MDADM_EXPERIMENTAL=1" +- +- - avoid including wayward devices +- If you split a RAID1, mount the two halves as two separate degraded RAID1s, +- and then later bring the two back together, it is possible that the md +- metadata won't properly show that one must over-ride the other. +- mdadm now does extra checking to detect this possibilty and avoid +- potentially corrupting data. +- +- - remove any possible confusion between similar options. +- e.g. --brief and --bitmap were mapped to 'b' and mdadm wouldn't +- notice if one was used where the other was expected. +- +- - allow K,M,G suffixes on chunk sizes +- +-Changes Prior to release 3.2 +- - By far the most significant change in this release related to the +- management of reshaping arrays. This code has been substantially +- re-written so that it can work with 'externally managed metadata' - +- Intel's IMSM in particular. We now support level migration and +- OnLine Capacity Expansion on these arrays. +- - Policy framework. +- Various policy statements can be made in the mdadm.conf to guide +- the behaviour of mdadm, particular with regards to how new devices +- are treated by "mdadm -I". +- Depending on the 'action' associated with a device (identified by +- its 'path') such need devices can be automatically re-added to and +- existing array that they previously fell out off, or automatically +- added as a spare if they appear to contain no data. +- +- - mdadm now has a limited understanding of partition tables. This +- allows the policy framework to make decisions about partitioned +- devices as well. +- +- - --incremental --remove can be told what --path the device was on, +- and this info will be recorded so that another device appearing at +- the same physical location can be preferentially added to the same +- array (provides the spare-same-slot action policy applied to the +- path). +- +- - A new flags "--invalid-backup" flag is available in --assemble +- mode. This can be used to re-assemble an array which was stopping +- in the middle of a reshape, and for which the 'backup file' is no +- longer available or is corrupted. The array may have some +- corruption in it at the point where reshape was up to, but at least +- the rest of the array will become available. +- +- +- - Various internal restructuring - more is needed. +- +-Changes Prior to release 3.1.5 +- - Fixes for v1.x metadata on big-endian machines. +- - man page improvements +- - Improve '--detail --export' when run on partitions of an md array. +- - Fix regression with removing 'failed' or 'detached' devices. +- - Fixes for "--assemble --force" in various unusual cases. +- - Allow '-Y' to mean --export. This was documented but not implemented. +- - Various fixed for handling 'ddf' metadata. This is now more reliable +- but could benefit from more interoperability testing. +- - Correctly list subarrays of a container in "--detail" output. +- - Improve checks on whether the requested number of devices is supported +- by the metadata - both for --create and --grow. +- - Don't remove partitions from a device that is being included in an +- array until we are fully committed to including it. +- - Allow "--assemble --update=no-bitmap" so an array with a corrupt +- bitmap can still be assembled. +- - Don't allow --add to succeed if it looks like a "--re-add" is probably +- wanted, but cannot succeed. This avoids inadvertently turning +- devices into spares when an array is failed. +- +-Changes Prior to release 3.1.4 +- Two fixes related to configs that aren't using udev: +- - Don't remove md devices which 'standard' names on --stop +- - Allow dev_open to work on read-only /dev +- And fixed regressions: +- - Allow --incremental to add spares to an array +- - Accept --no-degraded as a deprecated option rather than +- throwing an error +- - Return correct success status when --incrmental assembling +- a container which does not yet have enough devices. +- - Don't link mdadm with pthreads, only mdmon needs it. +- - Fix compiler warning due to bad use of snprintf +- +-Changes Prior to release 3.1.3 +- - mapfile now lives in a fixed location which default to +- /dev/.mdadm/map but can be changed at compile time. This +- location is choses and most distros provide it during early +- boot and preserve it through. As long a /dev exists and is +- writable, /dev/.mdadm will be created. +- Other files file communication with mdmon live here too. +- This fixes a bug reported by Debian and Gentoo users where +- udev would spin in early-boot. +- - IMSM and DDF metadata will not be recognised on partitions +- as they should only be used on whole-disks. +- - Various overflows causes by 2G drives have been addressed. +- - A subarray of an IMSM contain can now be killed with +- --kill-subarray. Also subarrays can be renamed with +- --update-subarray +- - -If (or --incremental --fail) can be used from udev to +- fail and remove from all arrays a device which has been +- unplugged from the system. i.e. hot-unplug-support. +- - "mdadm /dev/mdX --re-add missing" will look for any device +- that looks like it should be a member of /dev/mdX but isn't +- and will automatically --re-add it +- - Now compile with -Wextra to get extra warnings. +- - Lots of minor bug fixes, documentation improvements, etcc +- +-Changes Prior to release 3.1.2 +- - The default metadata has change again (sorry about that). +- It is now v1.2 and will hopefully stay that way. It turned +- out there with boot-block issues with v1.1 which make it +- unsuitable for a default, though in many cases it is still +- suitable to use. +- - Stopping a container is not permitted when members are still +- active +- - Add 'homehost' to the valid words for the "AUTO" config file +- line. When followed by "-all", this causes mdadm to +- auto-assemble any array belonging to this host, but not +- auto-assemble anything else. +- - Fix some bugs with "--grow --chunksize=" for changing chunksize. +- - VAR_RUN can be easily changed at compile time just like ALT_RUN. +- This gives distros more flexability in how to manage the +- pid and sock files that mdmon needs. +- - Various mdmon fixes +- - Alway make bitmap 4K-aligned if at all possible. +- - If mdadm.conf lists arrays which have inter-dependencies, +- the previously had to be listed in the "right" order. Now +- any order should work. +- - Fix --force assembly of v1.x arrays which are in the process +- of recovering. +- - Add section on 'scrubbing' to 'md' man page. +- - Various command-line-option parsing improvements. +- - ... and lots of other bug fixes. +- +-Changes Prior to release 3.1.1 +- - Multiple fixes for new --grow levels including fixes for +- serious data corruption problems. +- - Change default metadata to v1.1 +- - Change default chunk size to 512K +- - Change default bitmap chunk size to 64Meg +- - When --re-add is used, don't fall back to +- --add if --re-add fails as this can destroy data. +- +-Changes Prior to release 3.1 +- - Support --grow to change the layout of RAID4/5/6 +- - Support --grow to change the chunksize of raid 4/5/6 +- - Support --grow to change level from RAID1 -> RAID5 -> RAID6 and +- back. +- - Support --grow to reduce the number of devices in RAID4/5/6. +- - Support restart of these grow options which assembling an array +- which is partially grown. +- - Assorted tests of this code, and of different RAID6 layouts. +- +-Changes Prior to release 3.0.3 +- - Improvements for creating arrays giving just a name, like 'foo', +- rather than the full '/dev/md/foo'. +- - Improvements for assembling member arrays of containers. +- - Improvements to test suite +- - Add option to change increment for RebuildNN messages reported +- by "mdadm --monitor" +- - Improvements to mdmon 'hand-over' from initrd to final root. +- - Handle merging of devices that have left an IMSM array and are +- being re-incorporated. +- - Add missing space in "--detail --brief" output. +- +-Changes Prior to release 3.0.2 +- - Fix crash when hosthost is not set, as often happens in +- early boot. +- +-Changes Prior to release 3.0.1 +- - Fix various segfaults +- - Fixed for --examine with containers +- - Lots of other little fixes. +- +-Changes Prior to release 3.0 +- - Support for externally managed metadata, specifically DDF and IMSM. +- - Depend on udev to create entries in /dev, rather than creating them +- ourselves. +- - remove --auto-update-home-hosts +- - new config file line "auto" +- - new "" and "any" options for "homehost" +- - numerous bug fixes and minor enhancements. +-- +2.41.0 + diff --git a/SOURCES/0048-mdadm-remove-symlink-option.patch b/SOURCES/0048-mdadm-remove-symlink-option.patch deleted file mode 100644 index 1956e2b..0000000 --- a/SOURCES/0048-mdadm-remove-symlink-option.patch +++ /dev/null @@ -1,176 +0,0 @@ -From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:22 +0200 -Subject: [PATCH 48/83] mdadm: remove symlink option - -The option is not used. Remove it from code. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 - - config.c | 7 +------ - mdadm.8.in | 9 --------- - mdadm.c | 20 -------------------- - mdadm.conf.5.in | 15 --------------- - mdadm.h | 2 -- - 6 files changed, 1 insertion(+), 53 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7518a32a..7f94847e 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -147,7 +147,6 @@ struct option long_options[] = { - {"nofailfast",0, 0, NoFailFast}, - {"re-add", 0, 0, ReAdd}, - {"homehost", 1, 0, HomeHost}, -- {"symlinks", 1, 0, Symlinks}, - {"data-offset",1, 0, DataOffset}, - {"nodes",1, 0, Nodes}, /* also for --assemble */ - {"home-cluster",1, 0, ClusterName}, -diff --git a/config.c b/config.c -index 9c725457..dc1620c1 100644 ---- a/config.c -+++ b/config.c -@@ -194,7 +194,6 @@ struct mddev_dev *load_containers(void) - - struct createinfo createinfo = { - .autof = 2, /* by default, create devices with standard names */ -- .symlinks = 1, - .names = 0, /* By default, stick with numbered md devices. */ - .bblist = 1, /* Use a bad block list by default */ - #ifdef DEBIAN -@@ -310,11 +309,7 @@ static void createline(char *line) - if (!createinfo.supertype) - pr_err("metadata format %s unknown, ignoring\n", - w+9); -- } else if (strncasecmp(w, "symlinks=yes", 12) == 0) -- createinfo.symlinks = 1; -- else if (strncasecmp(w, "symlinks=no", 11) == 0) -- createinfo.symlinks = 0; -- else if (strncasecmp(w, "names=yes", 12) == 0) -+ } else if (strncasecmp(w, "names=yes", 12) == 0) - createinfo.names = 1; - else if (strncasecmp(w, "names=no", 11) == 0) - createinfo.names = 0; -diff --git a/mdadm.8.in b/mdadm.8.in -index 0be02e4a..f2736226 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -1048,11 +1048,6 @@ simultaneously. If not specified, this defaults to 4. - Specify journal device for the RAID-4/5/6 array. The journal device - should be a SSD with reasonable lifetime. - --.TP --.BR \-\-symlinks --Auto creation of symlinks in /dev to /dev/md, option --symlinks must --be 'no' or 'yes' and work with --create and --build. -- - .TP - .BR \-k ", " \-\-consistency\-policy= - Specify how the array maintains consistency in case of unexpected shutdown. -@@ -1405,10 +1400,6 @@ Reshape can be continued later using the - .B \-\-continue - option for the grow command. - --.TP --.BR \-\-symlinks --See this option under Create and Build options. -- - .SH For Manage mode: - - .TP -diff --git a/mdadm.c b/mdadm.c -index 56722ed9..180f7a9c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -59,7 +59,6 @@ int main(int argc, char *argv[]) - struct mddev_dev *dv; - mdu_array_info_t array; - int devs_found = 0; -- char *symlinks = NULL; - int grow_continue = 0; - /* autof indicates whether and how to create device node. - * bottom 3 bits are style. Rest (when shifted) are number of parts -@@ -663,13 +662,6 @@ int main(int argc, char *argv[]) - case O(ASSEMBLE,Auto): /* auto-creation of device node */ - c.autof = parse_auto(optarg, "--auto flag", 0); - continue; -- -- case O(CREATE,Symlinks): -- case O(BUILD,Symlinks): -- case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */ -- symlinks = optarg; -- continue; -- - case O(BUILD,'f'): /* force honouring '-n 1' */ - case O(BUILD,Force): /* force honouring '-n 1' */ - case O(GROW,'f'): /* ditto */ -@@ -1325,18 +1317,6 @@ int main(int argc, char *argv[]) - exit(2); - } - -- if (symlinks) { -- struct createinfo *ci = conf_get_create_info(); -- -- if (strcasecmp(symlinks, "yes") == 0) -- ci->symlinks = 1; -- else if (strcasecmp(symlinks, "no") == 0) -- ci->symlinks = 0; -- else { -- pr_err("option --symlinks must be 'no' or 'yes'\n"); -- exit(2); -- } -- } - /* Ok, got the option parsing out of the way - * hopefully it's mostly right but there might be some stuff - * missing -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index cd4e6a9d..bc2295c2 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -338,21 +338,6 @@ missing device entries should be created. - The name of the metadata format to use if none is explicitly given. - This can be useful to impose a system-wide default of version-1 superblocks. - --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- - .TP - .B names=yes - Since Linux 2.6.29 it has been possible to create -diff --git a/mdadm.h b/mdadm.h -index add9c0b6..93e72786 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -394,7 +394,6 @@ struct createinfo { - int gid; - int autof; - int mode; -- int symlinks; - int names; - int bblist; - struct supertype *supertype; -@@ -442,7 +441,6 @@ enum special_options { - BackupFile, - HomeHost, - AutoHomeHost, -- Symlinks, - AutoDetect, - Waitclean, - DetailPlatform, --- -2.38.1 - diff --git a/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch b/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch new file mode 100644 index 0000000..ac846f5 --- /dev/null +++ b/SOURCES/0049-mdadm-Add-MAINTAINERS.md.patch @@ -0,0 +1,66 @@ +From 21d6c5d96a5a467b5877ba1d38106b3746005bcc Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:11 +0100 +Subject: [PATCH 49/69] mdadm: Add MAINTAINERS.md + +Describe rules maintainer should follow. + +Signed-off-by: Mariusz Tkaczyk +--- + MAINTAINERS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + create mode 100644 MAINTAINERS.md + +diff --git a/MAINTAINERS.md b/MAINTAINERS.md +new file mode 100644 +index 00000000..9c79ba87 +--- /dev/null ++++ b/MAINTAINERS.md +@@ -0,0 +1,44 @@ ++# Maintainer tools ++ ++Useful tools used in daily routines: ++- [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) ++- [kup](https://korg.docs.kernel.org/kup.html) ++- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer) ++- [b4](https://b4.docs.kernel.org/en/latest/) ++ ++# Checklist before applying patch ++ ++We don't have CI testing yet, so all those steps must be performed manually: ++- Style check with [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html): ++ ++ This is the current code style follows. We are not strict to all rules. It must be run ++ by **checkpatch --no-tree**, see README.md. ++ ++- [Commit style](https://www.kernel.org/doc/html/v4.10/process/submitting-patches.html): ++ ++ It doesn't need to be followed as strictly as is in kernel but changes should be logically ++ separated. Submitter should care at least to mention "It is used in next patches" if unused ++ externs/files are added in patch. We love: *Reported-by:*, *Suggested-by:*, *Fixes:* tags. ++ ++- Compilation, ideally on various gcc versions. ++- Mdadm test suite execution. ++- Consider requesting new tests from submitter, especially for new functionalities. ++- Ensure that maintainer *sign-off* is added, before pushing. ++ ++# Making a release ++ ++Assuming that maintainer is certain that release is safe, following steps must be done: ++ ++- Update versions strings in release commit, please refer to previous releases for examples. ++ ++- Create GPG signed tag and push it to repo. Use same format as was used previously, prefixed by ++ **mdadm-**, e.g. **mdadm-3.1.2**, **mdadm-4.1**. ++ ++- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer): ++ ++ Adopt script to our release tag model. When ready, push signed note to repository. If it is done ++ correctly, then *(sig)* is added to the package automatically generated by kernel.org automation. ++ There is no need to upload archive manually. ++ ++- Update CHANGELOG.md. ++- Write "ANNOUNCE" mail to linux-raid@kernel.org to notify community. +-- +2.41.0 + diff --git a/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch b/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch deleted file mode 100644 index 5dca508..0000000 --- a/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch +++ /dev/null @@ -1,232 +0,0 @@ -From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:23 +0200 -Subject: [PATCH 49/83] mdadm: move data_offset to struct shape - -Data offset is a shape property so move it there to remove additional -parameter from some functions. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Create.c | 16 ++++++++-------- - Grow.c | 7 +++---- - mdadm.c | 20 +++++++++----------- - mdadm.h | 5 ++--- - 4 files changed, 22 insertions(+), 26 deletions(-) - -diff --git a/Create.c b/Create.c -index c84c1ac8..e06ec2ae 100644 ---- a/Create.c -+++ b/Create.c -@@ -95,7 +95,7 @@ int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, unsigned long long data_offset) -+ struct context *c) - { - /* - * Create a new raid array. -@@ -288,7 +288,7 @@ int Create(struct supertype *st, char *mddev, - newsize = s->size * 2; - if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, - &s->chunk, s->size*2, -- data_offset, NULL, -+ s->data_offset, NULL, - &newsize, s->consistency_policy, - c->verbose >= 0)) - return 1; -@@ -323,10 +323,10 @@ int Create(struct supertype *st, char *mddev, - info.array.working_disks = 0; - dnum = 0; - for (dv = devlist; dv; dv = dv->next) -- if (data_offset == VARIABLE_OFFSET) -+ if (s->data_offset == VARIABLE_OFFSET) - dv->data_offset = INVALID_SECTORS; - else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) { - char *dname = dv->devname; -@@ -342,7 +342,7 @@ int Create(struct supertype *st, char *mddev, - missing_disks ++; - continue; - } -- if (data_offset == VARIABLE_OFFSET) { -+ if (s->data_offset == VARIABLE_OFFSET) { - doff = strchr(dname, ':'); - if (doff) { - *doff++ = 0; -@@ -350,7 +350,7 @@ int Create(struct supertype *st, char *mddev, - } else - dv->data_offset = INVALID_SECTORS; - } else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - dfd = open(dname, O_RDONLY); - if (dfd < 0) { -@@ -535,7 +535,7 @@ int Create(struct supertype *st, char *mddev, - if (!st->ss->validate_geometry(st, s->level, s->layout, - s->raiddisks, - &s->chunk, minsize*2, -- data_offset, -+ s->data_offset, - NULL, NULL, - s->consistency_policy, 0)) { - pr_err("devices too large for RAID level %d\n", s->level); -@@ -754,7 +754,7 @@ int Create(struct supertype *st, char *mddev, - } - } - if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid, -- data_offset)) -+ s->data_offset)) - goto abort_locked; - - total_slots = info.array.nr_disks; -diff --git a/Grow.c b/Grow.c -index 5780635a..868bdc3a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1775,7 +1775,6 @@ static int reshape_container(char *container, char *devname, - - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s) - { - /* Make some changes in the shape of an array. -@@ -1821,7 +1820,7 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (data_offset != INVALID_SECTORS && array.level != 10 && -+ if (s->data_offset != INVALID_SECTORS && array.level != 10 && - (array.level < 4 || array.level > 6)) { - pr_err("--grow --data-offset not yet supported\n"); - return 1; -@@ -2179,7 +2178,7 @@ size_change_error: - if ((s->level == UnSet || s->level == array.level) && - (s->layout_str == NULL) && - (s->chunk == 0 || s->chunk == array.chunk_size) && -- data_offset == INVALID_SECTORS && -+ s->data_offset == INVALID_SECTORS && - (s->raiddisks == 0 || s->raiddisks == array.raid_disks)) { - /* Nothing more to do */ - if (!changed && c->verbose >= 0) -@@ -2379,7 +2378,7 @@ size_change_error: - } - sync_metadata(st); - rv = reshape_array(container, fd, devname, st, &info, c->force, -- devlist, data_offset, c->backup_file, -+ devlist, s->data_offset, c->backup_file, - c->verbose, 0, 0, 0); - frozen = 0; - } -diff --git a/mdadm.c b/mdadm.c -index 180f7a9c..845e4466 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -49,7 +49,6 @@ int main(int argc, char *argv[]) - int i; - - unsigned long long array_size = 0; -- unsigned long long data_offset = INVALID_SECTORS; - struct mddev_ident ident; - char *configfile = NULL; - int devmode = 0; -@@ -79,6 +78,7 @@ int main(int argc, char *argv[]) - .layout = UnSet, - .bitmap_chunk = UnSet, - .consistency_policy = CONSISTENCY_POLICY_UNKNOWN, -+ .data_offset = INVALID_SECTORS, - }; - - char sys_hostname[256]; -@@ -479,15 +479,15 @@ int main(int argc, char *argv[]) - - case O(CREATE,DataOffset): - case O(GROW,DataOffset): -- if (data_offset != INVALID_SECTORS) { -+ if (s.data_offset != INVALID_SECTORS) { - pr_err("data-offset may only be specified one. Second value is %s.\n", optarg); - exit(2); - } - if (mode == CREATE && strcmp(optarg, "variable") == 0) -- data_offset = VARIABLE_OFFSET; -+ s.data_offset = VARIABLE_OFFSET; - else -- data_offset = parse_size(optarg); -- if (data_offset == INVALID_SECTORS) { -+ s.data_offset = parse_size(optarg); -+ if (s.data_offset == INVALID_SECTORS) { - pr_err("invalid data-offset: %s\n", - optarg); - exit(2); -@@ -1416,7 +1416,7 @@ int main(int argc, char *argv[]) - exit(1); - } - -- if (c.backup_file && data_offset != INVALID_SECTORS) { -+ if (c.backup_file && s.data_offset != INVALID_SECTORS) { - pr_err("--backup-file and --data-offset are incompatible\n"); - exit(2); - } -@@ -1587,8 +1587,7 @@ int main(int argc, char *argv[]) - - rv = Create(ss, devlist->devname, - ident.name, ident.uuid_set ? ident.uuid : NULL, -- devs_found-1, devlist->next, -- &s, &c, data_offset); -+ devs_found - 1, devlist->next, &s, &c); - break; - case MISC: - if (devmode == 'E') { -@@ -1706,10 +1705,9 @@ int main(int argc, char *argv[]) - c.verbose); - else if (s.size > 0 || s.raiddisks || s.layout_str || - s.chunk != 0 || s.level != UnSet || -- data_offset != INVALID_SECTORS) { -+ s.data_offset != INVALID_SECTORS) { - rv = Grow_reshape(devlist->devname, mdfd, -- devlist->next, -- data_offset, &c, &s); -+ devlist->next, &c, &s); - } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); - } else if (array_size == 0) -diff --git a/mdadm.h b/mdadm.h -index 93e72786..adb7cdaa 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -595,6 +595,7 @@ struct shape { - int assume_clean; - int write_behind; - unsigned long long size; -+ unsigned long long data_offset; - int consistency_policy; - }; - -@@ -1431,7 +1432,6 @@ extern int Grow_addbitmap(char *devname, int fd, - struct context *c, struct shape *s); - extern int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s); - extern int Grow_restart(struct supertype *st, struct mdinfo *info, - int *fdlist, int cnt, char *backup_file, int verbose); -@@ -1462,8 +1462,7 @@ extern int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, -- unsigned long long data_offset); -+ struct context *c); - - extern int Detail(char *dev, struct context *c); - extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); --- -2.38.1 - diff --git a/SOURCES/0050-mdadm-Add-README.md.patch b/SOURCES/0050-mdadm-Add-README.md.patch new file mode 100644 index 0000000..aabbbf4 --- /dev/null +++ b/SOURCES/0050-mdadm-Add-README.md.patch @@ -0,0 +1,106 @@ +From 256edaef3d43a112356762aaea4a48f021f45aec Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 26 Mar 2024 13:21:12 +0100 +Subject: [PATCH 50/69] mdadm: Add README.md + +Describe supported metadata types, add step-by-step patch sending +instruction, mention minimally supported kernel version and licensing. + +Signed-off-by: Mariusz Tkaczyk +--- + README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 83 insertions(+) + create mode 100644 README.md + +diff --git a/README.md b/README.md +new file mode 100644 +index 00000000..64f2ecec +--- /dev/null ++++ b/README.md +@@ -0,0 +1,83 @@ ++**mdadm** is a utility used to create and manage **software RAID** devices implemented through ++**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats: ++ ++* [Linux native RAID](https://raid.wiki.kernel.org/index.php/RAID_superblock_formats): ++ ++ Known as **native** or **native RAID**. First and default metadata format. Metadata management ++ is implemented in **MD driver**. ++ ++* Matrix Storage Manager Support (no reference, metadata format documentation is proprietary). ++ ++ Known as **IMSM**. Metadata format developed and maintained by **Intel®** as a part of **VROC** ++ solution. There are some functional differences between **native** and **imsm**. The most ++ important difference is that the metadata is managed from userspace. ++ ++ **CAUTION:** **imsm** is compatible with **Intel RST**, however it is not officially supported. ++ You are using it on your own risk. ++ ++* [Common RAID DDF Specification Revision](https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf) ++ ++ **IMPORTANT:** DDF is in **maintenance only** mode. There is no active development around it. ++ Please do not use it in new solutions. ++ ++# How to Contribute ++ ++ **mdadm** is hosted on [kernel.org](https://kernel.org/). You can access repository ++[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git). ++ ++It is maintained similarly to kernel, using *mailing list*. Patches must be send through email. ++Please familiarize with general kernel ++[submitting patches](https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html) ++documentation. Formatting, tags and commit message guidelines applies to **mdadm**. ++ ++## Sending patches step-by-step ++ ++To maximize change of patches being taken, follow this instruction when submitting: ++ ++1. Create possibly logically separated commits and generate patches: ++ ++ Use ``git format-patch --cover-letter --signoff -v `` to create patches: ++ * ``--cover-letter`` can be skipped if it is only one patch; ++ * ``--signoff`` adds sign-off tag; ++ * ``-v `` indicates review revision number, sender should increment it before resending. ++ ++2. Check style of every patch with kernel ++ [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) script: ++ ++ It is important to keep same coding style that is why in **mdadm** ++ [kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html) ++ is preferred. ``checkpath --no-tree `` can be used to verify patches. ++ Following checkpatch issues can be ignored: ++ - New typedefs. ++ - comparing with *True/False*. ++ - kernel *MAINTAINERS* file warning. ++ - *extern* keyword in headers. ++ ++3. Send patches using ``git send-mail --to=linux-raid@vger.kernel.org (...)`` ++ ++# Maintainers ++ ++It is good practice to add **mdadm maintainers** to recipients for patches: ++ ++- Jes Sorensen ; ++- Mariusz Tkaczyk ; ++ ++Adding **MD maintainers** could be reasonable, especially if patches may affect MD driver: ++ ++- Song Liu ; ++- Yu Kuai ; ++ ++# Reviewers ++ ++**mdadm** utility is not part of kernel tree, so there is no certificated *Reviewers* list. Everyone ++can comment on mailing list, last decision (and merging) belongs to maintainers. ++ ++# Minimal supported kernel version ++ ++We do not support kernel versions below **v3.10**. Please be aware that maintainers may remove ++workarounds and fixes for legacy issues. ++ ++# License ++ ++It is released under the terms of the **GNU General Public License version 2** as published ++by the **Free Software Foundation**. +-- +2.41.0 + diff --git a/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch deleted file mode 100644 index c319da2..0000000 --- a/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:46 -0600 -Subject: [PATCH 50/83] mdadm: Don't open md device for CREATE and ASSEMBLE - -The mdadm command tries to open the md device for most modes, first -thing, no matter what. When running to create or assemble an array, -in most cases, the md device will not exist, the open call will fail -and everything will proceed correctly. - -However, when running tests, a create or assembly command may be run -shortly after stopping an array and the old md device file may still -be around. Then, if create_on_open is set in the kernel, a new md -device will be created when mdadm does its initial open. - -When mdadm gets around to creating the new device with the new_array -parameter it issues this error: - - mdadm: Fail to create md0 when using - /sys/module/md_mod/parameters/new_array, fallback to creation via node - -This is because an mddev was already created by the kernel with the -earlier open() call and thus the new one being created will fail with -EEXIST. The mdadm command will still successfully be created due to -falling back to the node creation method. However, the error message -itself will fail any test that's running it. - -This issue is a race condition that is very rare, but a recent change -in the kernel caused this to happen more frequently: about 1 in 50 -times. - -To fix this, don't bother trying to open the md device for CREATE, -ASSEMBLE and BUILD commands, as the file descriptor will never be used -anyway even if it is successfully openned. The mdfd has not been used -for these commands since: - - 7f91af49ad09 ("Delay creation of array devices for assemble/build/create") - -The checks that were done on the open device can be changed to being -done with stat. - -Side note: it would be nice to disable create_on_open as well to help -solve this, but it seems the work for this was never finished. By default, -mdadm will create using the old node interface when a name is specified -unless the user specifically puts names=yes in a config file, which -doesn't seem to be common or desirable to require this.. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - lib.c | 12 ++++++++++++ - mdadm.c | 40 ++++++++++++++++++++-------------------- - mdadm.h | 1 + - 3 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/lib.c b/lib.c -index 7e3e3d47..e395b28d 100644 ---- a/lib.c -+++ b/lib.c -@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st) - return devid2devnm(st->st_rdev); - } - -+bool stat_is_md_dev(struct stat *st) -+{ -+ if ((S_IFMT & st->st_mode) != S_IFBLK) -+ return false; -+ if (major(st->st_rdev) == MD_MAJOR) -+ return true; -+ if (major(st->st_rdev) == (unsigned)get_mdp_major()) -+ return true; -+ -+ return false; -+} -+ - char *fd2devnm(int fd) - { - struct stat stb; -diff --git a/mdadm.c b/mdadm.c -index 845e4466..972adb52 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1329,6 +1329,9 @@ int main(int argc, char *argv[]) - - if (mode == MANAGE || mode == BUILD || mode == CREATE || - mode == GROW || (mode == ASSEMBLE && ! c.scan)) { -+ struct stat stb; -+ int ret; -+ - if (devs_found < 1) { - pr_err("an md device must be given in this mode\n"); - exit(2); -@@ -1341,6 +1344,12 @@ int main(int argc, char *argv[]) - mdfd = open_mddev(devlist->devname, 1); - if (mdfd < 0) - exit(1); -+ -+ ret = fstat(mdfd, &stb); -+ if (ret) { -+ pr_err("fstat failed on %s.\n", devlist->devname); -+ exit(1); -+ } - } else { - char *bname = basename(devlist->devname); - -@@ -1348,30 +1357,21 @@ int main(int argc, char *argv[]) - pr_err("Name %s is too long.\n", devlist->devname); - exit(1); - } -- /* non-existent device is OK */ -- mdfd = open_mddev(devlist->devname, 0); -- } -- if (mdfd == -2) { -- pr_err("device %s exists but is not an md array.\n", devlist->devname); -- exit(1); -- } -- if ((int)ident.super_minor == -2) { -- struct stat stb; -- if (mdfd < 0) { -+ -+ ret = stat(devlist->devname, &stb); -+ if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -- devlist->devname); -+ devlist->devname); -+ exit(1); -+ } -+ -+ if (!ret && !stat_is_md_dev(&stb)) { -+ pr_err("device %s exists but is not an md array.\n", devlist->devname); - exit(1); - } -- fstat(mdfd, &stb); -- ident.super_minor = minor(stb.st_rdev); -- } -- if (mdfd >= 0 && mode != MANAGE && mode != GROW) { -- /* We don't really want this open yet, we just might -- * have wanted to check some things -- */ -- close(mdfd); -- mdfd = -1; - } -+ if (ident.super_minor == -2) -+ ident.super_minor = minor(stb.st_rdev); - } - - if (s.raiddisks) { -diff --git a/mdadm.h b/mdadm.h -index adb7cdaa..8208b81e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1672,6 +1672,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - extern char *stat2kname(struct stat *st); - extern char *fd2kname(int fd); - extern char *stat2devnm(struct stat *st); -+bool stat_is_md_dev(struct stat *st); - extern char *fd2devnm(int fd); - extern void udev_block(char *devnm); - extern void udev_unblock(void); --- -2.38.1 - diff --git a/SOURCES/0051-Create.c-fix-uclibc-build.patch b/SOURCES/0051-Create.c-fix-uclibc-build.patch new file mode 100644 index 0000000..8e38a6a --- /dev/null +++ b/SOURCES/0051-Create.c-fix-uclibc-build.patch @@ -0,0 +1,41 @@ +From 52bead95d2957437c691891fcdc49bd6afccdd49 Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Fri, 12 Apr 2024 18:45:13 +0200 +Subject: [PATCH 51/69] Create.c: fix uclibc build + +Define FALLOC_FL_ZERO_RANGE if needed as FALLOC_FL_ZERO_RANGE is only +defined for aarch64 on uclibc-ng resulting in the following or1k build +failure since commit 577fd10486d8d1472a6b559066f344ac30a3a391: + +Create.c: In function 'write_zeroes_fork': +Create.c:155:35: error: 'FALLOC_FL_ZERO_RANGE' undeclared (first use in this function) + 155 | if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, + | ^~~~~~~~~~~~~~~~~~~~ + +Fixes: + - http://autobuild.buildroot.org/results/0e04bcdb591ca5642053e1f7e31384f06581e989 + +Signed-off-by: Fabrice Fontaine +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Create.c b/Create.c +index 4397ff49..d94253b1 100644 +--- a/Create.c ++++ b/Create.c +@@ -32,6 +32,10 @@ + #include + #include + ++#ifndef FALLOC_FL_ZERO_RANGE ++#define FALLOC_FL_ZERO_RANGE 16 ++#endif ++ + static int round_size_and_verify(unsigned long long *size, int chunk) + { + if (*size == 0) +-- +2.41.0 + diff --git a/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch b/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch deleted file mode 100644 index 8fe5894..0000000 --- a/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch +++ /dev/null @@ -1,231 +0,0 @@ -From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 28 Jul 2022 20:20:53 +0800 -Subject: [PATCH 51/83] Grow: Split Grow_reshape into helper function - -Grow_reshape should be split into helper functions given its size. -- Add helper function for preparing reshape on external metadata. -- Close cfd file descriptor. - -Signed-off-by: Mateusz Kusiak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 125 ++++++++++++++++++++++++++++++-------------------------- - mdadm.h | 1 + - util.c | 14 +++++++ - 3 files changed, 81 insertions(+), 59 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 868bdc3a..0f07a894 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname, - char *backup_file, int verbose, - int forked, int restart, int freeze_reshape); - -+/** -+ * prepare_external_reshape() - prepares update on external metadata if supported. -+ * @devname: Device name. -+ * @subarray: Subarray. -+ * @st: Supertype. -+ * @container: Container. -+ * @cfd: Container file descriptor. -+ * -+ * Function checks that the requested reshape is supported on external metadata, -+ * and performs an initial check that the container holds the pre-requisite -+ * spare devices (mdmon owns final validation). -+ * -+ * Return: 0 on success, else 1 -+ */ -+static int prepare_external_reshape(char *devname, char *subarray, -+ struct supertype *st, char *container, -+ const int cfd) -+{ -+ struct mdinfo *cc = NULL; -+ struct mdinfo *content = NULL; -+ -+ if (st->ss->load_container(st, cfd, NULL)) { -+ pr_err("Cannot read superblock for %s\n", devname); -+ return 1; -+ } -+ -+ if (!st->ss->container_content) -+ return 1; -+ -+ cc = st->ss->container_content(st, subarray); -+ for (content = cc; content ; content = content->next) { -+ /* -+ * check if reshape is allowed based on metadata -+ * indications stored in content.array.status -+ */ -+ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) || -+ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) { -+ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -+ devname, container); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) { -+ pr_err("Operation not supported when ppl consistency policy is enabled\n"); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) { -+ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n"); -+ goto error; -+ } -+ } -+ sysfs_free(cc); -+ if (mdmon_running(container)) -+ st->update_tail = &st->updates; -+ return 0; -+error: -+ sysfs_free(cc); -+ return 1; -+} -+ - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, - struct context *c, struct shape *s) -@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd, - struct supertype *st; - char *subarray = NULL; - -- int frozen; -+ int frozen = 0; - int changed = 0; - char *container = NULL; - int cfd = -1; -@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd, - int added_disks; - - struct mdinfo info; -- struct mdinfo *sra; -+ struct mdinfo *sra = NULL; - - if (md_get_array_info(fd, &array) < 0) { - pr_err("%s is not an active md array - aborting\n", -@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd, - } - } - -- /* in the external case we need to check that the requested reshape is -- * supported, and perform an initial check that the container holds the -- * pre-requisite spare devices (mdmon owns final validation) -- */ - if (st->ss->external) { -- int retval; -- - if (subarray) { - container = st->container_devnm; - cfd = open_dev_excl(st->container_devnm); -@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- retval = st->ss->load_container(st, cfd, NULL); -- -- if (retval) { -- pr_err("Cannot read superblock for %s\n", devname); -- close(cfd); -+ rv = prepare_external_reshape(devname, subarray, st, -+ container, cfd); -+ if (rv > 0) { - free(subarray); -- return 1; -+ close(cfd); -+ goto release; - } - - if (s->raiddisks && subarray) { -@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd, - free(subarray); - return 1; - } -- -- /* check if operation is supported for metadata handler */ -- if (st->ss->container_content) { -- struct mdinfo *cc = NULL; -- struct mdinfo *content = NULL; -- -- cc = st->ss->container_content(st, subarray); -- for (content = cc; content ; content = content->next) { -- int allow_reshape = 1; -- -- /* check if reshape is allowed based on metadata -- * indications stored in content.array.status -- */ -- if (content->array.state & -- (1 << MD_SB_BLOCK_VOLUME)) -- allow_reshape = 0; -- if (content->array.state & -- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE)) -- allow_reshape = 0; -- if (!allow_reshape) { -- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -- devname, container); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_PPL) { -- pr_err("Operation not supported when ppl consistency policy is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_BITMAP) { -- pr_err("Operation not supported when write-intent bitmap is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- } -- sysfs_free(cc); -- } -- if (mdmon_running(container)) -- st->update_tail = &st->updates; - } - - added_disks = 0; -diff --git a/mdadm.h b/mdadm.h -index 8208b81e..941a5f38 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev); - extern bool is_dev_alive(char *path); - extern int get_mdp_major(void); - extern int get_maj_min(char *dev, int *major, int *minor); -+extern bool is_bit_set(int *val, unsigned char index); - extern int dev_open(char *dev, int flags); - extern int open_dev(char *devnm); - extern void reopen_mddev(int mdfd); -diff --git a/util.c b/util.c -index ca48d976..26ffdcea 100644 ---- a/util.c -+++ b/util.c -@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor) - *e == 0); - } - -+/** -+ * is_bit_set() - get bit value by index. -+ * @val: value. -+ * @index: index of the bit (LSB numbering). -+ * -+ * Return: bit value. -+ */ -+bool is_bit_set(int *val, unsigned char index) -+{ -+ if ((*val) & (1 << index)) -+ return true; -+ return false; -+} -+ - int dev_open(char *dev, int flags) - { - /* like 'open', but if 'dev' matches %d:%d, create a temp --- -2.38.1 - diff --git a/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch b/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch deleted file mode 100644 index 52d08b8..0000000 --- a/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 19 Aug 2022 02:55:46 +0200 -Subject: [PATCH 52/83] Assemble: check if device is container before - scheduling force-clean update - -Up to now using assemble with force flag making each array as clean. -Force-clean should not be done for the container. This commit add -check if device is different than container before cleaning. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Assemble.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index be2160b4..1dd82a8c 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1809,10 +1809,9 @@ try_again: - } - #endif - } -- if (c->force && !clean && -+ if (c->force && !clean && content->array.level != LEVEL_CONTAINER && - !enough(content->array.level, content->array.raid_disks, -- content->array.layout, clean, -- avail)) { -+ content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", - devices[chosen_drive].devname, c->verbose, - 0, NULL); --- -2.38.1 - diff --git a/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch b/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch new file mode 100644 index 0000000..68368e4 --- /dev/null +++ b/SOURCES/0052-mdadm-pass-struct-context-for-external-reshapes.patch @@ -0,0 +1,309 @@ +From bdc2c56998abf76141294b04facf20217cfd1911 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:13 +0200 +Subject: [PATCH 52/69] mdadm: pass struct context for external reshapes + +This patch alters mutiple functions calls so the context is passed to +external reshape functions. + +There are two main reasons behind it: +- reduces number of arguments passed and unifies them, +- imsm code will make use of context in incoming patches. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 7 ++---- + Grow.c | 68 +++++++++++++++++++++------------------------------ + mdadm.c | 2 +- + mdadm.h | 11 +++------ + super-intel.c | 6 ++--- + 5 files changed, 37 insertions(+), 57 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index f6c5b99e..f5e9ab1f 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1197,9 +1197,7 @@ static int start_array(int mdfd, + rv = sysfs_set_str(content, NULL, + "array_state", "readonly"); + if (rv == 0) +- rv = Grow_continue(mdfd, st, content, +- c->backup_file, 0, +- c->freeze_reshape); ++ rv = Grow_continue(mdfd, st, content, 0, c); + } else if (c->readonly && + sysfs_attribute_available(content, NULL, + "array_state")) { +@@ -2180,8 +2178,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + st->update_tail = &st->updates; + } + +- err = Grow_continue(mdfd, st, content, c->backup_file, +- 0, c->freeze_reshape); ++ err = Grow_continue(mdfd, st, content, 0, c); + } else switch(content->array.level) { + case LEVEL_LINEAR: + case LEVEL_MULTIPATH: +diff --git a/Grow.c b/Grow.c +index 074f1995..f477b438 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -864,8 +864,7 @@ static void wait_reshape(struct mdinfo *sra) + + static int reshape_super(struct supertype *st, unsigned long long size, + int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup_file, char *dev, +- int direction, int verbose) ++ int delta_disks, char *dev, int direction, struct context *c) + { + /* nothing extra to check in the native case */ + if (!st->ss->external) +@@ -876,9 +875,8 @@ static int reshape_super(struct supertype *st, unsigned long long size, + return 1; + } + +- return st->ss->reshape_super(st, size, level, layout, chunksize, +- raid_disks, delta_disks, backup_file, dev, +- direction, verbose); ++ return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks, ++ delta_disks, dev, direction, c); + } + + static void sync_metadata(struct supertype *st) +@@ -1764,9 +1762,8 @@ static int reshape_container(char *container, char *devname, + int mdfd, + struct supertype *st, + struct mdinfo *info, +- int force, +- char *backup_file, int verbose, +- int forked, int restart, int freeze_reshape); ++ struct context *c, ++ int forked, int restart); + + /** + * prepare_external_reshape() - prepares update on external metadata if supported. +@@ -2004,9 +2001,8 @@ int Grow_reshape(char *devname, int fd, + goto release; + } + +- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, +- devname, APPLY_METADATA_CHANGES, +- c->verbose > 0)) { ++ if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, ++ devname, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -2124,10 +2120,8 @@ size_change_error: + int err = errno; + + /* restore metadata */ +- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, +- UnSet, NULL, devname, +- ROLLBACK_METADATA_CHANGES, +- c->verbose) == 0) ++ if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet, ++ devname, ROLLBACK_METADATA_CHANGES, c) == 0) + sync_metadata(st); + pr_err("Cannot set device size for %s: %s\n", + devname, strerror(err)); +@@ -2338,8 +2332,7 @@ size_change_error: + */ + close_fd(&fd); + rv = reshape_container(container, devname, -1, st, &info, +- c->force, c->backup_file, c->verbose, +- 0, 0, 0); ++ c, 0, 0); + frozen = 0; + } else { + /* get spare devices from external metadata +@@ -2356,13 +2349,13 @@ size_change_error: + } + + /* Impose these changes on a single array. First +- * check that the metadata is OK with the change. */ ++ * check that the metadata is OK with the change. ++ */ + + if (reshape_super(st, 0, info.new_level, + info.new_layout, info.new_chunk, + info.array.raid_disks, info.delta_disks, +- c->backup_file, devname, +- APPLY_METADATA_CHANGES, c->verbose)) { ++ devname, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -3668,9 +3661,8 @@ int reshape_container(char *container, char *devname, + int mdfd, + struct supertype *st, + struct mdinfo *info, +- int force, +- char *backup_file, int verbose, +- int forked, int restart, int freeze_reshape) ++ struct context *c, ++ int forked, int restart) + { + struct mdinfo *cc = NULL; + int rv = restart; +@@ -3683,8 +3675,7 @@ int reshape_container(char *container, char *devname, + reshape_super(st, 0, info->new_level, + info->new_layout, info->new_chunk, + info->array.raid_disks, info->delta_disks, +- backup_file, devname, APPLY_METADATA_CHANGES, +- verbose)) { ++ devname, APPLY_METADATA_CHANGES, c)) { + unfreeze(st); + return 1; + } +@@ -3695,7 +3686,7 @@ int reshape_container(char *container, char *devname, + */ + ping_monitor(container); + +- if (!forked && !freeze_reshape) ++ if (!forked && !c->freeze_reshape) + if (continue_via_systemd(container, GROW_SERVICE, NULL)) + return 0; + +@@ -3705,7 +3696,7 @@ int reshape_container(char *container, char *devname, + unfreeze(st); + return 1; + default: /* parent */ +- if (!freeze_reshape) ++ if (!c->freeze_reshape) + printf("%s: multi-array reshape continues in background\n", Name); + return 0; + case 0: /* child */ +@@ -3802,12 +3793,12 @@ int reshape_container(char *container, char *devname, + flush_mdmon(container); + + rv = reshape_array(container, fd, adev, st, +- content, force, NULL, INVALID_SECTORS, +- backup_file, verbose, 1, restart, +- freeze_reshape); ++ content, c->force, NULL, INVALID_SECTORS, ++ c->backup_file, c->verbose, 1, restart, ++ c->freeze_reshape); + close(fd); + +- if (freeze_reshape) { ++ if (c->freeze_reshape) { + sysfs_free(cc); + exit(0); + } +@@ -4970,8 +4961,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, + return 1; + } + +-int Grow_continue_command(char *devname, int fd, +- char *backup_file, int verbose) ++int Grow_continue_command(char *devname, int fd, struct context *c) + { + int ret_val = 0; + struct supertype *st = NULL; +@@ -5157,7 +5147,7 @@ int Grow_continue_command(char *devname, int fd, + + /* continue reshape + */ +- ret_val = Grow_continue(fd, st, content, backup_file, 1, 0); ++ ret_val = Grow_continue(fd, st, content, 1, c); + + Grow_continue_command_exit: + if (cfd > -1) +@@ -5171,7 +5161,7 @@ Grow_continue_command_exit: + } + + int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, +- char *backup_file, int forked, int freeze_reshape) ++ int forked, struct context *c) + { + int ret_val = 2; + +@@ -5187,14 +5177,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, + st->ss->load_container(st, cfd, st->container_devnm); + close(cfd); + ret_val = reshape_container(st->container_devnm, NULL, mdfd, +- st, info, 0, backup_file, 0, +- forked, 1 | info->reshape_active, +- freeze_reshape); ++ st, info, c, forked, 1 | info->reshape_active); + } else + ret_val = reshape_array(NULL, mdfd, "array", st, info, 1, +- NULL, INVALID_SECTORS, backup_file, ++ NULL, INVALID_SECTORS, c->backup_file, + 0, forked, 1 | info->reshape_active, +- freeze_reshape); ++ c->freeze_reshape); + + return ret_val; + } +diff --git a/mdadm.c b/mdadm.c +index 3f191288..d18619db 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1636,7 +1636,7 @@ int main(int argc, char *argv[]) + c.delay = DEFAULT_BITMAP_DELAY; + rv = Grow_addbitmap(ident.devname, mdfd, &c, &s); + } else if (grow_continue) +- rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose); ++ rv = Grow_continue_command(ident.devname, mdfd, &c); + else if (s.size > 0 || s.raiddisks || s.layout_str || + s.chunk != 0 || s.level != UnSet || + s.data_offset != INVALID_SECTORS) { +diff --git a/mdadm.h b/mdadm.h +index 2640b396..0ade4beb 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1235,9 +1235,8 @@ extern struct superswitch { + int (*reshape_super)(struct supertype *st, + unsigned long long size, int level, + int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup, char *dev, +- int direction, +- int verbose); /* optional */ ++ int delta_disks, char *dev, int direction, ++ struct context *c); + int (*manage_reshape)( /* optional */ + int afd, struct mdinfo *sra, struct reshape *reshape, + struct supertype *st, unsigned long blocks, +@@ -1541,8 +1540,7 @@ extern int Grow_reshape(char *devname, int fd, + extern int Grow_restart(struct supertype *st, struct mdinfo *info, + int *fdlist, int cnt, char *backup_file, int verbose); + extern int Grow_continue(int mdfd, struct supertype *st, +- struct mdinfo *info, char *backup_file, +- int forked, int freeze_reshape); ++ struct mdinfo *info, int forked, struct context *c); + extern int Grow_consistency_policy(char *devname, int fd, + struct context *c, struct shape *s); + +@@ -1552,8 +1550,7 @@ extern int restore_backup(struct supertype *st, + int spares, + char **backup_filep, + int verbose); +-extern int Grow_continue_command(char *devname, int fd, +- char *backup_file, int verbose); ++extern int Grow_continue_command(char *devname, int fd, struct context *c); + + extern int Assemble(struct supertype *st, char *mddev, + struct mddev_ident *ident, +diff --git a/super-intel.c b/super-intel.c +index 1faab607..417da267 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -12153,10 +12153,8 @@ exit: + } + + static int imsm_reshape_super(struct supertype *st, unsigned long long size, +- int level, +- int layout, int chunksize, int raid_disks, +- int delta_disks, char *backup, char *dev, +- int direction, int verbose) ++ int level, int layout, int chunksize, int raid_disks, ++ int delta_disks, char *dev, int direction, struct context *c) + { + int ret_val = 1; + struct geo_params geo; +-- +2.41.0 + diff --git a/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch b/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch new file mode 100644 index 0000000..7fe21f2 --- /dev/null +++ b/SOURCES/0053-mdadm-use-struct-context-in-reshape_super.patch @@ -0,0 +1,296 @@ +From 0acda7053df653022e46fa3b7caf1f4d4ba31a66 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:14 +0200 +Subject: [PATCH 53/69] mdadm: use struct context in reshape_super() + +reshape_super() takes too many arguments. Change passing params in +favor of single struct. + +Add devname pointer and change direction members to struct shape +and use it for reshape_super(). + +Create reshape_array_size() and reshape_array_non_size() to handle +reshape_super() calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 93 +++++++++++++++++++++++++++++++++++++-------------- + mdadm.h | 18 +++++----- + super-intel.c | 43 +++++++++++++++--------- + 3 files changed, 105 insertions(+), 49 deletions(-) + +diff --git a/Grow.c b/Grow.c +index f477b438..87ed9214 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -862,9 +862,7 @@ static void wait_reshape(struct mdinfo *sra) + close(fd); + } + +-static int reshape_super(struct supertype *st, unsigned long long size, +- int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, struct context *c) ++static int reshape_super(struct supertype *st, struct shape *shape, struct context *c) + { + /* nothing extra to check in the native case */ + if (!st->ss->external) +@@ -875,8 +873,65 @@ static int reshape_super(struct supertype *st, unsigned long long size, + return 1; + } + +- return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks, +- delta_disks, dev, direction, c); ++ return st->ss->reshape_super(st, shape, c); ++} ++ ++/** ++ * reshape_super_size() - Reshape array, size only. ++ * ++ * @st: supertype. ++ * @devname: device name. ++ * @size: component size. ++ * @dir metadata changes direction ++ * Returns: 0 on success, 1 otherwise. ++ * ++ * This function is solely used to change size of the volume. ++ * Setting size is not valid for container. ++ * Size is only change that can be rolled back, thus the @dir param. ++ */ ++static int reshape_super_size(struct supertype *st, char *devname, ++ unsigned long long size, change_dir_t direction, ++ struct context *c) ++{ ++ struct shape shape = {0}; ++ ++ shape.level = UnSet; ++ shape.layout = UnSet; ++ shape.delta_disks = UnSet; ++ shape.dev = devname; ++ shape.size = size; ++ shape.direction = direction; ++ ++ return reshape_super(st, &shape, c); ++} ++ ++/** ++ * reshape_super_non_size() - Reshape array, non size changes. ++ * ++ * @st: supertype. ++ * @devname: device name. ++ * @info: superblock info. ++ * Returns: 0 on success, 1 otherwise. ++ * ++ * This function is used for any external array changes but size. ++ * It handles both volumes and containers. ++ * For changes other than size, rollback is not possible. ++ */ ++static int reshape_super_non_size(struct supertype *st, char *devname, ++ struct mdinfo *info, struct context *c) ++{ ++ struct shape shape = {0}; ++ /* Size already set to zero, not updating size */ ++ shape.level = info->new_level; ++ shape.layout = info->new_layout; ++ shape.chunk = info->new_chunk; ++ shape.raiddisks = info->array.raid_disks; ++ shape.delta_disks = info->delta_disks; ++ shape.dev = devname; ++ /* Rollback not possible for non size changes */ ++ shape.direction = APPLY_METADATA_CHANGES; ++ ++ return reshape_super(st, &shape, c); + } + + static void sync_metadata(struct supertype *st) +@@ -1979,9 +2034,8 @@ int Grow_reshape(char *devname, int fd, + } + + /* ========= set size =============== */ +- if (s->size > 0 && +- (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { +- unsigned long long orig_size = get_component_size(fd)/2; ++ if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { ++ unsigned long long orig_size = get_component_size(fd) / 2; + unsigned long long min_csize; + struct mdinfo *mdi; + int raid0_takeover = 0; +@@ -2001,8 +2055,7 @@ int Grow_reshape(char *devname, int fd, + goto release; + } + +- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, +- devname, APPLY_METADATA_CHANGES, c)) { ++ if (reshape_super_size(st, devname, s->size, APPLY_METADATA_CHANGES, c)) { + rv = 1; + goto release; + } +@@ -2120,8 +2173,8 @@ size_change_error: + int err = errno; + + /* restore metadata */ +- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet, +- devname, ROLLBACK_METADATA_CHANGES, c) == 0) ++ if (reshape_super_size(st, devname, orig_size, ++ ROLLBACK_METADATA_CHANGES, c) == 0) + sync_metadata(st); + pr_err("Cannot set device size for %s: %s\n", + devname, strerror(err)); +@@ -2351,11 +2404,7 @@ size_change_error: + /* Impose these changes on a single array. First + * check that the metadata is OK with the change. + */ +- +- if (reshape_super(st, 0, info.new_level, +- info.new_layout, info.new_chunk, +- info.array.raid_disks, info.delta_disks, +- devname, APPLY_METADATA_CHANGES, c)) { ++ if (reshape_super_non_size(st, devname, &info, c)) { + rv = 1; + goto release; + } +@@ -3668,14 +3717,8 @@ int reshape_container(char *container, char *devname, + int rv = restart; + char last_devnm[32] = ""; + +- /* component_size is not meaningful for a container, +- * so pass '0' meaning 'no change' +- */ +- if (!restart && +- reshape_super(st, 0, info->new_level, +- info->new_layout, info->new_chunk, +- info->array.raid_disks, info->delta_disks, +- devname, APPLY_METADATA_CHANGES, c)) { ++ /* component_size is not meaningful for a container */ ++ if (!restart && reshape_super_non_size(st, devname, info, c)) { + unfreeze(st); + return 1; + } +diff --git a/mdadm.h b/mdadm.h +index 0ade4beb..2ff3e463 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -594,6 +594,11 @@ enum flag_mode { + FlagDefault, FlagSet, FlagClear, + }; + ++typedef enum { ++ ROLLBACK_METADATA_CHANGES, ++ APPLY_METADATA_CHANGES ++} change_dir_t; ++ + /* structures read from config file */ + /* List of mddevice names and identifiers + * Identifiers can be: +@@ -667,7 +672,9 @@ struct context { + }; + + struct shape { ++ char *dev; + int raiddisks; ++ int delta_disks; + int sparedisks; + int journaldisks; + int level; +@@ -682,6 +689,7 @@ struct shape { + unsigned long long size; + unsigned long long data_offset; + int consistency_policy; ++ change_dir_t direction; + }; + + /* List of device names - wildcards expanded */ +@@ -1229,14 +1237,8 @@ extern struct superswitch { + * initialized to indicate if reshape is being performed at the + * container or subarray level + */ +-#define APPLY_METADATA_CHANGES 1 +-#define ROLLBACK_METADATA_CHANGES 0 +- +- int (*reshape_super)(struct supertype *st, +- unsigned long long size, int level, +- int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, +- struct context *c); ++ ++ int (*reshape_super)(struct supertype *st, struct shape *shape, struct context *c); + int (*manage_reshape)( /* optional */ + int afd, struct mdinfo *sra, struct reshape *reshape, + struct supertype *st, unsigned long blocks, +diff --git a/super-intel.c b/super-intel.c +index 417da267..1a8a7b12 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -12152,26 +12152,37 @@ exit: + return ret_val; + } + +-static int imsm_reshape_super(struct supertype *st, unsigned long long size, +- int level, int layout, int chunksize, int raid_disks, +- int delta_disks, char *dev, int direction, struct context *c) ++/** ++ * shape_to_geo() - fill geo_params from shape. ++ * ++ * @shape: array details. ++ * @geo: new geometry params. ++ * Returns: 0 on success, 1 otherwise. ++ */ ++static void shape_to_geo(struct shape *shape, struct geo_params *geo) ++{ ++ assert(shape); ++ assert(geo); ++ ++ geo->dev_name = shape->dev; ++ geo->size = shape->size; ++ geo->level = shape->level; ++ geo->layout = shape->layout; ++ geo->chunksize = shape->chunk; ++ geo->raid_disks = shape->raiddisks; ++} ++ ++static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct context *c) + { + int ret_val = 1; +- struct geo_params geo; ++ struct geo_params geo = {0}; + + dprintf("(enter)\n"); + +- memset(&geo, 0, sizeof(struct geo_params)); +- +- geo.dev_name = dev; ++ shape_to_geo(shape, &geo); + strcpy(geo.devnm, st->devnm); +- geo.size = size; +- geo.level = level; +- geo.layout = layout; +- geo.chunksize = chunksize; +- geo.raid_disks = raid_disks; +- if (delta_disks != UnSet) +- geo.raid_disks += delta_disks; ++ if (shape->delta_disks != UnSet) ++ geo.raid_disks += shape->delta_disks; + + dprintf("for level : %i\n", geo.level); + dprintf("for raid_disks : %i\n", geo.raid_disks); +@@ -12182,7 +12193,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, + int old_raid_disks = 0; + + if (imsm_reshape_is_allowed_on_container( +- st, &geo, &old_raid_disks, direction)) { ++ st, &geo, &old_raid_disks, shape->direction)) { + struct imsm_update_reshape *u = NULL; + int len; + +@@ -12236,7 +12247,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, + goto exit_imsm_reshape_super; + } + super->current_vol = dev->index; +- change = imsm_analyze_change(st, &geo, direction); ++ change = imsm_analyze_change(st, &geo, shape->direction); + switch (change) { + case CH_TAKEOVER: + ret_val = imsm_takeover(st, &geo); +-- +2.41.0 + diff --git a/SOURCES/0053-super1-report-truncated-device.patch b/SOURCES/0053-super1-report-truncated-device.patch deleted file mode 100644 index 35cbd4b..0000000 --- a/SOURCES/0053-super1-report-truncated-device.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Fri, 26 Aug 2022 08:55:56 +1000 -Subject: [PATCH 53/83] super1: report truncated device - -When the metadata is at the start of the device, it is possible that it -describes a device large than the one it is actually stored on. When -this happens, report it loudly in --examine. - -.... - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE -.... - -Also report in --assemble so that the failure which the kernel will -report will be explained. - -mdadm: Device /dev/sdb is not large enough for data described in superblock -mdadm: no RAID superblock on /dev/sdb -mdadm: /dev/sdb has no superblock - assembly aborted - -Scenario can be demonstrated as follows: - -mdadm: Note: this array has metadata at the start and - may not be suitable as a boot device. If you plan to - store '/boot' on this device please ensure that - your boot-loader understands md/v1.x metadata, or use - --metadata=0.90 -mdadm: Defaulting to version 1.2 metadata -mdadm: array /dev/md/test started. -mdadm: stopped /dev/md/test - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - super1.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - -diff --git a/super1.c b/super1.c -index 71af860c..58345e68 100644 ---- a/super1.c -+++ b/super1.c -@@ -406,12 +406,18 @@ static void examine_super1(struct supertype *st, char *homehost) - - st->ss->getinfo_super(st, &info, NULL); - if (info.space_after != 1 && -- !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) -- printf(" Unused Space : before=%llu sectors, after=%llu sectors\n", -- info.space_before, info.space_after); -- -- printf(" State : %s\n", -- (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); -+ !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { -+ printf(" Unused Space : before=%llu sectors, ", -+ info.space_before); -+ if (info.space_after < INT64_MAX) -+ printf("after=%llu sectors\n", info.space_after); -+ else -+ printf("after=-%llu sectors DEVICE TOO SMALL\n", -+ UINT64_MAX - info.space_after); -+ } -+ printf(" State : %s%s\n", -+ (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); - for (i=0; i<16; i++) { - if ((i&3)==0 && i != 0) -@@ -2206,6 +2212,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - tst.ss = &super1; - for (tst.minor_version = 0; tst.minor_version <= 2; - tst.minor_version++) { -+ tst.ignore_hw_compat = st->ignore_hw_compat; - switch(load_super1(&tst, fd, devname)) { - case 0: super = tst.sb; - if (bestvers == -1 || -@@ -2312,7 +2319,6 @@ static int load_super1(struct supertype *st, int fd, char *devname) - free(super); - return 2; - } -- st->sb = super; - - bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); - -@@ -2322,6 +2328,21 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); - -+ if (st->minor_version >= 1 && -+ st->ignore_hw_compat == 0 && -+ (dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size)) -+ || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->data_size)))) { -+ if (devname) -+ pr_err("Device %s is not large enough for data described in superblock\n", -+ devname); -+ free(super); -+ return 2; -+ } -+ st->sb = super; -+ - /* Now check on the bitmap superblock */ - if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) - return 0; --- -2.38.1 - diff --git a/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch b/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch new file mode 100644 index 0000000..c90bf87 --- /dev/null +++ b/SOURCES/0054-imsm-add-support-for-literal-RAID-10.patch @@ -0,0 +1,184 @@ +From 27550b13297adbdefe42fe4eb785b7fde1c0ed91 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:15 +0200 +Subject: [PATCH 54/69] imsm: add support for literal RAID 10 + +As for now, IMSM supports only 4 drive RAID 1+0. This patch is first in +series to add support for literal RAID 10 (with more than 4 drives) to +imsm. + +Allow setting RAID 10 as raid level for imsm arrays. + +Add update_imsm_raid_level() to handle raid level updates. Set RAID10 as +default level for imsm R0 to R10 migrations. Replace magic numbers with +defined values for RAID level checks/assigns. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 67 ++++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 48 insertions(+), 19 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 1a8a7b12..a7efc8df 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -166,7 +166,8 @@ struct imsm_map { + __u8 raid_level; + #define IMSM_T_RAID0 0 + #define IMSM_T_RAID1 1 +-#define IMSM_T_RAID5 5 /* since metadata version 1.2.02 ? */ ++#define IMSM_T_RAID5 5 ++#define IMSM_T_RAID10 10 + __u8 num_members; /* number of member disks */ + __u8 num_domains; /* number of parity domains */ + __u8 failed_disk_num; /* valid only when state is degraded */ +@@ -1259,14 +1260,42 @@ static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) + + return IMSM_STATUS_ERROR; + } ++/** ++ * update_imsm_raid_level() - update raid level appropriately in &imsm_map. ++ * @map: &imsm_map pointer. ++ * @new_level: MD style level. ++ * ++ * For backward compatibility reasons we need to differentiate RAID10. ++ * In the past IMSM RAID10 was presented as RAID1. ++ * Keep compatibility unless it is not explicitly updated by UEFI driver. ++ * ++ * Routine needs num_members to be set and (optionally) raid_level. ++ */ ++static void update_imsm_raid_level(struct imsm_map *map, int new_level) ++{ ++ if (new_level != IMSM_T_RAID10) { ++ map->raid_level = new_level; ++ return; ++ } ++ ++ if (map->num_members == 4) { ++ if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1) ++ return; ++ ++ map->raid_level = IMSM_T_RAID1; ++ return; ++ } ++ ++ map->raid_level = IMSM_T_RAID10; ++} + + static int get_imsm_raid_level(struct imsm_map *map) + { +- if (map->raid_level == 1) { ++ if (map->raid_level == IMSM_T_RAID1) { + if (map->num_members == 2) +- return 1; ++ return IMSM_T_RAID1; + else +- return 10; ++ return IMSM_T_RAID10; + } + + return map->raid_level; +@@ -5678,7 +5707,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + set_pba_of_lba0(map, super->create_offset); + map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info)); + map->failed_disk_num = ~0; +- if (info->level > 0) ++ if (info->level > IMSM_T_RAID0) + map->map_state = (info->state ? IMSM_T_STATE_NORMAL + : IMSM_T_STATE_UNINITIALIZED); + else +@@ -5686,16 +5715,15 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + IMSM_T_STATE_NORMAL; + map->ddf = 1; + +- if (info->level == 1 && info->raid_disks > 2) { ++ if (info->level == IMSM_T_RAID1 && info->raid_disks > 2) { + free(dev); + free(dv); +- pr_err("imsm does not support more than 2 disksin a raid1 volume\n"); ++ pr_err("imsm does not support more than 2 disks in a raid1 volume\n"); + return 0; + } ++ map->num_members = info->raid_disks; + +- map->raid_level = info->level; +- if (info->level == 10) +- map->raid_level = 1; ++ update_imsm_raid_level(map, info->level); + set_num_domains(map); + + size_per_member += NUM_BLOCKS_DIRTY_STRIPE_REGION; +@@ -5703,7 +5731,6 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + size_per_member / + BLOCKS_PER_KB)); + +- map->num_members = info->raid_disks; + update_num_data_stripes(map, array_blocks); + for (i = 0; i < map->num_members; i++) { + /* initialized in add_to_super */ +@@ -8275,7 +8302,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + info_d->data_offset = pba_of_lba0(map); + info_d->component_size = calc_component_size(map, dev); + +- if (map->raid_level == 5) { ++ if (map->raid_level == IMSM_T_RAID5) { + info_d->ppl_sector = this->ppl_sector; + info_d->ppl_size = this->ppl_size; + if (this->consistency_policy == CONSISTENCY_POLICY_PPL && +@@ -9533,7 +9560,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + } + + to_state = map->map_state; +- if ((u->new_level == 5) && (map->raid_level == 0)) { ++ if ((u->new_level == IMSM_T_RAID5) && (map->raid_level == IMSM_T_RAID0)) { + map->num_members++; + /* this should not happen */ + if (u->new_disks[0] < 0) { +@@ -9544,11 +9571,13 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + to_state = IMSM_T_STATE_NORMAL; + } + migrate(new_dev, super, to_state, MIGR_GEN_MIGR); ++ + if (u->new_level > -1) +- map->raid_level = u->new_level; ++ update_imsm_raid_level(map, u->new_level); ++ + migr_map = get_imsm_map(new_dev, MAP_1); +- if ((u->new_level == 5) && +- (migr_map->raid_level == 0)) { ++ if ((u->new_level == IMSM_T_RAID5) && ++ (migr_map->raid_level == IMSM_T_RAID0)) { + int ord = map->num_members - 1; + migr_map->num_members--; + if (u->new_disks[0] < 0) +@@ -9584,7 +9613,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * + + /* add disk + */ +- if (u->new_level != 5 || migr_map->raid_level != 0 || ++ if (u->new_level != IMSM_T_RAID5 || migr_map->raid_level != IMSM_T_RAID0 || + migr_map->raid_level == map->raid_level) + goto skip_disk_add; + +@@ -9963,7 +9992,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u, + /* update map */ + map->num_members /= map->num_domains; + map->map_state = IMSM_T_STATE_NORMAL; +- map->raid_level = 0; ++ update_imsm_raid_level(map, IMSM_T_RAID0); + set_num_domains(map); + update_num_data_stripes(map, imsm_dev_size(dev)); + map->failed_disk_num = -1; +@@ -10007,7 +10036,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u, + map = get_imsm_map(dev_new, MAP_0); + + map->map_state = IMSM_T_STATE_DEGRADED; +- map->raid_level = 1; ++ update_imsm_raid_level(map, IMSM_T_RAID10); + set_num_domains(map); + map->num_members = map->num_members * map->num_domains; + update_num_data_stripes(map, imsm_dev_size(dev)); +-- +2.41.0 + diff --git a/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch b/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch deleted file mode 100644 index c37276f..0000000 --- a/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:52:12 +0200 -Subject: [PATCH 54/83] mdadm: Correct typos, punctuation and grammar in man - -Signed-off-by: Mateusz Grzonka -Reviewed-by: Wol -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 178 ++++++++++++++++++++++++++--------------------------- - 1 file changed, 88 insertions(+), 90 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index f2736226..70c79d1e 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -158,7 +158,7 @@ adding new spares and removing faulty devices. - .B Misc - This is an 'everything else' mode that supports operations on active - arrays, operations on component devices such as erasing old superblocks, and --information gathering operations. -+information-gathering operations. - .\"This mode allows operations on independent devices such as examine MD - .\"superblocks, erasing old superblocks and stopping active arrays. - -@@ -231,12 +231,12 @@ mode to be assumed. - - .TP - .BR \-h ", " \-\-help --Display general help message or, after one of the above options, a -+Display a general help message or, after one of the above options, a - mode-specific help message. - - .TP - .B \-\-help\-options --Display more detailed help about command line parsing and some commonly -+Display more detailed help about command-line parsing and some commonly - used options. - - .TP -@@ -266,7 +266,7 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. If not specified, default config file -+Specify the config file or directory. If not specified, the default config file - and default conf.d directory will be used. See - .BR mdadm.conf (5) - for more details. -@@ -379,7 +379,7 @@ When creating an array, the - .B homehost - will be recorded in the metadata. For version-1 superblocks, it will - be prefixed to the array name. For version-0.90 superblocks, part of --the SHA1 hash of the hostname will be stored in the later half of the -+the SHA1 hash of the hostname will be stored in the latter half of the - UUID. - - When reporting information about an array, any array which is tagged -@@ -388,7 +388,7 @@ for the given homehost will be reported as such. - When using Auto-Assemble, only arrays tagged for the given homehost - will be allowed to use 'local' names (i.e. not ending in '_' followed - by a digit string). See below under --.BR "Auto Assembly" . -+.BR "Auto-Assembly" . - - The special name "\fBany\fP" can be used as a wild card. If an array - is created with -@@ -403,7 +403,7 @@ When - .I mdadm - needs to print the name for a device it normally finds the name in - .B /dev --which refers to the device and is shortest. When a path component is -+which refers to the device and is the shortest. When a path component is - given with - .B \-\-prefer - .I mdadm -@@ -478,9 +478,9 @@ still be larger than any replacement. - - This option can be used with - .B \-\-create --for determining initial size of an array. For external metadata, -+for determining the initial size of an array. For external metadata, - it can be used on a volume, but not on a container itself. --Setting initial size of -+Setting the initial size of - .B RAID 0 - array is only valid for external metadata. - -@@ -545,20 +545,20 @@ Clustered arrays do not support this parameter yet. - - .TP - .BR \-c ", " \-\-chunk= --Specify chunk size of kilobytes. The default when creating an -+Specify chunk size in kilobytes. The default when creating an - array is 512KB. To ensure compatibility with earlier versions, the - default when building an array with no persistent metadata is 64KB. - This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10. - - RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power --of 2. In any case it must be a multiple of 4KB. -+of 2, with minimal chunk size being 4KB. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, - Megabytes, Gigabytes or Terabytes respectively. - - .TP - .BR \-\-rounding= --Specify rounding factor for a Linear array. The size of each -+Specify the rounding factor for a Linear array. The size of each - component will be rounded down to a multiple of this size. - This is a synonym for - .B \-\-chunk -@@ -655,7 +655,8 @@ option to set subsequent failure modes. - and "flush" will clear any persistent faults. - - The layout options for RAID10 are one of 'n', 'o' or 'f' followed --by a small number. The default is 'n2'. The supported options are: -+by a small number signifying the number of copies of each datablock. -+The default is 'n2'. The supported options are: - - .I 'n' - signals 'near' copies. Multiple copies of one data block are at -@@ -673,7 +674,7 @@ signals 'far' copies - (multiple copies have very different offsets). - See md(4) for more detail about 'near', 'offset', and 'far'. - --The number is the number of copies of each datablock. 2 is normal, 3 -+As for the number of copies of each data block, 2 is normal, 3 - can be useful. This number can be at most equal to the number of - devices in the array. It does not need to divide evenly into that - number (e.g. it is perfectly legal to have an 'n2' layout for an array -@@ -684,7 +685,7 @@ A bug introduced in Linux 3.14 means that RAID0 arrays - started using a different layout. This could lead to - data corruption. Since Linux 5.4 (and various stable releases that received - backports), the kernel will not accept such an array unless --a layout is explictly set. It can be set to -+a layout is explicitly set. It can be set to - .RB ' original ' - or - .RB ' alternate '. -@@ -760,13 +761,13 @@ or by selecting a different consistency policy with - - .TP - .BR \-\-bitmap\-chunk= --Set the chunksize of the bitmap. Each bit corresponds to that many -+Set the chunk size of the bitmap. Each bit corresponds to that many - Kilobytes of storage. --When using a file based bitmap, the default is to use the smallest --size that is at-least 4 and requires no more than 2^21 chunks. -+When using a file-based bitmap, the default is to use the smallest -+size that is at least 4 and requires no more than 2^21 chunks. - When using an - .B internal --bitmap, the chunksize defaults to 64Meg, or larger if necessary to -+bitmap, the chunk size defaults to 64Meg, or larger if necessary to - fit the bitmap into the available space. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, -@@ -840,7 +841,7 @@ can be used with that command to avoid the automatic resync. - .BR \-\-backup\-file= - This is needed when - .B \-\-grow --is used to increase the number of raid-devices in a RAID5 or RAID6 if -+is used to increase the number of raid devices in a RAID5 or RAID6 if - there are no spare devices available, or to shrink, change RAID level - or layout. See the GROW MODE section below on RAID\-DEVICES CHANGES. - The file must be stored on a separate device, not on the RAID array -@@ -879,7 +880,7 @@ When creating an array, - .B \-\-data\-offset - can be specified as - .BR variable . --In the case each member device is expected to have a offset appended -+In the case each member device is expected to have an offset appended - to the name, separated by a colon. This makes it possible to recreate - exactly an array which has varying data offsets (as can happen when - different versions of -@@ -943,7 +944,7 @@ Insist that - .I mdadm - accept the geometry and layout specified without question. Normally - .I mdadm --will not allow creation of an array with only one device, and will try -+will not allow the creation of an array with only one device, and will try - to create a RAID5 array with one missing drive (as this makes the - initial resync work faster). With - .BR \-\-force , -@@ -1004,7 +1005,7 @@ number added, e.g. - If the md device name is in a 'standard' format as described in DEVICE - NAMES, then it will be created, if necessary, with the appropriate - device number based on that name. If the device name is not in one of these --formats, then a unused device number will be allocated. The device -+formats, then an unused device number will be allocated. The device - number will be considered unused if there is no active array for that - number, and there is no entry in /dev for that number and with a - non-standard name. Names that are not in 'standard' format are only -@@ -1032,25 +1033,25 @@ then - .B \-\-add - can be used to add some extra devices to be included in the array. - In most cases this is not needed as the extra devices can be added as --spares first, and then the number of raid-disks can be changed. --However for RAID0, it is not possible to add spares. So to increase -+spares first, and then the number of raid disks can be changed. -+However, for RAID0 it is not possible to add spares. So to increase - the number of devices in a RAID0, it is necessary to set the new - number of devices, and to add the new devices, in the same command. - - .TP - .BR \-\-nodes --Only works when the array is for clustered environment. It specifies -+Only works when the array is created for a clustered environment. It specifies - the maximum number of nodes in the cluster that will use this device - simultaneously. If not specified, this defaults to 4. - - .TP - .BR \-\-write-journal - Specify journal device for the RAID-4/5/6 array. The journal device --should be a SSD with reasonable lifetime. -+should be an SSD with a reasonable lifetime. - - .TP - .BR \-k ", " \-\-consistency\-policy= --Specify how the array maintains consistency in case of unexpected shutdown. -+Specify how the array maintains consistency in the case of an unexpected shutdown. - Only relevant for RAID levels with redundancy. - Currently supported options are: - .RS -@@ -1058,7 +1059,7 @@ Currently supported options are: - .TP - .B resync - Full resync is performed and all redundancy is regenerated when the array is --started after unclean shutdown. -+started after an unclean shutdown. - - .TP - .B bitmap -@@ -1067,8 +1068,8 @@ Resync assisted by a write-intent bitmap. Implicitly selected when using - - .TP - .B journal --For RAID levels 4/5/6, journal device is used to log transactions and replay --after unclean shutdown. Implicitly selected when using -+For RAID levels 4/5/6, the journal device is used to log transactions and replay -+after an unclean shutdown. Implicitly selected when using - .BR \-\-write\-journal . - - .TP -@@ -1237,7 +1238,7 @@ This can be useful if - reports a different "Preferred Minor" to - .BR \-\-detail . - In some cases this update will be performed automatically --by the kernel driver. In particular the update happens automatically -+by the kernel driver. In particular, the update happens automatically - at the first write to an array with redundancy (RAID level 1 or - greater) on a 2.6 (or later) kernel. - -@@ -1277,7 +1278,7 @@ For version-1 superblocks, this involves updating the name. - The - .B home\-cluster - option will change the cluster name as recorded in the superblock and --bitmap. This option only works for clustered environment. -+bitmap. This option only works for a clustered environment. - - The - .B resync -@@ -1390,10 +1391,10 @@ This option should be used with great caution. - - .TP - .BR \-\-freeze\-reshape --Option is intended to be used in start-up scripts during initrd boot phase. --When array under reshape is assembled during initrd phase, this option --stops reshape after reshape critical section is being restored. This happens --before file system pivot operation and avoids loss of file system context. -+This option is intended to be used in start-up scripts during the initrd boot phase. -+When the array under reshape is assembled during the initrd phase, this option -+stops the reshape after the reshape-critical section has been restored. This happens -+before the file system pivot operation and avoids loss of filesystem context. - Losing file system context would cause reshape to be broken. - - Reshape can be continued later using the -@@ -1437,9 +1438,9 @@ re\-add a device that was previously removed from an array. - If the metadata on the device reports that it is a member of the - array, and the slot that it used is still vacant, then the device will - be added back to the array in the same position. This will normally --cause the data for that device to be recovered. However based on the -+cause the data for that device to be recovered. However, based on the - event count on the device, the recovery may only require sections that --are flagged a write-intent bitmap to be recovered or may not require -+are flagged by a write-intent bitmap to be recovered or may not require - any recovery at all. - - When used on an array that has no metadata (i.e. it was built with -@@ -1447,13 +1448,12 @@ When used on an array that has no metadata (i.e. it was built with - it will be assumed that bitmap-based recovery is enough to make the - device fully consistent with the array. - --When used with v1.x metadata, - .B \-\-re\-add --can be accompanied by -+can also be accompanied by - .BR \-\-update=devicesize , - .BR \-\-update=bbl ", or" - .BR \-\-update=no\-bbl . --See the description of these option when used in Assemble mode for an -+See descriptions of these options when used in Assemble mode for an - explanation of their use. - - If the device name given is -@@ -1480,7 +1480,7 @@ Add a device as a spare. This is similar to - except that it does not attempt - .B \-\-re\-add - first. The device will be added as a spare even if it looks like it --could be an recent member of the array. -+could be a recent member of the array. - - .TP - .BR \-r ", " \-\-remove -@@ -1497,12 +1497,12 @@ and names like - .B set-A - can be given to - .BR \-\-remove . --The first causes all failed device to be removed. The second causes -+The first causes all failed devices to be removed. The second causes - any device which is no longer connected to the system (i.e an 'open' - returns - .BR ENXIO ) - to be removed. --The third will remove a set as describe below under -+The third will remove a set as described below under - .BR \-\-fail . - - .TP -@@ -1519,7 +1519,7 @@ For RAID10 arrays where the number of copies evenly divides the number - of devices, the devices can be conceptually divided into sets where - each set contains a single complete copy of the data on the array. - Sometimes a RAID10 array will be configured so that these sets are on --separate controllers. In this case all the devices in one set can be -+separate controllers. In this case, all the devices in one set can be - failed by giving a name like - .B set\-A - or -@@ -1549,9 +1549,9 @@ This can follow a list of - .B \-\-replace - devices. The devices listed after - .B \-\-with --will be preferentially used to replace the devices listed after -+will preferentially be used to replace the devices listed after - .BR \-\-replace . --These device must already be spare devices in the array. -+These devices must already be spare devices in the array. - - .TP - .BR \-\-write\-mostly -@@ -1574,8 +1574,8 @@ the device is found or :missing in case the device is not found. - - .TP - .BR \-\-add-journal --Add journal to an existing array, or recreate journal for RAID-4/5/6 array --that lost a journal device. To avoid interrupting on-going write opertions, -+Add a journal to an existing array, or recreate journal for a RAID-4/5/6 array -+that lost a journal device. To avoid interrupting ongoing write operations, - .B \-\-add-journal - only works for array in Read-Only state. - -@@ -1631,9 +1631,9 @@ Print details of one or more md devices. - .TP - .BR \-\-detail\-platform - Print details of the platform's RAID capabilities (firmware / hardware --topology) for a given metadata format. If used without argument, mdadm -+topology) for a given metadata format. If used without an argument, mdadm - will scan all controllers looking for their capabilities. Otherwise, mdadm --will only look at the controller specified by the argument in form of an -+will only look at the controller specified by the argument in the form of an - absolute filepath or a link, e.g. - .IR /sys/devices/pci0000:00/0000:00:1f.2 . - -@@ -1742,8 +1742,8 @@ the block where the superblock would be is overwritten even if it - doesn't appear to be valid. - - .B Note: --Be careful to call \-\-zero\-superblock with clustered raid, make sure --array isn't used or assembled in other cluster node before execute it. -+Be careful when calling \-\-zero\-superblock with clustered raid. Make sure -+the array isn't used or assembled in another cluster node before executing it. - - .TP - .B \-\-kill\-subarray= -@@ -1790,7 +1790,7 @@ For each md device given, or each device in /proc/mdstat if - is given, arrange for the array to be marked clean as soon as possible. - .I mdadm - will return with success if the array uses external metadata and we --successfully waited. For native arrays this returns immediately as the -+successfully waited. For native arrays, this returns immediately as the - kernel handles dirty-clean transitions at shutdown. No action is taken - if safe-mode handling is disabled. - -@@ -1830,7 +1830,7 @@ uses to help track which arrays are currently being assembled. - - .TP - .BR \-\-run ", " \-R --Run any array assembled as soon as a minimal number of devices are -+Run any array assembled as soon as a minimal number of devices is - available, rather than waiting until all expected devices are present. - - .TP -@@ -1860,7 +1860,7 @@ Only used with \-\-fail. The 'path' given will be recorded so that if - a new device appears at the same location it can be automatically - added to the same array. This allows the failed device to be - automatically replaced by a new device without metadata if it appears --at specified path. This option is normally only set by a -+at specified path. This option is normally only set by an - .I udev - script. - -@@ -1961,7 +1961,7 @@ Usage: - .PP - This usage assembles one or more RAID arrays from pre-existing components. - For each array, mdadm needs to know the md device, the identity of the --array, and a number of component-devices. These can be found in a number of ways. -+array, and the number of component devices. These can be found in a number of ways. - - In the first usage example (without the - .BR \-\-scan ) -@@ -2001,7 +2001,7 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, default config file is used. See -+In the latter case, the default config file is used. See - .BR mdadm.conf (5) - for more details. - -@@ -2039,14 +2039,14 @@ detects that udev is not configured, it will create the devices in - .B /dev - itself. - --In Linux kernels prior to version 2.6.28 there were two distinctly --different types of md devices that could be created: one that could be -+In Linux kernels prior to version 2.6.28 there were two distinct -+types of md devices that could be created: one that could be - partitioned using standard partitioning tools and one that could not. --Since 2.6.28 that distinction is no longer relevant as both type of -+Since 2.6.28 that distinction is no longer relevant as both types of - devices can be partitioned. - .I mdadm - will normally create the type that originally could not be partitioned --as it has a well defined major number (9). -+as it has a well-defined major number (9). - - Prior to 2.6.28, it is important that mdadm chooses the correct type - of array device to use. This can be controlled with the -@@ -2066,7 +2066,7 @@ can also be given in the configuration file as a word starting - .B auto= - on the ARRAY line for the relevant array. - --.SS Auto Assembly -+.SS Auto-Assembly - When - .B \-\-assemble - is used with -@@ -2122,11 +2122,11 @@ See - .IR mdadm.conf (5) - for further details. - --Note: Auto assembly cannot be used for assembling and activating some -+Note: Auto-assembly cannot be used for assembling and activating some - arrays which are undergoing reshape. In particular as the - .B backup\-file --cannot be given, any reshape which requires a backup-file to continue --cannot be started by auto assembly. An array which is growing to more -+cannot be given, any reshape which requires a backup file to continue -+cannot be started by auto-assembly. An array which is growing to more - devices and has passed the critical section can be assembled using - auto-assembly. - -@@ -2233,7 +2233,7 @@ When creating a partition based array, using - .I mdadm - with version-1.x metadata, the partition type should be set to - .B 0xDA --(non fs-data). This type selection allows for greater precision since -+(non fs-data). This type of selection allows for greater precision since - using any other [RAID auto-detect (0xFD) or a GNU/Linux partition (0x83)], - might create problems in the event of array recovery through a live cdrom. - -@@ -2249,7 +2249,7 @@ when creating a v0.90 array will silently override any - setting. - .\"If the - .\".B \-\-size --.\"option is given, it is not necessary to list any component-devices in this command. -+.\"option is given, it is not necessary to list any component devices in this command. - .\"They can be added later, before a - .\".B \-\-run. - .\"If no -@@ -2263,7 +2263,7 @@ requested with the - .B \-\-bitmap - option or a different consistency policy is selected with the - .B \-\-consistency\-policy --option. In any case space for a bitmap will be reserved so that one -+option. In any case, space for a bitmap will be reserved so that one - can be added later with - .BR "\-\-grow \-\-bitmap=internal" . - -@@ -2313,7 +2313,7 @@ will firstly mark - as faulty in - .B /dev/md0 - and will then remove it from the array and finally add it back --in as a spare. However only one md array can be affected by a single -+in as a spare. However, only one md array can be affected by a single - command. - - When a device is added to an active array, mdadm checks to see if it -@@ -2458,14 +2458,14 @@ config file to be examined. - If the device contains RAID metadata, a file will be created in the - .I directory - and the metadata will be written to it. The file will be the same --size as the device and have the metadata written in the file at the --same locate that it exists in the device. However the file will be "sparse" so -+size as the device and will have the metadata written at the -+same location as it exists in the device. However, the file will be "sparse" so - that only those blocks containing metadata will be allocated. The - total space used will be small. - --The file name used in the -+The filename used in the - .I directory --will be the base name of the device. Further if any links appear in -+will be the base name of the device. Further, if any links appear in - .I /dev/disk/by-id - which point to the device, then hard links to the file will be created - in -@@ -2567,7 +2567,7 @@ and if the destination array has a failed drive but no spares. - - If any devices are listed on the command line, - .I mdadm --will only monitor those devices. Otherwise all arrays listed in the -+will only monitor those devices, otherwise, all arrays listed in the - configuration file will be monitored. Further, if - .B \-\-scan - is given, then any other md devices that appear in -@@ -2624,10 +2624,10 @@ check, repair). (syslog priority: Warning) - .BI Rebuild NN - Where - .I NN --is a two-digit number (ie. 05, 48). This indicates that rebuild --has passed that many percent of the total. The events are generated --with fixed increment since 0. Increment size may be specified with --a commandline option (default is 20). (syslog priority: Warning) -+is a two-digit number (eg. 05, 48). This indicates that the rebuild -+has reached that percentage of the total. The events are generated -+at a fixed increment from 0. The increment size may be specified with -+a command-line option (the default is 20). (syslog priority: Warning) - - .TP - .B RebuildFinished -@@ -2735,8 +2735,8 @@ When - detects that an array in a spare group has fewer active - devices than necessary for the complete array, and has no spare - devices, it will look for another array in the same spare group that --has a full complement of working drive and a spare. It will then --attempt to remove the spare from the second drive and add it to the -+has a full complement of working drives and a spare. It will then -+attempt to remove the spare from the second array and add it to the - first. - If the removal succeeds but the adding fails, then it is added back to - the original array. -@@ -2750,10 +2750,8 @@ and then follow similar steps as above if a matching spare is found. - .SH GROW MODE - The GROW mode is used for changing the size or shape of an active - array. --For this to work, the kernel must support the necessary change. --Various types of growth are being added during 2.6 development. - --Currently the supported changes include -+During the kernel 2.6 era the following changes were added: - .IP \(bu 4 - change the "size" attribute for RAID1, RAID4, RAID5 and RAID6. - .IP \(bu 4 -@@ -2796,8 +2794,8 @@ use more than half of a spare device for backup space. - - .SS SIZE CHANGES - Normally when an array is built the "size" is taken from the smallest --of the drives. If all the small drives in an arrays are, one at a --time, removed and replaced with larger drives, then you could have an -+of the drives. If all the small drives in an arrays are, over time, -+removed and replaced with larger drives, then you could have an - array of large drives with only a small amount used. In this - situation, changing the "size" with "GROW" mode will allow the extra - space to start being used. If the size is increased in this way, a -@@ -2812,7 +2810,7 @@ after growing, or to reduce its size - .B prior - to shrinking the array. - --Also the size of an array cannot be changed while it has an active -+Also, the size of an array cannot be changed while it has an active - bitmap. If an array has a bitmap, it must be removed before the size - can be changed. Once the change is complete a new bitmap can be created. - -@@ -2892,7 +2890,7 @@ long time. A - is required. If the array is not simultaneously being grown or - shrunk, so that the array size will remain the same - for example, - reshaping a 3-drive RAID5 into a 4-drive RAID6 - the backup file will --be used not just for a "cricital section" but throughout the reshape -+be used not just for a "critical section" but throughout the reshape - operation, as described below under LAYOUT CHANGES. - - .SS CHUNK-SIZE AND LAYOUT CHANGES -@@ -2910,7 +2908,7 @@ slowly. - If the reshape is interrupted for any reason, this backup file must be - made available to - .B "mdadm --assemble" --so the array can be reassembled. Consequently the file cannot be -+so the array can be reassembled. Consequently, the file cannot be - stored on the device being reshaped. - - --- -2.38.1 - diff --git a/SOURCES/0055-Manage-Block-unsafe-member-failing.patch b/SOURCES/0055-Manage-Block-unsafe-member-failing.patch deleted file mode 100644 index 290c56f..0000000 --- a/SOURCES/0055-Manage-Block-unsafe-member-failing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 18 Aug 2022 11:47:21 +0200 -Subject: [PATCH 55/83] Manage: Block unsafe member failing - -Kernel may or may not block mdadm from removing member device if it -will cause arrays failed state. It depends on raid personality -implementation in kernel. -Add verification on requested removal path (#mdadm --set-faulty -command). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 52 insertions(+), 1 deletion(-) - -diff --git a/Manage.c b/Manage.c -index a142f8bd..b1d0e630 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1285,6 +1285,50 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, - return -1; - } - -+/** -+ * is_remove_safe() - Check if remove is safe. -+ * @array: Array info. -+ * @fd: Array file descriptor. -+ * @devname: Name of device to remove. -+ * @verbose: Verbose. -+ * -+ * The function determines if array will be operational -+ * after removing &devname. -+ * -+ * Return: True if array will be operational, false otherwise. -+ */ -+bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose) -+{ -+ dev_t devid = devnm2devid(devname + 5); -+ struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE); -+ -+ if (!mdi) { -+ if (verbose) -+ pr_err("Failed to read sysfs attributes for %s\n", devname); -+ return false; -+ } -+ -+ char *avail = xcalloc(array->raid_disks, sizeof(char)); -+ -+ for (mdi = mdi->devs; mdi; mdi = mdi->next) { -+ if (mdi->disk.raid_disk < 0) -+ continue; -+ if (!(mdi->disk.state & (1 << MD_DISK_SYNC))) -+ continue; -+ if (makedev(mdi->disk.major, mdi->disk.minor) == devid) -+ continue; -+ avail[mdi->disk.raid_disk] = 1; -+ } -+ sysfs_free(mdi); -+ -+ bool is_enough = enough(array->level, array->raid_disks, -+ array->layout, (array->state & 1), -+ avail); -+ -+ free(avail); -+ return is_enough; -+} -+ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - char *update, int force) -@@ -1598,7 +1642,14 @@ int Manage_subdevs(char *devname, int fd, - break; - - case 'f': /* set faulty */ -- /* FIXME check current member */ -+ if (!is_remove_safe(&array, fd, dv->devname, verbose)) { -+ pr_err("Cannot remove %s from %s, array will be failed.\n", -+ dv->devname, devname); -+ if (sysfd >= 0) -+ close(sysfd); -+ goto abort; -+ } -+ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/SOURCES/0055-imsm-refactor-RAID-level-handling.patch b/SOURCES/0055-imsm-refactor-RAID-level-handling.patch new file mode 100644 index 0000000..2e855b2 --- /dev/null +++ b/SOURCES/0055-imsm-refactor-RAID-level-handling.patch @@ -0,0 +1,345 @@ +From 191e6ddb1388236c5c54baf5020a87c996be941f Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:16 +0200 +Subject: [PATCH 55/69] imsm: refactor RAID level handling + +Add imsm_level_ops struct for better handling and unifying raid level +support. Add helper methods and move "orom_has_raid[...]" methods from +header to source file. + +RAID 1e is not supported under Linux, remove RAID 1e associated code. + +Refactor imsm_analyze_change() and is_raid_level_supported(). +Remove hardcoded check for 4 drives and make devNumChange a multiplier +for RAID 10. + +Refactor printing supported raid levels. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 57 ++++++++++++++++++++++++ + platform-intel.h | 32 ++++++-------- + super-intel.c | 111 ++++++++++++++++++++++++++++------------------- + 3 files changed, 138 insertions(+), 62 deletions(-) + +diff --git a/platform-intel.c b/platform-intel.c +index ac282bc5..40e8fb82 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -32,6 +32,63 @@ + + #define NVME_SUBSYS_PATH "/sys/devices/virtual/nvme-subsystem/" + ++static bool imsm_orom_has_raid0(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID0); ++} ++ ++static bool imsm_orom_has_raid1(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID1); ++} ++ ++static bool imsm_orom_has_raid10(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID10); ++} ++ ++static bool imsm_orom_has_raid5(const struct imsm_orom *orom) ++{ ++ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID5); ++} ++ ++/* IMSM platforms do not define how many disks are allowed for each level, ++ * but there are some global limitations we need to follow. ++ */ ++static bool imsm_orom_support_raid_disks_count_raid0(const int raid_disks) ++{ ++ return true; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid1(const int raid_disks) ++{ ++ if (raid_disks == 2) ++ return true; ++ return false; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks) ++{ ++ if (raid_disks > 2) ++ return true; ++ return false; ++} ++ ++static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks) ++{ ++ if (raid_disks == 4) ++ return true; ++ return false; ++} ++ ++struct imsm_level_ops imsm_level_ops[] = { ++ {0, imsm_orom_has_raid0, imsm_orom_support_raid_disks_count_raid0, "raid0"}, ++ {1, imsm_orom_has_raid1, imsm_orom_support_raid_disks_count_raid1, "raid1"}, ++ {5, imsm_orom_has_raid5, imsm_orom_support_raid_disks_count_raid5, "raid5"}, ++ {10, imsm_orom_has_raid10, imsm_orom_support_raid_disks_count_raid10, "raid10"}, ++ {-1, NULL, NULL, NULL} ++}; ++ + static int devpath_to_ll(const char *dev_path, const char *entry, + unsigned long long *val); + +diff --git a/platform-intel.h b/platform-intel.h +index 3c2bc595..dcc5aaa7 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -109,25 +109,21 @@ struct imsm_orom { + #define IMSM_OROM_CAPABILITIES_TPV (1 << 10) + } __attribute__((packed)); + +-static inline int imsm_orom_has_raid0(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID0); +-} +-static inline int imsm_orom_has_raid1(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID1); +-} +-static inline int imsm_orom_has_raid1e(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID1E); +-} +-static inline int imsm_orom_has_raid10(const struct imsm_orom *orom) +-{ +- return !!(orom->rlc & IMSM_OROM_RLC_RAID10); +-} +-static inline int imsm_orom_has_raid5(const struct imsm_orom *orom) ++/* IMSM metadata requirements for each level */ ++struct imsm_level_ops { ++ int level; ++ bool (*is_level_supported)(const struct imsm_orom *); ++ bool (*is_raiddisks_count_supported)(const int); ++ char *name; ++}; ++ ++extern struct imsm_level_ops imsm_level_ops[]; ++ ++static inline bool imsm_rlc_has_bit(const struct imsm_orom *orom, const unsigned short bit) + { +- return !!(orom->rlc & IMSM_OROM_RLC_RAID5); ++ if (orom->rlc & bit) ++ return true; ++ return false; + } + + /** +diff --git a/super-intel.c b/super-intel.c +index a7efc8df..da17265d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2681,6 +2681,15 @@ static int ahci_get_port_count(const char *hba_path, int *port_count) + return host_base; + } + ++static void print_imsm_level_capability(const struct imsm_orom *orom) ++{ ++ int idx; ++ ++ for (idx = 0; imsm_level_ops[idx].name; idx++) ++ if (imsm_level_ops[idx].is_level_supported(orom)) ++ printf("%s ", imsm_level_ops[idx].name); ++} ++ + static void print_imsm_capability(const struct imsm_orom *orom) + { + printf(" Platform : Intel(R) "); +@@ -2699,12 +2708,11 @@ static void print_imsm_capability(const struct imsm_orom *orom) + printf(" Version : %d.%d.%d.%d\n", orom->major_ver, + orom->minor_ver, orom->hotfix_ver, orom->build); + } +- printf(" RAID Levels :%s%s%s%s%s\n", +- imsm_orom_has_raid0(orom) ? " raid0" : "", +- imsm_orom_has_raid1(orom) ? " raid1" : "", +- imsm_orom_has_raid1e(orom) ? " raid1e" : "", +- imsm_orom_has_raid10(orom) ? " raid10" : "", +- imsm_orom_has_raid5(orom) ? " raid5" : ""); ++ ++ printf(" RAID Levels : "); ++ print_imsm_level_capability(orom); ++ printf("\n"); ++ + printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + imsm_orom_has_chunk(orom, 2) ? " 2k" : "", + imsm_orom_has_chunk(orom, 4) ? " 4k" : "", +@@ -2739,12 +2747,11 @@ static void print_imsm_capability_export(const struct imsm_orom *orom) + if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) + printf("IMSM_VERSION=%d.%d.%d.%d\n", orom->major_ver, orom->minor_ver, + orom->hotfix_ver, orom->build); +- printf("IMSM_SUPPORTED_RAID_LEVELS=%s%s%s%s%s\n", +- imsm_orom_has_raid0(orom) ? "raid0 " : "", +- imsm_orom_has_raid1(orom) ? "raid1 " : "", +- imsm_orom_has_raid1e(orom) ? "raid1e " : "", +- imsm_orom_has_raid5(orom) ? "raid10 " : "", +- imsm_orom_has_raid10(orom) ? "raid5 " : ""); ++ ++ printf("IMSM_SUPPORTED_RAID_LEVELS="); ++ print_imsm_level_capability(orom); ++ printf("\n"); ++ + printf("IMSM_SUPPORTED_CHUNK_SIZES=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + imsm_orom_has_chunk(orom, 2) ? "2k " : "", + imsm_orom_has_chunk(orom, 4) ? "4k " : "", +@@ -6992,26 +6999,41 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex + return free_size - reservation_size; + } + +-static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) ++/** ++ * is_raid_level_supported() - check if this count of drives and level is supported by platform. ++ * @orom: hardware properties, could be NULL. ++ * @level: requested raid level. ++ * @raiddisks: requested disk count. ++ * ++ * IMSM UEFI/OROM does not provide information about supported count of raid disks ++ * for particular level. That is why it is hardcoded. ++ * It is recommended to not allow of usage other levels than supported, ++ * IMSM code is not tested against different level implementations. ++ * ++ * Return: true if supported, false otherwise. ++ */ ++static bool is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) + { +- if (level < 0 || level == 6 || level == 4) +- return 0; ++ int idx; + +- /* if we have an orom prevent invalid raid levels */ +- if (orom) +- switch (level) { +- case 0: return imsm_orom_has_raid0(orom); +- case 1: +- if (raiddisks > 2) +- return imsm_orom_has_raid1e(orom); +- return imsm_orom_has_raid1(orom) && raiddisks == 2; +- case 10: return imsm_orom_has_raid10(orom) && raiddisks == 4; +- case 5: return imsm_orom_has_raid5(orom) && raiddisks > 2; +- } +- else +- return 1; /* not on an Intel RAID platform so anything goes */ ++ for (idx = 0; imsm_level_ops[idx].name; idx++) { ++ if (imsm_level_ops[idx].level == level) ++ break; ++ } + +- return 0; ++ if (!imsm_level_ops[idx].name) ++ return false; ++ ++ if (!imsm_level_ops[idx].is_raiddisks_count_supported(raiddisks)) ++ return false; ++ ++ if (!orom) ++ return true; ++ ++ if (imsm_level_ops[idx].is_level_supported(orom)) ++ return true; ++ ++ return false; + } + + static int +@@ -11962,18 +11984,17 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + int change = -1; + int check_devs = 0; + int chunk; +- /* number of added/removed disks in operation result */ +- int devNumChange = 0; + /* imsm compatible layout value for array geometry verification */ + int imsm_layout = -1; ++ int raid_disks = geo->raid_disks; + imsm_status_t rv; + + getinfo_super_imsm_volume(st, &info, NULL); +- if (geo->level != info.array.level && geo->level >= 0 && ++ if (geo->level != info.array.level && geo->level >= IMSM_T_RAID0 && + geo->level != UnSet) { + switch (info.array.level) { +- case 0: +- if (geo->level == 5) { ++ case IMSM_T_RAID0: ++ if (geo->level == IMSM_T_RAID5) { + change = CH_MIGRATION; + if (geo->layout != ALGORITHM_LEFT_ASYMMETRIC) { + pr_err("Error. Requested Layout not supported (left-asymmetric layout is supported only)!\n"); +@@ -11982,20 +12003,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + } + imsm_layout = geo->layout; + check_devs = 1; +- devNumChange = 1; /* parity disk added */ +- } else if (geo->level == 10) { ++ raid_disks += 1; /* parity disk added */ ++ } else if (geo->level == IMSM_T_RAID10) { + change = CH_TAKEOVER; + check_devs = 1; +- devNumChange = 2; /* two mirrors added */ ++ raid_disks *= 2; /* mirrors added */ + imsm_layout = 0x102; /* imsm supported layout */ + } + break; +- case 1: +- case 10: ++ case IMSM_T_RAID1: ++ case IMSM_T_RAID10: + if (geo->level == 0) { + change = CH_TAKEOVER; + check_devs = 1; +- devNumChange = -(geo->raid_disks/2); ++ raid_disks /= 2; + imsm_layout = 0; /* imsm raid0 layout */ + } + break; +@@ -12011,10 +12032,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + if (geo->layout != info.array.layout && + (geo->layout != UnSet && geo->layout != -1)) { + change = CH_MIGRATION; +- if (info.array.layout == 0 && info.array.level == 5 && ++ if (info.array.layout == 0 && info.array.level == IMSM_T_RAID5 && + geo->layout == 5) { + /* reshape 5 -> 4 */ +- } else if (info.array.layout == 5 && info.array.level == 5 && ++ } else if (info.array.layout == 5 && info.array.level == IMSM_T_RAID5 && + geo->layout == 0) { + /* reshape 4 -> 5 */ + geo->layout = 0; +@@ -12033,7 +12054,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + + if (geo->chunksize > 0 && geo->chunksize != UnSet && + geo->chunksize != info.array.chunk_size) { +- if (info.array.level == 10) { ++ if (info.array.level == IMSM_T_RAID10) { + pr_err("Error. Chunk size change for RAID 10 is not supported.\n"); + change = -1; + goto analyse_change_exit; +@@ -12058,14 +12079,16 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + rv = imsm_analyze_expand(st, geo, &info, direction); + if (rv != IMSM_STATUS_OK) + goto analyse_change_exit; ++ raid_disks = geo->raid_disks; + change = CH_ARRAY_SIZE; + } + + chunk = geo->chunksize / 1024; ++ + if (!validate_geometry_imsm(st, + geo->level, + imsm_layout, +- geo->raid_disks + devNumChange, ++ raid_disks, + &chunk, + geo->size, INVALID_SECTORS, + 0, 0, info.consistency_policy, 1)) +-- +2.41.0 + diff --git a/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch b/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch deleted file mode 100644 index ad36a25..0000000 --- a/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001 -From: Pawel Baldysiak -Date: Thu, 1 Sep 2022 11:20:31 +0200 -Subject: [PATCH 56/83] Monitor: Fix statelist memory leaks - -Free statelist in error path in Monitor initialization. - -Signed-off-by: Pawel Baldysiak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 40 +++++++++++++++++++++++++++++++--------- - 1 file changed, 31 insertions(+), 9 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 93f36ac0..b4e954c6 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - int test, struct alert_info *info); - static void try_spare_migration(struct state *statelist, struct alert_info *info); - static void link_containers_with_subarrays(struct state *list); -+static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -@@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist, - */ - - struct state *statelist = NULL; -- struct state *st2; - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -@@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ if (!is_mddev(mdlist->devname)) { -+ free_statelist(statelist); -+ return 1; -+ } - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), - "/dev/md/%s", basename(mdlist->devname)); -- if (!is_mddev(mdlist->devname)) -- return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) -+ if (!is_mddev(dv->devname)) { -+ free_statelist(statelist); - return 1; -+ } - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -@@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->spare_group); -+ if (st->spare_group) -+ free(st->spare_group); -+ - free(st); - } else - stp = &st->next; - } - } -- for (st2 = statelist; st2; st2 = statelist) { -- statelist = st2->next; -- free(st2); -- } -+ -+ free_statelist(statelist); - - if (pidfile) - unlink(pidfile); -@@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list) - } - } - -+/** -+ * free_statelist() - Frees statelist. -+ * @statelist: statelist to free -+ */ -+static void free_statelist(struct state *statelist) -+{ -+ struct state *tmp = NULL; -+ -+ while (statelist) { -+ if (statelist->spare_group) -+ free(statelist->spare_group); -+ -+ tmp = statelist; -+ statelist = statelist->next; -+ free(tmp); -+ } -+} -+ - #ifndef NO_LIBUDEV - /* function: check_udev_activity - * Description: Function waits for udev to finish --- -2.38.1 - diff --git a/SOURCES/0056-imsm-bump-minimal-version.patch b/SOURCES/0056-imsm-bump-minimal-version.patch new file mode 100644 index 0000000..5ce8ed6 --- /dev/null +++ b/SOURCES/0056-imsm-bump-minimal-version.patch @@ -0,0 +1,180 @@ +From ec7e873ba6643a9e5e74311b00ede66a3d2e36c9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:17 +0200 +Subject: [PATCH 56/69] imsm: bump minimal version + +IMSM version 1.3 (called ATTRIBS) brought attributes used to define array +properties which require support in driver. The goal of this change was +to avoid changing version when adding new features. + +For some reasons migration has never been completed and currently (after +10 years of implementing) IMSM can use older versions. + +It is right time to finally switch it. There is no point in using old +versions, use 1.3.00 as minimal one. + +Define JD_VERSION used by Windows driver. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 87 ++++++++++++++++++++++----------------------------- + 1 file changed, 38 insertions(+), 49 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index da17265d..4b168add 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -32,14 +32,19 @@ + /* MPB == Metadata Parameter Block */ + #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " + #define MPB_SIG_LEN (strlen(MPB_SIGNATURE)) +-#define MPB_VERSION_RAID0 "1.0.00" +-#define MPB_VERSION_RAID1 "1.1.00" +-#define MPB_VERSION_MANY_VOLUMES_PER_ARRAY "1.2.00" +-#define MPB_VERSION_3OR4_DISK_ARRAY "1.2.01" +-#define MPB_VERSION_RAID5 "1.2.02" +-#define MPB_VERSION_5OR6_DISK_ARRAY "1.2.04" +-#define MPB_VERSION_CNG "1.2.06" ++ ++/* Legacy IMSM versions: ++ * MPB_VERSION_RAID0 1.0.00 ++ * MPB_VERSION_RAID1 1.1.00 ++ * MPB_VERSION_MANY_VOLUMES_PER_ARRAY 1.2.00 ++ * MPB_VERSION_3OR4_DISK_ARRAY 1.2.01 ++ * MPB_VERSION_RAID5 1.2.02 ++ * MPB_VERSION_5OR6_DISK_ARRAY 1.2.04 ++ * MPB_VERSION_CNG 1.2.06 ++ */ ++ + #define MPB_VERSION_ATTRIBS "1.3.00" ++#define MPB_VERSION_ATTRIBS_JD "2.0.00" + #define MAX_SIGNATURE_LENGTH 32 + #define MAX_RAID_SERIAL_LEN 16 + +@@ -5512,51 +5517,46 @@ static unsigned long long info_to_blocks_per_member(mdu_array_info_t *info, + return (size * 2) & ~(info_to_blocks_per_strip(info) - 1); + } + ++static void imsm_write_signature(struct imsm_super *mpb) ++{ ++ /* It is safer to eventually truncate version rather than left it not NULL ended */ ++ snprintf((char *) mpb->sig, MAX_SIGNATURE_LENGTH, MPB_SIGNATURE MPB_VERSION_ATTRIBS); ++} ++ + static void imsm_update_version_info(struct intel_super *super) + { + /* update the version and attributes */ + struct imsm_super *mpb = super->anchor; +- char *version; + struct imsm_dev *dev; + struct imsm_map *map; + int i; + ++ mpb->attributes |= MPB_ATTRIB_CHECKSUM_VERIFY; ++ + for (i = 0; i < mpb->num_raid_devs; i++) { + dev = get_imsm_dev(super, i); + map = get_imsm_map(dev, MAP_0); ++ + if (__le32_to_cpu(dev->size_high) > 0) + mpb->attributes |= MPB_ATTRIB_2TB; + +- /* FIXME detect when an array spans a port multiplier */ +- #if 0 +- mpb->attributes |= MPB_ATTRIB_PM; +- #endif +- +- if (mpb->num_raid_devs > 1 || +- mpb->attributes != MPB_ATTRIB_CHECKSUM_VERIFY) { +- version = MPB_VERSION_ATTRIBS; +- switch (get_imsm_raid_level(map)) { +- case 0: mpb->attributes |= MPB_ATTRIB_RAID0; break; +- case 1: mpb->attributes |= MPB_ATTRIB_RAID1; break; +- case 10: mpb->attributes |= MPB_ATTRIB_RAID10; break; +- case 5: mpb->attributes |= MPB_ATTRIB_RAID5; break; +- } +- } else { +- if (map->num_members >= 5) +- version = MPB_VERSION_5OR6_DISK_ARRAY; +- else if (dev->status == DEV_CLONE_N_GO) +- version = MPB_VERSION_CNG; +- else if (get_imsm_raid_level(map) == 5) +- version = MPB_VERSION_RAID5; +- else if (map->num_members >= 3) +- version = MPB_VERSION_3OR4_DISK_ARRAY; +- else if (get_imsm_raid_level(map) == 1) +- version = MPB_VERSION_RAID1; +- else +- version = MPB_VERSION_RAID0; ++ switch (get_imsm_raid_level(map)) { ++ case IMSM_T_RAID0: ++ mpb->attributes |= MPB_ATTRIB_RAID0; ++ break; ++ case IMSM_T_RAID1: ++ mpb->attributes |= MPB_ATTRIB_RAID1; ++ break; ++ case IMSM_T_RAID5: ++ mpb->attributes |= MPB_ATTRIB_RAID5; ++ break; ++ case IMSM_T_RAID10: ++ mpb->attributes |= MPB_ATTRIB_RAID10; ++ break; + } +- strcpy(((char *) mpb->sig) + strlen(MPB_SIGNATURE), version); + } ++ ++ imsm_write_signature(mpb); + } + + /** +@@ -5785,7 +5785,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + struct intel_super *super; + struct imsm_super *mpb; + size_t mpb_size; +- char *version; + + if (data_offset != INVALID_SECTORS) { + pr_err("data-offset not supported by imsm\n"); +@@ -5828,13 +5827,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + return 0; + } + +- mpb->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; +- +- version = (char *) mpb->sig; +- strcpy(version, MPB_SIGNATURE); +- version += strlen(MPB_SIGNATURE); +- strcpy(version, MPB_VERSION_RAID0); +- ++ imsm_update_version_info(super); + return 1; + } + +@@ -6208,7 +6201,6 @@ static union { + + static int write_super_imsm_spare(struct intel_super *super, struct dl *d) + { +- struct imsm_super *mpb = super->anchor; + struct imsm_super *spare = &spare_record.anchor; + __u32 sum; + +@@ -6217,14 +6209,11 @@ static int write_super_imsm_spare(struct intel_super *super, struct dl *d) + + spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)); + spare->generation_num = __cpu_to_le32(1UL); +- spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; + spare->num_disks = 1; + spare->num_raid_devs = 0; +- spare->cache_size = mpb->cache_size; + spare->pwr_cycle_count = __cpu_to_le32(1); + +- snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH, +- MPB_SIGNATURE MPB_VERSION_RAID0); ++ imsm_write_signature(spare); + + spare->disk[0] = d->disk; + if (__le32_to_cpu(d->disk.total_blocks_hi) > 0) +-- +2.41.0 + diff --git a/SOURCES/0057-imsm-define-RAID_10-attribute.patch b/SOURCES/0057-imsm-define-RAID_10-attribute.patch new file mode 100644 index 0000000..fc6f152 --- /dev/null +++ b/SOURCES/0057-imsm-define-RAID_10-attribute.patch @@ -0,0 +1,67 @@ +From 610fc2ee6fc09e828b14e8fa221b3f4f70fc7b2b Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:18 +0200 +Subject: [PATCH 57/69] imsm: define RAID_10 attribute + +Add MPB_ATTRIB_RAID10_EXT attribute to support RAID 10 +with more than 4 drives. + +Allow more than 4 drives in imsm_orom_support_raid_disks_raid10(). + +This is one of last patches for introducing R10D4+ to imsm. +Only small adjustments in reshape behaviours are needed. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 3 ++- + super-intel.c | 5 +++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 40e8fb82..15a9fa5a 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -76,7 +76,8 @@ static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks) + + static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks) + { +- if (raid_disks == 4) ++ /* raid_disks count must be higher than 4 and even */ ++ if (raid_disks >= 4 && (raid_disks & 1) == 0) + return true; + return false; + } +diff --git a/super-intel.c b/super-intel.c +index 4b168add..2d309316 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -62,6 +62,8 @@ + #define MPB_ATTRIB_RAIDCNG __cpu_to_le32(0x00000020) + /* supports expanded stripe sizes of 256K, 512K and 1MB */ + #define MPB_ATTRIB_EXP_STRIPE_SIZE __cpu_to_le32(0x00000040) ++/* supports RAID10 with more than 4 drives */ ++#define MPB_ATTRIB_RAID10_EXT __cpu_to_le32(0x00000080) + + /* The OROM Support RST Caching of Volumes */ + #define MPB_ATTRIB_NVM __cpu_to_le32(0x02000000) +@@ -89,6 +91,7 @@ + MPB_ATTRIB_RAID10 | \ + MPB_ATTRIB_RAID5 | \ + MPB_ATTRIB_EXP_STRIPE_SIZE | \ ++ MPB_ATTRIB_RAID10_EXT | \ + MPB_ATTRIB_BBM) + + /* Define attributes that are unused but not harmful */ +@@ -5552,6 +5555,8 @@ static void imsm_update_version_info(struct intel_super *super) + break; + case IMSM_T_RAID10: + mpb->attributes |= MPB_ATTRIB_RAID10; ++ if (map->num_members > 4) ++ mpb->attributes |= MPB_ATTRIB_RAID10_EXT; + break; + } + } +-- +2.41.0 + diff --git a/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch b/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch deleted file mode 100644 index 79a3262..0000000 --- a/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ea7a02a3294aae223e1329aed5da7f4aa3ac05c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= -Date: Wed, 31 Aug 2022 19:57:29 +0200 -Subject: [PATCH 57/83] mdadm: added support for Intel Alderlake RST on VMD - platform -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Alderlake RST on VMD uses RstVmdV UEFI variable name, so detect it. - -Signed-off-by: Oldřich Jedlička -Reviewed-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index 5a8729e7..757f0b1b 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -512,7 +512,8 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) - #define AHCI_PROP "RstSataV" - #define AHCI_SSATA_PROP "RstsSatV" - #define AHCI_TSATA_PROP "RsttSatV" --#define VMD_PROP "RstUefiV" -+#define VROC_VMD_PROP "RstUefiV" -+#define RST_VMD_PROP "RstVmdV" - - #define VENDOR_GUID \ - EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) -@@ -605,6 +606,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - struct orom_entry *ret; - static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP, - AHCI_TSATA_PROP}; -+ static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP}; - unsigned long i; - - if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) -@@ -636,10 +638,16 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - - break; - case SYS_DEV_VMD: -- if (!read_efi_variable(&orom, sizeof(orom), VMD_PROP, -- VENDOR_GUID)) -- break; -- return NULL; -+ for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { -+ if (!read_efi_variable(&orom, sizeof(orom), -+ vmd_efivars[i], VENDOR_GUID)) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(vmd_efivars)) -+ return NULL; -+ -+ break; - default: - return NULL; - } --- -2.38.1 - diff --git a/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch b/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch new file mode 100644 index 0000000..e822557 --- /dev/null +++ b/SOURCES/0058-imsm-simplify-imsm_check_attributes.patch @@ -0,0 +1,153 @@ +From e0e56f4b2ed514f5049eb96b4ff8f7fdf30a4c49 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:19 +0200 +Subject: [PATCH 58/69] imsm: simplify imsm_check_attributes() + +imsm_check_attributes() is too complex for that it really does. + +Remove repeating code and simplify the function. +Fix function calls. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + super-intel.c | 106 ++++++++------------------------------------------ + 1 file changed, 16 insertions(+), 90 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 2d309316..d60915e8 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2135,91 +2135,18 @@ void convert_from_4k(struct intel_super *super) + mpb->check_sum = __gen_imsm_checksum(mpb); + } + +-/******************************************************************************* +- * function: imsm_check_attributes +- * Description: Function checks if features represented by attributes flags +- * are supported by mdadm. +- * Parameters: +- * attributes - Attributes read from metadata +- * Returns: +- * 0 - passed attributes contains unsupported features flags +- * 1 - all features are supported +- ******************************************************************************/ +-static int imsm_check_attributes(__u32 attributes) ++/** ++ * imsm_check_attributes() - Check if features represented by attributes flags are supported. ++ * ++ * @attributes: attributes read from metadata. ++ * Returns: true if all features are supported, false otherwise. ++ */ ++static bool imsm_check_attributes(__u32 attributes) + { +- int ret_val = 1; +- __u32 not_supported = MPB_ATTRIB_SUPPORTED^0xffffffff; +- +- not_supported &= ~MPB_ATTRIB_IGNORED; +- +- not_supported &= attributes; +- if (not_supported) { +- pr_err("(IMSM): Unsupported attributes : %x\n", +- (unsigned)__le32_to_cpu(not_supported)); +- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) { +- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY \n"); +- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY; +- } +- if (not_supported & MPB_ATTRIB_2TB) { +- dprintf("\t\tMPB_ATTRIB_2TB\n"); +- not_supported ^= MPB_ATTRIB_2TB; +- } +- if (not_supported & MPB_ATTRIB_RAID0) { +- dprintf("\t\tMPB_ATTRIB_RAID0\n"); +- not_supported ^= MPB_ATTRIB_RAID0; +- } +- if (not_supported & MPB_ATTRIB_RAID1) { +- dprintf("\t\tMPB_ATTRIB_RAID1\n"); +- not_supported ^= MPB_ATTRIB_RAID1; +- } +- if (not_supported & MPB_ATTRIB_RAID10) { +- dprintf("\t\tMPB_ATTRIB_RAID10\n"); +- not_supported ^= MPB_ATTRIB_RAID10; +- } +- if (not_supported & MPB_ATTRIB_RAID1E) { +- dprintf("\t\tMPB_ATTRIB_RAID1E\n"); +- not_supported ^= MPB_ATTRIB_RAID1E; +- } +- if (not_supported & MPB_ATTRIB_RAID5) { +- dprintf("\t\tMPB_ATTRIB_RAID5\n"); +- not_supported ^= MPB_ATTRIB_RAID5; +- } +- if (not_supported & MPB_ATTRIB_RAIDCNG) { +- dprintf("\t\tMPB_ATTRIB_RAIDCNG\n"); +- not_supported ^= MPB_ATTRIB_RAIDCNG; +- } +- if (not_supported & MPB_ATTRIB_BBM) { +- dprintf("\t\tMPB_ATTRIB_BBM\n"); +- not_supported ^= MPB_ATTRIB_BBM; +- } +- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) { +- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY (== MPB_ATTRIB_LEGACY)\n"); +- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY; +- } +- if (not_supported & MPB_ATTRIB_EXP_STRIPE_SIZE) { +- dprintf("\t\tMPB_ATTRIB_EXP_STRIP_SIZE\n"); +- not_supported ^= MPB_ATTRIB_EXP_STRIPE_SIZE; +- } +- if (not_supported & MPB_ATTRIB_2TB_DISK) { +- dprintf("\t\tMPB_ATTRIB_2TB_DISK\n"); +- not_supported ^= MPB_ATTRIB_2TB_DISK; +- } +- if (not_supported & MPB_ATTRIB_NEVER_USE2) { +- dprintf("\t\tMPB_ATTRIB_NEVER_USE2\n"); +- not_supported ^= MPB_ATTRIB_NEVER_USE2; +- } +- if (not_supported & MPB_ATTRIB_NEVER_USE) { +- dprintf("\t\tMPB_ATTRIB_NEVER_USE\n"); +- not_supported ^= MPB_ATTRIB_NEVER_USE; +- } +- +- if (not_supported) +- dprintf("(IMSM): Unknown attributes : %x\n", not_supported); +- +- ret_val = 0; +- } ++ if ((attributes & (MPB_ATTRIB_SUPPORTED | MPB_ATTRIB_IGNORED)) == attributes) ++ return true; + +- return ret_val; ++ return false; + } + + static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map); +@@ -2247,11 +2174,10 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + creation_time = __le64_to_cpu(mpb->creation_time); + printf(" Creation Time : %.24s\n", + creation_time ? ctime(&creation_time) : "Unknown"); +- printf(" Attributes : "); +- if (imsm_check_attributes(mpb->attributes)) +- printf("All supported\n"); +- else +- printf("not supported\n"); ++ ++ printf(" Attributes : %08x (%s)\n", mpb->attributes, ++ imsm_check_attributes(mpb->attributes) ? "supported" : "not supported"); ++ + getinfo_super_imsm(st, &info, NULL); + fname_from_uuid(&info, nbuf); + printf(" UUID : %s\n", nbuf + 5); +@@ -8182,9 +8108,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + int current_vol = super->current_vol; + + /* do not assemble arrays when not all attributes are supported */ +- if (imsm_check_attributes(mpb->attributes) == 0) { ++ if (imsm_check_attributes(mpb->attributes) == false) { + sb_errors = 1; +- pr_err("Unsupported attributes in IMSM metadata.Arrays activation is blocked.\n"); ++ pr_err("Unsupported attributes in IMSM metadata. Arrays activation is blocked.\n"); + } + + /* count spare devices, not used in maps +-- +2.41.0 + diff --git a/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch b/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch deleted file mode 100644 index 6e1a179..0000000 --- a/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch +++ /dev/null @@ -1,111 +0,0 @@ -From ea109700563d93704ebdc540c7770d874369f667 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:33 +0200 -Subject: [PATCH 58/83] mdadm: Add Documentation entries to systemd services - -Add documentation section. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdadm-last-resort@.service | 1 + - systemd/mdcheck_continue.service | 3 ++- - systemd/mdcheck_start.service | 1 + - systemd/mdmon@.service | 1 + - systemd/mdmonitor-oneshot.service | 1 + - systemd/mdmonitor.service | 1 + - 7 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9fdc8ec7..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -8,6 +8,7 @@ - [Unit] - Description=Manage MD Reshape on /dev/%I - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - ExecStart=BINDIR/mdadm --grow --continue /dev/%I -diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service -index efeb3f63..e9381125 100644 ---- a/systemd/mdadm-last-resort@.service -+++ b/systemd/mdadm-last-resort@.service -@@ -2,6 +2,7 @@ - Description=Activate md array %I even though degraded - DefaultDependencies=no - ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index 854317f1..f5324905 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -7,7 +7,8 @@ - - [Unit] - Description=MD array scrubbing - continuation --ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* -+ConditionPathExistsGlob=/var/lib/mdcheck/MD_UUID_* -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 3bb3d130..703a6583 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array scrubbing - Wants=mdcheck_continue.timer -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 77533958..97a1acd9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -9,6 +9,7 @@ - Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target -+Documentation=man:mdmon(8) - - [Service] - # mdmon should never complain due to lack of a platform, -diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service -index 373955a2..ba86b44e 100644 ---- a/systemd/mdmonitor-oneshot.service -+++ b/systemd/mdmonitor-oneshot.service -@@ -7,6 +7,7 @@ - - [Unit] - Description=Reminder for degraded MD arrays -+Documentation=man:mdadm(8) - - [Service] - Environment=MDADM_MONITOR_ARGS=--scan -diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service -index 46f7b880..9c364785 100644 ---- a/systemd/mdmonitor.service -+++ b/systemd/mdmonitor.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array monitor - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - Environment= MDADM_MONITOR_ARGS=--scan --- -2.38.1 - diff --git a/SOURCES/0059-ReadMe-fix-command-line-help.patch b/SOURCES/0059-ReadMe-fix-command-line-help.patch deleted file mode 100644 index 837a339..0000000 --- a/SOURCES/0059-ReadMe-fix-command-line-help.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f7cbd810b639eb946ba1b3bddb1faefb9696de42 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:34 +0200 -Subject: [PATCH 59/83] ReadMe: fix command-line help - -Make command-line help consistent with manual page. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7f94847e..50a5e36d 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -477,7 +477,7 @@ char Help_assemble[] = - ; - - char Help_manage[] = --"Usage: mdadm arraydevice options component devices...\n" -+"Usage: mdadm [mode] arraydevice [options] \n" - "\n" - "This usage is for managing the component devices within an array.\n" - "The --manage option is not needed and is assumed if the first argument\n" --- -2.38.1 - diff --git a/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch b/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch new file mode 100644 index 0000000..1a5e642 --- /dev/null +++ b/SOURCES/0059-imsm-support-RAID-10-with-more-than-4-drives.patch @@ -0,0 +1,168 @@ +From 44463edeb303a464c4a44fcea184b267aeb53302 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 29 Apr 2024 15:07:20 +0200 +Subject: [PATCH 59/69] imsm: support RAID 10 with more than 4 drives + +VROC UEFI driver does not support RAID 10 with more than 4 drives. +Add user prompts if such layout is being created and for R0->R10 +reshapes. + +Refactor ask() function: +- simplify the code, +- remove dialog reattempts, +- do no pass '?' sign on function calls, +- highlight default option on output. + +This patch completes adding support for R10D4+ to IMSM. + +Signed-off-by: Mateusz Kusiak +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 9 ++++++++- + super-intel.c | 14 ++++++++++++-- + util.c | 39 +++++++++++++++++++++++++-------------- + 3 files changed, 45 insertions(+), 17 deletions(-) + +diff --git a/Create.c b/Create.c +index d94253b1..d033eb68 100644 +--- a/Create.c ++++ b/Create.c +@@ -965,6 +965,13 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + return 1; + } + ++ if (st->ss == &super_imsm && s->level == 10 && s->raiddisks > 4) { ++ /* Print no matter runstop was specifed */ ++ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n"); ++ pr_err("Array won't be suitable as boot device.\n"); ++ warn = 1; ++ } ++ + if (!have_container && s->level > 0 && ((maxsize-s->size)*100 > maxsize)) { + if (c->runstop != 1 || c->verbose >= 0) + pr_err("largest drive (%s) exceeds size (%lluK) by more than 1%%\n", +@@ -984,7 +991,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, + + if (warn) { + if (c->runstop!= 1) { +- if (!ask("Continue creating array? ")) { ++ if (!ask("Continue creating array")) { + pr_err("create aborted.\n"); + return 1; + } +diff --git a/super-intel.c b/super-intel.c +index d60915e8..2b8b6fda 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -523,6 +523,7 @@ enum imsm_reshape_type { + CH_TAKEOVER, + CH_MIGRATION, + CH_ARRAY_SIZE, ++ CH_ABORT + }; + + /* definition of messages passed to imsm_process_update */ +@@ -11898,7 +11899,7 @@ success: + ****************************************************************************/ + enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + struct geo_params *geo, +- int direction) ++ int direction, struct context *c) + { + struct mdinfo info; + int change = -1; +@@ -11925,6 +11926,14 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, + check_devs = 1; + raid_disks += 1; /* parity disk added */ + } else if (geo->level == IMSM_T_RAID10) { ++ if (geo->level == IMSM_T_RAID10 && geo->raid_disks > 2 && ++ !c->force) { ++ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n"); ++ pr_err("Array won't be suitable as boot device.\n"); ++ pr_err("Note: You can omit this check with \"--force\"\n"); ++ if (ask("Do you want to continue") < 1) ++ return CH_ABORT; ++ } + change = CH_TAKEOVER; + check_devs = 1; + raid_disks *= 2; /* mirrors added */ +@@ -12219,7 +12228,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct + goto exit_imsm_reshape_super; + } + super->current_vol = dev->index; +- change = imsm_analyze_change(st, &geo, shape->direction); ++ change = imsm_analyze_change(st, &geo, shape->direction, c); + switch (change) { + case CH_TAKEOVER: + ret_val = imsm_takeover(st, &geo); +@@ -12262,6 +12271,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct + free(u); + } + break; ++ case CH_ABORT: + default: + ret_val = 1; + } +diff --git a/util.c b/util.c +index 9e837045..4fbf11c4 100644 +--- a/util.c ++++ b/util.c +@@ -725,23 +725,33 @@ int stat_is_blkdev(char *devname, dev_t *rdev) + return 1; + } + ++/** ++ * ask() - prompt user for "yes/no" dialog. ++ * @mesg: message to be printed, without '?' sign. ++ * Returns: 1 if 'Y/y', 0 otherwise. ++ * ++ * The default value is 'N/n', thus the caps on "N" on prompt. ++ */ + int ask(char *mesg) + { +- char *add = ""; +- int i; +- for (i = 0; i < 5; i++) { +- char buf[100]; +- fprintf(stderr, "%s%s", mesg, add); +- fflush(stderr); +- if (fgets(buf, 100, stdin)==NULL) +- return 0; +- if (buf[0]=='y' || buf[0]=='Y') +- return 1; +- if (buf[0]=='n' || buf[0]=='N') +- return 0; +- add = "(y/n) "; ++ char buf[3] = {0}; ++ ++ fprintf(stderr, "%s [y/N]? ", mesg); ++ fflush(stderr); ++ if (fgets(buf, 3, stdin) == NULL) ++ return 0; ++ if (strlen(buf) == 1) { ++ pr_err("assuming no.\n"); ++ return 0; + } +- pr_err("assuming 'no'\n"); ++ if (buf[1] != '\n') ++ goto bad_option; ++ if (toupper(buf[0]) == 'Y') ++ return 1; ++ if (toupper(buf[0]) == 'N') ++ return 0; ++bad_option: ++ pr_err("bad option.\n"); + return 0; + } + +@@ -1868,6 +1878,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + + if (st->ss->external) + return sysfs_set_array(info); ++ + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; + inf.minor_version = info->array.minor_version; +-- +2.41.0 + diff --git a/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch b/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch deleted file mode 100644 index 7b2b6b2..0000000 --- a/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 6f2af6a48c541f207cb727a31fb86de2cd04fc21 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 2 Sep 2022 08:49:23 +0200 -Subject: [PATCH 60/83] mdadm: replace container level checking with inline - -To unify all containers checks in code, is_container() function is -added and propagated. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 +++---- - Create.c | 6 +++--- - Grow.c | 6 +++--- - Incremental.c | 4 ++-- - mdadm.h | 14 ++++++++++++++ - super-ddf.c | 6 +++--- - super-intel.c | 4 ++-- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 2 +- - 10 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 1dd82a8c..8b0af0c9 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1120,7 +1120,7 @@ static int start_array(int mdfd, - i/2, mddev); - } - -- if (content->array.level == LEVEL_CONTAINER) { -+ if (is_container(content->array.level)) { - sysfs_rules_apply(mddev, content); - if (c->verbose >= 0) { - pr_err("Container %s has been assembled with %d drive%s", -@@ -1549,8 +1549,7 @@ try_again: - */ - trustworthy = LOCAL; - -- if (name[0] == 0 && -- content->array.level == LEVEL_CONTAINER) { -+ if (!name[0] && is_container(content->array.level)) { - name = content->text_version; - trustworthy = METADATA; - } -@@ -1809,7 +1808,7 @@ try_again: - } - #endif - } -- if (c->force && !clean && content->array.level != LEVEL_CONTAINER && -+ if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", -diff --git a/Create.c b/Create.c -index e06ec2ae..953e7372 100644 ---- a/Create.c -+++ b/Create.c -@@ -487,7 +487,7 @@ int Create(struct supertype *st, char *mddev, - st->minor_version >= 1) - /* metadata at front */ - warn |= check_partitions(fd, dname, 0, 0); -- else if (s->level == 1 || s->level == LEVEL_CONTAINER || -+ else if (s->level == 1 || is_container(s->level) || - (s->level == 0 && s->raiddisks == 1)) - /* partitions could be meaningful */ - warn |= check_partitions(fd, dname, freesize*2, s->size*2); -@@ -997,7 +997,7 @@ int Create(struct supertype *st, char *mddev, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && s->level != LEVEL_CONTAINER && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info.uuid, 0)) { - map_update(&map, fd2devnm(mdfd), - info_new.text_version, -@@ -1040,7 +1040,7 @@ int Create(struct supertype *st, char *mddev, - map_unlock(&map); - free(infos); - -- if (s->level == LEVEL_CONTAINER) { -+ if (is_container(s->level)) { - /* No need to start. But we should signal udev to - * create links */ - sysfs_uevent(&info, "change"); -diff --git a/Grow.c b/Grow.c -index 0f07a894..e362403a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2175,7 +2175,7 @@ size_change_error: - devname, s->size); - } - changed = 1; -- } else if (array.level != LEVEL_CONTAINER) { -+ } else if (!is_container(array.level)) { - s->size = get_component_size(fd)/2; - if (s->size == 0) - s->size = array.size; -@@ -2231,7 +2231,7 @@ size_change_error: - info.component_size = s->size*2; - info.new_level = s->level; - info.new_chunk = s->chunk * 1024; -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - info.delta_disks = UnSet; - info.array.raid_disks = s->raiddisks; - } else if (s->raiddisks) -@@ -2344,7 +2344,7 @@ size_change_error: - printf("layout for %s set to %d\n", - devname, array.layout); - } -- } else if (array.level == LEVEL_CONTAINER) { -+ } else if (is_container(array.level)) { - /* This change is to be applied to every array in the - * container. This is only needed when the metadata imposes - * restraints of the various arrays in the container. -diff --git a/Incremental.c b/Incremental.c -index 4d0cd9d6..5a5f4c4c 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -244,7 +244,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - c->autof = ci->autof; - - name_to_use = info.name; -- if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) { -+ if (name_to_use[0] == 0 && is_container(info.array.level)) { - name_to_use = info.text_version; - trustworthy = METADATA; - } -@@ -472,7 +472,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - - /* 7/ Is there enough devices to possibly start the array? */ - /* 7a/ if not, finish with success. */ -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - char devnm[32]; - /* Try to assemble within the container */ - sysfs_uevent(sra, "change"); -diff --git a/mdadm.h b/mdadm.h -index 941a5f38..3673494e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1924,3 +1924,17 @@ enum r0layout { - * This is true for native and DDF, IMSM allows 16. - */ - #define MD_NAME_MAX 32 -+ -+/** -+ * is_container() - check if @level is &LEVEL_CONTAINER -+ * @level: level value -+ * -+ * return: -+ * 1 if level is equal to &LEVEL_CONTAINER, 0 otherwise. -+ */ -+static inline int is_container(const int level) -+{ -+ if (level == LEVEL_CONTAINER) -+ return 1; -+ return 0; -+} -diff --git a/super-ddf.c b/super-ddf.c -index 949e7d15..9d1e3b94 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3325,7 +3325,7 @@ validate_geometry_ddf_container(struct supertype *st, - int fd; - unsigned long long ldsize; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -3371,7 +3371,7 @@ static int validate_geometry_ddf(struct supertype *st, - - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - /* Must be a fresh device to add to a container */ - return validate_geometry_ddf_container(st, level, raiddisks, - data_offset, dev, -@@ -3488,7 +3488,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, - struct dl *dl; - unsigned long long maxsize; - /* ddf/bvd supports lots of things, but not containers */ -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("DDF cannot create a container within an container\n"); - return 0; -diff --git a/super-intel.c b/super-intel.c -index 4d82af3d..b0565610 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6727,7 +6727,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, - struct intel_super *super = NULL; - int rv = 0; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -7692,7 +7692,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - * if given unused devices create a container - * if given given devices in a container create a member volume - */ -- if (level == LEVEL_CONTAINER) -+ if (is_container(level)) - /* Must be a fresh device to add to a container */ - return validate_geometry_imsm_container(st, level, raiddisks, - data_offset, dev, -diff --git a/super0.c b/super0.c -index 37f595ed..93876e2e 100644 ---- a/super0.c -+++ b/super0.c -@@ -1273,7 +1273,7 @@ static int validate_geometry0(struct supertype *st, int level, - if (get_linux_version() < 3001000) - tbmax = 2; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("0.90 metadata does not support containers\n"); - return 0; -diff --git a/super1.c b/super1.c -index 58345e68..0b505a7e 100644 ---- a/super1.c -+++ b/super1.c -@@ -2830,7 +2830,7 @@ static int validate_geometry1(struct supertype *st, int level, - unsigned long long overhead; - int fd; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("1.x metadata does not support containers\n"); - return 0; -diff --git a/sysfs.c b/sysfs.c -index 0d98a65f..ca1d888f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -763,7 +763,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) - - rv = sysfs_set_num(sra, sd, "offset", sd->data_offset); - rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2); -- if (sra->array.level != LEVEL_CONTAINER) { -+ if (!is_container(sra->array.level)) { - if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) { - rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector); - rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size); --- -2.38.1 - diff --git a/SOURCES/0060-tests-01r5fail-enhance.patch b/SOURCES/0060-tests-01r5fail-enhance.patch new file mode 100644 index 0000000..8d2c464 --- /dev/null +++ b/SOURCES/0060-tests-01r5fail-enhance.patch @@ -0,0 +1,41 @@ +From d399c494c6364a6b6d0f965c08443fdc79d1e248 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:19 +0800 +Subject: [PATCH 60/69] tests/01r5fail enhance + +After removing dev0, the recovery starts because it already has a spare +disk. It's good to check recovery. But it's not right to check recovery +after adding dev3. Because the recovery may finish. It depends on the +recovery performance of the testing machine. If the recovery finishes, +it will fail. But dev3 is only added as a spare disk, we can't expect +there is a recovery happens. + +So remove the codes about adding dev3. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01r5fail | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/tests/01r5fail b/tests/01r5fail +index 873dba58..c210d6e7 100644 +--- a/tests/01r5fail ++++ b/tests/01r5fail +@@ -17,11 +17,7 @@ check wait + mdadm $md0 --fail $dev0 + mdadm $md0 --remove $dev3 $dev0 + check recovery +-check state _UUU +- +-mdadm $md0 -a $dev3 +-check recovery + check wait + check state UUUU + +-mdadm -S $md0 +\ No newline at end of file ++mdadm -S $md0 +-- +2.41.0 + diff --git a/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch b/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch deleted file mode 100644 index 062ecdf..0000000 --- a/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8b668d4aa3305af5963162b7499b128bd71f8f29 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Thu, 22 Sep 2022 08:29:50 +0200 -Subject: [PATCH 61/83] Mdmonitor: Omit non-md devices - -Fix segfault commit [1] introduced check whether given device is -mddevice, but it happend to terminate Mdmonitor if at least one of given -devices didn't fulfill that condition. In result Mdmonitor service was -no longer started on boot (with --scan option) when config contained some -non-existent array entry. - -This commit introduces ommiting non-md devices so scan option can still -be used when config is wrong and allow Mdmonitor service to run on boot. - -Giving a list of devices to monitor containing non-existing or -non-md devices will result in monitoring only confirmed mddevices. - -[1] https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=e702f392959d1c2ad2089e595b52235ed97b4e18 - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index b4e954c6..7d7dc4d2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -185,10 +185,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -- if (!is_mddev(mdlist->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(mdlist->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -@@ -208,10 +206,8 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(dv->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); --- -2.38.1 - diff --git a/SOURCES/0061-tests-01r5integ.broken.patch b/SOURCES/0061-tests-01r5integ.broken.patch new file mode 100644 index 0000000..04856bc --- /dev/null +++ b/SOURCES/0061-tests-01r5integ.broken.patch @@ -0,0 +1,32 @@ +From a20cb3872c02241e4f0f7cc26933a43bac7d1cbb Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:20 +0800 +Subject: [PATCH 61/69] tests/01r5integ.broken + +01r5integ can be run successfully 152 times without error with +kernel 6.9.0-rc4 and mdadm - v4.3-51-g52bead95. So remove this +one broken case. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01r5integ.broken | 7 ------- + 1 file changed, 7 deletions(-) + delete mode 100644 tests/01r5integ.broken + +diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken +deleted file mode 100644 +index 20737637..00000000 +--- a/tests/01r5integ.broken ++++ /dev/null +@@ -1,7 +0,0 @@ +-fails rarely +- +-Fails about 1 in every 30 runs with a sha mismatch error: +- +- c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match +- 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3 +- missing +-- +2.41.0 + diff --git a/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch b/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch deleted file mode 100644 index c7562e7..0000000 --- a/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 3698867194f27fdd7824b8bdd172d619a2c087cc Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 7 Sep 2022 14:56:49 +0200 -Subject: [PATCH 62/83] Mdmonitor: Split alert() into separate functions - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 186 ++++++++++++++++++++++++++++-------------------------- - 1 file changed, 95 insertions(+), 91 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 7d7dc4d2..0036e8cd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -66,7 +66,7 @@ struct alert_info { - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(char *event, char *dev, char *disc, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); - static int check_array(struct state *st, struct mdstat_ent *mdstat, - int test, struct alert_info *info, - int increments, char *prefer); -@@ -407,111 +407,115 @@ static void write_autorebuild_pid() - } - } - --static void alert(char *event, char *dev, char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ int pid = fork(); -+ -+ switch (pid) { -+ default: -+ waitpid(pid, NULL, 0); -+ break; -+ case -1: -+ pr_err("Cannot fork to execute alert command"); -+ break; -+ case 0: -+ execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ exit(2); -+ } -+} -+ -+static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ FILE *mp, *mdstat; -+ char hname[256]; -+ char buf[BUFSIZ]; -+ int n; -+ -+ mp = popen(Sendmail, "w"); -+ if (!mp) { -+ pr_err("Cannot open pipe stream for sendmail.\n"); -+ return; -+ } -+ -+ gethostname(hname, sizeof(hname)); -+ signal(SIGPIPE, SIG_IGN); -+ if (info->mailfrom) -+ fprintf(mp, "From: %s\n", info->mailfrom); -+ else -+ fprintf(mp, "From: %s monitoring \n", Name); -+ fprintf(mp, "To: %s\n", info->mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "This is an automatically generated mail message. \n"); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ -+ if (disc && disc[0] != ' ') -+ fprintf(mp, -+ "It could be related to component device %s.\n\n", disc); -+ if (disc && disc[0] == ' ') -+ fprintf(mp, "Extra information:%s.\n\n", disc); -+ -+ mdstat = fopen("/proc/mdstat", "r"); -+ if (!mdstat) { -+ pr_err("Cannot open /proc/mdstat\n"); -+ pclose(mp); -+ return; -+ } -+ -+ fprintf(mp, "The /proc/mdstat file currently contains the following:\n\n"); -+ while ((n = fread(buf, 1, sizeof(buf), mdstat)) > 0) -+ n = fwrite(buf, 1, n, mp); -+ fclose(mdstat); -+ pclose(mp); -+} -+ -+static void log_event_to_syslog(const char *event, const char *dev, const char *disc) - { - int priority; -+ /* Log at a different severity depending on the event. -+ * -+ * These are the critical events: */ -+ if (strncmp(event, "Fail", 4) == 0 || -+ strncmp(event, "Degrade", 7) == 0 || -+ strncmp(event, "DeviceDisappeared", 17) == 0) -+ priority = LOG_CRIT; -+ /* Good to know about, but are not failures: */ -+ else if (strncmp(event, "Rebuild", 7) == 0 || -+ strncmp(event, "MoveSpare", 9) == 0 || -+ strncmp(event, "Spares", 6) != 0) -+ priority = LOG_WARNING; -+ /* Everything else: */ -+ else -+ priority = LOG_INFO; - -+ if (disc && disc[0] != ' ') -+ syslog(priority, -+ "%s event detected on md device %s, component device %s", event, dev, disc); -+ else if (disc) -+ syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ else -+ syslog(priority, "%s event detected on md device %s", event, dev); -+} -+ -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ - if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) { -- int pid = fork(); -- switch(pid) { -- default: -- waitpid(pid, NULL, 0); -- break; -- case -1: -- break; -- case 0: -- execl(info->alert_cmd, info->alert_cmd, -- event, dev, disc, NULL); -- exit(2); -- } -- } -+ if (info->alert_cmd) -+ execute_alert_cmd(event, dev, disc, info); -+ - if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- FILE *mp = popen(Sendmail, "w"); -- if (mp) { -- FILE *mdstat; -- char hname[256]; -- -- gethostname(hname, sizeof(hname)); -- signal_s(SIGPIPE, SIG_IGN); -- -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -- else -- fprintf(mp, "From: %s monitoring \n", -- Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", -- event, dev, hname); -- -- fprintf(mp, -- "This is an automatically generated mail message from %s\n", Name); -- fprintf(mp, "running on %s\n\n", hname); -- -- fprintf(mp, -- "A %s event had been detected on md device %s.\n\n", event, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -- -- fprintf(mp, "Faithfully yours, etc.\n"); -- -- mdstat = fopen("/proc/mdstat", "r"); -- if (mdstat) { -- char buf[8192]; -- int n; -- fprintf(mp, -- "\nP.S. The /proc/mdstat file currently contains the following:\n\n"); -- while ((n = fread(buf, 1, sizeof(buf), -- mdstat)) > 0) -- n = fwrite(buf, 1, n, mp); -- fclose(mdstat); -- } -- pclose(mp); -- } -+ send_event_email(event, dev, disc, info); - } - -- /* log the event to syslog maybe */ -- if (info->dosyslog) { -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -- else if (disc) -- syslog(priority, -- "%s event detected on md device %s: %s", -- event, dev, disc); -- else -- syslog(priority, -- "%s event detected on md device %s", -- event, dev); -- } -+ if (info->dosyslog) -+ log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, --- -2.38.1 - diff --git a/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch b/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch new file mode 100644 index 0000000..7abeaea --- /dev/null +++ b/SOURCES/0062-tests-01raid6integ.broken-can-be-removed.patch @@ -0,0 +1,31 @@ +From 896948b14ad26f15590269dce50ac4896284dc29 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 18 Apr 2024 18:23:21 +0800 +Subject: [PATCH 62/69] tests/01raid6integ.broken can be removed + +01raid6integ can be run successfully with kernel 6.9.0-rc3. +So remove 01raid6integ.broken. + +Signed-off-by: Xiao Ni +Signed-off-by: Mariusz Tkaczyk +--- + tests/01raid6integ.broken | 7 ------- + 1 file changed, 7 deletions(-) + delete mode 100644 tests/01raid6integ.broken + +diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken +deleted file mode 100644 +index 1df735f0..00000000 +--- a/tests/01raid6integ.broken ++++ /dev/null +@@ -1,7 +0,0 @@ +-fails infrequently +- +-Fails about 1 in 5 with a sha mismatch: +- +- 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match +- a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and +- /dev/loop3 missing +-- +2.41.0 + diff --git a/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch b/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch new file mode 100644 index 0000000..db2cb18 --- /dev/null +++ b/SOURCES/0063-Makefile-Move-pie-to-LDFLAGS.patch @@ -0,0 +1,38 @@ +From 893a55831e5abbcd15b171db66fa1f389fb61506 Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Tue, 7 May 2024 19:32:16 +0200 +Subject: [PATCH 63/69] Makefile: Move -pie to LDFLAGS + +Move -pie from LDLIBS to LDFLAGS and make LDFLAGS configurable to allow +the user to drop it by setting their own LDFLAGS (e.g. PIE could be +enabled or disabled by the buildsystem such as buildroot). + +Suggested-by: Mariusz Tkaczyk +Signed-off-by: Fabrice Fontaine +Signed-off-by: Mariusz Tkaczyk +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index 7c221a89..adac7905 100644 +--- a/Makefile ++++ b/Makefile +@@ -132,12 +132,12 @@ CFLAGS += -DUSE_PTHREADS + MON_LDFLAGS += -pthread + endif + +-LDFLAGS = -Wl,-z,now,-z,noexecstack ++LDFLAGS ?= -pie -Wl,-z,now,-z,noexecstack + + # If you want a static binary, you might uncomment these + # LDFLAGS += -static + # STRIP = -s +-LDLIBS = -ldl -pie ++LDLIBS = -ldl + + # To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS + ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS))) +-- +2.41.0 + diff --git a/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch b/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch deleted file mode 100644 index d993d9d..0000000 --- a/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f40ac0e7e6043361ad12e9db97c07e56c3977cf6 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:57 +0100 -Subject: [PATCH 63/83] Monitor: block if monitor modes are combined. - -Block monitoring start if --scan mode and MD devices list are combined. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Monitor.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index 0036e8cd..188cb8be 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -123,7 +123,7 @@ int Monitor(struct mddev_dev *devlist, - * and if we can get_disk_info and find a name - * Then we hot-remove and hot-add to the other array - * -- * If devlist is NULL, then we can monitor everything because --scan -+ * If devlist is NULL, then we can monitor everything if --scan - * was given. We get an initial list from config file and add anything - * that appears in /proc/mdstat - */ -@@ -136,6 +136,11 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -+ if (devlist && c->scan) { -+ pr_err("Devices list and --scan option cannot be combined - not monitoring.\n"); -+ return 1; -+ } -+ - if (!mailaddr) - mailaddr = conf_get_mailaddr(); - --- -2.38.1 - diff --git a/SOURCES/0064-Update-mdadm-Monitor-manual.patch b/SOURCES/0064-Update-mdadm-Monitor-manual.patch deleted file mode 100644 index 15f52e1..0000000 --- a/SOURCES/0064-Update-mdadm-Monitor-manual.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 725e37cd14866906ba28c970394b9f7a4cd97413 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:58 +0100 -Subject: [PATCH 64/83] Update mdadm Monitor manual. - -- describe monitor work modes, -- clarify the turning off condition, -- describe the mdmonitor.service as a prefered management way. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 71 ++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 50 insertions(+), 21 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 70c79d1e..64f71ed1 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -2548,13 +2548,33 @@ Usage: - .I options... devices... - - .PP --This usage causes -+Monitor option can work in two modes: -+.IP \(bu 4 -+system wide mode, follow all md devices based on -+.B /proc/mdstat, -+.IP \(bu 4 -+follow only specified MD devices in command line. -+.PP -+ -+.B \-\-scan - -+indicates system wide mode. Option causes the -+.I monitor -+to track all md devices that appear in -+.B /proc/mdstat. -+If it is not set, then at least one -+.B device -+must be specified. -+ -+Monitor usage causes - .I mdadm - to periodically poll a number of md arrays and to report on any events - noticed. --.I mdadm --will never exit once it decides that there are arrays to be checked, --so it should normally be run in the background. -+ -+In both modes, -+.I monitor -+will work as long as there is an active array with redundancy and it is defined to follow (for -+.B \-\-scan -+every array is followed). - - As well as reporting events, - .I mdadm -@@ -2565,15 +2585,6 @@ or - .B domain - and if the destination array has a failed drive but no spares. - --If any devices are listed on the command line, --.I mdadm --will only monitor those devices, otherwise, all arrays listed in the --configuration file will be monitored. Further, if --.B \-\-scan --is given, then any other md devices that appear in --.B /proc/mdstat --will also be monitored. -- - The result of monitoring the arrays is the generation of events. - These events are passed to a separate program (if specified) and may - be mailed to a given E-mail address. -@@ -2586,16 +2597,34 @@ device if relevant (such as a component device that has failed). - - If - .B \-\-scan --is given, then a program or an E-mail address must be specified on the --command line or in the config file. If neither are available, then -+is given, then a -+.B program -+or an -+.B e-mail -+address must be specified on the -+command line or in the config file. If neither are available, then - .I mdadm - will not monitor anything. --Without --.B \-\-scan, --.I mdadm --will continue monitoring as long as something was found to monitor. If --no program or email is given, then each event is reported to --.BR stdout . -+For devices given directly in command line, without -+.B program -+or -+.B email -+specified, each event is reported to -+.BR stdout. -+ -+Note: For systems where -+.If mdadm monitor -+is configured via systemd, -+.B mdmonitor(mdmonitor.service) -+should be configured. The service is designed to be primary solution for array monitoring, -+it is configured to work in system wide mode. -+It is automatically started and stopped according to current state and types of MD arrays in system. -+The service may require additional configuration, like -+.B e-mail -+or -+.B delay. -+That should be done in -+.B mdadm.conf. - - The different events are: - --- -2.38.1 - diff --git a/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch b/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch new file mode 100644 index 0000000..ee8bc37 --- /dev/null +++ b/SOURCES/0064-tests-23rdev-lifetime-fix-a-typo.patch @@ -0,0 +1,30 @@ +From a0174749426f49a04f11ae0e728cb0a681bfa465 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Thu, 9 May 2024 09:10:59 +0800 +Subject: [PATCH 64/69] tests/23rdev-lifetime: fix a typo + +"pill" was wrong, while it should be "kill", test will still pass while +test thread will not be cleaned up. + +Signed-off-by: Yu Kuai +Signed-off-by: Mariusz Tkaczyk +--- + tests/23rdev-lifetime | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime +index 1750b0db..03b61de4 100644 +--- a/tests/23rdev-lifetime ++++ b/tests/23rdev-lifetime +@@ -4,7 +4,7 @@ pid="" + runtime=2 + + clean_up_test() { +- pill -9 $pid ++ kill -9 $pid + echo clear > /sys/block/md0/md/array_state + } + +-- +2.41.0 + diff --git a/SOURCES/0065-Grow-fix-possible-memory-leak.patch b/SOURCES/0065-Grow-fix-possible-memory-leak.patch deleted file mode 100644 index 07d9fb6..0000000 --- a/SOURCES/0065-Grow-fix-possible-memory-leak.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 434b3b9bb96a76dc12f693b64cf23b581781e20b Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Tue, 20 Dec 2022 12:07:51 +0100 -Subject: [PATCH 65/83] Grow: fix possible memory leak. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Grow.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index e362403a..b73ec2ae 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -432,6 +432,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); -+ free(mdi); - return 1; - } - fd2 = dev_open(dv, O_RDWR); -@@ -453,8 +454,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - pr_err("failed to load super-block.\n"); - } - close(fd2); -- if (rv) -+ if (rv) { -+ free(mdi); - return 1; -+ } - } - if (offset_setable) { - st->ss->getinfo_super(st, mdi, NULL); --- -2.38.1 - diff --git a/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch b/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch new file mode 100644 index 0000000..48cc6d7 --- /dev/null +++ b/SOURCES/0065-util.c-change-devnm-to-const-in-mdmon-functions.patch @@ -0,0 +1,55 @@ +From b0f4e8e30f38d83f7e3f53d01d72d4cb3b4d42d7 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 7 May 2024 05:38:55 +0200 +Subject: [PATCH 65/69] util.c: change devnm to const in mdmon functions + +Devnm shall not be changed inside mdmon_running() +and mdmon_pid() functions, change this parameter to const. + +Signed-off-by: Kinga Stefaniuk +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 4 ++-- + util.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 2ff3e463..1ba541fc 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1768,8 +1768,8 @@ extern int is_subarray_active(char *subarray, char *devname); + extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet); + extern struct superswitch *version_to_superswitch(char *vers); + +-extern int mdmon_running(char *devnm); +-extern int mdmon_pid(char *devnm); ++extern int mdmon_running(const char *devnm); ++extern int mdmon_pid(const char *devnm); + extern int check_env(char *name); + extern __u32 random32(void); + extern void random_uuid(__u8 *buf); +diff --git a/util.c b/util.c +index 4fbf11c4..e2b490e1 100644 +--- a/util.c ++++ b/util.c +@@ -1902,7 +1902,7 @@ unsigned long long min_recovery_start(struct mdinfo *array) + return recovery_start; + } + +-int mdmon_pid(char *devnm) ++int mdmon_pid(const char *devnm) + { + char path[100]; + char pid[10]; +@@ -1922,7 +1922,7 @@ int mdmon_pid(char *devnm) + return atoi(pid); + } + +-int mdmon_running(char *devnm) ++int mdmon_running(const char *devnm) + { + int pid = mdmon_pid(devnm); + if (pid <= 0) +-- +2.41.0 + diff --git a/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch b/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch new file mode 100644 index 0000000..4b9851c --- /dev/null +++ b/SOURCES/0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch @@ -0,0 +1,121 @@ +From aa1cc5815d2b14a8b47add18cfaa8264e19c10ce Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 7 May 2024 05:38:56 +0200 +Subject: [PATCH 66/69] Wait for mdmon when it is stared via systemd + +When mdmon is being started it may need few seconds to start. +For now, we didn't wait for it. Introduce wait_for_mdmon() +function, which waits up to 5 seconds for mdmon to start completely. + +Signed-off-by: Kinga Stefaniuk +Signed-off-by: Mariusz Tkaczyk +--- + Assemble.c | 4 ++-- + Grow.c | 7 ++++--- + mdadm.h | 2 ++ + util.c | 29 +++++++++++++++++++++++++++++ + 4 files changed, 37 insertions(+), 5 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index f5e9ab1f..83dced19 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -2173,8 +2173,8 @@ int assemble_container_content(struct supertype *st, int mdfd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(st->container_devnm); +- if (mdmon_running(st->container_devnm) && +- st->update_tail == NULL) ++ if (wait_for_mdmon(st->container_devnm) == MDADM_STATUS_SUCCESS && ++ !st->update_tail) + st->update_tail = &st->updates; + } + +diff --git a/Grow.c b/Grow.c +index 87ed9214..1923c27c 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2134,7 +2134,7 @@ int Grow_reshape(char *devname, int fd, + if (!mdmon_running(st->container_devnm)) + start_mdmon(st->container_devnm); + ping_monitor(container); +- if (mdmon_running(st->container_devnm) == false) { ++ if (wait_for_mdmon(st->container_devnm) != MDADM_STATUS_SUCCESS) { + pr_err("No mdmon found. Grow cannot continue.\n"); + goto release; + } +@@ -3218,7 +3218,8 @@ static int reshape_array(char *container, int fd, char *devname, + if (!mdmon_running(container)) + start_mdmon(container); + ping_monitor(container); +- if (mdmon_running(container) && st->update_tail == NULL) ++ if (wait_for_mdmon(container) == MDADM_STATUS_SUCCESS && ++ !st->update_tail) + st->update_tail = &st->updates; + } + } +@@ -5173,7 +5174,7 @@ int Grow_continue_command(char *devname, int fd, struct context *c) + start_mdmon(container); + ping_monitor(container); + +- if (mdmon_running(container) == false) { ++ if (wait_for_mdmon(container) != MDADM_STATUS_SUCCESS) { + pr_err("No mdmon found. Grow cannot continue.\n"); + ret_val = 1; + goto Grow_continue_command_exit; +diff --git a/mdadm.h b/mdadm.h +index 1ba541fc..b71d7b32 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1770,6 +1770,8 @@ extern struct superswitch *version_to_superswitch(char *vers); + + extern int mdmon_running(const char *devnm); + extern int mdmon_pid(const char *devnm); ++extern mdadm_status_t wait_for_mdmon(const char *devnm); ++ + extern int check_env(char *name); + extern __u32 random32(void); + extern void random_uuid(__u8 *buf); +diff --git a/util.c b/util.c +index e2b490e1..bf79742f 100644 +--- a/util.c ++++ b/util.c +@@ -1932,6 +1932,35 @@ int mdmon_running(const char *devnm) + return 0; + } + ++/* ++ * wait_for_mdmon() - Waits for mdmon within specified time. ++ * @devnm: Device for which mdmon should start. ++ * ++ * Function waits for mdmon to start. It may need few seconds ++ * to start, we set timeout to 5, it should be sufficient. ++ * Do not wait if mdmon has been started. ++ * ++ * Return: MDADM_STATUS_SUCCESS if mdmon is running, error code otherwise. ++ */ ++mdadm_status_t wait_for_mdmon(const char *devnm) ++{ ++ const time_t mdmon_timeout = 5; ++ time_t start_time = time(0); ++ ++ if (mdmon_running(devnm)) ++ return MDADM_STATUS_SUCCESS; ++ ++ pr_info("Waiting for mdmon to start\n"); ++ while (time(0) - start_time < mdmon_timeout) { ++ sleep_for(0, MSEC_TO_NSEC(200), true); ++ if (mdmon_running(devnm)) ++ return MDADM_STATUS_SUCCESS; ++ }; ++ ++ pr_err("Timeout waiting for mdmon\n"); ++ return MDADM_STATUS_ERROR; ++} ++ + int start_mdmon(char *devnm) + { + int i; +-- +2.41.0 + diff --git a/SOURCES/0066-mdadm-create-ident_init.patch b/SOURCES/0066-mdadm-create-ident_init.patch deleted file mode 100644 index 32d374b..0000000 --- a/SOURCES/0066-mdadm-create-ident_init.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 7fcbfd7c620e2dcd3b539d18e93cb503ee3a8a62 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Wed, 21 Dec 2022 12:50:17 +0100 -Subject: [PATCH 66/83] mdadm: create ident_init() - -Add a wrapper for repeated initializations in mdadm.c and config.c. -Move includes up. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 45 +++++++++++++++++++++++++++++---------------- - mdadm.c | 16 ++-------------- - mdadm.h | 7 +++++-- - 3 files changed, 36 insertions(+), 32 deletions(-) - -diff --git a/config.c b/config.c -index dc1620c1..eeedd0c6 100644 ---- a/config.c -+++ b/config.c -@@ -119,6 +119,34 @@ int match_keyword(char *word) - return -1; - } - -+/** -+ * ident_init() - Set defaults. -+ * @ident: ident pointer, not NULL. -+ */ -+inline void ident_init(struct mddev_ident *ident) -+{ -+ assert(ident); -+ -+ ident->assembled = false; -+ ident->autof = 0; -+ ident->bitmap_fd = -1; -+ ident->bitmap_file = NULL; -+ ident->container = NULL; -+ ident->devices = NULL; -+ ident->devname = NULL; -+ ident->level = UnSet; -+ ident->member = NULL; -+ ident->name[0] = 0; -+ ident->next = NULL; -+ ident->raid_disks = UnSet; -+ ident->spare_group = NULL; -+ ident->spare_disks = 0; -+ ident->st = NULL; -+ ident->super_minor = UnSet; -+ ident->uuid[0] = 0; -+ ident->uuid_set = 0; -+} -+ - struct conf_dev { - struct conf_dev *next; - char *name; -@@ -363,22 +391,7 @@ void arrayline(char *line) - struct mddev_ident mis; - struct mddev_ident *mi; - -- mis.uuid_set = 0; -- mis.super_minor = UnSet; -- mis.level = UnSet; -- mis.raid_disks = UnSet; -- mis.spare_disks = 0; -- mis.devices = NULL; -- mis.devname = NULL; -- mis.spare_group = NULL; -- mis.autof = 0; -- mis.next = NULL; -- mis.st = NULL; -- mis.bitmap_fd = -1; -- mis.bitmap_file = NULL; -- mis.name[0] = 0; -- mis.container = NULL; -- mis.member = NULL; -+ ident_init(&mis); - - for (w = dl_next(line); w != line; w = dl_next(w)) { - if (w[0] == '/' || strchr(w, '=') == NULL) { -diff --git a/mdadm.c b/mdadm.c -index 972adb52..74fdec31 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,25 +107,13 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- ident.uuid_set = 0; -- ident.level = UnSet; -- ident.raid_disks = UnSet; -- ident.super_minor = UnSet; -- ident.devices = 0; -- ident.spare_group = NULL; -- ident.autof = 0; -- ident.st = NULL; -- ident.bitmap_fd = -1; -- ident.bitmap_file = NULL; -- ident.name[0] = 0; -- ident.container = NULL; -- ident.member = NULL; -- - if (get_linux_version() < 2006015) { - pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); - exit(1); - } - -+ ident_init(&ident); -+ - while ((option_index = -1), - (opt = getopt_long(argc, argv, shortopt, long_options, - &option_index)) != -1) { -diff --git a/mdadm.h b/mdadm.h -index 3673494e..23ffe977 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - # endif - #endif - -+#include - #include - #include -+#include - #include - #include - #include -@@ -1552,6 +1554,8 @@ extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name); - -+extern void ident_init(struct mddev_ident *ident); -+ - extern int parse_auto(char *str, char *msg, int config); - extern struct mddev_ident *conf_get_ident(char *dev); - extern struct mddev_dev *conf_get_devs(void); -@@ -1779,8 +1783,7 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler) - #define dprintf_cont(fmt, arg...) \ - ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) - #endif --#include --#include -+ - static inline int xasprintf(char **strp, const char *fmt, ...) { - va_list ap; - int ret; --- -2.38.1 - diff --git a/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch b/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch deleted file mode 100644 index faa7113..0000000 --- a/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 2568ce89ea5c26225e8984733adc2ea7559d853a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:15 +0100 -Subject: [PATCH 67/83] mdadm: Add option validation for --update-subarray - -Subset of options available for "--update" is not same as for "--update-subarray". -Define maps and enum for update options and use them instead of direct comparisons. -Add proper error message. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 31 +++++++++++++++++ - maps.c | 31 +++++++++++++++++ - mdadm.c | 104 +++++++++++++++++-------------------------------------- - mdadm.h | 32 ++++++++++++++++- - 4 files changed, 124 insertions(+), 74 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 50a5e36d..bd8d50d2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -655,3 +655,34 @@ char *mode_help[mode_count] = { - [GROW] = Help_grow, - [INCREMENTAL] = Help_incr, - }; -+ -+/** -+ * fprint_update_options() - Print valid update options depending on the mode. -+ * @outf: File (output stream) -+ * @update_mode: Used to distinguish update and update_subarray -+ */ -+void fprint_update_options(FILE *outf, enum update_opt update_mode) -+{ -+ int counter = UOPT_NAME, breakpoint = UOPT_HELP; -+ mapping_t *map = update_options; -+ -+ if (!outf) -+ return; -+ if (update_mode == UOPT_SUBARRAY_ONLY) { -+ breakpoint = UOPT_SUBARRAY_ONLY; -+ fprintf(outf, "Valid --update options for update-subarray are:\n\t"); -+ } else -+ fprintf(outf, "Valid --update options are:\n\t"); -+ while (map->num) { -+ if (map->num >= breakpoint) -+ break; -+ fprintf(outf, "'%s', ", map->name); -+ if (counter % 5 == 0) -+ fprintf(outf, "\n\t"); -+ counter++; -+ map++; -+ } -+ if ((counter - 1) % 5) -+ fprintf(outf, "\n"); -+ fprintf(outf, "\r"); -+} -diff --git a/maps.c b/maps.c -index 20fcf719..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -165,6 +165,37 @@ mapping_t sysfs_array_states[] = { - { "broken", ARRAY_BROKEN }, - { NULL, ARRAY_UNKNOWN_STATE } - }; -+/** -+ * mapping_t update_options - stores supported update options. -+ */ -+mapping_t update_options[] = { -+ { "name", UOPT_NAME }, -+ { "ppl", UOPT_PPL }, -+ { "no-ppl", UOPT_NO_PPL }, -+ { "bitmap", UOPT_BITMAP }, -+ { "no-bitmap", UOPT_NO_BITMAP }, -+ { "sparc2.2", UOPT_SPARC22 }, -+ { "super-minor", UOPT_SUPER_MINOR }, -+ { "summaries", UOPT_SUMMARIES }, -+ { "resync", UOPT_RESYNC }, -+ { "uuid", UOPT_UUID }, -+ { "homehost", UOPT_HOMEHOST }, -+ { "home-cluster", UOPT_HOME_CLUSTER }, -+ { "nodes", UOPT_NODES }, -+ { "devicesize", UOPT_DEVICESIZE }, -+ { "bbl", UOPT_BBL }, -+ { "no-bbl", UOPT_NO_BBL }, -+ { "force-no-bbl", UOPT_FORCE_NO_BBL }, -+ { "metadata", UOPT_METADATA }, -+ { "revert-reshape", UOPT_REVERT_RESHAPE }, -+ { "layout-original", UOPT_LAYOUT_ORIGINAL }, -+ { "layout-alternate", UOPT_LAYOUT_ALTERNATE }, -+ { "layout-unspecified", UOPT_LAYOUT_UNSPECIFIED }, -+ { "byteorder", UOPT_BYTEORDER }, -+ { "help", UOPT_HELP }, -+ { "?", UOPT_HELP }, -+ { NULL, UOPT_UNDEFINED} -+}; - - /** - * map_num_s() - Safer alternative of map_num() function. -diff --git a/mdadm.c b/mdadm.c -index 74fdec31..f5f505fe 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -100,7 +100,7 @@ int main(int argc, char *argv[]) - char *dump_directory = NULL; - - int print_help = 0; -- FILE *outf; -+ FILE *outf = NULL; - - int mdfd = -1; - int locked = 0; -@@ -723,7 +723,11 @@ int main(int argc, char *argv[]) - continue; - - case O(ASSEMBLE,'U'): /* update the superblock */ -- case O(MISC,'U'): -+ case O(MISC,'U'): { -+ enum update_opt updateopt = map_name(update_options, c.update); -+ enum update_opt print_mode = UOPT_HELP; -+ const char *error_addon = "update option"; -+ - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", - c.update, optarg); -@@ -733,83 +737,37 @@ int main(int argc, char *argv[]) - pr_err("Only subarrays can be updated in misc mode\n"); - exit(2); - } -+ - c.update = optarg; -- if (strcmp(c.update, "sparc2.2") == 0) -- continue; -- if (strcmp(c.update, "super-minor") == 0) -- continue; -- if (strcmp(c.update, "summaries") == 0) -- continue; -- if (strcmp(c.update, "resync") == 0) -- continue; -- if (strcmp(c.update, "uuid") == 0) -- continue; -- if (strcmp(c.update, "name") == 0) -- continue; -- if (strcmp(c.update, "homehost") == 0) -- continue; -- if (strcmp(c.update, "home-cluster") == 0) -- continue; -- if (strcmp(c.update, "nodes") == 0) -- continue; -- if (strcmp(c.update, "devicesize") == 0) -- continue; -- if (strcmp(c.update, "bitmap") == 0) -- continue; -- if (strcmp(c.update, "no-bitmap") == 0) -- continue; -- if (strcmp(c.update, "bbl") == 0) -- continue; -- if (strcmp(c.update, "no-bbl") == 0) -- continue; -- if (strcmp(c.update, "force-no-bbl") == 0) -- continue; -- if (strcmp(c.update, "ppl") == 0) -- continue; -- if (strcmp(c.update, "no-ppl") == 0) -- continue; -- if (strcmp(c.update, "metadata") == 0) -- continue; -- if (strcmp(c.update, "revert-reshape") == 0) -- continue; -- if (strcmp(c.update, "layout-original") == 0 || -- strcmp(c.update, "layout-alternate") == 0 || -- strcmp(c.update, "layout-unspecified") == 0) -- continue; -- if (strcmp(c.update, "byteorder") == 0) { -+ -+ if (devmode == UpdateSubarray) { -+ print_mode = UOPT_SUBARRAY_ONLY; -+ error_addon = "update-subarray option"; -+ -+ if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -+ updateopt = UOPT_UNDEFINED; -+ } -+ -+ switch (updateopt) { -+ case UOPT_UNDEFINED: -+ pr_err("'--update=%s' is invalid %s. ", -+ c.update, error_addon); -+ outf = stderr; -+ case UOPT_HELP: -+ if (!outf) -+ outf = stdout; -+ fprint_update_options(outf, print_mode); -+ exit(outf == stdout ? 0 : 2); -+ case UOPT_BYTEORDER: - if (ss) { - pr_err("must not set metadata type with --update=byteorder.\n"); - exit(2); - } -- for(i = 0; !ss && superlist[i]; i++) -- ss = superlist[i]->match_metadata_desc( -- "0.swap"); -- if (!ss) { -- pr_err("INTERNAL ERROR cannot find 0.swap\n"); -- exit(2); -- } -- -- continue; -+ default: -+ break; - } -- if (strcmp(c.update,"?") == 0 || -- strcmp(c.update, "help") == 0) { -- outf = stdout; -- fprintf(outf, "%s: ", Name); -- } else { -- outf = stderr; -- fprintf(outf, -- "%s: '--update=%s' is invalid. ", -- Name, c.update); -- } -- fprintf(outf, "Valid --update options are:\n" -- " 'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n" -- " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n" -- " 'bitmap', 'no-bitmap', 'metadata', 'revert-reshape'\n" -- " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n" -- " 'layout-original', 'layout-alternate', 'layout-unspecified'\n" -- ); -- exit(outf == stdout ? 0 : 2); -- -+ continue; -+ } - case O(MANAGE,'U'): - /* update=devicesize is allowed with --re-add */ - if (devmode != 'A') { -diff --git a/mdadm.h b/mdadm.h -index 23ffe977..51f1db2d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -497,6 +497,36 @@ enum special_options { - ConsistencyPolicy, - }; - -+enum update_opt { -+ UOPT_NAME = 1, -+ UOPT_PPL, -+ UOPT_NO_PPL, -+ UOPT_BITMAP, -+ UOPT_NO_BITMAP, -+ UOPT_SUBARRAY_ONLY, -+ UOPT_SPARC22, -+ UOPT_SUPER_MINOR, -+ UOPT_SUMMARIES, -+ UOPT_RESYNC, -+ UOPT_UUID, -+ UOPT_HOMEHOST, -+ UOPT_HOME_CLUSTER, -+ UOPT_NODES, -+ UOPT_DEVICESIZE, -+ UOPT_BBL, -+ UOPT_NO_BBL, -+ UOPT_FORCE_NO_BBL, -+ UOPT_METADATA, -+ UOPT_REVERT_RESHAPE, -+ UOPT_LAYOUT_ORIGINAL, -+ UOPT_LAYOUT_ALTERNATE, -+ UOPT_LAYOUT_UNSPECIFIED, -+ UOPT_BYTEORDER, -+ UOPT_HELP, -+ UOPT_UNDEFINED -+}; -+extern void fprint_update_options(FILE *outf, enum update_opt update_mode); -+ - enum prefix_standard { - JEDEC, - IEC -@@ -777,7 +807,7 @@ extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], - pers[], modes[], faultylayout[]; --extern mapping_t consistency_policies[], sysfs_array_states[]; -+extern mapping_t consistency_policies[], sysfs_array_states[], update_options[]; - - extern char *map_dev_preferred(int major, int minor, int create, - char *prefer); --- -2.38.1 - diff --git a/SOURCES/0068-Fix-update-subarray-on-active-volume.patch b/SOURCES/0068-Fix-update-subarray-on-active-volume.patch deleted file mode 100644 index 7c1c4bc..0000000 --- a/SOURCES/0068-Fix-update-subarray-on-active-volume.patch +++ /dev/null @@ -1,54 +0,0 @@ -From db10eab68e652f141169b7240e057d110d626c3d Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:16 +0100 -Subject: [PATCH 68/83] Fix --update-subarray on active volume - -Options: bitmap, ppl and name should not be updated when array is active. -Those features are mutually exclusive and share the same data area in IMSM (danger of overwriting by kernel). -Remove check for active subarrays from super-intel. -Since ddf is not supported, apply it globally for all options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 7 +++++++ - super-intel.c | 5 ----- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/Manage.c b/Manage.c -index b1d0e630..5a9ea316 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1745,6 +1745,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -+ if (is_subarray_active(subarray, st->devnm)) { -+ if (verbose >= 0) -+ pr_err("Subarray %s in %s is active, cannot update %s\n", -+ subarray, dev, update); -+ goto free_super; -+ } -+ - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -diff --git a/super-intel.c b/super-intel.c -index b0565610..5f93f3d3 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7914,11 +7914,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - char *ep; - int vol; - -- if (is_subarray_active(subarray, st->devnm)) { -- pr_err("Unable to update name of active subarray\n"); -- return 2; -- } -- - if (!check_name(super, name, 0)) - return 2; - --- -2.38.1 - diff --git a/SOURCES/0069-Add-code-specific-update-options-to-enum.patch b/SOURCES/0069-Add-code-specific-update-options-to-enum.patch deleted file mode 100644 index 57386f5..0000000 --- a/SOURCES/0069-Add-code-specific-update-options-to-enum.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2257de106cbf17a7f1df33a10cfd2be0d5a064cb Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:17 +0100 -Subject: [PATCH 69/83] Add code specific update options to enum. - -Some of update options aren't taken from user input, but are hard-coded -as strings. -Include those options in enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - maps.c | 21 +++++++++++++++++++++ - mdadm.h | 15 +++++++++++++++ - 2 files changed, 36 insertions(+) - -diff --git a/maps.c b/maps.c -index b586679a..c59036f1 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,6 +194,27 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -+ /* -+ * Those enries are temporary and will be removed in this patchset. -+ * -+ * Before update_super:update can be changed to enum, -+ * all update_super sub-functions must be adapted first. -+ * Update options will be passed as string (as it is for now), -+ * and then mapped, so all options must be handled temporarily. -+ * -+ * Those options code specific and should not be accessible for user. -+ */ -+ { "force-one", UOPT_SPEC_FORCE_ONE }, -+ { "force-array", UOPT_SPEC_FORCE_ARRAY }, -+ { "assemble", UOPT_SPEC_ASSEMBLE }, -+ { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -+ { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -+ { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -+ { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -+ { "readwrite", UOPT_SPEC_READWRITE }, -+ { "failfast", UOPT_SPEC_FAILFAST }, -+ { "nofailfast", UOPT_SPEC_NOFAILFAST }, -+ { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 51f1db2d..31db25f5 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -523,6 +523,21 @@ enum update_opt { - UOPT_LAYOUT_UNSPECIFIED, - UOPT_BYTEORDER, - UOPT_HELP, -+ UOPT_USER_ONLY, -+ /* -+ * Code specific options, cannot be set by the user -+ */ -+ UOPT_SPEC_FORCE_ONE, -+ UOPT_SPEC_FORCE_ARRAY, -+ UOPT_SPEC_ASSEMBLE, -+ UOPT_SPEC_LINEAR_GROW_NEW, -+ UOPT_SPEC_LINEAR_GROW_UPDATE, -+ UOPT_SPEC__RESHAPE_PROGRESS, -+ UOPT_SPEC_WRITEMOSTLY, -+ UOPT_SPEC_READWRITE, -+ UOPT_SPEC_FAILFAST, -+ UOPT_SPEC_NOFAILFAST, -+ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - UOPT_UNDEFINED - }; - extern void fprint_update_options(FILE *outf, enum update_opt update_mode); --- -2.38.1 - diff --git a/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch b/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch new file mode 100644 index 0000000..12464af --- /dev/null +++ b/SOURCES/0069-mdadm-Fix-compilation-for-32-bit-arch.patch @@ -0,0 +1,62 @@ +From c5879860eac64ddd7bec4ba50c9adbfebcbf1d2e Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Wed, 15 May 2024 13:26:28 +0200 +Subject: [PATCH 69/69] mdadm: Fix compilation for 32-bit arch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Casting void pointer to __u64 works for 64-bit arch but fails to compile +on 32-bit arch like i686. + +Fail on i686 platform: +drive_encryption.c: In function ‘nvme_security_recv_ioctl’: +drive_encryption.c:236:25: error: cast from pointer to integer of +different size [-Werror=pointer-to-int-cast] + 236 | nvme_cmd.addr = (__u64)response_buffer; + | ^ +drive_encryption.c: In function ‘nvme_identify_ioctl’: +drive_encryption.c:271:25: error: cast from pointer to integer of +different size [-Werror=pointer-to-int-cast] + 271 | nvme_cmd.addr = (__u64)response_buffer; + | ^ +cc1: all warnings being treated as errors +make: *** [Makefile:211: drive_encryption.o] Error 1 + +This change adds cast void pointer to uintptr_t first to ensure that +proper pointer size is used for casting from pointer type. Then is safe to +cast it to __u64 because it is tracked as u_int, regardless it is 32-bit +or 64-bit arch. + +Reported-by: Xiao Ni +Fixes: cc48406887b3 ("Add reading Opal NVMe encryption information") +Signed-off-by: Blazej Kucman +--- + drive_encryption.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drive_encryption.c b/drive_encryption.c +index 27da9621..a4ad799f 100644 +--- a/drive_encryption.c ++++ b/drive_encryption.c +@@ -233,7 +233,7 @@ nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *re + nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8; + nvme_cmd.cdw11 = buf_size; + nvme_cmd.data_len = buf_size; +- nvme_cmd.addr = (__u64)response_buffer; ++ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer; + + status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); + if (status != 0) { +@@ -268,7 +268,7 @@ nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const i + nvme_cmd.opcode = NVME_IDENTIFY; + nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA; + nvme_cmd.data_len = buf_size; +- nvme_cmd.addr = (__u64)response_buffer; ++ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer; + + status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd); + if (status != 0) { +-- +2.41.0 + diff --git a/SOURCES/0070-Detail-fix-detail-export-for-uuid_zero.patch b/SOURCES/0070-Detail-fix-detail-export-for-uuid_zero.patch new file mode 100644 index 0000000..f9499cd --- /dev/null +++ b/SOURCES/0070-Detail-fix-detail-export-for-uuid_zero.patch @@ -0,0 +1,36 @@ +From 5be749ce416852e7acbb2415be380be358859612 Mon Sep 17 00:00:00 2001 +From: Kinga Stefaniuk +Date: Tue, 23 Jul 2024 15:38:41 +0200 +Subject: [PATCH 1/1] Detail: fix --detail --export for uuid_zero + +Mentioned commit (see Fixes) causes that devices with UUID +equal to uuid_zero was not recognized properly. For few devices +the first one was taken always, and the same information was +printed. It caused regression, when few containers were created, +symlinks were generated only for the first one. + +Add checking if uuid is uuid_zero and, if yes, use devname to +differentiate devices. + +Fixes: 60c19530dd7c ("Detail: remove duplicated code") +Signed-off-by: Kinga Stefaniuk +--- + Detail.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Detail.c b/Detail.c +index 55a086d3..f8b9e847 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -274,7 +274,7 @@ int Detail(char *dev, struct context *c) + array.minor_version); + } + +- if (info) ++ if (info && memcmp(info->uuid, uuid_zero, sizeof(int[4])) != 0) + mp = map_by_uuid(&map, info->uuid); + if (!mp) + mp = map_by_devnm(&map, fd2devnm(fd)); +-- +2.41.0 + diff --git a/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch b/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch deleted file mode 100644 index 7a6d213..0000000 --- a/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 35aa44c549290e22f285896684c704acb53b7717 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:18 +0100 -Subject: [PATCH 70/83] super-ddf: Remove update_super_ddf. - -This is not supported by ddf. -It hides errors by returning success status for some updates. -Remove update_super_dff(). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 70 ----------------------------------------------------- - 1 file changed, 70 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d1e3b94..309812df 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -2139,75 +2139,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha - } - } - --static int update_super_ddf(struct supertype *st, struct mdinfo *info, -- char *update, -- char *devname, int verbose, -- int uuid_set, char *homehost) --{ -- /* For 'assemble' and 'force' we need to return non-zero if any -- * change was made. For others, the return value is ignored. -- * Update options are: -- * force-one : This device looks a bit old but needs to be included, -- * update age info appropriately. -- * assemble: clear any 'faulty' flag to allow this device to -- * be assembled. -- * force-array: Array is degraded but being forced, mark it clean -- * if that will be needed to assemble it. -- * -- * newdev: not used ???? -- * grow: Array has gained a new device - this is currently for -- * linear only -- * resync: mark as dirty so a resync will happen. -- * uuid: Change the uuid of the array to match what is given -- * homehost: update the recorded homehost -- * name: update the name - preserving the homehost -- * _reshape_progress: record new reshape_progress position. -- * -- * Following are not relevant for this version: -- * sparc2.2 : update from old dodgey metadata -- * super-minor: change the preferred_minor number -- * summaries: update redundant counters. -- */ -- int rv = 0; --// struct ddf_super *ddf = st->sb; --// struct vd_config *vd = find_vdcr(ddf, info->container_member); --// struct virtual_entry *ve = find_ve(ddf); -- -- /* we don't need to handle "force-*" or "assemble" as -- * there is no need to 'trick' the kernel. When the metadata is -- * first updated to activate the array, all the implied modifications -- * will just happen. -- */ -- -- if (strcmp(update, "grow") == 0) { -- /* FIXME */ -- } else if (strcmp(update, "resync") == 0) { --// info->resync_checkpoint = 0; -- } else if (strcmp(update, "homehost") == 0) { -- /* homehost is stored in controller->vendor_data, -- * or it is when we are the vendor -- */ --// if (info->vendor_is_local) --// strcpy(ddf->controller.vendor_data, homehost); -- rv = -1; -- } else if (strcmp(update, "name") == 0) { -- /* name is stored in virtual_entry->name */ --// memset(ve->name, ' ', 16); --// strncpy(ve->name, info->name, 16); -- rv = -1; -- } else if (strcmp(update, "_reshape_progress") == 0) { -- /* We don't support reshape yet */ -- } else if (strcmp(update, "assemble") == 0 ) { -- /* Do nothing, just succeed */ -- rv = 0; -- } else -- rv = -1; -- --// update_all_csum(ddf); -- -- return rv; --} -- - static void make_header_guid(char *guid) - { - be32 stamp; -@@ -5211,7 +5142,6 @@ struct superswitch super_ddf = { - .match_home = match_home_ddf, - .uuid_from_super= uuid_from_super_ddf, - .getinfo_super = getinfo_super_ddf, -- .update_super = update_super_ddf, - - .avail_size = avail_size_ddf, - --- -2.38.1 - diff --git a/SOURCES/0071-super0-refactor-the-code-for-enum.patch b/SOURCES/0071-super0-refactor-the-code-for-enum.patch deleted file mode 100644 index f01c534..0000000 --- a/SOURCES/0071-super0-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0a9e39383d3bf63e1f5cf10f64200083a1af8091 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:19 +0100 -Subject: [PATCH 71/83] super0: refactor the code for enum - -It prepares update_super0 for change context->update to enum. -Change if else statements to switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super0.c | 102 ++++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 63 insertions(+), 39 deletions(-) - -diff --git a/super0.c b/super0.c -index 93876e2e..d9f5bff4 100644 ---- a/super0.c -+++ b/super0.c -@@ -502,19 +502,39 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update = "uuid"; -+ update_enum = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- if (strcmp(update, "sparc2.2")==0 ) { -+ switch (update_enum) { -+ case UOPT_UUID: -+ if (!uuid_set && homehost) { -+ char buf[20]; -+ memcpy(info->uuid+2, -+ sha1_buffer(homehost, strlen(homehost), buf), -+ 8); -+ } -+ sb->set_uuid0 = info->uuid[0]; -+ sb->set_uuid1 = info->uuid[1]; -+ sb->set_uuid2 = info->uuid[2]; -+ sb->set_uuid3 = info->uuid[3]; -+ if (sb->state & (1<uuid, uuid, 16); -+ } -+ break; -+ case UOPT_SPARC22: { - /* 2.2 sparc put the events in the wrong place - * So we copy the tail of the superblock - * up 4 bytes before continuing -@@ -527,12 +547,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (verbose >= 0) - pr_err("adjusting superblock of %s for 2.2/sparc compatibility.\n", - devname); -- } else if (strcmp(update, "super-minor") ==0) { -+ break; -+ } -+ case UOPT_SUPER_MINOR: - sb->md_minor = info->array.md_minor; - if (verbose > 0) - pr_err("updating superblock of %s with minor number %d\n", - devname, info->array.md_minor); -- } else if (strcmp(update, "summaries") == 0) { -+ break; -+ case UOPT_SUMMARIES: { - unsigned int i; - /* set nr_disks, active_disks, working_disks, - * failed_disks, spare_disks based on disks[] -@@ -559,7 +582,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->spare_disks++; - } else if (i >= sb->raid_disks && sb->disks[i].number == 0) - sb->disks[i].state = 0; -- } else if (strcmp(update, "force-one")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: { - /* Not enough devices for a working array, so - * bring this one up-to-date. - */ -@@ -569,7 +594,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (sb->events_hi != ehi || - sb->events_lo != elo) - rv = 1; -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ARRAY: - /* degraded array and 'force' requested, so - * maybe need to mark it 'clean' - */ -@@ -579,7 +606,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->state |= (1 << MD_SB_CLEAN); - rv = 1; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int wonly = sb->disks[d].state & (1<disks[d].state & (1<reshape_position = info->reshape_progress; - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: - memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); - sb->disks[info->disk.number].number = info->disk.number; - sb->disks[info->disk.number].major = info->disk.major; -@@ -617,7 +647,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; - sb->this_disk = sb->disks[info->disk.number]; -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: - sb->raid_disks = info->array.raid_disks; - sb->nr_disks = info->array.nr_disks; - sb->active_disks = info->array.active_disks; -@@ -628,29 +659,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].minor = info->disk.minor; - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -+ break; -+ case UOPT_RESYNC: -+ /* -+ * make sure resync happens -+ */ - sb->state &= ~(1<recovery_cp = 0; -- } else if (strcmp(update, "uuid") == 0) { -- if (!uuid_set && homehost) { -- char buf[20]; -- char *hash = sha1_buffer(homehost, -- strlen(homehost), -- buf); -- memcpy(info->uuid+2, hash, 8); -- } -- sb->set_uuid0 = info->uuid[0]; -- sb->set_uuid1 = info->uuid[1]; -- sb->set_uuid2 = info->uuid[2]; -- sb->set_uuid3 = info->uuid[3]; -- if (sb->state & (1<uuid, uuid, 16); -- } -- } else if (strcmp(update, "metadata") == 0) { -+ break; -+ case UOPT_METADATA: - /* Create some v1.0 metadata to match ours but make the - * ctime bigger. Also update info->array.*_version. - * We need to arrange that store_super writes out -@@ -670,7 +687,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - uuid_from_super0(st, info->uuid); - st->other = super1_make_v0(st, info, st->sb); - } -- } else if (strcmp(update, "revert-reshape") == 0) { -+ break; -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (sb->minor_version <= 90) - pr_err("No active reshape to revert on %s\n", -@@ -702,16 +720,22 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->new_chunk = sb->chunk_size; - sb->chunk_size = tmp; - } -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->state &= ~(1<reshape_position = info->reshape_progress; -- else if (strcmp(update, "writemostly")==0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->state |= (1<state &= ~(1<sb_csum = calc_sb0_csum(sb); - return rv; --- -2.38.1 - diff --git a/SOURCES/0072-super1-refactor-the-code-for-enum.patch b/SOURCES/0072-super1-refactor-the-code-for-enum.patch deleted file mode 100644 index bd164b8..0000000 --- a/SOURCES/0072-super1-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 7e8daba8b7937716dce8ea28298a4e2e72cb829e Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:20 +0100 -Subject: [PATCH 72/83] super1: refactor the code for enum - -It prepares update_super1 for change context->update to enum. -Change if else statements into switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super1.c | 152 +++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 91 insertions(+), 61 deletions(-) - -diff --git a/super1.c b/super1.c -index 0b505a7e..b0a97016 100644 ---- a/super1.c -+++ b/super1.c -@@ -1218,30 +1218,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* Note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update = "name"; -+ update_enum = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- strncpy(info->name, c+1, 31 - (c-sb->set_name)); -+ snprintf(info->name, sizeof(info->name), "%s", c+1); - else -- strncpy(info->name, sb->set_name, 32); -- info->name[32] = 0; -+ snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- if (strcmp(update, "force-one")==0) { -+ switch (update_enum) { -+ case UOPT_NAME: { -+ int namelen; -+ -+ if (!info->name[0]) -+ snprintf(info->name, sizeof(info->name), "%d", info->array.md_minor); -+ memset(sb->set_name, 0, sizeof(sb->set_name)); -+ -+ namelen = strnlen(homehost, MD_NAME_MAX) + 1 + strnlen(info->name, MD_NAME_MAX); -+ if (homehost && -+ strchr(info->name, ':') == NULL && -+ namelen < MD_NAME_MAX) { -+ strcpy(sb->set_name, homehost); -+ strcat(sb->set_name, ":"); -+ strcat(sb->set_name, info->name); -+ } else { -+ namelen = min((int)strnlen(info->name, MD_NAME_MAX), -+ (int)sizeof(sb->set_name) - 1); -+ memcpy(sb->set_name, info->name, namelen); -+ memset(&sb->set_name[namelen], '\0', -+ sizeof(sb->set_name) - namelen); -+ } -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: - /* Not enough devices for a working array, - * so bring this one up-to-date - */ - if (sb->events != __cpu_to_le64(info->events)) - rv = 1; - sb->events = __cpu_to_le64(info->events); -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ case UOPT_SPEC_FORCE_ARRAY: - /* Degraded array and 'force' requests to - * maybe need to mark it 'clean'. - */ -@@ -1254,7 +1279,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - rv = 1; - sb->resync_offset = MaxSector; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int want; - if (info->disk.state & (1<reshape_progress); - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: { - int i; - int fd; - int max = __le32_to_cpu(sb->max_dev); -@@ -1330,7 +1358,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - ds - __le64_to_cpu(sb->data_offset)); - } - } -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: { - int max = __le32_to_cpu(sb->max_dev); - int i = info->disk.number; - if (max > MAX_DEVS || i > MAX_DEVS) -@@ -1342,19 +1372,20 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -- sb->resync_offset = 0ULL; -- } else if (strcmp(update, "uuid") == 0) { -+ break; -+ } -+ case UOPT_UUID: - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - - if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) - memcpy(bms->uuid, sb->set_uuid, 16); -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); - if (bms->version == BITMAP_MAJOR_CLUSTERED && !IsBitmapDirty(devname)) - sb->resync_offset = MaxSector; -- } else if (strcmp(update, "bbl") == 0) { -+ break; -+ case UOPT_BBL: { - /* only possible if there is room after the bitmap, or if - * there is no bitmap - */ -@@ -1383,14 +1414,12 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - bb_offset = bitmap_offset + bm_sectors; - while (bb_offset < (long)sb_offset + 8 + 32*2 && - bb_offset + 8+8 <= (long)data_offset) -- /* too close to bitmap, and room to grow */ - bb_offset += 8; - if (bb_offset + 8 <= (long)data_offset) { - sb->bblog_size = __cpu_to_le16(8); - sb->bblog_offset = __cpu_to_le32(bb_offset); - } - } else { -- /* 1.0 - Put bbl just before super block */ - if (bm_sectors && bitmap_offset < 0) - space = -bitmap_offset - bm_sectors; - else -@@ -1401,7 +1430,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_offset = __cpu_to_le32((unsigned)-8); - } - } -- } else if (strcmp(update, "no-bbl") == 0) { -+ break; -+ } -+ case UOPT_NO_BBL: - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) - pr_err("Cannot remove active bbl from %s\n",devname); - else { -@@ -1409,12 +1440,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_shift = 0; - sb->bblog_offset = 0; - } -- } else if (strcmp(update, "force-no-bbl") == 0) { -+ break; -+ case UOPT_FORCE_NO_BBL: - sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_BAD_BLOCKS); - sb->bblog_size = 0; - sb->bblog_shift = 0; - sb->bblog_offset = 0; -- } else if (strcmp(update, "ppl") == 0) { -+ break; -+ case UOPT_PPL: { - unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); - unsigned long long data_offset = __le64_to_cpu(sb->data_offset); - unsigned long long data_size = __le64_to_cpu(sb->data_size); -@@ -1464,37 +1497,26 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->ppl.offset = __cpu_to_le16(offset); - sb->ppl.size = __cpu_to_le16(space); - sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); -- } else if (strcmp(update, "no-ppl") == 0) { -+ break; -+ } -+ case UOPT_NO_PPL: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | - MD_FEATURE_MUTLIPLE_PPLS); -- } else if (strcmp(update, "name") == 0) { -- if (info->name[0] == 0) -- sprintf(info->name, "%d", info->array.md_minor); -- memset(sb->set_name, 0, sizeof(sb->set_name)); -- if (homehost && -- strchr(info->name, ':') == NULL && -- strlen(homehost)+1+strlen(info->name) < 32) { -- strcpy(sb->set_name, homehost); -- strcat(sb->set_name, ":"); -- strcat(sb->set_name, info->name); -- } else { -- int namelen; -- -- namelen = min((int)strlen(info->name), -- (int)sizeof(sb->set_name) - 1); -- memcpy(sb->set_name, info->name, namelen); -- memset(&sb->set_name[namelen], '\0', -- sizeof(sb->set_name) - namelen); -- } -- } else if (strcmp(update, "devicesize") == 0 && -- __le64_to_cpu(sb->super_offset) < -- __le64_to_cpu(sb->data_offset)) { -- /* set data_size to device size less data_offset */ -+ break; -+ case UOPT_DEVICESIZE: -+ if (__le64_to_cpu(sb->super_offset) >= -+ __le64_to_cpu(sb->data_offset)) -+ break; -+ /* -+ * set data_size to device size less data_offset -+ */ - struct misc_dev_info *misc = (struct misc_dev_info*) - (st->sb + MAX_SB_SIZE + BM_SUPER_SIZE); - sb->data_size = __cpu_to_le64( - misc->device_size - __le64_to_cpu(sb->data_offset)); -- } else if (strncmp(update, "revert-reshape", 14) == 0) { -+ break; -+ case UOPT_SPEC_REVERT_RESHAPE_NOBACKUP: -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (!(sb->feature_map & - __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) -@@ -1512,7 +1534,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (strcmp(update, "revert-reshape-nobackup") == 0 && -+ if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1575,32 +1597,40 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - } - done:; - } -- } else if (strcmp(update, "_reshape_progress") == 0) -+ break; -+ case UOPT_SPEC__RESHAPE_PROGRESS: - sb->reshape_position = __cpu_to_le64(info->reshape_progress); -- else if (strcmp(update, "writemostly") == 0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->devflags |= WriteMostly1; -- else if (strcmp(update, "readwrite") == 0) -+ break; -+ case UOPT_SPEC_READWRITE: - sb->devflags &= ~WriteMostly1; -- else if (strcmp(update, "failfast") == 0) -+ break; -+ case UOPT_SPEC_FAILFAST: - sb->devflags |= FailFast1; -- else if (strcmp(update, "nofailfast") == 0) -+ break; -+ case UOPT_SPEC_NOFAILFAST: - sb->devflags &= ~FailFast1; -- else if (strcmp(update, "layout-original") == 0 || -- strcmp(update, "layout-alternate") == 0 || -- strcmp(update, "layout-unspecified") == 0) { -+ break; -+ case UOPT_LAYOUT_ORIGINAL: -+ case UOPT_LAYOUT_ALTERNATE: -+ case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname?:"", update); -+ devname ?: "", map_num(update_options, update_enum)); - rv = -1; -- } else if (strcmp(update, "layout-unspecified") == 0) { -+ } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); -+ sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } -- } else -+ break; -+ default: - rv = -1; -+ } - - sb->sb_csum = calc_sb_1_csum(sb); - --- -2.38.1 - diff --git a/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch b/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch deleted file mode 100644 index 6756297..0000000 --- a/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 4345e135c4c7dd04bb15bad140dfc4747f677738 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:21 +0100 -Subject: [PATCH 73/83] super-intel: refactor the code for enum - -It prepares super-intel for change context->update to enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 37 +++++++++++++++++++++++++------------ - 1 file changed, 25 insertions(+), 12 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5f93f3d3..85fb7f17 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3930,7 +3930,8 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- if (strcmp(update, "uuid") == 0) { -+ switch (map_name(update_options, update)) { -+ case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really - * allow an explicit uuid to be given. And it is hard to reliably -@@ -3954,10 +3955,14 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - } - if (rv == 0) - mpb->orig_family_num = info->uuid[0]; -- } else if (strcmp(update, "assemble") == 0) -+ break; -+ case UOPT_SPEC_ASSEMBLE: - rv = 0; -- else -+ break; -+ default: - rv = -1; -+ break; -+ } - - /* successful update? recompute checksum */ - if (rv == 0) -@@ -7889,17 +7894,25 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) - return 0; - } - --static int get_rwh_policy_from_update(char *update) -+/** -+ * get_rwh_policy_from_update() - Get the rwh policy for update option. -+ * @update: Update option. -+ */ -+static int get_rwh_policy_from_update(enum update_opt update) - { -- if (strcmp(update, "ppl") == 0) -+ switch (update) { -+ case UOPT_PPL: - return RWH_MULTIPLE_DISTRIBUTED; -- else if (strcmp(update, "no-ppl") == 0) -+ case UOPT_NO_PPL: - return RWH_MULTIPLE_OFF; -- else if (strcmp(update, "bitmap") == 0) -+ case UOPT_BITMAP: - return RWH_BITMAP; -- else if (strcmp(update, "no-bitmap") == 0) -+ case UOPT_NO_BITMAP: - return RWH_OFF; -- return -1; -+ default: -+ break; -+ } -+ return UOPT_UNDEFINED; - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -@@ -7909,7 +7922,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (strcmp(update, "name") == 0) { -+ if (map_name(update_options, update) == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7943,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(update) != -1) { -+ } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7951,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(update); -+ new_policy = get_rwh_policy_from_update(map_name(update_options, update)); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); --- -2.38.1 - diff --git a/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch b/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch deleted file mode 100644 index c9e186e..0000000 --- a/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch +++ /dev/null @@ -1,424 +0,0 @@ -From 03312b5240438ffc3b63114bdc87e911222f01e5 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:22 +0100 -Subject: [PATCH 74/83] Change update to enum in update_super and - update_subarray - -Use already existing enum, change update_super and update_subarray -update to enum globally. -Refactor function references also. -Remove code specific options from update_options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 14 +++++++++----- - Examine.c | 2 +- - Grow.c | 9 +++++---- - Manage.c | 14 ++++++++------ - maps.c | 21 --------------------- - mdadm.h | 12 +++++++++--- - super-intel.c | 16 ++++++++-------- - super0.c | 9 ++++----- - super1.c | 17 ++++++++--------- - 9 files changed, 52 insertions(+), 62 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 8b0af0c9..dba910cd 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -695,12 +695,16 @@ static int load_devices(struct devs *devices, char *devmap, - } else if (strcmp(c->update, "revert-reshape") == 0 && - c->invalid_backup) - err = tst->ss->update_super(tst, content, -- "revert-reshape-nobackup", -+ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- err = tst->ss->update_super(tst, content, c->update, -+ /* -+ * Mapping is temporary, will be removed in this patchset -+ */ -+ err = tst->ss->update_super(tst, content, -+ map_name(update_options, c->update), - devname, c->verbose, - ident->uuid_set, - c->homehost); -@@ -960,7 +964,7 @@ static int force_array(struct mdinfo *content, - continue; - } - content->events = devices[most_recent].i.events; -- tst->ss->update_super(tst, content, "force-one", -+ tst->ss->update_super(tst, content, UOPT_SPEC_FORCE_ONE, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - -@@ -1788,7 +1792,7 @@ try_again: - if (!(devices[j].i.array.state & 1)) - clean = 0; - -- if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, -+ if (st->ss->update_super(st, &devices[j].i, UOPT_SPEC_ASSEMBLE, NULL, - c->verbose, 0, NULL)) { - if (c->force) { - if (c->verbose >= 0) -@@ -1811,7 +1815,7 @@ try_again: - if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { -- change += st->ss->update_super(st, content, "force-array", -+ change += st->ss->update_super(st, content, UOPT_SPEC_FORCE_ARRAY, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - was_forced = 1; -diff --git a/Examine.c b/Examine.c -index 9574a3cc..c9605a60 100644 ---- a/Examine.c -+++ b/Examine.c -@@ -117,7 +117,7 @@ int Examine(struct mddev_dev *devlist, - } - - if (c->SparcAdjust) -- st->ss->update_super(st, NULL, "sparc2.2", -+ st->ss->update_super(st, NULL, UOPT_SPARC22, - devlist->devname, 0, 0, NULL); - /* Ok, its good enough to try, though the checksum could be wrong */ - -diff --git a/Grow.c b/Grow.c -index b73ec2ae..82d5d2ea 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -196,7 +196,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.disk.minor = minor(rdev); - info.disk.raid_disk = d; - info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); -- if (st->ss->update_super(st, &info, "linear-grow-new", newdev, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_NEW, newdev, - 0, 0, NULL) != 0) { - pr_err("Preparing new metadata failed on %s\n", newdev); - close(nfd); -@@ -254,7 +254,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.array.active_disks = nd+1; - info.array.working_disks = nd+1; - -- if (st->ss->update_super(st, &info, "linear-grow-update", dv, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_UPDATE, dv, - 0, 0, NULL) != 0) { - pr_err("Updating metadata failed on %s\n", dv); - close(fd2); -@@ -668,7 +668,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - goto free_info; - } - -- ret = st->ss->update_super(st, sra, "ppl", -+ ret = st->ss->update_super(st, sra, UOPT_PPL, - devname, - c->verbose, 0, NULL); - if (ret) { -@@ -4950,7 +4950,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, - continue; - st->ss->getinfo_super(st, &dinfo, NULL); - dinfo.reshape_progress = info->reshape_progress; -- st->ss->update_super(st, &dinfo, "_reshape_progress", -+ st->ss->update_super(st, &dinfo, -+ UOPT_SPEC__RESHAPE_PROGRESS, - NULL,0, 0, NULL); - st->ss->store_super(st, fdlist[j]); - st->ss->free_super(st); -diff --git a/Manage.c b/Manage.c -index 5a9ea316..87b8aa0c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -605,6 +605,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -+ enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -666,23 +667,23 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - - if (dv->writemostly == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "writemostly", -+ dev_st, NULL, UOPT_SPEC_WRITEMOSTLY, - devname, verbose, 0, NULL); - if (dv->writemostly == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "readwrite", -+ dev_st, NULL, UOPT_SPEC_READWRITE, - devname, verbose, 0, NULL); - if (dv->failfast == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "failfast", -+ dev_st, NULL, UOPT_SPEC_FAILFAST, - devname, verbose, 0, NULL); - if (dv->failfast == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "nofailfast", -+ dev_st, NULL, UOPT_SPEC_NOFAILFAST, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update, -+ dev_st, NULL, update_enum, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -1731,6 +1732,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -+ enum update_opt update_enum = map_name(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1762,7 +1764,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update, ident); -+ rv = st->ss->update_subarray(st, subarray, update_enum, ident); - - if (rv) { - if (verbose >= 0) -diff --git a/maps.c b/maps.c -index c59036f1..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,27 +194,6 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -- /* -- * Those enries are temporary and will be removed in this patchset. -- * -- * Before update_super:update can be changed to enum, -- * all update_super sub-functions must be adapted first. -- * Update options will be passed as string (as it is for now), -- * and then mapped, so all options must be handled temporarily. -- * -- * Those options code specific and should not be accessible for user. -- */ -- { "force-one", UOPT_SPEC_FORCE_ONE }, -- { "force-array", UOPT_SPEC_FORCE_ARRAY }, -- { "assemble", UOPT_SPEC_ASSEMBLE }, -- { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -- { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -- { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -- { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -- { "readwrite", UOPT_SPEC_READWRITE }, -- { "failfast", UOPT_SPEC_FAILFAST }, -- { "nofailfast", UOPT_SPEC_NOFAILFAST }, -- { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 31db25f5..5dc94390 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1011,7 +1011,7 @@ extern struct superswitch { - * it will resume going in the opposite direction. - */ - int (*update_super)(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost); - -@@ -1137,9 +1137,15 @@ extern struct superswitch { - /* Permit subarray's to be deleted from inactive containers */ - int (*kill_subarray)(struct supertype *st, - char *subarray_id); /* optional */ -- /* Permit subarray's to be modified */ -+ /** -+ * update_subarray() - Permit subarray to be modified. -+ * @st: Supertype. -+ * @subarray: Subarray name. -+ * @update: Update option. -+ * @ident: Optional identifiers. -+ */ - int (*update_subarray)(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident); /* optional */ -+ enum update_opt update, struct mddev_ident *ident); - /* Check if reshape is supported for this external format. - * st is obtained from super_by_fd() where st->subarray[0] is - * initialized to indicate if reshape is being performed at the -diff --git a/super-intel.c b/super-intel.c -index 85fb7f17..1f5f6eda 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3893,8 +3893,8 @@ struct mdinfo *getinfo_super_disks_imsm(struct supertype *st) - } - - static int update_super_imsm(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -- int uuid_set, char *homehost) -+ enum update_opt update, char *devname, -+ int verbose, int uuid_set, char *homehost) - { - /* For 'assemble' and 'force' we need to return non-zero if any - * change was made. For others, the return value is ignored. -@@ -3930,7 +3930,7 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- switch (map_name(update_options, update)) { -+ switch (update) { - case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really -@@ -6538,7 +6538,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, - if (mdmon_running(st->container_devnm)) - st->update_tail = &st->updates; - -- if (st->ss->update_subarray(st, subarray, "ppl", NULL)) { -+ if (st->ss->update_subarray(st, subarray, UOPT_PPL, NULL)) { - pr_err("Failed to update subarray %s\n", - subarray); - } else { -@@ -7916,13 +7916,13 @@ static int get_rwh_policy_from_update(enum update_opt update) - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident) -+ enum update_opt update, struct mddev_ident *ident) - { - /* update the subarray currently referenced by ->current_vol */ - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (map_name(update_options, update) == UOPT_NAME) { -+ if (update == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7956,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { -+ } else if (get_rwh_policy_from_update(update) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7964,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(map_name(update_options, update)); -+ new_policy = get_rwh_policy_from_update(update); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); -diff --git a/super0.c b/super0.c -index d9f5bff4..a7c5f813 100644 ---- a/super0.c -+++ b/super0.c -@@ -491,7 +491,7 @@ static struct mdinfo *container_content0(struct supertype *st, char *subarray) - } - - static int update_super0(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost) - { -@@ -502,20 +502,19 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update_enum = UOPT_UUID; -+ update = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_UUID: - if (!uuid_set && homehost) { - char buf[20]; -diff --git a/super1.c b/super1.c -index b0a97016..f7020320 100644 ---- a/super1.c -+++ b/super1.c -@@ -1208,7 +1208,7 @@ static struct mdinfo *container_content1(struct supertype *st, char *subarray) - } - - static int update_super1(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -+ enum update_opt update, char *devname, int verbose, - int uuid_set, char *homehost) - { - /* NOTE: for 'assemble' and 'force' we need to return non-zero -@@ -1218,15 +1218,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update_enum = UOPT_NAME; -+ update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) - snprintf(info->name, sizeof(info->name), "%s", c+1); -@@ -1234,7 +1233,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_NAME: { - int namelen; - -@@ -1534,7 +1533,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && -+ if (update == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1618,14 +1617,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname ?: "", map_num(update_options, update_enum)); -+ devname ?: "", map_num(update_options, update)); - rv = -1; -- } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { -+ } else if (update == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); -+ sb->layout = __cpu_to_le32(update == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } - break; - default: --- -2.38.1 - diff --git a/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch b/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch deleted file mode 100644 index d4b20ff..0000000 --- a/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch +++ /dev/null @@ -1,279 +0,0 @@ -From f2e8393bd7223c419aaa33c45feeb5c75440b986 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:23 +0100 -Subject: [PATCH 75/83] Manage&Incremental: code refactor, string to enum - -Prepare Manage and Incremental for later changing context->update to enum. -Change update from string to enum in multiple functions and pass enum -where already possible. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++---- - Incremental.c | 8 ++++---- - Manage.c | 35 +++++++++++++++++------------------ - mdadm.c | 23 ++++++++++++++++++----- - mdadm.h | 4 ++-- - 5 files changed, 45 insertions(+), 33 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 82d5d2ea..8f5cf07d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -605,12 +605,12 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - if (subarray) { -- char *update; -+ enum update_opt update; - - if (s->consistency_policy == CONSISTENCY_POLICY_PPL) -- update = "ppl"; -+ update = UOPT_PPL; - else -- update = "no-ppl"; -+ update = UOPT_NO_PPL; - - sprintf(container_dev, "/dev/%s", st->container_devnm); - -@@ -3243,7 +3243,7 @@ static int reshape_array(char *container, int fd, char *devname, - * level and frozen, we can safely add them. - */ - if (devlist) { -- if (Manage_subdevs(devname, fd, devlist, verbose, 0, NULL, 0)) -+ if (Manage_subdevs(devname, fd, devlist, verbose, 0, UOPT_UNDEFINED, 0)) - goto release; - } - -diff --git a/Incremental.c b/Incremental.c -index 5a5f4c4c..ff3548c0 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1025,7 +1025,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, - close(dfd); - *dfdp = -1; - rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - close(mdfd); - } - if (verbose > 0) { -@@ -1666,7 +1666,7 @@ static void remove_from_member_array(struct mdstat_ent *memb, - - if (subfd >= 0) { - rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, -- 0, NULL, 0); -+ 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - if (sysfs_init(&mmdi, -1, memb->devnm)) - pr_err("unable to initialize sysfs for: %s\n", -@@ -1758,7 +1758,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - free_mdstat(mdstat); - } else { - rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - /* Failed due to EBUSY, try to stop the array. - * Give udisks a chance to unmount it first. -@@ -1770,7 +1770,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - devlist.disposition = 'r'; - rv = Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - end: - close(mdfd); - free_mdstat(ent); -diff --git a/Manage.c b/Manage.c -index 87b8aa0c..594e3d2c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -598,14 +598,12 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) - - int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *dev_st, struct supertype *tst, -- unsigned long rdev, -- char *update, char *devname, int verbose, -- mdu_array_info_t *array) -+ unsigned long rdev, enum update_opt update, -+ char *devname, int verbose, mdu_array_info_t *array) - { - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -- enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -683,7 +681,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update_enum, -+ dev_st, NULL, update, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -715,8 +713,8 @@ skip_re_add: - int Manage_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *tst, mdu_array_info_t *array, - int force, int verbose, char *devname, -- char *update, unsigned long rdev, unsigned long long array_size, -- int raid_slot) -+ enum update_opt update, unsigned long rdev, -+ unsigned long long array_size, int raid_slot) - { - unsigned long long ldsize; - struct supertype *dev_st; -@@ -1332,7 +1330,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force) -+ enum update_opt update, int force) - { - /* Do something to each dev. - * devmode can be -@@ -1727,12 +1725,13 @@ int autodetect(void) - return rv; - } - --int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int verbose) -+int Update_subarray(char *dev, char *subarray, enum update_opt update, -+ struct mddev_ident *ident, int verbose) - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -- enum update_opt update_enum = map_name(update_options, update); -+ char *update_verb = map_num(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1750,7 +1749,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (is_subarray_active(subarray, st->devnm)) { - if (verbose >= 0) - pr_err("Subarray %s in %s is active, cannot update %s\n", -- subarray, dev, update); -+ subarray, dev, update_verb); - goto free_super; - } - -@@ -1759,23 +1758,23 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - - info = st->ss->container_content(st, subarray); - -- if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ if (update == UOPT_PPL && !is_level456(info->array.level)) { - pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update_enum, ident); -+ rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { - if (verbose >= 0) - pr_err("Failed to update %s of subarray-%s in %s\n", -- update, subarray, dev); -+ update_verb, subarray, dev); - } else if (st->update_tail) - flush_metadata_updates(st); - else - st->ss->sync_metadata(st); - -- if (rv == 0 && strcmp(update, "name") == 0 && verbose >= 0) -+ if (rv == 0 && update == UOPT_NAME && verbose >= 0) - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -@@ -1816,10 +1815,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - sprintf(devname, "%d:%d", major(devid), minor(devid)); - - devlist.disposition = 'r'; -- if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { -+ if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, UOPT_UNDEFINED, 0) == 0) { - devlist.disposition = 'a'; - if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, -- NULL, 0) == 0) { -+ UOPT_UNDEFINED, 0) == 0) { - /* make sure manager is aware of changes */ - ping_manager(to_devname); - ping_manager(from_devname); -@@ -1829,7 +1828,7 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - } - else - Manage_subdevs(from_devname, fd2, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - } - close(fd1); - close(fd2); -diff --git a/mdadm.c b/mdadm.c -index f5f505fe..d06e2820 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1402,10 +1402,22 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found>1) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- c.update, c.force); -+ if (!rv && devs_found > 1) { -+ /* -+ * This is temporary and will be removed in next patches -+ * Null c.update will cause segfault -+ */ -+ if (c.update) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ map_name(update_options, c.update), -+ c.force); -+ else -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ UOPT_UNDEFINED, -+ c.force); -+ } - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1931,7 +1943,8 @@ static int misc_list(struct mddev_dev *devlist, - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- c->update, ident, c->verbose); -+ map_name(update_options, c->update), -+ ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 5dc94390..924f4b63 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1478,7 +1478,7 @@ extern int Manage_stop(char *devname, int fd, int quiet, - int will_retry); - extern int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force); -+ enum update_opt update, int force); - extern int autodetect(void); - extern int Grow_Add_device(char *devname, int fd, char *newdev); - extern int Grow_addbitmap(char *devname, int fd, -@@ -1532,7 +1532,7 @@ extern int Monitor(struct mddev_dev *devlist, - - extern int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl); - extern int Kill_subarray(char *dev, char *subarray, int verbose); --extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet); -+extern int Update_subarray(char *dev, char *subarray, enum update_opt update, struct mddev_ident *ident, int quiet); - extern int Wait(char *dev); - extern int WaitClean(char *dev, int verbose); - extern int SetAction(char *dev, char *action); --- -2.38.1 - diff --git a/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch b/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch deleted file mode 100644 index a18f8d1..0000000 --- a/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 3a87fa67112dc2c2c3664aeecd0b49cb4b6ceaa9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:24 +0100 -Subject: [PATCH 76/83] Change char* to enum in context->update & refactor code - -Storing update option in string is bad for frequent comparisons and -error prone. -Replace char array with enum so already existing enum is passed around -instead of string. -Adapt code to changes. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 40 +++++++++++++++++----------------------- - mdadm.c | 52 +++++++++++++++++++--------------------------------- - mdadm.h | 2 +- - 3 files changed, 37 insertions(+), 57 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index dba910cd..49804941 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -135,17 +135,17 @@ static int ident_matches(struct mddev_ident *ident, - struct mdinfo *content, - struct supertype *tst, - char *homehost, int require_homehost, -- char *update, char *devname) -+ enum update_opt update, char *devname) - { - -- if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) && -+ if (ident->uuid_set && update != UOPT_UUID && - same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 && - memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) { - if (devname) - pr_err("%s has wrong uuid.\n", devname); - return 0; - } -- if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && -+ if (ident->name[0] && update != UOPT_NAME && - name_matches(content->name, ident->name, homehost, require_homehost)==0) { - if (devname) - pr_err("%s has wrong name.\n", devname); -@@ -648,11 +648,10 @@ static int load_devices(struct devs *devices, char *devmap, - int err; - fstat(mdfd, &stb2); - -- if (strcmp(c->update, "uuid") == 0 && !ident->uuid_set) -+ if (c->update == UOPT_UUID && !ident->uuid_set) - random_uuid((__u8 *)ident->uuid); - -- if (strcmp(c->update, "ppl") == 0 && -- ident->bitmap_fd >= 0) { -+ if (c->update == UOPT_PPL && ident->bitmap_fd >= 0) { - pr_err("PPL is not compatible with bitmap\n"); - close(mdfd); - free(devices); -@@ -684,34 +683,30 @@ static int load_devices(struct devs *devices, char *devmap, - strcpy(content->name, ident->name); - content->array.md_minor = minor(stb2.st_rdev); - -- if (strcmp(c->update, "byteorder") == 0) -+ if (c->update == UOPT_BYTEORDER) - err = 0; -- else if (strcmp(c->update, "home-cluster") == 0) { -+ else if (c->update == UOPT_HOME_CLUSTER) { - tst->cluster_name = c->homecluster; - err = tst->ss->write_bitmap(tst, dfd, NameUpdate); -- } else if (strcmp(c->update, "nodes") == 0) { -+ } else if (c->update == UOPT_NODES) { - tst->nodes = c->nodes; - err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate); -- } else if (strcmp(c->update, "revert-reshape") == 0 && -- c->invalid_backup) -+ } else if (c->update == UOPT_REVERT_RESHAPE && c->invalid_backup) - err = tst->ss->update_super(tst, content, - UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- /* -- * Mapping is temporary, will be removed in this patchset -- */ - err = tst->ss->update_super(tst, content, -- map_name(update_options, c->update), -+ c->update, - devname, c->verbose, - ident->uuid_set, - c->homehost); - if (err < 0) { - if (err == -1) - pr_err("--update=%s not understood for %s metadata\n", -- c->update, tst->ss->name); -+ map_num(update_options, c->update), tst->ss->name); - tst->ss->free_super(tst); - free(tst); - close(mdfd); -@@ -721,7 +716,7 @@ static int load_devices(struct devs *devices, char *devmap, - *stp = st; - return -1; - } -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - !ident->uuid_set) { - ident->uuid_set = 1; - memcpy(ident->uuid, content->uuid, 16); -@@ -730,7 +725,7 @@ static int load_devices(struct devs *devices, char *devmap, - pr_err("Could not re-write superblock on %s.\n", - devname); - -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - ident->bitmap_fd >= 0 && !bitmap_done) { - if (bitmap_update_uuid(ident->bitmap_fd, - content->uuid, -@@ -1188,8 +1183,7 @@ static int start_array(int mdfd, - pr_err("%s: Need a backup file to complete reshape of this array.\n", - mddev); - pr_err("Please provided one with \"--backup-file=...\"\n"); -- if (c->update && -- strcmp(c->update, "revert-reshape") == 0) -+ if (c->update == UOPT_REVERT_RESHAPE) - pr_err("(Don't specify --update=revert-reshape again, that part succeeded.)\n"); - return 1; - } -@@ -1487,7 +1481,7 @@ try_again: - */ - if (map_lock(&map)) - pr_err("failed to get exclusive lock on mapfile - continue anyway...\n"); -- if (c->update && strcmp(c->update,"uuid") == 0) -+ if (c->update == UOPT_UUID) - mp = NULL; - else - mp = map_by_uuid(&map, content->uuid); -@@ -1634,7 +1628,7 @@ try_again: - goto out; - } - -- if (c->update && strcmp(c->update, "byteorder")==0) -+ if (c->update == UOPT_BYTEORDER) - st->minor_version = 90; - - st->ss->getinfo_super(st, content, NULL); -@@ -1902,7 +1896,7 @@ try_again: - /* First, fill in the map, so that udev can find our name - * as soon as we become active. - */ -- if (c->update && strcmp(c->update, "metadata")==0) { -+ if (c->update == UOPT_METADATA) { - content->array.major_version = 1; - content->array.minor_version = 0; - strcpy(content->text_version, "1.0"); -diff --git a/mdadm.c b/mdadm.c -index d06e2820..57e8e6fa 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -724,13 +724,12 @@ int main(int argc, char *argv[]) - - case O(ASSEMBLE,'U'): /* update the superblock */ - case O(MISC,'U'): { -- enum update_opt updateopt = map_name(update_options, c.update); - enum update_opt print_mode = UOPT_HELP; - const char *error_addon = "update option"; - - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } - if (mode == MISC && !c.subarray) { -@@ -738,20 +737,20 @@ int main(int argc, char *argv[]) - exit(2); - } - -- c.update = optarg; -+ c.update = map_name(update_options, optarg); - - if (devmode == UpdateSubarray) { - print_mode = UOPT_SUBARRAY_ONLY; - error_addon = "update-subarray option"; - -- if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -- updateopt = UOPT_UNDEFINED; -+ if (c.update > UOPT_SUBARRAY_ONLY && c.update < UOPT_HELP) -+ c.update = UOPT_UNDEFINED; - } - -- switch (updateopt) { -+ switch (c.update) { - case UOPT_UNDEFINED: - pr_err("'--update=%s' is invalid %s. ", -- c.update, error_addon); -+ optarg, error_addon); - outf = stderr; - case UOPT_HELP: - if (!outf) -@@ -776,14 +775,14 @@ int main(int argc, char *argv[]) - } - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } -- c.update = optarg; -- if (strcmp(c.update, "devicesize") != 0 && -- strcmp(c.update, "bbl") != 0 && -- strcmp(c.update, "force-no-bbl") != 0 && -- strcmp(c.update, "no-bbl") != 0) { -+ c.update = map_name(update_options, optarg); -+ if (c.update != UOPT_DEVICESIZE && -+ c.update != UOPT_BBL && -+ c.update != UOPT_NO_BBL && -+ c.update != UOPT_FORCE_NO_BBL) { - pr_err("only 'devicesize', 'bbl', 'no-bbl', and 'force-no-bbl' can be updated with --re-add\n"); - exit(2); - } -@@ -1357,7 +1356,7 @@ int main(int argc, char *argv[]) - } - } - -- if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) { -+ if (c.update && c.update == UOPT_NODES && c.nodes == 0) { - pr_err("Please specify nodes number with --nodes\n"); - exit(1); - } -@@ -1402,22 +1401,10 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found > 1) { -- /* -- * This is temporary and will be removed in next patches -- * Null c.update will cause segfault -- */ -- if (c.update) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- map_name(update_options, c.update), -- c.force); -- else -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- UOPT_UNDEFINED, -- c.force); -- } -+ if (!rv && devs_found > 1) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, -+ c.test, c.update, c.force); - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1937,14 +1924,13 @@ static int misc_list(struct mddev_dev *devlist, - rv |= Kill_subarray(dv->devname, c->subarray, c->verbose); - continue; - case UpdateSubarray: -- if (c->update == NULL) { -+ if (!c->update) { - pr_err("-U/--update must be specified with --update-subarray\n"); - rv |= 1; - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- map_name(update_options, c->update), -- ident, c->verbose); -+ c->update, ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 924f4b63..13f8b4cb 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -616,7 +616,7 @@ struct context { - int export; - int test; - char *subarray; -- char *update; -+ enum update_opt update; - int scan; - int SparcAdjust; - int autof; --- -2.38.1 - diff --git a/SOURCES/0077-mdmon-fix-segfault.patch b/SOURCES/0077-mdmon-fix-segfault.patch deleted file mode 100644 index 980ceda..0000000 --- a/SOURCES/0077-mdmon-fix-segfault.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 9b429fc0a4ffd7028b3b336589d38e32fb9045dc Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:21 +0100 -Subject: [PATCH 77/83] mdmon: fix segfault - -Mdmon crashes if stat2devnm returns null. -Use open_mddev to check if device is mddevice and get name using -fd2devnm. -Refactor container name handling. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Makefile | 2 +- - mdmon.c | 26 ++++++++++++-------------- - 2 files changed, 13 insertions(+), 15 deletions(-) - -diff --git a/Makefile b/Makefile -index ec1f99ed..5eac1a4e 100644 ---- a/Makefile -+++ b/Makefile -@@ -160,7 +160,7 @@ SRCS = $(patsubst %.o,%.c,$(OBJS)) - - INCL = mdadm.h part.h bitmap.h - --MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \ -+MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o config.o mapfile.o mdopen.o\ - policy.o lib.o \ - Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ - super-mbr.o super-gpt.o \ -diff --git a/mdmon.c b/mdmon.c -index e9d035eb..ecf52dc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -363,14 +363,14 @@ int main(int argc, char *argv[]) - } - - if (all == 0 && container_name == NULL) { -- if (argv[optind]) -- container_name = argv[optind]; -+ if (argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ container_name = argv[optind]; -+ } - } - -- if (container_name == NULL) -- usage(); -- -- if (argc - optind > 1) -+ if (container_name == NULL || argc - optind > 1) - usage(); - - if (strcmp(container_name, "/proc/mdstat") == 0) -@@ -402,21 +402,19 @@ int main(int argc, char *argv[]) - free_mdstat(mdstat); - - return status; -- } else if (strncmp(container_name, "md", 2) == 0) { -- int id = devnm2devid(container_name); -- if (id) -- devnm = container_name; - } else { -- struct stat st; -+ int mdfd = open_mddev(container_name, 1); - -- if (stat(container_name, &st) == 0) -- devnm = xstrdup(stat2devnm(&st)); -+ if (mdfd < 0) -+ return 1; -+ devnm = fd2devnm(mdfd); -+ close(mdfd); - } - - if (!devnm) { - pr_err("%s is not a valid md device name\n", - container_name); -- exit(1); -+ return 1; - } - return mdmon(devnm, dofork && do_fork(), takeover); - } --- -2.38.1 - diff --git a/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch b/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch deleted file mode 100644 index b371d39..0000000 --- a/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch +++ /dev/null @@ -1,116 +0,0 @@ -From b938519e7719c992dae2d61c796c45fe49e6b71b Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:22 +0100 -Subject: [PATCH 78/83] util: remove obsolete code from get_md_name - -get_md_name() is used only with mdstat entries. -Remove dead code and simplyfy function. - -Remove redundadnt checks from mdmon.c - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 8 +++----- - util.c | 51 +++++++++++++++++---------------------------------- - 2 files changed, 20 insertions(+), 39 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index ecf52dc8..60ba3182 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -366,7 +366,7 @@ int main(int argc, char *argv[]) - if (argv[optind]) { - container_name = get_md_name(argv[optind]); - if (!container_name) -- container_name = argv[optind]; -+ return 1; - } - } - -@@ -403,11 +403,9 @@ int main(int argc, char *argv[]) - - return status; - } else { -- int mdfd = open_mddev(container_name, 1); -- -- if (mdfd < 0) -- return 1; -+ int mdfd = open_mddev(container_name, 0); - devnm = fd2devnm(mdfd); -+ - close(mdfd); - } - -diff --git a/util.c b/util.c -index 26ffdcea..9cd89fa4 100644 ---- a/util.c -+++ b/util.c -@@ -968,47 +968,30 @@ dev_t devnm2devid(char *devnm) - return 0; - } - -+/** -+ * get_md_name() - Get main dev node of the md device. -+ * @devnm: Md device name or path. -+ * -+ * Function checks if the full name was passed and returns md name -+ * if it is the MD device. -+ * -+ * Return: Main dev node of the md device or NULL if not found. -+ */ - char *get_md_name(char *devnm) - { -- /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ -- /* if dev < 0, want /dev/md/d%d or find mdp in /proc/devices ... */ -- -- static char devname[50]; -+ static char devname[NAME_MAX]; - struct stat stb; -- dev_t rdev = devnm2devid(devnm); -- char *dn; - -- if (rdev == 0) -- return 0; -- if (strncmp(devnm, "md_", 3) == 0) { -- snprintf(devname, sizeof(devname), "/dev/md/%s", -- devnm + 3); -- if (stat(devname, &stb) == 0 && -- (S_IFMT&stb.st_mode) == S_IFBLK && (stb.st_rdev == rdev)) -- return devname; -- } -- snprintf(devname, sizeof(devname), "/dev/%s", devnm); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -+ if (strncmp(devnm, "/dev/", 5) == 0) -+ snprintf(devname, sizeof(devname), "%s", devnm); -+ else -+ snprintf(devname, sizeof(devname), "/dev/%s", devnm); - -- snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -+ if (!is_mddev(devname)) -+ return NULL; -+ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK) - return devname; - -- dn = map_dev(major(rdev), minor(rdev), 0); -- if (dn) -- return dn; -- snprintf(devname, sizeof(devname), "/dev/.tmp.%s", devnm); -- if (mknod(devname, S_IFBLK | 0600, rdev) == -1) -- if (errno != EEXIST) -- return NULL; -- -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -- unlink(devname); - return NULL; - } - --- -2.38.1 - diff --git a/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch b/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch deleted file mode 100644 index f888a09..0000000 --- a/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 24d329fc97a64ec185ef27e59730f3f058c09029 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Thu, 5 Jan 2023 00:29:20 +0800 -Subject: [PATCH 79/83] mdadm/udev: Don't handle change event on raw devices - -The raw devices are ready when add event happpens and the raid -can be assembled. So there is no need to handle change events. -And it can cause some inconvenient problems. - -For example, the OS is installed on md0(/root) and md1(/home). -md0 and md1 are created on partitions. When it wants to re-install -OS, anaconda can't clear the storage configure. It deletes one -partition and does some jobs. The change event happens. Now -the raid device is assembled again. It can't delete the other -partitions. - -So in this patch, we don't handle change event on raw devices -anymore. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - udev-md-raid-assembly.rules | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index 39b4344b..d4a7f0a5 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -11,6 +11,11 @@ SUBSYSTEM!="block", GOTO="md_inc_end" - ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end" - - # handle potential components of arrays (the ones supported by md) -+# For member devices which are md/dm devices, we don't need to -+# handle add event. Because md/dm devices need to do some init jobs. -+# Then the change event happens. -+# When adding md/dm devices, ID_FS_TYPE can only be linux_raid_member -+# after change event happens. - ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc" - - # "noiswmd" on kernel command line stops mdadm from handling -@@ -28,6 +33,9 @@ GOTO="md_inc_end" - - LABEL="md_inc" - -+# Bare disks are ready when add event happens, the raid can be assembled. -+ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end" -+ - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' - ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --- -2.38.1 - diff --git a/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch b/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch deleted file mode 100644 index e2c1179..0000000 --- a/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b3e7b7eb1dfedd7cbd9a3800e884941f67d94c96 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:42 +0100 -Subject: [PATCH 80/83] Manage: do not check array state when drive is removed - -Array state doesn't need to be checked when drive is -removed, but until now clean state was required. Result -of the is_remove_safe() function will be independent -from array state. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Manage.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 594e3d2c..4d6e54b1 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1321,8 +1321,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - sysfs_free(mdi); - - bool is_enough = enough(array->level, array->raid_disks, -- array->layout, (array->state & 1), -- avail); -+ array->layout, 1, avail); - - free(avail); - return is_enough; --- -2.38.1 - diff --git a/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch b/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch deleted file mode 100644 index 4e0169c..0000000 --- a/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 461fae7e7809670d286cc19aac5bfa861c29f93a Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:43 +0100 -Subject: [PATCH 81/83] incremental, manage: do not verify if remove is safe - -Function is_remove_safe() was introduced to verify if removing -member device won't cause failed state of the array. This -verification should be used only with set-faulty command. Add -special mode indicating that Incremental removal was executed. -If this mode is used do not execute is_remove_safe() routine. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Incremental.c | 2 +- - Manage.c | 7 ++++--- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index ff3548c0..09b94b9f 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1744,7 +1744,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - memset(&devlist, 0, sizeof(devlist)); - devlist.devname = devname; -- devlist.disposition = 'f'; -+ devlist.disposition = 'I'; - /* for a container, we must fail each member array */ - if (ent->metadata_version && - strncmp(ent->metadata_version, "external:", 9) == 0) { -diff --git a/Manage.c b/Manage.c -index 4d6e54b1..6184d3f7 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1494,8 +1494,9 @@ int Manage_subdevs(char *devname, int fd, - /* Assume this is a kernel-internal name like 'sda1' */ - int found = 0; - char dname[55]; -- if (dv->disposition != 'r' && dv->disposition != 'f') { -- pr_err("%s only meaningful with -r or -f, not -%c\n", -+ if (dv->disposition != 'r' && dv->disposition != 'f' && -+ dv->disposition != 'I') { -+ pr_err("%s only meaningful with -r, -f or -I, not -%c\n", - dv->devname, dv->disposition); - goto abort; - } -@@ -1647,7 +1648,7 @@ int Manage_subdevs(char *devname, int fd, - close(sysfd); - goto abort; - } -- -+ case 'I': /* incremental fail */ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch b/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch deleted file mode 100644 index 0035c89..0000000 --- a/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 071f839ea549e2a384cd13bba445245cd87e48b1 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 28 Oct 2022 04:51:17 +0200 -Subject: [PATCH 82/83] super-intel: make freesize not required for chunk size - migration - -Freesize is needed to be set for migrations where size of RAID could -be changed - expand. It tells how many free space is determined for -members. In chunk size migartion freesize is not needed to be set, -pointer shouldn't be checked if exists. This commit moves check to -condition which contains size calculations, instead of checking it -always at the first step. -Fix return value when superblock is not set. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - super-intel.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 1f5f6eda..89fac626 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7719,11 +7719,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - struct intel_super *super = st->sb; - - /* -- * Autolayout mode, st->sb and freesize must be set. -+ * Autolayout mode, st->sb must be set. - */ -- if (!super || !freesize) { -- pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -- return 1; -+ if (!super) { -+ pr_vrb("superblock must be set for autolayout, aborting\n"); -+ return 0; - } - - if (!validate_geometry_imsm_orom(st->sb, level, layout, -@@ -7731,7 +7731,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - verbose)) - return 0; - -- if (super->orom) { -+ if (super->orom && freesize) { - imsm_status_t rv; - int count = count_volumes(super->hba, super->orom->dpa, - verbose); --- -2.38.1 - diff --git a/SOURCES/0083-manage-move-comment-with-function-description.patch b/SOURCES/0083-manage-move-comment-with-function-description.patch deleted file mode 100644 index 091854f..0000000 --- a/SOURCES/0083-manage-move-comment-with-function-description.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 36a707824eb1dafbb990f5daf1cbbe0e37dbbefb Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 5 Jan 2023 06:31:25 +0100 -Subject: [PATCH 83/83] manage: move comment with function description - -Move the function description from the function body to outside -to obey kernel coding style. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Manage.c | 72 ++++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 44 insertions(+), 28 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 6184d3f7..fde6aba3 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1327,38 +1327,54 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - return is_enough; - } - -+/** -+ * Manage_subdevs() - Execute operation depending on devmode. -+ * -+ * @devname: name of the device. -+ * @fd: file descriptor. -+ * @devlist: list of sub-devices to manage. -+ * @verbose: verbose level. -+ * @test: test flag. -+ * @update: type of update. -+ * @force: force flag. -+ * -+ * This function executes operation defined by devmode -+ * for each dev from devlist. -+ * Devmode can be: -+ * 'a' - add the device -+ * 'S' - add the device as a spare - don't try re-add -+ * 'j' - add the device as a journal device -+ * 'A' - re-add the device -+ * 'r' - remove the device: HOT_REMOVE_DISK -+ * device can be 'faulty' or 'detached' in which case all -+ * matching devices are removed. -+ * 'f' - set the device faulty SET_DISK_FAULTY -+ * device can be 'detached' in which case any device that -+ * is inaccessible will be marked faulty. -+ * 'I' - remove device by using incremental fail -+ * which is executed when device is removed surprisingly. -+ * 'R' - mark this device as wanting replacement. -+ * 'W' - this device is added if necessary and activated as -+ * a replacement for a previous 'R' device. -+ * ----- -+ * 'w' - 'W' will be changed to 'w' when it is paired with -+ * a 'R' device. If a 'W' is found while walking the list -+ * it must be unpaired, and is an error. -+ * 'M' - this is created by a 'missing' target. It is a slight -+ * variant on 'A' -+ * 'F' - Another variant of 'A', where the device was faulty -+ * so must be removed from the array first. -+ * 'c' - confirm the device as found (for clustered environments) -+ * -+ * For 'f' and 'r', the device can also be a kernel-internal -+ * name such as 'sdb'. -+ * -+ * Return: 0 on success, otherwise 1 or 2. -+ */ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - enum update_opt update, int force) - { -- /* Do something to each dev. -- * devmode can be -- * 'a' - add the device -- * 'S' - add the device as a spare - don't try re-add -- * 'j' - add the device as a journal device -- * 'A' - re-add the device -- * 'r' - remove the device: HOT_REMOVE_DISK -- * device can be 'faulty' or 'detached' in which case all -- * matching devices are removed. -- * 'f' - set the device faulty SET_DISK_FAULTY -- * device can be 'detached' in which case any device that -- * is inaccessible will be marked faulty. -- * 'R' - mark this device as wanting replacement. -- * 'W' - this device is added if necessary and activated as -- * a replacement for a previous 'R' device. -- * ----- -- * 'w' - 'W' will be changed to 'w' when it is paired with -- * a 'R' device. If a 'W' is found while walking the list -- * it must be unpaired, and is an error. -- * 'M' - this is created by a 'missing' target. It is a slight -- * variant on 'A' -- * 'F' - Another variant of 'A', where the device was faulty -- * so must be removed from the array first. -- * 'c' - confirm the device as found (for clustered environments) -- * -- * For 'f' and 'r', the device can also be a kernel-internal -- * name such as 'sdb'. -- */ - mdu_array_info_t array; - unsigned long long array_size; - struct mddev_dev *dv; --- -2.38.1 - diff --git a/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch b/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch deleted file mode 100644 index 493a0e9..0000000 --- a/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 28a083955c6f58f8e582734c8c82aff909a7d461 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 2 Feb 2023 08:56:31 +0100 -Subject: [PATCH 084/125] Revert "mdadm/systemd: remove KillMode=none from - service file" - -This reverts commit 52c67fcdd6dadc4138ecad73e65599551804d445. - -The functionality is marked as deprecated but we don't have alternative -solution yet. Shutdown hangs if OS is installed on external array: - -task:umount state:D stack: 0 pid: 6285 ppid: flags:0x00004084 -Call Trace: -__schedule+0x2d1/0x830 -? finish_wait+0x80/0x80 -schedule+0x35/0xa0 -md_write_start+0x14b/0x220 -? finish_wait+0x80/0x80 -raid1_make_request+0x3c/0x90 [raid1] -md_handle_request+0x128/0x1b0 -md_make_request+0x5b/0xb0 -generic_make_request_no_check+0x202/0x330 -submit_bio+0x3c/0x160 - -Use it until new solution is implemented. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdmon@.service | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 64b8254a..9ccadca3 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,3 +15,4 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null -+KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 97a1acd9..cb6482d9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -26,3 +26,4 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid -+KillMode=none --- -2.38.1 - diff --git a/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch b/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch deleted file mode 100644 index d0ff1ff..0000000 --- a/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Thu, 23 Feb 2023 22:39:39 +0800 -Subject: [PATCH 085/125] Grow: fix can't change bitmap type from none to - clustered. - -Commit a042210648ed ("disallow create or grow clustered bitmap with -writemostly set") introduced this bug. We should use 'true' logic not -'== 0' to deny setting up clustered array under WRITEMOSTLY condition. - -How to trigger - -``` -~/mdadm # ./mdadm -Ss && ./mdadm --zero-superblock /dev/sd{a,b} -~/mdadm # ./mdadm -C /dev/md0 -l mirror -b clustered -e 1.2 -n 2 \ -/dev/sda /dev/sdb --assume-clean -mdadm: array /dev/md0 started. -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=none -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=clustered -mdadm: /dev/md0 disks marked write-mostly are not supported with clustered bitmap -``` - -Signed-off-by: Heming Zhao -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8f5cf07d..bb5fe45c 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -429,7 +429,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - dv = map_dev(disk.major, disk.minor, 1); - if (!dv) - continue; -- if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && -+ if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); - free(mdi); --- -2.38.1 - diff --git a/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch b/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch deleted file mode 100644 index 766874b..0000000 --- a/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch +++ /dev/null @@ -1,76 +0,0 @@ -From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001 -From: Li Xiao Keng -Date: Mon, 27 Feb 2023 11:12:07 +0800 -Subject: [PATCH 086/125] Fix NULL dereference in super_by_fd - -When we create 100 partitions (major is 259 not 254) in a raid device, -mdadm may coredump: - -Core was generated by `/usr/sbin/mdadm --detail --export /dev/md1p7'. -Program terminated with signal SIGSEGV, Segmentation fault. -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -74 VPCMPEQ (%rdi), %ymm0, %ymm1 -(gdb) bt -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -#1 0x00007fbb9a7e4139 in __strcpy_chk (dest=dest@entry=0x55d55d6a13ac "", src=0x0, destlen=destlen@entry=32) at strcpy_chk.c:28 -#2 0x000055d55ba1766d in strcpy (__src=, __dest=0x55d55d6a13ac "") at /usr/include/bits/string_fortified.h:79 -#3 super_by_fd (fd=fd@entry=3, subarrayp=subarrayp@entry=0x7fff44dfcc48) at util.c:1289 -#4 0x000055d55ba273a6 in Detail (dev=0x7fff44dfef0b "/dev/md1p7", c=0x7fff44dfe440) at Detail.c:101 -#5 0x000055d55ba0de61 in misc_list (c=, ss=, dump_directory=, ident=, devlist=) at mdadm.c:1959 -#6 main (argc=, argv=) at mdadm.c:1629 - -The direct cause is fd2devnm returning NULL, so add a check. - -Signed-off-by: Li Xiao Keng -Signed-off-by: Wu Guang Hao -Acked-by: Coly Li -Acked-by: Coly Li > -Signed-off-by: Jes Sorensen ---- - mapfile.c | 4 ++++ - util.c | 7 ++++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/mapfile.c b/mapfile.c -index 6b2207dd..ac351768 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -292,6 +292,10 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) - struct map_ent *map_by_devnm(struct map_ent **map, char *devnm) - { - struct map_ent *mp; -+ -+ if (!devnm) -+ return NULL; -+ - if (!*map) - map_read(map); - -diff --git a/util.c b/util.c -index 9cd89fa4..8c7f3fd5 100644 ---- a/util.c -+++ b/util.c -@@ -1160,6 +1160,11 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - int i; - char *subarray = NULL; - char container[32] = ""; -+ char *devnm = NULL; -+ -+ devnm = fd2devnm(fd); -+ if (!devnm) -+ return NULL; - - sra = sysfs_read(fd, NULL, GET_VERSION); - -@@ -1205,7 +1210,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - if (subarrayp) - *subarrayp = subarray; - strcpy(st->container_devnm, container); -- strcpy(st->devnm, fd2devnm(fd)); -+ strncpy(st->devnm, devnm, MD_NAME_MAX - 1); - } else - free(subarray); - --- -2.38.1 - diff --git a/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch b/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch deleted file mode 100644 index 6819fba..0000000 --- a/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch +++ /dev/null @@ -1,369 +0,0 @@ -From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:26:59 +0100 -Subject: [PATCH 087/125] Mdmonitor: Make alert_info global - -Move information about --test flag and hostname into alert_info. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 124 +++++++++++++++++++++++++++--------------------------- - 1 file changed, 61 insertions(+), 63 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 188cb8be..9ef4dab8 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -58,21 +58,20 @@ struct state { - }; - - struct alert_info { -+ char hostname[HOST_NAME_MAX]; - char *mailaddr; - char *mailfrom; - char *alert_cmd; - int dosyslog; --}; -+ int test; -+} info; - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); --static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *info, -- int increments, char *prefer); --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info); --static void try_spare_migration(struct state *statelist, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); -+static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV -@@ -132,7 +131,6 @@ int Monitor(struct mddev_dev *devlist, - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -- struct alert_info info; - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -@@ -166,6 +164,13 @@ int Monitor(struct mddev_dev *devlist, - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; - info.dosyslog = dosyslog; -+ info.test = c->test; -+ -+ if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { -+ pr_err("Cannot get hostname.\n"); -+ return 1; -+ } -+ info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ - if (check_one_sharer(c->scan)) -@@ -241,8 +246,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat = mdstat_read(oneshot ? 0 : 1, 0); - - for (st = statelist; st; st = st->next) { -- if (check_array(st, mdstat, c->test, &info, -- increments, c->prefer)) -+ if (check_array(st, mdstat, increments, c->prefer)) - anydegraded = 1; - /* for external arrays, metadata is filled for - * containers only -@@ -255,15 +259,14 @@ int Monitor(struct mddev_dev *devlist, - - /* now check if there are any new devices found in mdstat */ - if (c->scan) -- new_found = add_new_arrays(mdstat, &statelist, c->test, -- &info); -+ new_found = add_new_arrays(mdstat, &statelist); - - /* If an array has active < raid && spare == 0 && spare_group != NULL - * Look for another array with spare > 0 and active == raid and same spare_group - * if found, choose a device and hotremove/hotadd - */ - if (share && anydegraded) -- try_spare_migration(statelist, &info); -+ try_spare_migration(statelist); - if (!new_found) { - if (oneshot) - break; -@@ -294,7 +297,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat_close(); - } - } -- c->test = 0; -+ info.test = 0; - - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { -@@ -412,7 +415,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -424,15 +427,14 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void send_event_email(const char *event, const char *dev, const char *disc) - { - FILE *mp, *mdstat; -- char hname[256]; - char buf[BUFSIZ]; - int n; - -@@ -442,14 +444,13 @@ static void send_event_email(const char *event, const char *dev, const char *dis - return; - } - -- gethostname(hname, sizeof(hname)); - signal(SIGPIPE, SIG_IGN); -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -+ if (info.mailfrom) -+ fprintf(mp, "From: %s\n", info.mailfrom); - else - fprintf(mp, "From: %s monitoring \n", Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "To: %s\n", info.mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); - fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); - -@@ -501,37 +502,36 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - syslog(priority, "%s event detected on md device %s", event, dev); - } - --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void alert(const char *event, const char *dev, const char *disc) - { -- if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { -+ if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) -- execute_alert_cmd(event, dev, disc, info); -+ if (info.alert_cmd) -+ execute_alert_cmd(event, dev, disc); - -- if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || -+ if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc, info); -+ send_event_email(event, dev, disc); - } - -- if (info->dosyslog) -+ if (info.dosyslog) - log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *ainfo, - int increments, char *prefer) - { - /* Update the state 'st' to reflect any changes shown in mdstat, - * or found by directly examining the array, and return - * '1' if the array is degraded, or '0' if it is optimal (or dead). - */ -- struct { int state, major, minor; } info[MAX_DISKS]; -+ struct { int state, major, minor; } disks_info[MAX_DISKS]; - struct mdinfo *sra = NULL; - mdu_array_info_t array; - struct mdstat_ent *mse = NULL, *mse2; -@@ -545,8 +545,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int is_container = 0; - unsigned long redundancy_only_flags = 0; - -- if (test) -- alert("TestMessage", dev, NULL, ainfo); -+ if (info.test) -+ alert("TestMessage", dev, NULL); - - retval = 0; - -@@ -595,7 +595,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); -+ alert("DeviceDisappeared", dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +612,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL, ainfo); -+ alert("NewArray", st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,14 +625,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL, ainfo); -+ alert("DegradedArray", dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL, ainfo); -+ alert("SparesMissing", dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL, ainfo); -+ alert("RebuildStarted", dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - char percentalert[18]; -@@ -647,7 +647,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(percentalert, sizeof(percentalert), - "Rebuild%02d", mse->percent); - -- alert(percentalert, dev, NULL, ainfo); -+ alert(percentalert, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +660,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt, ainfo); -+ alert("RebuildFinished", dev, cnt); - } else -- alert("RebuildFinished", dev, NULL, ainfo); -+ alert("RebuildFinished", dev, NULL); - } - st->percent = mse->percent; - -@@ -671,13 +671,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - mdu_disk_info_t disc; - disc.number = i; - if (md_get_disk_info(fd, &disc) >= 0) { -- info[i].state = disc.state; -- info[i].major = disc.major; -- info[i].minor = disc.minor; -+ disks_info[i].state = disc.state; -+ disks_info[i].major = disc.major; -+ disks_info[i].minor = disc.minor; - if (disc.major || disc.minor) - remaining_disks --; - } else -- info[i].major = info[i].minor = 0; -+ disks_info[i].major = disks_info[i].minor = 0; - } - last_disk = i; - -@@ -700,13 +700,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int change; - char *dv = NULL; - disc.number = i; -- if (i < last_disk && (info[i].major || info[i].minor)) { -- newstate = info[i].state; -- dv = map_dev_preferred(info[i].major, info[i].minor, 1, -+ if (i < last_disk && (disks_info[i].major || disks_info[i].minor)) { -+ newstate = disks_info[i].state; -+ dv = map_dev_preferred(disks_info[i].major, disks_info[i].minor, 1, - prefer); - disc.state = newstate; -- disc.major = info[i].major; -- disc.minor = info[i].minor; -+ disc.major = disks_info[i].major; -+ disc.minor = disks_info[i].minor; - } else - newstate = (1 << MD_DISK_REMOVED); - -@@ -716,14 +716,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv, ainfo); -+ alert("Fail", dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv, ainfo); -+ alert("FailSpare", dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv, ainfo); -+ alert("SpareActive", dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,13 +747,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL, ainfo); -+ alert("DeviceDisappeared", dev, NULL); - st->err++; - goto out; - } - --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info) -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - { - struct mdstat_ent *mse; - int new_found = 0; -@@ -806,8 +805,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - } else - st->parent_devnm[0] = 0; - *statelist = st; -- if (test) -- alert("TestMessage", st->devname, NULL, info); -+ if (info.test) -+ alert("TestMessage", st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -971,7 +970,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to, - return dev; - } - --static void try_spare_migration(struct state *statelist, struct alert_info *info) -+static void try_spare_migration(struct state *statelist) - { - struct state *from; - struct state *st; -@@ -1030,8 +1029,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, -- from->devname, info); -+ alert("MoveSpare", to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch b/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch deleted file mode 100644 index 770d3d1..0000000 --- a/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch +++ /dev/null @@ -1,313 +0,0 @@ -From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:00 +0100 -Subject: [PATCH 088/125] Mdmonitor: Pass events to alert() using enums instead - of strings - -Add events enum, and mapping_t struct, that maps them to strings, so -that enums are passed around instead of strings. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 136 +++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 83 insertions(+), 53 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 9ef4dab8..029e9efd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,8 @@ - #include - #endif - -+#define EVENT_NAME_MAX 32 -+ - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ - char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ -@@ -65,10 +67,43 @@ struct alert_info { - int dosyslog; - int test; - } info; -+ -+enum event { -+ EVENT_SPARE_ACTIVE = 0, -+ EVENT_NEW_ARRAY, -+ EVENT_MOVE_SPARE, -+ EVENT_TEST_MESSAGE, -+ EVENT_REBUILD_STARTED, -+ EVENT_REBUILD, -+ EVENT_REBUILD_FINISHED, -+ EVENT_SPARES_MISSING, -+ EVENT_DEVICE_DISAPPEARED, -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_UNKNOWN -+}; -+ -+mapping_t events_map[] = { -+ {"SpareActive", EVENT_SPARE_ACTIVE}, -+ {"NewArray", EVENT_NEW_ARRAY}, -+ {"MoveSpare", EVENT_MOVE_SPARE}, -+ {"TestMessage", EVENT_TEST_MESSAGE}, -+ {"RebuildStarted", EVENT_REBUILD_STARTED}, -+ {"Rebuild", EVENT_REBUILD}, -+ {"RebuildFinished", EVENT_REBUILD_FINISHED}, -+ {"SparesMissing", EVENT_SPARES_MISSING}, -+ {"DeviceDisappeared", EVENT_DEVICE_DISAPPEARED}, -+ {"Fail", EVENT_FAIL}, -+ {"FailSpare", EVENT_FAIL_SPARE}, -+ {"DegradedArray", EVENT_DEGRADED_ARRAY}, -+ {NULL, EVENT_UNKNOWN} -+}; -+ - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc); -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); - static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); -@@ -415,7 +450,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc) -+static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -427,12 +462,12 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc) -+static void send_event_email(const char *event_name, const char *dev, const char *disc) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -450,9 +485,9 @@ static void send_event_email(const char *event, const char *dev, const char *dis - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); - - if (disc && disc[0] != ' ') - fprintf(mp, -@@ -474,20 +509,20 @@ static void send_event_email(const char *event, const char *dev, const char *dis - pclose(mp); - } - --static void log_event_to_syslog(const char *event, const char *dev, const char *disc) -+static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) - { - int priority; - /* Log at a different severity depending on the event. - * - * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -+ if (event_enum == EVENT_FAIL || -+ event_enum == EVENT_DEGRADED_ARRAY || -+ event_enum == EVENT_DEVICE_DISAPPEARED) - priority = LOG_CRIT; - /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -+ else if (event_enum == EVENT_REBUILD || -+ event_enum == EVENT_MOVE_SPARE || -+ event_enum == EVENT_SPARES_MISSING) - priority = LOG_WARNING; - /* Everything else: */ - else -@@ -495,33 +530,37 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - - if (disc && disc[0] != ' ') - syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -+ "%s event detected on md device %s, component device %s", -+ event_name, dev, disc); - else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); - else -- syslog(priority, "%s event detected on md device %s", event, dev); -+ syslog(priority, "%s event detected on md device %s", event_name, dev); - } - --static void alert(const char *event, const char *dev, const char *disc) -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) - { -- if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { -- time_t now = time(0); -+ char event_name[EVENT_NAME_MAX]; - -- printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, -- event, dev, disc?disc:"unknown device"); -+ if (event_enum == EVENT_REBUILD) { -+ snprintf(event_name, sizeof(event_name), "%s%02d", -+ map_num_s(events_map, EVENT_REBUILD), progress); -+ } else { -+ snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); - } -+ - if (info.alert_cmd) -- execute_alert_cmd(event, dev, disc); -+ execute_alert_cmd(event_name, dev, disc); - -- if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Test", 4) == 0 || -- strncmp(event, "Spares", 6) == 0 || -- strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc); -+ if (info.mailaddr && (event_enum == EVENT_FAIL || -+ event_enum == EVENT_TEST_MESSAGE || -+ event_enum == EVENT_SPARES_MISSING || -+ event_enum == EVENT_DEGRADED_ARRAY)) { -+ send_event_email(event_name, dev, disc); - } - - if (info.dosyslog) -- log_event_to_syslog(event, dev, disc); -+ log_event_to_syslog(event_enum, event_name, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -546,7 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert("TestMessage", dev, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, dev, NULL); - - retval = 0; - -@@ -595,7 +634,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +651,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,29 +664,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL); -+ alert(EVENT_SPARES_MISSING, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { -- char percentalert[18]; -- /* -- * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) -- */ -- - if((mse->percent / increments) == 0) -- snprintf(percentalert, sizeof(percentalert), -- "RebuildStarted"); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - else -- snprintf(percentalert, sizeof(percentalert), -- "Rebuild%02d", mse->percent); -- -- alert(percentalert, dev, NULL); -+ alert(EVENT_REBUILD, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +690,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); - } else -- alert("RebuildFinished", dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -716,14 +746,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv); -+ alert(EVENT_FAIL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv); -+ alert(EVENT_FAIL_SPARE, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv); -+ alert(EVENT_SPARE_ACTIVE, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,7 +777,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); - st->err++; - goto out; - } -@@ -806,7 +836,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert("TestMessage", st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1029,7 +1059,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0089-Mdmonitor-Add-helper-functions.patch b/SOURCES/0089-Mdmonitor-Add-helper-functions.patch deleted file mode 100644 index 930b63a..0000000 --- a/SOURCES/0089-Mdmonitor-Add-helper-functions.patch +++ /dev/null @@ -1,406 +0,0 @@ -From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:01 +0100 -Subject: [PATCH 089/125] Mdmonitor: Add helper functions - -Add functions: -- is_email_event(), -- get_syslog_event_priority(), -- sprint_event_message(), -with kernel style comments containing more detailed descriptions. - -Also update event syslog priorities to be consistent with man. MoveSpare event was described in man as priority info, while implemented as warning. Move event data into a struct, so that it is passed between different functions if needed. -Sort function declarations alphabetically and remove redundant alert() declaration. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 228 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 158 insertions(+), 70 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 029e9efd..39598ba0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -73,10 +73,12 @@ enum event { - EVENT_NEW_ARRAY, - EVENT_MOVE_SPARE, - EVENT_TEST_MESSAGE, -+ __SYSLOG_PRIORITY_WARNING, - EVENT_REBUILD_STARTED, - EVENT_REBUILD, - EVENT_REBUILD_FINISHED, - EVENT_SPARES_MISSING, -+ __SYSLOG_PRIORITY_CRITICAL, - EVENT_DEVICE_DISAPPEARED, - EVENT_FAIL, - EVENT_FAIL_SPARE, -@@ -100,18 +102,31 @@ mapping_t events_map[] = { - {NULL, EVENT_UNKNOWN} - }; - --static int make_daemon(char *pidfile); --static int check_one_sharer(int scan); --static void write_autorebuild_pid(void); --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); --static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+struct event_data { -+ enum event event_enum; -+ /* -+ * @event_name: Rebuild event name must be in form "RebuildXX", where XX is rebuild progress. -+ */ -+ char event_name[EVENT_NAME_MAX]; -+ char message[BUFSIZ]; -+ const char *description; -+ const char *dev; -+ const char *disc; -+}; -+ - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int check_one_sharer(int scan); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -+static void link_containers_with_subarrays(struct state *list); -+static int make_daemon(char *pidfile); -+static void try_spare_migration(struct state *statelist); -+static void write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -450,7 +465,80 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) -+#define BASE_MESSAGE "%s event detected on md device %s" -+#define COMPONENT_DEVICE_MESSAGE ", component device %s" -+#define DESCRIPTION_MESSAGE ": %s" -+/* -+ * sprint_event_message() - Writes basic message about detected event to destination ptr. -+ * @dest: message destination, should be at least the size of BUFSIZ -+ * @data: event data -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int sprint_event_message(char *dest, const struct event_data *data) -+{ -+ if (!dest || !data) -+ return 1; -+ -+ if (data->disc && data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->disc, data->description); -+ else if (data->disc) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE, -+ data->event_name, data->dev, data->disc); -+ else if (data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->description); -+ else -+ snprintf(dest, BUFSIZ, BASE_MESSAGE, data->event_name, data->dev); -+ -+ return 0; -+} -+ -+/* -+ * get_syslog_event_priority() - Determines event priority. -+ * @event_enum: event to be checked -+ * -+ * Return: LOG_CRIT, LOG_WARNING or LOG_INFO -+ */ -+static int get_syslog_event_priority(const enum event event_enum) -+{ -+ if (event_enum > __SYSLOG_PRIORITY_CRITICAL) -+ return LOG_CRIT; -+ if (event_enum > __SYSLOG_PRIORITY_WARNING) -+ return LOG_WARNING; -+ return LOG_INFO; -+} -+ -+/* -+ * is_email_event() - Determines whether email for event should be sent or not. -+ * @event_enum: event to be checked -+ * -+ * Return: true if email should be sent, false otherwise -+ */ -+static bool is_email_event(const enum event event_enum) -+{ -+ static const enum event email_events[] = { -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_SPARES_MISSING, -+ EVENT_TEST_MESSAGE -+ }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(email_events); ++i) { -+ if (event_enum == email_events[i]) -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * execute_alert_cmd() - Forks and executes command provided as alert_cmd. -+ * @data: event data -+ */ -+static void execute_alert_cmd(const struct event_data *data) - { - int pid = fork(); - -@@ -462,12 +550,16 @@ static void execute_alert_cmd(const char *event_name, const char *dev, const cha - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, data->event_name, data->dev, data->disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event_name, const char *dev, const char *disc) -+/* -+ * send_event_email() - Sends an email about event detected by monitor. -+ * @data: event data -+ */ -+static void send_event_email(const struct event_data *data) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -485,15 +577,9 @@ static void send_event_email(const char *event_name, const char *dev, const char - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); -- fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", data->event_name, data->dev, info.hostname); -+ fprintf(mp, "This is an automatically generated mail message.\n"); -+ fprintf(mp, "%s\n", data->message); - - mdstat = fopen("/proc/mdstat", "r"); - if (!mdstat) { -@@ -509,58 +595,60 @@ static void send_event_email(const char *event_name, const char *dev, const char - pclose(mp); - } - --static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) -+/* -+ * log_event_to_syslog() - Logs an event into syslog. -+ * @data: event data -+ */ -+static void log_event_to_syslog(const struct event_data *data) - { - int priority; -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (event_enum == EVENT_FAIL || -- event_enum == EVENT_DEGRADED_ARRAY || -- event_enum == EVENT_DEVICE_DISAPPEARED) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (event_enum == EVENT_REBUILD || -- event_enum == EVENT_MOVE_SPARE || -- event_enum == EVENT_SPARES_MISSING) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", -- event_name, dev, disc); -- else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); -- else -- syslog(priority, "%s event detected on md device %s", event_name, dev); -+ -+ priority = get_syslog_event_priority(data->event_enum); -+ -+ syslog(priority, "%s\n", data->message); - } - --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) -+/* -+ * alert() - Alerts about the monitor event. -+ * @event_enum: event to be sent -+ * @description: event description -+ * @progress: rebuild progress -+ * @dev: md device name -+ * @disc: component device -+ * -+ * If needed function executes alert command, sends an email or logs event to syslog. -+ */ -+static void alert(const enum event event_enum, const char *description, const uint8_t progress, -+ const char *dev, const char *disc) - { -- char event_name[EVENT_NAME_MAX]; -+ struct event_data data = {.dev = dev, .disc = disc, .description = description}; -+ -+ if (!dev) -+ return; - - if (event_enum == EVENT_REBUILD) { -- snprintf(event_name, sizeof(event_name), "%s%02d", -+ snprintf(data.event_name, sizeof(data.event_name), "%s%02d", - map_num_s(events_map, EVENT_REBUILD), progress); - } else { -- snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); -+ snprintf(data.event_name, sizeof(data.event_name), "%s", map_num_s(events_map, event_enum)); - } - -- if (info.alert_cmd) -- execute_alert_cmd(event_name, dev, disc); -+ data.event_enum = event_enum; - -- if (info.mailaddr && (event_enum == EVENT_FAIL || -- event_enum == EVENT_TEST_MESSAGE || -- event_enum == EVENT_SPARES_MISSING || -- event_enum == EVENT_DEGRADED_ARRAY)) { -- send_event_email(event_name, dev, disc); -+ if (sprint_event_message(data.message, &data) != 0) { -+ pr_err("Cannot create event message.\n"); -+ return; - } -+ pr_err("%s\n", data.message); -+ -+ if (info.alert_cmd) -+ execute_alert_cmd(&data); -+ -+ if (info.mailaddr && is_email_event(event_enum)) -+ send_event_email(&data); - - if (info.dosyslog) -- log_event_to_syslog(event_enum, event_name, dev, disc); -+ log_event_to_syslog(&data); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -585,7 +673,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, dev, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, dev, NULL); - - retval = 0; - -@@ -634,7 +722,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, "Wrong-Level", 0, dev, NULL); - st->err++; - goto out; - } -@@ -651,7 +739,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, NULL, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -664,20 +752,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, NULL, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert(EVENT_SPARES_MISSING, 0, dev, NULL); -+ alert(EVENT_SPARES_MISSING, NULL, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - if((mse->percent / increments) == 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - else -- alert(EVENT_REBUILD, mse->percent, dev, NULL); -+ alert(EVENT_REBUILD, NULL, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -690,9 +778,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, cnt); - } else -- alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -746,14 +834,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_FAIL, 0, dev, dv); -+ alert(EVENT_FAIL, NULL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert(EVENT_FAIL_SPARE, 0, dev, dv); -+ alert(EVENT_FAIL_SPARE, NULL, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_SPARE_ACTIVE, 0, dev, dv); -+ alert(EVENT_SPARE_ACTIVE, NULL, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -777,7 +865,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, NULL, 0, dev, NULL); - st->err++; - goto out; - } -@@ -836,7 +924,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1059,7 +1147,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, NULL, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch b/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch deleted file mode 100644 index 294f8af..0000000 --- a/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:02 +0100 -Subject: [PATCH 090/125] Add helpers to determine whether directories or files - are soft links - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.h | 2 ++ - util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/mdadm.h b/mdadm.h -index 13f8b4cb..1674ce13 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1777,6 +1777,8 @@ extern void set_dlm_hooks(void); - #define MSEC_TO_NSEC(msec) ((msec) * 1000000) - #define USEC_TO_NSEC(usec) ((usec) * 1000) - extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+extern bool is_directory(const char *path); -+extern bool is_file(const char *path); - - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) -diff --git a/util.c b/util.c -index 8c7f3fd5..7fc881bf 100644 ---- a/util.c -+++ b/util.c -@@ -2401,3 +2401,48 @@ void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) - } - } while (!wake_after_interrupt && errno == EINTR); - } -+ -+/* is_directory() - Checks if directory provided by path is indeed a regular directory. -+ * @path: directory path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a directory, false if not -+ */ -+bool is_directory(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISDIR(st.st_mode)) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * is_file() - Checks if file provided by path is indeed a regular file. -+ * @path: file path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a file, false if not -+ */ -+bool is_file(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISREG(st.st_mode)) -+ return false; -+ -+ return true; -+} --- -2.38.1 - diff --git a/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch b/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch deleted file mode 100644 index 84b4e63..0000000 --- a/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:03 +0100 -Subject: [PATCH 091/125] Mdmonitor: Refactor write_autorebuild_pid() - -Add better error handling and check for symlinks when opening MDMON_DIR. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 55 ++++++++++++++++++++++++++++++++++++------------------- - 1 file changed, 36 insertions(+), 19 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 39598ba0..14a2dfe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,6 +33,7 @@ - #endif - - #define EVENT_NAME_MAX 32 -+#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -@@ -126,7 +127,7 @@ static int check_udev_activity(void); - static void link_containers_with_subarrays(struct state *list); - static int make_daemon(char *pidfile); - static void try_spare_migration(struct state *statelist); --static void write_autorebuild_pid(void); -+static int write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -234,7 +235,8 @@ int Monitor(struct mddev_dev *devlist, - } - - if (share) -- write_autorebuild_pid(); -+ if (write_autorebuild_pid() != 0) -+ return 1; - - if (devlist == NULL) { - mdlist = conf_get_ident(NULL); -@@ -440,29 +442,44 @@ static int check_one_sharer(int scan) - return 0; - } - --static void write_autorebuild_pid() -+/* -+ * write_autorebuild_pid() - Writes pid to autorebuild.pid file. -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int write_autorebuild_pid(void) - { -- char path[PATH_MAX]; -- int pid; -- FILE *fp = NULL; -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -+ FILE *fp; -+ int fd; - - if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) { -- pr_err("Can't create autorebuild.pid file\n"); -- } else { -- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ pr_err("%s: %s\n", strerror(errno), MDMON_DIR); -+ return 1; -+ } - -- if (fd >= 0) -- fp = fdopen(fd, "w"); -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ return 1; -+ } - -- if (!fp) -- pr_err("Can't create autorebuild.pid file\n"); -- else { -- pid = getpid(); -- fprintf(fp, "%d\n", pid); -- fclose(fp); -- } -+ fd = open(AUTOREBUILD_PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ -+ if (fd < 0) { -+ pr_err("Error opening %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; - } -+ -+ fp = fdopen(fd, "w"); -+ -+ if (!fp) { -+ pr_err("Error opening fd for %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; -+ } -+ -+ fprintf(fp, "%d\n", getpid()); -+ -+ fclose(fp); -+ return 0; - } - - #define BASE_MESSAGE "%s event detected on md device %s" --- -2.38.1 - diff --git a/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch b/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch deleted file mode 100644 index f8708a1..0000000 --- a/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:04 +0100 -Subject: [PATCH 092/125] Mdmonitor: Refactor check_one_sharer() for better - error handling - -Also check if autorebuild.pid is a symlink, which we shouldn't accept. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 89 ++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 62 insertions(+), 27 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 14a2dfe5..44918184 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,7 @@ - #include - #endif - -+#define TASK_COMM_LEN 16 - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - -@@ -224,7 +225,7 @@ int Monitor(struct mddev_dev *devlist, - info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ -- if (check_one_sharer(c->scan)) -+ if (check_one_sharer(c->scan) == 2) - return 1; - } - -@@ -406,39 +407,73 @@ static int make_daemon(char *pidfile) - return -1; - } - -+/* -+ * check_one_sharer() - Checks for other mdmon processes running. -+ * -+ * Return: -+ * 0 - no other processes running, -+ * 1 - warning, -+ * 2 - error, or when scan mode is enabled, and one mdmon process already exists -+ */ - static int check_one_sharer(int scan) - { - int pid; -- FILE *comm_fp; -- FILE *fp; -+ FILE *fp, *comm_fp; - char comm_path[PATH_MAX]; -- char path[PATH_MAX]; -- char comm[20]; -- -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -- fp = fopen(path, "r"); -- if (fp) { -- if (fscanf(fp, "%d", &pid) != 1) -- pid = -1; -- snprintf(comm_path, sizeof(comm_path), -- "/proc/%d/comm", pid); -- comm_fp = fopen(comm_path, "r"); -- if (comm_fp) { -- if (fscanf(comm_fp, "%19s", comm) && -- strncmp(basename(comm), Name, strlen(Name)) == 0) { -- if (scan) { -- pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); -- fclose(comm_fp); -- fclose(fp); -- return 1; -- } else { -- pr_err("Warning: One autorebuild process already running.\n"); -- } -- } -+ char comm[TASK_COMM_LEN]; -+ -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ return 2; -+ } -+ -+ if (access(AUTOREBUILD_PID_PATH, F_OK) != 0) -+ return 0; -+ -+ if (!is_file(AUTOREBUILD_PID_PATH)) { -+ pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); -+ return 2; -+ } -+ -+ fp = fopen(AUTOREBUILD_PID_PATH, "r"); -+ if (!fp) { -+ pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); -+ return 2; -+ } -+ -+ if (fscanf(fp, "%d", &pid) != 1) { -+ pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); -+ fclose(fp); -+ return 2; -+ } -+ -+ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid); -+ -+ comm_fp = fopen(comm_path, "r"); -+ if (!comm_fp) { -+ dprintf("Warning: Cannot open %s, continuing\n", comm_path); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (fscanf(comm_fp, "%15s", comm) == 0) { -+ dprintf("Warning: Cannot read comm from %s, continuing\n", comm_path); -+ fclose(comm_fp); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (strncmp(basename(comm), Name, strlen(Name)) == 0) { -+ if (scan) { -+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); - fclose(comm_fp); -+ fclose(fp); -+ return 2; - } -- fclose(fp); -+ pr_err("Warning: One autorebuild process already running.\n"); - } -+ fclose(comm_fp); -+ fclose(fp); - return 0; - } - --- -2.38.1 - diff --git a/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch b/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch deleted file mode 100644 index dee708a..0000000 --- a/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Sat, 4 Mar 2023 00:21:30 +0800 -Subject: [PATCH 093/125] util.c: reorder code lines in parse_layout_faulty() - -Resort the code lines in parse_layout_faulty() to make it more -comfortable, no logic change. - -Signed-off-by: Coly Li -Reviewed-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - util.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/util.c b/util.c -index 7fc881bf..b0b7aec4 100644 ---- a/util.c -+++ b/util.c -@@ -421,12 +421,15 @@ int parse_layout_10(char *layout) - - int parse_layout_faulty(char *layout) - { -+ int ln, mode; -+ char *m; -+ - if (!layout) - return -1; -+ - /* Parse the layout string for 'faulty' */ -- int ln = strcspn(layout, "0123456789"); -- char *m = xstrdup(layout); -- int mode; -+ ln = strcspn(layout, "0123456789"); -+ m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); - if (mode == UnSet) --- -2.38.1 - diff --git a/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch b/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch deleted file mode 100644 index 255d195..0000000 --- a/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:31 +0800 -Subject: [PATCH 094/125] util.c: fix memleak in parse_layout_faulty() - -char *m is allocated by xstrdup but not free() before return, will cause -a memory leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util.c b/util.c -index b0b7aec4..9f1e1f7c 100644 ---- a/util.c -+++ b/util.c -@@ -432,6 +432,8 @@ int parse_layout_faulty(char *layout) - m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); -+ free(m); -+ - if (mode == UnSet) - return -1; - --- -2.38.1 - diff --git a/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch b/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch deleted file mode 100644 index f3d9846..0000000 --- a/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:32 +0800 -Subject: [PATCH 095/125] Detail.c: fix memleak in Detail() - -char *sysdev = xstrdup() but not free() in for loop, will cause memory -leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Detail.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Detail.c b/Detail.c -index ce7a8445..4ef26460 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -303,6 +303,7 @@ int Detail(char *dev, struct context *c) - if (path) - printf("MD_DEVICE_%s_DEV=%s\n", - sysdev, path); -+ free(sysdev); - } - } - goto out; --- -2.38.1 - diff --git a/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch b/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch deleted file mode 100644 index 2561c51..0000000 --- a/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:33 +0800 -Subject: [PATCH 096/125] isuper-intel.c: fix double free in load_imsm_mpb() - -In load_imsm_mpb() there is potential double free issue on super->buf. - -The first location to free super->buf is from get_super_block() <== -load_and_parse_mpb() <== load_imsm_mpb(): - 4514 if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE, - 4515 MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - 4516 pr_err("could not allocate migr_rec buffer\n"); - 4517 free(super->buf); - 4518 return 2; - 4519 } - -If the above error condition happens, super->buf is freed and value 2 -is returned to get_super_block() eventually. Then in the following code -block inside load_imsm_mpb(), - 5289 error: - 5290 if (!err) { - 5291 s->next = *super_list; - 5292 *super_list = s; - 5293 } else { - 5294 if (s) - 5295 free_imsm(s); - 5296 close_fd(&dfd); - 5297 } -at line 5295 when free_imsm() is called, super->buf is freed again from -the call chain free_imsm() <== __free_imsm(), in following code block, - 4651 if (super->buf) { - 4652 free(super->buf); - 4653 super->buf = NULL; - 4654 } - -This patch sets super->buf as NULL after line 4517 in load_imsm_mpb() -to avoid the potential double free(). - -(Coly Li helps to re-compose the commit log) - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/super-intel.c b/super-intel.c -index 89fac626..4a3da847 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -4515,6 +4515,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) - MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - pr_err("could not allocate migr_rec buffer\n"); - free(super->buf); -+ super->buf = NULL; - return 2; - } - super->clean_migration_record_by_mdmon = 0; --- -2.38.1 - diff --git a/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch b/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch deleted file mode 100644 index dbd5eeb..0000000 --- a/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:34 +0800 -Subject: [PATCH 097/125] super-intel.c: fix memleak in - find_disk_attached_hba() - -If disk_path = diskfd_to_devpath(), we need free(disk_path) before -return, otherwise there will be a memory leak - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 4a3da847..e155a8ae 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -713,12 +713,12 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) - - for (elem = list; elem; elem = elem->next) - if (path_attached_to_hba(disk_path, elem->path)) -- return elem; -+ break; - - if (disk_path != devname) - free(disk_path); - -- return NULL; -+ return elem; - } - - static int find_intel_hba_capability(int fd, struct intel_super *super, --- -2.38.1 - diff --git a/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch b/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch deleted file mode 100644 index d31b162..0000000 --- a/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:35 +0800 -Subject: [PATCH 098/125] super-ddf.c: fix memleak in get_vd_num_of_subarray() - -sra = sysfs_read() should be free before return in -get_vd_num_of_subarray() - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 309812df..b86c6acd 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1592,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st) - sra = sysfs_read(-1, st->devnm, GET_VERSION); - if (!sra || sra->array.major_version != -1 || - sra->array.minor_version != -2 || -- !is_subarray(sra->text_version)) -+ !is_subarray(sra->text_version)) { -+ if (sra) -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - sub = strchr(sra->text_version + 1, '/'); - if (sub != NULL) - vcnum = strtoul(sub + 1, &end, 10); - if (sub == NULL || *sub == '\0' || *end != '\0' || -- vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) -+ vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) { -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - return vcnum; - } --- -2.38.1 - diff --git a/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch b/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch deleted file mode 100644 index dacf428..0000000 --- a/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:29 -0700 -Subject: [PATCH 099/125] Create: goto abort_locked instead of return 1 in - error path - -The return 1 after the fstat_is_blkdev() check should be replaced -with an error return that goes through the error path to unlock -resources locked by this function. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index 953e7372..2e8203ec 100644 ---- a/Create.c -+++ b/Create.c -@@ -939,7 +939,7 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- return 1; -+ goto abort_locked; - inf->disk.major = major(rdev); - inf->disk.minor = minor(rdev); - } --- -2.38.1 - diff --git a/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch b/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch deleted file mode 100644 index a813d87..0000000 --- a/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:30 -0700 -Subject: [PATCH 100/125] Create: remove safe_mode_delay local variable - -All .getinfo_super() call sets the info.safe_mode_delay variables -to a constant value, so no matter what the current state is -that function will always set it to the same value. - -Create() calls .getinfo_super() multiple times while creating the array. -The value is stored in a local variable for every disk in the loop -to add disks (so the last disc call takes precedence). The local -variable is then used in the call to sysfs_set_safemode(). - -This can be simplified by using info.safe_mode_delay directly. The info -variable had .getinfo_super() called on it early in the function so, by the -reasoning above, it will have the same value as the local variable which -can thus be removed. - -Doing this allows for factoring out code from Create() in a subsequent -patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 2e8203ec..8ded81dc 100644 ---- a/Create.c -+++ b/Create.c -@@ -137,7 +137,6 @@ int Create(struct supertype *st, char *mddev, - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -- unsigned long safe_mode_delay = 0; - char chosen_name[1024]; - struct map_ent *map = NULL; - unsigned long long newsize; -@@ -952,7 +951,6 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - st->ss->getinfo_super(st, inf, NULL); -- safe_mode_delay = inf->safe_mode_delay; - - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", -@@ -1065,7 +1063,7 @@ int Create(struct supertype *st, char *mddev, - "readonly"); - break; - } -- sysfs_set_safemode(&info, safe_mode_delay); -+ sysfs_set_safemode(&info, info.safe_mode_delay); - if (err) { - pr_err("failed to activate array.\n"); - ioctl(mdfd, STOP_ARRAY, NULL); --- -2.38.1 - diff --git a/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch b/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch deleted file mode 100644 index 6546497..0000000 --- a/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch +++ /dev/null @@ -1,452 +0,0 @@ -From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:31 -0700 -Subject: [PATCH 101/125] Create: Factor out add_disks() helpers - -The Create function is massive with a very large number of variables. -Reading and understanding the function is almost impossible. To help -with this, factor out the two pass loop that adds the disks to the array. - -This moves about 160 lines into three new helper functions and removes -a bunch of local variables from the main Create function. The main new -helper function add_disks() does the two pass loop and calls into -add_disk_to_super() and update_metadata(). Factoring out the -latter two helpers also helps to reduce a ton of indentation. - -No functional changes intended. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 382 +++++++++++++++++++++++++++++++------------------------ - 1 file changed, 213 insertions(+), 169 deletions(-) - -diff --git a/Create.c b/Create.c -index 8ded81dc..6a044664 100644 ---- a/Create.c -+++ b/Create.c -@@ -91,6 +91,214 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, -+ struct supertype *st, struct mddev_dev *dv, -+ struct mdinfo *info, int have_container, int major_num) -+{ -+ dev_t rdev; -+ int fd; -+ -+ if (dv->disposition == 'j') { -+ info->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -+ info->disk.state = (1<disk.raid_disk < s->raiddisks) { -+ info->disk.state = (1<disk.state = 0; -+ } -+ -+ if (dv->writemostly == FlagSet) { -+ if (major_num == BITMAP_MAJOR_CLUSTERED) { -+ pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -+ return 1; -+ } else { -+ info->disk.state |= (1<failfast == FlagSet) -+ info->disk.state |= (1<ss->external && st->container_devnm[0]) -+ fd = open(dv->devname, O_RDWR); -+ else -+ fd = open(dv->devname, O_RDWR|O_EXCL); -+ -+ if (fd < 0) { -+ pr_err("failed to open %s after earlier success - aborting\n", -+ dv->devname); -+ return 1; -+ } -+ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -+ return 1; -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ if (fd >= 0) -+ remove_partitions(fd); -+ if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, -+ dv->data_offset)) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ st->ss->getinfo_super(st, info, NULL); -+ -+ if (have_container && c->verbose > 0) -+ pr_err("Using %s for device %d\n", -+ map_dev(info->disk.major, info->disk.minor, 0), -+ info->disk.number); -+ -+ if (!have_container) { -+ /* getinfo_super might have lost these ... */ -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ -+ return 0; -+} -+ -+static int update_metadata(int mdfd, struct shape *s, struct supertype *st, -+ struct map_ent **map, struct mdinfo *info, -+ char *chosen_name) -+{ -+ struct mdinfo info_new; -+ struct map_ent *me = NULL; -+ -+ /* check to see if the uuid has changed due to these -+ * metadata changes, and if so update the member array -+ * and container uuid. Note ->write_init_super clears -+ * the subarray cursor such that ->getinfo_super once -+ * again returns container info. -+ */ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ if (st->ss->external && is_container(s->level) && -+ !same_uuid(info_new.uuid, info->uuid, 0)) { -+ map_update(map, fd2devnm(mdfd), -+ info_new.text_version, -+ info_new.uuid, chosen_name); -+ me = map_by_devnm(map, st->container_devnm); -+ } -+ -+ if (st->ss->write_init_super(st)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* -+ * Before activating the array, perform extra steps -+ * required to configure the internal write-intent -+ * bitmap. -+ */ -+ if (info_new.consistency_policy == CONSISTENCY_POLICY_BITMAP && -+ st->ss->set_bitmap && st->ss->set_bitmap(st, info)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* update parent container uuid */ -+ if (me) { -+ char *path = xstrdup(me->path); -+ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ map_update(map, st->container_devnm, info_new.text_version, -+ info_new.uuid, path); -+ free(path); -+ } -+ -+ flush_metadata_updates(st); -+ st->ss->free_super(st); -+ -+ return 0; -+} -+ -+static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, -+ struct context *c, struct supertype *st, -+ struct map_ent **map, struct mddev_dev *devlist, -+ int total_slots, int have_container, int insert_point, -+ int major_num, char *chosen_name) -+{ -+ struct mddev_dev *moved_disk = NULL; -+ int pass, raid_disk_num, dnum; -+ struct mddev_dev *dv; -+ struct mdinfo *infos; -+ int ret = 0; -+ -+ infos = xmalloc(sizeof(*infos) * total_slots); -+ enable_fds(total_slots); -+ for (pass = 1; pass <= 2; pass++) { -+ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -+ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -+ if (dnum >= total_slots) -+ abort(); -+ if (dnum == insert_point) { -+ raid_disk_num += 1; -+ moved_disk = dv; -+ continue; -+ } -+ if (strcasecmp(dv->devname, "missing") == 0) { -+ raid_disk_num += 1; -+ continue; -+ } -+ if (have_container) -+ moved_disk = NULL; -+ if (have_container && dnum < total_slots - 1) -+ /* repeatedly use the container */ -+ moved_disk = dv; -+ -+ switch(pass) { -+ case 1: -+ infos[dnum] = *info; -+ infos[dnum].disk.number = dnum; -+ infos[dnum].disk.raid_disk = raid_disk_num++; -+ -+ if (dv->disposition == 'j') -+ raid_disk_num--; -+ -+ ret = add_disk_to_super(mdfd, s, c, st, dv, -+ &infos[dnum], have_container, -+ major_num); -+ if (ret) -+ goto out; -+ -+ break; -+ case 2: -+ infos[dnum].errors = 0; -+ -+ ret = add_disk(mdfd, st, info, &infos[dnum]); -+ if (ret) { -+ pr_err("ADD_NEW_DISK for %s failed: %s\n", -+ dv->devname, strerror(errno)); -+ if (errno == EINVAL && -+ info->array.level == 0) { -+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -+ pr_err("Either upgrade, or use --layout=dangerous\n"); -+ } -+ goto out; -+ } -+ break; -+ } -+ if (!have_container && -+ dv == moved_disk && dnum != insert_point) break; -+ } -+ -+ if (pass == 1) { -+ ret = update_metadata(mdfd, s, st, map, info, -+ chosen_name); -+ if (ret) -+ goto out; -+ } -+ } -+ -+out: -+ free(infos); -+ return ret; -+} -+ - int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, -@@ -117,7 +325,7 @@ int Create(struct supertype *st, char *mddev, - unsigned long long minsize = 0, maxsize = 0; - char *mindisc = NULL; - char *maxdisc = NULL; -- int dnum, raid_disk_num; -+ int dnum; - struct mddev_dev *dv; - dev_t rdev; - int fail = 0, warn = 0; -@@ -126,14 +334,13 @@ int Create(struct supertype *st, char *mddev, - int missing_disks = 0; - int insert_point = subdevs * 2; /* where to insert a missing drive */ - int total_slots; -- int pass; - int rv; - int bitmap_fd; - int have_container = 0; - int container_fd = -1; - int need_mdmon = 0; - unsigned long long bitmapsize; -- struct mdinfo info, *infos; -+ struct mdinfo info; - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -@@ -869,174 +1076,11 @@ int Create(struct supertype *st, char *mddev, - } - } - -- infos = xmalloc(sizeof(*infos) * total_slots); -- enable_fds(total_slots); -- for (pass = 1; pass <= 2; pass++) { -- struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */ -- -- for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -- dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -- int fd; -- struct mdinfo *inf = &infos[dnum]; -- -- if (dnum >= total_slots) -- abort(); -- if (dnum == insert_point) { -- raid_disk_num += 1; -- moved_disk = dv; -- continue; -- } -- if (strcasecmp(dv->devname, "missing") == 0) { -- raid_disk_num += 1; -- continue; -- } -- if (have_container) -- moved_disk = NULL; -- if (have_container && dnum < info.array.raid_disks - 1) -- /* repeatedly use the container */ -- moved_disk = dv; -- -- switch(pass) { -- case 1: -- *inf = info; -- -- inf->disk.number = dnum; -- inf->disk.raid_disk = raid_disk_num++; -- -- if (dv->disposition == 'j') { -- inf->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -- inf->disk.state = (1<disk.raid_disk < s->raiddisks) -- inf->disk.state = (1<disk.state = 0; -- -- if (dv->writemostly == FlagSet) { -- if (major_num == BITMAP_MAJOR_CLUSTERED) { -- pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -- goto abort_locked; -- } else -- inf->disk.state |= (1<failfast == FlagSet) -- inf->disk.state |= (1<ss->external && -- st->container_devnm[0]) -- fd = open(dv->devname, O_RDWR); -- else -- fd = open(dv->devname, O_RDWR|O_EXCL); -- -- if (fd < 0) { -- pr_err("failed to open %s after earlier success - aborting\n", -- dv->devname); -- goto abort_locked; -- } -- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- goto abort_locked; -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- if (fd >= 0) -- remove_partitions(fd); -- if (st->ss->add_to_super(st, &inf->disk, -- fd, dv->devname, -- dv->data_offset)) { -- ioctl(mdfd, STOP_ARRAY, NULL); -- goto abort_locked; -- } -- st->ss->getinfo_super(st, inf, NULL); -- -- if (have_container && c->verbose > 0) -- pr_err("Using %s for device %d\n", -- map_dev(inf->disk.major, -- inf->disk.minor, -- 0), dnum); -- -- if (!have_container) { -- /* getinfo_super might have lost these ... */ -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- break; -- case 2: -- inf->errors = 0; -- -- rv = add_disk(mdfd, st, &info, inf); -- -- if (rv) { -- pr_err("ADD_NEW_DISK for %s failed: %s\n", -- dv->devname, strerror(errno)); -- if (errno == EINVAL && -- info.array.level == 0) { -- pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -- pr_err("Either upgrade, or use --layout=dangerous\n"); -- } -- goto abort_locked; -- } -- break; -- } -- if (!have_container && -- dv == moved_disk && dnum != insert_point) break; -- } -- if (pass == 1) { -- struct mdinfo info_new; -- struct map_ent *me = NULL; -- -- /* check to see if the uuid has changed due to these -- * metadata changes, and if so update the member array -- * and container uuid. Note ->write_init_super clears -- * the subarray cursor such that ->getinfo_super once -- * again returns container info. -- */ -- st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && !is_container(s->level) && -- !same_uuid(info_new.uuid, info.uuid, 0)) { -- map_update(&map, fd2devnm(mdfd), -- info_new.text_version, -- info_new.uuid, chosen_name); -- me = map_by_devnm(&map, st->container_devnm); -- } -- -- if (st->ss->write_init_super(st)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- /* -- * Before activating the array, perform extra steps -- * required to configure the internal write-intent -- * bitmap. -- */ -- if (info_new.consistency_policy == -- CONSISTENCY_POLICY_BITMAP && -- st->ss->set_bitmap && -- st->ss->set_bitmap(st, &info)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- -- /* update parent container uuid */ -- if (me) { -- char *path = xstrdup(me->path); -- -- st->ss->getinfo_super(st, &info_new, NULL); -- map_update(&map, st->container_devnm, -- info_new.text_version, -- info_new.uuid, path); -- free(path); -- } -+ if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots, -+ have_container, insert_point, major_num, chosen_name)) -+ goto abort_locked; - -- flush_metadata_updates(st); -- st->ss->free_super(st); -- } -- } - map_unlock(&map); -- free(infos); - - if (is_container(s->level)) { - /* No need to start. But we should signal udev to --- -2.38.1 - diff --git a/SOURCES/0102-mdadm-Introduce-pr_info.patch b/SOURCES/0102-mdadm-Introduce-pr_info.patch deleted file mode 100644 index 4059e20..0000000 --- a/SOURCES/0102-mdadm-Introduce-pr_info.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:32 -0700 -Subject: [PATCH 102/125] mdadm: Introduce pr_info() - -Feedback was given to avoid informational pr_err() calls that print -to stderr, even though that's done all through out the code. - -Using printf() directly doesn't maintain the same format (an "mdadm" -prefix on every line. - -So introduce pr_info() which prints to stdout with the same format -and use it for a couple informational pr_err() calls in Create(). - -Future work can make this call used in more cases. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Acked-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - Create.c | 7 ++++--- - mdadm.h | 2 ++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 6a044664..4acda30c 100644 ---- a/Create.c -+++ b/Create.c -@@ -984,11 +984,12 @@ int Create(struct supertype *st, char *mddev, - - mdi = sysfs_read(-1, devnm, GET_VERSION); - -- pr_err("Creating array inside %s container %s\n", -+ pr_info("Creating array inside %s container %s\n", - mdi?mdi->text_version:"managed", devnm); - sysfs_free(mdi); - } else -- pr_err("Defaulting to version %s metadata\n", info.text_version); -+ pr_info("Defaulting to version %s metadata\n", -+ info.text_version); - } - - map_update(&map, fd2devnm(mdfd), info.text_version, -@@ -1145,7 +1146,7 @@ int Create(struct supertype *st, char *mddev, - ioctl(mdfd, RESTART_ARRAY_RW, NULL); - } - if (c->verbose >= 0) -- pr_err("array %s started.\n", mddev); -+ pr_info("array %s started.\n", mddev); - if (st->ss->external && st->container_devnm[0]) { - if (need_mdmon) - start_mdmon(st->container_devnm); -diff --git a/mdadm.h b/mdadm.h -index 1674ce13..4336be4d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1854,6 +1854,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { - #endif - #define cont_err(fmt ...) fprintf(stderr, " " fmt) - -+#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) -+ - void *xmalloc(size_t len); - void *xrealloc(void *ptr, size_t len); - void *xcalloc(size_t num, size_t size); --- -2.38.1 - diff --git a/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch b/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch deleted file mode 100644 index 2f39174..0000000 --- a/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:33 -0700 -Subject: [PATCH 103/125] mdadm: Add --write-zeros option for Create - -Add the --write-zeros option for Create which will send a write zeros -request to all the disks before assembling the array. After zeroing -the array, the disks will be in a known clean state and the initial -sync may be skipped. - -Writing zeroes is best used when there is a hardware offload method -to zero the data. But even still, zeroing can take several minutes on -a large device. Because of this, all disks are zeroed in parallel using -their own forked process and a message is printed to the user. The main -process will proceed only after all the zeroing processes have completed -successfully. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - ReadMe.c | 2 + - mdadm.c | 9 +++ - mdadm.h | 5 ++ - 4 files changed, 190 insertions(+), 2 deletions(-) - -diff --git a/Create.c b/Create.c -index 4acda30c..bbe9e13d 100644 ---- a/Create.c -+++ b/Create.c -@@ -26,6 +26,10 @@ - #include "md_u.h" - #include "md_p.h" - #include -+#include -+#include -+#include -+#include - - static int round_size_and_verify(unsigned long long *size, int chunk) - { -@@ -91,9 +95,149 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static pid_t write_zeroes_fork(int fd, struct shape *s, struct supertype *st, -+ struct mddev_dev *dv) -+ -+{ -+ const unsigned long long req_size = 1 << 30; -+ unsigned long long offset_bytes, size_bytes, sz; -+ sigset_t sigset; -+ int ret = 0; -+ pid_t pid; -+ -+ size_bytes = KIB_TO_BYTES(s->size); -+ -+ /* -+ * If size_bytes is zero, this is a zoned raid array where -+ * each disk is of a different size and uses its full -+ * disk. Thus zero the entire disk. -+ */ -+ if (!size_bytes && !get_dev_size(fd, dv->devname, &size_bytes)) -+ return -1; -+ -+ if (dv->data_offset != INVALID_SECTORS) -+ offset_bytes = SEC_TO_BYTES(dv->data_offset); -+ else -+ offset_bytes = SEC_TO_BYTES(st->data_offset); -+ -+ pr_info("zeroing data from %lld to %lld on: %s\n", -+ offset_bytes, size_bytes, dv->devname); -+ -+ pid = fork(); -+ if (pid < 0) { -+ pr_err("Could not fork to zero disks: %s\n", strerror(errno)); -+ return pid; -+ } else if (pid != 0) { -+ return pid; -+ } -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_UNBLOCK, &sigset, NULL); -+ -+ while (size_bytes) { -+ /* -+ * Split requests to the kernel into 1GB chunks seeing the -+ * fallocate() call is not interruptible and blocking a -+ * ctrl-c for several minutes is not desirable. -+ * -+ * 1GB is chosen as a compromise: the user may still have -+ * to wait several seconds if they ctrl-c on devices that -+ * zero slowly, but will reduce the number of requests -+ * required and thus the overhead on devices that perform -+ * better. -+ */ -+ sz = size_bytes; -+ if (sz >= req_size) -+ sz = req_size; -+ -+ if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, -+ offset_bytes, sz)) { -+ pr_err("zeroing %s failed: %s\n", dv->devname, -+ strerror(errno)); -+ ret = 1; -+ break; -+ } -+ -+ offset_bytes += sz; -+ size_bytes -= sz; -+ } -+ -+ exit(ret); -+} -+ -+static int wait_for_zero_forks(int *zero_pids, int count) -+{ -+ int wstatus, ret = 0, i, sfd, wait_count = 0; -+ struct signalfd_siginfo fdsi; -+ bool interrupted = false; -+ sigset_t sigset; -+ ssize_t s; -+ -+ for (i = 0; i < count; i++) -+ if (zero_pids[i]) -+ wait_count++; -+ if (!wait_count) -+ return 0; -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigaddset(&sigset, SIGCHLD); -+ sigprocmask(SIG_BLOCK, &sigset, NULL); -+ -+ sfd = signalfd(-1, &sigset, 0); -+ if (sfd < 0) { -+ pr_err("Unable to create signalfd: %s\n", strerror(errno)); -+ return 1; -+ } -+ -+ while (1) { -+ s = read(sfd, &fdsi, sizeof(fdsi)); -+ if (s != sizeof(fdsi)) { -+ pr_err("Invalid signalfd read: %s\n", strerror(errno)); -+ close(sfd); -+ return 1; -+ } -+ -+ if (fdsi.ssi_signo == SIGINT) { -+ printf("\n"); -+ pr_info("Interrupting zeroing processes, please wait...\n"); -+ interrupted = true; -+ } else if (fdsi.ssi_signo == SIGCHLD) { -+ if (!--wait_count) -+ break; -+ } -+ } -+ -+ close(sfd); -+ -+ for (i = 0; i < count; i++) { -+ if (!zero_pids[i]) -+ continue; -+ -+ waitpid(zero_pids[i], &wstatus, 0); -+ zero_pids[i] = 0; -+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) -+ ret = 1; -+ } -+ -+ if (interrupted) { -+ pr_err("zeroing interrupted!\n"); -+ return 1; -+ } -+ -+ if (ret) -+ pr_err("zeroing failed!\n"); -+ else -+ pr_info("zeroing finished\n"); -+ -+ return ret; -+} -+ - static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - struct supertype *st, struct mddev_dev *dv, -- struct mdinfo *info, int have_container, int major_num) -+ struct mdinfo *info, int have_container, int major_num, -+ int *zero_pid) - { - dev_t rdev; - int fd; -@@ -148,6 +292,14 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - } - st->ss->getinfo_super(st, info, NULL); - -+ if (fd >= 0 && s->write_zeroes) { -+ *zero_pid = write_zeroes_fork(fd, s, st, dv); -+ if (*zero_pid <= 0) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ } -+ - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", - map_dev(info->disk.major, info->disk.minor, 0), -@@ -224,10 +376,23 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - { - struct mddev_dev *moved_disk = NULL; - int pass, raid_disk_num, dnum; -+ int zero_pids[total_slots]; - struct mddev_dev *dv; - struct mdinfo *infos; -+ sigset_t sigset, orig_sigset; - int ret = 0; - -+ /* -+ * Block SIGINT so the main thread will always wait for the -+ * zeroing processes when being interrupted. Otherwise the -+ * zeroing processes will finish their work in the background -+ * keeping the disk busy. -+ */ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_BLOCK, &sigset, &orig_sigset); -+ memset(zero_pids, 0, sizeof(zero_pids)); -+ - infos = xmalloc(sizeof(*infos) * total_slots); - enable_fds(total_slots); - for (pass = 1; pass <= 2; pass++) { -@@ -261,7 +426,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - - ret = add_disk_to_super(mdfd, s, c, st, dv, - &infos[dnum], have_container, -- major_num); -+ major_num, &zero_pids[dnum]); - if (ret) - goto out; - -@@ -287,6 +452,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - if (pass == 1) { -+ ret = wait_for_zero_forks(zero_pids, total_slots); -+ if (ret) -+ goto out; -+ - ret = update_metadata(mdfd, s, st, map, info, - chosen_name); - if (ret) -@@ -295,7 +464,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - out: -+ if (ret) -+ wait_for_zero_forks(zero_pids, total_slots); - free(infos); -+ sigprocmask(SIG_SETMASK, &orig_sigset, NULL); - return ret; - } - -diff --git a/ReadMe.c b/ReadMe.c -index bd8d50d2..db251ed2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -138,6 +138,7 @@ struct option long_options[] = { - {"size", 1, 0, 'z'}, - {"auto", 1, 0, Auto}, /* also for --assemble */ - {"assume-clean",0,0, AssumeClean }, -+ {"write-zeroes",0,0, WriteZeroes }, - {"metadata", 1, 0, 'e'}, /* superblock format */ - {"bitmap", 1, 0, Bitmap}, - {"bitmap-chunk", 1, 0, BitmapChunk}, -@@ -390,6 +391,7 @@ char Help_create[] = - " --write-journal= : Specify journal device for RAID-4/5/6 array\n" - " --consistency-policy= : Specify the policy that determines how the array\n" - " -k : maintains consistency in case of unexpected shutdown.\n" -+" --write-zeroes : Write zeroes to the disks before creating. This will bypass initial sync.\n" - "\n" - ; - -diff --git a/mdadm.c b/mdadm.c -index 57e8e6fa..4685ad6b 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -590,6 +590,10 @@ int main(int argc, char *argv[]) - s.assume_clean = 1; - continue; - -+ case O(CREATE, WriteZeroes): -+ s.write_zeroes = 1; -+ continue; -+ - case O(GROW,'n'): - case O(CREATE,'n'): - case O(BUILD,'n'): /* number of raid disks */ -@@ -1251,6 +1255,11 @@ int main(int argc, char *argv[]) - } - } - -+ if (s.write_zeroes && !s.assume_clean) { -+ pr_info("Disk zeroing requested, setting --assume-clean to skip resync\n"); -+ s.assume_clean = 1; -+ } -+ - if (!mode && devs_found) { - mode = MISC; - devmode = 'Q'; -diff --git a/mdadm.h b/mdadm.h -index 4336be4d..b9127f9a 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -275,6 +275,9 @@ static inline void __put_unaligned32(__u32 val, void *p) - - #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -+#define KIB_TO_BYTES(x) ((x) << 10) -+#define SEC_TO_BYTES(x) ((x) << 9) -+ - extern const char Name[]; - - struct md_bb_entry { -@@ -435,6 +438,7 @@ extern char Version[], Usage[], Help[], OptionHelp[], - */ - enum special_options { - AssumeClean = 300, -+ WriteZeroes, - BitmapChunk, - WriteBehind, - ReAdd, -@@ -640,6 +644,7 @@ struct shape { - int bitmap_chunk; - char *bitmap_file; - int assume_clean; -+ bool write_zeroes; - int write_behind; - unsigned long long size; - unsigned long long data_offset; --- -2.38.1 - diff --git a/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch b/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch deleted file mode 100644 index 441aef2..0000000 --- a/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c918cf2af993b55bca9f396c79713e54d3f8b6fb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:34 -0700 -Subject: [PATCH 104/125] tests/00raid5-zero: Introduce test to exercise - --write-zeros. - -Attempt to create a raid5 array with --write-zeros. If it is successful -check the array to ensure it is in sync. - -If it is unsuccessful and an unsupported error is printed, skip the -test. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - tests/00raid5-zero | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - create mode 100644 tests/00raid5-zero - -diff --git a/tests/00raid5-zero b/tests/00raid5-zero -new file mode 100644 -index 00000000..7d0f05a1 ---- /dev/null -+++ b/tests/00raid5-zero -@@ -0,0 +1,12 @@ -+ -+if mdadm -CfR $md0 -l 5 -n3 $dev0 $dev1 $dev2 --write-zeroes ; then -+ check nosync -+ echo check > /sys/block/md0/md/sync_action; -+ check wait -+elif grep "zeroing [^ ]* failed: Operation not supported" \ -+ $targetdir/stderr; then -+ echo "write-zeros not supported, skipping" -+else -+ echo >&2 "ERROR: mdadm return failure without not supported message" -+ exit 1 -+fi --- -2.38.1 - diff --git a/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch b/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch deleted file mode 100644 index 16a0e3f..0000000 --- a/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:35 -0700 -Subject: [PATCH 105/125] manpage: Add --write-zeroes option to manpage - -Document the new --write-zeroes option in the manpage. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 64f71ed1..6f0f6c13 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -837,6 +837,22 @@ array is resynced at creation. From Linux version 3.0, - .B \-\-assume\-clean - can be used with that command to avoid the automatic resync. - -+.TP -+.BR \-\-write-zeroes -+When creating an array, send write zeroes requests to all the block -+devices. This should zero the data area on all disks such that the -+initial sync is not necessary and, if successfull, will behave -+as if -+.B \-\-assume\-clean -+was specified. -+.IP -+This is intended for use with devices that have hardware offload for -+zeroing, but despite this zeroing can still take several minutes for -+large disks. Thus a message is printed before and after zeroing and -+each disk is zeroed in parallel with the others. -+.IP -+This is only meaningful with --create. -+ - .TP - .BR \-\-backup\-file= - This is needed when -@@ -1370,7 +1386,7 @@ and - .B layout\-alternate - options are for RAID0 arrays with non-uniform devices size that were in - use before Linux 5.4. If the array was being used with Linux 3.13 or --earlier, then to assemble the array on a new kernel, -+earlier, then to assemble the array on a new kernel, - .B \-\-update=layout\-original - must be given. If the array was created and used with a kernel from Linux 3.14 to - Linux 5.3, then --- -2.38.1 - diff --git a/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch b/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch deleted file mode 100644 index 13765d8..0000000 --- a/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Wed, 18 Jan 2023 00:32:36 -0800 -Subject: [PATCH 106/125] Define alignof using _Alignof when using C11 or newer - -WG14 N2350 made very clear that it is an UB having type definitions -within "offsetof" [1]. This patch enhances the implementation of macro -alignof_slot to use builtin "_Alignof" to avoid undefined behavior on -when using std=c11 or newer - -clang 16+ has started to flag this [2] - -Fixes build when using -std >= gnu11 and using clang16+ - -Older compilers gcc < 4.9 or clang < 8 has buggy _Alignof even though it -may support C11, exclude those compilers too - -[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm -[2] https://reviews.llvm.org/D133574 - -Upstream-Status: Pending -Signed-off-by: Khem Raj -Signed-off-by: Jes Sorensen ---- - sha1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/sha1.c b/sha1.c -index 89b32f46..1e4ad5d9 100644 ---- a/sha1.c -+++ b/sha1.c -@@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) - if (len >= 64) - { - #if !_STRING_ARCH_unaligned --# define alignof(type) offsetof (struct { char c; type x; }, x) -+/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 -+ . -+ clang versions < 8.0.0 have the same bug. */ -+# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ -+ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ -+ && !defined __clang__) \ -+ || (defined __clang__ && __clang_major__ < 8)) -+# define alignof(type) offsetof (struct { char c; type x; }, x) -+# else -+# define alignof(type) _Alignof(type) -+# endif - # define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) --- -2.38.1 - diff --git a/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch b/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch deleted file mode 100644 index 20f2755..0000000 --- a/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch +++ /dev/null @@ -1,41 +0,0 @@ -From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 107/125] Use existence of /etc/initrd-release to detect - initrd. - -Since v183, systemd has used the existence of /etc/initrd-release to -detect if it is running in an initrd, rather than looking at the magic -number of the root filesystem's device. It is time for mdadm to do the -same. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - util.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/util.c b/util.c -index 9f1e1f7c..509fb43e 100644 ---- a/util.c -+++ b/util.c -@@ -2227,15 +2227,7 @@ int continue_via_systemd(char *devnm, char *service_name) - - int in_initrd(void) - { -- /* This is based on similar function in systemd. */ -- struct statfs s; -- /* statfs.f_type is signed long on s390x and MIPS, causing all -- sorts of sign extension problems with RAMFS_MAGIC being -- defined as 0x858458f6 */ -- return statfs("/", &s) >= 0 && -- ((unsigned long)s.f_type == TMPFS_MAGIC || -- ((unsigned long)s.f_type & 0xFFFFFFFFUL) == -- ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL)); -+ return access("/etc/initrd-release", F_OK) >= 0; - } - - void reopen_mddev(int mdfd) --- -2.38.1 - diff --git a/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch b/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch deleted file mode 100644 index 0926a9d..0000000 --- a/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 108/125] mdmon: don't test both 'all' and 'container_name'. - -If 'all' is not set, then container_name must be NULL, as nothing else -can set it. So simplify the test to ignore container_name. -This makes the purpose of the code more obvious. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdmon.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 60ba3182..f8fd2f0f 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -352,7 +352,6 @@ int main(int argc, char *argv[]) - } - } - -- - if (in_initrd()) { - /* - * set first char of argv[0] to @. This is used by -@@ -362,12 +361,10 @@ int main(int argc, char *argv[]) - argv[0][0] = '@'; - } - -- if (all == 0 && container_name == NULL) { -- if (argv[optind]) { -- container_name = get_md_name(argv[optind]); -- if (!container_name) -- return 1; -- } -+ if (!all && argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ return 1; - } - - if (container_name == NULL || argc - optind > 1) --- -2.38.1 - diff --git a/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch b/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch deleted file mode 100644 index b2822c8..0000000 --- a/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 109/125] mdmon: change systemd unit file to use --foreground - -There is no value in mdmon forking when it is running under systemd - -systemd can still track it anyway. - -So add --foreground option, and remove "Type=forking". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index cb6482d9..bba9b0eb 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -20,8 +20,7 @@ Environment=IMSM_NO_PLATFORM=1 - # 'takeover'. As the '--offroot --takeover' don't hurt when - # not necessary, are are useful with root-on-md in dracut, - # have them always present. --ExecStart=BINDIR/mdmon --offroot --takeover %I --Type=forking -+ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # Don't set the PIDFile. It isn't necessary (systemd can work - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. --- -2.38.1 - diff --git a/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch b/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch deleted file mode 100644 index d1cde02..0000000 --- a/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 110/125] mdmon: Remove need for KillMode=none - -mdmon needs to keep running during the switchroot out of (at boot) and -then back into (at shutdown) the initrd. It runs until a new mdmon -takes over. - -Killmode=none is used to achieve this, with the help of --offroot which -sets argv[0][0] to '@' which systemd understands. - -This is needed because mdmon is currently run in system-mdmon.slice -which conflicts with shutdown.target so without Killmode=none mdmon -would get killed early in shutdown when system.mdmon.slice is removed. - -As described in systemd.service(5), this conflict with shutdown can be -resolved by explicitly requesting system.slice, which is a natural -counterpart to DefaultDependencies=no. - -So add that, and also add IgnoreOnIsolate=true to avoid another possible -source of an early death. With these we no longer need KillMode=none -which the systemd developers have marked as "deprecated". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index bba9b0eb..303ad05c 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -10,6 +10,9 @@ Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -+# Allow mdmon to keep running after switchroot, until a new -+# instance is started. -+IgnoreOnIsolate=true - - [Service] - # mdmon should never complain due to lack of a platform, -@@ -25,4 +28,6 @@ ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none -+# The default slice is system-mdmon.slice which Conflicts -+# with shutdown, causing mdmon to exit early. So use system.slice. -+Slice=system.slice --- -2.38.1 - diff --git a/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch b/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch deleted file mode 100644 index 96fedb3..0000000 --- a/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 111/125] mdmon: Improve switchroot interactions. - -We need a new mdmon@mdfoo instance to run in the root filesystem after -switch root, as /sys and /dev are removed from the initrd. - -systemd will not start a new unit with the same name running while the -old unit is still active, and we want the two mdmon processes to overlap -in time to avoid any risk of deadlock, which can happen when a write is -attempted with no mdmon running. - -So we need a different unit name in the initrd than in the root. Apart -from the name, everything else should be the same. - -This is easily achieved using a different instance name as the -mdmon@.service unit file already supports multiple instances (for -different arrays). - -So start "mdmon@mdfoo.service" from root, but -"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which -circumstance is the case by looking for /etc/initrd-release. -continue_from_systemd() is enhanced so that the "initrd-" prefix can be -requested. - -Teach mdmon that a container name like "initrd/foo" should be treated -just like "foo". Note that systemd passes the instance name -"initrd-foo" as "initrd/foo". - -We don't need a similar mechanism at shutdown because dracut runs -"mdmon --takeover --all" when appropriate. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - mdadm.h | 2 +- - mdmon.c | 7 ++++++- - systemd/mdmon@.service | 2 +- - udev-md-raid-arrays.rules | 3 ++- - util.c | 7 ++++--- - 6 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/Grow.c b/Grow.c -index bb5fe45c..06001f2d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3516,7 +3516,7 @@ started: - - if (!forked) - if (continue_via_systemd(container ?: sra->sys_name, -- GROW_SERVICE)) { -+ GROW_SERVICE, NULL)) { - free(fdlist); - free(offsets); - sysfs_free(sra); -@@ -3714,7 +3714,7 @@ int reshape_container(char *container, char *devname, - ping_monitor(container); - - if (!forked && !freeze_reshape) -- if (continue_via_systemd(container, GROW_SERVICE)) -+ if (continue_via_systemd(container, GROW_SERVICE, NULL)) - return 0; - - switch (forked ? 0 : fork()) { -diff --git a/mdadm.h b/mdadm.h -index b9127f9a..1e518276 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1608,7 +1608,7 @@ extern int same_dev(char *one, char *two); - extern int compare_paths (char* path1,char* path2); - extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); --extern int continue_via_systemd(char *devnm, char *service_name); -+extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); - -diff --git a/mdmon.c b/mdmon.c -index f8fd2f0f..096b4d76 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -362,7 +362,12 @@ int main(int argc, char *argv[]) - } - - if (!all && argv[optind]) { -- container_name = get_md_name(argv[optind]); -+ static const char prefix[] = "initrd/"; -+ container_name = argv[optind]; -+ if (strncmp(container_name, prefix, -+ sizeof(prefix) - 1) == 0) -+ container_name += sizeof(prefix)-1; -+ container_name = get_md_name(container_name); - if (!container_name) - return 1; - } -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 303ad05c..23a375f6 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -6,7 +6,7 @@ - # (at your option) any later version. - - [Unit] --Description=MD Metadata Monitor on /dev/%I -+Description=MD Metadata Monitor on %I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 2967ace1..4e64b249 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" - - # Tell systemd to run mdmon for our container, if we need it. - ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" --ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" -+ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service" -+ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" - ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" - - LABEL="md_end" -diff --git a/util.c b/util.c -index 509fb43e..d70ca43b 100644 ---- a/util.c -+++ b/util.c -@@ -1916,6 +1916,7 @@ int start_mdmon(char *devnm) - int len; - pid_t pid; - int status; -+ char *prefix = in_initrd() ? "initrd-" : ""; - char pathbuf[1024]; - char *paths[4] = { - pathbuf, -@@ -1926,7 +1927,7 @@ int start_mdmon(char *devnm) - - if (check_env("MDADM_NO_MDMON")) - return 0; -- if (continue_via_systemd(devnm, MDMON_SERVICE)) -+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix)) - return 0; - - /* That failed, try running mdmon directly */ -@@ -2197,7 +2198,7 @@ void manage_fork_fds(int close_all) - * 1- if systemd service has been started - * 0- otherwise - */ --int continue_via_systemd(char *devnm, char *service_name) -+int continue_via_systemd(char *devnm, char *service_name, char *prefix) - { - int pid, status; - char pathbuf[1024]; -@@ -2209,7 +2210,7 @@ int continue_via_systemd(char *devnm, char *service_name) - case 0: - manage_fork_fds(1); - snprintf(pathbuf, sizeof(pathbuf), -- "%s@%s.service", service_name, devnm); -+ "%s@%s%s.service", service_name, prefix ?: "", devnm); - status = execl("/usr/bin/systemctl", "systemctl", "restart", - pathbuf, NULL); - status = execl("/bin/systemctl", "systemctl", "restart", --- -2.38.1 - diff --git a/SOURCES/0112-mdopen-always-try-create_named_array.patch b/SOURCES/0112-mdopen-always-try-create_named_array.patch deleted file mode 100644 index 6d857ad..0000000 --- a/SOURCES/0112-mdopen-always-try-create_named_array.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Tue, 14 Mar 2023 11:06:25 +1100 -Subject: [PATCH 112/125] mdopen: always try create_named_array() - -mdopen() will use create_named_array() to ask the kernel to create the -given md array, but only if it is given a number or name. -If it is NOT given a name and is required to choose one itself using -find_free_devnm() it does NOT use create_named_array(). - -On kernels with CONFIG_BLOCK_LEGACY_AUTOLOAD not set, this can result in -failure to assemble an array. This can particularly seen when the -"name" of the array begins with a host name different to the name of the -host running the command. - -So add the missing call to create_named_array(). - -Link: https://bugzilla.kernel.org/show_bug.cgi?id=217074 -Signed-off-by: NeilBrown -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdopen.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/mdopen.c b/mdopen.c -index d18c9319..810f79a3 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - } - if (block_udev) - udev_block(devnm); -+ create_named_array(devnm); - } - - sprintf(devname, "/dev/%s", devnm); --- -2.38.1 - diff --git a/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch b/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch deleted file mode 100644 index 1a510f1..0000000 --- a/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 20 Mar 2023 14:43:54 +1100 -Subject: [PATCH 113/125] Improvements for IMSM_NO_PLATFORM testing. - -Factor out IMSM_NO_PLATFORM testing into a single function that caches -the result. - -Allow mdmon to explicitly set the result to "1" so that we don't need -the ENV var in the unit file - -Check if the kernel command line contains "mdadm.imsm.test=1" and in -that case assert NO_PLATFORM. This simplifies testing in a virtual -machine. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 5 +++++ - mdadm.h | 2 ++ - mdmon.c | 6 ++++++ - super-intel.c | 45 +++++++++++++++++++++++++++++++++++++++--- - systemd/mdmon@.service | 3 --- - 5 files changed, 55 insertions(+), 6 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 6f0f6c13..b7159509 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -3197,6 +3197,11 @@ environment. This can be useful for testing or for disaster - recovery. You should be aware that interoperability may be - compromised by setting this value. - -+These change can also be suppressed by adding -+.B mdadm.imsm.test=1 -+to the kernel command line. This makes it easy to test IMSM -+code in a virtual machine that doesn't have IMSM virtual hardware. -+ - .TP - .B MDADM_GROW_ALLOW_OLD - If an array is stopped while it is performing a reshape and that -diff --git a/mdadm.h b/mdadm.h -index 1e518276..0d995445 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1263,6 +1263,8 @@ extern struct superswitch super0, super1; - extern struct superswitch super_imsm, super_ddf; - extern struct superswitch mbr, gpt; - -+void imsm_set_no_platform(int v); -+ - struct metadata_update { - int len; - char *buf; -diff --git a/mdmon.c b/mdmon.c -index 096b4d76..cef5bbc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -318,6 +318,12 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -+ /* -+ * mdmon should never complain due to lack of a platform, -+ * that is mdadm's job if at all. -+ */ -+ imsm_set_no_platform(1); -+ - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -diff --git a/super-intel.c b/super-intel.c -index e155a8ae..a5c86cb2 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -20,6 +20,7 @@ - #define HAVE_STDINT_H 1 - #include "mdadm.h" - #include "mdmon.h" -+#include "dlink.h" - #include "sha1.h" - #include "platform-intel.h" - #include -@@ -629,6 +630,44 @@ static const char *_sys_dev_type[] = { - [SYS_DEV_VMD] = "VMD" - }; - -+static int no_platform = -1; -+ -+static int check_no_platform(void) -+{ -+ static const char search[] = "mdadm.imsm.test=1"; -+ FILE *fp; -+ -+ if (no_platform >= 0) -+ return no_platform; -+ -+ if (check_env("IMSM_NO_PLATFORM")) { -+ no_platform = 1; -+ return 1; -+ } -+ fp = fopen("/proc/cmdline", "r"); -+ if (fp) { -+ char *l = conf_line(fp); -+ char *w = l; -+ -+ do { -+ if (strcmp(w, search) == 0) -+ no_platform = 1; -+ w = dl_next(w); -+ } while (w != l); -+ free_line(l); -+ fclose(fp); -+ if (no_platform >= 0) -+ return no_platform; -+ } -+ no_platform = 0; -+ return 0; -+} -+ -+void imsm_set_no_platform(int v) -+{ -+ no_platform = v; -+} -+ - const char *get_sys_dev_type(enum sys_dev_type type) - { - if (type >= SYS_DEV_MAX) -@@ -2699,7 +2738,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - int result=1; - - if (enumerate_only) { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - list = find_intel_devices(); - if (!list) -@@ -4722,7 +4761,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de - devname); - return 1; - } -- if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) { -+ if (!is_fd_valid(fd) || check_no_platform()) { - super->orom = NULL; - super->hba = NULL; - return 0; -@@ -10697,7 +10736,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks, - ******************************************************************************/ - int validate_container_imsm(struct mdinfo *info) - { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - - struct sys_dev *idev; -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 23a375f6..020cc7e1 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -15,9 +15,6 @@ Documentation=man:mdmon(8) - IgnoreOnIsolate=true - - [Service] --# mdmon should never complain due to lack of a platform, --# that is mdadm's job if at all. --Environment=IMSM_NO_PLATFORM=1 - # The mdmon starting in the initramfs (with dracut at least) - # cannot see sysfs after root is mounted, so we will have to - # 'takeover'. As the '--offroot --takeover' don't hurt when --- -2.38.1 - diff --git a/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch b/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch deleted file mode 100644 index 4db3370..0000000 --- a/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9b6e3b43381245cb128ad98bf117a565ce5defe5 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:13:18 +0100 -Subject: [PATCH 114/125] Revert "Revert "mdadm/systemd: remove KillMode=none - from service file"" - -This reverts commit 28a083955c6f58f8e582734c8c82aff909a7d461. - -Resolved by commit 723d1df4946e ("mdmon: Improve switchroot -interactions.") We are ready to drop it. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9ccadca3..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none --- -2.38.1 - diff --git a/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch b/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch deleted file mode 100644 index d533d8b..0000000 --- a/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 23 Mar 2023 12:50:00 +0100 -Subject: [PATCH 115/125] Create: Fix checking for container in update_metadata - -The commit 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -introduced a regression that caused timeouts and udev failing to create -links. - -Steps to reproduce the issue were as following: -$ mdadm -CR imsm -e imsm -n4 /dev/nvme[0-3]n1 -$ mdadm -CR vol -l5 -n4 /dev/nvme[0-3]n1 --assume-clean - -I found the check for container was wrong because negation was missing. - -Fixes: 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index bbe9e13d..0911bf92 100644 ---- a/Create.c -+++ b/Create.c -@@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && is_container(s->level) && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info->uuid, 0)) { - map_update(map, fd2devnm(mdfd), - info_new.text_version, --- -2.38.1 - diff --git a/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch b/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch deleted file mode 100644 index ca8176c..0000000 --- a/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 890212d6800646153210ac264ce73035cc7dd5cc Mon Sep 17 00:00:00 2001 -From: miaoguanqin -Date: Tue, 4 Apr 2023 19:31:24 +0800 -Subject: [PATCH 116/125] Fix null pointer for incremental in mdadm - -when we excute mdadm --assemble, udev-md-raid-assembly.rules is triggered. -Then we stop array, we found an coredump for mdadm --incremental.func -stack are as follows: - -#0 enough (level=10, raid_disks=4, layout=258, clean=1, - avail=avail@entry=0x0) at util.c:555 -#1 0x0000562170c26965 in Incremental (devlist=, - c=, st=0x5621729b6dc0) at Incremental.c:514 -#2 0x0000562170bfb6ff in main (argc=, - argv=) at mdadm.c:1762 - -func enough() use array avail,avail allocate space in func count_active, -it may not alloc space, causing a coredump.We fix this coredump. - -Signed-off-by: Guanqin Miao -Signed-off-by: lixiaokeng -Signed-off-by: Jes Sorensen ---- - Incremental.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Incremental.c b/Incremental.c -index 09b94b9f..49a71f72 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -507,6 +507,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - GET_OFFSET | GET_SIZE)); - active_disks = count_active(st, sra, mdfd, &avail, &info); - -+ if (!avail) -+ goto out_unlock; -+ - journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); - - if (info.consistency_policy == CONSISTENCY_POLICY_PPL) --- -2.38.1 - diff --git a/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch b/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch deleted file mode 100644 index cf61c2d..0000000 --- a/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1c6f2a1dbfe17df14dd5b062fc53a60c5c387e47 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Sat, 1 Apr 2023 23:01:35 +0300 -Subject: [PATCH 117/125] super1: fix truncation check for journal device - -The journal device can be smaller than the component devices. - -Fixes: 171e9743881e ("super1: report truncated device") -Signed-off-by: Hristo Venev -Signed-off-by: Jes Sorensen ---- - super1.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/super1.c b/super1.c -index f7020320..44d6ecad 100644 ---- a/super1.c -+++ b/super1.c -@@ -2359,8 +2359,9 @@ static int load_super1(struct supertype *st, int fd, char *devname) - - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && -- (dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size)) -+ ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) - || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { --- -2.38.1 - diff --git a/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch b/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch deleted file mode 100644 index 889471f..0000000 --- a/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch +++ /dev/null @@ -1,433 +0,0 @@ -From d3bb888d885fc96fc6239fbf6c22c63143eba461 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:40:42 -0400 -Subject: [PATCH 118/125] Fix some cases eyesore formatting - -Summary: No functional change .... just make it more readable. - -Signed-off-by: Jes Sorensen ---- - super1.c | 117 ++++++++++++++++++++++++++++--------------------------- - 1 file changed, 60 insertions(+), 57 deletions(-) - -diff --git a/super1.c b/super1.c -index 44d6ecad..1d20ef55 100644 ---- a/super1.c -+++ b/super1.c -@@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - unsigned int disk_csum, csum; - unsigned long long newcsum; - int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2; -- unsigned int *isuper = (unsigned int*)sb; -+ unsigned int *isuper = (unsigned int *)sb; - - /* make sure I can count... */ - if (offsetof(struct mdp_superblock_1,data_offset) != 128 || -@@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - disk_csum = sb->sb_csum; - sb->sb_csum = 0; - newcsum = 0; -- for (; size>=4; size -= 4 ) { -+ for (; size >= 4; size -= 4) { - newcsum += __le32_to_cpu(*isuper); - isuper++; - } -@@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk) - static void examine_super1(struct supertype *st, char *homehost) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - time_t atime; - unsigned int d; - int role; -@@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost) - printf(".0\n"); - printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map)); - printf(" Array UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) printf(":"); -+ for (i = 0; i < 16; i++) { -+ if ((i & 3) == 0 && i != 0) -+ printf(":"); - printf("%02x", sb->set_uuid[i]); - } - printf("\n"); -@@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost) - UINT64_MAX - info.space_after); - } - printf(" State : %s%s\n", -- (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (__le64_to_cpu(sb->resync_offset) + 1) ? "active":"clean", - (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) -+ for (i = 0; i < 16; i++) { -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This turns out to just be confusing */ - printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number)); -- for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--) -+ for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--) - if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE) - break; - for (d = 0; d < i; d++) { -@@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This is confusing too */ - faulty = 0; -- for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { -+ for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { - int role = __le16_to_cpu(sb->dev_roles[i]); - if (role == MD_DISK_ROLE_FAULTY) - faulty++; -@@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost) - if (inconsistent) { - printf("WARNING Array state is inconsistent - each number should appear only once\n"); - for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) -- if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY) -+ if (__le16_to_cpu(sb->dev_roles[d]) >= -+ MD_DISK_ROLE_FAULTY) - printf(" %d:-", d); - else -- printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d])); -+ printf(" %d:%d", d, -+ __le16_to_cpu(sb->dev_roles[d])); - printf("\n"); - } - } -@@ -659,7 +662,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) - printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks)); - printf("UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3)==0 && i != 0) -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -713,7 +716,7 @@ static void export_examine_super1(struct supertype *st) - } - printf("MD_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -722,7 +725,7 @@ static void export_examine_super1(struct supertype *st) - __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL); - printf("MD_DEV_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -812,7 +815,7 @@ static int copy_metadata1(struct supertype *st, int from, int to) - /* have the header, can calculate - * correct bitmap bytes */ - bitmap_super_t *bms; -- bms = (void*)buf; -+ bms = (void *)buf; - bytes = calc_bitmap_size(bms, 512); - if (n > bytes) - n = bytes; -@@ -867,7 +870,7 @@ err: - static void detail_super1(struct supertype *st, char *homehost, char *subarray) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int i; - int l = homehost ? strlen(homehost) : 0; - -@@ -880,7 +883,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray) - printf("\n Cluster Name : %-64s", bms->cluster_name); - printf("\n UUID : "); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -939,7 +942,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) - } - - size = __le16_to_cpu(sb->bblog_size)* 512; -- if (posix_memalign((void**)&bbl, 4096, size) != 0) { -+ if (posix_memalign((void **)&bbl, 4096, size) != 0) { - pr_err("could not allocate badblocks list\n"); - return 0; - } -@@ -987,7 +990,7 @@ static int match_home1(struct supertype *st, char *homehost) - static void uuid_from_super1(struct supertype *st, int uuid[4]) - { - struct mdp_superblock_1 *super = st->sb; -- char *cuuid = (char*)uuid; -+ char *cuuid = (char *)uuid; - int i; - for (i = 0; i < 16; i++) - cuuid[i] = super->set_uuid[i]; -@@ -996,9 +999,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) - static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - { - struct mdp_superblock_1 *sb = st->sb; -- struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE); - struct misc_dev_info *misc = -- (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE); - int working = 0; - unsigned int i; - unsigned int role; -@@ -1166,7 +1169,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - info->recovery_blocked = info->reshape_active; - - if (map) -- for (i=0; imax_dev); i++) { - role = __le16_to_cpu(sb->dev_roles[i]); -@@ -1217,7 +1220,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - */ - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - - if (update == UOPT_HOMEHOST && homehost) { - /* -@@ -1228,9 +1231,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- snprintf(info->name, sizeof(info->name), "%s", c+1); -+ snprintf(info->name, sizeof(info->name), "%s", c + 1); - else -- snprintf(info->name, sizeof(info->name), "%s", sb->set_name); -+ snprintf(info->name, sizeof(info->name), "%s", -+ sb->set_name); - } - - switch (update) { -@@ -1331,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->dev_number = __cpu_to_le32(i); - - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - if (i > max) - return -2; - -@@ -1350,8 +1354,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); - } else { -- ds -= 8*2; -- ds &= ~(unsigned long long)(4*2-1); -+ ds -= 8 * 2; -+ ds &= ~(unsigned long long)(4 * 2 - 1); - sb->super_offset = __cpu_to_le64(ds); - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); -@@ -1367,7 +1371,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - if (i > max) - return -2; - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -@@ -1645,7 +1649,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - char defname[10]; - int sbsize; - -- if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 0; - } -@@ -1679,8 +1683,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - name = defname; - } - if (homehost && -- strchr(name, ':')== NULL && -- strlen(homehost)+1+strlen(name) < 32) { -+ strchr(name, ':') == NULL && -+ strlen(homehost) + 1 + strlen(name) < 32) { - strcpy(sb->set_name, homehost); - strcat(sb->set_name, ":"); - strcat(sb->set_name, name); -@@ -1759,7 +1763,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, - - if (dk->number >= (int)__le32_to_cpu(sb->max_dev) && - __le32_to_cpu(sb->max_dev) < MAX_DEVS) -- sb->max_dev = __cpu_to_le32(dk->number+1); -+ sb->max_dev = __cpu_to_le32(dk->number + 1); - - sb->dev_number = __cpu_to_le32(dk->number); - sb->devflags = 0; /* don't copy another disks flags */ -@@ -1840,8 +1844,8 @@ static int store_super1(struct supertype *st, int fd) - return 4; - - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { -- struct bitmap_super_s *bm = (struct bitmap_super_s*) -- (((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bm; -+ bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE); - if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { - locate_bitmap1(st, fd, 0); - if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm)) -@@ -1928,7 +1932,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) - - init_afd(&afd, fd); - -- if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) { -+ if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) { - pr_err("Could not allocate memory for the meta block.\n"); - return 1; - } -@@ -2197,7 +2201,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst, - return 1; - - if (!first) { -- if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2310,7 +2314,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 1; - } - -- if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2349,10 +2353,10 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 2; - } - -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - - misc = (struct misc_dev_info*) -- (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE); - misc->device_size = dsize; - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); -@@ -2360,9 +2364,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && - ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -- dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size))) -- || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { - if (devname) -@@ -2391,8 +2394,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 0; - - no_bitmap: -- super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) -- & ~MD_FEATURE_BITMAP_OFFSET); -+ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & -+ ~MD_FEATURE_BITMAP_OFFSET); - return 0; - } - -@@ -2450,7 +2453,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, - if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) { - /* hot-add. allow for actual size of bitmap */ - struct bitmap_super_s *bsb; -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - bmspace = calc_bitmap_size(bsb, 4096) >> 9; - } else if (md_feature_any_ppl_on(super->feature_map)) { - bmspace = __le16_to_cpu(super->ppl.size); -@@ -2519,7 +2522,7 @@ add_internal_bitmap1(struct supertype *st, - int creating = 0; - int len; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int uuid[4]; - - if (__le64_to_cpu(sb->data_size) == 0) -@@ -2607,10 +2610,10 @@ add_internal_bitmap1(struct supertype *st, - max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8; - - min_chunk = 4096; /* sub-page chunks don't work yet.. */ -- bits = (size*512)/min_chunk +1; -+ bits = (size * 512) / min_chunk + 1; - while (bits > max_bits) { - min_chunk *= 2; -- bits = (bits+1)/2; -+ bits = (bits + 1) / 2; - } - if (chunk == UnSet) { - /* For practical purpose, 64Meg is a good -@@ -2628,8 +2631,8 @@ add_internal_bitmap1(struct supertype *st, - /* start bitmap on a 4K boundary with enough space for - * the bitmap - */ -- bits = (size*512) / chunk + 1; -- room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096; -+ bits = (size * 512) / chunk + 1; -+ room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096; - room *= 8; /* convert 4K blocks to sectors */ - offset = -room - bbl_size; - } -@@ -2683,7 +2686,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - - offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset); - if (node_num) { -- bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9; - offset += bm_sectors_per_node * node_num; - } -@@ -2696,7 +2699,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int rv = 0; - void *buf; - int towrite, n, len; -@@ -2970,16 +2973,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - sprintf(sb->set_name, "%d", sb0->md_minor); -- sb->ctime = __cpu_to_le32(info->array.ctime+1); -+ sb->ctime = __cpu_to_le32(info->array.ctime + 1); - sb->level = __cpu_to_le32(info->array.level); - sb->layout = __cpu_to_le32(info->array.layout); - sb->size = __cpu_to_le64(info->component_size); -- sb->chunksize = __cpu_to_le32(info->array.chunk_size/512); -+ sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - if (info->array.level > 0) - sb->data_size = sb->size; - else -- sb->data_size = st->ss->avail_size(st, st->devsize/512, 0); -+ sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0); - sb->resync_offset = MaxSector; - sb->max_dev = __cpu_to_le32(MD_SB_DISKS); - sb->dev_number = __cpu_to_le32(info->disk.number); --- -2.38.1 - diff --git a/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch b/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch deleted file mode 100644 index 486f799..0000000 --- a/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch +++ /dev/null @@ -1,136 +0,0 @@ -From f8d2c4286a92b7acb7872271a401ad1efe336096 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:45:34 -0400 -Subject: [PATCH 119/125] Bump minimum kernel version to 2.6.32 - -Summary: At this point it probably is reasonable to drop support for -anything prior to 3.10. - -Signed-off-by: Jes Sorensen ---- - Create.c | 5 ----- - Grow.c | 16 ---------------- - Manage.c | 17 ----------------- - mdadm.c | 4 ++-- - super1.c | 5 ----- - 5 files changed, 2 insertions(+), 45 deletions(-) - -diff --git a/Create.c b/Create.c -index 0911bf92..aa0472dd 100644 ---- a/Create.c -+++ b/Create.c -@@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev, - break; - case LEVEL_LINEAR: - /* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */ -- if (get_linux_version() < 2006016 && s->chunk == 0) { -- s->chunk = 64; -- if (c->verbose > 0) -- pr_err("chunk size defaults to 64K\n"); -- } - break; - case 1: - case LEVEL_FAULTY: -diff --git a/Grow.c b/Grow.c -index 06001f2d..8fa97875 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) - return NULL; - } - -- if (re->after.data_disks == re->before.data_disks && -- get_linux_version() < 2006032) -- return "in-place reshape is not safe before 2.6.32 - sorry."; -- -- if (re->after.data_disks < re->before.data_disks && -- get_linux_version() < 2006030) -- return "reshape to fewer devices is not supported before 2.6.30 - sorry."; -- - re->backup_blocks = compute_backup_blocks( - info->new_chunk, info->array.chunk_size, - re->after.data_disks, re->before.data_disks); -@@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (s->raiddisks && s->raiddisks < array.raid_disks && -- array.level > 1 && get_linux_version() < 2006032 && -- !check_env("MDADM_FORCE_FEWER")) { -- pr_err("reducing the number of devices is not safe before Linux 2.6.32\n" -- " Please use a newer kernel\n"); -- return 1; -- } -- - if (array.level > 1 && s->size > 1 && - (unsigned long long) (array.chunk_size / 1024) > s->size) { - pr_err("component size must be larger than chunk size.\n"); -diff --git a/Manage.c b/Manage.c -index fde6aba3..f54de7c6 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -461,17 +461,6 @@ done: - goto out; - } - -- if (get_linux_version() < 2006028) { -- /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array -- * was stopped, so We'll do it here just to be sure. Drop any -- * partitions as well... -- */ -- if (fd >= 0) -- ioctl(fd, BLKRRPART, 0); -- if (mdi) -- sysfs_uevent(mdi, "change"); -- } -- - if (devnm[0] && use_udev()) { - struct map_ent *mp = map_by_devnm(&map, devnm); - remove_devices(devnm, mp ? mp->path : NULL); -@@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - * though. - */ - mdu_disk_info_t disc; -- /* re-add doesn't work for version-1 superblocks -- * before 2.6.18 :-( -- */ -- if (array->major_version == 1 && -- get_linux_version() <= 2006018) -- goto skip_re_add; - disc.number = mdi.disk.number; - if (md_get_disk_info(fd, &disc) != 0 || - disc.major != 0 || disc.minor != 0) -diff --git a/mdadm.c b/mdadm.c -index 4685ad6b..2296911d 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,8 +107,8 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- if (get_linux_version() < 2006015) { -- pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); -+ if (get_linux_version() < 2006032) { -+ pr_err("This version of mdadm does not support kernels older than 2.6.32\n"); - exit(1); - } - -diff --git a/super1.c b/super1.c -index 1d20ef55..938c3a68 100644 ---- a/super1.c -+++ b/super1.c -@@ -2033,11 +2033,6 @@ static int write_init_super1(struct supertype *st) - /* same array, so preserve events and - * dev_number */ - sb->events = refsb->events; -- /* bugs in 2.6.17 and earlier mean the -- * dev_number chosen in Manage must be preserved -- */ -- if (get_linux_version() >= 2006018) -- sb->dev_number = refsb->dev_number; - } - free_super1(refst); - } --- -2.38.1 - diff --git a/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch b/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch deleted file mode 100644 index 4160281..0000000 --- a/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 7 Apr 2023 08:45:28 +0800 -Subject: [PATCH 120/125] Remove the config files in mdcheck_start|continue - service - -We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files. -And mdcheck doesn't use any configs from the config file. So we can remove -the dependencies. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdcheck_continue.service | 2 -- - systemd/mdcheck_start.service | 2 -- - 2 files changed, 4 deletions(-) - -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index f5324905..70892a1f 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 703a6583..fc4fc438 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} --- -2.38.1 - diff --git a/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch b/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch deleted file mode 100644 index 047c45e..0000000 --- a/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch +++ /dev/null @@ -1,347 +0,0 @@ -From b9ce7ab0218c550488587fdad5708628d6a5ffc2 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:14 +0100 -Subject: [PATCH 121/125] mdadm: define DEV_MD_DIR - -It is used many times. Additionally define _LEN to avoid repeated -strlen() calls when length is needed. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Create.c | 7 +++---- - Detail.c | 9 ++++----- - Incremental.c | 4 ++-- - Monitor.c | 32 ++++++++++++++++++-------------- - config.c | 10 +++++----- - lib.c | 2 +- - mapfile.c | 12 ++++++------ - mdadm.h | 8 ++++++++ - mdopen.c | 6 +++--- - super-ddf.c | 2 +- - super-intel.c | 2 +- - super1.c | 3 +-- - sysfs.c | 2 +- - 13 files changed, 54 insertions(+), 45 deletions(-) - -diff --git a/Create.c b/Create.c -index aa0472dd..ea6a4745 100644 ---- a/Create.c -+++ b/Create.c -@@ -1024,10 +1024,9 @@ int Create(struct supertype *st, char *mddev, - * it could be in conflict with already existing device - * e.g. container, array - */ -- if (strncmp(chosen_name, "/dev/md/", 8) == 0 && -- map_by_name(&map, chosen_name+8) != NULL) { -- pr_err("Array name %s is in use already.\n", -- chosen_name); -+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 && -+ map_by_name(&map, chosen_name + DEV_MD_DIR_LEN)) { -+ pr_err("Array name %s is in use already.\n", chosen_name); - close(mdfd); - map_unlock(&map); - udev_unblock(); -diff --git a/Detail.c b/Detail.c -index 4ef26460..206d88e3 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -254,10 +254,9 @@ int Detail(char *dev, struct context *c) - fname_from_uuid(st, info, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf + 5); - mp = map_by_uuid(&map, info->uuid); -- if (mp && mp->path && -- strncmp(mp->path, "/dev/md/", 8) == 0) { -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - printf("MD_DEVNAME="); -- print_escape(mp->path + 8); -+ print_escape(mp->path + DEV_MD_DIR_LEN); - putchar('\n'); - } - -@@ -273,9 +272,9 @@ int Detail(char *dev, struct context *c) - printf("MD_UUID=%s\n", nbuf+5); - } - if (mp && mp->path && -- strncmp(mp->path, "/dev/md/", 8) == 0) { -+ strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - printf("MD_DEVNAME="); -- print_escape(mp->path+8); -+ print_escape(mp->path + DEV_MD_DIR_LEN); - putchar('\n'); - } - map_free(map); -diff --git a/Incremental.c b/Incremental.c -index 49a71f72..59b850f1 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -460,8 +460,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - info.array.working_disks ++; - - } -- if (strncmp(chosen_name, "/dev/md/", 8) == 0) -- md_devname = chosen_name+8; -+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ md_devname = chosen_name + DEV_MD_DIR_LEN; - else - md_devname = chosen_name; - if (c->export) { -diff --git a/Monitor.c b/Monitor.c -index 44918184..3273f2fb 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -36,9 +36,18 @@ - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - -+/** -+ * struct state - external array or container properties. -+ * @devname: has length of %DEV_MD_DIR + device name + terminating byte -+ * @devnm: to sync with mdstat info -+ * @parent_devnm: or subarray, devnm of parent, for others, "" -+ * @subarray: for a container it is a link to first subarray, for a subarray it is a link to next -+ * subarray in the same container -+ * @parent: for a subarray it is a link to its container -+ */ - struct state { -- char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -- char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ -+ char devname[MD_NAME_MAX + sizeof(DEV_MD_DIR)]; -+ char devnm[MD_NAME_MAX]; - unsigned int utime; - int err; - char *spare_group; -@@ -49,15 +58,10 @@ struct state { - int devstate[MAX_DISKS]; - dev_t devid[MAX_DISKS]; - int percent; -- char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. -- * For others, "" -- */ -+ char parent_devnm[MD_NAME_MAX]; - struct supertype *metadata; -- struct state *subarray;/* for a container it is a link to first subarray -- * for a subarray it is a link to next subarray -- * in the same container */ -- struct state *parent; /* for a subarray it is a link to its container -- */ -+ struct state *subarray; -+ struct state *parent; - struct state *next; - }; - -@@ -252,8 +256,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - - st = xcalloc(1, sizeof *st); -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -- "/dev/md/%s", basename(mdlist->devname)); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s", -+ basename(mdlist->devname)); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -274,7 +278,7 @@ int Monitor(struct mddev_dev *devlist, - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", dv->devname); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -942,7 +946,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - continue; - } - -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", name); - if ((fd = open(st->devname, O_RDONLY)) < 0 || - md_get_array_info(fd, &array) < 0) { - /* no such array */ -diff --git a/config.c b/config.c -index eeedd0c6..59d5bfb6 100644 ---- a/config.c -+++ b/config.c -@@ -405,7 +405,7 @@ void arrayline(char *line) - * or anything that doesn't start '/' or '<' - */ - if (strcasecmp(w, "") == 0 || -- strncmp(w, "/dev/md/", 8) == 0 || -+ strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || - (strncmp(w, "/dev/md", 7) == 0 && - is_number(w + 7)) || -@@ -1102,13 +1102,13 @@ int devname_matches(char *name, char *match) - * mdNN with NN - * then just strcmp - */ -- if (strncmp(name, "/dev/md/", 8) == 0) -- name += 8; -+ if (strncmp(name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ name += DEV_MD_DIR_LEN; - else if (strncmp(name, "/dev/", 5) == 0) - name += 5; - -- if (strncmp(match, "/dev/md/", 8) == 0) -- match += 8; -+ if (strncmp(match, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ match += DEV_MD_DIR_LEN; - else if (strncmp(match, "/dev/", 5) == 0) - match += 5; - -diff --git a/lib.c b/lib.c -index e395b28d..65ea51e0 100644 ---- a/lib.c -+++ b/lib.c -@@ -313,7 +313,7 @@ char *map_dev_preferred(int major, int minor, int create, - - for (p = devlist; p; p = p->next) - if (p->major == major && p->minor == minor) { -- if (strncmp(p->name, "/dev/md/",8) == 0 || -+ if (strncmp(p->name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (prefer && strstr(p->name, prefer))) { - if (preferred == NULL || - strlen(p->name) < strlen(preferred)) -diff --git a/mapfile.c b/mapfile.c -index ac351768..34fea179 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -320,9 +320,9 @@ struct map_ent *map_by_name(struct map_ent **map, char *name) - for (mp = *map ; mp ; mp = mp->next) { - if (!mp->path) - continue; -- if (strncmp(mp->path, "/dev/md/", 8) != 0) -+ if (strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) - continue; -- if (strcmp(mp->path+8, name) != 0) -+ if (strcmp(mp->path + DEV_MD_DIR_LEN, name) != 0) - continue; - if (!mddev_busy(mp->devnm)) { - mp->bad = 1; -@@ -413,7 +413,7 @@ void RebuildMap(void) - devid = devnm2devid(md->devnm); - path = map_dev(major(devid), minor(devid), 0); - if (path == NULL || -- strncmp(path, "/dev/md/", 8) != 0) { -+ strncmp(path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) { - /* We would really like a name that provides - * an MD_DEVNAME for udev. - * The name needs to be unique both in /dev/md/ -@@ -434,7 +434,7 @@ void RebuildMap(void) - if (match && match->devname && match->devname[0] == '/') { - path = match->devname; - if (path[0] != '/') { -- strcpy(namebuf, "/dev/md/"); -+ strcpy(namebuf, DEV_MD_DIR); - strcat(namebuf, path); - path = namebuf; - } -@@ -478,10 +478,10 @@ void RebuildMap(void) - - while (conflict) { - if (unum >= 0) -- sprintf(namebuf, "/dev/md/%s%s%d", -+ sprintf(namebuf, DEV_MD_DIR "%s%s%d", - name, sep, unum); - else -- sprintf(namebuf, "/dev/md/%s", -+ sprintf(namebuf, DEV_MD_DIR "%s", - name); - unum++; - if (lstat(namebuf, &stb) != 0 && -diff --git a/mdadm.h b/mdadm.h -index 0d995445..67d73f96 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -100,6 +100,14 @@ struct dlm_lksb { - #define DEFAULT_BITMAP_DELAY 5 - #define DEFAULT_MAX_WRITE_BEHIND 256 - -+/* DEV_MD_DIR points to named MD devices directory. -+ * DEV_MD_DIR_LEN is a length with Null byte excluded. -+ */ -+#ifndef DEV_MD_DIR -+#define DEV_MD_DIR "/dev/md/" -+#define DEV_MD_DIR_LEN (sizeof(DEV_MD_DIR) - 1) -+#endif /* DEV_MD_DIR */ -+ - /* MAP_DIR should be somewhere that persists across the pivotroot - * from early boot to late boot. - * /run seems to have emerged as the best standard. -diff --git a/mdopen.c b/mdopen.c -index 810f79a3..6c3bdb6a 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -188,12 +188,12 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - parts = autof >> 3; - autof &= 7; - -- strcpy(chosen, "/dev/md/"); -+ strcpy(chosen, DEV_MD_DIR); - cname = chosen + strlen(chosen); - - if (dev) { -- if (strncmp(dev, "/dev/md/", 8) == 0) { -- strcpy(cname, dev+8); -+ if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -+ strcpy(cname, dev + DEV_MD_DIR_LEN); - } else if (strncmp(dev, "/dev/", 5) == 0) { - char *e = dev + strlen(dev); - while (e > dev && isdigit(e[-1])) -diff --git a/super-ddf.c b/super-ddf.c -index b86c6acd..7213284e 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1648,7 +1648,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) - fname_from_uuid(st, &info, nbuf1, ':'); - _ddf_array_name(namebuf, ddf, i); - printf("ARRAY%s%s container=%s member=%d UUID=%s\n", -- namebuf[0] == '\0' ? "" : " /dev/md/", namebuf, -+ namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf, - nbuf+5, i, nbuf1+5); - } - } -diff --git a/super-intel.c b/super-intel.c -index a5c86cb2..aaf6659e 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -2309,7 +2309,7 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose) - super->current_vol = i; - getinfo_super_imsm(st, &info, NULL); - fname_from_uuid(st, &info, nbuf1, ':'); -- printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n", -+ printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n", - dev->volume, nbuf + 5, i, nbuf1 + 5); - } - } -diff --git a/super1.c b/super1.c -index 938c3a68..856b0208 100644 ---- a/super1.c -+++ b/super1.c -@@ -645,8 +645,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) - - printf("ARRAY "); - if (nm) { -- printf("/dev/md/"); -- print_escape(nm); -+ printf(DEV_MD_DIR "%s", nm); - putchar(' '); - } - if (verbose && c) -diff --git a/sysfs.c b/sysfs.c -index ca1d888f..94d02f53 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -1114,7 +1114,7 @@ void sysfsline(char *line) - if (strncasecmp(w, "name=", 5) == 0) { - char *devname = w + 5; - -- if (strncmp(devname, "/dev/md/", 8) == 0) { -+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - if (sr->devname) - pr_err("Only give one device per SYSFS line: %s\n", - devname); --- -2.38.1 - diff --git a/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch b/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch deleted file mode 100644 index 645aa62..0000000 --- a/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0f8347d4f6588ee6ded55af3e307418cee286a6f Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:15 +0100 -Subject: [PATCH 122/125] mdadm: define DEV_NUM_PREF - -Use define instead of inlines. Add _LEN define. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 4 ++-- - mdadm.h | 8 ++++++++ - mdopen.c | 10 +++++----- - 3 files changed, 15 insertions(+), 7 deletions(-) - -diff --git a/config.c b/config.c -index 59d5bfb6..f44cc1d3 100644 ---- a/config.c -+++ b/config.c -@@ -407,8 +407,8 @@ void arrayline(char *line) - if (strcasecmp(w, "") == 0 || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || -- (strncmp(w, "/dev/md", 7) == 0 && -- is_number(w + 7)) || -+ (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -+ is_number(w + DEV_NUM_PREF_LEN)) || - (strncmp(w, "/dev/md_d", 9) == 0 && - is_number(w + 9))) { - /* This is acceptable */; -diff --git a/mdadm.h b/mdadm.h -index 67d73f96..f2e70baa 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -100,6 +100,14 @@ struct dlm_lksb { - #define DEFAULT_BITMAP_DELAY 5 - #define DEFAULT_MAX_WRITE_BEHIND 256 - -+/* DEV_NUM_PREF is a subpath to numbered MD devices, e.g. /dev/md1 or directory name. -+ * DEV_NUM_PREF_LEN is a length with Null byte excluded. -+ */ -+#ifndef DEV_NUM_PREF -+#define DEV_NUM_PREF "/dev/md" -+#define DEV_NUM_PREF_LEN (sizeof(DEV_NUM_PREF) - 1) -+#endif /* DEV_NUM_PREF */ -+ - /* DEV_MD_DIR points to named MD devices directory. - * DEV_MD_DIR_LEN is a length with Null byte excluded. - */ -diff --git a/mdopen.c b/mdopen.c -index 6c3bdb6a..d3022a54 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -412,11 +412,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - make_parts(devname, parts); - - if (strcmp(chosen, devname) != 0) { -- if (mkdir("/dev/md",0700) == 0) { -- if (chown("/dev/md", ci->uid, ci->gid)) -- perror("chown /dev/md"); -- if (chmod("/dev/md", ci->mode| ((ci->mode>>2) & 0111))) -- perror("chmod /dev/md"); -+ if (mkdir(DEV_NUM_PREF, 0700) == 0) { -+ if (chown(DEV_NUM_PREF, ci->uid, ci->gid)) -+ perror("chown " DEV_NUM_PREF); -+ if (chmod(DEV_NUM_PREF, ci->mode | ((ci->mode >> 2) & 0111))) -+ perror("chmod " DEV_NUM_PREF); - } - - if (dev && strcmp(chosen, dev) == 0) --- -2.38.1 - diff --git a/SOURCES/0123-mdadm-define-is_devname_ignore.patch b/SOURCES/0123-mdadm-define-is_devname_ignore.patch deleted file mode 100644 index 3526be2..0000000 --- a/SOURCES/0123-mdadm-define-is_devname_ignore.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 7b3b691ba69b909ea8c172aae693fa2a6938fd14 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:16 +0100 -Subject: [PATCH 123/125] mdadm: define is_devname_ignore() - -Use function instead of direct checks across code. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Incremental.c | 6 ++---- - Monitor.c | 2 +- - config.c | 16 ++++++++++++++-- - mdadm.c | 5 ++--- - mdadm.h | 1 + - 5 files changed, 20 insertions(+), 10 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index 59b850f1..f13ce027 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -202,8 +202,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - if (!match && rv == 2) - goto out; - -- if (match && match->devname && -- strcasecmp(match->devname, "") == 0) { -+ if (match && match->devname && is_devname_ignore(match->devname) == true) { - if (c->verbose >= 0) - pr_err("array containing %s is explicitly ignored by mdadm.conf\n", - devname); -@@ -1567,8 +1566,7 @@ static int Incremental_container(struct supertype *st, char *devname, - break; - } - -- if (match && match->devname && -- strcasecmp(match->devname, "") == 0) { -+ if (match && match->devname && is_devname_ignore(match->devname) == true) { - if (c->verbose > 0) - pr_err("array %s/%s is explicitly ignored by mdadm.conf\n", - match->container, match->member); -diff --git a/Monitor.c b/Monitor.c -index 3273f2fb..66175968 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -250,7 +250,7 @@ int Monitor(struct mddev_dev *devlist, - - if (mdlist->devname == NULL) - continue; -- if (strcasecmp(mdlist->devname, "") == 0) -+ if (is_devname_ignore(mdlist->devname) == true) - continue; - if (!is_mddev(mdlist->devname)) - continue; -diff --git a/config.c b/config.c -index f44cc1d3..e61c0496 100644 ---- a/config.c -+++ b/config.c -@@ -119,6 +119,18 @@ int match_keyword(char *word) - return -1; - } - -+/** -+ * is_devname_ignore() - check if &devname is a special "" keyword. -+ */ -+bool is_devname_ignore(char *devname) -+{ -+ static const char keyword[] = ""; -+ -+ if (strcasecmp(devname, keyword) == 0) -+ return true; -+ return false; -+} -+ - /** - * ident_init() - Set defaults. - * @ident: ident pointer, not NULL. -@@ -404,7 +416,7 @@ void arrayline(char *line) - * - * or anything that doesn't start '/' or '<' - */ -- if (strcasecmp(w, "") == 0 || -+ if (is_devname_ignore(w) == true || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || - (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -@@ -571,7 +583,7 @@ void homehostline(char *line) - char *w; - - for (w = dl_next(line); w != line; w = dl_next(w)) { -- if (strcasecmp(w, "") == 0) -+ if (is_devname_ignore(w) == true) - require_homehost = 0; - else if (home_host == NULL) { - if (strcasecmp(w, "") == 0) -diff --git a/mdadm.c b/mdadm.c -index 2296911d..076b45e0 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) - continue; - - case HomeHost: -- if (strcasecmp(optarg, "") == 0) -+ if (is_devname_ignore(optarg) == true) - c.require_homehost = 0; - else - c.homehost = optarg; -@@ -1749,8 +1749,7 @@ static int scan_assemble(struct supertype *ss, - int r; - if (a->assembled) - continue; -- if (a->devname && -- strcasecmp(a->devname, "") == 0) -+ if (a->devname && is_devname_ignore(a->devname) == true) - continue; - - r = Assemble(ss, a->devname, -diff --git a/mdadm.h b/mdadm.h -index f2e70baa..0932c2d3 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1650,6 +1650,7 @@ extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); -+extern bool is_devname_ignore(char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); - extern int devname_matches(char *name, char *match); - extern struct mddev_ident *conf_match(struct supertype *st, --- -2.38.1 - diff --git a/SOURCES/0124-mdadm-numbered-names-verification.patch b/SOURCES/0124-mdadm-numbered-names-verification.patch deleted file mode 100644 index a3e94f0..0000000 --- a/SOURCES/0124-mdadm-numbered-names-verification.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 25aa7329141c0b28d8811671627f0f5c5dc22273 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:17 +0100 -Subject: [PATCH 124/125] mdadm: numbered names verification - -New functions added to remove literals and make the code reusable. -Use parse_num() instead of is_numer(). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 17 ++--------------- - lib.c | 2 +- - mdadm.h | 4 +++- - util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 50 insertions(+), 17 deletions(-) - -diff --git a/config.c b/config.c -index e61c0496..450880e3 100644 ---- a/config.c -+++ b/config.c -@@ -385,17 +385,6 @@ void devline(char *line) - struct mddev_ident *mddevlist = NULL; - struct mddev_ident **mddevlp = &mddevlist; - --static int is_number(char *w) --{ -- /* check if there are 1 or more digits and nothing else */ -- int digits = 0; -- while (*w && isdigit(*w)) { -- digits++; -- w++; -- } -- return (digits && ! *w); --} -- - void arrayline(char *line) - { - char *w; -@@ -419,10 +408,8 @@ void arrayline(char *line) - if (is_devname_ignore(w) == true || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || -- (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -- is_number(w + DEV_NUM_PREF_LEN)) || -- (strncmp(w, "/dev/md_d", 9) == 0 && -- is_number(w + 9))) { -+ is_devname_md_numbered(w) == true || -+ is_devname_md_d_numbered(w) == true) { - /* This is acceptable */; - if (mis.devname) - pr_err("only give one device per ARRAY line: %s and %s\n", -diff --git a/lib.c b/lib.c -index 65ea51e0..fe5c8d2c 100644 ---- a/lib.c -+++ b/lib.c -@@ -570,7 +570,7 @@ void free_line(char *line) - * - * Return: 0 on success, 1 otherwise. - */ --int parse_num(int *dest, char *num) -+int parse_num(int *dest, const char *num) - { - char *c = NULL; - long temp; -diff --git a/mdadm.h b/mdadm.h -index 0932c2d3..83f2cf7f 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1601,7 +1601,7 @@ int default_layout(struct supertype *st, int level, int verbose); - extern int is_near_layout_10(int layout); - extern int parse_layout_10(char *layout); - extern int parse_layout_faulty(char *layout); --extern int parse_num(int *dest, char *num); -+extern int parse_num(int *dest, const char *num); - extern int parse_cluster_confirm_arg(char *inp, char **devname, int *slot); - extern int check_ext2(int fd, char *name); - extern int check_reiser(int fd, char *name); -@@ -1651,6 +1651,8 @@ extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); - extern bool is_devname_ignore(char *devname); -+extern bool is_devname_md_numbered(const char *devname); -+extern bool is_devname_md_d_numbered(const char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); - extern int devname_matches(char *name, char *match); - extern struct mddev_ident *conf_match(struct supertype *st, -diff --git a/util.c b/util.c -index d70ca43b..fa378eba 100644 ---- a/util.c -+++ b/util.c -@@ -973,6 +973,50 @@ dev_t devnm2devid(char *devnm) - return 0; - } - -+/** -+ * is_devname_numbered() - helper for numbered devname verification. -+ * @devname: path or name to check. -+ * @pref: expected devname prefix. -+ * @pref_len: prefix len. -+ */ -+static bool is_devname_numbered(const char *devname, const char *pref, const int pref_len) -+{ -+ int val; -+ -+ assert(devname && pref); -+ -+ if (strncmp(devname, pref, pref_len) != 0) -+ return false; -+ -+ if (parse_num(&val, devname + pref_len) != 0) -+ return false; -+ -+ if (val > 127) -+ return false; -+ -+ return true; -+} -+ -+/** -+ * is_devname_md_numbered() - check if &devname is numbered MD device (md). -+ * @devname: path or name to check. -+ */ -+bool is_devname_md_numbered(const char *devname) -+{ -+ return is_devname_numbered(devname, DEV_NUM_PREF, DEV_NUM_PREF_LEN); -+} -+ -+/** -+ * is_devname_md_d_numbered() - check if &devname is secondary numbered MD device (md_d). -+ * @devname: path or name to check. -+ */ -+bool is_devname_md_d_numbered(const char *devname) -+{ -+ static const char d_dev[] = DEV_NUM_PREF "_d"; -+ -+ return is_devname_numbered(devname, d_dev, sizeof(d_dev) - 1); -+} -+ - /** - * get_md_name() - Get main dev node of the md device. - * @devnm: Md device name or path. --- -2.38.1 - diff --git a/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch b/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch deleted file mode 100644 index 4866fe3..0000000 --- a/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 75350d87c86001c47076e1f62478079bdc072223 Mon Sep 17 00:00:00 2001 -From: Kevin Friedberg -Date: Wed, 15 Feb 2023 23:41:34 -0500 -Subject: [PATCH 125/125] enable RAID for SATA under VMD - -Detect when a SATA controller has been mapped under Intel Alderlake RST -VMD, so that it can use the VMD controller's RAID capabilities. Create -new device type SYS_DEV_SATA_VMD and list separate controller to prevent -mixing with the NVMe SYS_DEV_VMD devices on the same VMD domain. - -Signed-off-by: Kevin Friedberg -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 21 ++++++++++++++++++--- - platform-intel.h | 1 + - super-intel.c | 28 ++++++++++++++++++---------- - 3 files changed, 37 insertions(+), 13 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index 757f0b1b..914164c0 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -64,9 +64,10 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - - if (strcmp(driver, "isci") == 0) - type = SYS_DEV_SAS; -- else if (strcmp(driver, "ahci") == 0) -+ else if (strcmp(driver, "ahci") == 0) { -+ vmd = find_driver_devices("pci", "vmd"); - type = SYS_DEV_SATA; -- else if (strcmp(driver, "nvme") == 0) { -+ } else if (strcmp(driver, "nvme") == 0) { - /* if looking for nvme devs, first look for vmd */ - vmd = find_driver_devices("pci", "vmd"); - type = SYS_DEV_NVME; -@@ -115,6 +116,17 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - free(rp); - } - -+ /* change sata type if under a vmd controller */ -+ if (type == SYS_DEV_SATA) { -+ struct sys_dev *dev; -+ char *rp = realpath(path, NULL); -+ for (dev = vmd; dev; dev = dev->next) { -+ if ((strncmp(dev->path, rp, strlen(dev->path)) == 0)) -+ type = SYS_DEV_SATA_VMD; -+ } -+ free(rp); -+ } -+ - /* if it's not Intel device or mark as VMD connected - skip it. */ - if (devpath_to_vendor(path) != 0x8086 || skip == 1) - continue; -@@ -166,7 +178,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - } - closedir(driver_dir); - -- if (vmd) { -+ /* nvme vmd needs a list separate from sata vmd */ -+ if (vmd && type == SYS_DEV_NVME) { - if (list) - list->next = vmd; - else -@@ -273,6 +286,7 @@ struct sys_dev *find_intel_devices(void) - free_sys_dev(&intel_devices); - - isci = find_driver_devices("pci", "isci"); -+ /* Searching for AHCI will return list of SATA and SATA VMD controllers */ - ahci = find_driver_devices("pci", "ahci"); - /* Searching for NVMe will return list of NVMe and VMD controllers */ - nvme = find_driver_devices("pci", "nvme"); -@@ -638,6 +652,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - - break; - case SYS_DEV_VMD: -+ case SYS_DEV_SATA_VMD: - for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { - if (!read_efi_variable(&orom, sizeof(orom), - vmd_efivars[i], VENDOR_GUID)) -diff --git a/platform-intel.h b/platform-intel.h -index 6238d23f..2c0f4e39 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -196,6 +196,7 @@ enum sys_dev_type { - SYS_DEV_SATA, - SYS_DEV_NVME, - SYS_DEV_VMD, -+ SYS_DEV_SATA_VMD, - SYS_DEV_MAX - }; - -diff --git a/super-intel.c b/super-intel.c -index aaf6659e..ae0f4a8c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -627,7 +627,8 @@ static const char *_sys_dev_type[] = { - [SYS_DEV_SAS] = "SAS", - [SYS_DEV_SATA] = "SATA", - [SYS_DEV_NVME] = "NVMe", -- [SYS_DEV_VMD] = "VMD" -+ [SYS_DEV_VMD] = "VMD", -+ [SYS_DEV_SATA_VMD] = "SATA VMD" - }; - - static int no_platform = -1; -@@ -2598,6 +2599,8 @@ static void print_found_intel_controllers(struct sys_dev *elem) - - if (elem->type == SYS_DEV_VMD) - fprintf(stderr, "VMD domain"); -+ else if (elem->type == SYS_DEV_SATA_VMD) -+ fprintf(stderr, "SATA VMD domain"); - else - fprintf(stderr, "RAID controller"); - -@@ -2768,8 +2771,9 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - if (!find_imsm_capability(hba)) { - char buf[PATH_MAX]; - pr_err("imsm capabilities not found for controller: %s (type %s)\n", -- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path, -- get_sys_dev_type(hba->type)); -+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ? -+ vmd_domain_to_controller(hba, buf) : -+ hba->path, get_sys_dev_type(hba->type)); - continue; - } - result = 0; -@@ -2822,11 +2826,12 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - - printf(" I/O Controller : %s (%s)\n", - hba->path, get_sys_dev_type(hba->type)); -- if (hba->type == SYS_DEV_SATA) { -+ if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) { - host_base = ahci_get_port_count(hba->path, &port_count); - if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { - if (verbose > 0) -- pr_err("failed to enumerate ports on SATA controller at %s.\n", hba->pci_id); -+ pr_err("failed to enumerate ports on %s controller at %s.\n", -+ get_sys_dev_type(hba->type), hba->pci_id); - result |= 2; - } - } -@@ -2856,7 +2861,8 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) - if (!find_imsm_capability(hba) && verbose > 0) { - char buf[PATH_MAX]; - pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n", -- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path); -+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ? -+ vmd_domain_to_controller(hba, buf) : hba->path); - } - else - result = 0; -@@ -2865,7 +2871,7 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) - const struct orom_entry *entry; - - for (entry = orom_entries; entry; entry = entry->next) { -- if (entry->type == SYS_DEV_VMD) { -+ if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_SATA_VMD) { - for (hba = list; hba; hba = hba->next) - print_imsm_capability_export(&entry->orom); - continue; -@@ -4782,10 +4788,12 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de - " but the container is assigned to Intel(R) %s %s (", - devname, - get_sys_dev_type(hba_name->type), -- hba_name->type == SYS_DEV_VMD ? "domain" : "RAID controller", -+ hba_name->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ? -+ "domain" : "RAID controller", - hba_name->pci_id ? : "Err!", - get_sys_dev_type(super->hba->type), -- hba->type == SYS_DEV_VMD ? "domain" : "RAID controller"); -+ hba->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ? -+ "domain" : "RAID controller"); - - while (hba) { - fprintf(stderr, "%s", hba->pci_id ? : "Err!"); -@@ -11274,7 +11282,7 @@ static const char *imsm_get_disk_controller_domain(const char *path) - hba = find_disk_attached_hba(-1, path); - if (hba && hba->type == SYS_DEV_SAS) - drv = "isci"; -- else if (hba && hba->type == SYS_DEV_SATA) -+ else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD)) - drv = "ahci"; - else if (hba && hba->type == SYS_DEV_VMD) - drv = "vmd"; --- -2.38.1 - diff --git a/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch b/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch deleted file mode 100644 index 1719f33..0000000 --- a/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch +++ /dev/null @@ -1,33 +0,0 @@ -From cf1577bf54afe76b77ecaa62df25901739ca8ae9 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 5 Jul 2023 16:34:56 +0200 -Subject: [PATCH 126/165] imsm: Fix possible segfault in check_no_platform() - -conf_line() may return NULL, which is not handled and might cause -segfault. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - super-intel.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/super-intel.c b/super-intel.c -index ae0f4a8c..4ef33d31 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -650,6 +650,11 @@ static int check_no_platform(void) - char *l = conf_line(fp); - char *w = l; - -+ if (l == NULL) { -+ fclose(fp); -+ return 0; -+ } -+ - do { - if (strcmp(w, search) == 0) - no_platform = 1; --- -2.40.1 - diff --git a/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch b/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch deleted file mode 100644 index c5bc8fc..0000000 --- a/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 9bc426fa1f236b8cad518431574a54fc60718739 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:33 +0200 -Subject: [PATCH 127/165] imsm: move sum_extents calculations to - merge_extents() - -This logic is only used by merge_extents() code, there is no need to pass -it as parameter. Move it up. Add proper description. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 37 +++++++++++++++++++------------------ - 1 file changed, 19 insertions(+), 18 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 4ef33d31..26b20313 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6882,21 +6882,31 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents) - return end - base_start; - } - --static unsigned long long merge_extents(struct intel_super *super, int sum_extents) -+/** merge_extents() - analyze extents and get max common free size. -+ * @super: Intel metadata, not NULL. -+ * -+ * Build a composite disk with all known extents and generate a new maxsize -+ * given the "all disks in an array must share a common start offset" -+ * constraint. -+ * -+ * Return: Max free space or 0 on failure. -+ */ -+static unsigned long long merge_extents(struct intel_super *super) - { -- /* build a composite disk with all known extents and generate a new -- * 'maxsize' given the "all disks in an array must share a common start -- * offset" constraint -- */ -- struct extent *e = xcalloc(sum_extents, sizeof(*e)); -+ struct extent *e; - struct dl *dl; - int i, j; -- int start_extent; -+ int start_extent, sum_extents = 0; - unsigned long long pos; - unsigned long long start = 0; - unsigned long long maxsize; - unsigned long reserve; - -+ for (dl = super->disks; dl; dl = dl->next) -+ if (dl->e) -+ sum_extents += dl->extent_cnt; -+ e = xcalloc(sum_extents, sizeof(struct extent)); -+ - /* coalesce and sort all extents. also, check to see if we need to - * reserve space between member arrays - */ -@@ -7555,13 +7565,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 0; - } - -- /* count total number of extents for merge */ -- i = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- i += dl->extent_cnt; -- -- maxsize = merge_extents(super, i); -+ maxsize = merge_extents(super); - - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -@@ -7615,7 +7619,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - struct imsm_super *mpb = super->anchor; - struct dl *dl; - int i; -- int extent_cnt; - struct extent *e; - unsigned long long maxsize; - unsigned long long minsize; -@@ -7624,7 +7627,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - - /* find the largest common start free region of the possible disks */ - used = 0; -- extent_cnt = 0; - cnt = 0; - for (dl = super->disks; dl; dl = dl->next) { - dl->raiddisk = -1; -@@ -7645,11 +7647,10 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - ; - dl->e = e; - dl->extent_cnt = i; -- extent_cnt += i; - cnt++; - } - -- maxsize = merge_extents(super, extent_cnt); -+ maxsize = merge_extents(super); - minsize = size; - if (size == 0) - /* chunk is in K */ --- -2.40.1 - diff --git a/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch b/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch deleted file mode 100644 index ed43855..0000000 --- a/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 5f027b9357c011ca0421400e258a777d97f18d17 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:34 +0200 -Subject: [PATCH 128/165] imsm: imsm_get_free_size() refactor. - -Move minsize calculations up. Add error message if free size is too small. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 27 ++++++++++++++------------- - 1 file changed, 14 insertions(+), 13 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 26b20313..16a30ba7 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7600,7 +7600,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - * @super: &intel_super pointer, not NULL. - * @raiddisks: number of raid disks. - * @size: requested size, could be 0 (means max size). -- * @chunk: requested chunk. -+ * @chunk: requested chunk size in KiB. - * @freesize: pointer for returned size value. - * - * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. -@@ -7620,14 +7620,15 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - struct dl *dl; - int i; - struct extent *e; -+ int cnt = 0; -+ int used = 0; - unsigned long long maxsize; -- unsigned long long minsize; -- int cnt; -- int used; -+ unsigned long long minsize = size; -+ -+ if (minsize == 0) -+ minsize = chunk * 2; - - /* find the largest common start free region of the possible disks */ -- used = 0; -- cnt = 0; - for (dl = super->disks; dl; dl = dl->next) { - dl->raiddisk = -1; - -@@ -7651,14 +7652,14 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - } - - maxsize = merge_extents(super); -- minsize = size; -- if (size == 0) -- /* chunk is in K */ -- minsize = chunk * 2; -+ if (maxsize < minsize) { -+ pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n", -+ maxsize, minsize); -+ return IMSM_STATUS_ERROR; -+ } - -- if (cnt < raiddisks || (super->orom && used && used != raiddisks) || -- maxsize < minsize || maxsize == 0) { -- pr_err("not enough devices with space to create array.\n"); -+ if (cnt < raiddisks || (super->orom && used && used != raiddisks)) { -+ pr_err("imsm: Not enough devices with space to create array.\n"); - return IMSM_STATUS_ERROR; - } - --- -2.40.1 - diff --git a/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch b/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch deleted file mode 100644 index 50d1d36..0000000 --- a/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 78c8028b331c8e281554d43fde4d46e9cb4a227e Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:35 +0200 -Subject: [PATCH 129/165] imsm: introduce round_member_size_to_mb() - -Extract rounding logic to separate function. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 31 +++++++++++++++++++++---------- - 1 file changed, 21 insertions(+), 10 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 16a30ba7..36171107 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -1644,17 +1644,29 @@ static int is_journal(struct imsm_disk *disk) - return (disk->status & JOURNAL_DISK) == JOURNAL_DISK; - } - --/* round array size down to closest MB and ensure it splits evenly -- * between members -+/** -+ * round_member_size_to_mb()- Round given size to closest MiB. -+ * @size: size to round in sectors. - */ --static unsigned long long round_size_to_mb(unsigned long long size, unsigned int -- disk_count) -+static inline unsigned long long round_member_size_to_mb(unsigned long long size) - { -- size /= disk_count; -- size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; -- size *= disk_count; -+ return (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; -+} - -- return size; -+/** -+ * round_size_to_mb()- Round given size. -+ * @array_size: size to round in sectors. -+ * @disk_count: count of data members. -+ * -+ * Get size per each data member and round it to closest MiB to ensure that data -+ * splits evenly between members. -+ * -+ * Return: Array size, rounded down. -+ */ -+static inline unsigned long long round_size_to_mb(unsigned long long array_size, -+ unsigned int disk_count) -+{ -+ return round_member_size_to_mb(array_size / disk_count) * disk_count; - } - - static int able_to_resync(int raid_level, int missing_disks) -@@ -11810,8 +11822,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - } else { - /* round size due to metadata compatibility - */ -- geo->size = (geo->size >> SECT_PER_MB_SHIFT) -- << SECT_PER_MB_SHIFT; -+ geo->size = round_member_size_to_mb(geo->size); - dprintf("Prepare update for size change to %llu\n", - geo->size ); - if (current_size >= geo->size) { --- -2.40.1 - diff --git a/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch b/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch deleted file mode 100644 index 6e5359e..0000000 --- a/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch +++ /dev/null @@ -1,238 +0,0 @@ -From cbaa7904a175628a294ed54b4de6c52afa4f830d Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:36 +0200 -Subject: [PATCH 130/165] imsm: move expand verification code into new function - -The code here is too complex. Move it to separate function and -simplify it. Add more error messages. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 187 +++++++++++++++++++++++++++----------------------- - 1 file changed, 101 insertions(+), 86 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 36171107..5bd70356 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11643,6 +11643,102 @@ static void imsm_update_metadata_locally(struct supertype *st, - } - } - -+/** -+ * imsm_analyze_expand() - check expand properties and calculate new size. -+ * @st: imsm supertype. -+ * @geo: new geometry params. -+ * @array: array info. -+ * @direction: reshape direction. -+ * -+ * Obtain free space after the &array and verify if expand to requested size is -+ * possible. If geo->size is set to %MAX_SIZE, assume that max free size is -+ * requested. -+ * -+ * Return: -+ * On success %IMSM_STATUS_OK is returned, geo->size and geo->raid_disks are -+ * updated. -+ * On error, %IMSM_STATUS_ERROR is returned. -+ */ -+static imsm_status_t imsm_analyze_expand(struct supertype *st, -+ struct geo_params *geo, -+ struct mdinfo *array, -+ int direction) -+{ -+ struct intel_super *super = st->sb; -+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); -+ int data_disks = imsm_num_data_members(map); -+ -+ unsigned long long current_size; -+ unsigned long long free_size; -+ unsigned long long new_size; -+ unsigned long long max_size; -+ -+ const int chunk_kib = geo->chunksize / 1024; -+ imsm_status_t rv; -+ -+ if (direction == ROLLBACK_METADATA_CHANGES) { -+ /** -+ * Accept size for rollback only. -+ */ -+ new_size = geo->size * 2; -+ goto success; -+ } -+ -+ if (super->current_vol + 1 != super->anchor->num_raid_devs) { -+ pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n", -+ super->current_vol, st->devnm); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (data_disks == 0) { -+ pr_err("imsm: Cannot retrieve data disks.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ current_size = array->custom_array_size / data_disks; -+ -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size); -+ if (rv != IMSM_STATUS_OK) { -+ pr_err("imsm: Cannot find free space for expand.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ max_size = round_member_size_to_mb(free_size + current_size); -+ -+ if (geo->size == MAX_SIZE) -+ new_size = max_size; -+ else -+ new_size = round_member_size_to_mb(geo->size * 2); -+ -+ if (new_size == 0) { -+ pr_err("imsm: Rounded requested size is 0.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size > max_size) { -+ pr_err("imsm: Rounded requested size (%llu) is larger than free space available (%llu).\n", -+ new_size, max_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size == current_size) { -+ pr_err("imsm: Rounded requested size (%llu) is same as current size (%llu).\n", -+ new_size, current_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size < current_size) { -+ pr_err("imsm: Size reduction is not supported, rounded requested size (%llu) is smaller than current (%llu).\n", -+ new_size, current_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+success: -+ dprintf("imsm: New size per member is %llu.\n", new_size); -+ geo->size = data_disks * new_size; -+ geo->raid_disks = dev->vol.map->num_members; -+ return IMSM_STATUS_OK; -+} -+ - /*************************************************************************** - * Function: imsm_analyze_change - * Description: Function analyze change for single volume -@@ -11663,13 +11759,6 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - int devNumChange = 0; - /* imsm compatible layout value for array geometry verification */ - int imsm_layout = -1; -- int data_disks; -- struct imsm_dev *dev; -- struct imsm_map *map; -- struct intel_super *super; -- unsigned long long current_size; -- unsigned long long free_size; -- unsigned long long max_size; - imsm_status_t rv; - - getinfo_super_imsm_volume(st, &info, NULL); -@@ -11752,94 +11841,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - geo->chunksize = info.array.chunk_size; - } - -- chunk = geo->chunksize / 1024; -- -- super = st->sb; -- dev = get_imsm_dev(super, super->current_vol); -- map = get_imsm_map(dev, MAP_0); -- data_disks = imsm_num_data_members(map); -- /* compute current size per disk member -- */ -- current_size = info.custom_array_size / data_disks; -- -- if (geo->size > 0 && geo->size != MAX_SIZE) { -- /* align component size -- */ -- geo->size = imsm_component_size_alignment_check( -- get_imsm_raid_level(dev->vol.map), -- chunk * 1024, super->sector_size, -- geo->size * 2); -- if (geo->size == 0) { -- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is 0).\n", -- current_size); -- goto analyse_change_exit; -- } -- } -- -- if (current_size != geo->size && geo->size > 0) { -+ if (geo->size > 0) { - if (change != -1) { - pr_err("Error. Size change should be the only one at a time.\n"); - change = -1; - goto analyse_change_exit; - } -- if ((super->current_vol + 1) != super->anchor->num_raid_devs) { -- pr_err("Error. The last volume in container can be expanded only (%i/%s).\n", -- super->current_vol, st->devnm); -- goto analyse_change_exit; -- } -- /* check the maximum available size -- */ -- rv = imsm_get_free_size(super, dev->vol.map->num_members, -- 0, chunk, &free_size); - -+ rv = imsm_analyze_expand(st, geo, &info, direction); - if (rv != IMSM_STATUS_OK) -- /* Cannot find maximum available space -- */ -- max_size = 0; -- else { -- max_size = free_size + current_size; -- /* align component size -- */ -- max_size = imsm_component_size_alignment_check( -- get_imsm_raid_level(dev->vol.map), -- chunk * 1024, super->sector_size, -- max_size); -- } -- if (geo->size == MAX_SIZE) { -- /* requested size change to the maximum available size -- */ -- if (max_size == 0) { -- pr_err("Error. Cannot find maximum available space.\n"); -- change = -1; -- goto analyse_change_exit; -- } else -- geo->size = max_size; -- } -- -- if (direction == ROLLBACK_METADATA_CHANGES) { -- /* accept size for rollback only -- */ -- } else { -- /* round size due to metadata compatibility -- */ -- geo->size = round_member_size_to_mb(geo->size); -- dprintf("Prepare update for size change to %llu\n", -- geo->size ); -- if (current_size >= geo->size) { -- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is %llu).\n", -- current_size, geo->size); -- goto analyse_change_exit; -- } -- if (max_size && geo->size > max_size) { -- pr_err("Error. Requested size is larger than maximum available size (maximum available size is %llu, requested size /rounded/ is %llu).\n", -- max_size, geo->size); -- goto analyse_change_exit; -- } -- } -- geo->size *= data_disks; -- geo->raid_disks = dev->vol.map->num_members; -+ goto analyse_change_exit; - change = CH_ARRAY_SIZE; - } -+ -+ chunk = geo->chunksize / 1024; - if (!validate_geometry_imsm(st, - geo->level, - imsm_layout, --- -2.40.1 - diff --git a/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch b/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch deleted file mode 100644 index 10faec5..0000000 --- a/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch +++ /dev/null @@ -1,214 +0,0 @@ -From aa19fdd45b2ba474f6a51a6d4b8f3c44ef19dafd Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:37 +0200 -Subject: [PATCH 131/165] imsm: return free space after volume for expand - -merge_extends() routine searches for the biggest free space. For expand, -it works only in standard cases where the last volume is expanded and -the free space is determined after the last volume. -Add volume index to extent struct and use that do determine size after -super->current_vol during expand. - -Limitation to last volume is no longer needed. It unblocks scenarios -where kill-subarray is used to remove first volume and later it is -recreated (now it is the second volume, even if it is placed before -existing one). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 71 +++++++++++++++++++++++++++------------------------ - 1 file changed, 37 insertions(+), 34 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5bd70356..e249d925 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -499,8 +499,15 @@ struct intel_disk { - struct intel_disk *next; - }; - -+/** -+ * struct extent - reserved space details. -+ * @start: start offset. -+ * @size: size of reservation, set to 0 for metadata reservation. -+ * @vol: index of the volume, meaningful if &size is set. -+ */ - struct extent { - unsigned long long start, size; -+ int vol; - }; - - /* definitions of reshape process types */ -@@ -1539,9 +1546,10 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - int get_minimal_reservation) - { - /* find a list of used extents on the given physical device */ -- struct extent *rv, *e; -- int i; - int memberships = count_memberships(dl, super); -+ struct extent *rv = xcalloc(memberships + 1, sizeof(struct extent)); -+ struct extent *e = rv; -+ int i; - __u32 reservation; - - /* trim the reserved area for spares, so they can join any array -@@ -1553,9 +1561,6 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - else - reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS; - -- rv = xcalloc(sizeof(struct extent), (memberships + 1)); -- e = rv; -- - for (i = 0; i < super->anchor->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); - struct imsm_map *map = get_imsm_map(dev, MAP_0); -@@ -1563,6 +1568,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - if (get_imsm_disk_slot(map, dl->index) >= 0) { - e->start = pba_of_lba0(map); - e->size = per_dev_array_size(map); -+ e->vol = i; - e++; - } - } -@@ -6894,24 +6900,26 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents) - return end - base_start; - } - --/** merge_extents() - analyze extents and get max common free size. -+/** merge_extents() - analyze extents and get free size. - * @super: Intel metadata, not NULL. -+ * @expanding: if set, we are expanding &super->current_vol. - * -- * Build a composite disk with all known extents and generate a new maxsize -- * given the "all disks in an array must share a common start offset" -- * constraint. -+ * Build a composite disk with all known extents and generate a size given the -+ * "all disks in an array must share a common start offset" constraint. -+ * If a volume is expanded, then return free space after the volume. - * -- * Return: Max free space or 0 on failure. -+ * Return: Free space or 0 on failure. - */ --static unsigned long long merge_extents(struct intel_super *super) -+static unsigned long long merge_extents(struct intel_super *super, const bool expanding) - { - struct extent *e; - struct dl *dl; -- int i, j; -- int start_extent, sum_extents = 0; -- unsigned long long pos; -+ int i, j, pos_vol_idx = -1; -+ int extent_idx = 0; -+ int sum_extents = 0; -+ unsigned long long pos = 0; - unsigned long long start = 0; -- unsigned long long maxsize; -+ unsigned long long maxsize = 0; - unsigned long reserve; - - for (dl = super->disks; dl; dl = dl->next) -@@ -6936,26 +6944,26 @@ static unsigned long long merge_extents(struct intel_super *super) - j = 0; - while (i < sum_extents) { - e[j].start = e[i].start; -+ e[j].vol = e[i].vol; - e[j].size = find_size(e, &i, sum_extents); - j++; - if (e[j-1].size == 0) - break; - } - -- pos = 0; -- maxsize = 0; -- start_extent = 0; - i = 0; - do { -- unsigned long long esize; -+ unsigned long long esize = e[i].start - pos; - -- esize = e[i].start - pos; -- if (esize >= maxsize) { -+ if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) { - maxsize = esize; - start = pos; -- start_extent = i; -+ extent_idx = i; - } -+ - pos = e[i].start + e[i].size; -+ pos_vol_idx = e[i].vol; -+ - i++; - } while (e[i-1].size); - free(e); -@@ -6966,7 +6974,7 @@ static unsigned long long merge_extents(struct intel_super *super) - /* FIXME assumes volume at offset 0 is the first volume in a - * container - */ -- if (start_extent > 0) -+ if (extent_idx > 0) - reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */ - else - reserve = 0; -@@ -7577,7 +7585,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 0; - } - -- maxsize = merge_extents(super); -+ maxsize = merge_extents(super, false); - - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -@@ -7626,7 +7634,8 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - const int raiddisks, - unsigned long long size, - const int chunk, -- unsigned long long *freesize) -+ unsigned long long *freesize, -+ bool expanding) - { - struct imsm_super *mpb = super->anchor; - struct dl *dl; -@@ -7663,7 +7672,7 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - cnt++; - } - -- maxsize = merge_extents(super); -+ maxsize = merge_extents(super, expanding); - if (maxsize < minsize) { - pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n", - maxsize, minsize); -@@ -7721,7 +7730,7 @@ static imsm_status_t autolayout_imsm(struct intel_super *super, - int vol_cnt = super->anchor->num_raid_devs; - imsm_status_t rv; - -- rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); -+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize, false); - if (rv != IMSM_STATUS_OK) - return IMSM_STATUS_ERROR; - -@@ -11685,19 +11694,13 @@ static imsm_status_t imsm_analyze_expand(struct supertype *st, - goto success; - } - -- if (super->current_vol + 1 != super->anchor->num_raid_devs) { -- pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n", -- super->current_vol, st->devnm); -- return IMSM_STATUS_ERROR; -- } -- - if (data_disks == 0) { - pr_err("imsm: Cannot retrieve data disks.\n"); - return IMSM_STATUS_ERROR; - } - current_size = array->custom_array_size / data_disks; - -- rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size); -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size, true); - if (rv != IMSM_STATUS_OK) { - pr_err("imsm: Cannot find free space for expand.\n"); - return IMSM_STATUS_ERROR; --- -2.40.1 - diff --git a/SOURCES/0132-imsm-fix-free-space-calculations.patch b/SOURCES/0132-imsm-fix-free-space-calculations.patch deleted file mode 100644 index fe3025f..0000000 --- a/SOURCES/0132-imsm-fix-free-space-calculations.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 1dea84ae38288fbefa04d9fda2b3f36c21a9e1bd Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:38 +0200 -Subject: [PATCH 132/165] imsm: fix free space calculations - -Between two volumes or between last volume and metadata at least -IMSM_RESERVED_SECTORS gap must exist. Currently the gap can be doubled -because metadata reservation contains IMSM_RESERVED_SECTORS too. - -Divide reserve variable into pre_reservation and post_reservation to be -more flexible and decide separately if each reservation is needed. - -Pre_reservation is needed only when a volume is created and it is not a -real first volume in a container (we can check that by extent_idx). -This type of reservation is not needed for expand. - -Post_reservation is not needed only if real last volume is created or -expanded because reservation is done with the metadata. - -The volume index in metadata cannot be trusted, because the real volume -order can be reversed. It is safer to use extent table, it is sorted by -start position. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 50 ++++++++++++++++++++++++++++++-------------------- - 1 file changed, 30 insertions(+), 20 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index e249d925..824c1356 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6919,8 +6919,11 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - int sum_extents = 0; - unsigned long long pos = 0; - unsigned long long start = 0; -- unsigned long long maxsize = 0; -- unsigned long reserve; -+ unsigned long long free_size = 0; -+ -+ unsigned long pre_reservation = 0; -+ unsigned long post_reservation = IMSM_RESERVED_SECTORS; -+ unsigned long reservation_size; - - for (dl = super->disks; dl; dl = dl->next) - if (dl->e) -@@ -6955,8 +6958,8 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - do { - unsigned long long esize = e[i].start - pos; - -- if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) { -- maxsize = esize; -+ if (expanding ? pos_vol_idx == super->current_vol : esize >= free_size) { -+ free_size = esize; - start = pos; - extent_idx = i; - } -@@ -6966,28 +6969,35 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - - i++; - } while (e[i-1].size); -- free(e); - -- if (maxsize == 0) -+ if (free_size == 0) { -+ dprintf("imsm: Cannot find free size.\n"); -+ free(e); - return 0; -+ } - -- /* FIXME assumes volume at offset 0 is the first volume in a -- * container -- */ -- if (extent_idx > 0) -- reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */ -- else -- reserve = 0; -+ if (!expanding && extent_idx != 0) -+ /* -+ * Not a real first volume in a container is created, pre_reservation is needed. -+ */ -+ pre_reservation = IMSM_RESERVED_SECTORS; - -- if (maxsize < reserve) -- return 0; -+ if (e[extent_idx].size == 0) -+ /* -+ * extent_idx points to the metadata, post_reservation is allready done. -+ */ -+ post_reservation = 0; -+ free(e); - -- super->create_offset = ~((unsigned long long) 0); -- if (start + reserve > super->create_offset) -- return 0; /* start overflows create_offset */ -- super->create_offset = start + reserve; -+ reservation_size = pre_reservation + post_reservation; -+ -+ if (free_size < reservation_size) { -+ dprintf("imsm: Reservation size is greater than free space.\n"); -+ return 0; -+ } - -- return maxsize - reserve; -+ super->create_offset = start + pre_reservation; -+ return free_size - reservation_size; - } - - static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) --- -2.40.1 - diff --git a/SOURCES/0133-Add-secure-gethostname-wrapper.patch b/SOURCES/0133-Add-secure-gethostname-wrapper.patch deleted file mode 100644 index 19f6c36..0000000 --- a/SOURCES/0133-Add-secure-gethostname-wrapper.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 21e622f214a38c048c5689158bc6314a91a46e40 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Fri, 16 Jun 2023 21:45:55 +0200 -Subject: [PATCH 133/165] Add secure gethostname() wrapper - -gethostname() func does not ensure null-terminated string -if hostname is longer than buffer length. -For security, a function s_gethostname() has been added -to ensure that "\0" is added to the end of the buffer. -Previously this had to be handled in each place -of the gethostname() call. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Monitor.c | 3 +-- - lib.c | 19 +++++++++++++++++++ - mapfile.c | 3 +-- - mdadm.c | 3 +-- - mdadm.h | 1 + - super-ddf.c | 3 +-- - 6 files changed, 24 insertions(+), 8 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 66175968..e74a0558 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -222,11 +222,10 @@ int Monitor(struct mddev_dev *devlist, - info.dosyslog = dosyslog; - info.test = c->test; - -- if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { -+ if (s_gethostname(info.hostname, sizeof(info.hostname)) != 0) { - pr_err("Cannot get hostname.\n"); - return 1; - } -- info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ - if (check_one_sharer(c->scan) == 2) -diff --git a/lib.c b/lib.c -index fe5c8d2c..8a4b48e0 100644 ---- a/lib.c -+++ b/lib.c -@@ -585,3 +585,22 @@ int parse_num(int *dest, const char *num) - *dest = temp; - return 0; - } -+ -+/** -+ * s_gethostname() - secure get hostname. Assure null-terminated string. -+ * -+ * @buf: buffer for hostname. -+ * @buf_len: buffer length. -+ * -+ * Return: gethostname() result. -+ */ -+int s_gethostname(char *buf, int buf_len) -+{ -+ assert(buf); -+ -+ int ret = gethostname(buf, buf_len); -+ -+ buf[buf_len - 1] = 0; -+ -+ return ret; -+} -diff --git a/mapfile.c b/mapfile.c -index 34fea179..f1f3ee2c 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -363,8 +363,7 @@ void RebuildMap(void) - char *homehost = conf_get_homehost(&require_homehost); - - if (homehost == NULL || strcmp(homehost, "")==0) { -- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { -- sys_hostname[sizeof(sys_hostname)-1] = 0; -+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { - homehost = sys_hostname; - } - } -diff --git a/mdadm.c b/mdadm.c -index 076b45e0..e32598cb 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1340,8 +1340,7 @@ int main(int argc, char *argv[]) - if (c.homehost == NULL && c.require_homehost) - c.homehost = conf_get_homehost(&c.require_homehost); - if (c.homehost == NULL || strcasecmp(c.homehost, "") == 0) { -- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { -- sys_hostname[sizeof(sys_hostname)-1] = 0; -+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { - c.homehost = sys_hostname; - } - } -diff --git a/mdadm.h b/mdadm.h -index 83f2cf7f..f0ceeb78 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1805,6 +1805,7 @@ extern void set_dlm_hooks(void); - extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); - extern bool is_directory(const char *path); - extern bool is_file(const char *path); -+extern int s_gethostname(char *buf, int buf_len); - - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) -diff --git a/super-ddf.c b/super-ddf.c -index 7213284e..c5242654 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -2364,8 +2364,7 @@ static int init_super_ddf(struct supertype *st, - * Remaining 16 are serial number.... maybe a hostname would do? - */ - memcpy(ddf->controller.guid, T10, sizeof(T10)); -- gethostname(hostname, sizeof(hostname)); -- hostname[sizeof(hostname) - 1] = 0; -+ s_gethostname(hostname, sizeof(hostname)); - hostlen = strlen(hostname); - memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen); - for (i = strlen(T10) ; i+hostlen < 24; i++) --- -2.40.1 - diff --git a/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch b/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch deleted file mode 100644 index abe9ef6..0000000 --- a/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1ab341e5ce0cb01a1533a2c36e5b69eabf12bf95 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 25 Aug 2023 20:55:41 +0800 -Subject: [PATCH 134/165] mdadm: Stop mdcheck_continue timer when mdcheck_start - service can finish check - -mdcheck_continue is triggered by mdcheck_start timer. It's used to -continue check action if the raid is too big and mdcheck_start -service can't finish check action. If mdcheck start can finish check -action, it doesn't need to mdcheck continue service anymore. So stop -it when mdcheck start service can finish check action. - -Signed-off-by: Xiao Ni -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - misc/mdcheck | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/misc/mdcheck b/misc/mdcheck -index 700c3e25..f87999d3 100644 ---- a/misc/mdcheck -+++ b/misc/mdcheck -@@ -140,7 +140,13 @@ do - echo $a > $fl - any=yes - done -- if [ -z "$any" ]; then exit 0; fi -+ # mdcheck_continue.timer is started by mdcheck_start.timer. -+ # When the check action can be finished in mdcheck_start.service, -+ # it doesn't need mdcheck_continue anymore. -+ if [ -z "$any" ]; then -+ systemctl stop mdcheck_continue.timer -+ exit 0; -+ fi - sleep 120 - done - --- -2.40.1 - diff --git a/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch b/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch deleted file mode 100644 index d7399c9..0000000 --- a/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e9fb93af0f769d147a13e86ab4e5d0aeb935e9fc Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:34 +0800 -Subject: [PATCH 135/165] Fix memory leak in file Assemble - -When we test mdadm with asan, we found some memory leaks in Assemble.c -We fix these memory leaks based on code logic. - -v2: Set st = NULL before jumping to loop - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Assemble.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 49804941..61e8cd17 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -341,8 +341,10 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -- if (tst) -+ if (tst) { - tst->ss->free_super(tst); -+ free(tst); -+ } - return -1; - } - -@@ -417,6 +419,7 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -+ free(st); - return -1; - } - if (c->verbose > 0) -@@ -425,6 +428,8 @@ static int select_devices(struct mddev_dev *devlist, - - /* make sure we finished the loop */ - tmpdev = NULL; -+ free(st); -+ st = NULL; - goto loop; - } else { - content = *contentp; -@@ -533,6 +538,7 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -+ free(tst); - return -1; - } - tmpdev->used = 1; -@@ -546,8 +552,10 @@ static int select_devices(struct mddev_dev *devlist, - } - dev_policy_free(pol); - pol = NULL; -- if (tst) -+ if (tst) { - tst->ss->free_super(tst); -+ free(tst); -+ } - } - - /* Check if we found some imsm spares but no members */ -@@ -839,6 +847,7 @@ static int load_devices(struct devs *devices, char *devmap, - close(mdfd); - free(devices); - free(devmap); -+ free(best); - *stp = st; - return -1; - } -@@ -1950,6 +1959,7 @@ out: - } else if (mdfd >= 0) - close(mdfd); - -+ free(best); - /* '2' means 'OK, but not started yet' */ - if (rv == -1) { - free(devices); --- -2.40.1 - diff --git a/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch b/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch deleted file mode 100644 index d4b1a83..0000000 --- a/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8fd0c565b09ba449418d7d604ceba66313246152 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:35 +0800 -Subject: [PATCH 136/165] Fix memory leak in file Kill - -When we test mdadm with asan, we found some memory leaks in Kill.c -We fix these memory leaks based on code logic. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Kill.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/Kill.c b/Kill.c -index bfd0efdc..43c9abed 100644 ---- a/Kill.c -+++ b/Kill.c -@@ -41,6 +41,7 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - * 4 - failed to find a superblock. - */ - -+ bool free_super = false; - int fd, rv = 0; - - if (force) -@@ -52,8 +53,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - dev); - return 2; - } -- if (st == NULL) -+ if (st == NULL) { - st = guess_super(fd); -+ free_super = true; -+ } - if (st == NULL || st->ss->init_super == NULL) { - if (verbose >= 0) - pr_err("Unrecognised md component device - %s\n", dev); -@@ -77,6 +80,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - rv = 0; - } - } -+ if (free_super && st) { -+ st->ss->free_super(st); -+ free(st); -+ } - close(fd); - return rv; - } --- -2.40.1 - diff --git a/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch b/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch deleted file mode 100644 index 214c0e2..0000000 --- a/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f6feb3fbb50f48c193e9e4d775a20aa20f7b47b3 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:36 +0800 -Subject: [PATCH 137/165] Fix memory leak in file Manage - -When we test mdadm with asan, we found some memory leaks in Manage.c -We fix these memory leaks based on code logic. - -v2: Fix free() of uninitialized 'tst' in abort path. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Manage.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/Manage.c b/Manage.c -index f54de7c6..f997b163 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - if (verbose >= 0) - pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n", - devname); -+ sysfs_free(mdi); - return 1; - } - /* If this is an mdmon managed array, just write 'inactive' -@@ -801,8 +802,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - rdev, update, devname, - verbose, array); - dev_st->ss->free_super(dev_st); -- if (rv) -+ if (rv) { -+ free(dev_st); - return rv; -+ } -+ } -+ if (dev_st) { -+ dev_st->ss->free_super(dev_st); -+ free(dev_st); - } - } - if (dv->disposition == 'M') { -@@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd, - unsigned long long array_size; - struct mddev_dev *dv; - int tfd = -1; -- struct supertype *tst; -+ struct supertype *tst = NULL; - char *subarray = NULL; - int sysfd = -1; - int count = 0; /* number of actions taken */ -@@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd, - break; - } - } -+ free(tst); - if (frozen > 0) - sysfs_set_str(&info, NULL, "sync_action","idle"); - if (test && count == 0) -@@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd, - return 0; - - abort: -+ free(tst); - if (frozen > 0) - sysfs_set_str(&info, NULL, "sync_action","idle"); - return !test && busy ? 2 : 1; --- -2.40.1 - diff --git a/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch b/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch deleted file mode 100644 index 2cb9f7f..0000000 --- a/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e62a561ee8b7157a2390eab215dcef6240bd7b03 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:37 +0800 -Subject: [PATCH 138/165] Fix memory leak in file mdadm - -When we test mdadm with asan, we found some memory leaks in mdadm.c -We fix these memory leaks based on code logic. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdadm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/mdadm.c b/mdadm.c -index e32598cb..22d1c53b 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1708,6 +1708,10 @@ int main(int argc, char *argv[]) - autodetect(); - break; - } -+ if (ss) { -+ ss->ss->free_super(ss); -+ free(ss); -+ } - if (locked) - cluster_release_dlmlock(); - close_fd(&mdfd); --- -2.40.1 - diff --git a/SOURCES/0139-Fix-unsafe-string-functions.patch b/SOURCES/0139-Fix-unsafe-string-functions.patch deleted file mode 100644 index 955b1bb..0000000 --- a/SOURCES/0139-Fix-unsafe-string-functions.patch +++ /dev/null @@ -1,116 +0,0 @@ -From dd5ab40204b1d78ec3bdbcfd5a38a8ffb72bdb50 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 11 May 2023 04:55:12 +0200 -Subject: [PATCH 139/165] Fix unsafe string functions - -Add string length limitations where necessary to -avoid buffer overflows. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - mdmon.c | 6 +++--- - mdopen.c | 4 ++-- - platform-intel.c | 2 +- - super-intel.c | 6 +++--- - 4 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index cef5bbc8..a2038fe6 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -240,7 +240,7 @@ static int make_control_sock(char *devname) - return -1; - - addr.sun_family = PF_LOCAL; -- strcpy(addr.sun_path, path); -+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - umask(077); /* ensure no world write access */ - if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - close(sfd); -@@ -389,7 +389,7 @@ int main(int argc, char *argv[]) - - if (all) { - struct mdstat_ent *mdstat, *e; -- int container_len = strlen(container_name); -+ int container_len = strnlen(container_name, MD_NAME_MAX); - - /* launch an mdmon instance for each container found */ - mdstat = mdstat_read(0, 0); -@@ -472,7 +472,7 @@ static int mdmon(char *devnm, int must_fork, int takeover) - pfd[0] = pfd[1] = -1; - - container = xcalloc(1, sizeof(*container)); -- strcpy(container->devnm, devnm); -+ snprintf(container->devnm, MD_NAME_MAX, "%s", devnm); - container->arrays = NULL; - container->sock = -1; - -diff --git a/mdopen.c b/mdopen.c -index d3022a54..3daa71f9 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -193,14 +193,14 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - - if (dev) { - if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- strcpy(cname, dev + DEV_MD_DIR_LEN); -+ snprintf(cname, MD_NAME_MAX, "%s", dev + DEV_MD_DIR_LEN); - } else if (strncmp(dev, "/dev/", 5) == 0) { - char *e = dev + strlen(dev); - while (e > dev && isdigit(e[-1])) - e--; - if (e[0]) - num = strtoul(e, NULL, 10); -- strcpy(cname, dev+5); -+ snprintf(cname, MD_NAME_MAX, "%s", dev + 5); - cname[e-(dev+5)] = 0; - /* name *must* be mdXX or md_dXX in this context */ - if (num < 0 || -diff --git a/platform-intel.c b/platform-intel.c -index 914164c0..eb6e1b7e 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -214,7 +214,7 @@ struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path) - - static int devpath_to_ll(const char *dev_path, const char *entry, unsigned long long *val) - { -- char path[strlen(dev_path) + strlen(entry) + 2]; -+ char path[strnlen(dev_path, PATH_MAX) + strnlen(entry, PATH_MAX) + 2]; - int fd; - int n; - -diff --git a/super-intel.c b/super-intel.c -index 824c1356..ce813172 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7043,7 +7043,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, - int fd = -1; - while (dev && !is_fd_valid(fd)) { - char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1); -- num = sprintf(path, "%s%s", "/dev/", dev->name); -+ num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name); - if (num > 0) - fd = open(path, O_RDONLY, 0); - if (num <= 0 || !is_fd_valid(fd)) { -@@ -7935,7 +7935,7 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) - - if (i < current_vol) - continue; -- sprintf(subarray, "%u", i); -+ snprintf(subarray, sizeof(subarray), "%u", i); - if (is_subarray_active(subarray, st->devnm)) { - pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n", - current_vol, i); -@@ -11308,7 +11308,7 @@ static const char *imsm_get_disk_controller_domain(const char *path) - char *drv=NULL; - struct stat st; - -- strcpy(disk_path, disk_by_path); -+ strncpy(disk_path, disk_by_path, PATH_MAX); - strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1); - if (stat(disk_path, &st) == 0) { - struct sys_dev* hba; --- -2.40.1 - diff --git a/SOURCES/0140-platform-intel-limit-guid-length.patch b/SOURCES/0140-platform-intel-limit-guid-length.patch deleted file mode 100644 index 8ed03fa..0000000 --- a/SOURCES/0140-platform-intel-limit-guid-length.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5ccd457b29809bee442749b5f66ac27ebba4a72d Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 11 May 2023 04:55:13 +0200 -Subject: [PATCH 140/165] platform-intel: limit guid length - -Moving GUID_STR_MAX to header to use it as -a length limitation for snprintf function. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 3 --- - platform-intel.h | 5 ++++- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index eb6e1b7e..ef90c3fd 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -510,9 +510,6 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) - return get_orom_by_device_id(hba->dev_id); - } - --#define GUID_STR_MAX 37 /* according to GUID format: -- * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ -- - #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ - ((struct efi_guid) \ - {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ -diff --git a/platform-intel.h b/platform-intel.h -index 2c0f4e39..ba97fb04 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -19,6 +19,9 @@ - #include - #include - -+/* according to GUID format: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ -+#define GUID_STR_MAX 37 -+ - /* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */ - struct imsm_orom { - __u8 signature[4]; -@@ -229,7 +232,7 @@ extern struct orom_entry *orom_entries; - - static inline char *guid_str(char *buf, struct efi_guid guid) - { -- sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", -+ snprintf(buf, GUID_STR_MAX, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid.b[3], guid.b[2], guid.b[1], guid.b[0], - guid.b[5], guid.b[4], guid.b[7], guid.b[6], - guid.b[8], guid.b[9], guid.b[10], guid.b[11], --- -2.40.1 - diff --git a/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch b/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch deleted file mode 100644 index be4cc37..0000000 --- a/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 8d1114be8c0a307d251c24078833b029efabc448 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 5 Jul 2023 16:23:17 +0200 -Subject: [PATCH 141/165] imsm: Add reading vmd register for finding imsm - capability - -Currently mdadm does not find imsm capability when running inside VM. -This patch adds the possibility to read from vmd register and check for -capability, effectively allowing to use mdadm with imsm inside virtual machines. - -Additionally refactor find_imsm_capability() to make assignments in new -lines. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++- - platform-intel.h | 11 ++++- - super-intel.c | 11 +++-- - 3 files changed, 130 insertions(+), 6 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index ef90c3fd..ac282bc5 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -700,6 +700,106 @@ const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba) - return &nvme_orom->orom; - } - -+#define VMD_REGISTER_OFFSET 0x3FC -+#define VMD_REGISTER_SKU_SHIFT 1 -+#define VMD_REGISTER_SKU_MASK (0x00000007) -+#define VMD_REGISTER_SKU_PREMIUM 2 -+#define MD_REGISTER_VER_MAJOR_SHIFT 4 -+#define MD_REGISTER_VER_MAJOR_MASK (0x0000000F) -+#define MD_REGISTER_VER_MINOR_SHIFT 8 -+#define MD_REGISTER_VER_MINOR_MASK (0x0000000F) -+ -+/* -+ * read_vmd_register() - Reads VMD register and writes contents to buff ptr -+ * @buff: buffer for vmd register data, should be the size of uint32_t -+ * -+ * Return: 0 on success, 1 on error -+ */ -+int read_vmd_register(uint32_t *buff, struct sys_dev *hba) -+{ -+ int fd; -+ char vmd_pci_config_path[PATH_MAX]; -+ -+ if (!vmd_domain_to_controller(hba, vmd_pci_config_path)) -+ return 1; -+ -+ strncat(vmd_pci_config_path, "/config", PATH_MAX - strnlen(vmd_pci_config_path, PATH_MAX)); -+ -+ fd = open(vmd_pci_config_path, O_RDONLY); -+ if (fd < 0) -+ return 1; -+ -+ if (pread(fd, buff, sizeof(uint32_t), VMD_REGISTER_OFFSET) != sizeof(uint32_t)) { -+ close(fd); -+ return 1; -+ } -+ close(fd); -+ return 0; -+} -+ -+/* -+ * add_vmd_orom() - Adds VMD orom cap to orom list, writes orom_entry ptr into vmd_orom -+ * @vmd_orom: pointer to orom entry pointer -+ * -+ * Return: 0 on success, 1 on error -+ */ -+int add_vmd_orom(struct orom_entry **vmd_orom, struct sys_dev *hba) -+{ -+ uint8_t sku; -+ uint32_t vmd_register_data; -+ struct imsm_orom vmd_orom_cap = { -+ .signature = IMSM_VMD_OROM_COMPAT_SIGNATURE, -+ .sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB | -+ IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB | -+ IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB, -+ .dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME, -+ .tds = IMSM_OROM_TOTAL_DISKS_VMD, -+ .vpa = IMSM_OROM_VOLUMES_PER_ARRAY, -+ .vphba = IMSM_OROM_VOLUMES_PER_HBA_VMD, -+ .attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK, -+ .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem | -+ IMSM_OROM_CAPABILITIES_TPV -+ }; -+ -+ if (read_vmd_register(&vmd_register_data, hba) != 0) -+ return 1; -+ -+ sku = (uint8_t)((vmd_register_data >> VMD_REGISTER_SKU_SHIFT) & -+ VMD_REGISTER_SKU_MASK); -+ -+ if (sku == VMD_REGISTER_SKU_PREMIUM) -+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | -+ IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5; -+ else -+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID_CNG; -+ -+ vmd_orom_cap.major_ver = (uint8_t) -+ ((vmd_register_data >> MD_REGISTER_VER_MAJOR_SHIFT) & -+ MD_REGISTER_VER_MAJOR_MASK); -+ vmd_orom_cap.minor_ver = (uint8_t) -+ ((vmd_register_data >> MD_REGISTER_VER_MINOR_SHIFT) & -+ MD_REGISTER_VER_MINOR_MASK); -+ -+ *vmd_orom = add_orom(&vmd_orom_cap); -+ -+ return 0; -+} -+ -+const struct imsm_orom *find_imsm_vmd(struct sys_dev *hba) -+{ -+ static struct orom_entry *vmd_orom; -+ -+ if (hba->type != SYS_DEV_VMD) -+ return NULL; -+ -+ if (!vmd_orom && add_vmd_orom(&vmd_orom, hba) != 0) -+ return NULL; -+ -+ add_orom_device_id(vmd_orom, hba->dev_id); -+ vmd_orom->type = SYS_DEV_VMD; -+ return &vmd_orom->orom; -+} -+ - const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) - { - const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id); -@@ -709,9 +809,19 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) - - if (hba->type == SYS_DEV_NVME) - return find_imsm_nvme(hba); -- if ((cap = find_imsm_efi(hba)) != NULL) -+ -+ cap = find_imsm_efi(hba); -+ if (cap) - return cap; -- if ((cap = find_imsm_hba_orom(hba)) != NULL) -+ -+ if (hba->type == SYS_DEV_VMD) { -+ cap = find_imsm_vmd(hba); -+ if (cap) -+ return cap; -+ } -+ -+ cap = find_imsm_hba_orom(hba); -+ if (cap) - return cap; - - return NULL; -diff --git a/platform-intel.h b/platform-intel.h -index ba97fb04..ce29d3da 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -27,6 +27,7 @@ struct imsm_orom { - __u8 signature[4]; - #define IMSM_OROM_SIGNATURE "$VER" - #define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM" -+ #define IMSM_VMD_OROM_COMPAT_SIGNATURE "$VMD" - __u8 table_ver_major; /* Currently 2 (can change with future revs) */ - __u8 table_ver_minor; /* Currently 2 (can change with future revs) */ - __u16 major_ver; /* Example: 8 as in 8.6.0.1020 */ -@@ -68,11 +69,13 @@ struct imsm_orom { - __u16 tds; /* Total Disks Supported */ - #define IMSM_OROM_TOTAL_DISKS 6 - #define IMSM_OROM_TOTAL_DISKS_NVME 12 -+ #define IMSM_OROM_TOTAL_DISKS_VMD 48 - __u8 vpa; /* # Volumes Per Array supported */ - #define IMSM_OROM_VOLUMES_PER_ARRAY 2 - __u8 vphba; /* # Volumes Per Host Bus Adapter supported */ - #define IMSM_OROM_VOLUMES_PER_HBA 4 - #define IMSM_OROM_VOLUMES_PER_HBA_NVME 4 -+ #define IMSM_OROM_VOLUMES_PER_HBA_VMD 24 - /* Attributes supported. This should map to the - * attributes in the MPB. Also, lower 16 bits - * should match/duplicate RLC bits above. -@@ -185,7 +188,13 @@ static inline int imsm_orom_is_enterprise(const struct imsm_orom *orom) - static inline int imsm_orom_is_nvme(const struct imsm_orom *orom) - { - return memcmp(orom->signature, IMSM_NVME_OROM_COMPAT_SIGNATURE, -- sizeof(orom->signature)) == 0; -+ sizeof(orom->signature)) == 0; -+} -+ -+static inline int imsm_orom_is_vmd_without_efi(const struct imsm_orom *orom) -+{ -+ return memcmp(orom->signature, IMSM_VMD_OROM_COMPAT_SIGNATURE, -+ sizeof(orom->signature)) == 0; - } - - static inline int imsm_orom_has_tpv_support(const struct imsm_orom *orom) -diff --git a/super-intel.c b/super-intel.c -index ce813172..77b0066f 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -2672,9 +2672,14 @@ static void print_imsm_capability(const struct imsm_orom *orom) - else - printf("Rapid Storage Technology%s\n", - imsm_orom_is_enterprise(orom) ? " enterprise" : ""); -- if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) -- printf(" Version : %d.%d.%d.%d\n", orom->major_ver, -- orom->minor_ver, orom->hotfix_ver, orom->build); -+ if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) { -+ if (imsm_orom_is_vmd_without_efi(orom)) -+ printf(" Version : %d.%d\n", orom->major_ver, -+ orom->minor_ver); -+ else -+ printf(" Version : %d.%d.%d.%d\n", orom->major_ver, -+ orom->minor_ver, orom->hotfix_ver, orom->build); -+ } - printf(" RAID Levels :%s%s%s%s%s\n", - imsm_orom_has_raid0(orom) ? " raid0" : "", - imsm_orom_has_raid1(orom) ? " raid1" : "", --- -2.40.1 - diff --git a/SOURCES/0142-Add-compiler-defenses-flags.patch b/SOURCES/0142-Add-compiler-defenses-flags.patch deleted file mode 100644 index 6102288..0000000 --- a/SOURCES/0142-Add-compiler-defenses-flags.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 55a1150c7438afcb7756fccd49713ede20a58e4a Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 17 Jul 2023 15:19:10 +0200 -Subject: [PATCH 142/165] Add compiler defenses flags - -It is essential to avoid buffer overflows and similar bugs as much as -possible. - -According to Intel rules we are obligated to verify certain -compiler flags, so it will be much easier if they are added to the -Makefile. - -Add gcc flags for prevention of buffer overflows, format string vulnerabilities, -stack protection to prevent stack overwrites and aslr enablement through -fPIE. -Also make the flags configurable. - -The changes were verified on gcc versions 7.5, 8.3, 9.2, 10 and 12.2. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Makefile | 41 +++++++++++++++++++++++++++++------------ - 1 file changed, 29 insertions(+), 12 deletions(-) - -diff --git a/Makefile b/Makefile -index 5eac1a4e..b3aa36f6 100644 ---- a/Makefile -+++ b/Makefile -@@ -30,7 +30,7 @@ - - # define "CXFLAGS" to give extra flags to CC. - # e.g. make CXFLAGS=-O to optimise --CXFLAGS ?=-O2 -+CXFLAGS ?=-O2 -D_FORTIFY_SOURCE=2 - TCC = tcc - UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found ) - #DIET_GCC = diet gcc -@@ -50,14 +50,30 @@ ifeq ($(origin CC),default) - CC := $(CROSS_COMPILE)gcc - endif - CXFLAGS ?= -ggdb --CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -+CWFLAGS ?= -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIE -Warray-bounds - ifdef WARN_UNUSED --CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 -+CWFLAGS += -Wp -O3 - endif - --FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l) --ifneq "$(FALLTHROUGH)" "0" --CWFLAGS += -Wimplicit-fallthrough=0 -+ifeq ($(origin FALLTHROUGH), undefined) -+ FALLTHROUGH := $(shell gcc -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l) -+ ifneq "$(FALLTHROUGH)" "0" -+ CWFLAGS += -Wimplicit-fallthrough=0 -+ endif -+endif -+ -+ifeq ($(origin FORMATOVERFLOW), undefined) -+ FORMATOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l) -+ ifneq "$(FORMATOVERFLOW)" "0" -+ CWFLAGS += -Wformat-overflow -+ endif -+endif -+ -+ifeq ($(origin STRINGOPOVERFLOW), undefined) -+ STRINGOPOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l) -+ ifneq "$(STRINGOPOVERFLOW)" "0" -+ CWFLAGS += -Wstringop-overflow -+ endif - endif - - ifdef DEBIAN -@@ -116,10 +132,12 @@ CFLAGS += -DUSE_PTHREADS - MON_LDFLAGS += -pthread - endif - -+LDFLAGS = -Wl,-z,now,-z,noexecstack -+ - # If you want a static binary, you might uncomment these --# LDFLAGS = -static -+# LDFLAGS += -static - # STRIP = -s --LDLIBS = -ldl -+LDLIBS = -ldl -pie - - # To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS - ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS))) -@@ -209,14 +227,13 @@ mdadm.Os : $(SRCS) $(INCL) - $(CC) -o mdadm.Os $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) $(LDLIBS) - - mdadm.O2 : $(SRCS) $(INCL) mdmon.O2 -- $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(SRCS) $(LDLIBS) -+ $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 $(SRCS) $(LDLIBS) - - mdmon.O2 : $(MON_SRCS) $(INCL) mdmon.h -- $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) $(LDLIBS) -+ $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 $(MON_SRCS) $(LDLIBS) - --# use '-z now' to guarantee no dynamic linker interactions with the monitor thread - mdmon : $(MON_OBJS) | check_rundir -- $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -Wl,-z,now -o mdmon $(MON_OBJS) $(LDLIBS) -+ $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -o mdmon $(MON_OBJS) $(LDLIBS) - msg.o: msg.c msg.h - - test_stripe : restripe.c xmalloc.o mdadm.h --- -2.40.1 - diff --git a/SOURCES/0143-Assemble-fix-redundant-memory-free.patch b/SOURCES/0143-Assemble-fix-redundant-memory-free.patch deleted file mode 100644 index 4583718..0000000 --- a/SOURCES/0143-Assemble-fix-redundant-memory-free.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 024d652e16dd9e3bd1ecdfce4d6f7a8cb498ba42 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 12 Sep 2023 04:27:01 +0200 -Subject: [PATCH 143/165] Assemble: fix redundant memory free - -Commit e9fb93af0f76 ("Fix memory leak in file Assemble") -fixes few memory leaks in Assemble, but it introduces -problem with assembling RAID volume. It was caused by -clearing metadata too fast, not only on fail in -select_devices() function. -This commit removes redundant memory free. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Assemble.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 61e8cd17..5be58e40 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -428,8 +428,6 @@ static int select_devices(struct mddev_dev *devlist, - - /* make sure we finished the loop */ - tmpdev = NULL; -- free(st); -- st = NULL; - goto loop; - } else { - content = *contentp; --- -2.40.1 - diff --git a/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch b/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch deleted file mode 100644 index dbbd3c5..0000000 --- a/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 7fe21767d3ab65a686518d2e36d18a07f535972e Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:19 +0800 -Subject: [PATCH 144/165] tests: add a new test for rdev lifetime - -This test add and remove a underlying disk to raid concurretly, verify -that the following problem is fixed: - -run mdadm test 23rdev-lifetime at Fri Apr 28 03:25:30 UTC 2023 -md: could not open device unknown-block(1,0). -sysfs: cannot create duplicate filename '/devices/virtual/block/md0/md/dev-ram0' -CPU: 26 PID: 10521 Comm: test Not tainted 6.3.0-rc2-00134-g7b3a8828043c #115 -Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/014 -Call Trace: - - dump_stack_lvl+0xe7/0x180 - dump_stack+0x18/0x30 - sysfs_warn_dup+0xa2/0xd0 - sysfs_create_dir_ns+0x119/0x140 - kobject_add_internal+0x143/0x4d0 - kobject_add_varg+0x35/0x70 - kobject_add+0x64/0xd0 - bind_rdev_to_array+0x254/0x840 [md_mod] - new_dev_store+0x14d/0x350 [md_mod] - md_attr_store+0xc1/0x1a0 [md_mod] - sysfs_kf_write+0x51/0x70 - kernfs_fop_write_iter+0x188/0x270 - vfs_write+0x27e/0x460 - ksys_write+0x85/0x180 - __x64_sys_write+0x21/0x30 - do_syscall_64+0x6c/0xe0 - entry_SYSCALL_64_after_hwframe+0x63/0xcd -RIP: 0033:0x7f26bacf5387 -Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 84 -RSP: 002b:00007ffe98d79e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 -RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f26bacf5387 -RDX: 0000000000000004 RSI: 000055bd10282bf0 RDI: 0000000000000001 -RBP: 000055bd10282bf0 R08: 000000000000000a R09: 00007f26bad8b4e0 -R10: 00007f26bad8b3e0 R11: 0000000000000246 R12: 0000000000000004 -R13: 00007f26badc8520 R14: 0000000000000004 R15: 00007f26badc8700 - - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/23rdev-lifetime | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 tests/23rdev-lifetime - -diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime -new file mode 100644 -index 00000000..1750b0db ---- /dev/null -+++ b/tests/23rdev-lifetime -@@ -0,0 +1,34 @@ -+devname=${dev0##*/} -+devt=`cat /sys/block/$devname/dev` -+pid="" -+runtime=2 -+ -+clean_up_test() { -+ pill -9 $pid -+ echo clear > /sys/block/md0/md/array_state -+} -+ -+trap 'clean_up_test' EXIT -+ -+add_by_sysfs() { -+ while true; do -+ echo $devt > /sys/block/md0/md/new_dev -+ done -+} -+ -+remove_by_sysfs(){ -+ while true; do -+ echo remove > /sys/block/md0/md/dev-${devname}/state -+ done -+} -+ -+echo md0 > /sys/module/md_mod/parameters/new_array || die "create md0 failed" -+ -+add_by_sysfs & -+pid="$pid $!" -+ -+remove_by_sysfs & -+pid="$pid $!" -+ -+sleep $runtime -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch b/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch deleted file mode 100644 index 39b38d2..0000000 --- a/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0ef9465f6355db612e53afc32e3084721c3dd7c7 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:20 +0800 -Subject: [PATCH 145/165] tests: support to skip checking dmesg - -Prepare to add a regression test for raid10 that require error injection -to trigger error path, and kernel will complain about io error, checking -dmesg for error log will make it impossible to pass this test. - -Signed-off-by: Yu Kuai -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - test | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/test b/test -index 61d9ee83..b244453b 100755 ---- a/test -+++ b/test -@@ -107,8 +107,12 @@ do_test() { - echo -ne "$_script... " - if ( set -ex ; . $_script ) &> $targetdir/log - then -- dmesg | grep -iq "error\|call trace\|segfault" && -- die "dmesg prints errors when testing $_basename!" -+ if [ -f "${_script}.inject_error" ]; then -+ echo "dmesg checking is skipped because test inject error" -+ else -+ dmesg | grep -iq "error\|call trace\|segfault" && -+ die "dmesg prints errors when testing $_basename!" -+ fi - echo "succeeded" - _fail=0 - else --- -2.40.1 - diff --git a/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch b/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch deleted file mode 100644 index 04e4304..0000000 --- a/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 3973f65293ce69ddd7c19be9a7a796abfe80e370 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:21 +0800 -Subject: [PATCH 146/165] tests: add a regression test for raid10 deadlock - -The deadlock is described in [1], it's fixed first by [2], however, -it turns out this commit will trigger other problems[3], hence this -commit will be reverted and the deadlock is supposed to be fixed by [1]. - -[1] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/ -[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/ -[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-2-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/24raid10deadlock | 88 +++++++++++++++++++++++++++++ - tests/24raid10deadlock.inject_error | 0 - 2 files changed, 88 insertions(+) - create mode 100644 tests/24raid10deadlock - create mode 100644 tests/24raid10deadlock.inject_error - -diff --git a/tests/24raid10deadlock b/tests/24raid10deadlock -new file mode 100644 -index 00000000..ee330aa9 ---- /dev/null -+++ b/tests/24raid10deadlock -@@ -0,0 +1,88 @@ -+devs="$dev0 $dev1 $dev2 $dev3" -+runtime=120 -+pid="" -+action_pid="" -+ -+set_up_injection() -+{ -+ echo -1 > /sys/kernel/debug/fail_make_request/times -+ echo 1 > /sys/kernel/debug/fail_make_request/probability -+ echo 0 > /sys/kernel/debug/fail_make_request/verbose -+ echo 1 > /sys/block/${1##*/}/make-it-fail -+} -+ -+clean_up_injection() -+{ -+ echo 0 > /sys/block/${1##*/}/make-it-fail -+ echo 0 > /sys/kernel/debug/fail_make_request/times -+ echo 0 > /sys/kernel/debug/fail_make_request/probability -+ echo 2 > /sys/kernel/debug/fail_make_request/verbose -+} -+ -+test_rdev() -+{ -+ while true; do -+ mdadm -f $md0 $1 &> /dev/null -+ mdadm -r $md0 $1 &> /dev/null -+ mdadm --zero-superblock $1 &> /dev/null -+ mdadm -a $md0 $1 &> /dev/null -+ sleep $2 -+ done -+} -+ -+test_write_action() -+{ -+ while true; do -+ echo frozen > /sys/block/md0/md/sync_action -+ echo idle > /sys/block/md0/md/sync_action -+ sleep 0.1 -+ done -+} -+ -+set_up_test() -+{ -+ fio -h &> /dev/null || die "fio not found" -+ -+ # create a simple raid10 -+ mdadm -Cv -R -n 4 -l10 $md0 $devs || die "create raid10 failed" -+} -+ -+clean_up_test() -+{ -+ clean_up_injection $dev0 -+ pkill -9 fio -+ kill -9 $pid -+ kill -9 $action_pid -+ -+ sleep 1 -+ -+ if ps $action_pid | tail -1 | awk '{print $3}' | grep D; then -+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered" -+ fi -+ mdadm -S $md0 -+} -+ -+cat /sys/kernel/debug/fail_make_request/times || die "fault injection is not enabled" -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# backgroup io pressure -+fio -filename=$md0 -rw=randwrite -direct=1 -name=test -bs=4k -numjobs=16 -iodepth=16 & -+ -+# trigger add/remove device by io failure -+set_up_injection $dev0 -+test_rdev $dev0 2 & -+pid="$pid $!" -+ -+# add/remove device directly -+test_rdev $dev3 10 & -+pid="$pid $!" -+ -+test_write_action & -+action_pid="$!" -+ -+sleep $runtime -+ -+exit 0 -diff --git a/tests/24raid10deadlock.inject_error b/tests/24raid10deadlock.inject_error -new file mode 100644 -index 00000000..e69de29b --- -2.40.1 - diff --git a/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch b/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch deleted file mode 100644 index 78c5836..0000000 --- a/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 9d0fb58f3b1314678564b4ac7bfb19942acc8926 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:22 +0800 -Subject: [PATCH 147/165] tests: add a regression test for raid456 deadlock - -The deadlock is described in [1], as the last patch described, it's -fixed first by [2], however this fix will be reverted and the deadlock -is supposed to be fixed by [3]. - -[1] https://lore.kernel.org/linux-raid/5ed54ffc-ce82-bf66-4eff-390cb23bc1ac@molgen.mpg.de/T/#t -[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/ -[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/24raid456deadlock | 58 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 58 insertions(+) - create mode 100644 tests/24raid456deadlock - -diff --git a/tests/24raid456deadlock b/tests/24raid456deadlock -new file mode 100644 -index 00000000..80e6e97e ---- /dev/null -+++ b/tests/24raid456deadlock -@@ -0,0 +1,58 @@ -+devs="$dev0 $dev1 $dev2 $dev3 $dev4 $dev5" -+runtime=120 -+pid="" -+old=`cat /proc/sys/vm/dirty_background_ratio` -+ -+test_write_action() -+{ -+ while true; do -+ echo check > /sys/block/md0/md/sync_action &> /dev/null -+ sleep 0.1 -+ echo idle > /sys/block/md0/md/sync_action &> /dev/null -+ done -+} -+ -+test_write_back() -+{ -+ fio -filename=$md0 -bs=4k -rw=write -numjobs=1 -name=test \ -+ -time_based -runtime=$runtime &> /dev/null -+} -+ -+set_up_test() -+{ -+ fio -h &> /dev/null || die "fio not found" -+ -+ # create a simple raid6 -+ mdadm -Cv -R -n 6 -l6 $md0 $devs --assume-clean || die "create raid6 failed" -+ -+ # trigger dirty pages write back -+ echo 0 > /proc/sys/vm/dirty_background_ratio -+} -+ -+clean_up_test() -+{ -+ echo $old > /proc/sys/vm/dirty_background_ratio -+ -+ pkill -9 fio -+ kill -9 $pid -+ -+ sleep 1 -+ -+ if ps $pid | tail -1 | awk '{print $3}' | grep D; then -+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered" -+ fi -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+test_write_back & -+ -+test_write_action & -+pid="$!" -+ -+sleep $runtime -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch b/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch deleted file mode 100644 index a10b3b2..0000000 --- a/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4db8a3d452daaf2def41ca45c36e36c5781627ac Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:23 +0800 -Subject: [PATCH 148/165] tests: add a regression test that raid456 can't - assemble - -If recovery is interrupted and reshape is started, then this array can't -assemble anymore. The problem is supposed to be fixed by [1]. - -[1] https://lore.kernel.org/linux-raid/20230529031045.1760883-1-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-while-recovery | 32 ++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - create mode 100644 tests/25raid456-reshape-while-recovery - -diff --git a/tests/25raid456-reshape-while-recovery b/tests/25raid456-reshape-while-recovery -new file mode 100644 -index 00000000..b9f871f2 ---- /dev/null -+++ b/tests/25raid456-reshape-while-recovery -@@ -0,0 +1,32 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# set up replacement -+echo want_replacement > /sys/block/md0/md/rd0/state -+sleep 1 -+ -+# trigger reshape -+echo frozen > /sys/block/md0/md/sync_action -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# reassemeble array -+mdadm -S $md0 || die "can't stop array" -+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch b/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch deleted file mode 100644 index 3d52868..0000000 --- a/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8d45abd0c317d3f4971b779b4f8d1e33b5490dac Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:24 +0800 -Subject: [PATCH 149/165] tests: add a regression test that raid456 can't - assemble again - -This is a regression test for commit 0aecb06e2249 ("md/raid5: don't allow -replacement while reshape is in progress"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-recovery-while-reshape | 33 ++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - create mode 100644 tests/25raid456-recovery-while-reshape - -diff --git a/tests/25raid456-recovery-while-reshape b/tests/25raid456-recovery-while-reshape -new file mode 100644 -index 00000000..3f6251bf ---- /dev/null -+++ b/tests/25raid456-recovery-while-reshape -@@ -0,0 +1,33 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# set up replacement -+echo frozen > /sys/block/md0/md/sync_action -+echo want_replacement > /sys/block/md0/md/rd0/state -+echo reshape > /sys/block/md0/md/sync_action -+sleep 1 -+ -+# reassemeble array -+mdadm -S $md0 || die "can't stop array" -+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch b/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch deleted file mode 100644 index 20f0272..0000000 --- a/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 481433482942c2ee2990965af394eff059990901 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:25 +0800 -Subject: [PATCH 150/165] tests: add a regression test that reshape can corrupt - data - -This is a regression test for commit 1544e95c6dd8 ("md: fix data -corruption for raid456 when reshape restart while grow up"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-corrupt-data | 35 ++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - create mode 100644 tests/25raid456-reshape-corrupt-data - -diff --git a/tests/25raid456-reshape-corrupt-data b/tests/25raid456-reshape-corrupt-data -new file mode 100644 -index 00000000..fdb875fb ---- /dev/null -+++ b/tests/25raid456-reshape-corrupt-data -@@ -0,0 +1,35 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array" -+ mkfs.xfs -f $md0 || die "mkfs failed" -+ xfs_ncheck $md0 || die "check fs failed" -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+echo 1000 > /sys/block/md0/md/sync_speed_max -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# stop and start reshape -+echo frozen > /sys/block/md0/md/sync_action -+echo system > /sys/block/md0/md/sync_speed_max -+echo reshape > /sys/block/md0/md/sync_action -+ -+mdadm -W $md0 -+ -+# check if data is corrupted -+xfs_ncheck $md0 || die "data is corrupted after reshape" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch b/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch deleted file mode 100644 index ab916c5..0000000 --- a/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c6c7bce5a3064ac9d2956ae42ecab27f2e33dc2b Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:26 +0800 -Subject: [PATCH 151/165] tests: add a regression test for raid456 deadlock - again - -This is a regression test for commit ("md/raid5: fix a deadlock in the -case that reshape is interrupted"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-deadlock | 34 ++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 tests/25raid456-reshape-deadlock - -diff --git a/tests/25raid456-reshape-deadlock b/tests/25raid456-reshape-deadlock -new file mode 100644 -index 00000000..bfa0cc56 ---- /dev/null -+++ b/tests/25raid456-reshape-deadlock -@@ -0,0 +1,34 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ echo idle > /sys/block/md0/md/sync_action -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# stop reshape -+echo frozen > /sys/block/md0/md/sync_action -+ -+# read accross reshape -+dd if=$md0 of=/dev/NULL bs=1m count=100 iflag=direct &> /dev/null & -+sleep 2 -+ -+# suspend array -+echo 1 > /sys/block/md0/md/suspend_lo -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0152-tests-create-names_template.patch b/SOURCES/0152-tests-create-names_template.patch deleted file mode 100644 index a3db688..0000000 --- a/SOURCES/0152-tests-create-names_template.patch +++ /dev/null @@ -1,193 +0,0 @@ -From d5fee8654e41dc4067dfdc3312542f1f43ebe884 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:45 +0200 -Subject: [PATCH 152/165] tests: create names_template - -Create templates directory and names_template. Move code from -00createnames. This code will be reused for 00confnames in next patch. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00createnames | 86 +++++++--------------------------- - tests/templates/names_template | 53 +++++++++++++++++++++ - 2 files changed, 70 insertions(+), 69 deletions(-) - create mode 100644 tests/templates/names_template - -diff --git a/tests/00createnames b/tests/00createnames -index 64b81b92..064eeef2 100644 ---- a/tests/00createnames -+++ b/tests/00createnames -@@ -1,93 +1,41 @@ - set -x -e -+. tests/templates/names_template - - # Test how and --name= are handled for create mode. --# We need to check three properties, generated from those parameters: --# - devnode name --# - link in /dev/md/ (MD_DEVNAME property from --detail --export) --# - name in metadata (MD_NAME property from --examine --export) -- --function _verify() { -- local DEVNODE_NAME="$1" -- local WANTED_LINK="$2" -- local WANTED_NAME="$3" -- -- local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -- if [[ "$?" != "0" ]]; then -- echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -- exit 1 -- fi -- -- if [[ "$WANTED_LINK" != "empty" ]]; then -- local EXPECTED="MD_DEVNAME=$WANTED_LINK" -- if [[ "$RES" != "$EXPECTED" ]]; then -- echo "$RES doesn't match $EXPECTED." -- exit 1 -- fi -- fi -- -- -- local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" -- if [[ "$?" != "0" ]]; then -- echo "Cannot get metadata from $dev0." -- exit 1 -- fi -- -- local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -- if [[ "$RES" != "$EXPECTED" ]]; then -- echo "$RES doesn't match $EXPECTED." -- exit 1 -- fi --} -- --function _create() { -- local DEVNAME=$1 -- local NAME=$2 -- -- if [[ -z "$NAME" ]]; then -- mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -- else -- mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force -- fi -- -- if [[ "$?" != "0" ]]; then -- echo "Cannot create device." -- exit 1 -- fi --} - - # The most trivial case. --_create "/dev/md/name" --_verify "/dev/md127" "name" "name" -+names_create "/dev/md/name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - --_create "name" --_verify "/dev/md127" "name" "name" -+names_create "name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # Use 'mdX' as name. --_create "/dev/md/md0" --_verify "/dev/md127" "md0" "md0" -+names_create "/dev/md/md0" -+names_verify "/dev/md127" "md0" "md0" - mdadm -S "/dev/md127" - --_create "md0" --_verify "/dev/md127" "md0" "md0" -+names_create "md0" -+names_verify "/dev/md127" "md0" "md0" - mdadm -S "/dev/md127" - - # is used to create MD_DEVNAME but, name is used to create MD_NAME. --_create "/dev/md/devnode" "name" --_verify "/dev/md127" "devnode" "name" -+names_create "/dev/md/devnode" "name" -+names_verify "/dev/md127" "devnode" "name" - mdadm -S "/dev/md127" - --_create "devnode" "name" --_verify "/dev/md127" "devnode" "name" -+names_create "devnode" "name" -+names_verify "/dev/md127" "devnode" "name" - mdadm -S "/dev/md127" - - # Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. --_create "/dev/md0" --_verify "/dev/md0" "empty" "0" -+names_create "/dev/md0" -+names_verify "/dev/md0" "empty" "0" - mdadm -S "/dev/md0" - - # Devnode points to /dev/ directory and name is set. --_create "/dev/md0" "name" --_verify "/dev/md0" "empty" "name" -+names_create "/dev/md0" "name" -+names_verify "/dev/md0" "empty" "name" - mdadm -S "/dev/md0" -diff --git a/tests/templates/names_template b/tests/templates/names_template -new file mode 100644 -index 00000000..9f09be9e ---- /dev/null -+++ b/tests/templates/names_template -@@ -0,0 +1,53 @@ -+# NAME is optional. Testing with native 1.2 superblock. -+function names_create() { -+ local DEVNAME=$1 -+ local NAME=$2 -+ -+ if [[ -z "$NAME" ]]; then -+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -+ else -+ mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force -+ fi -+ -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot create device." -+ exit 1 -+ fi -+} -+ -+# Three properties to check: -+# - devnode name -+# - link in /dev/md/ (MD_DEVNAME property from --detail --export) -+# - name in metadata (MD_NAME property from --detail --export)- that works only with 1.2 sb. -+function names_verify() { -+ local DEVNODE_NAME="$1" -+ local WANTED_LINK="$2" -+ local WANTED_NAME="$3" -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -+ exit 1 -+ fi -+ -+ if [[ "$WANTED_LINK" != "empty" ]]; then -+ local EXPECTED="MD_DEVNAME=$WANTED_LINK" -+ fi -+ -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_NAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get metadata from $dev0." -+ exit 1 -+ fi -+ -+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+} --- -2.40.1 - diff --git a/SOURCES/0153-tests-create-00confnames.patch b/SOURCES/0153-tests-create-00confnames.patch deleted file mode 100644 index 1534d93..0000000 --- a/SOURCES/0153-tests-create-00confnames.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 569a23425939e4bfc7b4d7f871d8510bb968f892 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:46 +0200 -Subject: [PATCH 153/165] tests: create 00confnames - -The test is an attempt to document current implementation of devnode -and name handling for config entries. It is focused on incremental- -default way of array assembling on boot. -The expectations are aligned to current implementation for native -metadata because it is the most complicated scenario- both variables -can be set. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00confnames | 107 +++++++++++++++++++++++++++++++++ - tests/templates/names_template | 20 ++++++ - 2 files changed, 127 insertions(+) - create mode 100644 tests/00confnames - -diff --git a/tests/00confnames b/tests/00confnames -new file mode 100644 -index 00000000..25a7127b ---- /dev/null -+++ b/tests/00confnames -@@ -0,0 +1,107 @@ -+set -x -e -+. tests/templates/names_template -+ -+# Test how and from config are handled during Incremental assemblation. -+# 1-6 only tests (no in config). -+# 6-10 and combinations are tested. -+# 11-13 corner cases. -+ -+names_create "/dev/md/name" -+local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)" -+[[ "$_UUID" == "" ]] && echo "Cannot obtain UUID for $DEVNODE_NAME" && exit 1 -+ -+ -+# 1. definition consistent with metadata name. -+names_make_conf $_UUID "/dev/md/name" "empty" $config -+mdadm -S "/dev/md127" -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 2. Same as 1, but use short name form of . -+names_make_conf $_UUID "name" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 3. Same as 1, but use different than metadata provides. -+names_make_conf $_UUID "/dev/md/other" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "other" "name" -+mdadm -S "/dev/md127" -+ -+# 4. Same as 3, but use short name form of . -+names_make_conf $_UUID "other" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "other" "name" -+mdadm -S "/dev/md127" -+ -+# 5. Force particular node creation by setting to /dev/mdX. Link is not created in this -+# case. -+names_make_conf $_UUID "/dev/md4" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md4" "empty" "name" -+mdadm -S "/dev/md4" -+ -+# 6. set to /dev/mdX, same as in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "/dev/md22" "name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 7. set to /dev/mdX, different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "/dev/md8" "other" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 8. Both and different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "devnode" "other_name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 9. set to metadata name, different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "name" "other_name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 10. Bad set, no . -+# Metadata name and default node used - expected. -+names_make_conf $_UUID "/im/bad/devname" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 11. with some special symbols and locales, no . -+# It needs to wait a while for timeout because udev cannot create a link - known issue. -+names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "tźż-\.,<>st+-" "name" -+mdadm -S "/dev/md127" -+ -+# 12. No and set. -+# Metadata name and default node used - expected. -+names_make_conf $_UUID "empty" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 13. No , set to /dev/mdX. -+# Entry should be ignored, it is not ignored but result is good anyway. -+names_make_conf $_UUID "empty" "/dev/md12" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 13. No , with special symbols and locales. -+# Entry should be ignored, it is not ignored but result is good anyway. -+names_make_conf $_UUID "empty" "./\śćń#&" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -diff --git a/tests/templates/names_template b/tests/templates/names_template -index 9f09be9e..8d2b5c81 100644 ---- a/tests/templates/names_template -+++ b/tests/templates/names_template -@@ -51,3 +51,23 @@ function names_verify() { - exit 1 - fi - } -+ -+# Generate ARRAYLINE for tested array. -+names_make_conf() { -+ local UUID="$1" -+ local WANTED_DEVNAME="$2" -+ local WANTED_NAME="$3" -+ local CONF="$4" -+ -+ local LINE="ARRAY metadata=1.2 UUID=$UUID" -+ -+ if [[ "$WANTED_DEVNAME" != "empty" ]]; then -+ LINE="$LINE $WANTED_DEVNAME" -+ fi -+ -+ if [[ "$WANTED_NAME" != "empty" ]]; then -+ LINE="$LINE name=$WANTED_NAME" -+ fi -+ -+ echo $LINE > $CONF -+} --- -2.40.1 - diff --git a/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch b/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch deleted file mode 100644 index 14ca30e..0000000 --- a/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 330c07f8e4d26f4f2d068e11f09c9df8a3380087 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:47 +0200 -Subject: [PATCH 154/165] mdadm: set ident.devname if applicable - -This patch tries to propagate the usage of struct mddev_ident for cmdline -where it is applicable. To avoid regression, this value is derived -from devlist->devname for applicable modes only. -As a result, the whole structure is passed to some functions. It produces -some changes for Build, Create and Assemble. -No functional changes intended. - -The goal of the change is to unify devname validation which is done in -next patches. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Build.c | 21 +++++++++------------ - Create.c | 35 ++++++++++++++++------------------ - mdadm.c | 57 +++++++++++++++++++++++++------------------------------- - mdadm.h | 13 +++++-------- - 4 files changed, 55 insertions(+), 71 deletions(-) - -diff --git a/Build.c b/Build.c -index 8d6f6f58..657ab315 100644 ---- a/Build.c -+++ b/Build.c -@@ -24,8 +24,8 @@ - - #include "mdadm.h" - --int Build(char *mddev, struct mddev_dev *devlist, -- struct shape *s, struct context *c) -+int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, -+ struct context *c) - { - /* Build a linear or raid0 arrays without superblocks - * We cannot really do any checks, we just do it. -@@ -75,13 +75,12 @@ int Build(char *mddev, struct mddev_dev *devlist, - - /* We need to create the device. It can have no name. */ - map_lock(&map); -- mdfd = create_mddev(mddev, NULL, c->autof, LOCAL, -+ mdfd = create_mddev(ident->devname, NULL, c->autof, LOCAL, - chosen_name, 0); - if (mdfd < 0) { - map_unlock(&map); - return 1; - } -- mddev = chosen_name; - - map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name); - map_unlock(&map); -@@ -93,7 +92,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - array.nr_disks = s->raiddisks; - array.raid_disks = s->raiddisks; - array.md_minor = 0; -- if (fstat_is_blkdev(mdfd, mddev, &rdev)) -+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev)) - array.md_minor = minor(rdev); - array.not_persistent = 1; - array.state = 0; /* not clean, but no errors */ -@@ -108,8 +107,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - array.chunk_size = s->chunk*1024; - array.layout = s->layout; - if (md_set_array_info(mdfd, &array)) { -- pr_err("md_set_array_info() failed for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("md_set_array_info() failed for %s: %s\n", chosen_name, strerror(errno)); - goto abort; - } - -@@ -178,8 +176,8 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - if (bitmap_fd >= 0) { - if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { -- pr_err("Cannot set bitmap file for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, -+ strerror(errno)); - goto abort; - } - } -@@ -193,9 +191,8 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - - if (c->verbose >= 0) -- pr_err("array %s built and started.\n", -- mddev); -- wait_for(mddev, mdfd); -+ pr_err("array %s built and started.\n", chosen_name); -+ wait_for(chosen_name, mdfd); - close(mdfd); - return 0; - -diff --git a/Create.c b/Create.c -index ea6a4745..a280c7bc 100644 ---- a/Create.c -+++ b/Create.c -@@ -471,11 +471,8 @@ out: - return ret; - } - --int Create(struct supertype *st, char *mddev, -- char *name, int *uuid, -- int subdevs, struct mddev_dev *devlist, -- struct shape *s, -- struct context *c) -+int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, -+ struct mddev_dev *devlist, struct shape *s, struct context *c) - { - /* - * Create a new raid array. -@@ -497,6 +494,8 @@ int Create(struct supertype *st, char *mddev, - unsigned long long minsize = 0, maxsize = 0; - char *mindisc = NULL; - char *maxdisc = NULL; -+ char *name = ident->name; -+ int *uuid = ident->uuid_set == 1 ? ident->uuid : NULL; - int dnum; - struct mddev_dev *dv; - dev_t rdev; -@@ -1015,7 +1014,7 @@ int Create(struct supertype *st, char *mddev, - - /* We need to create the device */ - map_lock(&map); -- mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1); -+ mdfd = create_mddev(ident->devname, ident->name, c->autof, LOCAL, chosen_name, 1); - if (mdfd < 0) { - map_unlock(&map); - return 1; -@@ -1032,7 +1031,6 @@ int Create(struct supertype *st, char *mddev, - udev_unblock(); - return 1; - } -- mddev = chosen_name; - - memset(&inf, 0, sizeof(inf)); - md_get_array_info(mdfd, &inf); -@@ -1050,7 +1048,7 @@ int Create(struct supertype *st, char *mddev, - * with, but it chooses to trust me instead. Sigh - */ - info.array.md_minor = 0; -- if (fstat_is_blkdev(mdfd, mddev, &rdev)) -+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev)) - info.array.md_minor = minor(rdev); - info.array.not_persistent = 0; - -@@ -1102,8 +1100,8 @@ int Create(struct supertype *st, char *mddev, - info.array.layout = s->layout; - info.array.chunk_size = s->chunk*1024; - -- if (name == NULL || *name == 0) { -- /* base name on mddev */ -+ if (*name == 0) { -+ /* base name on devname */ - /* /dev/md0 -> 0 - * /dev/md_d0 -> d0 - * /dev/md_foo -> foo -@@ -1113,15 +1111,16 @@ int Create(struct supertype *st, char *mddev, - * /dev/mdhome -> home - */ - /* FIXME compare this with rules in create_mddev */ -- name = strrchr(mddev, '/'); -+ name = strrchr(chosen_name, '/'); -+ - if (name) { - name++; - if (strncmp(name, "md_", 3) == 0 && -- strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */) -+ strlen(name) > 3 && (name - chosen_name) == 5 /* /dev/ */) - name += 3; - else if (strncmp(name, "md", 2) == 0 && - strlen(name) > 2 && isdigit(name[2]) && -- (name-mddev) == 5 /* /dev/ */) -+ (name - chosen_name) == 5 /* /dev/ */) - name += 2; - } - } -@@ -1215,8 +1214,7 @@ int Create(struct supertype *st, char *mddev, - } - rv = set_array_info(mdfd, st, &info); - if (rv) { -- pr_err("failed to set array info for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("failed to set array info for %s: %s\n", chosen_name, strerror(errno)); - goto abort_locked; - } - -@@ -1237,8 +1235,7 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { -- pr_err("Cannot set bitmap file for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, strerror(errno)); - goto abort_locked; - } - } -@@ -1254,7 +1251,7 @@ int Create(struct supertype *st, char *mddev, - * create links */ - sysfs_uevent(&info, "change"); - if (c->verbose >= 0) -- pr_err("container %s prepared.\n", mddev); -+ pr_err("container %s prepared.\n", chosen_name); - wait_for(chosen_name, mdfd); - } else if (c->runstop == 1 || subdevs >= s->raiddisks) { - if (st->ss->external) { -@@ -1312,7 +1309,7 @@ int Create(struct supertype *st, char *mddev, - ioctl(mdfd, RESTART_ARRAY_RW, NULL); - } - if (c->verbose >= 0) -- pr_info("array %s started.\n", mddev); -+ pr_info("array %s started.\n", chosen_name); - if (st->ss->external && st->container_devnm[0]) { - if (need_mdmon) - start_mdmon(st->container_devnm); -diff --git a/mdadm.c b/mdadm.c -index 22d1c53b..0a56ed26 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1290,37 +1290,39 @@ int main(int argc, char *argv[]) - pr_err("an md device must be given in this mode\n"); - exit(2); - } -+ ident.devname = devlist->devname; -+ - if ((int)ident.super_minor == -2 && c.autof) { - pr_err("--super-minor=dev is incompatible with --auto\n"); - exit(2); - } - if (mode == MANAGE || mode == GROW) { -- mdfd = open_mddev(devlist->devname, 1); -+ mdfd = open_mddev(ident.devname, 1); - if (mdfd < 0) - exit(1); - - ret = fstat(mdfd, &stb); - if (ret) { -- pr_err("fstat failed on %s.\n", devlist->devname); -+ pr_err("fstat failed on %s.\n", ident.devname); - exit(1); - } - } else { -- char *bname = basename(devlist->devname); -+ char *bname = basename(ident.devname); - - if (strlen(bname) > MD_NAME_MAX) { -- pr_err("Name %s is too long.\n", devlist->devname); -+ pr_err("Name %s is too long.\n", ident.devname); - exit(1); - } - -- ret = stat(devlist->devname, &stb); -+ ret = stat(ident.devname, &stb); - if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -- devlist->devname); -+ ident.devname); - exit(1); - } - - if (!ret && !stat_is_md_dev(&stb)) { -- pr_err("device %s exists but is not an md array.\n", devlist->devname); -+ pr_err("device %s exists but is not an md array.\n", ident.devname); - exit(1); - } - } -@@ -1408,17 +1410,17 @@ int main(int argc, char *argv[]) - case MANAGE: - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) -- rv = Manage_ro(devlist->devname, mdfd, c.readonly); -+ rv = Manage_ro(ident.devname, mdfd, c.readonly); - if (!rv && devs_found > 1) -- rv = Manage_subdevs(devlist->devname, mdfd, -+ rv = Manage_subdevs(ident.devname, mdfd, - devlist->next, c.verbose, - c.test, c.update, c.force); - if (!rv && c.readonly < 0) -- rv = Manage_ro(devlist->devname, mdfd, c.readonly); -+ rv = Manage_ro(ident.devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -- rv = Manage_run(devlist->devname, mdfd, &c); -+ rv = Manage_run(ident.devname, mdfd, &c); - if (!rv && c.runstop < 0) -- rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0); -+ rv = Manage_stop(ident.devname, mdfd, c.verbose, 0); - break; - case ASSEMBLE: - if (!c.scan && c.runstop == -1) { -@@ -1428,22 +1430,19 @@ int main(int argc, char *argv[]) - ident.super_minor == UnSet && ident.name[0] == 0 && - !c.scan) { - /* Only a device has been given, so get details from config file */ -- struct mddev_ident *array_ident = conf_get_ident(devlist->devname); -+ struct mddev_ident *array_ident = conf_get_ident(ident.devname); - if (array_ident == NULL) { -- pr_err("%s not identified in config file.\n", -- devlist->devname); -+ pr_err("%s not identified in config file.\n", ident.devname); - rv |= 1; - if (mdfd >= 0) - close(mdfd); - } else { - if (array_ident->autof == 0) - array_ident->autof = c.autof; -- rv |= Assemble(ss, devlist->devname, array_ident, -- NULL, &c); -+ rv |= Assemble(ss, ident.devname, array_ident, NULL, &c); - } - } else if (!c.scan) -- rv = Assemble(ss, devlist->devname, &ident, -- devlist->next, &c); -+ rv = Assemble(ss, ident.devname, &ident, devlist->next, &c); - else if (devs_found > 0) { - if (c.update && devs_found > 1) { - pr_err("can only update a single array at a time\n"); -@@ -1501,7 +1500,7 @@ int main(int argc, char *argv[]) - break; - } - } -- rv = Build(devlist->devname, devlist->next, &s, &c); -+ rv = Build(&ident, devlist->next, &s, &c); - break; - case CREATE: - if (c.delay == 0) -@@ -1538,9 +1537,7 @@ int main(int argc, char *argv[]) - break; - } - -- rv = Create(ss, devlist->devname, -- ident.name, ident.uuid_set ? ident.uuid : NULL, -- devs_found - 1, devlist->next, &s, &c); -+ rv = Create(ss, &ident, devs_found - 1, devlist->next, &s, &c); - break; - case MISC: - if (devmode == 'E') { -@@ -1637,8 +1634,7 @@ int main(int argc, char *argv[]) - break; - } - for (dv = devlist->next; dv; dv = dv->next) { -- rv = Grow_Add_device(devlist->devname, mdfd, -- dv->devname); -+ rv = Grow_Add_device(ident.devname, mdfd, dv->devname); - if (rv) - break; - } -@@ -1651,18 +1647,15 @@ int main(int argc, char *argv[]) - } - if (c.delay == 0) - c.delay = DEFAULT_BITMAP_DELAY; -- rv = Grow_addbitmap(devlist->devname, mdfd, &c, &s); -+ rv = Grow_addbitmap(ident.devname, mdfd, &c, &s); - } else if (grow_continue) -- rv = Grow_continue_command(devlist->devname, -- mdfd, c.backup_file, -- c.verbose); -+ rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose); - else if (s.size > 0 || s.raiddisks || s.layout_str || - s.chunk != 0 || s.level != UnSet || - s.data_offset != INVALID_SECTORS) { -- rv = Grow_reshape(devlist->devname, mdfd, -- devlist->next, &c, &s); -+ rv = Grow_reshape(ident.devname, mdfd, devlist->next, &c, &s); - } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { -- rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); -+ rv = Grow_consistency_policy(ident.devname, mdfd, &c, &s); - } else if (array_size == 0) - pr_err("no changes to --grow\n"); - break; -diff --git a/mdadm.h b/mdadm.h -index f0ceeb78..5678eb11 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1531,14 +1531,11 @@ extern int Assemble(struct supertype *st, char *mddev, - struct mddev_dev *devlist, - struct context *c); - --extern int Build(char *mddev, struct mddev_dev *devlist, -- struct shape *s, struct context *c); -- --extern int Create(struct supertype *st, char *mddev, -- char *name, int *uuid, -- int subdevs, struct mddev_dev *devlist, -- struct shape *s, -- struct context *c); -+extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, -+ struct context *c); -+ -+extern int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, -+ struct mddev_dev *devlist, struct shape *s, struct context *c); - - extern int Detail(char *dev, struct context *c); - extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); --- -2.40.1 - diff --git a/SOURCES/0155-mdadm-refactor-ident-name-handling.patch b/SOURCES/0155-mdadm-refactor-ident-name-handling.patch deleted file mode 100644 index 423b876..0000000 --- a/SOURCES/0155-mdadm-refactor-ident-name-handling.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 67417d9222c505103357191bb0e0ae300892e8a9 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:48 +0200 -Subject: [PATCH 155/165] mdadm: refactor ident->name handling - -Create dedicated setter for name in mddev_ident and propagate it. -Following changes are made: -- move duplicated code from config.c and mdadm.c into new function. -- Add error enum in mdadm.h. -- Use MD_NAME_MAX instead of hardcoded value in mddev_ident. -- Use secure functions. -- Add more detailed verification of the name. -- make error messages reusable for cmdline and config: - - for cmdline, these are errors so use pr_err(). - - for config, these are just warnings, so use pr_info(). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------ - lib.c | 18 +++++++++++++ - mdadm.c | 12 +++------ - mdadm.h | 20 ++++++++++----- - 4 files changed, 104 insertions(+), 23 deletions(-) - -diff --git a/config.c b/config.c -index 450880e3..a9a0b4f7 100644 ---- a/config.c -+++ b/config.c -@@ -131,6 +131,34 @@ bool is_devname_ignore(char *devname) - return false; - } - -+/** -+ * ident_log() - generate and write message to the user. -+ * @param_name: name of the property. -+ * @value: value of the property. -+ * @reason: meaningful description. -+ * @cmdline: context dependent actions, see below. -+ * -+ * The function is made to provide similar error handling for both config and cmdline. The behavior -+ * is configurable via @cmdline. Message has following format: -+ * "Value "@value" cannot be set for @param_name. Reason: @reason." -+ * -+ * If cmdline is on: -+ * - message is written to stderr. -+ * otherwise: -+ * - message is written to stdout. -+ * - "Value ignored" is added at the end of the message. -+ */ -+static void ident_log(const char *param_name, const char *value, const char *reason, -+ const bool cmdline) -+{ -+ if (cmdline == true) -+ pr_err("Value \"%s\" cannot be set as %s. Reason: %s.\n", value, param_name, -+ reason); -+ else -+ pr_info("Value \"%s\" cannot be set as %s. Reason: %s. Value ignored.\n", value, -+ param_name, reason); -+} -+ - /** - * ident_init() - Set defaults. - * @ident: ident pointer, not NULL. -@@ -159,6 +187,46 @@ inline void ident_init(struct mddev_ident *ident) - ident->uuid_set = 0; - } - -+/** -+ * _ident_set_name()- set name in &mddev_ident. -+ * @ident: pointer to &mddev_ident. -+ * @name: name to be set. -+ * @cmdline: context dependent actions. -+ * -+ * If criteria passed, set name in @ident. -+ * -+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -+ */ -+static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *name, -+ const bool cmdline) -+{ -+ assert(name); -+ assert(ident); -+ -+ const char *prop_name = "name"; -+ -+ if (ident->name[0]) { -+ ident_log(prop_name, name, "Already defined", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) { -+ ident_log(prop_name, name, "Too long or empty", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); -+ return MDADM_STATUS_SUCCESS; -+} -+ -+/** -+ * ident_set_name()- exported, for cmdline. -+ */ -+mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name) -+{ -+ return _ident_set_name(ident, name, true); -+} -+ - struct conf_dev { - struct conf_dev *next; - char *name; -@@ -444,14 +512,7 @@ void arrayline(char *line) - mis.super_minor = minor; - } - } else if (strncasecmp(w, "name=", 5) == 0) { -- if (mis.name[0]) -- pr_err("only specify name once, %s ignored.\n", -- w); -- else if (strlen(w + 5) > 32) -- pr_err("name too long, ignoring %s\n", w); -- else -- strcpy(mis.name, w + 5); -- -+ _ident_set_name(&mis, w + 5, false); - } else if (strncasecmp(w, "bitmap=", 7) == 0) { - if (mis.bitmap_file) - pr_err("only specify bitmap file once. %s ignored\n", -diff --git a/lib.c b/lib.c -index 8a4b48e0..03198e2d 100644 ---- a/lib.c -+++ b/lib.c -@@ -27,6 +27,24 @@ - #include - #include - -+/** -+ * is_string_lq() - Check if string length with NULL byte is lower or equal to requested. -+ * @str: string to check. -+ * @max_len: max length. -+ * -+ * @str length must be bigger than 0 and be lower or equal @max_len, including termination byte. -+ */ -+bool is_string_lq(const char * const str, size_t max_len) -+{ -+ assert(str); -+ -+ size_t _len = strnlen(str, max_len); -+ -+ if (_len > 0 && _len < max_len) -+ return true; -+ return false; -+} -+ - bool is_dev_alive(char *path) - { - if (!path) -diff --git a/mdadm.c b/mdadm.c -index 0a56ed26..8bc9304e 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -690,20 +690,14 @@ int main(int argc, char *argv[]) - case O(CREATE,'N'): - case O(ASSEMBLE,'N'): - case O(MISC,'N'): -- if (ident.name[0]) { -- pr_err("name cannot be set twice. Second value %s.\n", optarg); -- exit(2); -- } - if (mode == MISC && !c.subarray) { - pr_err("-N/--name only valid with --update-subarray in misc mode\n"); - exit(2); - } -- if (strlen(optarg) > 32) { -- pr_err("name '%s' is too long, 32 chars max.\n", -- optarg); -+ -+ if (ident_set_name(&ident, optarg) != MDADM_STATUS_SUCCESS) - exit(2); -- } -- strcpy(ident.name, optarg); -+ - continue; - - case O(ASSEMBLE,'m'): /* super-minor for array */ -diff --git a/mdadm.h b/mdadm.h -index 5678eb11..bbf386d6 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -294,6 +294,11 @@ static inline void __put_unaligned32(__u32 val, void *p) - #define KIB_TO_BYTES(x) ((x) << 10) - #define SEC_TO_BYTES(x) ((x) << 9) - -+/** -+ * This is true for native and DDF, IMSM allows 16. -+ */ -+#define MD_NAME_MAX 32 -+ - extern const char Name[]; - - struct md_bb_entry { -@@ -425,6 +430,12 @@ struct spare_criteria { - unsigned int sector_size; - }; - -+typedef enum mdadm_status { -+ MDADM_STATUS_SUCCESS = 0, -+ MDADM_STATUS_ERROR, -+ MDADM_STATUS_UNDEF, -+} mdadm_status_t; -+ - enum mode { - ASSEMBLE=1, - BUILD, -@@ -593,7 +604,7 @@ struct mddev_ident { - - int uuid_set; - int uuid[4]; -- char name[33]; -+ char name[MD_NAME_MAX + 1]; - - int super_minor; - -@@ -1609,6 +1620,7 @@ extern int check_partitions(int fd, char *dname, - extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); - extern int stat_is_blkdev(char *devname, dev_t *rdev); - -+extern bool is_string_lq(const char * const str, size_t max_len); - extern bool is_dev_alive(char *path); - extern int get_mdp_major(void); - extern int get_maj_min(char *dev, int *major, int *minor); -@@ -1626,6 +1638,7 @@ extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); -+extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name); - - extern int parse_auto(char *str, char *msg, int config); - extern struct mddev_ident *conf_get_ident(char *dev); -@@ -2002,11 +2015,6 @@ enum r0layout { - /* And another special number needed for --data_offset=variable */ - #define VARIABLE_OFFSET 3 - --/** -- * This is true for native and DDF, IMSM allows 16. -- */ --#define MD_NAME_MAX 32 -- - /** - * is_container() - check if @level is &LEVEL_CONTAINER - * @level: level value --- -2.40.1 - diff --git a/SOURCES/0156-mdadm-define-ident_set_devname.patch b/SOURCES/0156-mdadm-define-ident_set_devname.patch deleted file mode 100644 index 8c7441b..0000000 --- a/SOURCES/0156-mdadm-define-ident_set_devname.patch +++ /dev/null @@ -1,249 +0,0 @@ -From ae5f13a971bc309e0e25087421119b86daf2e510 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:49 +0200 -Subject: [PATCH 156/165] mdadm: define ident_set_devname() - -Use dedicated set method for ident->devname. Now, devname validation -is done early for modes where device is created (Build, Create and -Assemble). The rules, used for devname validation are derived from -config file. - -It could cause regression with execeptional cases where existing device -has name which doesn't match criteria for Manage and Grow modes. It is -low risk and those modes are not omitted from early devname validation. -Use can used main numbered devnode to avoid this problem. -Messages exposed to user are changed so it might cause a regression -in negative scenarios. Error codes are not changed. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 102 +++++++++++++++++++++++++-------- - mdadm.c | 10 +--- - mdadm.h | 3 +- - tests/00createnames | 3 + - tests/templates/names_template | 7 +++ - 5 files changed, 92 insertions(+), 33 deletions(-) - -diff --git a/config.c b/config.c -index a9a0b4f7..a0424845 100644 ---- a/config.c -+++ b/config.c -@@ -122,7 +122,7 @@ int match_keyword(char *word) - /** - * is_devname_ignore() - check if &devname is a special "" keyword. - */ --bool is_devname_ignore(char *devname) -+bool is_devname_ignore(const char *devname) - { - static const char keyword[] = ""; - -@@ -187,6 +187,74 @@ inline void ident_init(struct mddev_ident *ident) - ident->uuid_set = 0; - } - -+/** -+ * _ident_set_devname()- verify devname and set it in &mddev_ident. -+ * @ident: pointer to &mddev_ident. -+ * @devname: devname to be set. -+ * @cmdline: context dependent actions. If set, ignore keyword is not allowed. -+ * -+ * @devname can have following forms: -+ * '' keyword (if allowed) -+ * /dev/md{number} -+ * /dev/md_d{number} (legacy) -+ * /dev/md_{name} -+ * /dev/md/{name} -+ * {name} - anything that doesn't start from '/' or '<'. -+ * -+ * {name} must follow name's criteria. -+ * If criteria passed, duplicate memory and set devname in @ident. -+ * -+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -+ */ -+mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname, -+ const bool cmdline) -+{ -+ assert(ident); -+ assert(devname); -+ -+ static const char named_dev_pref[] = DEV_NUM_PREF "_"; -+ static const int named_dev_pref_size = sizeof(named_dev_pref) - 1; -+ const char *prop_name = "devname"; -+ const char *name; -+ -+ if (ident->devname) { -+ ident_log(prop_name, devname, "Already defined", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_devname_ignore(devname) == true) { -+ if (!cmdline) -+ goto pass; -+ -+ ident_log(prop_name, devname, "Special keyword is invalid in this context", -+ cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_devname_md_numbered(devname) == true || is_devname_md_d_numbered(devname) == true) -+ goto pass; -+ -+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ name = devname + DEV_MD_DIR_LEN; -+ else if (strncmp(devname, named_dev_pref, named_dev_pref_size) == 0) -+ name = devname + named_dev_pref_size; -+ else -+ name = devname; -+ -+ if (*name == '/' || *name == '<') { -+ ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) { -+ ident_log(prop_name, devname, "Invalid length", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+pass: -+ ident->devname = xstrdup(devname); -+ return MDADM_STATUS_SUCCESS; -+} -+ - /** - * _ident_set_name()- set name in &mddev_ident. - * @ident: pointer to &mddev_ident. -@@ -219,6 +287,14 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam - return MDADM_STATUS_SUCCESS; - } - -+/** -+ * ident_set_devname()- exported, for cmdline. -+ */ -+mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *name) -+{ -+ return _ident_set_devname(ident, name, true); -+} -+ - /** - * ident_set_name()- exported, for cmdline. - */ -@@ -464,29 +540,7 @@ void arrayline(char *line) - - for (w = dl_next(line); w != line; w = dl_next(w)) { - if (w[0] == '/' || strchr(w, '=') == NULL) { -- /* This names the device, or is ''. -- * The rules match those in create_mddev. -- * 'w' must be: -- * /dev/md/{anything} -- * /dev/mdNN -- * /dev/md_dNN -- * -- * or anything that doesn't start '/' or '<' -- */ -- if (is_devname_ignore(w) == true || -- strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || -- (w[0] != '/' && w[0] != '<') || -- is_devname_md_numbered(w) == true || -- is_devname_md_d_numbered(w) == true) { -- /* This is acceptable */; -- if (mis.devname) -- pr_err("only give one device per ARRAY line: %s and %s\n", -- mis.devname, w); -- else -- mis.devname = w; -- }else { -- pr_err("%s is an invalid name for an md device - ignored.\n", w); -- } -+ _ident_set_devname(&mis, w, false); - } else if (strncasecmp(w, "uuid=", 5) == 0) { - if (mis.uuid_set) - pr_err("only specify uuid once, %s ignored.\n", -diff --git a/mdadm.c b/mdadm.c -index 8bc9304e..62f981df 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1284,7 +1284,8 @@ int main(int argc, char *argv[]) - pr_err("an md device must be given in this mode\n"); - exit(2); - } -- ident.devname = devlist->devname; -+ if (ident_set_devname(&ident, devlist->devname) != MDADM_STATUS_SUCCESS) -+ exit(1); - - if ((int)ident.super_minor == -2 && c.autof) { - pr_err("--super-minor=dev is incompatible with --auto\n"); -@@ -1301,13 +1302,6 @@ int main(int argc, char *argv[]) - exit(1); - } - } else { -- char *bname = basename(ident.devname); -- -- if (strlen(bname) > MD_NAME_MAX) { -- pr_err("Name %s is too long.\n", ident.devname); -- exit(1); -- } -- - ret = stat(ident.devname, &stb); - if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -diff --git a/mdadm.h b/mdadm.h -index bbf386d6..49422e24 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1638,6 +1638,7 @@ extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); -+extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname); - extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name); - - extern int parse_auto(char *str, char *msg, int config); -@@ -1660,7 +1661,7 @@ extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); --extern bool is_devname_ignore(char *devname); -+extern bool is_devname_ignore(const char *devname); - extern bool is_devname_md_numbered(const char *devname); - extern bool is_devname_md_d_numbered(const char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); -diff --git a/tests/00createnames b/tests/00createnames -index 064eeef2..a95e7d2b 100644 ---- a/tests/00createnames -+++ b/tests/00createnames -@@ -39,3 +39,6 @@ mdadm -S "/dev/md0" - names_create "/dev/md0" "name" - names_verify "/dev/md0" "empty" "name" - mdadm -S "/dev/md0" -+ -+# Devnode is a special ignore keyword. Should be rejected. -+names_create "" "name", "true" -diff --git a/tests/templates/names_template b/tests/templates/names_template -index 8d2b5c81..6181bfaa 100644 ---- a/tests/templates/names_template -+++ b/tests/templates/names_template -@@ -2,6 +2,7 @@ - function names_create() { - local DEVNAME=$1 - local NAME=$2 -+ local NEG_TEST=$3 - - if [[ -z "$NAME" ]]; then - mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -@@ -9,6 +10,12 @@ function names_create() { - mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force - fi - -+ if [[ "$NEG_TEST" == "true" ]]; then -+ [[ "$?" == "0" ]] && return 0 -+ echo "Negative verification failed" -+ exit 1 -+ fi -+ - if [[ "$?" != "0" ]]; then - echo "Cannot create device." - exit 1 --- -2.40.1 - diff --git a/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch b/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch deleted file mode 100644 index 50d2bbb..0000000 --- a/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch +++ /dev/null @@ -1,471 +0,0 @@ -From e2eb503bd797908f515b58428b274f1ba6a05349 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:50 +0200 -Subject: [PATCH 157/165] mdadm: Follow POSIX Portable Character Set - -When the user creates a device with a name that contains whitespace, -mdadm timeouts and throws an error. This issue is caused by udev, which -truncates /dev/md link until the first whitespace. - -This patch introduces prohibition of characters other than A-Za-z0-9.-_ -in the device name. Also, it prohibits using leading "-" in device name, -so name won't be confused with cli parameter. -Set of allowed characters is taken from POSIX 3.280 Portable Character -Set. Also, device name length now is limited to NAME_MAX. - -In some places, there are other requirements for string length (e.g. size -up to MD_NAME_MAX for device name). This routine is made to follow POSIX -and other, more strict limitations should be checked separately. -We are aware of the risk of regression in exceptional cases (as -escape_devname function is removed) that should be fixed by updating -the array name. - -The POSIX validation is added for: -- 'name' parameter in every mode. -- first devlist entry, for Build, Create, Assemble, Manage, Grow. -- config entries, both devname and "name=". - -Additionally, some manual cleanups are made. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Detail.c | 17 ++++-------- - config.c | 13 ++++++--- - lib.c | 58 ++++++++++++++++++++++++++++----------- - mdadm.8.in | 70 ++++++++++++++++++++--------------------------- - mdadm.conf.5.in | 4 --- - mdadm.h | 2 +- - super-intel.c | 47 ++++++++++++++++--------------- - tests/00confnames | 4 +-- - 8 files changed, 113 insertions(+), 102 deletions(-) - -diff --git a/Detail.c b/Detail.c -index 206d88e3..57ac336f 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -254,11 +254,9 @@ int Detail(char *dev, struct context *c) - fname_from_uuid(st, info, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf + 5); - mp = map_by_uuid(&map, info->uuid); -- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- printf("MD_DEVNAME="); -- print_escape(mp->path + DEV_MD_DIR_LEN); -- putchar('\n'); -- } -+ -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); - - if (st->ss->export_detail_super) - st->ss->export_detail_super(st); -@@ -271,12 +269,9 @@ int Detail(char *dev, struct context *c) - __fname_from_uuid(mp->uuid, 0, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf+5); - } -- if (mp && mp->path && -- strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- printf("MD_DEVNAME="); -- print_escape(mp->path + DEV_MD_DIR_LEN); -- putchar('\n'); -- } -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); -+ - map_free(map); - } - if (!c->no_devices && sra) { -diff --git a/config.c b/config.c -index a0424845..5f12a1f8 100644 ---- a/config.c -+++ b/config.c -@@ -199,9 +199,9 @@ inline void ident_init(struct mddev_ident *ident) - * /dev/md_d{number} (legacy) - * /dev/md_{name} - * /dev/md/{name} -- * {name} - anything that doesn't start from '/' or '<'. -+ * {name} - * -- * {name} must follow name's criteria. -+ * {name} must follow name's criteria and be POSIX compatible. - * If criteria passed, duplicate memory and set devname in @ident. - * - * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -@@ -241,8 +241,8 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname - else - name = devname; - -- if (*name == '/' || *name == '<') { -- ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline); -+ if (is_name_posix_compatible(name) == false) { -+ ident_log(prop_name, name, "Not POSIX compatible", cmdline); - return MDADM_STATUS_ERROR; - } - -@@ -283,6 +283,11 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam - return MDADM_STATUS_ERROR; - } - -+ if (is_name_posix_compatible(name) == false) { -+ ident_log(prop_name, name, "Not POSIX compatible", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ - snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); - return MDADM_STATUS_SUCCESS; - } -diff --git a/lib.c b/lib.c -index 03198e2d..7ab59988 100644 ---- a/lib.c -+++ b/lib.c -@@ -483,24 +483,50 @@ void print_quoted(char *str) - putchar(q); - } - --void print_escape(char *str) -+/** -+ * is_alphanum() - Check if sign is letter or digit. -+ * @c: char to analyze. -+ * -+ * Similar to isalnum() but additional locales are excluded. -+ * -+ * Return: %true on success, %false otherwise. -+ */ -+bool is_alphanum(const char c) - { -- /* print str, but change space and tab to '_' -- * as is suitable for device names -- */ -- for (; *str; str++) { -- switch (*str) { -- case ' ': -- case '\t': -- putchar('_'); -- break; -- case '/': -- putchar('-'); -- break; -- default: -- putchar(*str); -- } -+ if (isupper(c) || islower(c) || isdigit(c) != 0) -+ return true; -+ return false; -+} -+ -+/** -+ * is_name_posix_compatible() - Check if name is POSIX compatible. -+ * @name: name to check. -+ * -+ * POSIX portable file name character set contains ASCII letters, -+ * digits, '_', '.', and '-'. Also forbid leading '-'. -+ * The length of the name cannot exceed NAME_MAX - 1 (ensure NULL ending). -+ * -+ * Return: %true on success, %false otherwise. -+ */ -+bool is_name_posix_compatible(const char * const name) -+{ -+ assert(name); -+ -+ char allowed_symbols[] = "-_."; -+ const char *n = name; -+ -+ if (!is_string_lq(name, NAME_MAX)) -+ return false; -+ -+ if (*n == '-') -+ return false; -+ -+ while (*n != '\0') { -+ if (!is_alphanum(*n) && !strchr(allowed_symbols, *n)) -+ return false; -+ n++; - } -+ return true; - } - - int check_env(char *name) -diff --git a/mdadm.8.in b/mdadm.8.in -index b7159509..3142436f 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -364,7 +364,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a - which is managed in a similar manner to DDF, and is supported by an - option-rom on some platforms: - .IP --.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html -+.B https://www.intel.com/content/www/us/en/support/products/122484 - .PP - .RE - -@@ -932,17 +932,14 @@ option will be ignored. - .BR \-N ", " \-\-name= - Set a - .B name --for the array. This is currently only effective when creating an --array with a version-1 superblock, or an array in a DDF container. --The name is a simple textual string that can be used to identify array --components when assembling. If name is needed but not specified, it --is taken from the basename of the device that is being created. --e.g. when creating --.I /dev/md/home --the --.B name --will default to --.IR home . -+for the array. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. This is effective when creating an array -+with a v1 metadata, or an external array. -+ -+If name is needed but not specified, it is taken from the basename of the device -+that is being created. See -+.BR "DEVICE NAMES" - - .TP - .BR \-R ", " \-\-run -@@ -1132,8 +1129,10 @@ is much safer. - - .TP - .BR \-N ", " \-\-name= --Specify the name of the array to assemble. This must be the name --that was specified when creating the array. It must either match -+Specify the name of the array to assemble. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. This must be the name -+that was specified when creating the array. It must either match - the name stored in the superblock exactly, or it must match - with the current - .I homehost -@@ -2179,14 +2178,17 @@ Usage: - .I md-device - .BI \-\-chunk= X - .BI \-\-level= Y --.br - .BI \-\-raid\-devices= Z - .I devices - - .PP --This usage will initialise a new md array, associate some devices with -+This usage will initialize a new md array, associate some devices with - it, and activate the array. - -+.I md-device -+is a new device. This could be standard name or chosen name. For details see: -+.BR "DEVICE NAMES" -+ - The named device will normally not exist when - .I "mdadm \-\-create" - is run, but will be created by -@@ -2227,24 +2229,6 @@ array. This feature can be overridden with the - .B \-\-force - option. - --When creating an array with version-1 metadata a name for the array is --required. --If this is not given with the --.B \-\-name --option, --.I mdadm --will choose a name based on the last component of the name of the --device being created. So if --.B /dev/md3 --is being created, then the name --.B 3 --will be chosen. --If --.B /dev/md/home --is being created, then the name --.B home --will be used. -- - When creating a partition based array, using - .I mdadm - with version-1.x metadata, the partition type should be set to -@@ -2429,12 +2413,10 @@ and - - The - .B name --option updates the subarray name in the metadata, it may not affect the --device node name or the device node symlink until the subarray is --re\-assembled. If updating --.B name --would change the UUID of an active subarray this operation is blocked, --and the command will end in an error. -+option updates the subarray name in the metadata. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. If successes, new value will be respected after -+next assembly. - - The - .B ppl -@@ -3395,6 +3377,10 @@ When - .B \-\-incremental - mode is used, this file gets a list of arrays currently being created. - -+.SH POSIX PORTABLE NAME -+A valid name can only consist of characters "A-Za-z0-9.-_". -+The name cannot start with a leading "-" and cannot exceed 255 chars. -+ - .SH DEVICE NAMES - - .I mdadm -@@ -3416,6 +3402,10 @@ can be given, or just the suffix of the second sort of name, such as - .I home - can be given. - -+In every style, raw name must be compatible with -+.BR "POSIX PORTABLE NAME" -+and has to be no longer than 32 chars. -+ - When - .I mdadm - chooses device names during auto-assembly or incremental assembly, it -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index bc2295c2..94e23dd0 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -717,10 +717,6 @@ ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b - .br - auto=part - .br --# The name of this array contains a space. --.br --ARRAY /dev/md9 name='Data Storage' --.sp - POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* - .br - action=spare -diff --git a/mdadm.h b/mdadm.h -index 49422e24..9effb941 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1617,6 +1617,7 @@ extern int check_raid(int fd, char *name); - extern int check_partitions(int fd, char *dname, - unsigned long long freesize, - unsigned long long size); -+extern bool is_name_posix_compatible(const char *path); - extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); - extern int stat_is_blkdev(char *devname, dev_t *rdev); - -@@ -1657,7 +1658,6 @@ extern int conf_get_monitor_delay(void); - extern char *conf_line(FILE *file); - extern char *conf_word(FILE *file, int allow_key); - extern void print_quoted(char *str); --extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); -diff --git a/super-intel.c b/super-intel.c -index 77b0066f..05d3b056 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5561,40 +5561,37 @@ static void imsm_update_version_info(struct intel_super *super) - } - } - --static int check_name(struct intel_super *super, char *name, int quiet) -+/** -+ * imsm_check_name() - check imsm naming criteria. -+ * @super: &intel_super pointer, not NULL. -+ * @name: name to check. -+ * @verbose: verbose level. -+ * -+ * Name must be no longer than &MAX_RAID_SERIAL_LEN and must be unique across volumes. -+ * -+ * Returns: &true if @name matches, &false otherwise. -+ */ -+static bool imsm_is_name_allowed(struct intel_super *super, const char * const name, -+ const int verbose) - { - struct imsm_super *mpb = super->anchor; -- char *reason = NULL; -- char *start = name; -- size_t len = strlen(name); - int i; - -- if (len > 0) { -- while (isspace(start[len - 1])) -- start[--len] = 0; -- while (*start && isspace(*start)) -- ++start, --len; -- memmove(name, start, len + 1); -+ if (is_string_lq(name, MAX_RAID_SERIAL_LEN + 1) == false) { -+ pr_vrb("imsm: Name \"%s\" is too long\n", name); -+ return false; - } - -- if (len > MAX_RAID_SERIAL_LEN) -- reason = "must be 16 characters or less"; -- else if (len == 0) -- reason = "must be a non-empty string"; -- - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); - - if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) { -- reason = "already exists"; -- break; -+ pr_vrb("imsm: Name \"%s\" already exists\n", name); -+ return false; - } - } - -- if (reason && !quiet) -- pr_err("imsm volume name %s\n", reason); -- -- return !reason; -+ return true; - } - - static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, -@@ -5689,8 +5686,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, - } - } - -- if (!check_name(super, name, 0)) -+ if (imsm_is_name_allowed(super, name, 1) == false) - return 0; -+ - dv = xmalloc(sizeof(*dv)); - dev = xcalloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1)); - /* -@@ -8018,7 +8016,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - char *ep; - int vol; - -- if (!check_name(super, name, 0)) -+ if (imsm_is_name_allowed(super, name, 1) == false) - return 2; - - vol = strtoul(subarray, &ep, 10); -@@ -10345,7 +10343,8 @@ static void imsm_process_update(struct supertype *st, - if (a->info.container_member == target) - break; - dev = get_imsm_dev(super, u->dev_idx); -- if (a || !check_name(super, name, 1)) { -+ -+ if (a || !dev || imsm_is_name_allowed(super, name, 0) == false) { - dprintf("failed to rename subarray-%d\n", target); - break; - } -diff --git a/tests/00confnames b/tests/00confnames -index 25a7127b..10823f01 100644 ---- a/tests/00confnames -+++ b/tests/00confnames -@@ -79,10 +79,10 @@ names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 11. with some special symbols and locales, no . --# It needs to wait a while for timeout because udev cannot create a link - known issue. -+# should be ignored. - names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config - mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "tźż-\.,<>st+-" "name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 12. No and set. --- -2.40.1 - diff --git a/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch b/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch deleted file mode 100644 index 68e1e6d..0000000 --- a/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch +++ /dev/null @@ -1,128 +0,0 @@ -From ba489abd688bf70c83e70700aaaec5f5e90889c5 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Mon, 14 Aug 2023 00:46:13 +0800 -Subject: [PATCH 158/165] Incremental: remove obsoleted calls to udisks - -Utility udisks is removed from udev upstream, calling this obsoleted -command in run_udisks() doesn't make any sense now. - -This patch removes the calls chain of udisks, which includes routines -run_udisk(), force_remove(), and 2 locations where force_remove() are -called. Considering force_remove() is removed with udisks util, it is -fair to remove Manage_stop() inside force_remove() as well. - -In the two modifications where calling force_remove() are removed, -the failure from Manage_subdevs() can be safely ignored, because, -1) udisks doesn't exist, no need to check the return value to umount - the file system by udisks and remove the component disk again. -2) After the 'I' inremental remove, there is another 'r' hot remove - following up. The first incremental remove is a best-try effort. - -Therefore in this patch, where force_remove() is removed, the return -value of calling Manage_subdevs() is not checked too. - -Signed-off-by: Coly Li -Reviewed-by: Mariusz Tkaczyk -Cc: Jes Sorensen -Signed-off-by: Jes Sorensen ---- - Incremental.c | 64 +++++++++++---------------------------------------- - 1 file changed, 13 insertions(+), 51 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index f13ce027..05b33c45 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1628,54 +1628,18 @@ release: - return rv; - } - --static void run_udisks(char *arg1, char *arg2) --{ -- int pid = fork(); -- int status; -- if (pid == 0) { -- manage_fork_fds(1); -- execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); -- execl("/bin/udisks", "udisks", arg1, arg2, NULL); -- exit(1); -- } -- while (pid > 0 && wait(&status) != pid) -- ; --} -- --static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose) --{ -- int rv; -- int devid = devnm2devid(devnm); -- -- run_udisks("--unmount", map_dev(major(devid), minor(devid), 0)); -- rv = Manage_stop(devnm, fd, verbose, 1); -- if (rv) { -- /* At least we can try to trigger a 'remove' */ -- sysfs_uevent(mdi, "remove"); -- if (verbose) -- pr_err("Fail to stop %s too.\n", devnm); -- } -- return rv; --} -- - static void remove_from_member_array(struct mdstat_ent *memb, - struct mddev_dev *devlist, int verbose) - { -- int rv; -- struct mdinfo mmdi; - int subfd = open_dev(memb->devnm); - - if (subfd >= 0) { -- rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, -- 0, UOPT_UNDEFINED, 0); -- if (rv & 2) { -- if (sysfs_init(&mmdi, -1, memb->devnm)) -- pr_err("unable to initialize sysfs for: %s\n", -- memb->devnm); -- else -- force_remove(memb->devnm, subfd, &mmdi, -- verbose); -- } -+ /* -+ * Ignore the return value because it's necessary -+ * to handle failure condition here. -+ */ -+ Manage_subdevs(memb->devnm, subfd, devlist, verbose, -+ 0, UOPT_UNDEFINED, 0); - close(subfd); - } - } -@@ -1758,21 +1722,19 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - } - free_mdstat(mdstat); - } else { -- rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, UOPT_UNDEFINED, 0); -- if (rv & 2) { -- /* Failed due to EBUSY, try to stop the array. -- * Give udisks a chance to unmount it first. -+ /* -+ * This 'I' incremental remove is a try-best effort, -+ * the failure condition can be safely ignored -+ * because of the following up 'r' remove. - */ -- rv = force_remove(ent->devnm, mdfd, &mdi, verbose); -- goto end; -- } -+ Manage_subdevs(ent->devnm, mdfd, &devlist, -+ verbose, 0, UOPT_UNDEFINED, 0); - } - - devlist.disposition = 'r'; - rv = Manage_subdevs(ent->devnm, mdfd, &devlist, - verbose, 0, UOPT_UNDEFINED, 0); --end: -+ - close(mdfd); - free_mdstat(ent); - return rv; --- -2.40.1 - diff --git a/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch b/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch deleted file mode 100644 index 1493294..0000000 --- a/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 28fc84168646910a9271ebe1a12b1571e14f5900 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Thu, 7 Sep 2023 16:57:44 +0800 -Subject: [PATCH 159/165] mdadm/tests: Fix regular expression failure - -The test fails because of the regular expression. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - tests/06name | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/06name b/tests/06name -index 4d5e824d..86eaab69 100644 ---- a/tests/06name -+++ b/tests/06name -@@ -3,8 +3,8 @@ set -x - # create an array with a name - - mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1 --mdadm -E $dev0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1 --mdadm -D $md0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1 -+mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1 -+mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1 - mdadm -S $md0 - - mdadm -A $md0 --name="Fred" $devlist --- -2.40.1 - diff --git a/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch b/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch deleted file mode 100644 index 311f30a..0000000 --- a/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch +++ /dev/null @@ -1,141 +0,0 @@ -From ed2c2cb3d440f3bd2692f1896446c4bcc703f05c Mon Sep 17 00:00:00 2001 -From: Li Xiao Keng -Date: Thu, 7 Sep 2023 19:37:44 +0800 -Subject: [PATCH 160/165] Fix race of "mdadm --add" and "mdadm --incremental" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There is a raid1 with sda and sdb. And we add sdc to this raid, -it may return -EBUSY. - -The main process of --add: -1. dev_open(sdc) in Manage_add -2. store_super1(st, di->fd) in write_init_super1 -3. fsync(fd) in store_super1 -4. close(di->fd) in write_init_super1 -5. ioctl(ADD_NEW_DISK) - -Step 2 and 3 will add sdc to metadata of raid1. There will be -udev(change of sdc) event after step4. Then "/usr/sbin/mdadm ---incremental --export $devnode --offroot $env{DEVLINKS}" -will be run, and the sdc will be added to the raid1. Then -step 5 will return -EBUSY because it checks if device isn't -claimed in md_import_device()->lock_rdev()->blkdev_get_by_dev() -->blkdev_get(). - -It will be confusing for users because sdc is added first time. -The "incremental" will get map_lock before add sdc to raid1. -So we add map_lock before write_init_super in "mdadm --add" -to fix the race of "add" and "incremental". - -Signed-off-by: Li Xiao Keng -Signed-off-by: Guanqin Miao -Reviewed-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Manage.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/Manage.c b/Manage.c -index f997b163..075dd720 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -704,6 +704,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *dev_st; - int j; - mdu_disk_info_t disc; -+ struct map_ent *map = NULL; - - if (!get_dev_size(tfd, dv->devname, &ldsize)) { - if (dv->disposition == 'M') -@@ -907,6 +908,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - disc.raid_disk = 0; - } - -+ if (map_lock(&map)) -+ pr_err("failed to get exclusive lock on mapfile when add disk\n"); -+ - if (array->not_persistent==0) { - int dfd; - if (dv->disposition == 'j') -@@ -918,9 +922,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); - if (tst->ss->add_to_super(tst, &disc, dfd, - dv->devname, INVALID_SECTORS)) -- return -1; -+ goto unlock; - if (tst->ss->write_init_super(tst)) -- return -1; -+ goto unlock; - } else if (dv->disposition == 'A') { - /* this had better be raid1. - * As we are "--re-add"ing we must find a spare slot -@@ -978,14 +982,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - pr_err("add failed for %s: could not get exclusive access to container\n", - dv->devname); - tst->ss->free_super(tst); -- return -1; -+ goto unlock; - } - - /* Check if metadata handler is able to accept the drive */ - if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL, - 0, 0, dv->devname, NULL, 0, 1)) { - close(container_fd); -- return -1; -+ goto unlock; - } - - Kill(dv->devname, NULL, 0, -1, 0); -@@ -994,7 +998,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dv->devname, INVALID_SECTORS)) { - close(dfd); - close(container_fd); -- return -1; -+ goto unlock; - } - if (!mdmon_running(tst->container_devnm)) - tst->ss->sync_metadata(tst); -@@ -1005,7 +1009,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dv->devname); - close(container_fd); - tst->ss->free_super(tst); -- return -1; -+ goto unlock; - } - sra->array.level = LEVEL_CONTAINER; - /* Need to set data_offset and component_size */ -@@ -1020,7 +1024,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - pr_err("add new device to external metadata failed for %s\n", dv->devname); - close(container_fd); - sysfs_free(sra); -- return -1; -+ goto unlock; - } - ping_monitor(devnm); - sysfs_free(sra); -@@ -1034,7 +1038,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - else - pr_err("add new device failed for %s as %d: %s\n", - dv->devname, j, strerror(errno)); -- return -1; -+ goto unlock; - } - if (dv->disposition == 'j') { - pr_err("Journal added successfully, making %s read-write\n", devname); -@@ -1045,7 +1049,11 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - } - if (verbose >= 0) - pr_err("added %s\n", dv->devname); -+ map_unlock(&map); - return 1; -+unlock: -+ map_unlock(&map); -+ return -1; - } - - int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, --- -2.40.1 - diff --git a/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch b/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch deleted file mode 100644 index 7d00a5b..0000000 --- a/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c32b4754014c1eec8cc0c025fad2e9b621486164 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 8 Sep 2023 16:44:35 +0800 -Subject: [PATCH 161/165] mdadm/tests: Don't run mknod before losetup - -Sometimes it can fail: -losetup: /var/tmp/mdtest0: failed to set up loop device: No such device or address -/dev/loop0 and /var/tmp/mdtest0 are already created before losetup. - -Because losetup can create device node by itself. So remove mknod. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - tests/func.sh | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tests/func.sh b/tests/func.sh -index 9710a53b..5053b012 100644 ---- a/tests/func.sh -+++ b/tests/func.sh -@@ -170,7 +170,6 @@ do_setup() { - dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1 - # make sure udev doesn't touch - mdadm --zero $targetdir/mdtest$d 2> /dev/null -- [ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d - if [ $d -eq 7 ] - then - losetup /dev/loop$d $targetdir/mdtest6 # for multipath use --- -2.40.1 - diff --git a/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch b/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch deleted file mode 100644 index 9c9ad6b..0000000 --- a/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 246b4b40558f6f7f84882e9c34659f1b582944e2 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Wed, 11 Oct 2023 21:03:32 +0800 -Subject: [PATCH 162/165] mdadm/ddf: Abort when raid disk is smaller in - getinfo_super_ddf -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The metadata is corrupted when the raid_disk<0. So abort directly. -This also can avoid a building error: -super-ddf.c:1988:58: error: array subscript -1 is below array bounds of ‘struct phys_disk_entry[0]’ - -Suggested-by: Mariusz Tkaczyk -Ackedy-by: Xiao Ni -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index c5242654..7571e3b7 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1984,12 +1984,14 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m - info->disk.number = be32_to_cpu(ddf->dlist->disk.refnum); - info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum); - -+ if (info->disk.raid_disk < 0) -+ return; -+ - info->data_offset = be64_to_cpu(ddf->phys-> - entries[info->disk.raid_disk]. - config_size); - info->component_size = ddf->dlist->size - info->data_offset; -- if (info->disk.raid_disk >= 0) -- pde = ddf->phys->entries + info->disk.raid_disk; -+ pde = ddf->phys->entries + info->disk.raid_disk; - if (pde && - !(be16_to_cpu(pde->state) & DDF_Failed) && - !(be16_to_cpu(pde->state) & DDF_Missing)) --- -2.40.1 - diff --git a/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch b/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch deleted file mode 100644 index f31d4c6..0000000 --- a/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 6af520a5b4d91cd0fd32ab6361ff4519505c7f47 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Tue, 17 Oct 2023 20:35:46 +0800 -Subject: [PATCH 163/165] mdadm/super1: Add MD_FEATURE_RAID0_LAYOUT if - kernel>=5.4 - -After and include kernel v5.4, it adds one feature bit MD_FEATURE_RAID0_LAYOUT. -It must need to specify a layout for raid0 with more than one zone. But for -raid0 with one zone, in fact it also has a defalut layout. - -Now for raid0 with one zone, *unknown* layout can be seen when running mdadm -D -command. It's the reason that mdadm doesn't set MD_FEATURE_RAID0_LAYOUT for -raid0 with one zone. Then in kernel space, super_1_validate sets mddev->layout -to -1 because of no MD_FEATURE_RAID0_LAYOUT. In fact, in raid0 io path, it -uses the default layout. Set raid0_need_layout to true if kernel_version<=v5.4. - -Fixes: 329dfc28debb ('Create: add support for RAID0 layouts.') -Signed-off-by: Xiao Ni -Reviewed-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super1.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/super1.c b/super1.c -index 856b0208..1da71b98 100644 ---- a/super1.c -+++ b/super1.c -@@ -1967,6 +1967,14 @@ fail_to_write: - return 1; - } - -+static bool has_raid0_layout(struct mdp_superblock_1 *sb) -+{ -+ if (sb->level == 0 && sb->layout != 0) -+ return true; -+ else -+ return false; -+} -+ - static int write_init_super1(struct supertype *st) - { - struct mdp_superblock_1 *sb = st->sb; -@@ -1978,12 +1986,17 @@ static int write_init_super1(struct supertype *st) - unsigned long long sb_offset; - unsigned long long data_offset; - long bm_offset; -- int raid0_need_layout = 0; -+ bool raid0_need_layout = false; -+ -+ /* Since linux kernel v5.4, raid0 always has a layout */ -+ if (has_raid0_layout(sb) && get_linux_version() >= 5004000) -+ raid0_need_layout = true; - - for (di = st->info; di; di = di->next) { - if (di->disk.state & (1 << MD_DISK_JOURNAL)) - sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); -- if (sb->level == 0 && sb->layout != 0) { -+ if (has_raid0_layout(sb) && !raid0_need_layout) { -+ - struct devinfo *di2 = st->info; - unsigned long long s1, s2; - s1 = di->dev_size; -@@ -1995,7 +2008,7 @@ static int write_init_super1(struct supertype *st) - s2 -= di2->data_offset; - s2 /= __le32_to_cpu(sb->chunksize); - if (s1 != s2) -- raid0_need_layout = 1; -+ raid0_need_layout = true; - } - } - --- -2.40.1 - diff --git a/SOURCES/0164-mdadm-remove-container_enough-logic.patch b/SOURCES/0164-mdadm-remove-container_enough-logic.patch deleted file mode 100644 index 2077aab..0000000 --- a/SOURCES/0164-mdadm-remove-container_enough-logic.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 4dde420fc3e24077ab926f79674eaae1b71de10b Mon Sep 17 00:00:00 2001 -From: Pawel Piatkowski -Date: Thu, 19 Oct 2023 16:35:24 +0200 -Subject: [PATCH 164/165] mdadm: remove container_enough logic - -Arrays without enough disk count will be assembled but not -started. -Now RAIDs will be assembled always (even if they are failed). -RAID devices in all states will be assembled and exposed -to mdstat. -This change affects only IMSM (for ddf it wasn't used, -container_enough was set to true always). -Removed this logic from incremental_container as well with -runstop checking because runstop condition is being verified -in assemble_container_content function. - -Signed-off-by: Pawel Piatkowski -Signed-off-by: Jes Sorensen ---- - Incremental.c | 11 ----------- - mdadm.h | 3 --- - super-ddf.c | 1 - - super-intel.c | 32 +------------------------------- - 4 files changed, 1 insertion(+), 46 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index 05b33c45..3551c65b 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1467,17 +1467,6 @@ static int Incremental_container(struct supertype *st, char *devname, - - st->ss->getinfo_super(st, &info, NULL); - -- if ((c->runstop > 0 && info.container_enough >= 0) || -- info.container_enough > 0) -- /* pass */; -- else { -- if (c->export) { -- printf("MD_STARTED=no\n"); -- } else if (c->verbose) -- pr_err("not enough devices to start the container\n"); -- return 0; -- } -- - match = conf_match(st, &info, devname, c->verbose, &rv); - if (match == NULL && rv == 2) - return rv; -diff --git a/mdadm.h b/mdadm.h -index 9effb941..b48e6f86 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -377,9 +377,6 @@ struct mdinfo { - int container_member; /* for assembling external-metatdata arrays - * This is to be used internally by metadata - * handler only */ -- int container_enough; /* flag external handlers can set to -- * indicate that subarrays have not enough (-1), -- * enough to start (0), or all expected disks (1) */ - char sys_name[32]; - struct mdinfo *devs; - struct mdinfo *next; -diff --git a/super-ddf.c b/super-ddf.c -index 7571e3b7..a87e3169 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1975,7 +1975,6 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m - info->array.ctime = DECADE + __be32_to_cpu(*cptr); - - info->array.chunk_size = 0; -- info->container_enough = 1; - - info->disk.major = 0; - info->disk.minor = 0; -diff --git a/super-intel.c b/super-intel.c -index 05d3b056..6bdd5c4c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3806,7 +3806,6 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - struct intel_super *super = st->sb; - struct imsm_disk *disk; - int map_disks = info->array.raid_disks; -- int max_enough = -1; - int i; - struct imsm_super *mpb; - -@@ -3848,12 +3847,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- int failed, enough, j, missing = 0; -+ int j = 0; - struct imsm_map *map; -- __u8 state; - -- failed = imsm_count_failed(super, dev, MAP_0); -- state = imsm_check_degraded(super, dev, failed, MAP_0); - map = get_imsm_map(dev, MAP_0); - - /* any newly missing disks? -@@ -3868,36 +3864,10 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - if (!(ord & IMSM_ORD_REBUILD) && - get_imsm_missing(super, idx)) { -- missing = 1; - break; - } - } -- -- if (state == IMSM_T_STATE_FAILED) -- enough = -1; -- else if (state == IMSM_T_STATE_DEGRADED && -- (state != map->map_state || missing)) -- enough = 0; -- else /* we're normal, or already degraded */ -- enough = 1; -- if (is_gen_migration(dev) && missing) { -- /* during general migration we need all disks -- * that process is running on. -- * No new missing disk is allowed. -- */ -- max_enough = -1; -- enough = -1; -- /* no more checks necessary -- */ -- break; -- } -- /* in the missing/failed disk case check to see -- * if at least one array is runnable -- */ -- max_enough = max(max_enough, enough); - } -- dprintf("enough: %d\n", max_enough); -- info->container_enough = max_enough; - - if (super->disks) { - __u32 reserved = imsm_reserved_sectors(super, super->disks); --- -2.40.1 - diff --git a/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch b/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch deleted file mode 100644 index 0db1767..0000000 --- a/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d8d09c1633b2f06f88633ab960aa02b41a6bdfb6 Mon Sep 17 00:00:00 2001 -From: Pawel Piatkowski -Date: Thu, 19 Oct 2023 16:35:25 +0200 -Subject: [PATCH 165/165] Fix assembling RAID volume by using incremental - -After change "mdadm: remove container_enough logic" -IMSM volumes are started immediately. If volume is during -reshape, then it will be blocked by block_subarray() during -first mdadm -I . Assemble_container_content() for -next disk will see the change because metadata version from -sysfs and metadata doesn't match and will execute -sysfs_set_array again. Then it fails to set same -component_size, it is prohibited by kernel. - -If array is frozen then first sign from metadata version -is different ("/" vs "-"), so exclude it from comparison. -All we want is to double check that base properties are set -and we don't need to call sysfs_set_array again. - -Signed-off-by: Pawel Piatkowski -Signed-off-by: Jes Sorensen ---- - Assemble.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 5be58e40..0557a007 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1990,12 +1990,10 @@ int assemble_container_content(struct supertype *st, int mdfd, - return 1; - } - -- if (strcmp(sra->text_version, content->text_version) != 0) { -- if (content->array.major_version == -1 && -- content->array.minor_version == -2 && -- c->readonly && -- content->text_version[0] == '/') -- content->text_version[0] = '-'; -+ /* Fill sysfs properties only if they are not set. Determine it by checking text_version -+ * and ignoring special character on the first place. -+ */ -+ if (strcmp(sra->text_version + 1, content->text_version + 1) != 0) { - if (sysfs_set_array(content, 9003) != 0) { - sysfs_free(sra); - return 1; --- -2.40.1 - diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec index 9795037..6425f2f 100644 --- a/SPECS/mdadm.spec +++ b/SPECS/mdadm.spec @@ -1,7 +1,7 @@ Name: mdadm -Version: 4.2 +Version: 4.3 # extraversion is used to define rhel internal version -%define extraversion 10 +%define extraversion 3 Release: %{extraversion}%{?dist} Summary: The mdadm program controls Linux md devices (software RAID arrays) URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ @@ -19,171 +19,74 @@ Source8: mdcheck Source9: md-auto-readd.rule Source10: md-auto-readd.sh -Patch000: 0001-Unify-error-message.patch -Patch001: 0002-mdadm-Fix-double-free.patch -Patch002: 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch -Patch003: 0004-udev-adapt-rules-to-systemd-v247.patch -Patch004: 0005-Replace-error-prone-signal-with-sigaction.patch -Patch005: 0006-mdadm-Respect-config-file-location-in-man.patch -Patch006: 0007-mdadm-Update-ReadMe.patch -Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch -Patch008: 0009-mdadm-Update-config-manual.patch -Patch009: 0010-Create-Build-use-default_layout.patch -Patch010: 0011-mdadm-add-map_num_s.patch -Patch011: 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch -Patch012: 0013-mdmon-Stop-parsing-duplicate-options.patch -Patch013: 0014-Grow-block-n-on-external-volumes.patch -Patch014: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch -Patch015: 0016-Mdmonitor-Fix-segfault.patch -Patch016: 0017-Mdmonitor-Improve-logging-method.patch -Patch017: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch -Patch018: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch -Patch019: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch -Patch020: 0021-util-replace-ioctl-use-with-function.patch -Patch021: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch -Patch022: 0023-imsm-introduce-get_disk_slot_in_dev.patch -Patch023: 0024-imsm-use-same-slot-across-container.patch -Patch024: 0025-imsm-block-changing-slots-during-creation.patch -Patch025: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch -Patch026: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch -Patch027: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch -Patch028: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch -Patch029: 0030-Monitor-use-snprintf-to-fill-device-name.patch -Patch030: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch -Patch031: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch -Patch032: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch -Patch033: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch -Patch034: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch -Patch035: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch -Patch036: 0037-mdadm-Fix-optional-write-behind-parameter.patch -Patch037: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch -Patch038: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch -Patch039: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch -Patch040: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch -Patch041: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch -Patch042: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch -Patch043: 0044-tests-Add-broken-files-for-all-broken-tests.patch -Patch044: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch -Patch045: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch -Patch046: 0047-tests-add-test-for-names.patch -Patch047: 0048-mdadm-remove-symlink-option.patch -Patch048: 0049-mdadm-move-data_offset-to-struct-shape.patch -Patch049: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch -Patch050: 0051-Grow-Split-Grow_reshape-into-helper-function.patch -Patch051: 0052-Assemble-check-if-device-is-container-before-schedul.patch -Patch052: 0053-super1-report-truncated-device.patch -Patch053: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch -Patch054: 0055-Manage-Block-unsafe-member-failing.patch -Patch055: 0056-Monitor-Fix-statelist-memory-leaks.patch -Patch056: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch -Patch057: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch -Patch058: 0059-ReadMe-fix-command-line-help.patch -Patch059: 0060-mdadm-replace-container-level-checking-with-inline.patch -Patch060: 0061-Mdmonitor-Omit-non-md-devices.patch -Patch061: 0062-Mdmonitor-Split-alert-into-separate-functions.patch -Patch062: 0063-Monitor-block-if-monitor-modes-are-combined.patch -Patch063: 0064-Update-mdadm-Monitor-manual.patch -Patch064: 0065-Grow-fix-possible-memory-leak.patch -Patch065: 0066-mdadm-create-ident_init.patch -Patch066: 0067-mdadm-Add-option-validation-for-update-subarray.patch -Patch067: 0068-Fix-update-subarray-on-active-volume.patch -Patch068: 0069-Add-code-specific-update-options-to-enum.patch -Patch069: 0070-super-ddf-Remove-update_super_ddf.patch -Patch070: 0071-super0-refactor-the-code-for-enum.patch -Patch071: 0072-super1-refactor-the-code-for-enum.patch -Patch072: 0073-super-intel-refactor-the-code-for-enum.patch -Patch073: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch -Patch074: 0075-Manage-Incremental-code-refactor-string-to-enum.patch -Patch075: 0076-Change-char-to-enum-in-context-update-refactor-code.patch -Patch076: 0077-mdmon-fix-segfault.patch -Patch077: 0078-util-remove-obsolete-code-from-get_md_name.patch -Patch078: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch -Patch079: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch -Patch080: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch -Patch081: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch -Patch082: 0083-manage-move-comment-with-function-description.patch -Patch083: 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch -Patch084: 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch -Patch085: 0086-Fix-NULL-dereference-in-super_by_fd.patch -Patch086: 0087-Mdmonitor-Make-alert_info-global.patch -Patch087: 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch -Patch088: 0089-Mdmonitor-Add-helper-functions.patch -Patch089: 0090-Add-helpers-to-determine-whether-directories-or-file.patch -Patch090: 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch -Patch091: 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch -Patch092: 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch -Patch093: 0094-util.c-fix-memleak-in-parse_layout_faulty.patch -Patch094: 0095-Detail.c-fix-memleak-in-Detail.patch -Patch095: 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch -Patch096: 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch -Patch097: 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch -Patch098: 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch -Patch099: 0100-Create-remove-safe_mode_delay-local-variable.patch -Patch100: 0101-Create-Factor-out-add_disks-helpers.patch -Patch101: 0102-mdadm-Introduce-pr_info.patch -Patch102: 0103-mdadm-Add-write-zeros-option-for-Create.patch -Patch103: 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch -Patch104: 0105-manpage-Add-write-zeroes-option-to-manpage.patch -Patch105: 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch -Patch106: 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch -Patch107: 0108-mdmon-don-t-test-both-all-and-container_name.patch -Patch108: 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch -Patch109: 0110-mdmon-Remove-need-for-KillMode-none.patch -Patch110: 0111-mdmon-Improve-switchroot-interactions.patch -Patch111: 0112-mdopen-always-try-create_named_array.patch -Patch112: 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch -Patch113: 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch -Patch114: 0115-Create-Fix-checking-for-container-in-update_metadata.patch -Patch115: 0116-Fix-null-pointer-for-incremental-in-mdadm.patch -Patch116: 0117-super1-fix-truncation-check-for-journal-device.patch -Patch117: 0118-Fix-some-cases-eyesore-formatting.patch -Patch118: 0119-Bump-minimum-kernel-version-to-2.6.32.patch -Patch119: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch -Patch120: 0121-mdadm-define-DEV_MD_DIR.patch -Patch121: 0122-mdadm-define-DEV_NUM_PREF.patch -Patch122: 0123-mdadm-define-is_devname_ignore.patch -Patch123: 0124-mdadm-numbered-names-verification.patch -Patch124: 0125-enable-RAID-for-SATA-under-VMD.patch -Patch125: 0126-imsm-Fix-possible-segfault-in-check_no_platform.patch -Patch126: 0127-imsm-move-sum_extents-calculations-to-merge_extents.patch -Patch127: 0128-imsm-imsm_get_free_size-refactor.patch -Patch128: 0129-imsm-introduce-round_member_size_to_mb.patch -Patch129: 0130-imsm-move-expand-verification-code-into-new-function.patch -Patch130: 0131-imsm-return-free-space-after-volume-for-expand.patch -Patch131: 0132-imsm-fix-free-space-calculations.patch -Patch132: 0133-Add-secure-gethostname-wrapper.patch -Patch133: 0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch -Patch134: 0135-Fix-memory-leak-in-file-Assemble.patch -Patch135: 0136-Fix-memory-leak-in-file-Kill.patch -Patch136: 0137-Fix-memory-leak-in-file-Manage.patch -Patch137: 0138-Fix-memory-leak-in-file-mdadm.patch -Patch138: 0139-Fix-unsafe-string-functions.patch -Patch139: 0140-platform-intel-limit-guid-length.patch -Patch140: 0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch -Patch141: 0142-Add-compiler-defenses-flags.patch -Patch142: 0143-Assemble-fix-redundant-memory-free.patch -Patch143: 0144-tests-add-a-new-test-for-rdev-lifetime.patch -Patch144: 0145-tests-support-to-skip-checking-dmesg.patch -Patch145: 0146-tests-add-a-regression-test-for-raid10-deadlock.patch -Patch146: 0147-tests-add-a-regression-test-for-raid456-deadlock.patch -Patch147: 0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch -Patch148: 0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch -Patch149: 0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch -Patch150: 0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch -Patch151: 0152-tests-create-names_template.patch -Patch152: 0153-tests-create-00confnames.patch -Patch153: 0154-mdadm-set-ident.devname-if-applicable.patch -Patch154: 0155-mdadm-refactor-ident-name-handling.patch -Patch155: 0156-mdadm-define-ident_set_devname.patch -Patch156: 0157-mdadm-Follow-POSIX-Portable-Character-Set.patch -Patch157: 0158-Incremental-remove-obsoleted-calls-to-udisks.patch -Patch158: 0159-mdadm-tests-Fix-regular-expression-failure.patch -Patch159: 0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch -Patch160: 0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch -Patch161: 0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch -Patch162: 0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch -Patch163: 0164-mdadm-remove-container_enough-logic.patch -Patch164: 0165-Fix-assembling-RAID-volume-by-using-incremental.patch +Patch000: 0001-Remove-hardcoded-checkpoint-interval-checking.patch +Patch001: 0002-monitor-refactor-checkpoint-update.patch +Patch002: 0003-Super-intel-Fix-first-checkpoint-restart.patch +Patch003: 0004-Grow-Move-update_tail-assign-to-Grow_reshape.patch +Patch004: 0005-Add-understanding-output-section-in-man.patch +Patch005: 0006-Create-add_disk_to_super-fix-resource-leak.patch +Patch006: 0007-mdadm-signal_s-init-variables.patch +Patch007: 0008-Monitor-open-file-before-check-in-check_one_sharer.patch +Patch008: 0009-Grow-remove-dead-condition-in-Grow_reshape.patch +Patch009: 0010-super1-check-fd-before-passing-to-get_dev_size-in-ad.patch +Patch010: 0011-mdmon-refactor-md-device-name-check-in-main.patch +Patch011: 0012-test-run-tests-on-system-level-mdadm.patch +Patch012: 0013-Monitor-Allow-no-PID-in-check_one_sharer.patch +Patch013: 0014-super-intel-respect-IMSM_DEVNAME_AS_SERIAL-flag.patch +Patch014: 0015-mdadm-remove-TODO.patch +Patch015: 0016-mdadm-remove-makedist.patch +Patch016: 0017-mdadm-remove-mdadm.spec.patch +Patch017: 0018-mdadm-remove-mkinitramfs-stuff.patch +Patch018: 0019-mdadm-move-documentation-to-folder.patch +Patch019: 0020-Detail-remove-duplicated-code.patch +Patch020: 0021-mdadm-Add-functions-for-spare-criteria-verification.patch +Patch021: 0022-mdadm-drop-get_required_spare_criteria.patch +Patch022: 0023-Manage-fix-check-after-dereference-issue.patch +Patch023: 0024-Manage-implement-manage_add_external.patch +Patch024: 0025-mdadm-introduce-sysfs_get_container_devnm.patch +Patch025: 0026-mdadm.h-Introduce-custom-device-policies.patch +Patch026: 0027-mdadm-test_and_add-device-policies-implementation.patch +Patch027: 0028-Create-Use-device-policies.patch +Patch028: 0029-Manage-check-device-policies-in-manage_add_external.patch +Patch029: 0030-Monitor-Incremental-use-device-policies.patch +Patch030: 0031-imsm-test_and_add_device_policies-implementation.patch +Patch031: 0032-mdadm-drop-get_disk_controller_domain.patch +Patch032: 0033-Revert-policy.c-Avoid-to-take-spare-without-defined-.patch +Patch033: 0034-mdadm-remove-inventory-file.patch +Patch034: 0035-udev.c-Do-not-require-libudev.h-if-DNO_LIBUDEV.patch +Patch035: 0036-util.c-add-limits.h-include-for-NAME_MAX-definition.patch +Patch036: 0037-mdadm-set-swapuuid-in-all-handlers.patch +Patch037: 0038-mdadm-Fix-native-detail-export.patch +Patch038: 0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch +Patch039: 0040-mdadm-fix-grow-segfault-for-IMSM.patch +Patch040: 0041-Remove-all-if-zeros-pt.2.patch +Patch041: 0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch +Patch042: 0043-Add-reading-Opal-NVMe-encryption-information.patch +Patch043: 0044-Add-reading-SATA-encryption-information.patch +Patch044: 0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch +Patch045: 0046-imsm-print-disk-encryption-information.patch +Patch046: 0047-imsm-drive-encryption-policy-implementation.patch +Patch047: 0048-mdadm-add-CHANGELOG.md.patch +Patch048: 0049-mdadm-Add-MAINTAINERS.md.patch +Patch049: 0050-mdadm-Add-README.md.patch +Patch050: 0051-Create.c-fix-uclibc-build.patch +Patch051: 0052-mdadm-pass-struct-context-for-external-reshapes.patch +Patch052: 0053-mdadm-use-struct-context-in-reshape_super.patch +Patch053: 0054-imsm-add-support-for-literal-RAID-10.patch +Patch054: 0055-imsm-refactor-RAID-level-handling.patch +Patch055: 0056-imsm-bump-minimal-version.patch +Patch056: 0057-imsm-define-RAID_10-attribute.patch +Patch057: 0058-imsm-simplify-imsm_check_attributes.patch +Patch058: 0059-imsm-support-RAID-10-with-more-than-4-drives.patch +Patch059: 0060-tests-01r5fail-enhance.patch +Patch060: 0061-tests-01r5integ.broken.patch +Patch061: 0062-tests-01raid6integ.broken-can-be-removed.patch +Patch062: 0063-Makefile-Move-pie-to-LDFLAGS.patch +Patch063: 0064-tests-23rdev-lifetime-fix-a-typo.patch +Patch064: 0065-util.c-change-devnm-to-const-in-mdmon-functions.patch +Patch065: 0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch +Patch066: 0069-mdadm-Fix-compilation-for-32-bit-arch.patch +Patch067: 0070-Detail-fix-detail-export-for-uuid_zero.patch # Fedora customization patches @@ -249,7 +152,7 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d %files %license COPYING -%doc mdadm.conf-example misc/* +%doc documentation/mdadm.conf-example misc/* %{_udevrulesdir}/* %{_sbindir}/* %{_unitdir}/* @@ -262,6 +165,26 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d /usr/share/mdadm/mdcheck %changelog +* Sun Aug 11 2024 Xiao Ni 4.3-3 +- /dev/md symlink not created for second RAID container +- Resolves RHEL-50456 + +* Thu May 16 2024 Xiao Ni 4.3-2 +- Update to latest upstream +- Resolves RHEL-36424 + +* Fri Mar 29 2024 Xiao Ni 4.3-1 +- Update to 4.3 and to latest upstream +- Resolves RHEL-30529 + +* Wed Mar 20 2024 Xiao Ni 4.2-12 +- To fix errata/osci problems +- Resolves RHEL-26272 + +* Fri Mar 15 2024 Xiao Ni 4.2-11 +- revert "mdadm: remove container_enough logic" +- Resolves RHEL-26272 + * Fri Nov 3 2023 Xiao Ni - 4.2-10 - Update to latest upstream - Resolves RHEL-15386