commit 68bd8b7b71bb61f493fe88bc6a90c33ced04453d25525767366d238662dc9f28 Author: Adrian Schröter Date: Fri May 3 16:43:57 2024 +0200 Sync from SUSE:SLFO:Main mdadm revision 1e9e1822f9b0ebc631287e432535cf6e diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/0001-Unify-error-message.patch b/0001-Unify-error-message.patch new file mode 100644 index 0000000..5e4566c --- /dev/null +++ b/0001-Unify-error-message.patch @@ -0,0 +1,50 @@ +From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Tue, 15 Mar 2022 09:30:30 +0100 +Subject: [PATCH 01/61] Unify error message. +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Grow.c | 4 ++-- + super-intel.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 9c6fc95..9a94720 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 d5fad10..5ffa763 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.35.3 + diff --git a/0002-mdadm-Fix-double-free.patch b/0002-mdadm-Fix-double-free.patch new file mode 100644 index 0000000..b5471a1 --- /dev/null +++ b/0002-mdadm-Fix-double-free.patch @@ -0,0 +1,36 @@ +From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 25 Mar 2022 12:48:59 +0100 +Subject: [PATCH 02/61] mdadm: Fix double free +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-intel.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 5ffa763..6ff336e 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.35.3 + diff --git a/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch b/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch new file mode 100644 index 0000000..d83114c --- /dev/null +++ b/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch @@ -0,0 +1,86 @@ +From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 23 Mar 2022 15:05:19 +0100 +Subject: [PATCH 03/61] Grow_reshape: Add r0 grow size error message and update + man +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Grow.c | 6 ++++++ + mdadm.8.in | 19 ++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 9a94720..aa72490 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 be902db..e2a4242 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.35.3 + diff --git a/0004-udev-adapt-rules-to-systemd-v247.patch b/0004-udev-adapt-rules-to-systemd-v247.patch new file mode 100644 index 0000000..d98b756 --- /dev/null +++ b/0004-udev-adapt-rules-to-systemd-v247.patch @@ -0,0 +1,70 @@ +From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 14 Jan 2022 16:44:33 +0100 +Subject: [PATCH 04/61] udev: adapt rules to systemd v247 +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 13c9076..2967ace 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 d668cdd..39b4344 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 12bdcaa..2e185ce 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.35.3 + diff --git a/0005-Replace-error-prone-signal-with-sigaction.patch b/0005-Replace-error-prone-signal-with-sigaction.patch new file mode 100644 index 0000000..a60128a --- /dev/null +++ b/0005-Replace-error-prone-signal-with-sigaction.patch @@ -0,0 +1,255 @@ +From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Mon, 21 Feb 2022 13:05:20 +0100 +Subject: [PATCH 05/61] Replace error prone signal() with sigaction() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 aa72490..18c5719 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 30c031a..c0ab541 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 bb7334c..0e9bdf0 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 c7268a7..26e7e5c 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 c71e62c..5570574 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 e0d3be6..b877e59 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 7ea04c7..94c80c2 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 a8e6005..9947776 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 3d05d07..cc94f96 100644 +--- a/util.c ++++ b/util.c +@@ -35,7 +35,6 @@ + #include + #include + #include +-#include + #include + + +-- +2.35.3 + diff --git a/0006-mdadm-Respect-config-file-location-in-man.patch b/0006-mdadm-Respect-config-file-location-in-man.patch new file mode 100644 index 0000000..2b476d6 --- /dev/null +++ b/0006-mdadm-Respect-config-file-location-in-man.patch @@ -0,0 +1,126 @@ +From e9dd5644843e2013a7dd1a8a5da2b9fa35837416 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:04 +0100 +Subject: [PATCH 06/61] mdadm: Respect config file location in man +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + .gitignore | 1 + + Makefile | 7 ++++++- + mdadm.8.in | 16 ++++++++-------- + mdadm.conf.5 => mdadm.conf.5.in | 2 +- + 4 files changed, 16 insertions(+), 10 deletions(-) + rename mdadm.conf.5 => mdadm.conf.5.in (99%) + +diff --git a/.gitignore b/.gitignore +index 217fe76..8d791c6 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 2a51d81..bf12603 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 e2a4242..8b21ffd 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.in +similarity index 99% +rename from mdadm.conf.5 +rename to mdadm.conf.5.in +index 74a21c5..83edd00 100644 +--- a/mdadm.conf.5 ++++ b/mdadm.conf.5.in +@@ -8,7 +8,7 @@ + .SH NAME + mdadm.conf \- configuration for management of Software RAID with mdadm + .SH SYNOPSIS +-/etc/mdadm.conf ++{CONFFILE} + .SH DESCRIPTION + .PP + .I mdadm +-- +2.35.3 + diff --git a/0007-mdadm-Update-ReadMe.patch b/0007-mdadm-Update-ReadMe.patch new file mode 100644 index 0000000..ded0df7 --- /dev/null +++ b/0007-mdadm-Update-ReadMe.patch @@ -0,0 +1,50 @@ +From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:05 +0100 +Subject: [PATCH 07/61] mdadm: Update ReadMe +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 8139976..8f873c4 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.35.3 + diff --git a/0008-mdadm-Update-config-man-regarding-default-files-and-.patch b/0008-mdadm-Update-config-man-regarding-default-files-and-.patch new file mode 100644 index 0000000..b1e8ae5 --- /dev/null +++ b/0008-mdadm-Update-config-man-regarding-default-files-and-.patch @@ -0,0 +1,205 @@ +From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:06 +0100 +Subject: [PATCH 08/61] mdadm: Update config man regarding default files and + multi-keyword behavior +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 8b21ffd..0be02e4 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 83edd00..dd331a6 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.35.3 + diff --git a/0009-mdadm-Update-config-manual.patch b/0009-mdadm-Update-config-manual.patch new file mode 100644 index 0000000..abb1236 --- /dev/null +++ b/0009-mdadm-Update-config-manual.patch @@ -0,0 +1,47 @@ +From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 18 Mar 2022 09:26:07 +0100 +Subject: [PATCH 09/61] mdadm: Update config manual +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 dd331a6..cd4e6a9 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.35.3 + diff --git a/0010-Create-Build-use-default_layout.patch b/0010-Create-Build-use-default_layout.patch new file mode 100644 index 0000000..1d1cab6 --- /dev/null +++ b/0010-Create-Build-use-default_layout.patch @@ -0,0 +1,156 @@ +From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 20 Jan 2022 13:18:32 +0100 +Subject: [PATCH 10/61] Create, Build: use default_layout() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 962c2e3..8d6f6f5 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 0ff1922..9ea19de 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 26e7e5c..cd72e71 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.35.3 + diff --git a/0011-mdadm-add-map_num_s.patch b/0011-mdadm-add-map_num_s.patch new file mode 100644 index 0000000..65825a4 --- /dev/null +++ b/0011-mdadm-add-map_num_s.patch @@ -0,0 +1,385 @@ +From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Thu, 20 Jan 2022 13:18:33 +0100 +Subject: [PATCH 11/61] mdadm: add map_num_s() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 704b829..9eac9ce 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 9ea19de..c84c1ac 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 95d4cc7..ce7a844 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 18c5719..8a242b0 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 23fbf8a..adcd231 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 a4fd279..20fcf71 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 26299b2..be40686 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 cd72e71..09915a0 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 3f304cd..8cda23a 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 6ff336e..ba3bd41 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 b79b97a..61c9ec1 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 a12a5bc..e3e2f95 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 2995713..0d98a65 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.35.3 + diff --git a/0012-mdmon-Stop-parsing-duplicate-options.patch b/0012-mdmon-Stop-parsing-duplicate-options.patch new file mode 100644 index 0000000..a340eb6 --- /dev/null +++ b/0012-mdmon-Stop-parsing-duplicate-options.patch @@ -0,0 +1,125 @@ +From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 13 May 2022 09:19:42 +0200 +Subject: [PATCH 13/61] mdmon: Stop parsing duplicate options +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + mdmon.c | 44 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 9 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 5570574..c057da6 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.35.3 + diff --git a/0013-Grow-block-n-on-external-volumes.patch b/0013-Grow-block-n-on-external-volumes.patch new file mode 100644 index 0000000..c45e532 --- /dev/null +++ b/0013-Grow-block-n-on-external-volumes.patch @@ -0,0 +1,44 @@ +From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 19 May 2022 09:16:08 +0200 +Subject: [PATCH 14/61] Grow: block -n on external volumes. +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Grow.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/Grow.c b/Grow.c +index 8a242b0..f6efbc4 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.35.3 + diff --git a/0014-Incremental-Fix-possible-memory-and-resource-leaks.patch b/0014-Incremental-Fix-possible-memory-and-resource-leaks.patch new file mode 100644 index 0000000..85dac52 --- /dev/null +++ b/0014-Incremental-Fix-possible-memory-and-resource-leaks.patch @@ -0,0 +1,93 @@ +From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 12:11:25 +0200 +Subject: [PATCH 15/61] Incremental: Fix possible memory and resource leaks +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Incremental.c | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index a57fc32..4d0cd9d 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.35.3 + diff --git a/0015-Mdmonitor-Fix-segfault.patch b/0015-Mdmonitor-Fix-segfault.patch new file mode 100644 index 0000000..e370091 --- /dev/null +++ b/0015-Mdmonitor-Fix-segfault.patch @@ -0,0 +1,101 @@ +From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Mon, 6 Jun 2022 12:32:12 +0200 +Subject: [PATCH 16/61] Mdmonitor: Fix segfault +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 c0ab541..4e5802b 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 09915a0..d53df16 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 245be53..d18c931 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.35.3 + diff --git a/0016-Mdmonitor-Improve-logging-method.patch b/0016-Mdmonitor-Improve-logging-method.patch new file mode 100644 index 0000000..6893ed3 --- /dev/null +++ b/0016-Mdmonitor-Improve-logging-method.patch @@ -0,0 +1,64 @@ +From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Mon, 6 Jun 2022 12:32:13 +0200 +Subject: [PATCH 17/61] Mdmonitor: Improve logging method +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Monitor.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 4e5802b..6ca1ebe 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.35.3 + diff --git a/0017-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/0017-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch new file mode 100644 index 0000000..4962ca4 --- /dev/null +++ b/0017-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch @@ -0,0 +1,76 @@ +From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 11:59:34 +0200 +Subject: [PATCH 18/61] Fix possible NULL ptr dereferences and memory leaks +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Assemble.c | 7 ++++++- + super-ddf.c | 9 +++++++-- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9eac9ce..4b21356 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 8cda23a..abbc8b0 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.35.3 + diff --git a/0018-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch b/0018-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch new file mode 100644 index 0000000..9e4cb8d --- /dev/null +++ b/0018-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch @@ -0,0 +1,304 @@ +From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Mon, 13 Jun 2022 12:00:09 +0200 +Subject: [PATCH 19/61] imsm: Remove possibility for get_imsm_dev to return + NULL +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-intel.c | 153 +++++++++++++++++++++++++------------------------- + 1 file changed, 78 insertions(+), 75 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index ba3bd41..3788feb 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.35.3 + diff --git a/0019-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch b/0019-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch new file mode 100644 index 0000000..860866a --- /dev/null +++ b/0019-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch @@ -0,0 +1,87 @@ +From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 18 Apr 2022 13:44:23 -0400 +Subject: [PATCH 20/61] Revert "mdadm: fix coredump of mdadm --monitor -r" +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 8f873c4..bec1be9 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.35.3 + diff --git a/0020-util-replace-ioctl-use-with-function.patch b/0020-util-replace-ioctl-use-with-function.patch new file mode 100644 index 0000000..7651040 --- /dev/null +++ b/0020-util-replace-ioctl-use-with-function.patch @@ -0,0 +1,33 @@ +From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 21 Jun 2022 00:10:39 +0800 +Subject: [PATCH 21/61] util: replace ioctl use with function +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 cc94f96..38f0420 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.35.3 + diff --git a/0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch b/0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch new file mode 100644 index 0000000..4bc6f21 --- /dev/null +++ b/0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch @@ -0,0 +1,112 @@ +From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Tue, 21 Jun 2022 00:10:40 +0800 +Subject: [PATCH 22/61] mdadm/super1: restore commit 45a87c2f31335 to fix + clustered slot issue +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 e3e2f95..3a0c69f 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.35.3 + diff --git a/0022-imsm-introduce-get_disk_slot_in_dev.patch b/0022-imsm-introduce-get_disk_slot_in_dev.patch new file mode 100644 index 0000000..9251f74 --- /dev/null +++ b/0022-imsm-introduce-get_disk_slot_in_dev.patch @@ -0,0 +1,124 @@ +From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:41 +0800 +Subject: [PATCH 23/61] imsm: introduce get_disk_slot_in_dev() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 3788feb..cd1f1e3 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.35.3 + diff --git a/0023-imsm-use-same-slot-across-container.patch b/0023-imsm-use-same-slot-across-container.patch new file mode 100644 index 0000000..d500e01 --- /dev/null +++ b/0023-imsm-use-same-slot-across-container.patch @@ -0,0 +1,254 @@ +From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:42 +0800 +Subject: [PATCH 24/61] imsm: use same slot across container +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 cd1f1e3..deef7c8 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.35.3 + diff --git a/0024-imsm-block-changing-slots-during-creation.patch b/0024-imsm-block-changing-slots-during-creation.patch new file mode 100644 index 0000000..f2398eb --- /dev/null +++ b/0024-imsm-block-changing-slots-during-creation.patch @@ -0,0 +1,124 @@ +From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 21 Jun 2022 00:10:43 +0800 +Subject: [PATCH 25/61] imsm: block changing slots during creation +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 deef7c8..8ffe485 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 ff5d209..0000000 +--- 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.35.3 + diff --git a/0025-mdadm-block-update-ppl-for-non-raid456-levels.patch b/0025-mdadm-block-update-ppl-for-non-raid456-levels.patch new file mode 100644 index 0000000..c4a6f8a --- /dev/null +++ b/0025-mdadm-block-update-ppl-for-non-raid456-levels.patch @@ -0,0 +1,180 @@ +From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Wed, 15 Jun 2022 14:28:39 +0200 +Subject: [PATCH 26/61] mdadm: block update=ppl for non raid456 levels +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 4b21356..6df6bfb 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 f6efbc4..8c520d4 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 f789e0c..e5e6abe 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 d53df16..974415b 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 61c9ec1..37f595e 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 3a0c69f..71af860 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.35.3 + diff --git a/0026-mdadm-Fix-array-size-mismatch-after-grow.patch b/0026-mdadm-Fix-array-size-mismatch-after-grow.patch new file mode 100644 index 0000000..5cd9368 --- /dev/null +++ b/0026-mdadm-Fix-array-size-mismatch-after-grow.patch @@ -0,0 +1,33 @@ +From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 22 Jul 2022 08:43:47 +0200 +Subject: [PATCH 27/61] mdadm: Fix array size mismatch after grow +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-intel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index 8ffe485..76b947f 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.35.3 + diff --git a/0027-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch b/0027-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch new file mode 100644 index 0000000..73d448e --- /dev/null +++ b/0027-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch @@ -0,0 +1,37 @@ +From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Fri, 22 Jul 2022 08:43:48 +0200 +Subject: [PATCH 28/61] mdadm: Remove dead code in imsm_fix_size_mismatch +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-intel.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 76b947f..4ddfcf9 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.35.3 + diff --git a/0028-Monitor-use-devname-as-char-array-instead-of-pointer.patch b/0028-Monitor-use-devname-as-char-array-instead-of-pointer.patch new file mode 100644 index 0000000..bda2ee2 --- /dev/null +++ b/0028-Monitor-use-devname-as-char-array-instead-of-pointer.patch @@ -0,0 +1,43 @@ +From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 14 Jul 2022 09:02:10 +0200 +Subject: [PATCH 29/61] Monitor: use devname as char array instead of pointer +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Monitor.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 6ca1ebe..a5b11ae 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.35.3 + diff --git a/0029-Monitor-use-snprintf-to-fill-device-name.patch b/0029-Monitor-use-snprintf-to-fill-device-name.patch new file mode 100644 index 0000000..ff5a84b --- /dev/null +++ b/0029-Monitor-use-snprintf-to-fill-device-name.patch @@ -0,0 +1,136 @@ +From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 14 Jul 2022 09:02:11 +0200 +Subject: [PATCH 30/61] Monitor: use snprintf to fill device name +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +Safe string functions are propagated in Monitor.c. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +Signed-off-by: Coly Li +--- + Monitor.c | 37 ++++++++++++++----------------------- + 1 file changed, 14 insertions(+), 23 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index a5b11ae..93f36ac 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.35.3 + diff --git a/0030-Makefile-Don-t-build-static-build-with-everything-an.patch b/0030-Makefile-Don-t-build-static-build-with-everything-an.patch new file mode 100644 index 0000000..bfb0253 --- /dev/null +++ b/0030-Makefile-Don-t-build-static-build-with-everything-an.patch @@ -0,0 +1,45 @@ +From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:06 -0600 +Subject: [PATCH 31/61] Makefile: Don't build static build with everything and + everything-test +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index bf12603..ec1f99e 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.35.3 + diff --git a/0031-DDF-Cleanup-validate_geometry_ddf_container.patch b/0031-DDF-Cleanup-validate_geometry_ddf_container.patch new file mode 100644 index 0000000..92cd6c7 --- /dev/null +++ b/0031-DDF-Cleanup-validate_geometry_ddf_container.patch @@ -0,0 +1,144 @@ +From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:07 -0600 +Subject: [PATCH 32/61] DDF: Cleanup validate_geometry_ddf_container() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-ddf.c | 88 ++++++++++++++++++++++++----------------------------- + 1 file changed, 39 insertions(+), 49 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index abbc8b0..9d867f6 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.35.3 + diff --git a/0032-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch b/0032-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch new file mode 100644 index 0000000..680c642 --- /dev/null +++ b/0032-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch @@ -0,0 +1,52 @@ +From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:08 -0600 +Subject: [PATCH 33/61] DDF: Fix NULL pointer dereference in + validate_geometry_ddf() +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super-ddf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 9d867f6..949e7d1 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.35.3 + diff --git a/0033-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch b/0033-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch new file mode 100644 index 0000000..0715e29 --- /dev/null +++ b/0033-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch @@ -0,0 +1,88 @@ +From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:09 -0600 +Subject: [PATCH 34/61] mdadm/Grow: Fix use after close bug by closing after + fork +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Grow.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 8c520d4..97f22c7 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.35.3 + diff --git a/0034-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch b/0034-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch new file mode 100644 index 0000000..2014ed1 --- /dev/null +++ b/0034-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch @@ -0,0 +1,39 @@ +From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:10 -0600 +Subject: [PATCH 35/61] monitor: Avoid segfault when calling NULL + get_bad_blocks +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + monitor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/monitor.c b/monitor.c +index b877e59..820a93d 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.35.3 + diff --git a/0035-mdadm-Fix-mdadm-r-remove-option-regression.patch b/0035-mdadm-Fix-mdadm-r-remove-option-regression.patch new file mode 100644 index 0000000..2656212 --- /dev/null +++ b/0035-mdadm-Fix-mdadm-r-remove-option-regression.patch @@ -0,0 +1,81 @@ +From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:11 -0600 +Subject: [PATCH 36/61] mdadm: Fix mdadm -r remove option regression +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + ReadMe.c | 1 + + mdadm.c | 1 + + mdadm.h | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/ReadMe.c b/ReadMe.c +index bec1be9..7518a32 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 be40686..d0c5e6d 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 974415b..163f4a4 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.35.3 + diff --git a/0036-mdadm-Fix-optional-write-behind-parameter.patch b/0036-mdadm-Fix-optional-write-behind-parameter.patch new file mode 100644 index 0000000..502174b --- /dev/null +++ b/0036-mdadm-Fix-optional-write-behind-parameter.patch @@ -0,0 +1,45 @@ +From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 22 Jun 2022 14:25:12 -0600 +Subject: [PATCH 37/61] mdadm: Fix optional --write-behind parameter +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + mdadm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index d0c5e6d..56722ed 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.35.3 + diff --git a/0037-mdadm-Replace-obsolete-usleep-with-nanosleep.patch b/0037-mdadm-Replace-obsolete-usleep-with-nanosleep.patch new file mode 100644 index 0000000..99e2f22 --- /dev/null +++ b/0037-mdadm-Replace-obsolete-usleep-with-nanosleep.patch @@ -0,0 +1,319 @@ +From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Fri, 12 Aug 2022 16:36:02 +0200 +Subject: [PATCH 45/61] mdadm: Replace obsolete usleep with nanosleep +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 6df6bfb..be2160b 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 97f22c7..5780635 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 e5e6abe..a142f8b 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 0e9bdf0..a7bfa8f 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 163f4a4..add9c0b 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 c057da6..e9d035e 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 4ddfcf9..4d82af3 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 38f0420..ca48d97 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.35.3 + diff --git a/0038-mdadm-remove-symlink-option.patch b/0038-mdadm-remove-symlink-option.patch new file mode 100644 index 0000000..a12dff2 --- /dev/null +++ b/0038-mdadm-remove-symlink-option.patch @@ -0,0 +1,179 @@ +From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 19 Jul 2022 14:48:22 +0200 +Subject: [PATCH 48/61] mdadm: remove symlink option +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +The option is not used. Remove it from code. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +Signed-off-by: Coly Li +--- + 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 7518a32..7f94847 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 9c72545..dc1620c 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 0be02e4..f273622 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 56722ed..180f7a9 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 cd4e6a9..bc2295c 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 add9c0b..93e7278 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.35.3 + diff --git a/0039-mdadm-move-data_offset-to-struct-shape.patch b/0039-mdadm-move-data_offset-to-struct-shape.patch new file mode 100644 index 0000000..f4fd958 --- /dev/null +++ b/0039-mdadm-move-data_offset-to-struct-shape.patch @@ -0,0 +1,235 @@ +From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 19 Jul 2022 14:48:23 +0200 +Subject: [PATCH 49/61] mdadm: move data_offset to struct shape +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 c84c1ac..e06ec2a 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 5780635..868bdc3 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 180f7a9..845e446 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 93e7278..adb7cda 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.35.3 + diff --git a/0040-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/0040-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch new file mode 100644 index 0000000..554a5b4 --- /dev/null +++ b/0040-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch @@ -0,0 +1,165 @@ +From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 27 Jul 2022 15:52:46 -0600 +Subject: [PATCH 50/61] mdadm: Don't open md device for CREATE and ASSEMBLE +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + 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 7e3e3d4..e395b28 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 845e446..972adb5 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 adb7cda..8208b81 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.35.3 + diff --git a/0041-Grow-Split-Grow_reshape-into-helper-function.patch b/0041-Grow-Split-Grow_reshape-into-helper-function.patch new file mode 100644 index 0000000..98af135 --- /dev/null +++ b/0041-Grow-Split-Grow_reshape-into-helper-function.patch @@ -0,0 +1,233 @@ +From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 28 Jul 2022 20:20:53 +0800 +Subject: [PATCH 51/61] Grow: Split Grow_reshape into helper function +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 868bdc3..0f07a89 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 8208b81..941a5f3 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 ca48d97..26ffdce 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.35.3 + diff --git a/0042-Assemble-check-if-device-is-container-before-schedul.patch b/0042-Assemble-check-if-device-is-container-before-schedul.patch new file mode 100644 index 0000000..e264894 --- /dev/null +++ b/0042-Assemble-check-if-device-is-container-before-schedul.patch @@ -0,0 +1,39 @@ +From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 19 Aug 2022 02:55:46 +0200 +Subject: [PATCH 52/61] Assemble: check if device is container before + scheduling force-clean update +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Assemble.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index be2160b..1dd82a8 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.35.3 + diff --git a/0043-super1-report-truncated-device.patch b/0043-super1-report-truncated-device.patch new file mode 100644 index 0000000..c787f8c --- /dev/null +++ b/0043-super1-report-truncated-device.patch @@ -0,0 +1,115 @@ +From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 26 Aug 2022 08:55:56 +1000 +Subject: [PATCH 53/61] super1: report truncated device +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + super1.c | 35 ++++++++++++++++++++++++++++------- + 1 file changed, 28 insertions(+), 7 deletions(-) + +diff --git a/super1.c b/super1.c +index 71af860..58345e6 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.35.3 + diff --git a/0044-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch b/0044-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch new file mode 100644 index 0000000..49ae568 --- /dev/null +++ b/0044-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch @@ -0,0 +1,619 @@ +From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Fri, 12 Aug 2022 16:52:12 +0200 +Subject: [PATCH 54/61] mdadm: Correct typos, punctuation and grammar in man +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +Signed-off-by: Mateusz Grzonka +Reviewed-by: Wol +Signed-off-by: Jes Sorensen +Signed-off-by: Coly Li +--- + mdadm.8.in | 178 ++++++++++++++++++++++++++--------------------------- + 1 file changed, 88 insertions(+), 90 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index f273622..70c79d1 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.35.3 + diff --git a/0046-Monitor-Fix-statelist-memory-leaks.patch b/0046-Monitor-Fix-statelist-memory-leaks.patch new file mode 100644 index 0000000..a5e5d52 --- /dev/null +++ b/0046-Monitor-Fix-statelist-memory-leaks.patch @@ -0,0 +1,115 @@ +From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 1 Sep 2022 11:20:31 +0200 +Subject: [PATCH 56/61] Monitor: Fix statelist memory leaks +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +Free statelist in error path in Monitor initialization. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +Signed-off-by: Coly Li +--- + Monitor.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 93f36ac..b4e954c 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.35.3 + diff --git a/0047-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch b/0047-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch new file mode 100644 index 0000000..5af8585 --- /dev/null +++ b/0047-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch @@ -0,0 +1,64 @@ +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/61] mdadm: added support for Intel Alderlake RST on VMD + platform +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + platform-intel.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 5a8729e..757f0b1 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.35.3 + diff --git a/0048-mdadm-Add-Documentation-entries-to-systemd-services.patch b/0048-mdadm-Add-Documentation-entries-to-systemd-services.patch new file mode 100644 index 0000000..dac59b6 --- /dev/null +++ b/0048-mdadm-Add-Documentation-entries-to-systemd-services.patch @@ -0,0 +1,113 @@ +From ea109700563d93704ebdc540c7770d874369f667 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 9 Sep 2022 15:50:33 +0200 +Subject: [PATCH 58/61] mdadm: Add Documentation entries to systemd services +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 9fdc8ec..64b8254 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 efeb3f6..e938112 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 854317f..f532490 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 3bb3d13..703a658 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 7753395..97a1acd 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 373955a..ba86b44 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 46f7b88..9c36478 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.35.3 + diff --git a/0049-ReadMe-fix-command-line-help.patch b/0049-ReadMe-fix-command-line-help.patch new file mode 100644 index 0000000..46b628b --- /dev/null +++ b/0049-ReadMe-fix-command-line-help.patch @@ -0,0 +1,34 @@ +From f7cbd810b639eb946ba1b3bddb1faefb9696de42 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 9 Sep 2022 15:50:34 +0200 +Subject: [PATCH 59/61] ReadMe: fix command-line help +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 7f94847..50a5e36 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.35.3 + diff --git a/0050-mdadm-replace-container-level-checking-with-inline.patch b/0050-mdadm-replace-container-level-checking-with-inline.patch new file mode 100644 index 0000000..978691a --- /dev/null +++ b/0050-mdadm-replace-container-level-checking-with-inline.patch @@ -0,0 +1,259 @@ +From 6f2af6a48c541f207cb727a31fb86de2cd04fc21 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 2 Sep 2022 08:49:23 +0200 +Subject: [PATCH 60/61] mdadm: replace container level checking with inline +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 1dd82a8..8b0af0c 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 e06ec2a..953e737 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 0f07a89..e362403 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 4d0cd9d..5a5f4c4 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 941a5f3..3673494 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 949e7d1..9d1e3b9 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 4d82af3..b056561 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 37f595e..93876e2 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 58345e6..0b505a7 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 0d98a65..ca1d888 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.35.3 + diff --git a/0051-Mdmonitor-Omit-non-md-devices.patch b/0051-Mdmonitor-Omit-non-md-devices.patch new file mode 100644 index 0000000..44a1c98 --- /dev/null +++ b/0051-Mdmonitor-Omit-non-md-devices.patch @@ -0,0 +1,61 @@ +From 8b668d4aa3305af5963162b7499b128bd71f8f29 Mon Sep 17 00:00:00 2001 +From: Lukasz Florczak +Date: Thu, 22 Sep 2022 08:29:50 +0200 +Subject: [PATCH 61/61] Mdmonitor: Omit non-md devices +Patch-mainline: mdadm-4.2+ +References: jsc#PED-1009 + +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 +Signed-off-by: Coly Li +--- + Monitor.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index b4e954c..7d7dc4d 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.35.3 + diff --git a/0052-mdmon-fix-segfault.patch b/0052-mdmon-fix-segfault.patch new file mode 100644 index 0000000..306bb61 --- /dev/null +++ b/0052-mdmon-fix-segfault.patch @@ -0,0 +1,87 @@ +From 9b429fc0a4ffd7028b3b336589d38e32fb9045dc Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:46:21 +0100 +Subject: [PATCH] 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 +Signed-off-by: Coly Li +--- + Makefile | 2 +- + mdmon.c | 26 ++++++++++++-------------- + 2 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/Makefile b/Makefile +index ec1f99e..5eac1a4 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 e9d035e..ecf52dc 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.35.3 + diff --git a/0053-util-remove-obsolete-code-from-get_md_name.patch b/0053-util-remove-obsolete-code-from-get_md_name.patch new file mode 100644 index 0000000..1114b2c --- /dev/null +++ b/0053-util-remove-obsolete-code-from-get_md_name.patch @@ -0,0 +1,117 @@ +From b938519e7719c992dae2d61c796c45fe49e6b71b Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:46:22 +0100 +Subject: [PATCH] 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 +Signed-off-by: Coly Li +--- + mdmon.c | 8 +++----- + util.c | 51 +++++++++++++++++---------------------------------- + 2 files changed, 20 insertions(+), 39 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index ecf52dc..60ba318 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 26ffdce..9cd89fa 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.35.3 + diff --git a/0054-mdmon-don-t-test-both-all-and-container_name.patch b/0054-mdmon-don-t-test-both-all-and-container_name.patch new file mode 100644 index 0000000..e714da2 --- /dev/null +++ b/0054-mdmon-don-t-test-both-all-and-container_name.patch @@ -0,0 +1,47 @@ +From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH] 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 60ba318..f8fd2f0 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.35.3 + diff --git a/0055-mdmon-change-systemd-unit-file-to-use-foreground.patch b/0055-mdmon-change-systemd-unit-file-to-use-foreground.patch new file mode 100644 index 0000000..327e56e --- /dev/null +++ b/0055-mdmon-change-systemd-unit-file-to-use-foreground.patch @@ -0,0 +1,33 @@ +From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH] 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 cb6482d..bba9b0e 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.35.3 + diff --git a/0056-mdmon-Remove-need-for-KillMode-none.patch b/0056-mdmon-Remove-need-for-KillMode-none.patch new file mode 100644 index 0000000..2845158 --- /dev/null +++ b/0056-mdmon-Remove-need-for-KillMode-none.patch @@ -0,0 +1,55 @@ +From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH] 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 bba9b0e..303ad05 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.35.3 + diff --git a/0057-mdmon-Improve-switchroot-interactions.patch b/0057-mdmon-Improve-switchroot-interactions.patch new file mode 100644 index 0000000..f01ffaa --- /dev/null +++ b/0057-mdmon-Improve-switchroot-interactions.patch @@ -0,0 +1,163 @@ +From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH] 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(-) + +Index: mdadm-4.2/Grow.c +=================================================================== +--- mdadm-4.2.orig/Grow.c ++++ mdadm-4.2/Grow.c +@@ -3513,7 +3513,7 @@ started: + + if (!forked) + if (continue_via_systemd(container ?: sra->sys_name, +- GROW_SERVICE)) { ++ GROW_SERVICE, NULL)) { + free(fdlist); + free(offsets); + sysfs_free(sra); +@@ -3711,7 +3711,7 @@ int reshape_container(char *container, c + 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()) { +Index: mdadm-4.2/mdadm.h +=================================================================== +--- mdadm-4.2.orig/mdadm.h ++++ mdadm-4.2/mdadm.h +@@ -1550,7 +1550,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 int parse_auto(char *str, char *msg, int config); + extern struct mddev_ident *conf_get_ident(char *dev); +Index: mdadm-4.2/mdmon.c +=================================================================== +--- mdadm-4.2.orig/mdmon.c ++++ mdadm-4.2/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; + } +Index: mdadm-4.2/systemd/mdmon@.service +=================================================================== +--- mdadm-4.2.orig/systemd/mdmon@.service ++++ mdadm-4.2/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) +Index: mdadm-4.2/udev-md-raid-arrays.rules +=================================================================== +--- mdadm-4.2.orig/udev-md-raid-arrays.rules ++++ mdadm-4.2/udev-md-raid-arrays.rules +@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD + + # 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" +Index: mdadm-4.2/util.c +=================================================================== +--- mdadm-4.2.orig/util.c ++++ mdadm-4.2/util.c +@@ -1906,6 +1906,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, +@@ -1916,7 +1917,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 */ +@@ -2187,7 +2188,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]; +@@ -2199,7 +2200,7 @@ int continue_via_systemd(char *devnm, ch + 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", diff --git a/0058-mdopen-always-try-create_named_array.patch b/0058-mdopen-always-try-create_named_array.patch new file mode 100644 index 0000000..f7f2d31 --- /dev/null +++ b/0058-mdopen-always-try-create_named_array.patch @@ -0,0 +1,40 @@ +From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 14 Mar 2023 11:06:25 +1100 +Subject: [PATCH] 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 d18c931..810f79a 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.35.3 + diff --git a/0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch b/0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch new file mode 100644 index 0000000..d7d244a --- /dev/null +++ b/0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch @@ -0,0 +1,172 @@ +From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 20 Mar 2023 14:43:54 +1100 +Subject: [PATCH] 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 6f0f6c1..b715950 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 1e51827..0d99544 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 096b4d7..cef5bbc 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 e155a8a..a5c86cb 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 23a375f..020cc7e 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.35.3 + diff --git a/0060-Grow-fix-possible-memory-leak.patch b/0060-Grow-fix-possible-memory-leak.patch new file mode 100644 index 0000000..a6fde80 --- /dev/null +++ b/0060-Grow-fix-possible-memory-leak.patch @@ -0,0 +1,42 @@ +From 434b3b9bb96a76dc12f693b64cf23b581781e20b Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Tue, 20 Dec 2022 12:07:51 +0100 +Subject: [PATCH] Grow: fix possible memory leak. +Git-commit: 434b3b9bb96a76dc12f693b64cf23b581781e20b +Patch-mainline: mdadm-4.2+ +References: bsc#1208618 + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +Signed-off-by: Coly Li +--- + Grow.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index e362403..b73ec2a 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.35.3 + diff --git a/0061-Grow-fix-can-t-change-bitmap-type-from-none-to-clustered.patch b/0061-Grow-fix-can-t-change-bitmap-type-from-none-to-clustered.patch new file mode 100644 index 0000000..2213e5f --- /dev/null +++ b/0061-Grow-fix-can-t-change-bitmap-type-from-none-to-clustered.patch @@ -0,0 +1,47 @@ +From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001 +From: Heming Zhao +Date: Thu, 23 Feb 2023 22:39:39 +0800 +Subject: [PATCH] Grow: fix can't change bitmap type from none to clustered. +Git-commit: d07e561810a2e33b667a8a9476edaff42eb119b9 +Patch-mainline: mdadm-4.2+ +References: bsc#1208618 + +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 8f5cf07..bb5fe45 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.35.3 + diff --git a/0062-Manage-Block-unsafe-member-failing.patch b/0062-Manage-Block-unsafe-member-failing.patch new file mode 100644 index 0000000..efac5bc --- /dev/null +++ b/0062-Manage-Block-unsafe-member-failing.patch @@ -0,0 +1,91 @@ +From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 18 Aug 2022 11:47:21 +0200 +Subject: [PATCH] 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 a142f8b..b1d0e63 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.35.3 + diff --git a/0063-Mdmonitor-Split-alert-into-separate-functions.patch b/0063-Mdmonitor-Split-alert-into-separate-functions.patch new file mode 100644 index 0000000..bc39426 --- /dev/null +++ b/0063-Mdmonitor-Split-alert-into-separate-functions.patch @@ -0,0 +1,233 @@ +From 3698867194f27fdd7824b8bdd172d619a2c087cc Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Wed, 7 Sep 2022 14:56:49 +0200 +Subject: [PATCH] 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 7d7dc4d..0036e8c 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.35.3 + diff --git a/0064-Monitor-block-if-monitor-modes-are-combined.patch b/0064-Monitor-block-if-monitor-modes-are-combined.patch new file mode 100644 index 0000000..241a5bd --- /dev/null +++ b/0064-Monitor-block-if-monitor-modes-are-combined.patch @@ -0,0 +1,41 @@ +From f40ac0e7e6043361ad12e9db97c07e56c3977cf6 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 19 Dec 2022 11:21:57 +0100 +Subject: [PATCH] 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 0036e8c..188cb8b 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.35.3 + diff --git a/0065-Update-mdadm-Monitor-manual.patch b/0065-Update-mdadm-Monitor-manual.patch new file mode 100644 index 0000000..317c90d --- /dev/null +++ b/0065-Update-mdadm-Monitor-manual.patch @@ -0,0 +1,119 @@ +From 725e37cd14866906ba28c970394b9f7a4cd97413 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 19 Dec 2022 11:21:58 +0100 +Subject: [PATCH] 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 70c79d1..64f71ed 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.35.3 + diff --git a/0066-mdadm-create-ident_init.patch b/0066-mdadm-create-ident_init.patch new file mode 100644 index 0000000..6a72044 --- /dev/null +++ b/0066-mdadm-create-ident_init.patch @@ -0,0 +1,145 @@ +From 7fcbfd7c620e2dcd3b539d18e93cb503ee3a8a62 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 21 Dec 2022 12:50:17 +0100 +Subject: [PATCH] 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(-) + +Index: mdadm-4.2/config.c +=================================================================== +--- mdadm-4.2.orig/config.c ++++ mdadm-4.2/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) { +Index: mdadm-4.2/mdadm.c +=================================================================== +--- mdadm-4.2.orig/mdadm.c ++++ mdadm-4.2/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) { +Index: mdadm-4.2/mdadm.h +=================================================================== +--- mdadm-4.2.orig/mdadm.h ++++ mdadm-4.2/mdadm.h +@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, + # endif + #endif + ++#include + #include + #include ++#include + #include + #include + #include +@@ -1554,6 +1556,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, char *prefix); + ++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); +@@ -1781,8 +1785,7 @@ static inline sighandler_t signal_s(int + #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; diff --git a/0067-mdadm-Add-option-validation-for-update-subarray.patch b/0067-mdadm-Add-option-validation-for-update-subarray.patch new file mode 100644 index 0000000..4e3e369 --- /dev/null +++ b/0067-mdadm-Add-option-validation-for-update-subarray.patch @@ -0,0 +1,287 @@ +From 2568ce89ea5c26225e8984733adc2ea7559d853a Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:15 +0100 +Subject: [PATCH] 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 50a5e36..bd8d50d 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 20fcf71..b586679 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 74fdec3..f5f505f 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 23ffe97..51f1db2 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.35.3 + diff --git a/0068-Fix-update-subarray-on-active-volume.patch b/0068-Fix-update-subarray-on-active-volume.patch new file mode 100644 index 0000000..48de504 --- /dev/null +++ b/0068-Fix-update-subarray-on-active-volume.patch @@ -0,0 +1,54 @@ +From db10eab68e652f141169b7240e057d110d626c3d Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:16 +0100 +Subject: [PATCH] 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 b1d0e63..5a9ea31 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 b056561..5f93f3d 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.35.3 + diff --git a/0069-Add-code-specific-update-options-to-enum.patch b/0069-Add-code-specific-update-options-to-enum.patch new file mode 100644 index 0000000..6be3821 --- /dev/null +++ b/0069-Add-code-specific-update-options-to-enum.patch @@ -0,0 +1,77 @@ +From 2257de106cbf17a7f1df33a10cfd2be0d5a064cb Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:17 +0100 +Subject: [PATCH] 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 b586679..c59036f 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 51f1db2..31db25f 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.35.3 + diff --git a/0070-super-ddf-Remove-update_super_ddf.patch b/0070-super-ddf-Remove-update_super_ddf.patch new file mode 100644 index 0000000..f493f9d --- /dev/null +++ b/0070-super-ddf-Remove-update_super_ddf.patch @@ -0,0 +1,106 @@ +From 35aa44c549290e22f285896684c704acb53b7717 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:18 +0100 +Subject: [PATCH] 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 9d1e3b9..309812d 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.35.3 + diff --git a/0071-super0-refactor-the-code-for-enum.patch b/0071-super0-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..66f504a --- /dev/null +++ b/0071-super0-refactor-the-code-for-enum.patch @@ -0,0 +1,212 @@ +From 0a9e39383d3bf63e1f5cf10f64200083a1af8091 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:19 +0100 +Subject: [PATCH] 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 93876e2..d9f5bff 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.35.3 + diff --git a/0072-super1-refactor-the-code-for-enum.patch b/0072-super1-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..266b7f0 --- /dev/null +++ b/0072-super1-refactor-the-code-for-enum.patch @@ -0,0 +1,302 @@ +From 7e8daba8b7937716dce8ea28298a4e2e72cb829e Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:20 +0100 +Subject: [PATCH] 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 0b505a7..b0a9701 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.35.3 + diff --git a/0073-super-intel-refactor-the-code-for-enum.patch b/0073-super-intel-refactor-the-code-for-enum.patch new file mode 100644 index 0000000..787e28a --- /dev/null +++ b/0073-super-intel-refactor-the-code-for-enum.patch @@ -0,0 +1,106 @@ +From 4345e135c4c7dd04bb15bad140dfc4747f677738 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:21 +0100 +Subject: [PATCH] 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 5f93f3d..85fb7f1 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.35.3 + diff --git a/0074-Change-update-to-enum-in-update_super-and-update_sub.patch b/0074-Change-update-to-enum-in-update_super-and-update_sub.patch new file mode 100644 index 0000000..433d914 --- /dev/null +++ b/0074-Change-update-to-enum-in-update_super-and-update_sub.patch @@ -0,0 +1,423 @@ +From 03312b5240438ffc3b63114bdc87e911222f01e5 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:22 +0100 +Subject: [PATCH] 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 8b0af0c..dba910c 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 9574a3c..c9605a6 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 b73ec2a..82d5d2e 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 5a9ea31..87b8aa0 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 c59036f..b586679 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 31db25f..5dc9439 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 85fb7f1..1f5f6ed 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 d9f5bff..a7c5f81 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 b0a9701..f702032 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.35.3 + diff --git a/0075-Manage-Incremental-code-refactor-string-to-enum.patch b/0075-Manage-Incremental-code-refactor-string-to-enum.patch new file mode 100644 index 0000000..30a09e8 --- /dev/null +++ b/0075-Manage-Incremental-code-refactor-string-to-enum.patch @@ -0,0 +1,279 @@ +From f2e8393bd7223c419aaa33c45feeb5c75440b986 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:23 +0100 +Subject: [PATCH] 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 82d5d2e..8f5cf07 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 5a5f4c4..ff3548c 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 87b8aa0..594e3d2 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 f5f505f..d06e282 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 5dc9439..924f4b6 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.35.3 + diff --git a/0076-Change-char-to-enum-in-context-update-refactor-code.patch b/0076-Change-char-to-enum-in-context-update-refactor-code.patch new file mode 100644 index 0000000..d5af825 --- /dev/null +++ b/0076-Change-char-to-enum-in-context-update-refactor-code.patch @@ -0,0 +1,289 @@ +From 3a87fa67112dc2c2c3664aeecd0b49cb4b6ceaa9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Mon, 2 Jan 2023 09:35:24 +0100 +Subject: [PATCH] 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 dba910c..4980494 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 d06e282..57e8e6f 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 924f4b6..13f8b4c 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.35.3 + diff --git a/0077-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch b/0077-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch new file mode 100644 index 0000000..2e8575a --- /dev/null +++ b/0077-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch @@ -0,0 +1,54 @@ +From 24d329fc97a64ec185ef27e59730f3f058c09029 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Thu, 5 Jan 2023 00:29:20 +0800 +Subject: [PATCH] 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 39b4344..d4a7f0a 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.35.3 + diff --git a/0078-Manage-do-not-check-array-state-when-drive-is-remove.patch b/0078-Manage-do-not-check-array-state-when-drive-is-remove.patch new file mode 100644 index 0000000..2987a01 --- /dev/null +++ b/0078-Manage-do-not-check-array-state-when-drive-is-remove.patch @@ -0,0 +1,33 @@ +From b3e7b7eb1dfedd7cbd9a3800e884941f67d94c96 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Dec 2022 06:50:42 +0100 +Subject: [PATCH] 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 594e3d2..4d6e54b 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.35.3 + diff --git a/0079-incremental-manage-do-not-verify-if-remove-is-safe.patch b/0079-incremental-manage-do-not-verify-if-remove-is-safe.patch new file mode 100644 index 0000000..e4452fa --- /dev/null +++ b/0079-incremental-manage-do-not-verify-if-remove-is-safe.patch @@ -0,0 +1,59 @@ +From 461fae7e7809670d286cc19aac5bfa861c29f93a Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 27 Dec 2022 06:50:43 +0100 +Subject: [PATCH] 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 ff3548c..09b94b9 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 4d6e54b..6184d3f 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.35.3 + diff --git a/0080-super-intel-make-freesize-not-required-for-chunk-siz.patch b/0080-super-intel-make-freesize-not-required-for-chunk-siz.patch new file mode 100644 index 0000000..793594d --- /dev/null +++ b/0080-super-intel-make-freesize-not-required-for-chunk-siz.patch @@ -0,0 +1,52 @@ +From 071f839ea549e2a384cd13bba445245cd87e48b1 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Fri, 28 Oct 2022 04:51:17 +0200 +Subject: [PATCH] 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 1f5f6ed..89fac62 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.35.3 + diff --git a/0081-manage-move-comment-with-function-description.patch b/0081-manage-move-comment-with-function-description.patch new file mode 100644 index 0000000..d8b6869 --- /dev/null +++ b/0081-manage-move-comment-with-function-description.patch @@ -0,0 +1,105 @@ +From 36a707824eb1dafbb990f5daf1cbbe0e37dbbefb Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 5 Jan 2023 06:31:25 +0100 +Subject: [PATCH] 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 6184d3f..fde6aba 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.35.3 + diff --git a/0082-Fix-NULL-dereference-in-super_by_fd.patch b/0082-Fix-NULL-dereference-in-super_by_fd.patch new file mode 100644 index 0000000..636e316 --- /dev/null +++ b/0082-Fix-NULL-dereference-in-super_by_fd.patch @@ -0,0 +1,76 @@ +From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001 +From: Li Xiao Keng +Date: Mon, 27 Feb 2023 11:12:07 +0800 +Subject: [PATCH] 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 6b2207d..ac35176 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 9cd89fa..8c7f3fd 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.35.3 + diff --git a/0083-Mdmonitor-Make-alert_info-global.patch b/0083-Mdmonitor-Make-alert_info-global.patch new file mode 100644 index 0000000..95df074 --- /dev/null +++ b/0083-Mdmonitor-Make-alert_info-global.patch @@ -0,0 +1,369 @@ +From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:26:59 +0100 +Subject: [PATCH] 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 188cb8b..9ef4dab 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.35.3 + diff --git a/0084-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch b/0084-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch new file mode 100644 index 0000000..a07227f --- /dev/null +++ b/0084-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch @@ -0,0 +1,313 @@ +From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:00 +0100 +Subject: [PATCH] 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 9ef4dab..029e9ef 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.35.3 + diff --git a/0085-Mdmonitor-Add-helper-functions.patch b/0085-Mdmonitor-Add-helper-functions.patch new file mode 100644 index 0000000..7e34b70 --- /dev/null +++ b/0085-Mdmonitor-Add-helper-functions.patch @@ -0,0 +1,406 @@ +From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:01 +0100 +Subject: [PATCH] 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 029e9ef..39598ba 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.35.3 + diff --git a/0086-Add-helpers-to-determine-whether-directories-or-file.patch b/0086-Add-helpers-to-determine-whether-directories-or-file.patch new file mode 100644 index 0000000..359150b --- /dev/null +++ b/0086-Add-helpers-to-determine-whether-directories-or-file.patch @@ -0,0 +1,83 @@ +From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:02 +0100 +Subject: [PATCH] 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 13f8b4c..1674ce1 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 8c7f3fd..7fc881b 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.35.3 + diff --git a/0087-Mdmonitor-Refactor-write_autorebuild_pid.patch b/0087-Mdmonitor-Refactor-write_autorebuild_pid.patch new file mode 100644 index 0000000..ddcc0d3 --- /dev/null +++ b/0087-Mdmonitor-Refactor-write_autorebuild_pid.patch @@ -0,0 +1,110 @@ +From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:03 +0100 +Subject: [PATCH] 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 39598ba..14a2dfe 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.35.3 + diff --git a/0088-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch b/0088-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch new file mode 100644 index 0000000..c1976b7 --- /dev/null +++ b/0088-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch @@ -0,0 +1,139 @@ +From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 2 Feb 2023 12:27:04 +0100 +Subject: [PATCH] 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 14a2dfe..4491818 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.35.3 + diff --git a/0089-util.c-reorder-code-lines-in-parse_layout_faulty.patch b/0089-util.c-reorder-code-lines-in-parse_layout_faulty.patch new file mode 100644 index 0000000..36fa926 --- /dev/null +++ b/0089-util.c-reorder-code-lines-in-parse_layout_faulty.patch @@ -0,0 +1,41 @@ +From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Sat, 4 Mar 2023 00:21:30 +0800 +Subject: [PATCH] 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 7fc881b..b0b7aec 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.35.3 + diff --git a/0090-util.c-fix-memleak-in-parse_layout_faulty.patch b/0090-util.c-fix-memleak-in-parse_layout_faulty.patch new file mode 100644 index 0000000..bf02436 --- /dev/null +++ b/0090-util.c-fix-memleak-in-parse_layout_faulty.patch @@ -0,0 +1,32 @@ +From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:31 +0800 +Subject: [PATCH] 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 b0b7aec..9f1e1f7 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.35.3 + diff --git a/0091-Detail.c-fix-memleak-in-Detail.patch b/0091-Detail.c-fix-memleak-in-Detail.patch new file mode 100644 index 0000000..7f68d7a --- /dev/null +++ b/0091-Detail.c-fix-memleak-in-Detail.patch @@ -0,0 +1,31 @@ +From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:32 +0800 +Subject: [PATCH] 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 ce7a844..4ef2646 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.35.3 + diff --git a/0092-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch b/0092-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch new file mode 100644 index 0000000..0278264 --- /dev/null +++ b/0092-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch @@ -0,0 +1,63 @@ +From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:33 +0800 +Subject: [PATCH] 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 89fac62..4a3da84 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.35.3 + diff --git a/0093-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch b/0093-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch new file mode 100644 index 0000000..a1a868c --- /dev/null +++ b/0093-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch @@ -0,0 +1,38 @@ +From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:34 +0800 +Subject: [PATCH] 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 4a3da84..e155a8a 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.35.3 + diff --git a/0094-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch b/0094-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch new file mode 100644 index 0000000..009223b --- /dev/null +++ b/0094-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch @@ -0,0 +1,46 @@ +From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Sat, 4 Mar 2023 00:21:35 +0800 +Subject: [PATCH] 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 309812d..b86c6ac 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.35.3 + diff --git a/0095-Create-goto-abort_locked-instead-of-return-1-in-erro.patch b/0095-Create-goto-abort_locked-instead-of-return-1-in-erro.patch new file mode 100644 index 0000000..47ce8dd --- /dev/null +++ b/0095-Create-goto-abort_locked-instead-of-return-1-in-erro.patch @@ -0,0 +1,35 @@ +From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:29 -0700 +Subject: [PATCH] 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 953e737..2e8203e 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.35.3 + diff --git a/0096-Create-remove-safe_mode_delay-local-variable.patch b/0096-Create-remove-safe_mode_delay-local-variable.patch new file mode 100644 index 0000000..d5b7aa7 --- /dev/null +++ b/0096-Create-remove-safe_mode_delay-local-variable.patch @@ -0,0 +1,64 @@ +From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:30 -0700 +Subject: [PATCH] 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 2e8203e..8ded81d 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.35.3 + diff --git a/0097-Create-Factor-out-add_disks-helpers.patch b/0097-Create-Factor-out-add_disks-helpers.patch new file mode 100644 index 0000000..525698c --- /dev/null +++ b/0097-Create-Factor-out-add_disks-helpers.patch @@ -0,0 +1,452 @@ +From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:31 -0700 +Subject: [PATCH] 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 8ded81d..6a04466 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.35.3 + diff --git a/0098-mdadm-Introduce-pr_info.patch b/0098-mdadm-Introduce-pr_info.patch new file mode 100644 index 0000000..ea3a6bb --- /dev/null +++ b/0098-mdadm-Introduce-pr_info.patch @@ -0,0 +1,72 @@ +From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:32 -0700 +Subject: [PATCH] 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 6a04466..4acda30 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 1674ce1..4336be4 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.35.3 + diff --git a/0099-mdadm-Add-write-zeros-option-for-Create.patch b/0099-mdadm-Add-write-zeros-option-for-Create.patch new file mode 100644 index 0000000..7344645 --- /dev/null +++ b/0099-mdadm-Add-write-zeros-option-for-Create.patch @@ -0,0 +1,346 @@ +From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:33 -0700 +Subject: [PATCH] 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 4acda30..bbe9e13 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 bd8d50d..db251ed 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 57e8e6f..4685ad6 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 4336be4..b9127f9 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.35.3 + diff --git a/0100-manpage-Add-write-zeroes-option-to-manpage.patch b/0100-manpage-Add-write-zeroes-option-to-manpage.patch new file mode 100644 index 0000000..faf8e73 --- /dev/null +++ b/0100-manpage-Add-write-zeroes-option-to-manpage.patch @@ -0,0 +1,56 @@ +From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001 +From: Logan Gunthorpe +Date: Wed, 1 Mar 2023 13:41:35 -0700 +Subject: [PATCH] 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 64f71ed..6f0f6c1 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.35.3 + diff --git a/0101-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch b/0101-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch new file mode 100644 index 0000000..e7f1ea6 --- /dev/null +++ b/0101-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch @@ -0,0 +1,53 @@ +From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Wed, 18 Jan 2023 00:32:36 -0800 +Subject: [PATCH] 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 89b32f4..1e4ad5d 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.35.3 + diff --git a/0102-Use-existence-of-etc-initrd-release-to-detect-initrd.patch b/0102-Use-existence-of-etc-initrd-release-to-detect-initrd.patch new file mode 100644 index 0000000..0544fd0 --- /dev/null +++ b/0102-Use-existence-of-etc-initrd-release-to-detect-initrd.patch @@ -0,0 +1,40 @@ +From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 13 Mar 2023 14:42:58 +1100 +Subject: [PATCH] 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 9f1e1f7..509fb43 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.35.3 + diff --git a/0103-Create-Fix-checking-for-container-in-update_metadata.patch b/0103-Create-Fix-checking-for-container-in-update_metadata.patch new file mode 100644 index 0000000..43c6788 --- /dev/null +++ b/0103-Create-Fix-checking-for-container-in-update_metadata.patch @@ -0,0 +1,38 @@ +From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001 +From: Mateusz Grzonka +Date: Thu, 23 Mar 2023 12:50:00 +0100 +Subject: [PATCH] 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 bbe9e13..0911bf9 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.35.3 + diff --git a/1001-display-timeout-status.patch b/1001-display-timeout-status.patch new file mode 100644 index 0000000..43426ec --- /dev/null +++ b/1001-display-timeout-status.patch @@ -0,0 +1,30 @@ +--- + Detail.c | 1 + + md_p.h | 1 + + 2 files changed, 2 insertions(+) + +Index: mdadm-4.0/Detail.c +=================================================================== +--- mdadm-4.0.orig/Detail.c ++++ mdadm-4.0/Detail.c +@@ -693,6 +693,8 @@ This is pretty boring + disk.raid_disk >= 0) + failed++; + } ++ if (disk.state & (1< +Subject: OnCalendar format fix of mdcheck_start.timer +Patch-mainline: in-house patch at this moment, will post to upstream in future +References: bsc#1173137 + +This patch includes the fix of the OnCalendar format, changing the format of +mdcheck_start.timer [Timer] section, +from OnCalendar=Sun *-*-1..7 1:00:00 +to OnCalendar=Sun *-*-* 1:00:00 + +Signed-off-by: Ali Abdallah +Acked-by: Coly Li +Index: mdadm-4.1/systemd/mdcheck_start.timer +=================================================================== +--- mdadm-4.1.orig/systemd/mdcheck_start.timer ++++ mdadm-4.1/systemd/mdcheck_start.timer +@@ -9,7 +9,7 @@ + Description=MD array scrubbing + + [Timer] +-OnCalendar=Sun *-*-1..7 1:00:00 ++OnCalendar=Sun *-*-* 1:00:00 + + [Install] + WantedBy= mdmonitor.service diff --git a/1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch b/1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch new file mode 100644 index 0000000..54e0295 --- /dev/null +++ b/1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch @@ -0,0 +1,59 @@ +From 2361620a9d78a4e26ec438b5cc21fe796d411497 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 31 Aug 2020 00:02:10 +0800 +Subject: [PATCH] mdadm: treat the Dell softraid array as local array +Patch-mainline: N/A, in-house usage only as a workaround to Dell's softraid bug +References: bsc#1175004 + +Dell softraid FW uses homehost in md raid superblock to store +its virtual disk name e.g. "VirtualDisk01". The improper usage +of md raid super block meta data from Dell softraid S150 utility +makes mdadm takes such md raid (Dell softraid Virtual Disk) as +foreign array and won't automatically assemble this array by +default. Here if an array's homehost name starts with "VirtualDisk" +then we take it as a Dell software raid and bypass the set_name +checking. This workaround makes current Dell software raid array +can be treated as local array and start automatically. + +This workaround patch will be withdrawn after Dell softraid FW +fixes the improper usage problem on md raid superblock. + +Signed-off-by: Coly Li +--- + super1.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/super1.c b/super1.c +index 7664883..d15067a 100644 +--- a/super1.c ++++ b/super1.c +@@ -954,8 +954,25 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + static int match_home1(struct supertype *st, char *homehost) + { + struct mdp_superblock_1 *sb = st->sb; +- int l = homehost ? strlen(homehost) : 0; ++ char *dell_softraid_header = "VirtualDisk"; ++ int l = strlen(dell_softraid_header); ++ ++ /* ++ * Dell softraid FW uses homehost in md raid superblock to store ++ * its virtual disk name e.g. "VirtualDisk01". The improper usage ++ * of md raid super block meta data from Dell softraid S150 utility ++ * makes mdadm takes such md raid (Dell softraid Virtual Disk) as ++ * foreign array and won't automatically assemble this array by ++ * default. Here if an array's homehost name starts with "VirtualDisk" ++ * then we take it as a Dell software raid and bypass the set_name ++ * checking. This workaround makes current Dell software raid array ++ * can be treated as local array and start automatically. ++ */ ++ if (strncmp(sb->set_name, dell_softraid_header, l) == 0) ++ return 1; + ++ /* Normal cases handleing */ ++ l = homehost ? strlen(homehost) : 0; + return (l > 0 && l < 32 && sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0); + } +-- +2.26.2 + diff --git a/1004-call-mdadm_env.sh-from-usr-libexec-mdadm.patch b/1004-call-mdadm_env.sh-from-usr-libexec-mdadm.patch new file mode 100644 index 0000000..8f86110 --- /dev/null +++ b/1004-call-mdadm_env.sh-from-usr-libexec-mdadm.patch @@ -0,0 +1,61 @@ +From 6e79d4bd229e5db4e435917daf4c57cd79db9265 Mon Sep 17 00:00:00 2001 +From: colyli +Date: Wed, 17 Oct 2018 11:08:39 +0800 +Subject: [PATCH] Call mdadm_env.sh from /usr/libexec/mdadm +Patch-mainline: N/A, SUSE only patch +References: bsc#1111960, bsc#1202090 + +Current Makefile installs mdadm_env.sh to /usr/libexec/mdadm but the +systemd service files call it from /usr/lib/mdadm. This patch changes +the calling path in systemd service files to /usr/libexec/mdadm to +make things working. + +Signed-off-by: Coly Li +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: mdadm-4.2/systemd/mdcheck_continue.service +=================================================================== +--- mdadm-4.2.orig/systemd/mdcheck_continue.service ++++ mdadm-4.2/systemd/mdcheck_continue.service +@@ -14,5 +14,5 @@ Documentation=man:mdadm(8) + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" + EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStartPre=-/usr/libexec/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +Index: mdadm-4.2/systemd/mdcheck_start.service +=================================================================== +--- mdadm-4.2.orig/systemd/mdcheck_start.service ++++ mdadm-4.2/systemd/mdcheck_start.service +@@ -14,5 +14,5 @@ Documentation=man:mdadm(8) + Type=oneshot + Environment="MDADM_CHECK_DURATION=6 hours" + EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStartPre=-/usr/libexec/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} +Index: mdadm-4.2/systemd/mdmonitor-oneshot.service +=================================================================== +--- mdadm-4.2.orig/systemd/mdmonitor-oneshot.service ++++ mdadm-4.2/systemd/mdmonitor-oneshot.service +@@ -12,5 +12,5 @@ Documentation=man:mdadm(8) + [Service] + Environment=MDADM_MONITOR_ARGS=--scan + EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStartPre=-/usr/libexec/mdadm/mdadm_env.sh + ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS +Index: mdadm-4.2/systemd/mdmonitor.service +=================================================================== +--- mdadm-4.2.orig/systemd/mdmonitor.service ++++ mdadm-4.2/systemd/mdmonitor.service +@@ -13,5 +13,5 @@ Documentation=man:mdadm(8) + [Service] + Environment= MDADM_MONITOR_ARGS=--scan + EnvironmentFile=-/run/sysconfig/mdadm +-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStartPre=-/usr/libexec/mdadm/mdadm_env.sh + ExecStart=BINDIR/mdadm --monitor $MDADM_MONITOR_ARGS diff --git a/1005-mdadm-enable-Intel-Alderlake-RSTe-configuration.patch b/1005-mdadm-enable-Intel-Alderlake-RSTe-configuration.patch new file mode 100644 index 0000000..d312c3b --- /dev/null +++ b/1005-mdadm-enable-Intel-Alderlake-RSTe-configuration.patch @@ -0,0 +1,58 @@ +From 449c8b62164880ab132ad6eec86a8d53f793af69 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Tue, 19 Jul 2022 13:18:23 +0800 +Subject: [PATCH 19/23] mdadm: enable Intel Alderlake RSTe configuration +Patch-mainline: N/A, SUSE only patch +References: bsc#1201297 + +Alderlake has a slightly different RST configuration; the UEFI +variable is name 'RstVmdV', and the AHCI controller shows up as +a child device of the VMD bridge, but continues to use the 'AHCI HBA' +PCI class (and not the RAID class as RSTe would normally do). + +Signed-off-by: Hannes Reinecke +Acked-by: Coly Li +--- + platform-intel.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +Index: mdadm-4.2/platform-intel.c +=================================================================== +--- mdadm-4.2.orig/platform-intel.c ++++ mdadm-4.2/platform-intel.c +@@ -512,6 +512,7 @@ static const struct imsm_orom *find_imsm + #define AHCI_PROP "RstSataV" + #define AHCI_SSATA_PROP "RstsSatV" + #define AHCI_TSATA_PROP "RsttSatV" ++#define AHCI_RST_PROP "RstVmdV" + #define VROC_VMD_PROP "RstUefiV" + #define RST_VMD_PROP "RstVmdV" + +@@ -519,6 +520,7 @@ static const struct imsm_orom *find_imsm + EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) + + #define PCI_CLASS_RAID_CNTRL 0x010400 ++#define PCI_CLASS_SATA_HBA 0x010601 + + static int read_efi_var(void *buffer, ssize_t buf_size, + const char *variable_name, struct efi_guid guid) +@@ -605,7 +607,8 @@ const struct imsm_orom *find_imsm_efi(st + struct imsm_orom orom; + struct orom_entry *ret; + static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP, +- AHCI_TSATA_PROP}; ++ AHCI_TSATA_PROP, ++ AHCI_RST_PROP}; + static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP}; + unsigned long i; + +@@ -624,7 +627,8 @@ const struct imsm_orom *find_imsm_efi(st + + return NULL; + case SYS_DEV_SATA: +- if (hba->class != PCI_CLASS_RAID_CNTRL) ++ if (hba->class != PCI_CLASS_RAID_CNTRL && ++ hba->class != PCI_CLASS_SATA_HBA) + return NULL; + + for (i = 0; i < ARRAY_SIZE(sata_efivars); i++) { diff --git a/Software-RAID.HOWTO.tar.bz2 b/Software-RAID.HOWTO.tar.bz2 new file mode 100644 index 0000000..8b185c0 --- /dev/null +++ b/Software-RAID.HOWTO.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa66bf2cadc6f85dfde50a2a31d7547483342fe74d88801129d383bf98796352 +size 29644 diff --git a/mdadm-4.2.tar.xz b/mdadm-4.2.tar.xz new file mode 100644 index 0000000..5acaaf7 --- /dev/null +++ b/mdadm-4.2.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:461c215670864bb74a4d1a3620684aa2b2f8296dffa06743f26dda5557acf01d +size 453624 diff --git a/mdadm.changes b/mdadm.changes new file mode 100644 index 0000000..6a1d905 --- /dev/null +++ b/mdadm.changes @@ -0,0 +1,3042 @@ +------------------------------------------------------------------- +Mon Jan 8 05:32:25 UTC 2024 - Coly Li + +- Update mdadm to latest upstream state upto commit + 582945c2d3bb. (jsc#PED-7542) + 1) The testing changes are not included here. + 2) Code clean up, and more helper routines added for Manage.c, + Monitor.c, mdadm.c, ReadMe.c, super-intel.c, super0.c, super1.c, + Create.c, Incremental.c and so on. + 3) Man page update for mdadm.8.in. + 4) Several memory leak and double free fixes. + 5) Check /etc/initrd-release for whether systemd running on an initrd. + - Manage: Block unsafe member failing + 0062-Manage-Block-unsafe-member-failing.patch + - Mdmonitor: Split alert() into separate functions + 0063-Mdmonitor-Split-alert-into-separate-functions.patch + - Monitor: block if monitor modes are combined. + 0064-Monitor-block-if-monitor-modes-are-combined.patch + - Update mdadm Monitor manual. + 0065-Update-mdadm-Monitor-manual.patch + - mdadm: create ident_init() + 0066-mdadm-create-ident_init.patch + - mdadm: Add option validation for --update-subarray + 0067-mdadm-Add-option-validation-for-update-subarray.patch + - Fix --update-subarray on active volume + 0068-Fix-update-subarray-on-active-volume.patch + - Add code specific update options to enum. + 0069-Add-code-specific-update-options-to-enum.patch + - super-ddf: Remove update_super_ddf. + 0070-super-ddf-Remove-update_super_ddf.patch + - super0: refactor the code for enum + 0071-super0-refactor-the-code-for-enum.patch + - super1: refactor the code for enum + 0072-super1-refactor-the-code-for-enum.patch + - super-intel: refactor the code for enum + 0073-super-intel-refactor-the-code-for-enum.patch + - Change update to enum in update_super and update_subarray + 0074-Change-update-to-enum-in-update_super-and-update_sub.patch + - Manage&Incremental: code refactor, string to enum + 0075-Manage-Incremental-code-refactor-string-to-enum.patch + - Change char* to enum in context->update & refactor code + 0076-Change-char-to-enum-in-context-update-refactor-code.patch + - mdadm/udev: Don't handle change event on raw devices + 0077-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch + - Manage: do not check array state when drive is removed + 0078-Manage-do-not-check-array-state-when-drive-is-remove.patch + - incremental, manage: do not verify if remove is safe + 0079-incremental-manage-do-not-verify-if-remove-is-safe.patch + - super-intel: make freesize not required for chunk size + 0080-super-intel-make-freesize-not-required-for-chunk-siz.patch + - manage: move comment with function description + 0081-manage-move-comment-with-function-description.patch + - Fix NULL dereference in super_by_fd + 0082-Fix-NULL-dereference-in-super_by_fd.patch + - Mdmonitor: Make alert_info global + 0083-Mdmonitor-Make-alert_info-global.patch + - Mdmonitor: Pass events to alert() using enums instead of + 0084-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch + - Mdmonitor: Add helper functions + 0085-Mdmonitor-Add-helper-functions.patch + - Add helpers to determine whether directories or files are + 0086-Add-helpers-to-determine-whether-directories-or-file.patch + - Mdmonitor: Refactor write_autorebuild_pid() + 0087-Mdmonitor-Refactor-write_autorebuild_pid.patch + - Mdmonitor: Refactor check_one_sharer() for better error + 0088-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch + - util.c: reorder code lines in parse_layout_faulty() + 0089-util.c-reorder-code-lines-in-parse_layout_faulty.patch + - util.c: fix memleak in parse_layout_faulty() + 0090-util.c-fix-memleak-in-parse_layout_faulty.patch + - Detail.c: fix memleak in Detail() + 0091-Detail.c-fix-memleak-in-Detail.patch + - isuper-intel.c: fix double free in load_imsm_mpb() + 0092-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch + - super-intel.c: fix memleak in find_disk_attached_hba() + 0093-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch + - super-ddf.c: fix memleak in get_vd_num_of_subarray() + 0094-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch + - Create: goto abort_locked instead of return 1 in error path + 0095-Create-goto-abort_locked-instead-of-return-1-in-erro.patch + - Create: remove safe_mode_delay local variable + 0096-Create-remove-safe_mode_delay-local-variable.patch + - Create: Factor out add_disks() helpers + 0097-Create-Factor-out-add_disks-helpers.patch + - mdadm: Introduce pr_info() + 0098-mdadm-Introduce-pr_info.patch + - mdadm: Add --write-zeros option for Create + 0099-mdadm-Add-write-zeros-option-for-Create.patch + - manpage: Add --write-zeroes option to manpage + 0100-manpage-Add-write-zeroes-option-to-manpage.patch + - Define alignof using _Alignof when using C11 or newer + 0101-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch + - Use existence of /etc/initrd-release to detect initrd. + 0102-Use-existence-of-etc-initrd-release-to-detect-initrd.patch + - Create: Fix checking for container in update_metadata + 0103-Create-Fix-checking-for-container-in-update_metadata.patch + +------------------------------------------------------------------- +Fri Nov 17 15:34:31 UTC 2023 - Dominique Leuenberger + +- No longer recommend smtp-daemon: this was a remainder from the + cron configuration, which was removed back in 2018. + +------------------------------------------------------------------- +Mon Jul 24 15:31:30 UTC 2023 - Ludwig Nussel + +- mdadm.spec: replace transitional %usrmerged macro with regular + version check (boo#1206798) + +------------------------------------------------------------------- +Fri May 26 02:29:42 UTC 2023 - Coly Li + +- Grow: fix possible memory leak (bsc#1208618) + 0060-Grow-fix-possible-memory-leak.patch +- Grow: fix can't change bitmap type from none to clustered + (bsc#1208618) + 0061-Grow-fix-can-t-change-bitmap-type-from-none-to-clustered.patch +- Use source code mdadm-4.2.tar.xz from kernel.org version for + checksum + - mdadm-4.2.tar.xz + +------------------------------------------------------------------- +Mon Apr 24 15:06:42 UTC 2023 - Coly Li + +- Fixes for mdmon to ensure it run at the right time in the + fight mount namespace. This fixes various problems with + IMSM raid arrays in 15-SP4 (bsc#1205493, bsc#1205830) + - mdmon: fix segfault + 0052-mdmon-fix-segfault.patch + - util: remove obsolete code from get_md_name + 0053-util-remove-obsolete-code-from-get_md_name.patch + - mdmon: don't test both 'all' and 'container_name'. + 0054-mdmon-don-t-test-both-all-and-container_name.patch + - mdmon: change systemd unit file to use --foreground + 0055-mdmon-change-systemd-unit-file-to-use-foreground.patch + - mdmon: Remove need for KillMode=none + 0056-mdmon-Remove-need-for-KillMode-none.patch + - mdmon: Improve switchroot interactions. + 0057-mdmon-Improve-switchroot-interactions.patch + - mdopen: always try create_named_array() + 0058-mdopen-always-try-create_named_array.patch + - Improvements for IMSM_NO_PLATFORM testing + 0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch + +------------------------------------------------------------------- +Sat Apr 1 15:17:58 UTC 2023 - Coly Li + +- sysconfig.mdadm: Remove ServiceRestart line to mdadm since there + is not such systemd service. (bsc#1203491) + +------------------------------------------------------------------- +Mon Dec 26 05:01:33 UTC 2022 - Coly Li + +- mdadm.spec: create the following symbolic link in /sbin for + compatibility, + /sbin/mdadm -> /usr/sbin/mdadm + /sbin/mdmon -> /usr/sbin/mdmon + (jsc#PED-1009, jsc#PED-947) + +------------------------------------------------------------------- +Wed Dec 7 08:42:17 UTC 2022 - Coly Li + +- Drop the patch which is reported as regression by upstream developer + (bsc#1206139) + 0045-Manage-Block-unsafe-member-failing.patch +- Add jsc#PED-947 together with jsc#PED-1009 in mdadm.changes, they + are both the requirement to update mdadm to latest upstream state + via different requestors. + +------------------------------------------------------------------- +Thu Nov 24 06:23:28 UTC 2022 - Coly Li + +- Call mdadm_env.sh from /usr/libexec/mdadm (bsc#1111960, bsc#1202090) + 1004-call-mdadm_env.sh-from-usr-libexec-mdadm.patch +- The patch (bsc#1111960) which fixed rpm check failure is replaced + by the above patch, + 1004-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch. + +------------------------------------------------------------------- +Thu Nov 24 05:57:50 UTC 2022 - Coly Li + +- mdadm.spec: remove "PreReq: %{_sbindir}/mkinitrd" as it is + unnecessary now. (bsc#1202352) + +------------------------------------------------------------------- +Thu Nov 3 15:58:38 UTC 2022 - Coly Li + +- Update mdadm package to latest mdadm since mdadm-4.2 + (jsc#PED-1009, jsc#PED-947) + * Only patches directly change runtime programs included, + - Unify error message. + 0001-Unify-error-message.patch + - mdadm: Fix double free + 0002-mdadm-Fix-double-free.patch + - Grow_reshape: Add r0 grow size error message and update + 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch + - udev: adapt rules to systemd v247 + 0004-udev-adapt-rules-to-systemd-v247.patch + - Replace error prone signal() with sigaction() + 0005-Replace-error-prone-signal-with-sigaction.patch + - mdadm: Respect config file location in man + 0006-mdadm-Respect-config-file-location-in-man.patch + - mdadm: Update ReadMe + 0007-mdadm-Update-ReadMe.patch + - mdadm: Update config man regarding default files and + 0008-mdadm-Update-config-man-regarding-default-files-and-.patch + - mdadm: Update config manual + 0009-mdadm-Update-config-manual.patch + - Create, Build: use default_layout() + 0010-Create-Build-use-default_layout.patch + - mdadm: add map_num_s() + 0011-mdadm-add-map_num_s.patch + - mdmon: Stop parsing duplicate options + 0012-mdmon-Stop-parsing-duplicate-options.patch + - Grow: block -n on external volumes. + 0013-Grow-block-n-on-external-volumes.patch + - Incremental: Fix possible memory and resource leaks + 0014-Incremental-Fix-possible-memory-and-resource-leaks.patch + - Mdmonitor: Fix segfault + 0015-Mdmonitor-Fix-segfault.patch + - Mdmonitor: Improve logging method + 0016-Mdmonitor-Improve-logging-method.patch + - Fix possible NULL ptr dereferences and memory leaks + 0017-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch + - imsm: Remove possibility for get_imsm_dev to return + 0018-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch + - Revert "mdadm: fix coredump of mdadm --monitor -r" + 0019-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch + - util: replace ioctl use with function + 0020-util-replace-ioctl-use-with-function.patch + - mdadm/super1: restore commit 45a87c2f31335 to fix + 0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch + - imsm: introduce get_disk_slot_in_dev() + 0022-imsm-introduce-get_disk_slot_in_dev.patch + - imsm: use same slot across container + 0023-imsm-use-same-slot-across-container.patch + - imsm: block changing slots during creation + 0024-imsm-block-changing-slots-during-creation.patch + - mdadm: block update=ppl for non raid456 levels + 0025-mdadm-block-update-ppl-for-non-raid456-levels.patch + - mdadm: Fix array size mismatch after grow + 0026-mdadm-Fix-array-size-mismatch-after-grow.patch + - mdadm: Remove dead code in imsm_fix_size_mismatch + 0027-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch + - Monitor: use devname as char array instead of pointer + 0028-Monitor-use-devname-as-char-array-instead-of-pointer.patch + - Monitor: use snprintf to fill device name + 0029-Monitor-use-snprintf-to-fill-device-name.patch + - Makefile: Don't build static build with everything and + 0030-Makefile-Don-t-build-static-build-with-everything-an.patch + - DDF: Cleanup validate_geometry_ddf_container() + 0031-DDF-Cleanup-validate_geometry_ddf_container.patch + - DDF: Fix NULL pointer dereference in + 0032-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch + - mdadm/Grow: Fix use after close bug by closing after + 0033-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch + - monitor: Avoid segfault when calling NULL + 0034-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch + - mdadm: Fix mdadm -r remove option regression + 0035-mdadm-Fix-mdadm-r-remove-option-regression.patch + - mdadm: Fix optional --write-behind parameter + 0036-mdadm-Fix-optional-write-behind-parameter.patch + - mdadm: Replace obsolete usleep with nanosleep + 0037-mdadm-Replace-obsolete-usleep-with-nanosleep.patch + - mdadm: remove symlink option + 0038-mdadm-remove-symlink-option.patch + - mdadm: move data_offset to struct shape + 0039-mdadm-move-data_offset-to-struct-shape.patch + - mdadm: Don't open md device for CREATE and ASSEMBLE + 0040-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch + - Grow: Split Grow_reshape into helper function + 0041-Grow-Split-Grow_reshape-into-helper-function.patch + - Assemble: check if device is container before + 0042-Assemble-check-if-device-is-container-before-schedul.patch + - super1: report truncated device + 0043-super1-report-truncated-device.patch + - mdadm: Correct typos, punctuation and grammar in man + 0044-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch + - Manage: Block unsafe member failing + 0045-Manage-Block-unsafe-member-failing.patch + - Monitor: Fix statelist memory leaks + 0046-Monitor-Fix-statelist-memory-leaks.patch + - mdadm: added support for Intel Alderlake RST on VMD + 0047-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch + - mdadm: Add Documentation entries to systemd services + 0048-mdadm-Add-Documentation-entries-to-systemd-services.patch + - ReadMe: fix command-line help + 0049-ReadMe-fix-command-line-help.patch + - mdadm: replace container level checking with inline + 0050-mdadm-replace-container-level-checking-with-inline.patch + - Mdmonitor: Omit non-md devices + 0051-Mdmonitor-Omit-non-md-devices.patch + +- Remove the following in house patch + 1004-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch + because upstream merged version added in as + 0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +- Rename 0000-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch + to 1004-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch. + +- Update mdadm package to mdadm-4.2 (jsc#PED-1009, jsc#PED-947) + All important modifications since previous update to mdadm-4.2 + are listed here. + * The patches about Intel Matrix Storage Manager (including + VROC support), + - super-intel.c: Handle errors from calls to get_dev_sector_size() + - imsm: change wrong size verification + - imsm: add generic method to resolve "device" links + - imsm: add devpath_to_char method + - imsm: Limit support to the lowest namespace + - imsm: correct offset for 4k disks in --examine output + - imsm: Fix possible memory leaks and refactor freeing struct dl + - imsm: fix num_data_stripes after raid0 takeover + - imsm: introduce helpers to manage file descriptors + - imsm: free allocated memory in imsm_fix_size_mismatch + - imsm: assert if there is migration but prev_map doesn't exist + * The patches to fix program issues, + - mdadm/super1: It needs to specify int32 for bitmap_offset + - Fix memory leak after "mdadm --detail" + - Utils: Change sprintf to snprintf + - mdadm: fix coredump of mdadm --monitor -r + - Fix error message when creating raid 4, 5 and 10 + - Fix buffer size warning for strcp + - Fix potential overlap dest buffer + - Correct checking if file descriptors are valid + - Monitor: print message before quit for no array to monitor + * Improvement or bug fixes for mdadm itself, + - Assemble: skip devices that don't match uuid instead of aborting the + assembly. + - Assemble: apply sysfs rules + - Assemble: start dirty and degraded array. + - Incremental: Close unclosed mdfd in IncrementalScan() + - Monitor: make libudev dependency optional + - Manage: Call validate_geometry when adding drive to external + container + - Remove Spare drives line from details for external metadata + - Don't associate spares with other arrays during RAID Examine + - Add error handling for chunk size in RAID1 + - Add monitor delay parameter to mdadm.conf + - disallow create or grow clustered bitmap with writemostly set + - mdadm/Detail: Can't show container name correctly when unpluging disks + - mdadm: block creation with long names + - mdadm: fix growing containers + +- Remove the following patches because they are all included + in mdadm-4.2, + - 0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch + - 0002-Document-PART-POLICY-lines.patch + - 0003-policy-support-devices-with-multiple-paths.patch + - 0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch + - 0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch + - 0006-imsm-update-metadata-correctly-while-raid10-double-d.patch + - 0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch + - 0008-Grow-avoid-overflow-in-compute_backup_blocks.patch + - 0009-Grow-report-correct-new-chunk-size.patch + - 0010-policy.c-prevent-NULL-pointer-referencing.patch + - 0012-policy.c-Fix-for-compiler-error.patch + - 0013-imsm-finish-recovery-when-drive-with-rebuild-fails.patch + - 0014-imsm-fix-reshape-for-2TB-drives.patch + - 0015-Fix-spelling-typos.patch + - 0016-Detail.c-do-not-skip-first-character-when-calling-xs.patch + - 0018-Fix-reshape-for-decreasing-data-offset.patch + - 0019-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch + - 0020-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch + - 0021-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch + - 0022-Assemble-Fix-starting-array-with-initial-reshape-che.patch + - 0023-add-missing-units-to-examine.patch + - 0024-imsm-fix-spare-activation-for-old-matrix-arrays.patch + - 0025-Create-Block-rounding-size-to-max.patch + - 0026-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch + - 0027-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch + - 0028-Enable-probe_roms-to-scan-more-than-6-roms.patch + - 0029-super-intel-Fix-issue-with-abs-being-irrelevant.patch + - 0030-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch + - 0031-super-intel-Use-put_unaligned-in-split_ull.patch + - 0032-mdadm-load-default-sysfs-attributes-after-assemblati.patch + - 0033-mdadm.h-include-sysmacros.h-unconditionally.patch + - 0034-mdadm-add-no-devices-to-avoid-component-devices-deta.patch + - 0035-udev-add-no-devices-option-for-calling-mdadm-detail.patch + - 0036-imsm-close-removed-drive-fd.patch + - 0037-mdadm-check-value-returned-by-snprintf-against-error.patch + - 0038-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch + - 0039-mdadm-force-a-uuid-swap-on-big-endian.patch + - 0040-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch + - 0041-Init-devlist-as-an-array.patch + - 0042-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch + - 0043-udev-allow-for-udev-attribute-reading-bug.patch + - 0044-imsm-save-current_vol-number.patch + - 0045-imsm-allow-to-specify-second-volume-size.patch + - 0046-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch + - 0050-mdcheck-use-to-pass-variable-to-mdcheck.patch + - 0051-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch + - 0052-super-intel-don-t-mark-structs-packed-unnecessarily.patch + - 0053-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch + - 0054-Remove-last-traces-of-HOT_ADD_DISK.patch + - 0055-Fix-up-a-few-formatting-issues.patch + - 0056-Remove-unused-code.patch + - 0057-imsm-return-correct-uuid-for-volume-in-detail.patch + - 0058-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch + - 0059-Create-add-support-for-RAID0-layouts.patch + - 0060-Assemble-add-support-for-RAID0-layouts.patch + - 0061-Respect-CROSS_COMPILE-when-CC-is-the-default.patch + - 0062-Change-warning-message.patch + - 0063-mdcheck-service-can-t-start-succesfully-because-of-s.patch + - 0064-imsm-Update-grow-manual.patch + - 0065-Add-support-for-Tebibytes.patch + - 0066-imsm-fill-working_disks-according-to-metadata.patch + - 0067-mdadm.8-add-note-information-for-raid0-growing-opera.patch + - 0068-Remove-the-legacy-whitespace.patch + - 0069-imsm-pass-subarray-id-to-kill_subarray-function.patch + - 0070-imsm-Remove-dump-restore-implementation.patch + - 0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch + - 0072-Detail-adding-sync-status-for-cluster-device.patch + - 0073-imsm-Correct-minimal-device-size.patch + - 0074-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch + - 0075-imsm-support-the-Array-Creation-Time-field-in-metada.patch + - 0076-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch + - 0077-udev-Ignore-change-event-for-imsm.patch + - 0078-Manage-imsm-Write-metadata-before-add.patch + - 0079-Assemble-print-error-message-if-mdadm-fails-assembli.patch + - 0080-clean-up-meaning-of-small-typo.patch + - 0081-Assemble.c-respect-force-flag.patch + - 0082-mdcheck-Log-when-done.patch + - 0083-Makefile-add-EXTRAVERSION-support.patch + - 0084-uuid.c-split-uuid-stuffs-from-util.c.patch + - 0085-Include-count-for-0-character-when-using-strncpy-to-.patch + - 0086-restripe-fix-ignoring-return-value-of-read-and-lseek.patch + - 0087-Block-overwriting-existing-links-while-manual-assemb.patch + - 0088-Detect-too-small-device-error-rather-than-underflow-.patch + - 0089-Use-more-secure-HTTPS-URLs.patch + - 0090-Update-link-to-Intel-page-for-IMSM.patch + - 0091-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch + - 0092-Specify-nodes-number-when-updating-cluster-nodes.patch + - 0093-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch + - 0094-manual-update-examine-badblocks.patch + - 0095-Detail-show-correct-raid-level-when-the-array-is-ina.patch + - 0096-Don-t-create-bitmap-for-raid5-with-journal-disk.patch + - 0097-Monitor-refresh-mdstat-fd-after-select.patch + - 0098-Monitor-stop-notifing-about-containers.patch + - 0099-mdmonitor-set-small-delay-once.patch + - 0100-Check-if-other-Monitor-instance-running-before-fork.patch + - 0101-Super1-allow-RAID0-layout-setting-to-be-removed.patch + - 0102-Detail-fix-segfault-during-IMSM-raid-creation.patch + - 0103-Create.c-close-mdfd-and-generate-uevent.patch + - 0104-imsm-update-num_data_stripes-according-to-dev_size.patch + - 0105-imsm-remove-redundant-calls-to-imsm_get_map.patch + - 0106-Monitor-don-t-use-default-modes-when-creating-a-file.patch + - 0107-imsm-limit-support-to-first-NVMe-namespace.patch + - 0108-mdadm-Unify-forks-behaviour.patch + - 0109-mdadm-Detail-show-correct-state-for-clustered-array.patch + - 0110-Make-target-to-install-binaries-only.patch + - 0111-udev-start-grow-service-automatically.patch + - 0112-Incremental-Remove-redundant-spare-movement-logic.patch + - 0113-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch + - 0114-super1-fix-Floating-point-exception.patch + - 0115-super1.c-avoid-useless-sync-when-bitmap-switches-fro.patch + - 0116-imsm-nvme-multipath-support.patch + - 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch + - 0118-Remove-Spare-drives-line-from-details-for-external-m.patch + - 0119-Don-t-associate-spares-with-other-arrays-during-RAID.patch + - 0120-udev-md-raid-assembly.rules-skip-if-DM_UDEV_DISABLE_.patch + - 0121-imsm-support-for-third-Sata-controller.patch +- The patch from SLE15-SP4 is removed because it is in mdadm-4.2 + upstream already, + - Monitor: print message before quit for no array to monitor + (bsc#1183229) + 0120-Monitor-print-message-before-quit-for-no-array-to-mo.patch + +------------------------------------------------------------------- +Mon Sep 19 14:18:41 CST 2022 - Coly Li + +- mdadm.spec: add EXTRAVERSION string to make command line + (jsc#SLE-24761, bsc#1193566) + +------------------------------------------------------------------- +Thu Aug 11 11:41:37 UTC 2022 - Coly Li + +- imsm: support for third Sata controller (bsc#1201297) + 0121-imsm-support-for-third-Sata-controller.patch +- mdadm: enable Intel Alderlake RSTe configuration (bsc#1201297) + 1005-mdadm-enable-Intel-Alderlake-RSTe-configuration.patch + +------------------------------------------------------------------- +Mon May 30 08:25:00 UTC 2022 - Heming Zhao + +- resource RAID failed during cluster patch, Mdadm gets floating point error (bsc#1197158) + 1004-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch + +------------------------------------------------------------------- +Fri Mar 18 22:48:41 UTC 2022 - Martin Wilck + +- skip RAID assembly if DM_UDEV_DISABLE_OTHER_RULES_FLAG (bsc#1196054) + * Add 0120-udev-md-raid-assembly.rules-skip-if-DM_UDEV_DISABLE_.patch + +------------------------------------------------------------------- +Tue Nov 23 08:42:24 UTC 2021 - Stefan Weiberg + +- Use %{_sbindir} for prerequisite of mkinitrd to work with + usrmerge of dracut-mkinitrd-deprecated + +------------------------------------------------------------------- +Wed Oct 6 04:15:49 UTC 2021 - Neil Brown + +- Install mdadm in _sbindir rather than /sbin. This is more + appropriate now that we have a merged-/usr. + (bsc#1191076) + +------------------------------------------------------------------- +Thu Sep 2 05:17:18 UTC 2021 - Coly Li + +- Remove Spare drives line from details for external metadata + (bsc#1180661, bsc#1182642) + 0118-Remove-Spare-drives-line-from-details-for-external-m.patch +- Don't associate spares with other arrays during RAID Examine + (bsc#1180661, bsc#1182642) + 0119-Don-t-associate-spares-with-other-arrays-during-RAID.patch + +------------------------------------------------------------------- +Fri May 14 14:40:40 UTC 2021 - Coly Li + +- Grow: be careful of corrupt dev_roles list (bsc#1181619) + 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch + +------------------------------------------------------------------- +Fri May 14 12:17:31 UTC 2021 - Coly Li + +- imsm: nvme multipath support (bsc#1175758) + 0116-imsm-nvme-multipath-support.patch + +------------------------------------------------------------------- +Wed Mar 17 02:35:00 UTC 2021 - Heming Zhao + +- cluster-md/mdadm : avoid useless re-sync (bsc#1181341) + 0114-super1-fix-Floating-point-exception.patch + 0115-super1.c-avoid-useless-sync-when-bitmap-switches-fro.patch + +------------------------------------------------------------------- +Tue Jan 5 12:02:12 UTC 2021 - Coly Li + +- Incremental: Remove redundant spare movement logic + (jsc#SLE-13700, bsc#1180220) + 0112-Incremental-Remove-redundant-spare-movement-logic.patch +- Dump: get stat from a wrong metadata file when restoring metadata + (jsc#SLE-13700) + 0113-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch + +------------------------------------------------------------------- +Sat Dec 5 13:53:38 UTC 2020 - Coly Li +- There are some important fixes merged in mdadm upstream which + should go with jsc#SLE-13700. This is the update from upstream + mdadm including the important fixes we should have. + +- Detail: show correct raid level when the array is inactive + (jsc#SLE-13700) + 0095-Detail-show-correct-raid-level-when-the-array-is-ina.patch +- Don't create bitmap for raid5 with journal disk + (jsc#SLE-13700) + 0096-Don-t-create-bitmap-for-raid5-with-journal-disk.patch +- Monitor: refresh mdstat fd after select (jsc#SLE-13700) + 0097-Monitor-refresh-mdstat-fd-after-select.patch +- Monitor: stop notifing about containers. (jsc#SLE-13700) + 0098-Monitor-stop-notifing-about-containers.patch +- mdmonitor: set small delay once (jsc#SLE-13700) + 0099-mdmonitor-set-small-delay-once.patch +- Check if other Monitor instance running before fork. + (jsc#SLE-13700) + 0100-Check-if-other-Monitor-instance-running-before-fork.patch +- Super1: allow RAID0 layout setting to be removed. + (jsc#SLE-13700) + 0101-Super1-allow-RAID0-layout-setting-to-be-removed.patch +- Detail: fix segfault during IMSM raid creation + (jsc#SLE-13700) + 0102-Detail-fix-segfault-during-IMSM-raid-creation.patch +- Create.c: close mdfd and generate uevent (jsc#SLE-13700) + 0103-Create.c-close-mdfd-and-generate-uevent.patch +- imsm: update num_data_stripes according to dev_size + (jsc#SLE-13700) + 0104-imsm-update-num_data_stripes-according-to-dev_size.patch +- imsm: remove redundant calls to imsm_get_map (jsc#SLE-13700) + 0105-imsm-remove-redundant-calls-to-imsm_get_map.patch +- Monitor: don't use default modes when creating a file + (jsc#SLE-13700) + 0106-Monitor-don-t-use-default-modes-when-creating-a-file.patch +- imsm: limit support to first NVMe namespace (jsc#SLE-13700) + 0107-imsm-limit-support-to-first-NVMe-namespace.patch +- mdadm: Unify forks behaviour (jsc#SLE-13700) + 0108-mdadm-Unify-forks-behaviour.patch +- mdadm/Detail: show correct state for clustered array + (jsc#SLE-13700) + 0109-mdadm-Detail-show-correct-state-for-clustered-array.patch +- Make target to install binaries only (jsc#SLE-13700) + 0110-Make-target-to-install-binaries-only.patch +- udev: start grow service automatically (jsc#SLE-13700) + 0111-udev-start-grow-service-automatically.patch + +------------------------------------------------------------------- +Sun Oct 11 16:14:50 UTC 2020 - Coly Li + +- Update to latest mdadm which is requested by jsc#SLE-13700 from + partners. Mostly the purpose is for latest Intel IMSM raid + support, while some other fixes are important too. + +- imsm: Correct minimal device size (jsc#SLE-13700) + 0073-imsm-Correct-minimal-device-size.patch +- Detail: show correct bitmap info for cluster raid device + (jsc#SLE-13700) + 0074-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch +- imsm: support the Array Creation Time field in metadata + (jsc#SLE-13700) + 0075-imsm-support-the-Array-Creation-Time-field-in-metada.patch +- imsm: show Subarray and Volume ID in --examine output + (jsc#SLE-13700) + 0076-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch +- udev: Ignore change event for imsm (jsc#SLE-13700) + 0077-udev-Ignore-change-event-for-imsm.patch +- Manage, imsm: Write metadata before add (jsc#SLE-13700) + 0078-Manage-imsm-Write-metadata-before-add.patch +- Assemble: print error message if mdadm fails assembling + with --uuid option (jsc#SLE-13700) + 0079-Assemble-print-error-message-if-mdadm-fails-assembli.patch +- clean up meaning of small typo (jsc#SLE-13700) + 0080-clean-up-meaning-of-small-typo.patch +- Assemble.c: respect force flag (jsc#SLE-13700) + 0081-Assemble.c-respect-force-flag.patch +- mdcheck: Log when done (jsc#SLE-13700) + 0082-mdcheck-Log-when-done.patch +- Makefile: add EXTRAVERSION support (jsc#SLE-13700) + 0083-Makefile-add-EXTRAVERSION-support.patch +- uuid.c: split uuid stuffs from util.c (jsc#SLE-13700) + 0084-uuid.c-split-uuid-stuffs-from-util.c.patch +- Include count for \0 character when using strncpy to + implement strdup. (jsc#SLE-13700) + 0085-Include-count-for-0-character-when-using-strncpy-to-.patch +- restripe: fix ignoring return value of read and lseek + (jsc#SLE-13700) + 0086-restripe-fix-ignoring-return-value-of-read-and-lseek.patch +- Block overwriting existing links while manual assembly + (jsc#SLE-13700) + 0087-Block-overwriting-existing-links-while-manual-assemb.patch +- Detect too-small device: error rather than underflow/crash + (jsc#SLE-13700) + 0088-Detect-too-small-device-error-rather-than-underflow-.patch +- Use more secure HTTPS URLs (jsc#SLE-13700) + 0089-Use-more-secure-HTTPS-URLs.patch +- Update link to Intel page for IMSM (jsc#SLE-13700) + 0090-Update-link-to-Intel-page-for-IMSM.patch +- mdadm/Grow: prevent md's fd from being occupied during delayed time + (jsc#SLE-13700) + 0091-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch +- Specify nodes number when updating cluster nodes (jsc#SLE-13700) + 0092-Specify-nodes-number-when-updating-cluster-nodes.patch +- mdadm/md.4: update path to in-kernel-tree documentation + (jsc#SLE-13700) + 0093-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch +- manual: update --examine-badblocks (jsc#SLE-13700) + 0094-manual-update-examine-badblocks.patch + +------------------------------------------------------------------- +Sun Aug 30 16:08:02 UTC 2020 - Coly Li + +- mdadm: treat the Dell softraid array as local array (bsc#1175004) + 1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch + +------------------------------------------------------------------- +Tue Jul 7 09:35:58 UTC 2020 - Callum Farmer + +- Fixes for %_libexecdir changing to /usr/libexec(bsc#1174075) + +------------------------------------------------------------------- +Mon Jun 22 16:12:47 UTC 2020 - Coly Li + +- OnCalendar format fix of mdcheck_start.timer (bsc#1173137) + 1002-OnCalendar-format-fix-of-mdcheck_start-timer.patch + +------------------------------------------------------------------- +Mon Jun 22 15:33:44 UTC 2020 - Coly Li + +- Detail: adding sync status for cluster device + (bsc#1163727) + 0072-Detail-adding-sync-status-for-cluster-device.patch +- Monitor: improve check_one_sharer() for checking duplicated process + (bsc#1168953) + 0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch + +------------------------------------------------------------------- +Fri Mar 27 03:52:47 UTC 2020 - Neil Brown + +- Don't list XX@.services even for sevice_del_preun + They cannot be stopped without an instance name, + so there is no value in listing them, and it causes + and error with "rpm -e mdadm --nodeps". + (bsc#1093163) + +------------------------------------------------------------------- +Tue Mar 3 05:32:58 UTC 2020 - Coly Li + +- Update for latest mdadm-4.1+ patches, this is required by + jsc#SLE-10078 and jsc#SLE-9348. Mostly the purpose is for + latest Intel IMSM raid support. + The following patches also include previous patches with + new re-ordered prefix numbers. + +- Makefile: install mdadm_env.sh to /usr/lib/mdadm (bsc#1111960) + 0000-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch +- Assemble: keep MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY flag + (jsc#SLE-10078, jsc#SLE-9348) + 0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch +- Document PART-POLICY lines (jsc#SLE-10078, jsc#SLE-9348) + 0002-Document-PART-POLICY-lines.patch +- policy: support devices with multiple paths. + (jsc#SLE-10078, jsc#SLE-9348) + 0003-policy-support-devices-with-multiple-paths.patch +- mdcheck: add systemd unit files to run mdcheck. (bsc#1115407) + 0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch +- Monitor: add system timer to run --oneshot periodically (bsc#1115407) + 0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch +- imsm: update metadata correctly while raid10 double + (jsc#SLE-10078, jsc#SLE-9348) + 0006-imsm-update-metadata-correctly-while-raid10-double-d.patch +- Assemble: mask FAILFAST and WRITEMOSTLY flags when finding + (jsc#SLE-10078, jsc#SLE-9348) + 0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch +- Grow: avoid overflow in compute_backup_blocks() + (jsc#SLE-10078, jsc#SLE-9348) + 0008-Grow-avoid-overflow-in-compute_backup_blocks.patch +- Grow: report correct new chunk size. (jsc#SLE-10078, jsc#SLE-9348) + 0009-Grow-report-correct-new-chunk-size.patch +- policy.c: prevent NULL pointer referencing (bsc#1106078) + 0010-policy.c-prevent-NULL-pointer-referencing.patch +- policy.c: Fix for compiler error (jsc#SLE-10078, jsc#SLE-9348) + 0012-policy.c-Fix-for-compiler-error.patch +- imsm: finish recovery when drive with rebuild fails (bsc#1126975) + 0013-imsm-finish-recovery-when-drive-with-rebuild-fails.patch +- imsm: fix reshape for >2TB drives (jsc#SLE-10078, jsc#SLE-9348) + 0014-imsm-fix-reshape-for-2TB-drives.patch +- Fix spelling typos. (jsc#SLE-10078, jsc#SLE-9348) + 0015-Fix-spelling-typos.patch +- Detail.c: do not skip first character when calling xstrdup in + Detail() (bsc#1123814) + 0016-Detail.c-do-not-skip-first-character-when-calling-xs.patch +- Fix reshape for decreasing data offset (jsc#SLE-10078, jsc#SLE-9348) + 0018-Fix-reshape-for-decreasing-data-offset.patch +- mdadm/tests: add one test case for failfast of raid1 + (jsc#SLE-10078, jsc#SLE-9348) + 0019-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch +- mdmon: don't attempt to manage new arrays when terminating + (bsc#1127526) + 0020-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch +- mdmon: wait for previous mdmon to exit during takeover + (jsc#SLE-10078, jsc#SLE-9348) + 0021-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch +- Assemble: Fix starting array with initial reshape checkpoint + (jsc#SLE-10078, jsc#SLE-9348) + 0022-Assemble-Fix-starting-array-with-initial-reshape-che.patch +- add missing units to --examine (jsc#SLE-10078, jsc#SLE-9348) + 0023-add-missing-units-to-examine.patch +- imsm: fix spare activation for old matrix arrays + (jsc#SLE-10078, jsc#SLE-9348) + 0024-imsm-fix-spare-activation-for-old-matrix-arrays.patch +- Create: Block rounding size to max (jsc#SLE-10078, jsc#SLE-9348) + 0025-Create-Block-rounding-size-to-max.patch +- udev: Add udev rules to create by-partuuid for md device + (jsc#SLE-10078, jsc#SLE-9348) + 0026-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch +- mdmon: fix wrong array state when disk fails during mdmon + (jsc#SLE-10078, jsc#SLE-9348) + 0027-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch +- Enable probe_roms to scan more than 6 roms. (bsc#1156040) + 0028-Enable-probe_roms-to-scan-more-than-6-roms.patch +- super-intel: Fix issue with abs() being irrelevant + (jsc#SLE-10078, jsc#SLE-9348) + 0029-super-intel-Fix-issue-with-abs-being-irrelevant.patch +- mdadm.h: Introduced unaligned {get,put}_unaligned{16,32}() + (jsc#SLE-10078, jsc#SLE-9348) + 0030-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch +- super-intel: Use put_unaligned in split_ull + (jsc#SLE-10078, jsc#SLE-9348) + 0031-super-intel-Use-put_unaligned-in-split_ull.patch +- mdadm: load default sysfs attributes after assemblation + (jsc#SLE-10078, jsc#SLE-9348) + 0032-mdadm-load-default-sysfs-attributes-after-assemblati.patch +- mdadm.h: include sysmacros.h unconditionally + (jsc#SLE-10078, jsc#SLE-9348) + 0033-mdadm.h-include-sysmacros.h-unconditionally.patch +- mdadm: add --no-devices to avoid component devices detail + (bsc#1139709) + 0034-mdadm-add-no-devices-to-avoid-component-devices-deta.patch +- udev: add --no-devices option for calling 'mdadm (bsc#1139709) + 0035-udev-add-no-devices-option-for-calling-mdadm-detail.patch +- imsm: close removed drive fd. (jsc#SLE-10078, jsc#SLE-9348) + 0036-imsm-close-removed-drive-fd.patch +- mdadm: check value returned by snprintf against errors + (jsc#SLE-10078, jsc#SLE-9348) + 0037-mdadm-check-value-returned-by-snprintf-against-error.patch +- mdadm: Introduce new array state 'broken' for raid0/linear + (jsc#SLE-10078, jsc#SLE-9348) + 0038-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch +- mdadm: force a uuid swap on big endian (jsc#SLE-10078, jsc#SLE-9348) + 0039-mdadm-force-a-uuid-swap-on-big-endian.patch +- mdadm/md.4: add the descriptions for bitmap sysfs nodes + (jsc#SLE-10078, jsc#SLE-9348) + 0040-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch +- Init devlist as an array (jsc#SLE-10078, jsc#SLE-9348) + 0041-Init-devlist-as-an-array.patch +- Don't need to check recovery after re-add when no I/O writes + (jsc#SLE-10078, jsc#SLE-9348) + 0042-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch +- udev: allow for udev attribute reading bug. + (jsc#SLE-10078, jsc#SLE-9348) + 0043-udev-allow-for-udev-attribute-reading-bug.patch +- imsm: save current_vol number (jsc#SLE-10078, jsc#SLE-9348) + 0044-imsm-save-current_vol-number.patch +- imsm: allow to specify second volume size + (jsc#SLE-10078, jsc#SLE-9348) + 0045-imsm-allow-to-specify-second-volume-size.patch +- mdcheck: when mdcheck_start is enabled, enable (bsc#1153258) + 0046-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch +- mdcheck: use ${} to pass variable to mdcheck (bsc#1153258) + 0050-mdcheck-use-to-pass-variable-to-mdcheck.patch +- SUSE-mdadm_env.sh: handle MDADM_CHECK_DURATION (bsc#1153258) + 0051-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch +- super-intel: don't mark structs 'packed' unnecessarily + (jsc#SLE-10078, jsc#SLE-9348) + 0052-super-intel-don-t-mark-structs-packed-unnecessarily.patch +- Manage: Remove the legacy code for md driver prior to 0.90.03 + (jsc#SLE-10078, jsc#SLE-9348) + 0053-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch +- Remove last traces of HOT_ADD_DISK (jsc#SLE-10078, jsc#SLE-9348) + 0054-Remove-last-traces-of-HOT_ADD_DISK.patch +- Fix up a few formatting issues (jsc#SLE-10078, jsc#SLE-9348) + 0055-Fix-up-a-few-formatting-issues.patch +- Remove unused code (jsc#SLE-10078, jsc#SLE-9348) + 0056-Remove-unused-code.patch +- imsm: return correct uuid for volume in detail + (jsc#SLE-10078, jsc#SLE-9348) + 0057-imsm-return-correct-uuid-for-volume-in-detail.patch +- imsm: Change the way of printing nvme drives in + (jsc#SLE-10078, jsc#SLE-9348) + 0058-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch +- Create: add support for RAID0 layouts. (bsc#1162479) + 0059-Create-add-support-for-RAID0-layouts.patch +- Assemble: add support for RAID0 layouts. (bsc#1162479) + 0060-Assemble-add-support-for-RAID0-layouts.patch +- Respect $(CROSS_COMPILE) when $(CC) is the default + (jsc#SLE-10078, jsc#SLE-9348) + 0061-Respect-CROSS_COMPILE-when-CC-is-the-default.patch +- Change warning message (jsc#SLE-10078, jsc#SLE-9348) + 0062-Change-warning-message.patch +- mdcheck service can't start succesfully because of syntax + (jsc#SLE-10078, jsc#SLE-9348) + 0063-mdcheck-service-can-t-start-succesfully-because-of-s.patch +- imsm: Update grow manual. (jsc#SLE-10078, jsc#SLE-9348) + 0064-imsm-Update-grow-manual.patch +- Add support for Tebibytes (jsc#SLE-10078, jsc#SLE-9348) + 0065-Add-support-for-Tebibytes.patch +- imsm: fill working_disks according to metadata. + (jsc#SLE-10078, jsc#SLE-9348) + 0066-imsm-fill-working_disks-according-to-metadata.patch +- mdadm.8: add note information for raid0 growing operation + (bsc#1129900) + 0067-mdadm.8-add-note-information-for-raid0-growing-opera.patch +- Remove the legacy whitespace (jsc#SLE-10078, jsc#SLE-9348) + 0068-Remove-the-legacy-whitespace.patch +- imsm: pass subarray id to kill_subarray function + (jsc#SLE-10078, jsc#SLE-9348) + 0069-imsm-pass-subarray-id-to-kill_subarray-function.patch +- imsm: Remove --dump/--restore implementation + (jsc#SLE-10078, jsc#SLE-9348) + 0070-imsm-Remove-dump-restore-implementation.patch + +------------------------------------------------------------------- +Tue Mar 3 05:31:39 UTC 2020 - Coly Li + +- Rename the following patches, they will be listed with new + re-ordered prefix number in following commit, + 0001-Document-PART-POLICY-lines.patch + 0001-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch + 0002-policy-support-devices-with-multiple-paths.patch + 0003-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch + 0004-Monitor-add-system-timer-to-run-oneshot-periodically.patch + 0005-imsm-update-metadata-correctly-while-raid10-double-d.patch + 0006-Grow-avoid-overflow-in-compute_backup_blocks.patch + 0007-Grow-report-correct-new-chunk-size.patch + 0008-policy.c-prevent-NULL-pointer-referencing.patch + 0009-Detail.c-do-not-skip-first-character-when-calling-xs.patch + 0010-imsm-finish-recovery-when-drive-with-rebuild-fails.patch + 0011-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch + 0012-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch + 0013-mdcheck-use-to-pass-variable-to-mdcheck.patch + 0014-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch + 0015-Create-add-support-for-RAID0-layouts.patch + 0016-Assemble-add-support-for-RAID0-layouts.patch + 1002-mdadm.8-add-note-information-for-raid0-growing-opera.patch + +------------------------------------------------------------------- +Tue Mar 3 05:31:21 UTC 2020 - Coly Li + +- Enable probe_roms to scan more than 6 roms. (bsc#1156040) + 0028-Enable-probe_roms-to-scan-more-than-6-roms.patch + +------------------------------------------------------------------- +Tue Mar 3 05:28:56 UTC 2020 - Coly Li + +- Add mdadm fixes from SLE15-SP1 package, +- Create: add support for RAID0 layouts. (bsc#1162479) + 0059-Create-add-support-for-RAID0-layouts.patch +- Assemble: add support for RAID0 layouts. (bsc#1162479) + 0060-Assemble-add-support-for-RAID0-layouts.patch +- mdadm.8: add note information for raid0 growing operation + (bsc#1129900) + 0067-mdadm.8-add-note-information-for-raid0-growing-opera.patch + +------------------------------------------------------------------- +Fri Feb 7 11:31:21 UTC 2020 - Coly Li + +- Create: add support for RAID0 layouts. (bsc#1162479) + 0015-Create-add-support-for-RAID0-layouts.patch +- Assemble: add support for RAID0 layouts. (bsc#1162479) + 0016-Assemble-add-support-for-RAID0-layouts.patch +- mdadm.8: add note information for raid0 growing operation + (bsc#1129900) + 1002-mdadm.8-add-note-information-for-raid0-growing-opera.patch + +------------------------------------------------------------------- +Wed Oct 30 00:10:38 UTC 2019 - Neil Brown + +- 0012-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch + 0013-mdcheck-use-to-pass-variable-to-mdcheck.patch + 0014-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch + Improve mdcheck (bsc#1153258) + +------------------------------------------------------------------- +Thu Mar 28 11:43:38 UTC 2019 - colyli@suse.com + +- imsm: finish recovery when drive with rebuild fails (bsc#1126975) + 0010-imsm-finish-recovery-when-drive-with-rebuild-fails.patch +- mdmon: don't attempt to manage new arrays when terminating + (bsc#1127526) + 0011-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch + +------------------------------------------------------------------- +Tue Feb 12 06:21:48 UTC 2019 - colyli@suse.com + +- Detail.c: do not skip first character when calling xstrdup in + Detail() (bsc#1123814) + 0009-Detail.c-do-not-skip-first-character-when-calling-xs.patch + +------------------------------------------------------------------- +Tue Dec 11 13:52:25 UTC 2018 - Jan Engelhardt + +- Update description. Remove references to historic software. + +------------------------------------------------------------------- +Mon Dec 10 01:52:35 UTC 2018 - Neil Brown + +- 0001-Document-PART-POLICY-lines.patch + 0002-policy-support-devices-with-multiple-paths.patch + 0008-policy.c-prevent-NULL-pointer-referencing.patch + (bsc#1106078) + +- 0003-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch + 0004-Monitor-add-system-timer-to-run-oneshot-periodically.patch + Remove mdadm.cron + Remove crond.mdadm + (bsc#1115407) + +- 0005-imsm-update-metadata-correctly-while-raid10-double-d.patch + 0006-Grow-avoid-overflow-in-compute_backup_blocks.patch + 0007-Grow-report-correct-new-chunk-size.patch + Other useful upstream patches. + +------------------------------------------------------------------- +Wed Oct 17 03:27:21 UTC 2018 - Coly Li + +- Update mdadm code base to mdadm-4.1 + (FATE#325869, bsc#1111960) + - Assorted bug-fixes, minor improvements, and code cleanup + - Add PPL support (alternate change-journalling model) +- Fix Makefile to install mdadm_env.sh to /usr/lib/mdadm/ + (bsc#1111960) + 0001-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch +- Remove the following code base and patches since they are in + mdadm-4.1 already, + - mdadm-4.0.tar.xz + - 0001-Makefile-Fix-date-to-be-output-in-ISO-format.patch + - 0002-imsm-fix-missing-error-message-during-migration.patch + - 0003-Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch + - 0004-mdadm-check-the-nodes-when-operate-clustered-array.patch + - 0005-examine-tidy-up-some-code.patch + - 0006-mdadm-add-man-page-for-symlinks.patch + - 0007-mdadm-add-checking-clustered-bitmap-in-assemble-mode.patch + - 0008-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch + - 0009-mdadm-Specify-enough-length-when-write-to-buffer.patch + - 0010-mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch + - 0011-mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch + - 0012-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch + - 0013-mdadm-Forced-type-conversion-to-avoid-truncation.patch + - 0014-super1-ignore-failfast-flag-for-setting-device-role.patch + - 0015-mdadm-bitmap-fixed-typos-in-comments-of-bitmap.h.patch + - 0016-udev-md-raid-assembly.rules-Skip-non-ready-devices.patch + - 0017-Retry-HOT_REMOVE_DISK-a-few-times.patch + - 0018-mdadm-Build-check-the-level-parameter-when-build-new.patch + - 0019-Introduce-sys_hot_remove_disk.patch + - 0020-Add-force-flag-to-hot_remove_disk.patch + - 0021-Detail-handle-non-existent-arrays-better.patch + - 0022-Generic-support-for-consistency-policy-and-PPL.patch + - 0023-Detail-show-consistency-policy.patch + - 0024-imsm-PPL-support.patch + - 0025-super1-PPL-support.patch + - 0026-Add-ppl-and-no-ppl-options-for-update.patch + - 0027-Grow-support-consistency-policy-change.patch + - 0028-mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch + - 0029-super1-replace-hard-coded-values-with-bit-definition.patch + - 0030-mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch + - 0031-mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch + - 0032-util-Cosmetic-changes.patch + - 0033-Grow-Fixup-a-pile-of-cosmetic-issues.patch + - 0034-Grow-Remove-unnecessary-optimization.patch + - 0035-Grow-Do-not-shadow-an-existing-variable.patch + - 0036-imsm-use-rounded-size-for-metadata-initialization.patch + - 0037-mdadm.c-fix-compile-error-switch-condition-has-boole.patch + - 0038-mdadm-Create-declaring-an-existing-struct-within-sam.patch + - 0039-Create-Fixup-bad-placement-of-logical-in-multi-line-.patch + - 0040-Create-Fixup-various-whitespace-issues.patch + - 0041-mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch + - 0042-mdopen-use-parameters-new_array-to-create-arrays-whe.patch + - 0043-mdadm-manpage-update-manpage-for-readonly-parameter.patch + - 0044-mdadm-manpage-clustered-arrays-don-t-support-array-s.patch + - 0045-maps-Terminate-modes-map-correctly.patch + - 0046-Grow_continue_command-ensure-content-is-properly-ini.patch + - 0047-systemd-mdadm-last-resort-use-ConditionPathExists-in.patch + - 0048-Detail-ensure-export-names-are-acceptable-as-shell-v.patch + - 0049-Grow-set-component-size-prior-to-array-size.patch + - 0050-Grow-don-t-allow-to-enable-PPL-when-reshape-is-in-pr.patch + - 0051-Grow-don-t-allow-array-geometry-change-with-ppl-enab.patch + - 0052-IMSM-Correct-examine-output-for-4k-disks.patch + - 0053-imsm-allow-drives-in-a-container-regardless-of-secto.patch + - 0054-imsm-allocate-buffer-to-support-maximum-sector-size.patch + - 0055-imsm-don-t-allow-disks-with-different-sector-size-in.patch + - 0056-mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch + - 0057-util-Introduce-md_get_array_info.patch + - 0058-Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch + - 0059-util-Introduce-md_get_disk_info.patch + - 0060-util-Introduce-md_set_array_info.patch + - 0061-md_u-Remove-some-unused-ioctl-declarations.patch + - 0062-mdadm-grow-reshape-would-be-stuck-from-raid1-to-raid.patch + - 0063-sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch + - 0064-sysfs-Make-sysfs_init-return-an-error-code.patch + - 0065-util-must_be_container-Use-sysfs_read-GET_VERSION-to.patch + - 0066-util-set_array_info-Simplify-code-since-md_get_versi.patch + - 0067-Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch + - 0068-Build-Stop-bothering-about-supporting-md-driver-olde.patch + - 0069-Grow-Stop-bothering-about-md-driver-versions-older-t.patch + - 0070-Detail-Stop-bothering-about-md-drivers-older-than-0..patch + - 0071-Create-Remove-all-attemps-to-handle-md-driver-older-.patch + - 0072-Manage-Remove-all-references-to-md_get_version.patch + - 0073-Query-Remove-all-references-to-md_get_version.patch + - 0074-bitmap-Remove-use-of-md_get_version.patch + - 0075-mdmon-Stop-bothering-about-md_get_version.patch + - 0076-mdopen-open_mddev-Use-md_get_array_info-to-determine.patch + - 0077-mdassemble-Use-md_get_array_info-to-check-for-valid-.patch + - 0078-Assemble-Assemble-Get-rid-of-last-use-of-md_get_vers.patch + - 0079-util-Finally-kill-off-md_get_version.patch + - 0080-mdadm-Fail-for-kernels-older-than-2.6.15.patch + - 0081-Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch + - 0082-Retire-mdassemble.patch + - 0083-super1-Clean-up-various-style-abuses.patch + - 0084-Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch + - 0085-Assemble-Remove-obsolete-test-for-kernels-older-than.patch + - 0086-Detail-Fixup-ugly-if-foo-abuse.patch + - 0087-Query-Handle-error-returned-by-fstat.patch + - 0088-Query-Use-sysfs-to-obtain-data-if-possible.patch + - 0089-sysfs-Parse-array_state-in-sysfs_read.patch + - 0090-util-Introduce-md_array_active-helper.patch + - 0091-maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch + - 0092-util-Get-rid-of-unused-enough_fd.patch + - 0093-mdadm-retire-mdassemble-in-make-everything.patch + - 0094-Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch + - 0095-Makefile-Default-to-O2-optimization.patch + - 0096-maps-Simplify-implementation-of-map_name.patch + - 0097-Don-t-use-UnSet-with-consistency_policy.patch + - 0098-Detail-determine-array-state-from-sysfs.patch + - 0099-Detail-Respect-code-lines-are-80-character-wide.patch + - 0100-Detail-Reinstate-support-for-not-having-sysfs.patch + - 0101-Incremental-Use-md_array_active-where-applicable.patch + - 0102-Incremental-Cleanup-some-if-statement-spaghetti.patch + - 0103-Create-tell-udev-md-device-is-not-ready-when-first-c.patch + - 0104-Incremental-Use-md_array_active-to-determine-state-o.patch + - 0105-Manage-Manage_ro-Use-md_array_active.patch + - 0106-IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch + - 0107-Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch + - 0108-change-back-0644-permission-for-Grow.c.patch + - 0109-util-md_array_valid-Introduce-md_array_valid-helper.patch + - 0110-kernel-patch-Remove-obsolete-kernel-patches-against-.patch + - 0111-mdassemble-Kill-off-the-last-remains.patch + - 0112-mdadm-util-unify-fstat-checking-blkdev-into-function.patch + - 0113-mdadm-util-unify-stat-checking-blkdev-into-function.patch + - 0114-Fix-typo-in-new-udev-rule.patch + - 0115-Incremental-return-is-not-a-function.patch + - 0116-sysfs-sysfs_read-Count-active_disks-and-failed_disks.patch + - 0117-container_members_max_degradation-Switch-to-using-sy.patch + - 0118-IncrementalScan-Use-md_array_active-instead-of-md_ge.patch + - 0119-Mention-endian-in-documentation-for-update-byte-orde.patch + - 0120-Monitor-Use-md_array_active-instead-of-manually-fidd.patch + - 0121-Monitor-Code-is-80-characters-per-line.patch + - 0122-mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch + - 0123-Allow-more-spare-selection-criteria.patch + - 0124-Add-sector-size-as-spare-selection-criterion.patch + - 0125-Monitor-check_array-Centralize-exit-path.patch + - 0126-Monitor-check_array-Reduce-duplicated-error-handling.patch + - 0127-Monitor-check_array-Declate-mdinfo-instance-globally.patch + - 0128-Monitor-check_array-Read-sysfs-entry-earlier.patch + - 0129-Monitor-check_array-Obtain-RAID-level-from-syfs.patch + - 0130-Monitor-check_array-Get-failed_disks-from-sysfs.patch + - 0131-Monitor-check_array-Get-array_disks-from-sysfs.patch + - 0132-Monitor-check_array-Get-nr_disks-active_disks-and-sp.patch + - 0133-sysfs-sysfs_read-Count-working_disks.patch + - 0134-Monitor-check_array-Use-working_disks-from-sysfs.patch + - 0135-retire-the-APIs-that-driver-no-longer-supports.patch + - 0136-Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch + - 0137-Monitor-mailfrom-is-initialized-correctly.patch + - 0138-Monitor-Fixup-a-pile-of-whitespace-issues.patch + - 0139-mdadm-Uninitialized-variable-rdev.patch + - 0140-super-ddf-sysfs_read-takes-a-pointer-as-device-name-.patch + - 0141-mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch + - 0142-mdadm-Fixup-more-broken-logical-operator-formatting.patch + - 0143-mdadm-Fix-broken-formatting.patch + - 0144-mdadm-Fixup-broken-formatting.patch + - 0145-Detail-don-t-exit-if-ioctl-has-been-successful.patch + - 0146-super1-fix-sb-max_dev-when-adding-a-new-disk-in-line.patch + - 0147-md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch + - 0148-Get-failed-disk-count-from-array-state.patch + - 0149-Monitor-don-t-assume-mdadm-parameter-is-a-block-devi.patch + - 0150-super1-Always-round-data-offset-to-1M.patch + - 0151-mdadm-r5cache-allow-adding-journal-to-array-without-.patch + - 0152-udev-rules-introduce-rules-for-cluster-md-to-confirm.patch + - 0153-Detail-correct-output-for-active-arrays.patch + - 0154-imsm-rebuild-from-2-disk-RAID10.patch + - 0155-Error-messages-should-end-with-a-newline-character.patch + - 0156-Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch + - 0157-super1-only-set-clustered-flag-when-bitmap-is-presen.patch + - 0158-Don-t-use-exit-ERANGE.patch + - 0159-Monitor-containers-don-t-have-the-same-sysfs-propert.patch + - 0160-Monitor-Include-containers-in-spare-migration.patch + - 0161-Detail-differentiate-between-container-and-inactive-.patch + - 0162-mdadm-install-two-more-udev-rules-in-mdadm.spec.patch + - 0163-mdadm-set-journal_clean-after-scanning-all-disks.patch + - 0164-mdadm-bitmap-examine-bitmap-failed-when-bitmap-is-ex.patch + - 0165-mdopen-call-modprobe-md_mod-if-it-might-be-needed.patch + - 0166-lib-devid2kname-should-take-a-dev_t.patch + - 0167-sysfs_init_dev-take-a-dev_t-argument.patch + - 0168-Manage_subdevs-Use-a-dev_t.patch + - 0169-util-Code-is-80-characters-wide.patch + - 0170-Close-mdfd-before-returning-main-function.patch + - 0171-Grow-stop-previous-reshape-process-first.patch + - 0172-imsm-New-disk-controller-domains.patch + - 0173-Monitor-Check-redundancy-for-arrays.patch + - 0174-mdadm-grow-Component-size-must-be-larger-than-chunk-.patch + - 0175-mdadm-manpage-disable-bitmap_resize-for-external-fil.patch + - 0176-mdadm-fixes-some-trivial-typos-in-comments.patch + - 0177-Don-t-abort-starting-the-array-if-kernel-does-not-su.patch + - 0178-super1-Add-support-for-multiple-ppls.patch + - 0179-imsm-Add-support-for-multiple-ppls.patch + - 0180-imsm-validate-multiple-ppls-during-assemble.patch + - 0181-Zeroout-whole-ppl-space-during-creation-force-assemb.patch + - 0182-imsm-switch-to-multiple-ppls-automatically-during-as.patch + - 0183-Grow-fix-switching-on-PPL-during-recovery.patch + - 0184-imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch + - 0185-imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch + - 0186-imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch + - 0187-imsm-use-correct-map-when-validating-ppl.patch + - 0188-imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch + - 0189-Grow-Use-all-80-characters.patch + - 0190-imsm-Set-disk-slot-number.patch + - 0191-mdmon-get-safe-mode-delay-file-descriptor-early.patch + - 0192-mdadm-mdstat-fixup-a-number-of-broken-formatting.patch + - 0193-mdadm-mdstat-correct-the-strncmp-number-4-as-6.patch + - 0194-mdcheck-add-some-logging.patch + - 0195-mdcheck-improve-cleanup.patch + - 0197-mdadm-grow-adding-a-test-to-ensure-resize-was-requir.patch + - 0198-mdadm-mdopen-create-new-function-create_named_array-.patch + - 0199-systemd-add-I-to-description-of-mdadm-last-resort-se.patch + - 0200-Incremental-Use-validate_geometry-instead-of-avail_s.patch + - 0201-imsm-fix-reading-scsi-serial.patch + - 0202-To-support-clustered-raid10.patch + - 0203-imsm-More-precise-message-when-spanned-raid-is-creat.patch + - 0204-sysfs-include-faulty-drive-in-disk-count.patch + - 0205-Monitor-msg-Don-t-print-error-message-if-mdmon-doesn.patch + - 0206-imsm-continue-resync-on-3-disk-RAID10.patch + - 0207-managemon-Don-t-add-disk-to-the-array-after-it-has-s.patch + - 0208-mdadm-grow-correct-the-s-size-1-to-make-max-work.patch + - 0209-policy.c-Avoid-to-take-spare-without-defined-domain-.patch + - 0210-mdadm-allow-clustered-raid10-to-be-created-with-defa.patch + +------------------------------------------------------------------- +Fri Aug 3 18:39:09 UTC 2018 - colyli@suse.com + +- Add missing patches which exist in SLE12-SP3 and should be in + SLE15 too, + - mdadm: improve the dlm locking mechanism for clustered raid + (bsc#1049126) + 0218-mdadm-improve-the-dlm-locking-mechanism-for-clustere.patch + - Assemble: provide protection when clustered raid do assemble + (bsc#1049126) + 0219-Assemble-provide-protection-when-clustered-raid-do-a.patch + - Assemble: cleanup the failure path + (bsc#1049126) + 0220-Assemble-cleanup-the-failure-path.patch + - Assemble: remove the protection when clustered raid do assemble + (bsc#1101348) + 0221-Assemble-remove-the-protection-when-clustered-raid-d.patch + - 1001-display-timeout-status.patch + +------------------------------------------------------------------- +Fri Aug 3 15:55:31 UTC 2018 - colyli@suse.com + +- mdadm.spec + Change %doc to %license for COPYING file, which was warned during + 'osc ci'. + +------------------------------------------------------------------- +Fri Aug 3 13:04:18 UTC 2018 - colyli@suse.com + +- imsm: change reserved space to 4MB + (bsc#1101110) + 0212-imsm-change-reserved-space-to-4MB.patch +- imsm: add functions to get and set imsm dev size + (bsc#1101110) + 0213-imsm-add-functions-to-get-and-set-imsm-dev-size.patch +- imsm: pass already existing map to imsm_num_data_members + (bsc#1101110) + 0214-imsm-pass-already-existing-map-to-imsm_num_data_memb.patch +- imsm: do not use blocks_per_member in array size calculations + (bsc#1101110) + 0215-imsm-do-not-use-blocks_per_member-in-array-size-calc.patch +- imsm: correct num_data_stripes in metadata map for migration + (bsc#1101110) + 0216-imsm-correct-num_data_stripes-in-metadata-map-for-mi.patch +- mdadm/grow: correct size and chunk_size casting + (bsc#1095177) + 0217-mdadm-grow-correct-size-and-chunk_size-casting.patch + +------------------------------------------------------------------- +Wed Jun 27 16:01:33 UTC 2018 - colyli@suse.com + +- Assemble: prevent segfault with faulty "best" devices + (bsc#1082766, bsc#1095729) + 0211-Assemble-prevent-segfault-with-faulty-best-devices.patch + +------------------------------------------------------------------- +Mon Mar 5 03:25:18 UTC 2018 - gqjiang@suse.com + +- mdadm: allow clustered raid10 to be created with default layout + (bsc#1083881) + 0210-mdadm-allow-clustered-raid10-to-be-created-with-defa.patch + +------------------------------------------------------------------- +Sat Feb 10 14:34:01 UTC 2018 - colyli@suse.com + +- policy.c: Avoid to take spare without defined domain by imsm + (bsc#1076588) + 0209-policy.c-Avoid-to-take-spare-without-defined-domain-.patch + +------------------------------------------------------------------- +Tue Jan 9 03:30:48 UTC 2018 - zlliu@suse.com + +- 0208-mdadm-grow-correct-the-s-size-1-to-make-max-work.patch + (bsc#1074949) + +------------------------------------------------------------------- +Wed Jan 3 14:44:06 UTC 2018 - colyli@suse.com + +- 0207-managemon-Don-t-add-disk-to-the-array-after-it-has-s.patch + (bsc#1073862) + +------------------------------------------------------------------- +Mon Dec 4 17:11:14 UTC 2017 - colyli@suse.com + +- Update mdadm for SLE15, for bug fixes and new feature enhancement +- 1000-The-mdcheck-script-now-adds-messages-to-the-system.patch is + removed because upstream has similar fix with almost identical + funcationality. +- The following patches are not deleted indeed, they are renamed + and added into all other new-added patches with different perfix + numbers, + 0038-Create-Fixup-bad-placement-of-logical-in-multi-line-.patch + 0039-Create-Fixup-various-whitespace-issues.patch + 0040-mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch + 0041-mdopen-use-parameters-new_array-to-create-arrays-whe.patch + 0042-mdadm-manpage-update-manpage-for-readonly-parameter.patch + 0043-mdadm-manpage-clustered-arrays-don-t-support-array-s.patch + 0044-maps-Terminate-modes-map-correctly.patch + 0045-Grow_continue_command-ensure-content-is-properly-ini.patch + 0046-systemd-mdadm-last-resort-use-ConditionPathExists-in.patch + 0047-Detail-ensure-export-names-are-acceptable-as-shell-v.patch + 0048-Grow-set-component-size-prior-to-array-size.patch + 0049-Grow-don-t-allow-to-enable-PPL-when-reshape-is-in-pr.patch + 0050-Grow-don-t-allow-array-geometry-change-with-ppl-enab.patch + 0051-IMSM-Correct-examine-output-for-4k-disks.patch + 0052-imsm-allow-drives-in-a-container-regardless-of-secto.patch + 0053-imsm-allocate-buffer-to-support-maximum-sector-size.patch + 0054-imsm-don-t-allow-disks-with-different-sector-size-in.patch + 0055-Allow-more-spare-selection-criteria.patch + 0056-Add-sector-size-as-spare-selection-criterion.patch + 0057-super1-fix-sb-max_dev-when-adding-a-new-disk-in-line.patch + 0058-super1-only-set-clustered-flag-when-bitmap-is-presen.patch + 0059-To-support-clustered-raid10.patch + 0060-udev-rules-introduce-rules-for-cluster-md-to-confirm.patch +- The following patche set includes the above renamed patches, + they have bug fixes for bsc#1068030, bsc#1069165, bsc#1069167, + and some other fixes and enhancement for raid5 ppl, imsm, and + general mdadm code, + 0038-mdadm-Create-declaring-an-existing-struct-within-sam.patch + 0039-Create-Fixup-bad-placement-of-logical-in-multi-line-.patch + 0040-Create-Fixup-various-whitespace-issues.patch + 0041-mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch + 0042-mdopen-use-parameters-new_array-to-create-arrays-whe.patch + 0043-mdadm-manpage-update-manpage-for-readonly-parameter.patch + 0044-mdadm-manpage-clustered-arrays-don-t-support-array-s.patch + 0045-maps-Terminate-modes-map-correctly.patch + 0046-Grow_continue_command-ensure-content-is-properly-ini.patch + 0047-systemd-mdadm-last-resort-use-ConditionPathExists-in.patch + 0048-Detail-ensure-export-names-are-acceptable-as-shell-v.patch + 0049-Grow-set-component-size-prior-to-array-size.patch + 0050-Grow-don-t-allow-to-enable-PPL-when-reshape-is-in-pr.patch + 0051-Grow-don-t-allow-array-geometry-change-with-ppl-enab.patch + 0052-IMSM-Correct-examine-output-for-4k-disks.patch + 0053-imsm-allow-drives-in-a-container-regardless-of-secto.patch + 0054-imsm-allocate-buffer-to-support-maximum-sector-size.patch + 0055-imsm-don-t-allow-disks-with-different-sector-size-in.patch + 0056-mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch + 0057-util-Introduce-md_get_array_info.patch + 0058-Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch + 0059-util-Introduce-md_get_disk_info.patch + 0060-util-Introduce-md_set_array_info.patch + 0061-md_u-Remove-some-unused-ioctl-declarations.patch + 0062-mdadm-grow-reshape-would-be-stuck-from-raid1-to-raid.patch + 0063-sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch + 0064-sysfs-Make-sysfs_init-return-an-error-code.patch + 0065-util-must_be_container-Use-sysfs_read-GET_VERSION-to.patch + 0066-util-set_array_info-Simplify-code-since-md_get_versi.patch + 0067-Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch + 0068-Build-Stop-bothering-about-supporting-md-driver-olde.patch + 0069-Grow-Stop-bothering-about-md-driver-versions-older-t.patch + 0070-Detail-Stop-bothering-about-md-drivers-older-than-0..patch + 0071-Create-Remove-all-attemps-to-handle-md-driver-older-.patch + 0072-Manage-Remove-all-references-to-md_get_version.patch + 0073-Query-Remove-all-references-to-md_get_version.patch + 0074-bitmap-Remove-use-of-md_get_version.patch + 0075-mdmon-Stop-bothering-about-md_get_version.patch + 0076-mdopen-open_mddev-Use-md_get_array_info-to-determine.patch + 0077-mdassemble-Use-md_get_array_info-to-check-for-valid-.patch + 0078-Assemble-Assemble-Get-rid-of-last-use-of-md_get_vers.patch + 0079-util-Finally-kill-off-md_get_version.patch + 0080-mdadm-Fail-for-kernels-older-than-2.6.15.patch + 0081-Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch + 0082-Retire-mdassemble.patch + 0083-super1-Clean-up-various-style-abuses.patch + 0084-Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch + 0085-Assemble-Remove-obsolete-test-for-kernels-older-than.patch + 0086-Detail-Fixup-ugly-if-foo-abuse.patch + 0087-Query-Handle-error-returned-by-fstat.patch + 0088-Query-Use-sysfs-to-obtain-data-if-possible.patch + 0089-sysfs-Parse-array_state-in-sysfs_read.patch + 0090-util-Introduce-md_array_active-helper.patch + 0091-maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch + 0092-util-Get-rid-of-unused-enough_fd.patch + 0093-mdadm-retire-mdassemble-in-make-everything.patch + 0094-Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch + 0095-Makefile-Default-to-O2-optimization.patch + 0096-maps-Simplify-implementation-of-map_name.patch + 0097-Don-t-use-UnSet-with-consistency_policy.patch + 0098-Detail-determine-array-state-from-sysfs.patch + 0099-Detail-Respect-code-lines-are-80-character-wide.patch + 0100-Detail-Reinstate-support-for-not-having-sysfs.patch + 0101-Incremental-Use-md_array_active-where-applicable.patch + 0102-Incremental-Cleanup-some-if-statement-spaghetti.patch + 0103-Create-tell-udev-md-device-is-not-ready-when-first-c.patch + 0104-Incremental-Use-md_array_active-to-determine-state-o.patch + 0105-Manage-Manage_ro-Use-md_array_active.patch + 0106-IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch + 0107-Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch + 0108-change-back-0644-permission-for-Grow.c.patch + 0109-util-md_array_valid-Introduce-md_array_valid-helper.patch + 0110-kernel-patch-Remove-obsolete-kernel-patches-against-.patch + 0111-mdassemble-Kill-off-the-last-remains.patch + 0112-mdadm-util-unify-fstat-checking-blkdev-into-function.patch + 0113-mdadm-util-unify-stat-checking-blkdev-into-function.patch + 0114-Fix-typo-in-new-udev-rule.patch + 0115-Incremental-return-is-not-a-function.patch + 0116-sysfs-sysfs_read-Count-active_disks-and-failed_disks.patch + 0117-container_members_max_degradation-Switch-to-using-sy.patch + 0118-IncrementalScan-Use-md_array_active-instead-of-md_ge.patch + 0119-Mention-endian-in-documentation-for-update-byte-orde.patch + 0120-Monitor-Use-md_array_active-instead-of-manually-fidd.patch + 0121-Monitor-Code-is-80-characters-per-line.patch + 0122-mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch + 0123-Allow-more-spare-selection-criteria.patch + 0124-Add-sector-size-as-spare-selection-criterion.patch + 0125-Monitor-check_array-Centralize-exit-path.patch + 0126-Monitor-check_array-Reduce-duplicated-error-handling.patch + 0127-Monitor-check_array-Declate-mdinfo-instance-globally.patch + 0128-Monitor-check_array-Read-sysfs-entry-earlier.patch + 0129-Monitor-check_array-Obtain-RAID-level-from-syfs.patch + 0130-Monitor-check_array-Get-failed_disks-from-sysfs.patch + 0131-Monitor-check_array-Get-array_disks-from-sysfs.patch + 0132-Monitor-check_array-Get-nr_disks-active_disks-and-sp.patch + 0133-sysfs-sysfs_read-Count-working_disks.patch + 0134-Monitor-check_array-Use-working_disks-from-sysfs.patch + 0135-retire-the-APIs-that-driver-no-longer-supports.patch + 0136-Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch + 0137-Monitor-mailfrom-is-initialized-correctly.patch + 0138-Monitor-Fixup-a-pile-of-whitespace-issues.patch + 0139-mdadm-Uninitialized-variable-rdev.patch + 0140-super-ddf-sysfs_read-takes-a-pointer-as-device-name-.patch + 0141-mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch + 0142-mdadm-Fixup-more-broken-logical-operator-formatting.patch + 0143-mdadm-Fix-broken-formatting.patch + 0144-mdadm-Fixup-broken-formatting.patch + 0145-Detail-don-t-exit-if-ioctl-has-been-successful.patch + 0146-super1-fix-sb-max_dev-when-adding-a-new-disk-in-line.patch + 0147-md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch + 0148-Get-failed-disk-count-from-array-state.patch + 0149-Monitor-don-t-assume-mdadm-parameter-is-a-block-devi.patch + 0150-super1-Always-round-data-offset-to-1M.patch + 0151-mdadm-r5cache-allow-adding-journal-to-array-without-.patch + 0152-udev-rules-introduce-rules-for-cluster-md-to-confirm.patch + 0153-Detail-correct-output-for-active-arrays.patch + 0154-imsm-rebuild-from-2-disk-RAID10.patch (bsc#1069165) + 0155-Error-messages-should-end-with-a-newline-character.patch + 0156-Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch + 0157-super1-only-set-clustered-flag-when-bitmap-is-presen.patch + 0158-Don-t-use-exit-ERANGE.patch + 0159-Monitor-containers-don-t-have-the-same-sysfs-propert.patch + 0160-Monitor-Include-containers-in-spare-migration.patch + 0161-Detail-differentiate-between-container-and-inactive-.patch + 0162-mdadm-install-two-more-udev-rules-in-mdadm.spec.patch + 0163-mdadm-set-journal_clean-after-scanning-all-disks.patch + 0164-mdadm-bitmap-examine-bitmap-failed-when-bitmap-is-ex.patch + 0165-mdopen-call-modprobe-md_mod-if-it-might-be-needed.patch + 0166-lib-devid2kname-should-take-a-dev_t.patch + 0167-sysfs_init_dev-take-a-dev_t-argument.patch + 0168-Manage_subdevs-Use-a-dev_t.patch + 0169-util-Code-is-80-characters-wide.patch + 0170-Close-mdfd-before-returning-main-function.patch + 0171-Grow-stop-previous-reshape-process-first.patch + 0172-imsm-New-disk-controller-domains.patch + 0173-Monitor-Check-redundancy-for-arrays.patch + 0174-mdadm-grow-Component-size-must-be-larger-than-chunk-.patch + 0175-mdadm-manpage-disable-bitmap_resize-for-external-fil.patch + 0176-mdadm-fixes-some-trivial-typos-in-comments.patch + (The following 12 patches are specifically for bsc#1068030) + 0177-Don-t-abort-starting-the-array-if-kernel-does-not-su.patch + 0178-super1-Add-support-for-multiple-ppls.patch + 0179-imsm-Add-support-for-multiple-ppls.patch + 0180-imsm-validate-multiple-ppls-during-assemble.patch + 0181-Zeroout-whole-ppl-space-during-creation-force-assemb.patch + 0182-imsm-switch-to-multiple-ppls-automatically-during-as.patch + 0183-Grow-fix-switching-on-PPL-during-recovery.patch + 0184-imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch + 0185-imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch + 0186-imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch + 0187-imsm-use-correct-map-when-validating-ppl.patch + 0188-imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch + 0189-Grow-Use-all-80-characters.patch + 0190-imsm-Set-disk-slot-number.patch + (The following 1 patch is specifically for bsc#1069167) + 0191-mdmon-get-safe-mode-delay-file-descriptor-early.patch + 0192-mdadm-mdstat-fixup-a-number-of-broken-formatting.patch + 0193-mdadm-mdstat-correct-the-strncmp-number-4-as-6.patch + 0194-mdcheck-add-some-logging.patch + 0195-mdcheck-improve-cleanup.patch + 0196-Move-mdadm_env.sh-out-of-usr-lib-systemd.patch + 0197-mdadm-grow-adding-a-test-to-ensure-resize-was-requir.patch + 0198-mdadm-mdopen-create-new-function-create_named_array-.patch + 0199-systemd-add-I-to-description-of-mdadm-last-resort-se.patch + 0200-Incremental-Use-validate_geometry-instead-of-avail_s.patch + 0201-imsm-fix-reading-scsi-serial.patch + 0202-To-support-clustered-raid10.patch + 0203-imsm-More-precise-message-when-spanned-raid-is-creat.patch + 0204-sysfs-include-faulty-drive-in-disk-count.patch + 0205-Monitor-msg-Don-t-print-error-message-if-mdmon-doesn.patch + 0206-imsm-continue-resync-on-3-disk-RAID10.patch + +------------------------------------------------------------------- +Fri Nov 24 01:26:09 UTC 2017 - gqjiang@suse.com + +- Add udev rules for cluster-md to confirm device (fate#316335) + 0060-udev-rules-introduce-rules-for-cluster-md-to-confirm.patch + +------------------------------------------------------------------- +Thu Nov 23 13:40:30 UTC 2017 - rbrown@suse.com + +- Replace references to /var/adm/fillup-templates with new + %_fillupdir macro (boo#1069468) + +------------------------------------------------------------------- +Wed Nov 15 01:27:06 UTC 2017 - gqjiang@suse.com + +- Add one mdadm patch to support clustered raid10 (fate#323171) + 0059-To-support-clustered-raid10.patch + +------------------------------------------------------------------- +Mon Aug 21 16:44:54 UTC 2017 - colyli@suse.com + +- SLE15 continues to use mdadm-4.0, synchronize mdadm package from + SLE12-SP3 to SLE15, re-order all patches. + +- Rename the following patches, they are deleted and re-add in next + part of patches + 0001-Generic-support-for-consistency-policy-and-PPL.patch + 0002-Detail-show-consistency-policy.patch + 0002-The-mdcheck-script-now-adds-messages-to-the-system.patch + 0003-imsm-PPL-support.patch + 0004-super1-PPL-support.patch + 0005-Add-ppl-and-no-ppl-options-for-update.patch + 0006-Grow-support-consistency-policy-change.patch + 0007-udev-md-raid-assembly.rules-Skip-non-ready-devices.patch + 0008-Retry-HOT_REMOVE_DISK-a-few-times.patch + 0009-Introduce-sys_hot_remove_disk.patch + 0010-Add-force-flag-to-hot_remove_disk.patch + 0011-Detail-handle-non-existent-arrays-better.patch + +- Synchronize patches from mdadm of SLE12-SP3, the above renamed + patches are re-add here, + 0001-Makefile-Fix-date-to-be-output-in-ISO-format.patch + 0002-imsm-fix-missing-error-message-during-migration.patch + 0003-Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch + 0004-mdadm-check-the-nodes-when-operate-clustered-array.patch + 0005-examine-tidy-up-some-code.patch + 0006-mdadm-add-man-page-for-symlinks.patch + 0007-mdadm-add-checking-clustered-bitmap-in-assemble-mode.patch + 0008-mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch + 0009-mdadm-Specify-enough-length-when-write-to-buffer.patch + 0010-mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch + 0011-mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch + 0012-Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch + 0013-mdadm-Forced-type-conversion-to-avoid-truncation.patch + 0014-super1-ignore-failfast-flag-for-setting-device-role.patch + 0015-mdadm-bitmap-fixed-typos-in-comments-of-bitmap.h.patch + 0016-udev-md-raid-assembly.rules-Skip-non-ready-devices.patch + 0017-Retry-HOT_REMOVE_DISK-a-few-times.patch + 0018-mdadm-Build-check-the-level-parameter-when-build-new.patch + 0019-Introduce-sys_hot_remove_disk.patch + 0020-Add-force-flag-to-hot_remove_disk.patch + 0021-Detail-handle-non-existent-arrays-better.patch + 0022-Generic-support-for-consistency-policy-and-PPL.patch + 0023-Detail-show-consistency-policy.patch + 0024-imsm-PPL-support.patch + 0025-super1-PPL-support.patch + 0026-Add-ppl-and-no-ppl-options-for-update.patch + 0027-Grow-support-consistency-policy-change.patch + 0028-mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch + 0029-super1-replace-hard-coded-values-with-bit-definition.patch + 0030-mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch + 0031-mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch + 0032-util-Cosmetic-changes.patch + 0033-Grow-Fixup-a-pile-of-cosmetic-issues.patch + 0034-Grow-Remove-unnecessary-optimization.patch + 0035-Grow-Do-not-shadow-an-existing-variable.patch + 0036-imsm-use-rounded-size-for-metadata-initialization.patch + 0037-mdadm.c-fix-compile-error-switch-condition-has-boole.patch + 0038-Create-Fixup-bad-placement-of-logical-in-multi-line-.patch + 0039-Create-Fixup-various-whitespace-issues.patch + 0040-mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch + 0041-mdopen-use-parameters-new_array-to-create-arrays-whe.patch + 0042-mdadm-manpage-update-manpage-for-readonly-parameter.patch + 0043-mdadm-manpage-clustered-arrays-don-t-support-array-s.patch + 0044-maps-Terminate-modes-map-correctly.patch + 0045-Grow_continue_command-ensure-content-is-properly-ini.patch + 0046-systemd-mdadm-last-resort-use-ConditionPathExists-in.patch + 0047-Detail-ensure-export-names-are-acceptable-as-shell-v.patch + 0048-Grow-set-component-size-prior-to-array-size.patch + 0049-Grow-don-t-allow-to-enable-PPL-when-reshape-is-in-pr.patch + 0050-Grow-don-t-allow-array-geometry-change-with-ppl-enab.patch + 0051-IMSM-Correct-examine-output-for-4k-disks.patch + 0052-imsm-allow-drives-in-a-container-regardless-of-secto.patch + 0053-imsm-allocate-buffer-to-support-maximum-sector-size.patch + 0054-imsm-don-t-allow-disks-with-different-sector-size-in.patch + 0055-Allow-more-spare-selection-criteria.patch + 0056-Add-sector-size-as-spare-selection-criterion.patch + 0057-super1-fix-sb-max_dev-when-adding-a-new-disk-in-line.patch + 0058-super1-only-set-clustered-flag-when-bitmap-is-presen.patch + 1000-The-mdcheck-script-now-adds-messages-to-the-system.patch + +------------------------------------------------------------------- +Fri Mar 24 04:10:22 UTC 2017 - nfbrown@suse.com + +- New upstream release 4.0 + Multiple bugfixes and various enhancements + including IMSM support for bad blocks and 4K block devices. + (FATE#321941) + +- DELETE 0001-super1-Clear-memory-allocated-for-superblock-bitmap-.patch + this was included upstream + +- 0001-Generic-support-for-consistency-policy-and-PPL.patch +- 0002-Detail-show-consistency-policy.patch +- 0003-imsm-PPL-support.patch +- 0004-super1-PPL-support.patch +- 0005-Add-ppl-and-no-ppl-options-for-update.patch +- 0006-Grow-support-consistency-policy-change.patch + Add support for Partial Parity Logs + (FATE#321941) + +- 0007-udev-md-raid-assembly.rules-Skip-non-ready-devices.patch + (bsc#956236) + +- 0008-Retry-HOT_REMOVE_DISK-a-few-times.patch + (bsc#808647) +- 0009-Introduce-sys_hot_remove_disk.patch + (bsc#974154) +- 0010-Add-force-flag-to-hot_remove_disk.patch + (bsc#808647) +- 0011-Detail-handle-non-existent-arrays-better.patch + (bsc#966773) + +------------------------------------------------------------------- +Sun May 22 15:01:13 UTC 2016 - bill@merriam.net + +- Added 0002-The-mdcheck-script-now-adds-messages-to-the-system.patch + The mdcheck bash script now writes messages to the syslog about + progress with check. + +------------------------------------------------------------------- +Fri May 20 05:13:48 UTC 2016 - neilb@suse.com + +- Do not list XXX@.service files for anything but service_del_preun. + They cannot be restarted by systemctl as they are + just templates. They don't need to be restarted + at reinstall anyway. + (bsc#979749) + +------------------------------------------------------------------- +Wed May 4 04:56:42 UTC 2016 - neilb@suse.com + +- New upstream release mdadm-3.4 + Adds support for clustered-raid1 and journalled raid5 +- 0001-super1-Clear-memory-allocated-for-superblock-bitmap-.patch + Important upstream bugfix relating to uninialised memory. + +------------------------------------------------------------------- +Thu Dec 10 17:07:40 CET 2015 - tiwai@suse.de + +- Add missing pre-requres for initrd macros (boo#958562) + +------------------------------------------------------------------- +Mon Sep 14 13:21:33 UTC 2015 - dimstar@opensuse.org + +- Own %{_systemdshutdowndir} in case nothing else does. This + ensures build success even if systemd-mini does not own it + (happens in some versions of our package). + +------------------------------------------------------------------- +Mon Aug 31 11:43:43 UTC 2015 - dimstar@opensuse.org + +- Do not BuildRequire systemd: it conflicts with systemd-mini, + pulled in by systemd-mini-devel (due to BuildRequires: + pkgconfig(systemd)). The reason systemd was added as a + buildrequires was for 'something' to onw + /usr/lib/systemd/system-shutdown/; systemd-mini does that also + for us. + +------------------------------------------------------------------- +Mon Aug 3 06:25:56 UTC 2015 - nfbrown@suse.com + +- new upstream version 3.3.4. Important bugfix + to honour IMSM ROM settings when RAID is disabled. + (bsc#939748 bsc#937363) + +------------------------------------------------------------------- +Mon Jul 27 04:17:43 UTC 2015 - nfbrown@suse.com + +- new upstream version 3.3.3. Lots of bug fixes, particular + "mdadm --assemble --force" would often not do the right thing + for RAID5. + +- 0001-Grow-Do-not-try-to-restart-if-reshape-is-running.patch + 0001-Grow-fix-removal-of-line-in-wrong-case.patch + 0001-IMSM-Add-warning-message-when-assemble-spanned-conta.patch + 0001-Makefile-install-mdadm-grow-continue-.service.patch + mdcheck-careful.patch + mdcheck-no-devices.fix + + All removed as now included upstream. + + +------------------------------------------------------------------- +Mon Jul 13 09:19:36 UTC 2015 - werner@suse.de + +- Make it build, that is build-require pkgconfig of udev and the + package systemd as this one is the owner of the directory + /usr/lib/systemd/system-shutdown + +------------------------------------------------------------------- +Mon Mar 2 20:33:12 UTC 2015 - mgorse@suse.com + +- 0001-IMSM-Add-warning-message-when-assemble-spanned-conta.patch + (bnc#882634) + +- 0001-Grow-Do-not-try-to-restart-if-reshape-is-running.patch + (bnc#887773) + +------------------------------------------------------------------- +Tue Feb 3 23:40:32 UTC 2015 - nfbrown@suse.com + +- mdcheck-careful.patch + Be careful about reading all output of "mdadm --detail --export" + as shell commands - it isn't quoted. + (bnc#910500) + +------------------------------------------------------------------- +Mon Nov 3 00:23:45 UTC 2014 - nfbrown@suse.com + +- mdcheck-no-devices.fix + mdcheck mustn't report an error if not md devices + exist (bnc#903051) + +------------------------------------------------------------------- +Mon Sep 29 01:23:13 UTC 2014 - nfbrown@suse.com + +- cron.d.mdadm: add correct PATH setting + (bnc#898239) + +------------------------------------------------------------------- +Tue Sep 16 01:04:36 UTC 2014 - nfbrown@suse.com + +- Add cron job to run 'mdcheck' regularly to + verify all md arrays. (bnc#869261) + +------------------------------------------------------------------- +Fri Jul 25 11:48:12 UTC 2014 - p.drouand@gmail.com + +- Remove insserv dependency; the package has been moved to systemd + init system +- Remove redundant %clean section + +------------------------------------------------------------------- +Mon Jul 7 01:52:35 UTC 2014 - nfbrown@suse.com + +- Remove mkinitrd scripts again. "libguestfs" now + includes them so "guestfs" does not need us to. + (bnc#883873) + +------------------------------------------------------------------- +Thu Jun 26 03:08:15 UTC 2014 - nfbrown@suse.com + +- 0001-Grow-fix-removal-of-line-in-wrong-case.patch + (bnc#881530) + +------------------------------------------------------------------- +Thu Jun 26 02:54:05 UTC 2014 - nfbrown@suse.com + +- add mkinitrd scripts back in. They are needed by + "guestfs" + (bnc#883873) + +------------------------------------------------------------------- +Thu Jun 12 02:08:31 UTC 2014 - nfbrown@suse.com + +- mdadm.spec: change calling of mkinitrd to use the + %regenerate_initrd_{post,posttrans} macros to optimise + initrd regeneration. (bnc#881780) + +------------------------------------------------------------------- +Tue Jun 10 04:05:48 UTC 2014 - nfbrown@suse.com + +- new upstream release 3.3.1, incorporates all current patches + and includes assorted other minor fixes. +- 0001-Makefile-install-mdadm-grow-continue-.service.patch + make sure mdadm-grow-continue.service is installed properly. +- remove mkinitrd files, we now use dracut + +- Delete 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch +- Delete 0001-DDF-mark-missing-on-assembly-device-properly.patch +- Delete 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch +- Delete 0001-systemd-various-fixes-for-boot-with-container-arrays.patch +- Delete 0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch +- Delete 0002-DDF-guard-against-pdnum-being-negative.patch +- Delete 0003-Assemble-change-load_devices-to-return-most_recent-s.patch +- Delete 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch +- Delete 0003-Work-around-architectures-having-statfs.f_type-defin.patch +- Delete 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch +- Delete 0004-DDF-report-seq-counter-as-events.patch +- Delete 0005-DDF-when-first-activating-an-array-record-any-missin.patch +- Delete Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch +- Delete Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch +- Delete Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch +- Delete DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch +- Delete DDF-allow-for-possibility-that-there-is-no-secondary.patch +- Delete DDF-brief_examine_subarrays_ddf-print-array-name.patch +- Delete DDF-compare_super_ddf-fix-sequence-number-check.patch +- Delete DDF-factor-out-array-name-generation.patch +- Delete DDF-fix-detection-of-failed-devices-during-assembly.patch +- Delete DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch +- Delete DDF-really-ignore-DDF-metadata-on-partitions.patch +- Delete Grow-fix-problems-with-prematurely-aborting-of-resha.patch +- Delete IMSM-don-t-crash-when-creating-an-array-with-missing.patch +- Delete Incremental-add-export-handling.patch +- Delete Incremental-improve-support-for-DEVICE-based-restric.patch +- Delete Make-IRs-and-run-work-properly-for-containers.patch +- Delete Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch +- Delete Monitor-write-meta-data-in-readonly-state-sometimes.patch +- Delete Restructure-assemble_container_content-and-improve-m.patch +- Delete config-set-auto_seen-after-processing-the-auto-line.patch +- Delete mdmon-.service-remove-over-ride-of-Standard-IO.patch +- Delete mdmon-don-t-complain-about-notifying-parent-when-the.patch +- Delete mdmon-honour-offroot-again.patch +- Delete mdmonitor +- Delete policy-NULL-path-isn-t-really-acceptable-use-the-dev.patch +- Delete systemd-mdadm-last-resort@.service +- Delete systemd-mdadm-last-resort@.timer +- Delete systemd-mdmon-set-IMSM_NO_PLATFORM-1.patch +- Delete udev-rules-try-mdadm-I-on-change-events.patch +- Delete udev-rules.degraded + +------------------------------------------------------------------- +Tue Apr 8 07:38:42 UTC 2014 - nfbrown@suse.com + +- 0001-systemd-various-fixes-for-boot-with-container-arrays.patch + various fixes to improve boot-from-DDF or IMSM + (bnc#866660) + +------------------------------------------------------------------- +Wed Apr 2 04:41:53 UTC 2014 - nfbrown@suse.com + +- 0001-DDF-mark-missing-on-assembly-device-properly.patch +- 0002-DDF-guard-against-pdnum-being-negative.patch +- 0003-DDF-fix-possible-mdmon-crash-when-updating-metadata.patch +- 0004-DDF-Don-t-fail-compare_super_ddf-due-to-re-configure.patch + More upstream DDF fixes (bnc#866660) + +------------------------------------------------------------------- +Wed Mar 26 04:00:51 UTC 2014 - nfbrown@suse.com + +- 0001-mdmon-.service-Change-type-of-process-start-up-to-fo.patch +- 0003-Work-around-architectures-having-statfs.f_type-defin.patch +- 0004-DDF-report-seq-counter-as-events.patch +- 0005-DDF-when-first-activating-an-array-record-any-missin.patch + Two fixes for DDF (bnc#866660) and a couple of other upstream fixes + just for good measure. + +------------------------------------------------------------------- +Tue Mar 4 22:48:20 UTC 2014 - nfbrown@suse.com + +- 0001-Assemble-allow-load_devices-to-change-the-st-which-i.patch + 0002-Assemble-re-arrange-freeing-of-tst-in-load_devices.patch + 0003-Assemble-change-load_devices-to-return-most_recent-s.patch + Allow RAID5 to be assembled even when firs device listed recently + failed (bnc#865221) + +------------------------------------------------------------------- +Wed Jan 22 23:45:34 UTC 2014 - nfbrown@suse.com + +- remove boot.md. It no longer does anything useful. + +------------------------------------------------------------------- +Wed Jan 22 04:54:22 UTC 2014 - nfbrown@suse.com + +- mdmonitor + run "mdadm --monitor" from systemd instead of init.d + sciprt (bnc#849523) +- remove mdadmd due to above. +- udev-rules-try-mdadm-I-on-change-events.patch + (bnc#851993) +- policy-NULL-path-isn-t-really-acceptable-use-the-dev.patch +- DDF-really-ignore-DDF-metadata-on-partitions.patch +- Assemble-avoid-infinite-loop-when-auto-assembling-pa.patch +- DDF-fix-detection-of-failed-devices-during-assembly.patch +- Grow-fix-problems-with-prematurely-aborting-of-resha.patch +- IMSM-don-t-crash-when-creating-an-array-with-missing.patch +- mdmon-don-t-complain-about-notifying-parent-when-the.patch +- systemd-mdmon-set-IMSM_NO_PLATFORM-1.patch +- mdmon-.service-remove-over-ride-of-Standard-IO.patch + Various upstream bug fixes. + +------------------------------------------------------------------- +Wed Dec 4 23:57:16 UTC 2013 - nfbrown@suse.com + +- Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch + Ensure fsck/mount don't find an md array to be BUSY + the moment it appears. +- mkinitrd-setup.sh: Make the array device names in + /etc/mdadm.conf in the initrd match those in /etc/mdadm.conf + in the root filesystem. (bnc#851993) + +------------------------------------------------------------------- +Tue Dec 3 03:06:07 UTC 2013 - nfbrown@suse.com + +- Restructure-assemble_container_content-and-improve-m.patch +- Incremental-add-export-handling.patch +- udev-rules.degraded +- systemd-mdadm-last-resort@.service +- systemd-mdadm-last-resort@.timer + Teach systemd to start degraded arrays after a timeout if + some missing devices never appear (bnc#832501) +- Incremental-improve-support-for-DEVICE-based-restric.patch + Teach "mdadm --incremental" to handle "DEVICE" lists from + mdadm.conf properly (bnc@851993) + +------------------------------------------------------------------- +Mon Nov 11 00:45:03 UTC 2013 - nfbrown@suse.com + + +- DDF-handle-fake-RAIDs-with-changing-subarray-UUIDs.patch +- DDF-compare_super_ddf-fix-sequence-number-check.patch +- Monitor-don-t-set-arrays-dirty-after-transition-to-r.patch +- DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch +- Monitor-write-meta-data-in-readonly-state-sometimes.patch +- Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch + Various bugfixes from upstream - several to improve + DDF support, one which fixes a nasty bug in "--assemble --force". + +------------------------------------------------------------------- +Wed Nov 6 05:31:54 UTC 2013 - nfbrown@suse.com + +- DDF-brief_examine_subarrays_ddf-print-array-name.patch + DDF-factor-out-array-name-generation.patch + Include name in "-Db" output for DDF + FATE#316007 + +------------------------------------------------------------------- +Fri Sep 13 01:46:00 UTC 2013 - nfbrown@suse.com + +- boot.md - simplify boot. + As array assembly is done by udev, it shouldn't + be done by boot.md. This will avoid some problems + with arrays getting started degraded. + +------------------------------------------------------------------- +Fri Sep 13 00:59:15 UTC 2013 - nfbrown@suse.com + +- Make-IRs-and-run-work-properly-for-containers.patch +- mdmon-honour-offroot-again.patch +- DDF-allow-for-possibility-that-there-is-no-secondary.patch + Upstream fixes + +------------------------------------------------------------------- +Thu Sep 12 01:12:36 UTC 2013 - nfbrown@suse.com + +- config-set-auto_seen-after-processing-the-auto-line.patch + Fix bug which causes "AUTO -all" in mdadm.conf + in initrd to be ignored, so array might be + auto-assembled too early. + +------------------------------------------------------------------- +Thu Sep 12 01:05:03 UTC 2013 - nfbrown@suse.com + +- mkinitrd-boot.sh: simplify boot sequence by relying + completely on udev running "mdadm -I". Thus + mkinitrd-boot.sh needs to do very little. + The devfunction script in the mkinitrd package has + been modified to start newly degraded array after + a suitable timeout. +- mkinitrd-setup.sh: + - don't save md_devs as it isn't used any more + - allow md device names like "/dev/md_foo" which will + need to be supported in due course. + +------------------------------------------------------------------- +Mon Sep 9 03:06:20 UTC 2013 - nfbrown@suse.com + +- mkinitd-boot.sh: Clear {root,resume}_major variable + + If multipath is in use, md is always on top of it. Therefore, the root + device is always an md device. (bnc#786526) + +------------------------------------------------------------------- +Fri Sep 6 04:02:41 UTC 2013 - nfbrown@suse.com + +- mkinitrd-setup.sh: copy new udev rules files into + the initrd. + The "mkinitrd" package does this for the old name. + It is easier if this packages does it for the files + this package installs. + (bnc#838777) + +------------------------------------------------------------------- +Tue Sep 3 05:45:28 UTC 2013 - nfbrown@suse.com + +- New upstream release - mdadm-3.3 + Lot of improvements to --grow and DDF support. + Better interaction with systemd. + Hot-replace support and more. + Removes patches: + assemble-EXCL-race.fix + 0001-Add-support-for-launching-mdmon-via-systemctl-instea.patch + 0002-In-case-launching-mdmon-fails-print-an-error-message.patch + 0003-mdmon-add-foreground-option.patch + 0004-Suppress-error-messages-from-systemctl.patch + which were backports from upstream. + +------------------------------------------------------------------- +Thu Jun 13 04:12:54 UTC 2013 - nfbrown@suse.com + +- assemble-EXCL-race.fix: avoid some races during + array assembled- particularly at boot (bnc#793954) +- boot.md: make sure systemd-udev-trigger runs before + boot.md to avoid races: bnc#793954 +- mdmon@.service - new file plus patches to allow + mdmon to be started by systemd, so it doesn't + kill it (bnc#321366) + +------------------------------------------------------------------- +Tue Apr 16 10:38:19 UTC 2013 - idonmez@suse.com + +- Add Source URL, see https://en.opensuse.org/SourceUrls + +------------------------------------------------------------------- +Wed Feb 27 08:14:49 UTC 2013 - cfarrell@suse.com + +- license update: GPL-2.0 + mdadm/Software-RAID.HOWTO.tar.bz2 + +------------------------------------------------------------------- +Sun Nov 4 01:43:34 UTC 2012 - crrodriguez@opensuse.org + +- Fix factory breakage on udev and systemd rules. + +------------------------------------------------------------------- +Thu Oct 25 23:18:19 UTC 2012 - nfbrown@suse.com + +- new upstream release 3.2.6. Subsumes all of our + patches and adds a lot of other bug fixes for + less common cases including for a couple that cause + mdadm to crash. + +------------------------------------------------------------------- +Tue Oct 9 03:35:22 UTC 2012 - nfbrown@suse.com + +- remove /lib/udev/devices from specfile as it is + unused +- mkinitrd-setup.sh: fixed recent breakage for IMSM + arrays (bnc#783444) + +------------------------------------------------------------------- +Thu Sep 20 06:03:45 UTC 2012 - nfbrown@suse.com + +- mdmon-takeover.fix + find-free-devnum.fix + mapfile-rebuild.fix + udev-offroot + Fix various issues will installation on IMSM + RAID arrays, booting from those arrays, and + clean shutdown when such an array is used for '/'. + (bnc#752107 bnc#732294 bnc#770351) + +- mkinitrd-setup.sh: allow use stable md device name + and allow it to have a ':' in it. (bnc#779087) + +- boot.md: make sure udev-trigger runs before + boot.md. (bnc#772286) + +------------------------------------------------------------------- +Mon Aug 20 06:53:24 UTC 2012 - nfbrown@suse.com + +- mdmon-takeover.fix + find-free-devnum.fix + mapfile-rebuild.fix + udev-offroot + Fix various issues will installation on IMSM + RAID arrays, booting from those arrays, and + clean shutdown when such an array is used for '/'. + (bnc#752107 bnc#732294 bnc#770351) + +------------------------------------------------------------------- +Thu Jul 26 16:50:03 UTC 2012 - fcrozat@suse.com + +- Add blkid-builtin.patch: use blkid built-in from udev + +------------------------------------------------------------------- +Thu Jul 5 03:14:43 UTC 2012 - nfbrown@suse.com + +- mdmon-arg.fix: fix arg parsing in mdmon so that + "--all --takeover" works. (bnc#767150) + +------------------------------------------------------------------- +Thu Jun 21 07:27:24 UTC 2012 - meissner@suse.com + +- use recommends: smtp_daemon, similar to cronie example + +------------------------------------------------------------------- +Thu Jun 14 18:55:05 UTC 2012 - opensuse@cboltz.de + +- add missing dependencies on cron and /usr/sbin/sendmail (bnc#767155) + +------------------------------------------------------------------- +Thu May 24 01:52:37 UTC 2012 - nfbrown@suse.com + +- udev-rules.fix: make sure systemd doesn't try + to mount array before it is fully assembled. + (bnc#752869) + +------------------------------------------------------------------- +Tue May 22 05:15:52 UTC 2012 - nfbrown@suse.com + +- boot.md/mkinitrd-boot.sh: complete any incremental + assembly before attempting to assemble arrays. + If incremental assembly has partialy assembled + degraded arrays, now is the time to start them going. + (bnc#752869) +- mdamd.cron: send daily reports if any arrays are + degraded. + +------------------------------------------------------------------- +Fri May 18 07:16:59 UTC 2012 - nfbrown@suse.com + +- New upstream version: 3.2.5. Serious regression + in 3.2.4 necessitated a new release. Only significant + fix is that "--add" now works again. + +------------------------------------------------------------------- +Wed May 9 01:22:11 UTC 2012 - nfbrown@suse.com + +- New upstream version: 3.2.4. /run/mdadm is not + used for runtime files, not /var/run or /dev/.mdadm. + +------------------------------------------------------------------- +Fri Apr 20 08:00:33 UTC 2012 - rmilasan@suse.com + +- Run update of initrd at %post and %postun. + We need this to make sure initrd reflects the updates. + +------------------------------------------------------------------- +Wed Dec 21 10:28:19 UTC 2011 - coolo@suse.com + +- remove call to suse_update_config (very old work around) + +------------------------------------------------------------------- +Thu Oct 6 02:16:35 UTC 2011 - nfbrown@suse.com + +- mkinitrd-setup.sh -- add "AUTO -all" to initrd mdadm.conf + so that only arrays needed for boot are auto-assembled. +- auto-line.fix -- fix handling of "AUTO" line + in mdadm.conf so it actually works. + (bnc#721905) + +------------------------------------------------------------------- +Fri Sep 30 15:35:39 UTC 2011 - uli@suse.com + +- cross-build fix: use %__cc macro + +------------------------------------------------------------------- +Thu Aug 18 06:30:45 UTC 2011 - nfbrown@novell.com + +- boot.md: improve 'status' and add 'reload' + function. Also change 'Raid' to 'RAID' + for consistency (bnc#709474) + +------------------------------------------------------------------- +Thu Aug 18 06:01:39 UTC 2011 - nfbrown@novell.com + +- Use udev rules file from upstream package, rather + have having a separate one. + +------------------------------------------------------------------- +Thu Aug 18 03:01:57 UTC 2011 - nfbrown@novell.com + +- Update to new upstream 3.2.2 plug git patches. + Also update FSF address in boot-md. + +------------------------------------------------------------------- +Wed Aug 10 02:54:57 UTC 2011 - crrodriguez@opensuse.org + +- Do not use -fno-strict-aliasing when not needed + +------------------------------------------------------------------- +Tue Jun 14 06:07:19 UTC 2011 - nfbrown@novell.com + +- 64-md-raid.rules - make clear distinction between + 'disk' and 'partition' cases. In particular it + is wrong and problematic to test for 'md/array_state' + for 'partition' devices as they cannot see 'md/*' + and cannot exist when it doesn't have a valid value + anyway. (bnc#684291) + +------------------------------------------------------------------- +Tue Mar 1 22:15:23 UTC 2011 - nfbrown@novell.com + +- mkinitrd-boot.sh: don't assume /dev/md when device + name cannot be found. It could easily be wrong, + and there is no need as mdadm will choose a device. + (bnc#656536) + +------------------------------------------------------------------- +Thu Feb 17 00:27:02 UTC 2011 - nfbrown@novell.com + +- 64-md-raid.rules: avoid races with md devices + appearing and disappearing. + If the 'array_state' file doesn't exist, that is equivalent + to it having 'clear' in it. (bnc#641382) + +------------------------------------------------------------------- +Wed Nov 17 03:27:33 UTC 2010 - nfbrown@novell.com + +- boot.md - change args to mdmon. + The argument parsing of mdmon changed in the recent update + and we need to change boot.md to match. + +------------------------------------------------------------------- +Thu Oct 21 18:01:14 CEST 2010 - ro@suse.de + +- update to 3.1.4 + - 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. + - The default metadata is now v1.2 + - 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. + - Alway make bitmap 4K-aligned if at all possible. +- removed patches: + - bitmap-4k-boundary.patch (obsolete/upstream) + - fix-dup.patch (obsolete/upstream) + - IMSM-part.patch (obsolete/upstream) + - container-argv-check (obsolete/upstream) + +------------------------------------------------------------------- +Mon Jun 28 06:38:35 UTC 2010 - jengelh@medozas.de + +- use %_smp_mflags + +------------------------------------------------------------------- +Tue Jun 1 15:09:53 CEST 2010 - mmarek@suse.cz + +- mkinitrd-setup.sh: Fix for empty $md_devs variable. + +------------------------------------------------------------------- +Fri Apr 23 10:57:57 UTC 2010 - nfbrown@novell.com + +- IMSM-part.patch - never try to include partitions in an + IMSM array - bnc#597787 +- container-argv-check - avoid incorrect error message when + assembling multiple containers - bnc#598827 + +------------------------------------------------------------------- +Thu Apr 22 15:04:30 CEST 2010 - mmarek@suse.cz + +- mkinitrd-boot.sh: Fix booting with root=/dev/disk/by-id/md-uuid*, + run mdadm -v when linuxrc=trace is given (bnc#597787). + +------------------------------------------------------------------- +Mon Apr 19 05:36:23 UTC 2010 - nfbrown@novell.com + +- fix-dup.patch: revised version to make sure partial + device is destroyed properly (bnc#587925). + +------------------------------------------------------------------- +Fri Mar 26 16:00:05 CET 2010 - mmarek@suse.cz + +- fix-dup.patch: catch attempts to add the same disk twice + (bnc#587925). + +------------------------------------------------------------------- +Wed Mar 24 17:37:27 CET 2010 - mmarek@suse.cz + +- 64-md-raid.rules: Use absolute path to grep, otherwise udev will + only search in /lib/udev (bnc#590832). + +------------------------------------------------------------------- +Tue Mar 23 14:49:38 CET 2010 - mmarek@suse.cz + +- mkinitrd-*.sh: Assemble md arrays even if the root= or resume= + option doesn't directly refer to md (bnc#589676, bnc#586837, + bnc#583424). + +------------------------------------------------------------------- +Mon Mar 22 16:30:11 CET 2010 - mmarek@suse.cz + +- mdmon: Fix crash if /proc/mdstat lists 0.9 superblocks + (bnc#589447). + +------------------------------------------------------------------- +Thu Mar 11 10:18:18 CET 2010 - mmarek@suse.cz + +- 64-md-raid.rules: Use blkid instead of vol_id. + +------------------------------------------------------------------- +Thu Mar 11 09:58:21 CET 2010 - mmarek@suse.cz + +- 64-md-raid.rules: Allow --incremental assembly if "AUTO -all" is + given in mdadm.conf (fate#307478). + +------------------------------------------------------------------- +Tue Mar 9 16:15:41 CET 2010 - mmarek@suse.cz + +- Install udev rules in /lib/udev/rules.d (fate#307478). + +------------------------------------------------------------------- +Mon Feb 22 15:14:03 CET 2010 - mmarek@suse.cz + +- mkinitrd-setup.sh: call mdadm --scan only if necessary + (bnc#581769). + +------------------------------------------------------------------- +Fri Feb 19 12:10:11 CET 2010 - mmarek@suse.cz + +- bitmap-4k-boundary.patch: Alling the internal bitmap on 4K + boundary (bnc#577468). + +Fri Jan 15 17:37:26 CET 2010 - mmarek@suse.cz + +- fix modprobe invocation in boot.md (bnc#565293). + +------------------------------------------------------------------- +Fri Jan 15 17:04:06 CET 2010 - mmarek@suse.cz + +- store mdmon runtime files in /dev/.mdadm, to make it easier to + transfer mdmon from the initrd to the real root. +- rework the mkinitrd setup script a bit. + +------------------------------------------------------------------- +Wed Jan 6 15:47:03 CET 2010 - mmarek@suse.cz + +- mkinitrd-*.sh: fix booting from partitionable md devices and + from container devices (bnc#565219). + +------------------------------------------------------------------- +Tue Dec 15 20:26:46 CET 2009 - jengelh@medozas.de + +- enable parallel building + +------------------------------------------------------------------- +Fri Dec 4 18:00:40 CET 2009 - mmarek@suse.cz + +- Support for partitionable md devices in mkinitrd scripts + (fate#305883). + +------------------------------------------------------------------- +Tue Nov 3 11:03:54 CET 2009 - mmarek@suse.cz + +- update to 3.0.3 (fate#307159) + * mdmon improvements (needed for fate#306823) + * other fixes + +------------------------------------------------------------------- +Fri Oct 30 16:49:40 CET 2009 - mmarek@suse.cz + +- mkinitrd-boot.sh: add /sbin/mdmon to the initrd (fate#306823). + +------------------------------------------------------------------- +Thu Oct 1 10:51:38 CEST 2009 - mmarek@suse.cz + +- updated to 3.0.2 + 2 patches + * bugfixes only + +------------------------------------------------------------------- +Fri Jun 12 09:43:43 CEST 2009 - mmarek@suse.cz + +- remove static md* device nodes, they should not be needed + anymore. + +------------------------------------------------------------------- +Thu Jun 11 11:32:55 CEST 2009 - mmarek@suse.cz + +- updated to 3.0 final +- dropped all patches + +------------------------------------------------------------------- +Tue Mar 3 10:36:11 CET 2009 - mmarek@suse.cz + +- super0: Do all metadata IO with 4096byte alignment +- super1 - do metadata IO in sector_size units. + (bnc#466172) + + +------------------------------------------------------------------- +Sat Feb 21 15:37:55 CET 2009 - mmarek@suse.cz + +- mkinitrd-setup.sh: filter out duplicate devices (bnc#461673, + patch by Xin Wei Hu) + +------------------------------------------------------------------- +Tue Feb 17 17:01:23 CET 2009 - mmarek@suse.cz + +- disable auto-assemly in boot.md completely as it can collide with + dmraid (bnc#474652). If someone wants to auto-assemble md arrays + in the rescue system, they can run + 'mdadm -Es -c partitions >mdadm.conf && mdadm -As -c mdadm.conf' + manually. + + +------------------------------------------------------------------- +Mon Feb 16 16:00:11 CET 2009 - mmarek@suse.cz + +- fix segfault when stopping imsm arrays + (bnc#473947, patch by Dan Williams) + +------------------------------------------------------------------- +Mon Jan 26 11:47:59 CET 2009 - ro@suse.de + +- change fillup call from "-Y" to "-y" the boot script has + been present in this package for long enough (SLES10-GA) + +------------------------------------------------------------------- +Fri Dec 5 10:21:10 CET 2008 - hare@suse.de + +- Wait for udev to settle before continuing (bnc#435778) + +------------------------------------------------------------------- +Fri Dec 5 06:18:44 CET 2008 - nfbrown@suse.de + +- boot.md : an exit status of '2' from "mdadm --assemble" + should not be seen as failure by boot.md. + It happens if one or more arrays is already + assembled. + (bnc#456028) + +------------------------------------------------------------------- +Thu Nov 20 07:07:06 CET 2008 - nfbrown@suse.de + +- don-t-auto-assemble-if-any-arrays-are-list.patch + Avoid assembling extra arrays during initrd + processing. bnc#445438 + +------------------------------------------------------------------- +Thu Nov 20 04:57:30 CET 2008 - nfbrown@suse.de + +- mdmon-pass-symbolic-name-to-mdmon-instead-of-device.patch + avoid problems if mdmon is run before + udev creates any devices. + +------------------------------------------------------------------- +Fri Nov 14 05:33:41 CET 2008 - nfbrown@suse.de + +- intel.fixes.patch : various fixes from intel for + proper handling of their metadata +- name.fixes.patch : various fixes for new handling + of device names - one could cause a crash. + +------------------------------------------------------------------- +Sun Nov 9 23:38:39 CET 2008 - ro@suse.de + +- fix patch apply depth + +------------------------------------------------------------------- +Fri Nov 7 12:34:30 CET 2008 - nfbrown@suse.de + +- mdadm-auto-assemble.patch - fix various bugs in + auto-assemble +- start-kpartx-for-imsm-devices.patch - IMSM devices + need to be partitioned, and may programs including + YaST don't understand partitioned md devices, + so run kpartx to create 'dm' based partitions which + have a better chance for being understood + This relates to FATE#304220 + +------------------------------------------------------------------- +Fri Nov 7 10:32:35 CET 2008 - ro@suse.de + +- remove udev rule (conflicting with file in udev package) + +------------------------------------------------------------------- +Fri Nov 7 02:58:40 CET 2008 - ro@suse.de + +- buildfix: add missing DESTDIR to Makefile for udev rule +- fix len in snprintf to silence compiler warning about potential + overflow + +------------------------------------------------------------------- +Thu Nov 6 03:22:50 CET 2008 - nfbrown@suse.de + +- Update from mdadm-3.0-devel1 to mdadm-3.0-devel2. + This includes various bug fixes and enhancements to the + extent that DDF and IMSM work reasonably well and can be + auto-assembled much like other arrays. +- Allow BOOT_MD_USE_MDADM_CONFIG to have the value 'part' + that, like 'no', arrays are auto-assembled. However they + get assembled as 'mdp' partitionable arrays where possible. + This currently only affect arrays with v1.x metadata. + This supports FATE#303894 + +------------------------------------------------------------------- +Fri Oct 3 15:28:49 CEST 2008 - mmarek@suse.cz + +- fixed mdmon's clone_monitor on ia64 + +------------------------------------------------------------------- +Fri Oct 3 14:28:55 CEST 2008 - mmarek@suse.cz + +- fixed byte swapping in super-intel.c on big endian. + +------------------------------------------------------------------- +Wed Sep 24 18:24:25 CEST 2008 - ro@suse.de + +- change "udevsettle" to "udevadm settle" + +------------------------------------------------------------------- +Fri Sep 19 11:14:05 CEST 2008 - mmarek@suse.cz + +- added /var/run/mdadm for mdmon +- fixed build + +------------------------------------------------------------------- +Thu Sep 18 09:33:19 CEST 2008 - nfbrown@suse.de + +- update to mdadm-3.0-devel1 + package version number is set to 3.0 to avodi future confusion. + This is a substantial update that provides support for handling + the metadata entirely in userspace and thus making easier to + handle a variety of metadata formats. Support is included for + DDF and for the Intel Matrix metadata used by recent ICH chipsets. + + An extra program 'mdmon' is needed and included. It is run to + monitor any array using 'external' (to the kernel) metadata + and will update the metadata in response to device failures etc. + + This is required for FATE 304219 + + +------------------------------------------------------------------- +Wed Sep 3 11:09:34 CEST 2008 - hare@suse.de + +- Call mkinitrd_setup during %post and %postun (bnc#413709) + +------------------------------------------------------------------- +Sun Aug 17 08:04:26 CEST 2008 - aj@suse.de + +- Fix init scripts. + +------------------------------------------------------------------- +Wed Jul 23 15:21:59 CEST 2008 - hare@suse.de + +- Include mkinitrd scriptlets. + +------------------------------------------------------------------- +Fri Jun 20 14:28:20 CEST 2008 - mmarek@suse.cz + +- updated to 2.6.7 + fixes from git + * Avoid segfault when parsing /proc/mdstat with auto-read-only + arrays. + * For v0.90 superblocks, print the 'Events' count as a real + count, not 2 numbers separated by a dot. + * Allow creation of a RAID6 with exactly one missing device. + * Use LOG_PID for syslog, so you get the pid of mdadm in the + log files. + * --export now works with --examine too (not just --detail) + * Improve auto-creation of device special file when using + --incremental + * Simple locking for --incremental so mdadm doesn't get + confused when run concurrently with itself. + * Make --incremental cope better with arrays that are being + reshaped. + * Fix autoassemble for stack arrays. +- remove /tmp/mdadm.conf in boot.md (bnc#401138) + +------------------------------------------------------------------- +Wed Apr 30 15:57:14 CEST 2008 - mmarek@suse.cz + +- added some fixes from Neil's git repo, fixing bnc#368704 among + others + +------------------------------------------------------------------- +Mon Feb 4 19:24:54 CET 2008 - mmarek@suse.cz + +- correctly display rc_status in boot.md + +------------------------------------------------------------------- +Wed Jan 23 15:55:24 CET 2008 - mmarek@suse.cz + +- fixed auto-assembly part of boot.md + * if /etc/mdadm.conf is empy or only contains whitespace or + comments, no autoassembly is done + * remove /tmp/mdadm.conf even if a directory [#329678] +- dropped mdrun and raidautorun (no longer needed) + +------------------------------------------------------------------- +Wed Oct 24 17:08:11 CEST 2007 - mmarek@suse.cz + +- updated to 2.6.4 + * Make "--create --auto=mdp" work for non-standard device names. + * Fix restarting of a 'reshape' if it was stopped in the middle. + * Fix a segfault when using v1 superblock. + * Make --write-mostly effective when re-adding a device to an + array. + * Various minor fixes +- changes in 2.6.3: + * allow --write-behind to be set for --grow. + * When adding new disk to an array, don't reserve so much bitmap + space that the disk cannot store the required data. (Needed + when 1.x array was created with older mdadm). + * When adding a drive that was a little too small, we did not get + the correct error message. + * Make sure that if --assemble find an array in the critical + region of a reshape, and cannot find the critical data to + restart the reshape, it gives an error message. + * Fix segfault with '--detail --export' and non-persistent + superblocks. + * Various manpage updates. + * Improved 'raid4' support (--assemble, --monitor) + * Option parsing fixes w.r.t -a + * Interpret "--assemble --metadata=1" to allow any version 1.x + metadata, and be more specific in the "metadata=" message + printed with --examine --brief + * Fix spare migration in --monitor. + +------------------------------------------------------------------- +Fri Jul 27 13:01:01 CEST 2007 - mmarek@suse.cz + +- changes to the init script [#288454] + * don't try to autoassemble if /etc/mdadm.conf exists (even an + empty one) + * ony autoassemble partitions found in /proc/partitions + +------------------------------------------------------------------- +Fri Jul 13 15:02:21 CEST 2007 - mmarek@suse.cz + +- updated to 2.6.2 + * --fail detached and --remove faulty can be used to fail and + remove devices that are no longer physically present. + * --export option for --detail or present information in a format + that can be processed by udev. + * fix internal bitmap allocation problems with v1.1, v1.2 + metadata. + * --help now goes to stdout so you can direct it to a pager. + * Various manpage updates. + * Make "--grow --add" for linear arrays really work. + * --auto-detect to trigger in-kernel autodetect. + * Make return code for "--detail --test" more reliable. Missing + devices as well as failed devices cause an error. +- added some fixes from Neil's git repo (mdadm-git-fixes.patch) + +------------------------------------------------------------------- +Thu Jun 21 15:58:37 CEST 2007 - adrian@suse.de + +- fix changelog entry order + +------------------------------------------------------------------- +Mon Apr 2 15:00:10 CEST 2007 - mmarek@suse.cz + +- updated to 2.6.1 + * --monitor was producing some meaningless warnings due to a bug. + * Fix some compiler warnings. + * Fully support --grow for raid6. If a reshape crashed during + the critical period, mdadm wouldn't restore the Q information + properly. + * Update documentation for --grow. + * Report bitmap status in --detail and --examine + * Default to v1 superblocks instead of v0.90 if the array + is too big for 0.90 to handle. + * Sort the output of "mdadm --detail --scan" so that it is + in a suitable order for assembling arrays. i.e. components come + before an array that they are part of. + * Require bitmap files to have a '/' in their name. + * Rewrite 'reshape' support including performing a backup + of the critical region for a raid5 growth, and restoring that + backup after a crash. + * Put a 'canary' at each end of the backup so a corruption + can be more easily detected. + * Support --backup-file for backing-up critical section during + growth. + * Erase old superblocks (of different versions) when creating new + array. + * Allow --monitor to work with arrays with >28 devices + * Report reshape information in --detail + * Handle symlinks in /dev better + * Fix mess in --detail output which a device is missing. + * Support 'bitmap=' in mdadm.conf for auto-assembling arrays with + write-intent bitmaps in separate files. + * Fix alignment problem in version-1 superblocks. + NOTE: This is an incompatable change affecting raid5 reshape. + If you want to reshape a raid5 using version-1 superblocks, + use 2.6.17-rc2 or later, and mdadm-2.4.1 or later. + * Support 'mailfrom' line in mdadm.conf so the From: line in alert + emails can be explicitly set. + * Arrange that SparesMissing (which is similar in import to + DegradedArray) generates an Email. + * Assume "DEVICE partitions" if no DEVICE line is given. + * Support new 'offset' layout for raid10. + * When creating a bitmap file, choose a chunksize to limit number + of bitmap chunks to 2 million. More than this can cause kmalloc + failure. + * New 'CREATE' line in mdadm.conf for defaults such as owner, group, + mode and auto-flag + * --detail checks if array has been started or not and includes that + in report. + * When using --update=uuid on an array with a bitmap, update the + bitmap's uuid too. + * Add a copy of /proc/mdstat to the mail message sent by mdadm + --monitor. + * New flag --no-degraded to avoid starting arrays if there are + fewer devices available than last time the array was started. + This is only needed with --scan, as with --scan, that behaviour + is the default. + * Support for 'homehost' concept. This is a fairly major update. + It includes a configfile option and a command line option for + specifying a homehost, records that host in the superblock, + and reports the homehost where possible. + * Support for Auto Assembly. "mdadm -As" will, if provided with + the name of a homehost, try to assemble all arrays it can find + that were created for that homehost. See man pages for more details. + * Don't try to create devices with --manage or --grow + * allow default metadata (superblock) type to be specified + in mdadm.conf + * Avoid some misdetection of overlapping partitions + * Add 'Array Slot' line to --examine for version-1 superblocks + to make it a bit easier to see what is happening. + * Work around bug in --add handling for version-1 superblocks + in 2.6.17 (and prior). + * Make -assemble a bit more resilient to finding strange + information in superblocks. + * When creating devices in /dev/md/ create matching symlinks + from /dev. e.g. /dev/md0 -> /dev/md/0. + Allow this to be disabled in mdadm.conf or on command line. + * Allow a number (of partitions) after the 'yes' option to --auto= + This is particularly useful in the 'create' line in mdadm.conf. + * Remove partitions from any whole device that is made part of + an md array. This is a work-around for annoying messages + when the first block on some drive accidentally looks like a + partition table. + * Close stray fd in mdassemble so that it can assemble stacked + devices + * If mdassemble finds an array already assembled, it marks it + read-write. + * Remove error in md_open if array is already active. This isn't + needed and gets in the ways if an array was created e.g. in + initramfs, but device doesn't yet exist in /dev. + * When --assemble --scan is run, if all arrays that could be found + have already been started, don't report an error. + * Allow --assemble --force to mark a raid6 clean when it has two + missing devices (which is needed else if won't assemble. + Without this fix it would only assemble if one or zero + missing devices. + * Support --update=devicesize for cases where the underlying device + can change size. + * Default to --auto=yes so the array devices with 'standard' names + get created automatically, as this is almost always what is wanted. + * Give useful message if raid4/5/6 cannot be started because it is + not clean and is also degraded. + * Increase raid456 stripe cache size if needed to --grow the array. + The setting used unfortunately requires intimate knowledge of the + kernel, and it not reset when the reshape finishes. + * Change 'Device Size' to 'Used Dev Size' because it only shows how + much of each device is actually used, not how big they are. + * --wait or -W will wait for resync activity to finish on the given + devices. + * If two drives in a raid5 disappear at the same time, then "-Af" + will add them both in rather than just one and forcing the array + to 'clean'. This is slightly safer in some cases. + * Don't hold md device open for so long in --monitor mode - map_dev + can be slow and interferes with trying to stop the array. + * Support --uuid= with --create to choose your own UUID. + * New major more "--incremental" for incremental assemble of arrays, + intended for use with udev. + * lots of bugfixes + * manpage updates + +------------------------------------------------------------------- +Wed Jan 10 11:58:14 CET 2007 - mmarek@suse.cz + +- use raidautorun instead of mdrun to autodetect the raid arrays in + boot.md [#230733] + +------------------------------------------------------------------- +Wed Nov 8 10:51:13 CET 2006 - prusnak@suse.cz + +- fixed subscript out of range [#212697] + +------------------------------------------------------------------- +Wed Sep 20 17:17:22 CEST 2006 - mjancar@suse.cz + +- update to 2.5.3 + * lots bugfixes + * drop all patches (integrated upstream) + +------------------------------------------------------------------- +Fri Jul 28 13:12:47 CEST 2006 - olh@suse.de + +- remove dropped boot.ibmsis from boot.md +- boot.rootfsck should start before boot.md (#181972) + +------------------------------------------------------------------- +Fri Jul 21 14:16:28 CEST 2006 - olh@suse.de + +- remove boot.proc from Required-Start: in boot.md (#178753) + +------------------------------------------------------------------- +Wed May 3 13:12:42 CEST 2006 - mjancar@suse.cz + +- fix false SparesMissing error (#171326) + +------------------------------------------------------------------- +Wed Apr 26 09:46:28 CEST 2006 - hare@suse.de + +- Fix init script dependencies +- Implement MDADM_DEVICE_TIMEOUT to set a timeout for + udevsettle (#149979) + +------------------------------------------------------------------- +Tue Apr 25 13:39:38 CEST 2006 - mjancar@suse.cz + +- add static device nodes for udev (#168824) + +------------------------------------------------------------------- +Wed Apr 19 10:27:19 CEST 2006 - mjancar@suse.cz + +- set $BOOT_MD_USE_MDADM_CONFIG to "yes" by default (#155120) + +------------------------------------------------------------------- +Fri Apr 7 11:33:15 CEST 2006 - mjancar@suse.cz + +- detach mdadmd from tty in rcmdadmd (#160881) + +------------------------------------------------------------------- +Mon Apr 3 09:54:55 CEST 2006 - mjancar@suse.cz + +- fix garbled output with --detail (#160827) +- fix fix write-mostly with --add and --re-add (#162968) + +------------------------------------------------------------------- +Fri Mar 24 21:31:54 CET 2006 - mjancar@suse.cz + +- add /sbin/raidautorun (#159460) + +------------------------------------------------------------------- +Wed Mar 8 18:33:12 CET 2006 - mjancar@suse.cz + +- add $BOOT_MD_USE_MDADM_CONFIG sysconfig variable (#155120) + +------------------------------------------------------------------- +Thu Feb 9 16:59:52 CET 2006 - mjancar@suse.cz + +- round free size to chunk size multiply on --create (#148562) + +------------------------------------------------------------------- +Tue Feb 7 08:59:50 CET 2006 - mjancar@suse.cz + +- move boot.multipath to Should-Start instead of Required-Start + +------------------------------------------------------------------- +Mon Feb 6 15:27:47 CET 2006 - mjancar@suse.cz + +- add "Obsoletes: raidtools" +- start boot.md after boot.multipath +- call mdadm without -a from mdrun, an argument is required in 2.2 + +------------------------------------------------------------------- +Mon Feb 6 11:36:26 CET 2006 - mjancar@suse.de + +- don't start mdadmd by default + +------------------------------------------------------------------- +Sun Feb 5 20:46:43 CET 2006 - mjancar@suse.cz + +- include option for email to be sent on start (#142105) +- fix missing md autostart due to raidtools dropped (#148234) + * include mdrun script from Debian + * create boot.md initscipt + +------------------------------------------------------------------- +Sun Feb 5 17:46:32 CET 2006 - schwab@suse.de + +- Fix memset parameters. + +------------------------------------------------------------------- +Thu Feb 2 12:30:26 CET 2006 - mjancar@suse.cz + +- fix segfault on --assemble (#146514) + +------------------------------------------------------------------- +Fri Jan 27 02:12:42 CET 2006 - mls@suse.de + +- converted neededforbuild to BuildRequires + +------------------------------------------------------------------- +Wed Jan 25 10:48:18 CET 2006 - olh@suse.de + +- fix uninitialized variable, memset call and memcmp/memcpy bug + mdadm.bug144647-array.init.patch + mdadm.bug144647-update_super1-memcpy.patch + mdadm.bug144647-add_internal_bitmap0-memcpy.patch + +------------------------------------------------------------------- +Wed Jan 11 13:49:54 CET 2006 - mjancar@suse.cz + +- update ro 2.2 + +------------------------------------------------------------------- +Tue Dec 20 12:57:25 CET 2005 - ro@suse.de + +- at least output errors if they occur (instead of ignoring) + +------------------------------------------------------------------- +Wed Nov 30 17:19:24 CET 2005 - schwab@suse.de + +- Fix broken formats. + +------------------------------------------------------------------- +Tue Oct 25 09:53:57 CEST 2005 - aj@suse.de + +- Build with -fno-strict-aliasing. + +------------------------------------------------------------------- +Wed Oct 12 20:18:00 CEST 2005 - mjancar@suse.cz + +- update to 2.1 + +------------------------------------------------------------------- +Thu Jul 28 20:28:32 CEST 2005 - anicka@suse.cz + +- update to 1.12.0 + +------------------------------------------------------------------- +Wed Jun 15 13:16:42 CEST 2005 - meissner@suse.de + +- use RPM_OPT_FLAGS correctly. + +------------------------------------------------------------------- +Tue Apr 19 13:48:24 CEST 2005 - postadal@suse.de + +- updated to version 1.11.0 +- fixed for gcc 4.0 +- removed obsoleted patch config-fix + +------------------------------------------------------------------- +Wed Mar 30 13:24:23 CEST 2005 - postadal@suse.cz + +- fixed parsing command line option '--config=partions' [#74603] + +------------------------------------------------------------------- +Fri Feb 4 13:09:49 CET 2005 - postadal@suse.cz + +- updated to version 1.9.0 + +------------------------------------------------------------------- +Thu Jan 13 17:24:55 CET 2005 - postadal@suse.cz + +- updated to version 1.8.1 +- extended comment in sysconfig.mdadm [#48567] + +------------------------------------------------------------------- +Fri Aug 06 12:09:58 CEST 2004 - postadal@suse.cz + +- updated to version 1.6.0 + * added --auto= and --assume-clean options + * added "degraded" and "recovering" options to the "Status:" entry + +------------------------------------------------------------------- +Tue Feb 10 13:45:52 CET 2004 - postadal@suse.cz + +- updated to version 1.5.0 + * new commands "mdassemble" + * support for raid6 as found in 2.6.2 + * support partitioned md arrays with a different major number and + naming scheme + * added "SparesMissing" event when --monitor first sees an array and + it doesn't have the enough spare devices. + +------------------------------------------------------------------- +Sun Jan 11 11:50:04 CET 2004 - adrian@suse.de + +- add %defattr + +------------------------------------------------------------------- +Mon Dec 1 10:53:02 CET 2003 - fehr@suse.de + +- fix quoting problem in start script (#33392) + +------------------------------------------------------------------- +Fri Aug 29 09:36:24 CEST 2003 - fehr@suse.de + +- add PreReq for fillup + +------------------------------------------------------------------- +Tue Aug 26 10:23:44 CEST 2003 - fehr@suse.de + +- add %stop_on_removal and %restart_on_update + +------------------------------------------------------------------- +Thu Aug 14 15:40:53 CEST 2003 - fehr@suse.de + +- add missing activation metadata in sysconfig (#28901) + +------------------------------------------------------------------- +Tue Jul 29 11:03:36 CEST 2003 - fehr@suse.de + +- update to new version 1.3.0 of package + +------------------------------------------------------------------- +Mon Apr 14 20:01:43 CEST 2003 - postadal@suse.cz + +- fixed init script (added return value for unimplemented reload function) + +------------------------------------------------------------------- +Mon Mar 31 17:37:03 CEST 2003 - postadal@suse.cz + +- added buildroot, init script, sysconfig +- bzip2 sources and cleaned specfile + +------------------------------------------------------------------- +Thu Mar 20 16:18:13 CET 2003 - fehr@suse.de + +- update to version 1.2.0 of package + +------------------------------------------------------------------- +Mon Mar 3 12:16:22 CET 2003 - fehr@suse.de + +- update to version 1.1.0 of package + +------------------------------------------------------------------- +Mon Dec 2 11:30:52 CET 2002 - fehr@suse.de + +- Fix for new glibc/gcc + +------------------------------------------------------------------- +Tue Sep 17 17:34:28 CEST 2002 - ro@suse.de + +- removed bogus self-provides + +------------------------------------------------------------------- +Mon Sep 13 15:10:00 CEST 2002 - lmb@suse.de + +- Fix for 64bit arch; ioctl returns long instead of int (#20339) + +------------------------------------------------------------------- +Fri Aug 23 11:16:51 MEST 2002 - lmb@suse.de + +- Multipath arrays can now be build manually even without a superblock. +- One debugging chunk removed from patch. + +------------------------------------------------------------------- +Tue Aug 13 14:43:02 MEST 2002 - lmb@suse.de + +- Fix for the assembly of multipath arrays. + +------------------------------------------------------------------- +Mon Aug 12 11:46:43 MEST 2002 - lmb@suse.de + +- Added patch to support the enhanced multipath features. + +------------------------------------------------------------------- +Mon Aug 5 16:05:19 CEST 2002 - fehr@suse.de + +- make SuSE package from version 1.0.1 of mdadm + diff --git a/mdadm.spec b/mdadm.spec new file mode 100644 index 0000000..1e1dd2b --- /dev/null +++ b/mdadm.spec @@ -0,0 +1,347 @@ +# +# spec file for package mdadm +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +#Compat macro for new _fillupdir macro introduced in Nov 2017 +%if ! %{defined _fillupdir} + %define _fillupdir /var/adm/fillup-templates +%endif + +Name: mdadm +Version: 4.2 +Release: 0 +BuildRequires: binutils-devel +BuildRequires: groff +BuildRequires: pkgconfig +BuildRequires: sgmltool +BuildRequires: pkgconfig(libudev) +BuildRequires: pkgconfig(systemd) +BuildRequires: pkgconfig(udev) +PreReq: %fillup_prereq +PreReq: coreutils +URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ +Summary: Utility for configuring "MD" software RAID devices +License: GPL-2.0-only +Group: System/Base +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/%{name}-%{version}.tar.xz +Source1: Software-RAID.HOWTO.tar.bz2 +Source2: sysconfig.mdadm +Patch1: 0001-Unify-error-message.patch +Patch2: 0002-mdadm-Fix-double-free.patch +Patch3: 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch +Patch4: 0004-udev-adapt-rules-to-systemd-v247.patch +Patch5: 0005-Replace-error-prone-signal-with-sigaction.patch +Patch6: 0006-mdadm-Respect-config-file-location-in-man.patch +Patch7: 0007-mdadm-Update-ReadMe.patch +Patch8: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch +Patch9: 0009-mdadm-Update-config-manual.patch +Patch10: 0010-Create-Build-use-default_layout.patch +Patch11: 0011-mdadm-add-map_num_s.patch +Patch12: 0012-mdmon-Stop-parsing-duplicate-options.patch +Patch13: 0013-Grow-block-n-on-external-volumes.patch +Patch14: 0014-Incremental-Fix-possible-memory-and-resource-leaks.patch +Patch15: 0015-Mdmonitor-Fix-segfault.patch +Patch16: 0016-Mdmonitor-Improve-logging-method.patch +Patch17: 0017-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +Patch18: 0018-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +Patch19: 0019-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +Patch20: 0020-util-replace-ioctl-use-with-function.patch +Patch21: 0021-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +Patch22: 0022-imsm-introduce-get_disk_slot_in_dev.patch +Patch23: 0023-imsm-use-same-slot-across-container.patch +Patch24: 0024-imsm-block-changing-slots-during-creation.patch +Patch25: 0025-mdadm-block-update-ppl-for-non-raid456-levels.patch +Patch26: 0026-mdadm-Fix-array-size-mismatch-after-grow.patch +Patch27: 0027-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +Patch28: 0028-Monitor-use-devname-as-char-array-instead-of-pointer.patch +Patch29: 0029-Monitor-use-snprintf-to-fill-device-name.patch +Patch30: 0030-Makefile-Don-t-build-static-build-with-everything-an.patch +Patch31: 0031-DDF-Cleanup-validate_geometry_ddf_container.patch +Patch32: 0032-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +Patch33: 0033-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +Patch34: 0034-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +Patch35: 0035-mdadm-Fix-mdadm-r-remove-option-regression.patch +Patch36: 0036-mdadm-Fix-optional-write-behind-parameter.patch +Patch37: 0037-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +Patch38: 0038-mdadm-remove-symlink-option.patch +Patch39: 0039-mdadm-move-data_offset-to-struct-shape.patch +Patch40: 0040-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +Patch41: 0041-Grow-Split-Grow_reshape-into-helper-function.patch +Patch42: 0042-Assemble-check-if-device-is-container-before-schedul.patch +Patch43: 0043-super1-report-truncated-device.patch +Patch44: 0044-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +Patch46: 0046-Monitor-Fix-statelist-memory-leaks.patch +Patch47: 0047-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +Patch48: 0048-mdadm-Add-Documentation-entries-to-systemd-services.patch +Patch49: 0049-ReadMe-fix-command-line-help.patch +Patch50: 0050-mdadm-replace-container-level-checking-with-inline.patch +Patch51: 0051-Mdmonitor-Omit-non-md-devices.patch +Patch52: 0052-mdmon-fix-segfault.patch +Patch53: 0053-util-remove-obsolete-code-from-get_md_name.patch +Patch54: 0054-mdmon-don-t-test-both-all-and-container_name.patch +Patch55: 0055-mdmon-change-systemd-unit-file-to-use-foreground.patch +Patch56: 0056-mdmon-Remove-need-for-KillMode-none.patch +Patch57: 0057-mdmon-Improve-switchroot-interactions.patch +Patch58: 0058-mdopen-always-try-create_named_array.patch +Patch59: 0059-Improvements-for-IMSM_NO_PLATFORM-testing.patch +Patch60: 0060-Grow-fix-possible-memory-leak.patch +Patch61: 0061-Grow-fix-can-t-change-bitmap-type-from-none-to-clustered.patch +Patch62: 0062-Manage-Block-unsafe-member-failing.patch +Patch63: 0063-Mdmonitor-Split-alert-into-separate-functions.patch +Patch64: 0064-Monitor-block-if-monitor-modes-are-combined.patch +Patch65: 0065-Update-mdadm-Monitor-manual.patch +Patch66: 0066-mdadm-create-ident_init.patch +Patch67: 0067-mdadm-Add-option-validation-for-update-subarray.patch +Patch68: 0068-Fix-update-subarray-on-active-volume.patch +Patch69: 0069-Add-code-specific-update-options-to-enum.patch +Patch70: 0070-super-ddf-Remove-update_super_ddf.patch +Patch71: 0071-super0-refactor-the-code-for-enum.patch +Patch72: 0072-super1-refactor-the-code-for-enum.patch +Patch73: 0073-super-intel-refactor-the-code-for-enum.patch +Patch74: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch +Patch75: 0075-Manage-Incremental-code-refactor-string-to-enum.patch +Patch76: 0076-Change-char-to-enum-in-context-update-refactor-code.patch +Patch77: 0077-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +Patch78: 0078-Manage-do-not-check-array-state-when-drive-is-remove.patch +Patch79: 0079-incremental-manage-do-not-verify-if-remove-is-safe.patch +Patch80: 0080-super-intel-make-freesize-not-required-for-chunk-siz.patch +Patch81: 0081-manage-move-comment-with-function-description.patch +Patch82: 0082-Fix-NULL-dereference-in-super_by_fd.patch +Patch83: 0083-Mdmonitor-Make-alert_info-global.patch +Patch84: 0084-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch +Patch85: 0085-Mdmonitor-Add-helper-functions.patch +Patch86: 0086-Add-helpers-to-determine-whether-directories-or-file.patch +Patch87: 0087-Mdmonitor-Refactor-write_autorebuild_pid.patch +Patch88: 0088-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch +Patch89: 0089-util.c-reorder-code-lines-in-parse_layout_faulty.patch +Patch90: 0090-util.c-fix-memleak-in-parse_layout_faulty.patch +Patch91: 0091-Detail.c-fix-memleak-in-Detail.patch +Patch92: 0092-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch +Patch93: 0093-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch +Patch94: 0094-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch +Patch95: 0095-Create-goto-abort_locked-instead-of-return-1-in-erro.patch +Patch96: 0096-Create-remove-safe_mode_delay-local-variable.patch +Patch97: 0097-Create-Factor-out-add_disks-helpers.patch +Patch98: 0098-mdadm-Introduce-pr_info.patch +Patch99: 0099-mdadm-Add-write-zeros-option-for-Create.patch +Patch100: 0100-manpage-Add-write-zeroes-option-to-manpage.patch +Patch101: 0101-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch +Patch102: 0102-Use-existence-of-etc-initrd-release-to-detect-initrd.patch +Patch103: 0103-Create-Fix-checking-for-container-in-update_metadata.patch +Patch1001: 1001-display-timeout-status.patch +Patch1002: 1002-OnCalendar-format-fix-of-mdcheck_start-timer.patch +Patch1003: 1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch +Patch1004: 1004-call-mdadm_env.sh-from-usr-libexec-mdadm.patch +Patch1005: 1005-mdadm-enable-Intel-Alderlake-RSTe-configuration.patch +%define _udevdir %(pkg-config --variable=udevdir udev) +%define _systemdshutdowndir %{_unitdir}/../system-shutdown + +%description +mdadm is a program that can be used to control Linux md devices. + +%prep +%setup -q -a1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 +%patch83 -p1 +%patch84 -p1 +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 +%patch90 -p1 +%patch91 -p1 +%patch92 -p1 +%patch93 -p1 +%patch94 -p1 +%patch95 -p1 +%patch96 -p1 +%patch97 -p1 +%patch98 -p1 +%patch99 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch1001 -p1 +%patch1002 -p1 +%patch1003 -p1 +%patch1004 -p1 +%patch1005 -p1 + +%build +make %{?_smp_mflags} CC="%__cc" CXFLAGS="%{optflags} -Wno-error" EXTRAVERSION="%{release}" SUSE=yes BINDIR=%{_sbindir} +cd Software-RAID.HOWTO +sgml2html Software-RAID.HOWTO.sgml +sgml2txt Software-RAID.HOWTO.sgml + +%install +%make_install install-systemd install-udev SYSTEMD_DIR=%{_unitdir} UDEVDIR=%{_udevdir} SUSE=yes BINDIR=%{_sbindir} +rm -rf %{buildroot}/lib/udev +install -d %{buildroot}%{_fillupdir} +install -d %{buildroot}/usr/share/mdadm +install -m 755 misc/mdcheck %{buildroot}/usr/share/mdadm/mdcheck +install -m 644 %{S:2} %{buildroot}%{_fillupdir}/ +install -d %{buildroot}%{_systemdshutdowndir} +install -d %{buildroot}%{_sbindir} +ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rcmdmonitor +%if 0%{?suse_version} < 1550 + mkdir -p %{buildroot}/sbin + ln -s %{_sbindir}/mdadm %{buildroot}/sbin/mdadm + ln -s %{_sbindir}/mdmon %{buildroot}/sbin/mdmon +%endif + +%define services mdmonitor.service mdcheck_start.service mdcheck_continue.service mdmonitor-oneshot.service + +%pre +%service_add_pre %services + +%post +%service_add_post %services +%{?regenerate_initrd_post} +%fillup_only + +%preun +%service_del_preun %services + +%postun +%service_del_postun %services +%{?regenerate_initrd_post} + +%posttrans +%{?regenerate_initrd_posttrans} + +%files +%defattr(-,root,root) +%license COPYING +%doc ChangeLog README.initramfs TODO mdadm.conf-example mkinitramfs +%doc Software-RAID.HOWTO/Software-RAID.HOWTO*{.txt,.html} +%doc %{_mandir}/man?/* +%{_sbindir}/* +%if 0%{?suse_version} < 1550 +/sbin/mdadm +/sbin/mdmon +%endif +%dir /usr/share/mdadm +/usr/share/mdadm/* +%{_fillupdir}/sysconfig.mdadm +%{_udevdir}/rules.d/01-md-raid-creating.rules +%{_udevdir}/rules.d/63-md-raid-arrays.rules +%{_udevdir}/rules.d/64-md-raid-assembly.rules +%{_udevdir}/rules.d/69-md-clustered-confirm-device.rules +# %%{_systemdshutdowndir}/ is not owned by all versions of systemd-mini. +# But we really do not want to pull in a full systemd, so we rather just own +# that directory by ourselves too. After all, this is allowed. +%dir %{_systemdshutdowndir} +%{_systemdshutdowndir}/mdadm.shutdown +%{_unitdir}/mdmon@.service +%{_unitdir}/mdmonitor.service +%{_unitdir}/mdadm-last-resort@.timer +%{_unitdir}/mdadm-last-resort@.service +%{_unitdir}/mdadm-grow-continue@.service +%{_unitdir}/mdcheck_continue.service +%{_unitdir}/mdcheck_continue.timer +%{_unitdir}/mdcheck_start.service +%{_unitdir}/mdcheck_start.timer +%{_unitdir}/mdmonitor-oneshot.service +%{_unitdir}/mdmonitor-oneshot.timer +%dir %{_prefix}/libexec/ +%dir %{_prefix}/libexec/mdadm +%{_prefix}/libexec/mdadm/mdadm_env.sh + +%changelog diff --git a/sysconfig.mdadm b/sysconfig.mdadm new file mode 100644 index 0000000..0cfabf0 --- /dev/null +++ b/sysconfig.mdadm @@ -0,0 +1,73 @@ +## Path: System/File systems/Mdadm +## Description: Additional options for the mdadm daemon (see man mdadm(8)). +## +## Type: integer +## Default: 60 +# +# A delay in seconds between polling the md arrays. +# +MDADM_DELAY=60 + +## Type: string +## Default: "" +# +# A mail address (or comma-separated list of mail addresses) to send alerts to. +# +MDADM_MAIL="root@localhost" + +## Type: string +## Default: "" +# +# A program to be run whenever an event is detected. +# +MDADM_PROGRAM="" + +## Type: string +## Default: "" +# +# Monitoring MD devices. +# +MDADM_RAIDDEVICES="" + +## Type: yesno +## Default: yes +# +# "yes" for scanning config file or /proc/mdstat for missing information. +# +MDADM_SCAN=yes + +## Type: string +## Default: "/etc/mdadm.conf" +# +# The config file. +# +MDADM_CONFIG="/etc/mdadm.conf" + +## Type: yesno +## Default: no +# +# "yes" for email to be sent on start +# +MDADM_SEND_MAIL_ON_START=no + +## Type: integer +## Default: 60 +# +# Timeout for udev device detection. This is the upper limit which the +# boot script will wait for udev to finish hotplug event processing. +# If not all devices are detected during boot this value should be +# increased. Setting this to '0' disables waiting for udev. +# +MDADM_DEVICE_TIMEOUT="60" + +## Type: string +## Default: 6 hours +# +# Amount of time to spend checking md arrays each morning. +# A check will start on the first Sunday of the month and run +# for this long. If it does not complete, then it will be +# continued each subsequent morning until all arrays have +# been checked. Any string understood by "date --date=" +# can be used. An empty string disables automatic checks. +# +MDADM_CHECK_DURATION="6 hours"