diff --git a/.gitignore b/.gitignore index 5635722..c3cc530 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/mdadm-4.2.tar.xz +mdadm-4.4.tar.gz diff --git a/.mdadm.metadata b/.mdadm.metadata deleted file mode 100644 index 56ea749..0000000 --- a/.mdadm.metadata +++ /dev/null @@ -1 +0,0 @@ -27f240cff200e00c28a486a028bcdb14f67f8790 SOURCES/mdadm-4.2.tar.xz diff --git a/0001-Coverity-fixes-resources-leaks.patch b/0001-Coverity-fixes-resources-leaks.patch new file mode 100644 index 0000000..6bc5606 --- /dev/null +++ b/0001-Coverity-fixes-resources-leaks.patch @@ -0,0 +1,91 @@ +From 8f54ce5b7eb0ca982803e270082e33f50897b9a6 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Mon, 4 Nov 2024 11:17:46 -0500 +Subject: [PATCH 01/37] Coverity fixes resources leaks + +Handle variable going out of scope leaks the handle. + +Signed-off-by: Nigel Croxon +--- + Assemble.c | 3 ++- + Incremental.c | 2 +- + bitmap.c | 7 +++++-- + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 37a530ee..f8099cd3 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -753,6 +753,7 @@ static int load_devices(struct devs *devices, char *devmap, + tst->ss->free_super(tst); + free(tst); + *stp = st; ++ free(best); + return -1; + } + close(dfd); +@@ -834,7 +835,6 @@ static int load_devices(struct devs *devices, char *devmap, + inargv ? "the list" : + "the\n DEVICE list in mdadm.conf" + ); +- free(best); + *stp = st; + goto error; + } +@@ -857,6 +857,7 @@ error: + close(mdfd); + free(devices); + free(devmap); ++ free(best); + return -1; + + } +diff --git a/Incremental.c b/Incremental.c +index aa5db3bf..9b455a12 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -282,7 +282,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + * clustering resource agents + */ + if (info.array.state & (1 << MD_SB_CLUSTERED)) +- goto out; ++ goto out_unlock; + + /* Couldn't find an existing array, maybe make a new one */ + mdfd = create_mddev(match ? match->devname : NULL, name_to_use, trustworthy, +diff --git a/bitmap.c b/bitmap.c +index c62d18d4..3f8da63d 100644 +--- a/bitmap.c ++++ b/bitmap.c +@@ -260,8 +260,11 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + return rv; + + info = bitmap_fd_read(fd, brief); +- if (!info) ++ if (!info) { ++ close_fd(&fd); ++ free(info); + return rv; ++ } + sb = &info->sb; + if (sb->magic != BITMAP_MAGIC) { + pr_err("This is an md array. To view a bitmap you need to examine\n"); +@@ -336,7 +339,6 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + printf(" Cluster name : %-64s\n", sb->cluster_name); + for (i = 0; i < (int)sb->nodes; i++) { + st = NULL; +- free(info); + fd = bitmap_file_open(filename, &st, i, fd); + if (fd < 0) { + printf(" Unable to open bitmap file on node: %i\n", i); +@@ -347,6 +349,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + printf(" Unable to read bitmap on node: %i\n", i); + continue; + } ++ free(sb); + sb = &info->sb; + if (sb->magic != BITMAP_MAGIC) + pr_err("invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic); +-- +2.41.0 + diff --git a/0002-Incremental-Document-workaround.patch b/0002-Incremental-Document-workaround.patch new file mode 100644 index 0000000..5cbb90a --- /dev/null +++ b/0002-Incremental-Document-workaround.patch @@ -0,0 +1,64 @@ +From 7de5dc53bfbc3bae7d43fc81e51c7c56638004f6 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 4 Nov 2024 11:37:41 +0100 +Subject: [PATCH 02/37] Incremental: Document workaround + +Keep it documented in code. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 9b455a12..60d6f8cb 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1693,15 +1693,30 @@ int Incremental_remove(char *devname, char *id_path, int verbose) + + mdfd = open_dev_excl(ent->devnm); + if (is_fd_valid(mdfd)) { ++ char *array_state_file = "array_state"; ++ ++ /** ++ * This is a workaround for the old issue. ++ * Incremental_remove() triggered from udev rule when disk is removed from OS ++ * tries to set array in auto-read-only mode. This can interrupt rebuild ++ * process which is started automatically, e.g. if array is mounted and ++ * spare disk is available (I/O errors limit might be achieved faster than disk is ++ * removed by mdadm). Prevent Incremental_remove() from setting array ++ * into "auto-read-only", by requiring exclusive open to succeed. ++ */ + close_fd(&mdfd); +- if (sysfs_get_str(&mdi, NULL, "array_state", +- buf, sizeof(buf)) > 0) { +- if (strncmp(buf, "active", 6) == 0 || +- strncmp(buf, "clean", 5) == 0) +- sysfs_set_str(&mdi, NULL, +- "array_state", "read-auto"); ++ ++ if (sysfs_get_str(&mdi, NULL, array_state_file, buf, sizeof(buf)) > 0) { ++ char *str_read_auto = map_num_s(sysfs_array_states, ARRAY_READ_AUTO); ++ char *str_active = map_num_s(sysfs_array_states, ARRAY_ACTIVE); ++ char *str_clean = map_num_s(sysfs_array_states, ARRAY_CLEAN); ++ ++ if (strncmp(buf, str_active, strlen(str_active)) == 0 || ++ strncmp(buf, str_clean, strlen(str_clean)) == 0) ++ sysfs_set_str(&mdi, NULL, array_state_file, str_read_auto); + } + } ++ + mdfd = open_dev(ent->devnm); + if (mdfd < 0) { + if (verbose >= 0) +@@ -1711,6 +1726,7 @@ int Incremental_remove(char *devname, char *id_path, int verbose) + + if (id_path) { + struct map_ent *map = NULL, *me; ++ + me = map_by_devnm(&map, ent->devnm); + if (me) + policy_save_path(id_path, me); +-- +2.41.0 + diff --git a/0003-sysfs-functions-for-writing-md-memb-state.patch b/0003-sysfs-functions-for-writing-md-memb-state.patch new file mode 100644 index 0000000..b951f59 --- /dev/null +++ b/0003-sysfs-functions-for-writing-md-memb-state.patch @@ -0,0 +1,164 @@ +From 42db5429cba52c7d86db965100873928e29c512b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 4 Nov 2024 15:08:30 +0100 +Subject: [PATCH 03/37] sysfs: functions for writing md//state + +Add dedicated enum to reflect possible values for mentioned file. +Not all values are mapped. Add map to present sysfs keywords. + +Signed-off-by: Mariusz Tkaczyk +--- + Manage.c | 4 +--- + mdadm.h | 19 +++++++++++++++++++ + monitor.c | 12 ++++++------ + sysfs.c | 32 ++++++++++++++++++++++++++++++++ + util.c | 3 +-- + 5 files changed, 59 insertions(+), 11 deletions(-) + +diff --git a/Manage.c b/Manage.c +index b14a9ab9..d618a2f0 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1675,9 +1675,7 @@ int Manage_subdevs(char *devname, int fd, + } + case 'I': + if (is_fd_valid(sysfd)) { +- static const char val[] = "faulty"; +- +- rv = sysfs_write_descriptor(sysfd, val, strlen(val), &err); ++ rv = sysfs_set_memb_state_fd(sysfd, MEMB_STATE_FAULTY, &err); + } else { + rv = ioctl(fd, SET_DISK_FAULTY, rdev); + if (rv) +diff --git a/mdadm.h b/mdadm.h +index ebb2ca18..218056c8 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -807,9 +807,28 @@ enum sysfs_read_flags { + + #define SYSFS_MAX_BUF_SIZE 64 + ++/** ++ * Defines md//state possible values. ++ * Note that remove can't be read-back from the file. ++ * ++ * This is not complete list. ++ */ ++typedef enum memb_state { ++ MEMB_STATE_EXTERNAL_BBL, ++ MEMB_STATE_BLOCKED, ++ MEMB_STATE_SPARE, ++ MEMB_STATE_WRITE_MOSTLY, ++ MEMB_STATE_IN_SYNC, ++ MEMB_STATE_FAULTY, ++ MEMB_STATE_REMOVE, ++ MEMB_STATE_UNKNOWN ++} memb_state_t; ++char *map_memb_state(memb_state_t state); ++ + extern mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, + const ssize_t len, int *errno_p); + extern mdadm_status_t write_attr(const char *value, const int fd); ++extern mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err); + extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf); + + extern int sysfs_open(char *devnm, char *devname, char *attr); +diff --git a/monitor.c b/monitor.c +index 3c54f8cb..b771707a 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -140,17 +140,17 @@ int read_dev_state(int fd) + + cp = buf; + while (cp) { +- if (sysfs_attr_match(cp, "faulty")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_FAULTY))) + rv |= DS_FAULTY; +- if (sysfs_attr_match(cp, "in_sync")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_IN_SYNC))) + rv |= DS_INSYNC; +- if (sysfs_attr_match(cp, "write_mostly")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_WRITE_MOSTLY))) + rv |= DS_WRITE_MOSTLY; +- if (sysfs_attr_match(cp, "spare")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_SPARE))) + rv |= DS_SPARE; +- if (sysfs_attr_match(cp, "blocked")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_BLOCKED))) + rv |= DS_BLOCKED; +- if (sysfs_attr_match(cp, "external_bbl")) ++ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_EXTERNAL_BBL))) + rv |= DS_EXTERNAL_BB; + cp = strchr(cp, ','); + if (cp) +diff --git a/sysfs.c b/sysfs.c +index a3bcb432..60b27459 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -75,6 +75,23 @@ void sysfs_free(struct mdinfo *sra) + sra = sra2; + } + } ++ ++mapping_t sysfs_memb_states[] = { ++ {"external_bbl", MEMB_STATE_EXTERNAL_BBL}, ++ {"blocked", MEMB_STATE_BLOCKED}, ++ {"spare", MEMB_STATE_SPARE}, ++ {"write_mostly", MEMB_STATE_WRITE_MOSTLY}, ++ {"in_sync", MEMB_STATE_IN_SYNC}, ++ {"faulty", MEMB_STATE_FAULTY}, ++ {"remove", MEMB_STATE_REMOVE}, ++ {NULL, MEMB_STATE_UNKNOWN} ++}; ++ ++char *map_memb_state(memb_state_t state) ++{ ++ return map_num_s(sysfs_memb_states, state); ++} ++ + /** + * write_attr() - write value to fd, don't check errno. + * @attr: value to write. +@@ -117,6 +134,21 @@ mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, const ssi + return MDADM_STATUS_SUCCESS; + } + ++/** ++ * sysfs_set_memb_state_fd() - write to md//state file. ++ * @fd: open file descriptor to the file. ++ * @state: enum value describing value to write ++ * @err: errno value pointer in case of error. ++ * ++ * This is helper to avoid inlining values, they are extracted from map now. ++ */ ++mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err) ++{ ++ const char *val = map_memb_state(state); ++ ++ return sysfs_write_descriptor(fd, val, strlen(val), err); ++} ++ + /** + * sysfs_get_container_devnm() - extract container device name. + * @mdi: md_info describes member array, with GET_VERSION option. +diff --git a/util.c b/util.c +index a120c985..6aa44a80 100644 +--- a/util.c ++++ b/util.c +@@ -1808,12 +1808,11 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force) + + int sys_hot_remove_disk(int statefd, int force) + { +- static const char val[] = "remove"; + int cnt = force ? 500 : 5; + + while (cnt--) { + int err = 0; +- int ret = sysfs_write_descriptor(statefd, val, strlen(val), &err); ++ int ret = sysfs_set_memb_state_fd(statefd, MEMB_STATE_REMOVE, &err); + + if (ret == MDADM_STATUS_SUCCESS) + return 0; +-- +2.41.0 + diff --git a/0004-Incremental-Simplify-remove-logic.patch b/0004-Incremental-Simplify-remove-logic.patch new file mode 100644 index 0000000..fb105ef --- /dev/null +++ b/0004-Incremental-Simplify-remove-logic.patch @@ -0,0 +1,259 @@ +From b9888145987e273a7613209721a68f75e060263e Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 5 Nov 2024 13:07:16 +0100 +Subject: [PATCH 04/37] Incremental: Simplify remove logic + +Incremental_remove() does not execute Manage_subdevs() now. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 116 ++++++++++++++++++++++++++++++++------------------ + Manage.c | 10 ++--- + mdadm.h | 1 + + sysfs.c | 23 ++++++++++ + 4 files changed, 102 insertions(+), 48 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 60d6f8cb..228d2bdd 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1610,22 +1610,6 @@ release: + return rv; + } + +-static void remove_from_member_array(struct mdstat_ent *memb, +- struct mddev_dev *devlist, int verbose) +-{ +- int subfd = open_dev(memb->devnm); +- +- if (subfd >= 0) { +- /* +- * Ignore the return value because it's necessary +- * to handle failure condition here. +- */ +- Manage_subdevs(memb->devnm, subfd, devlist, verbose, +- 0, UOPT_UNDEFINED, 0); +- close(subfd); +- } +-} +- + /** + * is_devnode_path() - check if the devname passed might be devnode path. + * @devnode: the path to check. +@@ -1646,25 +1630,81 @@ static bool is_devnode_path(char *devnode) + return false; + } + ++/** ++ * Incremental_remove_external() - Remove the device from external container. ++ * @device_devnm: block device to remove. ++ * @container_devnm: the parent container ++ * @mdstat: mdstat file content. ++ * @verbose: verbose flag. ++ * ++ * Fail member device in each subarray and remove member device from external container. ++ * The resposibility of removing member disks from external subararys belongs to mdmon. ++ */ ++static mdadm_status_t Incremental_remove_external(char *device_devnm, char *container_devnm, ++ struct mdstat_ent *mdstat, int verbose) ++{ ++ mdadm_status_t rv = MDADM_STATUS_SUCCESS; ++ struct mdstat_ent *memb; ++ ++ for (memb = mdstat ; memb ; memb = memb->next) { ++ mdadm_status_t ret = MDADM_STATUS_SUCCESS; ++ int state_fd; ++ ++ if (!is_container_member(memb, container_devnm)) ++ continue; ++ ++ /* ++ * Checking mdstat is pointles because it might be outdated, try open descriptor ++ * instead. If it fails, we are fine with that, device is already gone. ++ */ ++ state_fd = sysfs_open_memb_attr(memb->devnm, device_devnm, "state", O_RDWR); ++ if (!is_fd_valid(state_fd)) ++ continue; ++ ++ ret = sysfs_set_memb_state_fd(state_fd, MEMB_STATE_FAULTY, NULL); ++ if (ret && verbose >= 0) ++ pr_err("Cannot fail member device %s in external subarray %s.\n", ++ device_devnm, memb->devnm); ++ ++ close_fd(&state_fd); ++ ++ /* ++ * Don't remove member device from container if it failed to remove it ++ * from any member array. ++ */ ++ rv |= ret; ++ } ++ ++ if (rv == MDADM_STATUS_SUCCESS) ++ rv = sysfs_set_memb_state(container_devnm, device_devnm, MEMB_STATE_REMOVE); ++ ++ if (rv && verbose >= 0) ++ pr_err("Cannot remove member device %s from container %s.\n", device_devnm, ++ container_devnm); ++ ++ return rv; ++} ++ + /** + * Incremental_remove() - Remove the device from all raid arrays. + * @devname: the device we want to remove, it could be kernel device name or devnode. + * @id_path: optional, /dev/disk/by-path path to save for bare scenarios support. + * @verbose: verbose flag. + * +- * First, fail the device (if needed) and then remove the device from native raid array or external +- * container. If it is external container, the device is removed from each subarray first. ++ * First, fail the device (if needed) and then remove the device. This code is critical for system ++ * funtionality and that is why it is keept as simple as possible. We do not load devices using ++ * sysfs_read() because any unerelated failure may lead us to abort. We also do not call ++ * Manage_Subdevs(). + */ + int Incremental_remove(char *devname, char *id_path, int verbose) + { ++ mdadm_status_t rv = MDADM_STATUS_SUCCESS; + char *devnm = basename(devname); +- struct mddev_dev devlist = {0}; + char buf[SYSFS_MAX_BUF_SIZE]; + struct mdstat_ent *mdstat; + struct mdstat_ent *ent; + struct mdinfo mdi; +- int rv = 1; +- int mdfd; ++ int mdfd = -1; + + if (strcmp(devnm, devname) != 0) + if (!is_devnode_path(devname)) { +@@ -1733,32 +1773,24 @@ int Incremental_remove(char *devname, char *id_path, int verbose) + map_free(map); + } + +- devlist.devname = devnm; +- devlist.disposition = 'I'; +- /* for a container, we must fail each member array */ + if (is_mdstat_ent_external(ent)) { +- struct mdstat_ent *memb; +- for (memb = mdstat ; memb ; memb = memb->next) { +- if (is_container_member(memb, ent->devnm)) +- remove_from_member_array(memb, +- &devlist, verbose); +- } +- } else { +- /* +- * This 'I' incremental remove is a try-best effort, +- * the failure condition can be safely ignored +- * because of the following up 'r' remove. +- */ +- Manage_subdevs(ent->devnm, mdfd, &devlist, +- verbose, 0, UOPT_UNDEFINED, 0); ++ rv = Incremental_remove_external(devnm, ent->devnm, mdstat, verbose); ++ goto out; + } + +- devlist.disposition = 'r'; +- rv = Manage_subdevs(ent->devnm, mdfd, &devlist, +- verbose, 0, UOPT_UNDEFINED, 0); ++ /* Native arrays are handled separatelly to provide more detailed error handling */ ++ rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_FAULTY); ++ if (rv && verbose >= 0) ++ pr_err("Cannot fail member device %s in array %s.\n", devnm, ent->devnm); ++ ++ if (rv == MDADM_STATUS_SUCCESS) ++ rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_REMOVE); ++ ++ if (rv && verbose >= 0) ++ pr_err("Cannot remove member device %s from %s.\n", devnm, ent->devnm); + +- close_fd(&mdfd); + out: ++ close_fd(&mdfd); + free_mdstat(mdstat); + return rv; + } +diff --git a/Manage.c b/Manage.c +index d618a2f0..034eb00c 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1381,8 +1381,6 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const + * '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. +@@ -1544,9 +1542,9 @@ int Manage_subdevs(char *devname, int fd, + + /* This is a kernel-internal name like 'sda1' */ + +- if (!strchr("rfI", dv->disposition)) { +- pr_err("%s only meaningful with -r, -f or -I, not -%c\n", +- dv->devname, dv->disposition); ++ if (!strchr("rf", dv->disposition)) { ++ pr_err("%s only meaningful with -r, -f, not -%c\n", dv->devname, ++ dv->disposition); + goto abort; + } + +@@ -1673,7 +1671,7 @@ int Manage_subdevs(char *devname, int fd, + close_fd(&sysfd); + goto abort; + } +- case 'I': ++ + if (is_fd_valid(sysfd)) { + rv = sysfs_set_memb_state_fd(sysfd, MEMB_STATE_FAULTY, &err); + } else { +diff --git a/mdadm.h b/mdadm.h +index 218056c8..77705b11 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -829,6 +829,7 @@ extern mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, + const ssize_t len, int *errno_p); + extern mdadm_status_t write_attr(const char *value, const int fd); + extern mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err); ++extern mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_state_t state); + extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf); + + extern int sysfs_open(char *devnm, char *devname, char *attr); +diff --git a/sysfs.c b/sysfs.c +index 60b27459..c030d634 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -149,6 +149,29 @@ mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err) + return sysfs_write_descriptor(fd, val, strlen(val), err); + } + ++/** ++ * sysfs_set_memb_state() - write to member disk state file. ++ * @array_devnm: kernel name of the array. ++ * @memb_devnm: kernel name of member device. ++ * @state: value to write. ++ * ++ * Function expects that the device exists, error is unconditionally printed. ++ */ ++mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_state_t state) ++{ ++ int state_fd = sysfs_open_memb_attr(array_devnm, memb_devnm, "state", O_RDWR); ++ ++ if (!is_fd_valid(state_fd)) { ++ pr_err("Cannot open file descriptor to %s in array %s, aborting.\n", ++ memb_devnm, array_devnm); ++ return MDADM_STATUS_ERROR; ++ } ++ ++ return sysfs_set_memb_state_fd(state_fd, state, NULL); ++ ++ close_fd(&state_fd); ++} ++ + /** + * sysfs_get_container_devnm() - extract container device name. + * @mdi: md_info describes member array, with GET_VERSION option. +-- +2.41.0 + diff --git a/0005-checkpatch.conf-ignore-NEW_TYPEDEFS.patch b/0005-checkpatch.conf-ignore-NEW_TYPEDEFS.patch new file mode 100644 index 0000000..0c43ad4 --- /dev/null +++ b/0005-checkpatch.conf-ignore-NEW_TYPEDEFS.patch @@ -0,0 +1,24 @@ +From 143d94f684b738d1aa89024b182ad4cfa1b9018b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 12 Nov 2024 14:05:11 +0100 +Subject: [PATCH 05/37] checkpatch.conf: ignore NEW_TYPEDEFS + +In mdadm, we have more flexible apporach to typedefs. + +Signed-off-by: Mariusz Tkaczyk +--- + .github/tools/.checkpatch.conf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/tools/.checkpatch.conf b/.github/tools/.checkpatch.conf +index d6e3bc44..03114847 100644 +--- a/.github/tools/.checkpatch.conf ++++ b/.github/tools/.checkpatch.conf +@@ -8,3 +8,4 @@ + --exclude tests + --ignore FILE_PATH_CHANGES + --ignore EMAIL_SUBJECT ++--ignore NEW_TYPEDEFS +-- +2.41.0 + diff --git a/0006-mdadm-add-MAINTAINERS-file.patch b/0006-mdadm-add-MAINTAINERS-file.patch new file mode 100644 index 0000000..016ab92 --- /dev/null +++ b/0006-mdadm-add-MAINTAINERS-file.patch @@ -0,0 +1,55 @@ +From 7f57f9b79dada30cdc64de1d2fe7541093c5b4e3 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Thu, 9 Jan 2025 15:09:51 -0500 +Subject: [PATCH 06/37] mdadm: add MAINTAINERS file + +Create a maintainers file to keep track of people +to contact when dealing with mdadm questions/issues. + +Signed-off-by: Nigel Croxon +--- + MAINTAINERS | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + create mode 100644 MAINTAINERS + +diff --git a/MAINTAINERS b/MAINTAINERS +new file mode 100644 +index 00000000..0a1229fd +--- /dev/null ++++ b/MAINTAINERS +@@ -0,0 +1,32 @@ ++ ++# List of maintainers for mdadm ++ ++ ++Descriptions of section entries: ++ ++M: Mail patches to: FullName ++L: Mailing list that is relevant to mdadm ++ ++ ++Alphabetical Order: ++ ++M: Blazej Kucman ++L: linux-raid@vger.kernel.org ++ ++M: Mateusz Kusiak ++L: linux-raid@vger.kernel.org ++ ++M: Mariusz Tkaczyk ++L: linux-raid@vger.kernel.org ++ ++M: Nigel Croxon ++L: linux-raid@vger.kernel.org ++ ++M: Song Liu ++L: linux-raid@vger.kernel.org ++ ++M: Xiao Ni ++L: linux-raid@vger.kernel.org ++ ++M: Yu Kuai ++L: linux-raid@vger.kernel.org +-- +2.41.0 + diff --git a/0007-mdadm.man-Remove-external-bitmap.patch b/0007-mdadm.man-Remove-external-bitmap.patch new file mode 100644 index 0000000..556089f --- /dev/null +++ b/0007-mdadm.man-Remove-external-bitmap.patch @@ -0,0 +1,127 @@ +From ef4b6a23189d804bfd8fa81f5038afe6ce825bde Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 7 Jan 2025 10:09:16 +0100 +Subject: [PATCH 07/37] mdadm.man: Remove external bitmap + +Remove external bitmap support from manual. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.8.in | 55 ++++++------------------------------------------------ + 1 file changed, 6 insertions(+), 49 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 2b6f3e50..83c0689f 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -740,27 +740,11 @@ parameter and are stored internally. + .B none + - create array with no bitmap or remove any present bitmap (grow mode). + +-Setting bitmap for file is deprecated and should not be used. The file should not exist unless +-.B \-\-force +-is also given. The same file should be provided when assembling the array. The file name must +-contain at least one slash ('/'). Bitmap files are only known to work on ext2 and ext3. Storing +-bitmap files on other filesystems may result in serious problems. +- +-When creating an array on devices which are 100G or larger, +-.I mdadm +-automatically adds an internal bitmap as it will usually be +-beneficial. This can be suppressed with +-.B "\-\-bitmap=none" +-or by selecting a different consistency policy with +-.BR \-\-consistency\-policy . +- + .TP + .BR \-\-bitmap\-chunk= + 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 an ++ + .B internal + bitmap, the chunk size defaults to 64Meg, or larger if necessary to + fit the bitmap into the available space. +@@ -1108,13 +1092,6 @@ are present. This is only needed with + and can be used if the physical connections to devices are + not as reliable as you would like. + +-.TP +-.BR \-b ", " \-\-bitmap= +-Specify the bitmap file that was given when the array was created. If +-an array has an +-.B internal +-bitmap, there is no need to specify this when assembling the array. +- + .TP + .BR \-\-backup\-file= + If +@@ -1614,9 +1591,8 @@ applies to a whole array which is currently active. + + .TP + .BR \-X ", " \-\-examine\-bitmap +-Report information about a bitmap file. +-The argument is either an external bitmap file or an array component +-in case of an internal bitmap. Note that running this on an array ++Report information about a bitmap. ++The argument is an array component. Note that running this on an array + device (e.g. + .BR /dev/md0 ) + does not report the bitmap for that array. +@@ -1774,10 +1750,7 @@ Only meaningful with + this will scan the + .B map + file for arrays that are being incrementally assembled and will try to +-start any that are not already started. If any such array is listed +-in +-.B mdadm.conf +-as requiring an external bitmap, that bitmap will be attached first. ++start any that are not already started. + + .TP + .BR \-\-fail ", " \-f +@@ -2151,15 +2124,7 @@ setting. + .\".B \-\-size + .\"is given, the apparent size of the smallest drive given is used. + +-If the array type supports a write-intent bitmap, and if the devices +-in the array exceed 100G is size, an internal write-intent bitmap +-will automatically be added unless some other option is explicitly +-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 +-can be added later with ++Space for a bitmap will be reserved so that one can be added later with + .BR "\-\-grow \-\-bitmap=internal" . + + If the metadata type supports it (currently only 1.x and IMSM metadata), +@@ -2735,11 +2700,6 @@ 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. + +-.PP +-Note: +-.B "--grow --size" +-is not yet supported for external file bitmap. +- + .SS RAID\-DEVICES CHANGES + + A RAID1 array can work with any number of devices from 1 upwards +@@ -2834,10 +2794,7 @@ stored on the device being reshaped. + .SS BITMAP CHANGES + + A write-intent bitmap can be added to, or removed from, an active +-array. Either internal bitmaps, or bitmaps stored in a separate file, +-can be added. Note that if you add a bitmap stored in a file which is +-in a filesystem that is on the RAID array being affected, the system +-will deadlock. The bitmap must be on a separate filesystem. ++array. + + .SS CONSISTENCY POLICY CHANGES + +-- +2.41.0 + diff --git a/0008-Remove-freeze-reshape-logic.patch b/0008-Remove-freeze-reshape-logic.patch new file mode 100644 index 0000000..aecf111 --- /dev/null +++ b/0008-Remove-freeze-reshape-logic.patch @@ -0,0 +1,223 @@ +From cbc1cd589496a4ae16eb226a7fbad71a7d3d842d Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 16 Oct 2024 10:48:08 +0000 +Subject: [PATCH 08/37] Remove --freeze-reshape logic + +This commit removes --freeze-reshape logic, it basicaly reverts +commit b76b30e0f950 ("Do not continue reshape during initrd phase"). +--freeze-reshape was supposed to be used to restore critical sector in +incremental and assemble operations without starting a reshape process, +but it's meaning has been lost through the years and it is not +currently used. + +A replacement for this logic will be added in incoming patches, so +reshapes won't be started in initrd phrase. + +Signed-off-by: Mateusz Kusiak +--- + Grow.c | 30 +++++++----------------------- + ReadMe.c | 1 - + mdadm.8.in | 37 ------------------------------------- + mdadm.c | 6 ------ + mdadm.h | 2 -- + 5 files changed, 7 insertions(+), 69 deletions(-) + +diff --git a/Grow.c b/Grow.c +index cc1be6cc..0d9e3b53 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1746,7 +1746,7 @@ static int reshape_array(char *container, int fd, char *devname, + int force, struct mddev_dev *devlist, + unsigned long long data_offset, + char *backup_file, int verbose, int forked, +- int restart, int freeze_reshape); ++ int restart); + static int reshape_container(char *container, char *devname, + int mdfd, + struct supertype *st, +@@ -2341,7 +2341,7 @@ size_change_error: + sync_metadata(st); + rv = reshape_array(container, fd, devname, st, &info, c->force, + devlist, s->data_offset, c->backup_file, +- c->verbose, 0, 0, 0); ++ c->verbose, 0, 0); + frozen = 0; + } + release: +@@ -3000,7 +3000,7 @@ static int reshape_array(char *container, int fd, char *devname, + int force, struct mddev_dev *devlist, + unsigned long long data_offset, + char *backup_file, int verbose, int forked, +- int restart, int freeze_reshape) ++ int restart) + { + struct reshape reshape; + int spares_needed; +@@ -3484,14 +3484,6 @@ started: + } + if (restart) + sysfs_set_str(sra, NULL, "array_state", "active"); +- if (freeze_reshape) { +- free(fdlist); +- free(offsets); +- sysfs_free(sra); +- pr_err("Reshape has to be continued from location %llu when root filesystem has been mounted.\n", +- sra->reshape_progress); +- return 1; +- } + + if (!forked) + if (continue_via_systemd(container ?: sra->sys_name, +@@ -3688,7 +3680,7 @@ int reshape_container(char *container, char *devname, + */ + ping_monitor(container); + +- if (!forked && !c->freeze_reshape) ++ if (!forked) + if (continue_via_systemd(container, GROW_SERVICE, NULL)) + return 0; + +@@ -3698,8 +3690,7 @@ int reshape_container(char *container, char *devname, + unfreeze(st); + return 1; + default: /* parent */ +- if (!c->freeze_reshape) +- printf("%s: multi-array reshape continues in background\n", Name); ++ printf("%s: multi-array reshape continues in background\n", Name); + return 0; + case 0: /* child */ + manage_fork_fds(0); +@@ -3797,15 +3788,9 @@ int reshape_container(char *container, char *devname, + + rv = reshape_array(container, fd, adev, st, + content, c->force, NULL, INVALID_SECTORS, +- c->backup_file, c->verbose, 1, restart, +- c->freeze_reshape); ++ c->backup_file, c->verbose, 1, restart); + close(fd); + +- if (c->freeze_reshape) { +- sysfs_free(cc); +- exit(0); +- } +- + restart = 0; + if (rv) + break; +@@ -5220,8 +5205,7 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, + } else + ret_val = reshape_array(NULL, mdfd, "array", st, info, 1, + NULL, INVALID_SECTORS, c->backup_file, +- 0, forked, 1 | info->reshape_active, +- c->freeze_reshape); ++ 0, forked, 1 | info->reshape_active); + + return ret_val; + } +diff --git a/ReadMe.c b/ReadMe.c +index 9c29723f..c2415c26 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -158,7 +158,6 @@ struct option long_options[] = { + {"scan", 0, 0, 's'}, + {"force", 0, 0, Force}, + {"update", 1, 0, 'U'}, +- {"freeze-reshape", 0, 0, FreezeReshape}, + + /* Management */ + {"add", 0, 0, Add}, +diff --git a/mdadm.8.in b/mdadm.8.in +index 83c0689f..45255521 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -880,31 +880,6 @@ different versions of + .I mdadm + are used to add different devices). + +-.TP +-.BR \-\-continue +-This option is complementary to the +-.B \-\-freeze-reshape +-option for assembly. It is needed when +-.B \-\-grow +-operation is interrupted and it is not restarted automatically due to +-.B \-\-freeze-reshape +-usage during array assembly. This option is used together with +-.BR \-G +-, ( +-.BR \-\-grow +-) command and device for a pending reshape to be continued. +-All parameters required for reshape continuation will be read from array metadata. +-If initial +-.BR \-\-grow +-command had required +-.BR \-\-backup\-file= +-option to be set, continuation option will require to have exactly the same +-backup file given as well. +-.IP +-Any other parameter passed together with +-.BR \-\-continue +-option will be ignored. +- + .TP + .BR \-N ", " \-\-name= + Set a +@@ -1302,18 +1277,6 @@ or + and allows the array to be again used on a kernel prior to Linux 5.3. + This option should be used with great caution. + +-.TP +-.BR \-\-freeze\-reshape +-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 +-.B \-\-continue +-option for the grow command. +- + .SH For Manage mode: + + .TP +diff --git a/mdadm.c b/mdadm.c +index 7d3b656b..a72058b4 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -710,12 +710,6 @@ int main(int argc, char *argv[]) + case O(MANAGE,Force): /* add device which is too large */ + c.force = 1; + continue; +- /* now for the Assemble options */ +- case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during +- * initrd phase */ +- case O(INCREMENTAL, FreezeReshape): +- c.freeze_reshape = 1; +- continue; + case O(CREATE,'u'): /* uuid of array */ + case O(ASSEMBLE,'u'): /* uuid of array */ + if (ident.uuid_set) { +diff --git a/mdadm.h b/mdadm.h +index 77705b11..6062e167 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -530,7 +530,6 @@ enum special_options { + RebuildMapOpt, + InvalidBackup, + UdevRules, +- FreezeReshape, + Continue, + OffRootOpt, + Prefer, +@@ -680,7 +679,6 @@ struct context { + int scan; + int SparcAdjust; + int delay; +- int freeze_reshape; + char *backup_file; + int invalid_backup; + char *action; +-- +2.41.0 + diff --git a/0009-Detail-Export-reshape-status.patch b/0009-Detail-Export-reshape-status.patch new file mode 100644 index 0000000..824eb81 --- /dev/null +++ b/0009-Detail-Export-reshape-status.patch @@ -0,0 +1,33 @@ +From 25267bcc1eb403b2d837069289990afdc097031f Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 9 Oct 2024 11:24:13 +0000 +Subject: [PATCH 09/37] Detail: Export reshape status + +Display if there's an ongoing reshape happening in mdadm --detail +--export output. + +This change is needed for incoming patches that will change "grow +continue" udev rules, to be based on actual array state. + +Signed-off-by: Mateusz Kusiak +--- + Detail.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Detail.c b/Detail.c +index 5819ced9..b804a624 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -290,6 +290,9 @@ int Detail(char *dev, struct context *c) + + map_free(map); + if (st && st->sb) { ++ if (info) ++ printf("MD_RESHAPE_ACTIVE=%s\n", ++ info->reshape_active ? "True" : "False"); + if (st->ss->export_detail_super) + st->ss->export_detail_super(st); + } +-- +2.41.0 + diff --git a/0010-mdadm-Do-not-start-reshape-before-switchroot.patch b/0010-mdadm-Do-not-start-reshape-before-switchroot.patch new file mode 100644 index 0000000..61b42a7 --- /dev/null +++ b/0010-mdadm-Do-not-start-reshape-before-switchroot.patch @@ -0,0 +1,217 @@ +From 8a0d3fea424c1c19c51993c0849ea76ea41e8003 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 10 Oct 2024 10:31:06 +0000 +Subject: [PATCH 10/37] mdadm: Do not start reshape before switchroot + +There are numerous issues for --grow --continue in switchroot phrase, +they include: +* Events being missed for restarting grow-continue service. This is + apparent mostly on OS on RAID scenarios. When a checkpoint (next step) + is committed, we have no reliable way to gracefully stop reshape until + it reaches that checkpoint. During boot, there's heavy I/O utilisation, + which causes sync speed drop, and naturally checkpoint takes longer to + reach. This further causes systemd to forcefully kill grow-continue + service due to timeouts, which results in udev event being missed for + grow-continue service restart. +* Grow-continue (seemingly) was not designed to be restarted without + reassembly, some things like stopping chunksize (to lower) migration + were straight up not working until recently. +This patch makes grow-continue (actual reshape) start after switchroot +phrase. This way we should not encounter issues related to restarting +the service. + +Add checks not start a reshape if in initrd, let it initialise only. +Change grow-continue udev rule to be triggered whenever there's a +reshape happening in metadata, rely on udev event to kick reshape after +switchroot. Add handle_forking helper function for reshapes to avoid +duplicating code. + +Signed-off-by: Mateusz Kusiak +--- + Grow.c | 81 +++++++++++++++++++++++++++------------ + mdadm_status.h | 3 +- + udev-md-raid-arrays.rules | 3 +- + util.c | 1 + + 4 files changed, 61 insertions(+), 27 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 0d9e3b53..2719346c 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2995,6 +2995,34 @@ static void catch_term(int sig) + sigterm = 1; + } + ++ ++/** ++ * handle_forking() - Handle reshape forking. ++ * ++ * @forked: if already forked. ++ * @devname: device name. ++ * Returns: -1 if fork() failed, ++ * 0 if child process, ++ * 1 if job delegated to forked process or systemd. ++ * ++ * This function is a helper function for reshapes for fork handling. ++ */ ++static mdadm_status_t handle_forking(bool forked, char *devname) ++{ ++ if (forked) ++ return MDADM_STATUS_FORKED; ++ ++ if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL)) ++ return MDADM_STATUS_SUCCESS; ++ ++ switch (fork()) { ++ case -1: return MDADM_STATUS_ERROR; /* error */ ++ case 0: return MDADM_STATUS_FORKED; /* child */ ++ default: return MDADM_STATUS_SUCCESS; /* parent */ ++ } ++ ++} ++ + static int reshape_array(char *container, int fd, char *devname, + struct supertype *st, struct mdinfo *info, + int force, struct mddev_dev *devlist, +@@ -3485,33 +3513,35 @@ started: + if (restart) + sysfs_set_str(sra, NULL, "array_state", "active"); + +- if (!forked) +- if (continue_via_systemd(container ?: sra->sys_name, +- GROW_SERVICE, NULL)) { +- free(fdlist); +- free(offsets); +- sysfs_free(sra); +- return 0; +- } ++ /* Do not run in initrd */ ++ if (in_initrd()) { ++ free(fdlist); ++ free(offsets); ++ sysfs_free(sra); ++ pr_info("Reshape has to be continued from location %llu when root filesystem has been mounted.\n", ++ sra->reshape_progress); ++ return 1; ++ } + + /* 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. + */ +- switch(forked ? 0 : fork()) { +- case -1: ++ switch (handle_forking(forked, container ? container : sra->sys_name)) { ++ default: /* Unused, only to satisfy compiler. */ ++ case MDADM_STATUS_ERROR: /* error */ + pr_err("Cannot run child to monitor reshape: %s\n", + strerror(errno)); + abort_reshape(sra); + goto release; +- default: ++ case MDADM_STATUS_FORKED: /* child */ ++ map_fork(); ++ break; ++ case MDADM_STATUS_SUCCESS: /* parent */ + free(fdlist); + free(offsets); + sysfs_free(sra); + return 0; +- case 0: +- map_fork(); +- break; + } + + /* Close unused file descriptor in the forked process */ +@@ -3680,22 +3710,19 @@ int reshape_container(char *container, char *devname, + */ + ping_monitor(container); + +- if (!forked) +- if (continue_via_systemd(container, GROW_SERVICE, NULL)) +- return 0; +- +- switch (forked ? 0 : fork()) { +- case -1: /* error */ ++ switch (handle_forking(forked, container)) { ++ default: /* Unused, only to satisfy compiler. */ ++ case MDADM_STATUS_ERROR: /* error */ + perror("Cannot fork to complete reshape\n"); + unfreeze(st); + return 1; +- default: /* parent */ +- printf("%s: multi-array reshape continues in background\n", Name); +- return 0; +- case 0: /* child */ ++ case MDADM_STATUS_FORKED: /* child */ + manage_fork_fds(0); + map_fork(); + break; ++ case MDADM_STATUS_SUCCESS: /* parent */ ++ printf("%s: multi-array reshape continues in background\n", Name); ++ return 0; + } + + /* close unused handle in child process +@@ -3791,6 +3818,12 @@ int reshape_container(char *container, char *devname, + c->backup_file, c->verbose, 1, restart); + close(fd); + ++ /* Do not run reshape in initrd but let it initialize.*/ ++ if (in_initrd()) { ++ sysfs_free(cc); ++ exit(0); ++ } ++ + restart = 0; + if (rv) + break; +diff --git a/mdadm_status.h b/mdadm_status.h +index 905105e2..e244127c 100644 +--- a/mdadm_status.h ++++ b/mdadm_status.h +@@ -7,7 +7,8 @@ typedef enum mdadm_status { + MDADM_STATUS_SUCCESS = 0, + MDADM_STATUS_ERROR, + MDADM_STATUS_UNDEF, +- MDADM_STATUS_MEM_FAIL ++ MDADM_STATUS_MEM_FAIL, ++ MDADM_STATUS_FORKED + } mdadm_status_t; + + #endif +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index 4e64b249..d8de6d00 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -15,7 +15,6 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state" + ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state" + TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end" + ATTR{md/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" +-ATTR{md/sync_action}=="reshape", ENV{RESHAPE_ACTIVE}="yes" + LABEL="md_ignore_state" + + IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode" +@@ -40,6 +39,6 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" + 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}=="?*", 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" ++ENV{MD_RESHAPE_ACTIVE}=="True", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" + + LABEL="md_end" +diff --git a/util.c b/util.c +index 6aa44a80..8099852f 100644 +--- a/util.c ++++ b/util.c +@@ -2307,6 +2307,7 @@ int continue_via_systemd(char *devnm, char *service_name, char *prefix) + int pid, status; + char pathbuf[1024]; + ++ dprintf("Start %s service\n", service_name); + /* Simply return that service cannot be started */ + if (check_env("MDADM_NO_SYSTEMCTL")) + return 0; +-- +2.41.0 + diff --git a/0011-Better-error-messages-for-broken-reshape.patch b/0011-Better-error-messages-for-broken-reshape.patch new file mode 100644 index 0000000..46a1fbe --- /dev/null +++ b/0011-Better-error-messages-for-broken-reshape.patch @@ -0,0 +1,48 @@ +From 70cba6ba8e83f2971d17ce6e36076d46191766d9 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Thu, 10 Oct 2024 12:45:11 +0000 +Subject: [PATCH 11/37] Better error messages for broken reshape + +mdadm --grow --continue has no functionality to restore critical sectors +if reshape was stopped during operation. This functionality belongs to +assemble or incremental. + +This patch adds hints to error messages, to try to reassemble array in +case of reshape failure to restore critical sector, so assemble can +handle restoration. + +Signed-off-by: Mateusz Kusiak +--- + Grow.c | 1 + + super-intel.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 2719346c..818eb6a4 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2387,6 +2387,7 @@ static int verify_reshape_position(struct mdinfo *info, int level) + } else if (info->reshape_progress > position) { + pr_err("Fatal error: array reshape was not properly frozen (expected reshape position is %llu, but reshape progress is %llu.\n", + position, info->reshape_progress); ++ pr_err("Reassemble array to try to restore critical sector.\n"); + ret_val = -1; + } else { + dprintf("Reshape position in md and metadata are the same;"); +diff --git a/super-intel.c b/super-intel.c +index 7e3c5f2b..cab84198 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -12596,7 +12596,8 @@ static int imsm_manage_reshape( + init_migr_record_imsm(st, dev, sra); + else { + if (__le32_to_cpu(migr_rec->rec_status) != UNIT_SRC_NORMAL) { +- dprintf("imsm: cannot restart migration when data are present in copy area.\n"); ++ pr_err("imsm: Cannot restart migration when data are present in copy area.\n" ++ " Reassemble array to try to restore critical sector.\n"); + goto abort; + } + /* Save checkpoint to update migration record for current +-- +2.41.0 + diff --git a/0012-Refactor-continue_via_systemd.patch b/0012-Refactor-continue_via_systemd.patch new file mode 100644 index 0000000..2ca2031 --- /dev/null +++ b/0012-Refactor-continue_via_systemd.patch @@ -0,0 +1,117 @@ +From 82ccad68d46d4b10a928bc860c0feedf26e483e3 Mon Sep 17 00:00:00 2001 +From: Mateusz Kusiak +Date: Wed, 20 Nov 2024 19:01:30 +0000 +Subject: [PATCH 12/37] Refactor continue_via_systemd() + +Refactor continue_via_systemd() and it's calls to make it more readable. +No functional changes. + +Signed-off-by: Mateusz Kusiak +--- + Grow.c | 2 +- + mdadm.h | 2 +- + util.c | 43 ++++++++++++++++++++++++------------------- + 3 files changed, 26 insertions(+), 21 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 818eb6a4..53b0b387 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3013,7 +3013,7 @@ static mdadm_status_t handle_forking(bool forked, char *devname) + if (forked) + return MDADM_STATUS_FORKED; + +- if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL)) ++ if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL) == MDADM_STATUS_SUCCESS) + return MDADM_STATUS_SUCCESS; + + switch (fork()) { +diff --git a/mdadm.h b/mdadm.h +index 6062e167..e84c341c 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1694,7 +1694,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, char *prefix); ++extern mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefix); + + extern void ident_init(struct mddev_ident *ident); + extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname); +diff --git a/util.c b/util.c +index 8099852f..8c45f0e1 100644 +--- a/util.c ++++ b/util.c +@@ -1982,7 +1982,7 @@ int start_mdmon(char *devnm) + + if (check_env("MDADM_NO_MDMON")) + return 0; +- if (continue_via_systemd(devnm, MDMON_SERVICE, prefix)) ++ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix) == MDADM_STATUS_SUCCESS) + return 0; + + /* That failed, try running mdmon directly */ +@@ -2299,36 +2299,41 @@ void manage_fork_fds(int close_all) + /* In a systemd/udev world, it is best to get systemd to + * run daemon rather than running in the background. + * Returns: +- * 1- if systemd service has been started +- * 0- otherwise ++ * MDADM_STATUS_SUCCESS - if systemd service has been started. ++ * MDADM_STATUS_ERROR - otherwise. + */ +-int continue_via_systemd(char *devnm, char *service_name, char *prefix) ++mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefix) + { + int pid, status; +- char pathbuf[1024]; ++ char pathbuf[PATH_MAX]; + + dprintf("Start %s service\n", service_name); + /* Simply return that service cannot be started */ + if (check_env("MDADM_NO_SYSTEMCTL")) +- return 0; ++ return MDADM_STATUS_SUCCESS; ++ ++ /* Fork in attempt to start services */ + switch (fork()) { +- case 0: +- manage_fork_fds(1); +- snprintf(pathbuf, sizeof(pathbuf), +- "%s@%s%s.service", service_name, prefix ?: "", devnm); +- status = execl("/usr/bin/systemctl", "systemctl", "restart", +- pathbuf, NULL); +- status = execl("/bin/systemctl", "systemctl", "restart", +- pathbuf, NULL); +- exit(1); +- case -1: /* Just do it ourselves. */ ++ case -1: /* Fork failed, just do it ourselves. */ + break; +- default: /* parent - good */ ++ case 0: /* child */ ++ manage_fork_fds(1); ++ snprintf(pathbuf, sizeof(pathbuf), "%s@%s%s.service", ++ service_name, prefix ? prefix : "", devnm); ++ ++ /* Attempt to start service. ++ * On success execl() will "kill" the fork, and return status of systemctl call. ++ */ ++ execl("/usr/bin/systemctl", "systemctl", "restart", pathbuf, NULL); ++ execl("/bin/systemctl", "systemctl", "restart", pathbuf, NULL); ++ exit(MDADM_STATUS_ERROR); ++ default: /* parent */ ++ /* Check if forked process successfully trigered service */ + pid = wait(&status); + if (pid >= 0 && status == 0) +- return 1; ++ return MDADM_STATUS_SUCCESS; + } +- return 0; ++ return MDADM_STATUS_ERROR; + } + + int in_initrd(void) +-- +2.41.0 + diff --git a/0013-mdadm-raid6check-add-xmalloc.h-to-raid6check.c.patch b/0013-mdadm-raid6check-add-xmalloc.h-to-raid6check.c.patch new file mode 100644 index 0000000..bbbd4ec --- /dev/null +++ b/0013-mdadm-raid6check-add-xmalloc.h-to-raid6check.c.patch @@ -0,0 +1,32 @@ +From e0df6c4c984d564e9e40913727e916a6cd8f466e Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 17 Jan 2025 15:15:40 +0800 +Subject: [PATCH 13/37] mdadm/raid6check: add xmalloc.h to raid6check.c + +It reports building error: +raid6check.c:324:26: error: implicit declaration of function xmalloc + +Add xmalloc.h to raid6check.c file to fix this. + +Signed-off-by: Xiao Ni +Link: https://lore.kernel.org/r/20250117071540.4094-1-xni@redhat.com +Signed-off-by: Song Liu +--- + raid6check.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/raid6check.c b/raid6check.c +index 99477761..95533f7d 100644 +--- a/raid6check.c ++++ b/raid6check.c +@@ -23,6 +23,7 @@ + */ + + #include "mdadm.h" ++#include "xmalloc.h" + #include + #include + +-- +2.41.0 + diff --git a/0014-mdopen-add-sbin-path-to-env-PATH-when-call-system-mo.patch b/0014-mdopen-add-sbin-path-to-env-PATH-when-call-system-mo.patch new file mode 100644 index 0000000..53b83ee --- /dev/null +++ b/0014-mdopen-add-sbin-path-to-env-PATH-when-call-system-mo.patch @@ -0,0 +1,56 @@ +From b1ee932b89a16c881a3336f9fd728d46c1f8c65d Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Wed, 22 Jan 2025 23:18:59 +0800 +Subject: [PATCH 14/37] mdopen: add sbin path to env PATH when call + system("modprobe md_mod") + +During the boot process if mdadm is called in udev context, sbin paths +like /sbin, /usr/sbin, /usr/local/sbin normally not defined in PATH env +variable, calling system("modprobe md_mod") in create_named_array() may +fail with 'sh: modprobe: command not found' error message. + +We don't want to move modprobe binary into udev private directory, so +setting the PATH env is a more proper method to avoid the above issue. + +This patch sets PATH env variable with "/sbin:/usr/sbin:/usr/local/sbin" +before calling system("modprobe md_mod"). The change only takes effect +within the udev worker context, not seen by global udev environment. + +Signed-off-by: Coly Li +Signed-off-by: Mariusz Tkaczyk +--- + mdopen.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/mdopen.c b/mdopen.c +index 26f0c716..57252b64 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -39,6 +39,24 @@ int create_named_array(char *devnm) + + fd = open(new_array_file, O_WRONLY); + if (fd < 0 && errno == ENOENT) { ++ char buf[PATH_MAX] = {0}; ++ char *env_ptr; ++ ++ env_ptr = getenv("PATH"); ++ /* ++ * When called by udev worker context, path of modprobe ++ * might not be in env PATH. Set sbin paths into PATH ++ * env to avoid potential failure when run modprobe here. ++ */ ++ if (env_ptr) ++ snprintf(buf, PATH_MAX - 1, "%s:%s", env_ptr, ++ "/sbin:/usr/sbin:/usr/local/sbin"); ++ else ++ snprintf(buf, PATH_MAX - 1, "%s", ++ "/sbin:/usr/sbin:/usr/local/sbin"); ++ ++ setenv("PATH", buf, 1); ++ + if (system("modprobe md_mod") == 0) + fd = open(new_array_file, O_WRONLY); + } +-- +2.41.0 + diff --git a/0015-udev-persist-properties-of-MD-devices-after-switch_r.patch b/0015-udev-persist-properties-of-MD-devices-after-switch_r.patch new file mode 100644 index 0000000..6d61792 --- /dev/null +++ b/0015-udev-persist-properties-of-MD-devices-after-switch_r.patch @@ -0,0 +1,40 @@ +From 21e4efb1cd15c4de4a57de26b0ea2e4234aa8ce5 Mon Sep 17 00:00:00 2001 +From: Antonio Alvarez Feijoo +Date: Thu, 23 Jan 2025 19:46:38 +0100 +Subject: [PATCH 15/37] udev: persist properties of MD devices after + switch_root + +dracut installs in the initrd a custom udev rule for MD devices +(59-persistent-storage-md.rules) only to set the db_persist option (see +[1]). The main purpose is that if an MD device is activated in the initrd, +its properties are kept on the udev database after the transition from the +initrd to the rootfs. This was added to fix detection issues when LVM is +on top. + +This patch would allow to remove the custom udev rule shipped by dracut +(63-md-raid-arrays.rules is already being installed in the initrd), and it +will also benefit other initrd generators that do not want to create +custom udev rules. + +[1] https://github.com/dracutdevs/dracut/blob/master/modules.d/90mdraid + +Signed-off-by: Antonio Alvarez Feijoo +--- + udev-md-raid-arrays.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index d8de6d00..a8098dc5 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -29,6 +29,7 @@ ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNA + IMPORT{builtin}="blkid" + OPTIONS+="link_priority=100" + OPTIONS+="watch" ++OPTIONS+="db_persist" + ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" + ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}" + ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" +-- +2.41.0 + diff --git a/0016-mdadm-fix-grow-with-add-for-linear.patch b/0016-mdadm-fix-grow-with-add-for-linear.patch new file mode 100644 index 0000000..90cb8d7 --- /dev/null +++ b/0016-mdadm-fix-grow-with-add-for-linear.patch @@ -0,0 +1,36 @@ +From c09ae8417dc9e11da1d5bf2867c6498050c6ddb9 Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Fri, 27 Dec 2024 14:07:02 +0800 +Subject: [PATCH 16/37] mdadm: fix --grow with --add for linear + +For the case mdadm --grow with --add, the s.btype should not be +initialized yet, hence BitmapUnknown should be checked instead of +BitmapNone. + +Noted that this behaviour should only support by md-linear, which is +removed from kernel, howerver, it turns out md-linear is used widely +in home NAS and we're planning to reintroduce it soon. + +Fixes: 581ba1341017 ("mdadm: remove bitmap file support") +Signed-off-by: Yu Kuai +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.c b/mdadm.c +index a72058b4..6200cd0e 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1619,7 +1619,7 @@ int main(int argc, char *argv[]) + if (devs_found > 1 && s.raiddisks == 0 && s.level == UnSet) { + /* must be '-a'. */ + if (s.size > 0 || s.chunk || +- s.layout_str || s.btype != BitmapNone) { ++ s.layout_str || s.btype != BitmapUnknown) { + pr_err("--add cannot be used with other geometry changes in --grow mode\n"); + rv = 1; + break; +-- +2.41.0 + diff --git a/0017-platform-intel-Disable-legacy-option-ROM-scan-on-UEF.patch b/0017-platform-intel-Disable-legacy-option-ROM-scan-on-UEF.patch new file mode 100644 index 0000000..a15cce3 --- /dev/null +++ b/0017-platform-intel-Disable-legacy-option-ROM-scan-on-UEF.patch @@ -0,0 +1,41 @@ +From 1fc0f290caeb0720aa6c97177ab429953f5bf10f Mon Sep 17 00:00:00 2001 +From: Ross Lagerwall +Date: Wed, 29 Jan 2025 13:31:11 +0000 +Subject: [PATCH 17/37] platform-intel: Disable legacy option ROM scan on UEFI + machines + +The legacy option ROM memory range from 0xc0000-0xeffff is not defined +on UEFI machines so don't attempt to scan it. This avoids lockdown log +spam when Secure Boot is enabled (avoids use of /dev/mem). + +Signed-off-by: Ross Lagerwall +--- + platform-intel.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/platform-intel.c b/platform-intel.c +index 95bc4929..270aef36 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -607,6 +607,7 @@ const struct imsm_orom *imsm_platform_test(struct sys_dev *hba) + + static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) + { ++ struct stat st; + unsigned long align; + + if (check_env("IMSM_TEST_OROM")) +@@ -616,6 +617,10 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) + if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) + return NULL; + ++ /* Skip legacy option ROM scan when EFI booted */ ++ if (stat("/sys/firmware/efi", &st) == 0 && S_ISDIR(st.st_mode)) ++ return NULL; ++ + find_intel_devices(); + + if (intel_devices == NULL) +-- +2.41.0 + diff --git a/0018-super-ddf-Prevent-crash-when-handling-DDF-metadata.patch b/0018-super-ddf-Prevent-crash-when-handling-DDF-metadata.patch new file mode 100644 index 0000000..14f40d2 --- /dev/null +++ b/0018-super-ddf-Prevent-crash-when-handling-DDF-metadata.patch @@ -0,0 +1,61 @@ +From 9e8b3b1492cff63dafb759382c74a479460f49e6 Mon Sep 17 00:00:00 2001 +From: lilinzhe +Date: Mon, 16 Dec 2024 12:00:02 +0800 +Subject: [PATCH 18/37] super-ddf: Prevent crash when handling DDF metadata + +A dummy function is defined because availability of ss->update_super is +not always verified. + +This fix addresses a crash reported when assembling a RAID array using +mdadm with DDF metadata. For more details, see the discussion at: +https://lore.kernel.org/all/ +CALHdMH30LuxR4tz9jP2ykDaDJtZ3P7L3LrZ+9e4Fq=Q6NwSM=Q@mail.gmail.com/ + +The discussion centers on an issue with mdadm where attempting to +assemble a RAID array caused a null pointer dereference. The problem +was traced to a missing update_super() function in super-ddf.c, which +led to a crash in Assemble.c. + +Signed-off-by: lilinzhe +--- + super-ddf.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/super-ddf.c b/super-ddf.c +index 6cd099ab..a06ed435 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -5195,6 +5195,21 @@ static void default_geometry_ddf(struct supertype *st, int *level, int *layout, + *layout = ddf_level_to_layout(*level); + } + ++static int update_super_ddf_dummy(struct supertype *st, struct mdinfo *info, ++ enum update_opt update, ++ char *devname, int verbose, ++ int uuid_set, char *homehost) ++{ ++ /* ++ * A dummy update_super function is required to ensure ++ * reliable handling of DDF metadata in mdadm. ++ * This implementation acts as a placeholder for cases ++ * where ss->update_super is not verified. ++ */ ++ dprintf("update_super is not implemented in DDF\n"); ++ return 0; ++} ++ + struct superswitch super_ddf = { + .examine_super = examine_super_ddf, + .brief_examine_super = brief_examine_super_ddf, +@@ -5213,6 +5228,8 @@ struct superswitch super_ddf = { + .uuid_from_super= uuid_from_super_ddf, + .getinfo_super = getinfo_super_ddf, + ++ .update_super = update_super_ddf_dummy, ++ + .avail_size = avail_size_ddf, + + .compare_super = compare_super_ddf, +-- +2.41.0 + diff --git a/0019-super-ddf-optimize-DDF-header-search-for-widely-used.patch b/0019-super-ddf-optimize-DDF-header-search-for-widely-used.patch new file mode 100644 index 0000000..850e18a --- /dev/null +++ b/0019-super-ddf-optimize-DDF-header-search-for-widely-used.patch @@ -0,0 +1,297 @@ +From f2197b6b6c14af6c788c628acd1fc6d92c268c53 Mon Sep 17 00:00:00 2001 +From: lilinzhe +Date: Mon, 16 Dec 2024 12:11:41 +0800 +Subject: [PATCH 19/37] super-ddf: optimize DDF header search for widely used + RAID controllers + +Implemented fallback logic to search the last 32MB of the device +for the DDF header (magic). If found, proceeds to load the DDF metadata +from the located position. + +When clearing metadata as required by the mdadm --zero (function Kill), +also erase the last 32MB of data; otherwise, it may result in an +infinite loop. + +According to the specification, the Anchor Header should be placed at +the end of the disk. However,some widely used RAID hardware, such as +LSI and PERC, do not position it within the last 512 bytes of the disk. + +Signed-off-by: lilinzhe +--- + super-ddf.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++----- + xmalloc.c | 11 +++ + xmalloc.h | 1 + + 3 files changed, 185 insertions(+), 17 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index a06ed435..6e7db924 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -272,6 +272,10 @@ struct phys_disk { + #define DDF_ReadErrors 32 + #define DDF_Missing 64 + ++ ++#define SEARCH_BLOCK_SIZE 4096 ++#define SEARCH_REGION_SIZE (32 * 1024 * 1024) ++ + /* The content of the virt_section global scope */ + struct virtual_disk { + be32 magic; /* DDF_VIRT_RECORDS_MAGIC */ +@@ -877,30 +881,180 @@ static void *load_section(int fd, struct ddf_super *super, void *buf, + return buf; + } + +-static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) ++ ++/* ++ * Search for DDF_HEADER_MAGIC in the last 32MB of the device ++ * ++ * According to the specification, the Anchor Header should be placed at ++ * the end of the disk. However,some widely used RAID hardware, such as ++ * LSI and PERC, do not position it within the last 512 bytes of the disk. ++ * ++ */ ++static int search_for_ddf_headers(int fd, char *devname, ++ unsigned long long *out) + { ++ unsigned long long search_start; ++ unsigned long long search_end; ++ size_t bytes_block_to_read; + unsigned long long dsize; ++ unsigned long long pos; ++ int bytes_current_read; ++ size_t offset; ++ ++ void *buffer = NULL; ++ be32 *magic_ptr = NULL; ++ ++ int result = 0; + + get_dev_size(fd, NULL, &dsize); + +- if (lseek64(fd, dsize - 512, 0) == -1L) { +- if (devname) +- pr_err("Cannot seek to anchor block on %s: %s\n", ++ ++ /* Determine the search range */ ++ if (dsize > SEARCH_REGION_SIZE) ++ search_start = dsize - SEARCH_REGION_SIZE; ++ else ++ search_start = 0; ++ ++ search_end = dsize; ++ pos = search_start; ++ ++ ++ buffer = xmemalign(SEARCH_BLOCK_SIZE, SEARCH_BLOCK_SIZE); ++ ++ if (buffer == NULL) { ++ result = 1; ++ goto cleanup; ++ } ++ ++ while (pos < search_end) { ++ /* Calculate the number of bytes to read in the current block */ ++ bytes_block_to_read = SEARCH_BLOCK_SIZE; ++ if (search_end - pos < SEARCH_BLOCK_SIZE) ++ bytes_block_to_read = search_end - pos; ++ ++ if (lseek64(fd, pos, SEEK_SET) < 0) { ++ pr_err("lseek64 for %s failed %d:%s\n", ++ fd2devnm(fd), errno, strerror(errno)); ++ result = 2; ++ goto cleanup; ++ } ++ ++ /*Read data from the device */ ++ bytes_current_read = read(fd, buffer, bytes_block_to_read); ++ ++ if (bytes_current_read <= 0) { ++ pr_err("Failed to read %s. %d:%s, Position=%llu, Bytes to read=%zu. Skipping.\n", ++ fd2devnm(fd), errno, strerror(errno), pos, bytes_block_to_read); ++ pos += SEARCH_BLOCK_SIZE; /* Skip to the next block */ ++ continue; ++ } ++ ++ /* Search for the magic value within the read block */ ++ for (offset = 0; ++ offset + sizeof(be32) <= (size_t)bytes_current_read; ++ offset += sizeof(be32)) { ++ ++ magic_ptr = (be32 *) ((char *)buffer + offset); ++ if (be32_eq(*magic_ptr, DDF_HEADER_MAGIC)) { ++ *out = pos + offset; ++ result = 0; ++ goto cleanup; ++ } ++ } ++ ++ pos += SEARCH_BLOCK_SIZE; ++ } ++ ++cleanup: ++ free(buffer); ++ return result; ++} ++ ++static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) ++{ ++ /* ++ * Load DDF headers from a device. ++ * First, check at dsize - 512, and if not found, search for it. ++ */ ++ unsigned long long dsize = 0; ++ unsigned long long ddfpos = 0; ++ unsigned long long ddffound = 0; ++ bool found_anchor = false; ++ ++ get_dev_size(fd, NULL, &dsize); ++ ++ /* Check the last 512 bytes for the DDF header. */ ++ if (lseek64(fd, dsize - 512, SEEK_SET) == -1L) { ++ if (devname) { ++ pr_err("Cannot seek to last 512 bytes on %s: %s\n", + devname, strerror(errno)); ++ } + return 1; + } +- if (read(fd, &super->anchor, 512) != 512) { +- if (devname) +- pr_err("Cannot read anchor block on %s: %s\n", ++ ++ ++ /* Read the last 512 bytes into the anchor block */ ++ if (read(fd, &super->anchor, 512) == 512) { ++ /* Check if the magic value matches */ ++ if (be32_eq(super->anchor.magic, DDF_HEADER_MAGIC)) ++ found_anchor = true; ++ ++ } else { ++ if (devname) { ++ pr_err("Cannot read last 512 bytes on %s: %s\n", + devname, strerror(errno)); +- return 1; ++ } + } +- if (!be32_eq(super->anchor.magic, DDF_HEADER_MAGIC)) { ++ ++ if (!found_anchor) { ++ /* If not found, perform a full search for DDF headers */ ++ ddffound = search_for_ddf_headers(fd, devname, &ddfpos); ++ if (ddffound != 0) { ++ if (devname) { ++ pr_err ++ ("DDF headers not found during search on %s\n", ++ devname); ++ } ++ return 2; ++ } ++ ++ /* Seek to the found position */ ++ if (lseek64(fd, ddfpos, SEEK_SET) == -1L) { ++ if (devname) { ++ pr_err("Cannot seek to anchor block on %s\n", ++ devname); ++ } ++ return 1; ++ } ++ ++ /* Read the header from the found position */ ++ if (read(fd, &super->anchor, 512) != 512) { ++ if (devname) { ++ pr_err ++ ("Cannot read DDF header at found position on %s: %s\n", ++ devname, strerror(errno)); ++ } ++ return 1; ++ } ++ ++ /* Verify the magic value again */ ++ if (!be32_eq(super->anchor.magic, DDF_HEADER_MAGIC)) { ++ if (devname) { ++ pr_err("Invalid DDF header magic value on %s\n", ++ devname); ++ } ++ return 2; ++ } ++ found_anchor = true; ++ } ++ if (!found_anchor) { ++ + if (devname) +- pr_err("no DDF anchor found on %s\n", +- devname); ++ pr_err("DDF headers not found on %s\n", devname); ++ + return 2; + } ++ + if (!be32_eq(calc_crc(&super->anchor, 512), super->anchor.crc)) { + if (devname) + pr_err("bad CRC on anchor on %s\n", +@@ -3889,16 +4043,17 @@ static int store_super_ddf(struct supertype *st, int fd) + dl->fd = ofd; + return ret; + } ++ // this is used for cleanup (Kill). to clean up 512 bytes ++ // at the end of the disk is not enough. ++ // clears SEARCH_REGION_SIZE bytes at the end of the disk. + +- if (posix_memalign(&buf, 512, 512) != 0) +- return 1; +- memset(buf, 0, 512); +- +- if (lseek64(fd, dsize - 512, 0) == -1L) { ++ buf = xmemalign(SEARCH_BLOCK_SIZE, SEARCH_REGION_SIZE); ++ memset(buf, 0, SEARCH_REGION_SIZE); ++ if (lseek64(fd, dsize - SEARCH_REGION_SIZE, 0) == -1L) { + free(buf); + return 1; + } +- rc = write(fd, buf, 512); ++ rc = write(fd, buf, SEARCH_REGION_SIZE); + free(buf); + if (rc < 0) + return 1; +@@ -5208,6 +5363,7 @@ static int update_super_ddf_dummy(struct supertype *st, struct mdinfo *info, + */ + dprintf("update_super is not implemented in DDF\n"); + return 0; ++ + } + + struct superswitch super_ddf = { +diff --git a/xmalloc.c b/xmalloc.c +index e28d3bd6..9472005e 100644 +--- a/xmalloc.c ++++ b/xmalloc.c +@@ -75,3 +75,14 @@ char *xstrdup(const char *str) + + return exit_memory_alloc_failure(); + } ++ ++void *xmemalign(size_t alignment, size_t size) ++{ ++ void *ptr = NULL; ++ int result = posix_memalign(&ptr, alignment, size); ++ ++ if (result == 0) ++ return ptr; ++ ++ return exit_memory_alloc_failure(); ++} +diff --git a/xmalloc.h b/xmalloc.h +index 0904b0ab..789948ae 100644 +--- a/xmalloc.h ++++ b/xmalloc.h +@@ -9,5 +9,6 @@ void *xmalloc(size_t len); + void *xrealloc(void *ptr, size_t len); + void *xcalloc(size_t num, size_t size); + char *xstrdup(const char *str); ++void *xmemalign(size_t alignment, size_t size); + + #endif +-- +2.41.0 + diff --git a/0020-bitmap.h-clear-__KERNEL__-based-headers.patch b/0020-bitmap.h-clear-__KERNEL__-based-headers.patch new file mode 100644 index 0000000..23bc562 --- /dev/null +++ b/0020-bitmap.h-clear-__KERNEL__-based-headers.patch @@ -0,0 +1,200 @@ +From eb9876f58658a107705a689852110903723e4d3b Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 3 Feb 2025 11:36:01 +0100 +Subject: [PATCH 20/37] bitmap.h - clear __KERNEL__ based headers + +It is unused for years. Clear it. + +Signed-off-by: Mariusz Tkaczyk +--- + bitmap.h | 169 ------------------------------------------------------- + 1 file changed, 169 deletions(-) + +diff --git a/bitmap.h b/bitmap.h +index 7b1f80f2..2614a14e 100644 +--- a/bitmap.h ++++ b/bitmap.h +@@ -78,63 +78,6 @@ + * + */ + +-#ifdef __KERNEL__ +- +-#define PAGE_BITS (PAGE_SIZE << 3) +-#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3) +- +-typedef __u16 bitmap_counter_t; +-#define COUNTER_BITS 16 +-#define COUNTER_BIT_SHIFT 4 +-#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8) +-#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3) +- +-#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1))) +-#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2))) +-#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1) +-#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK) +-#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK) +-#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX) +- +-/* how many counters per page? */ +-#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS) +-/* same, except a shift value for more efficient bitops */ +-#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT) +-/* same, except a mask value for more efficient bitops */ +-#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1) +- +-#define BITMAP_BLOCK_SIZE 512 +-#define BITMAP_BLOCK_SHIFT 9 +- +-/* how many blocks per chunk? (this is variable) */ +-#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT) +-#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT) +-#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1) +- +-/* when hijacked, the counters and bits represent even larger "chunks" */ +-/* there will be 1024 chunks represented by each counter in the page pointers */ +-#define PAGEPTR_BLOCK_RATIO(bitmap) \ +- (CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1) +-#define PAGEPTR_BLOCK_SHIFT(bitmap) \ +- (CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1) +-#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1) +- +-/* +- * on-disk bitmap: +- * +- * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap +- * file a page at a time. There's a superblock at the start of the file. +- */ +- +-/* map chunks (bits) to file pages - offset by the size of the superblock */ +-#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3)) +- +-#endif +- +-/* +- * bitmap structures: +- */ +- + #define BITMAP_MAGIC 0x6d746962 + + /* use these for bitmap->flags and bitmap->sb->state bit-fields */ +@@ -176,116 +119,4 @@ typedef struct bitmap_super_s { + * devices. For raid10 it is the size of the array. + */ + +-#ifdef __KERNEL__ +- +-/* the in-memory bitmap is represented by bitmap_pages */ +-struct bitmap_page { +- /* +- * map points to the actual memory page +- */ +- char *map; +- /* +- * in emergencies (when map cannot be allocated), hijack the map +- * pointer and use it as two counters itself +- */ +- unsigned int hijacked; +- /* +- * count of dirty bits on the page +- */ +- int count; +-}; +- +-/* keep track of bitmap file pages that have pending writes on them */ +-struct page_list { +- struct list_head list; +- struct page *page; +-}; +- +-/* the main bitmap structure - one per mddev */ +-struct bitmap { +- struct bitmap_page *bp; +- unsigned long pages; /* total number of pages in the bitmap */ +- unsigned long missing_pages; /* number of pages not yet allocated */ +- +- mddev_t *mddev; /* the md device that the bitmap is for */ +- +- int counter_bits; /* how many bits per block counter */ +- +- /* bitmap chunksize -- how much data does each bit represent? */ +- unsigned long chunksize; +- unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */ +- unsigned long chunks; /* total number of data chunks for the array */ +- +- /* We hold a count on the chunk currently being synced, and drop +- * it when the last block is started. If the resync is aborted +- * midway, we need to be able to drop that count, so we remember +- * the counted chunk.. +- */ +- unsigned long syncchunk; +- +- __u64 events_cleared; +- +- /* bitmap spinlock */ +- spinlock_t lock; +- +- struct file *file; /* backing disk file */ +- struct page *sb_page; /* cached copy of the bitmap file superblock */ +- struct page **filemap; /* list of cache pages for the file */ +- unsigned long *filemap_attr; /* attributes associated w/ filemap pages */ +- unsigned long file_pages; /* number of pages in the file */ +- +- unsigned long flags; +- +- /* +- * the bitmap daemon - periodically wakes up and sweeps the bitmap +- * file, cleaning up bits and flushing out pages to disk as necessary +- */ +- mdk_thread_t *daemon; +- unsigned long daemon_sleep; /* how many seconds between updates? */ +- +- /* +- * bitmap write daemon - this daemon performs writes to the bitmap file +- * this thread is only needed because of a limitation in ext3 (jbd) +- * that does not allow a task to have two journal transactions ongoing +- * simultaneously (even if the transactions are for two different +- * filesystems) -- in the case of bitmap, that would be the filesystem +- * that the bitmap file resides on and the filesystem that is mounted +- * on the md device -- see current->journal_info in jbd/transaction.c +- */ +- mdk_thread_t *write_daemon; +- mdk_thread_t *writeback_daemon; +- spinlock_t write_lock; +- struct semaphore write_ready; +- struct semaphore write_done; +- unsigned long writes_pending; +- wait_queue_head_t write_wait; +- struct list_head write_pages; +- struct list_head complete_pages; +- mempool_t *write_pool; +-}; +- +-/* the bitmap API */ +- +-/* these are used only by md/bitmap */ +-int bitmap_create(mddev_t *mddev); +-void bitmap_destroy(mddev_t *mddev); +-int bitmap_active(struct bitmap *bitmap); +- +-char *file_path(struct file *file, char *buf, int count); +-void bitmap_print_sb(struct bitmap *bitmap); +-int bitmap_update_sb(struct bitmap *bitmap); +- +-int bitmap_setallbits(struct bitmap *bitmap); +- +-/* these are exported */ +-void bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors); +-void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, +- int success); +-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks); +-void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); +-void bitmap_close_sync(struct bitmap *bitmap); +- +-int bitmap_unplug(struct bitmap *bitmap); +-#endif +- + #endif +-- +2.41.0 + diff --git a/0021-bitmap.h-Minor-fixes.patch b/0021-bitmap.h-Minor-fixes.patch new file mode 100644 index 0000000..0d88e0d --- /dev/null +++ b/0021-bitmap.h-Minor-fixes.patch @@ -0,0 +1,206 @@ +From 17fed47a64e1890df9820b93548c396b7de54e31 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 5 Feb 2025 11:34:45 +0100 +Subject: [PATCH 21/37] bitmap.h: Minor fixes + +Move documentation to documentation/bitmap.md. Add Neil's copyrights, +add missing license. Remove unused macros. + +Signed-off-by: Mariusz Tkaczyk +--- + bitmap.h | 94 ++++------------------------------------- + documentation/bitmap.md | 67 +++++++++++++++++++++++++++++ + 2 files changed, 75 insertions(+), 86 deletions(-) + create mode 100644 documentation/bitmap.md + +diff --git a/bitmap.h b/bitmap.h +index 2614a14e..9f3d4f3e 100644 +--- a/bitmap.h ++++ b/bitmap.h +@@ -1,83 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++ + /* +- * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 +- * +- * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc. ++ * Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003 ++ * Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc. ++ * Copyright (C) 2005 Neil Brown + */ ++ ++/* See documentation/bitmap.md */ ++ + #ifndef BITMAP_H + #define BITMAP_H 1 + + #define BITMAP_MAJOR_LO 3 +-/* version 4 insists the bitmap is in little-endian order +- * with version 3, it is host-endian which is non-portable +- */ + #define BITMAP_MAJOR_HI 4 +-#define BITMAP_MAJOR_HOSTENDIAN 3 + #define BITMAP_MAJOR_CLUSTERED 5 +- +-#define BITMAP_MINOR 39 +- +-/* +- * in-memory bitmap: +- * +- * Use 16 bit block counters to track pending writes to each "chunk". +- * The 2 high order bits are special-purpose, the first is a flag indicating +- * whether a resync is needed. The second is a flag indicating whether a +- * resync is active. +- * This means that the counter is actually 14 bits: +- * +- * +--------+--------+------------------------------------------------+ +- * | resync | resync | counter | +- * | needed | active | | +- * | (0-1) | (0-1) | (0-16383) | +- * +--------+--------+------------------------------------------------+ +- * +- * The "resync needed" bit is set when: +- * a '1' bit is read from storage at startup. +- * a write request fails on some drives +- * a resync is aborted on a chunk with 'resync active' set +- * It is cleared (and resync-active set) when a resync starts across all drives +- * of the chunk. +- * +- * +- * The "resync active" bit is set when: +- * a resync is started on all drives, and resync_needed is set. +- * resync_needed will be cleared (as long as resync_active wasn't already set). +- * It is cleared when a resync completes. +- * +- * The counter counts pending write requests, plus the on-disk bit. +- * When the counter is '1' and the resync bits are clear, the on-disk +- * bit can be cleared as well, thus setting the counter to 0. +- * When we set a bit, or in the counter (to start a write), if the fields is +- * 0, we first set the disk bit and set the counter to 1. +- * +- * If the counter is 0, the on-disk bit is clear and the stipe is clean +- * Anything that dirties the stipe pushes the counter to 2 (at least) +- * and sets the on-disk bit (lazily). +- * If a periodic sweep find the counter at 2, it is decremented to 1. +- * If the sweep find the counter at 1, the on-disk bit is cleared and the +- * counter goes to zero. +- * +- * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block +- * counters as a fallback when "page" memory cannot be allocated: +- * +- * Normal case (page memory allocated): +- * +- * page pointer (32-bit) +- * +- * [ ] ------+ +- * | +- * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) +- * c1 c2 c2048 +- * +- * Hijacked case (page memory allocation failed): +- * +- * hijacked page pointer (32-bit) +- * +- * [ ][ ] (no page memory allocated) +- * counter #1 (16-bit) counter #2 (16-bit) +- * +- */ +- + #define BITMAP_MAGIC 0x6d746962 + + /* use these for bitmap->flags and bitmap->sb->state bit-fields */ +@@ -105,18 +41,4 @@ typedef struct bitmap_super_s { + __u8 pad[256 - 136]; /* set to zero */ + } bitmap_super_t; + +-/* notes: +- * (1) This event counter is updated before the eventcounter in the md superblock +- * When a bitmap is loaded, it is only accepted if this event counter is equal +- * to, or one greater than, the event counter in the superblock. +- * (2) This event counter is updated when the other one is *if*and*only*if* the +- * array is not degraded. As bits are not cleared when the array is degraded, +- * this represents the last time that any bits were cleared. +- * If a device is being added that has an event count with this value or +- * higher, it is accepted as conforming to the bitmap. +- * (3)This is the number of sectors represented by the bitmap, and is the range that +- * resync happens across. For raid1 and raid5/6 it is the size of individual +- * devices. For raid10 it is the size of the array. +- */ +- + #endif +diff --git a/documentation/bitmap.md b/documentation/bitmap.md +new file mode 100644 +index 00000000..bdc146e5 +--- /dev/null ++++ b/documentation/bitmap.md +@@ -0,0 +1,67 @@ ++# Internal bitmap block design ++ ++Use 16 bit block counters to track pending writes to each "chunk". ++The 2 high order bits are special-purpose, the first is a flag indicating ++whether a resync is needed. The second is a flag indicating whether a ++resync is active. This means that the counter is actually 14 bits: ++ ++| resync_needed | resync_active | counter | ++| :----: | :----: | :----: | ++| (0-1) | (0-1) | (0-16383) | ++ ++The `resync_needed` bit is set when: ++- a `1` bit is read from storage at startup; ++- a write request fails on some drives; ++- a resync is aborted on a chunk with `resync_active` set; ++- It is cleared (and `resync_active` set) when a resync starts across all drives of the chunk. ++ ++The `resync_active` bit is set when: ++- a resync is started on all drives, and `resync_needed` is set. ++- `resync_needed` will be cleared (as long as `resync_active` wasn't already set). ++- It is cleared when a resync completes. ++ ++The counter counts pending write requests, plus the on-disk bit. ++When the counter is `1` and the resync bits are clear, the on-disk ++bit can be cleared as well, thus setting the counter to `0`. ++When we set a bit, or in the counter (to start a write), if the fields is ++`0`, we first set the disk bit and set the counter to `1`. ++ ++If the counter is `0`, the on-disk bit is clear and the stipe is clean ++Anything that dirties the stipe pushes the counter to `2` (at least) ++and sets the on-disk bit (lazily). ++If a periodic sweep find the counter at `2`, it is decremented to `1`. ++If the sweep find the counter at `1`, the on-disk bit is cleared and the ++counter goes to `0`. ++ ++Also, we'll hijack the "map" pointer itself and use it as two 16 bit block ++counters as a fallback when "page" memory cannot be allocated: ++ ++Normal case (page memory allocated): ++ ++page pointer (32-bit) ++ ++ [ ] ------+ ++ | ++ +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters) ++ c1 c2 c2048 ++ ++ Hijacked case (page memory allocation failed): ++ ++ hijacked page pointer (32-bit) ++ ++ [ ][ ] (no page memory allocated) ++ counter #1 (16-bit) counter #2 (16-bit) ++ ++ ++## Notes: ++1. bitmap_super_s->events counter is updated before the event counter in the md superblock; ++ When a bitmap is loaded, it is only accepted if this event counter is equal ++ to, or one greater than, the event counter in the superblock. ++2. bitmap_super_s->events is updated when the other one is `if` and `only if` the ++ array is not degraded. As bits are not cleared when the array is degraded, ++ this represents the last time that any bits were cleared. If a device is being ++ added that has an event count with this value or higher, it is accepted ++ as conforming to the bitmap. ++3. bitmap_super_s->chunksize is the number of sectors represented by the bitmap, ++ and is the range that resync happens across. For raid1 and raid5/6 it is the ++ size of individual devices. For raid10 it is the size of the array. +-- +2.41.0 + diff --git a/0022-Move-release-steps-to-documentation.patch b/0022-Move-release-steps-to-documentation.patch new file mode 100644 index 0000000..a9ac26b --- /dev/null +++ b/0022-Move-release-steps-to-documentation.patch @@ -0,0 +1,20 @@ +From 4b3932487a8dc2e87530e595ccabe48c79446f30 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 12 Feb 2025 11:29:05 +0100 +Subject: [PATCH 22/37] Move release steps to documentation/ + +Make a room for release MAINTAINERS file. + +Signed-off-by: Mariusz Tkaczyk +--- + MAINTAINERS.md => documentation/HOW_TO_RELEASE.md | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + rename MAINTAINERS.md => documentation/HOW_TO_RELEASE.md (100%) + +diff --git a/MAINTAINERS.md b/documentation/HOW_TO_RELEASE.md +similarity index 100% +rename from MAINTAINERS.md +rename to documentation/HOW_TO_RELEASE.md +-- +2.41.0 + diff --git a/0023-Rework-MAINTAINERS-file.patch b/0023-Rework-MAINTAINERS-file.patch new file mode 100644 index 0000000..2cf2c07 --- /dev/null +++ b/0023-Rework-MAINTAINERS-file.patch @@ -0,0 +1,102 @@ +From dacce2a0009f3506a5accf91f8fa9956eb36218e Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 12 Feb 2025 12:41:58 +0100 +Subject: [PATCH 23/37] Rework MAINTAINERS file + +Remove Mateusz. Intergrate it with README.md + +Signed-off-by: Mariusz Tkaczyk +--- + MAINTAINERS | 32 -------------------------------- + MAINTAINERS.md | 23 +++++++++++++++++++++++ + README.md | 5 +---- + 3 files changed, 24 insertions(+), 36 deletions(-) + delete mode 100644 MAINTAINERS + create mode 100644 MAINTAINERS.md + +diff --git a/MAINTAINERS b/MAINTAINERS +deleted file mode 100644 +index 0a1229fd..00000000 +--- a/MAINTAINERS ++++ /dev/null +@@ -1,32 +0,0 @@ +- +-# List of maintainers for mdadm +- +- +-Descriptions of section entries: +- +-M: Mail patches to: FullName +-L: Mailing list that is relevant to mdadm +- +- +-Alphabetical Order: +- +-M: Blazej Kucman +-L: linux-raid@vger.kernel.org +- +-M: Mateusz Kusiak +-L: linux-raid@vger.kernel.org +- +-M: Mariusz Tkaczyk +-L: linux-raid@vger.kernel.org +- +-M: Nigel Croxon +-L: linux-raid@vger.kernel.org +- +-M: Song Liu +-L: linux-raid@vger.kernel.org +- +-M: Xiao Ni +-L: linux-raid@vger.kernel.org +- +-M: Yu Kuai +-L: linux-raid@vger.kernel.org +diff --git a/MAINTAINERS.md b/MAINTAINERS.md +new file mode 100644 +index 00000000..00587484 +--- /dev/null ++++ b/MAINTAINERS.md +@@ -0,0 +1,23 @@ ++If you are sending patch through mailing list, please include everyone listed ++in this file. ++ ++## Github maintainers team ++ ++Github Pull Request must be `approved` by at least 2 maintainers team members: ++ ++ Name | Github Profile | Email address | ++| -- |----------------|---------------| ++| Blazej Kucman | [bkucman](https://github.com/bkucman) | | ++| Mariusz Tkaczyk | [mtkaczyk](https://github.com/mtkaczyk) | | ++| Nigel Croxon | [ncroxon](https://github.com/ncroxon) | | ++| Xiao Ni | [XiaoNi87](https://github.com/XiaoNi87) | | ++ ++## Kernel.org maintainers ++Reach this team specifically if you are observing differences ++between kernel.org and Github. ++ ++| Name | Email address | ++|------|----------------| ++| Mariusz Tkaczyk | | ++| Song Liu | | ++| Yu Kuai | | +diff --git a/README.md b/README.md +index 0c299a9a..029e0ee2 100644 +--- a/README.md ++++ b/README.md +@@ -77,10 +77,7 @@ to the chosen branch, then Pull Request will be automatically updated. + + # Maintainers of mdadm repository on kernel.org + +-If there are differences between github and kernel.org, please contact kernel.org mdadm maintainers: +- +-- Jes Sorensen ; +-- Mariusz Tkaczyk ; ++See [Maintainers File](MAINTAINERS.md). + + # Minimal supported kernel version + +-- +2.41.0 + diff --git a/0024-mdmon-imsm-fix-metadata-corruption-when-managing-new.patch b/0024-mdmon-imsm-fix-metadata-corruption-when-managing-new.patch new file mode 100644 index 0000000..1d41259 --- /dev/null +++ b/0024-mdmon-imsm-fix-metadata-corruption-when-managing-new.patch @@ -0,0 +1,122 @@ +From 7d29b3823c18a24d6efbb502f08638788f97e04b Mon Sep 17 00:00:00 2001 +From: Junxiao Bi +Date: Tue, 18 Feb 2025 10:48:31 -0800 +Subject: [PATCH 24/37] mdmon: imsm: fix metadata corruption when managing new + array + +When manager thread detects new array, it will invoke manage_new(). +For imsm array, it will further invoke imsm_open_new(). Since +commit bbab0940fa75("imsm: write bad block log on metadata sync"), +it preallocates bad block log when opening the array, that requires +increasing the mpb buffer size. +For that, imsm_open_new() invokes function imsm_update_metadata_locally(), +which first uses imsm_prepare_update() to allocate a larger mpb buffer +and store it at "mpb->next_buf", and then invoke imsm_process_update() +to copy the content from current mpb buffer "mpb->buf" to "mpb->next_buf", +and then free the current mpb buffer and set the new buffer as current. + +There is a small race window, when monitor thread is syncing metadata, +it gets current buffer pointer in imsm_sync_metadata()->write_super_imsm(), +but before flushing the buffer to disk, manager thread does above switching +buffer which frees current buffer, then monitor thread will run into +use-after-free issue and could cause on-disk metadata corruption. +If system keeps running, further metadata update could fix the corruption, +because after switching buffer, the new buffer will contain good metadata, +but if panic/power cycle happens while disk metadata is corrupted, +the system will run into bootup failure if array is used as root, +otherwise the array can not be assembled after boot if not used as root. + +This issue will not happen for imsm array with only one member array, +because the memory array has not be opened yet, monitor thread will not +do any metadata updates. +This can happen for imsm array with at lease two member array, in the +following two scenarios: +1. Restarting mdmon process with at least two member array +This will happen during system boot up or user restart mdmon after mdadm +upgrade +2. Adding new member array to exist imsm array with at least one member +array. + +To fix this, delay the switching buffer operation to monitor thread. + +Fixes: bbab0940fa75 ("imsm: write bad block log on metadata sync") +Signed-off-by: Junxiao Bi +--- + managemon.c | 10 ++++++++-- + super-intel.c | 14 +++++++++++--- + 2 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/managemon.c b/managemon.c +index d7981328..74b64bfc 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -721,11 +721,12 @@ static void manage_new(struct mdstat_ent *mdstat, + * the monitor. + */ + ++ struct metadata_update *update = NULL; + struct active_array *new = NULL; + struct mdinfo *mdi = NULL, *di; +- int i, inst; +- int failed = 0; + char buf[SYSFS_MAX_BUF_SIZE]; ++ int failed = 0; ++ int i, inst; + + /* check if array is ready to be monitored */ + if (!mdstat->active || !mdstat->level) +@@ -824,9 +825,14 @@ static void manage_new(struct mdstat_ent *mdstat, + /* if everything checks out tell the metadata handler we want to + * manage this instance + */ ++ container->update_tail = &update; + if (!aa_ready(new) || container->ss->open_new(container, new, inst) < 0) { ++ container->update_tail = NULL; + goto error; + } else { ++ if (update) ++ queue_metadata_update(update); ++ container->update_tail = NULL; + replace_array(container, victim, new); + if (failed) { + new->check_degraded = 1; +diff --git a/super-intel.c b/super-intel.c +index cab84198..4988eef1 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8467,12 +8467,15 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev, + return failed; + } + ++static int imsm_prepare_update(struct supertype *st, ++ struct metadata_update *update); + static int imsm_open_new(struct supertype *c, struct active_array *a, + int inst) + { + struct intel_super *super = c->sb; + struct imsm_super *mpb = super->anchor; +- struct imsm_update_prealloc_bb_mem u; ++ struct imsm_update_prealloc_bb_mem *u; ++ struct metadata_update mu; + + if (inst >= mpb->num_raid_devs) { + pr_err("subarry index %d, out of range\n", inst); +@@ -8482,8 +8485,13 @@ static int imsm_open_new(struct supertype *c, struct active_array *a, + dprintf("imsm: open_new %d\n", inst); + a->info.container_member = inst; + +- u.type = update_prealloc_badblocks_mem; +- imsm_update_metadata_locally(c, &u, sizeof(u)); ++ u = xmalloc(sizeof(*u)); ++ u->type = update_prealloc_badblocks_mem; ++ mu.len = sizeof(*u); ++ mu.buf = (char *)u; ++ imsm_prepare_update(c, &mu); ++ if (c->update_tail) ++ append_metadata_update(c, u, sizeof(*u)); + + return 0; + } +-- +2.41.0 + diff --git a/0025-Regression-fix-156.patch b/0025-Regression-fix-156.patch new file mode 100644 index 0000000..dc803f8 --- /dev/null +++ b/0025-Regression-fix-156.patch @@ -0,0 +1,217 @@ +From c2fbf66ba0243f499f78ed43fa1207a9bd9361b5 Mon Sep 17 00:00:00 2001 +From: XiaoNi87 +Date: Tue, 18 Mar 2025 08:18:04 +0800 +Subject: [PATCH 25/37] Regression fix (#156) + +Signed-off-by: Xiao Ni +--- + .github/tools/run_mdadm_tests.sh | 2 +- + test | 22 +++++++++++++++++++--- + tests/05r6tor0.broken | 15 +++++++++++++++ + tests/07revert-inplace.broken | 8 ++++++++ + tests/10ddf-create.broken | 5 ----- + tests/10ddf-fail-two-spares.broken | 5 ----- + tests/20raid5journal.broken | 17 +++++++++++++++++ + tests/env-ddf-template | 3 +-- + tests/skiptests | 9 +++++++++ + util.c | 2 +- + 10 files changed, 71 insertions(+), 17 deletions(-) + create mode 100644 tests/05r6tor0.broken + create mode 100644 tests/07revert-inplace.broken + delete mode 100644 tests/10ddf-create.broken + delete mode 100644 tests/10ddf-fail-two-spares.broken + create mode 100644 tests/20raid5journal.broken + create mode 100644 tests/skiptests + +diff --git a/.github/tools/run_mdadm_tests.sh b/.github/tools/run_mdadm_tests.sh +index 456874b5..22d89a8c 100755 +--- a/.github/tools/run_mdadm_tests.sh ++++ b/.github/tools/run_mdadm_tests.sh +@@ -11,7 +11,7 @@ sudo ./test setup + + #sudo ./test --tests=00createnames + +-sudo ./test --skip-broken --no-error --disable-integrity --disable-multipath --disable-linear --keep-going ++sudo ./test --skip-broken --no-error --disable-integrity --disable-multipath --disable-linear --keep-going --skip-bigcase + + ret=$? + sudo ./test cleanup +diff --git a/test b/test +index 88e44f18..7fa68177 100755 +--- a/test ++++ b/test +@@ -26,6 +26,10 @@ savelogs=0 + exitonerror=1 + ctrl_c_error=0 + skipbroken=0 ++skipbigcase=0 ++skipfile="skiptests" ++skipcheckfile=$testdir/$skipfile ++checkscript="" + loop=1 + prefix='[0-9][0-9]' + +@@ -192,6 +196,7 @@ do_help() { + --loop=N Run tests N times (0 to run forever) + --skip-broken Skip tests that are known to be broken + --skip-always-broken Skip tests that are known to always fail ++ --skip-bigcase Skip tests that need time than 200 seconds + --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk + --disks= Provide a bunch of physical devices for test + --volgroup=name LVM volume group for LVM test +@@ -295,6 +300,9 @@ parse_args() { + --skip-always-broken ) + skipbroken=always + ;; ++ --skip-bigcase ) ++ skipbigcase=all ++ ;; + --disable-multipath ) + unset MULTIPATH + ;; +@@ -369,9 +377,17 @@ main() { + else + for script in $testdir/$prefix $testdir/$prefix*[^~] + do +- case $script in *.broken) ;; +- *) +- do_test $script ++ checkscript="${script##*/}" ++ case $script in ++ *.broken) ++ ;; ++ *) ++ if grep -q "$checkscript" "$skipcheckfile"; then ++ if [ "$skipbigcase" == "all" ]; then ++ continue ++ fi ++ fi ++ do_test $script + esac + done + fi +diff --git a/tests/05r6tor0.broken b/tests/05r6tor0.broken +new file mode 100644 +index 00000000..930a0941 +--- /dev/null ++++ b/tests/05r6tor0.broken +@@ -0,0 +1,15 @@ ++Sometimes ++ +++++ pgrep -f 'mdadm --grow --continue' ++++ [[ '' != '' ]] ++++ break ++++ echo 100 ++++ echo 500 ++++ sleep 2 ++++ check raid5 ++++ case $1 in ++++ grep -sq 'active raid5 ' /proc/mdstat ++++ die 'active raid5 not found' ++++ echo -e '\n\tERROR: active raid5 not found \n' ++ ++ ERROR: active raid5 not found +diff --git a/tests/07revert-inplace.broken b/tests/07revert-inplace.broken +new file mode 100644 +index 00000000..73d98a04 +--- /dev/null ++++ b/tests/07revert-inplace.broken +@@ -0,0 +1,8 @@ ++always fails ++ ++Fails with errors: ++ ++ /usr/sbin/mdadm -A /dev/md0 --update=revert-reshape /dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3 /dev/loop4 --backup-file=/tmp/md-backup ++++ rv=1 ++++ case $* in ++++ cat /var/tmp/stderr ++mdadm: failed to RUN_ARRAY /dev/md0: Invalid argument +diff --git a/tests/10ddf-create.broken b/tests/10ddf-create.broken +deleted file mode 100644 +index 0f7d25e5..00000000 +--- a/tests/10ddf-create.broken ++++ /dev/null +@@ -1,5 +0,0 @@ +-Fails due to segmentation fault at assemble. +- +-Too much effort to diagnose this now, marking as broken to make CI clear. +- ++ /usr/sbin/mdadm -A /dev/md/ddf0 /dev/loop8 /dev/loop9 /dev/loop10 /dev/loop11 /dev/loop12 +- ./test: line 76: 101955 Segmentation fault (core dumped) $mdadm "$@" 2> $targetdir/stderr +diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken +deleted file mode 100644 +index eeea56d9..00000000 +--- a/tests/10ddf-fail-two-spares.broken ++++ /dev/null +@@ -1,5 +0,0 @@ +-fails infrequently +- +-Fails roughly 1 in 3 with error: +- +- ERROR: /dev/md/vol1 should be optimal in meta data +diff --git a/tests/20raid5journal.broken b/tests/20raid5journal.broken +new file mode 100644 +index 00000000..c7b214af +--- /dev/null ++++ b/tests/20raid5journal.broken +@@ -0,0 +1,17 @@ ++always fail ++ ++++ /usr/sbin/mdadm -I /dev/loop4 ++++ rv=0 ++++ case $* in ++++ cat /var/tmp/stderr ++mdadm: /dev/loop4 attached to /dev/md/0_0, which has been started. ++++ return 0 ++++ check raid5 ++++ case $1 in ++++ grep -sq 'active raid5 ' /proc/mdstat ++++ die 'active raid5 not found' ++++ echo -e '\n\tERROR: active raid5 not found \n' ++ ++ ERROR: active raid5 not found ++ ++++ save_log fail +diff --git a/tests/env-ddf-template b/tests/env-ddf-template +index 4f4ad0f3..ebc0ebf3 100644 +--- a/tests/env-ddf-template ++++ b/tests/env-ddf-template +@@ -3,8 +3,7 @@ sha1_sum() { + } + + get_rootdev() { +- local part=$(grep ' / ' /proc/mounts | awk '{print $1}') +- local bd=/dev/$(lsblk -no PKNAME $part) ++ local bd=$(grep ' / ' /proc/mounts | awk '{print $1}') + [ -b $bd ] || exit 1 + echo $bd + } +diff --git a/tests/skiptests b/tests/skiptests +new file mode 100644 +index 00000000..fd0893f1 +--- /dev/null ++++ b/tests/skiptests +@@ -0,0 +1,9 @@ ++casename:seconds ++01raid6integ:1732 ++01replace:396 ++07layouts:836 ++11spare-migration:1140 ++12imsm-r0_2d-grow-r0_5d:218 ++13imsm-r0_r0_2d-grow-r0_r0_4d:218 ++13imsm-r0_r0_2d-grow-r0_r0_5d:246 ++19raid6check:268 +diff --git a/util.c b/util.c +index 8c45f0e1..9fe2d227 100644 +--- a/util.c ++++ b/util.c +@@ -2310,7 +2310,7 @@ mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefi + dprintf("Start %s service\n", service_name); + /* Simply return that service cannot be started */ + if (check_env("MDADM_NO_SYSTEMCTL")) +- return MDADM_STATUS_SUCCESS; ++ return MDADM_STATUS_ERROR; + + /* Fork in attempt to start services */ + switch (fork()) { +-- +2.41.0 + diff --git a/0026-super1-Clear-extra-flags-when-initializing-metadata.patch b/0026-super1-Clear-extra-flags-when-initializing-metadata.patch new file mode 100644 index 0000000..07408dc --- /dev/null +++ b/0026-super1-Clear-extra-flags-when-initializing-metadata.patch @@ -0,0 +1,72 @@ +From 4e2e208c8d3e9ba0fae88136d7c4cd0292af73b0 Mon Sep 17 00:00:00 2001 +From: Wu Guanghao +Date: Tue, 11 Mar 2025 03:11:55 +0000 +Subject: [PATCH 26/37] super1: Clear extra flags when initializing metadata + +When adding a disk to a RAID1 array, the metadata is read from the +existing member disks for sync. However, only the bad_blocks flag are +copied, the bad_blocks records are not copied, so the bad_blocks +records are all zeros. The kernel function super_1_load() detects +bad_blocks flag and reads the bad_blocks record, then sets the bad +block using badblocks_set(). + +After the kernel commit 1726c7746783 (badblocks: improve badblocks_set() +for multiple ranges handling) if the length of a bad_blocks record is 0, +it will return a failure. Therefore the device addition will fail. + +So when adding a new disk, some flags cannot be sync and need to be clead. + +Signed-off-by: Wu Guanghao +--- + super1.c | 3 +++ + tests/05r1-add-badblocks | 24 ++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + create mode 100644 tests/05r1-add-badblocks + +diff --git a/super1.c b/super1.c +index fe3c4c64..c828b682 100644 +--- a/super1.c ++++ b/super1.c +@@ -1971,6 +1971,9 @@ static int write_init_super1(struct supertype *st) + long bm_offset; + bool raid0_need_layout = false; + ++ /* Clear extra flags */ ++ sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT); ++ + /* Since linux kernel v5.4, raid0 always has a layout */ + if (has_raid0_layout(sb) && get_linux_version() >= 5004000) + raid0_need_layout = true; +diff --git a/tests/05r1-add-badblocks b/tests/05r1-add-badblocks +new file mode 100644 +index 00000000..6192327a +--- /dev/null ++++ b/tests/05r1-add-badblocks +@@ -0,0 +1,24 @@ ++# ++# create a raid1 with a drive and set badblocks for the drive. ++# add a new drive does not cause an error. ++# ++ ++# create raid1 ++mdadm -CR $md0 -l1 -n2 -e1.0 $dev1 missing ++testdev $md0 1 $mdsize1a 64 ++sleep 3 ++ ++# set badblocks for the drive ++dev1_name=$(basename $dev1) ++echo "100 100" > /sys/block/md0/md/dev-$dev1_name/bad_blocks ++echo "write_error" > /sys/block/md0/md/dev-$dev1_name/state ++ ++# write badblocks to metadata ++dd if=/dev/zero of=$md0 bs=512 count=200 oflag=direct ++ ++# re-add and recovery ++mdadm $md0 -a $dev2 ++check recovery ++ ++mdadm -S $md0 ++ +-- +2.41.0 + diff --git a/0027-imsm-Fix-RAID0-to-RAID10-migration.patch b/0027-imsm-Fix-RAID0-to-RAID10-migration.patch new file mode 100644 index 0000000..26b5d6b --- /dev/null +++ b/0027-imsm-Fix-RAID0-to-RAID10-migration.patch @@ -0,0 +1,74 @@ +From 127e38b59cbdf717d1569bcdc75b8d823d8485f3 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 31 Mar 2025 12:46:52 +0200 +Subject: [PATCH 27/37] imsm: Fix RAID0 to RAID10 migration + +Support for RAID10 with +4 disks in IMSM introduced an inconsistency +between the VROC UEFI driver and Linux IMSM. VROC UEFI does not +support RAID10 with +4 disks, therefore appropriate protections were +added to the mdadm IMSM code that results in skipping processing of +such RAID in the UEFI phase. Unfortunately the case of migration +RAID0 2 disks to RAID10 4 disks was omitted, this case requires +maintaining compatibility with the VROC UEFI driver because it is +supported. + +For RAID10 +4 disk the MPB_ATTRIB_RAID10_EXT attribute is set in the +metadata, thanks to which the UEFI driver does not process such RAID. +In the series adding support, a new metadata raid level value +IMSM_T_RAID10 was also introduced. It is not recognized by VROC UEFI. + +The issue is caused by the fact that in the case of the mentioned +migration, IMSM_T_RAID10 is entered into the metadata but attribute +MPB_ATTRIB_RAID10_EXT is not entered, which causes an attempt to +process such RAID in the UEFI phase. This situation results in +the platform hang during booting in UEFI phase, this also results in +data loss after failed and interrupted RAID processing in VROC UEFI. + +The above situation is result of the update_imsm_raid_level() +function, for the mentioned migration function is executed on a map +with a not yet updated number of disks. + +The fix is to explicitly handle migration in the function mentioned +above to maintain compatibility with VROC UEFI driver. + +Steps to reproduce: +mdadm -C /dev/md/imsm0 -e imsm -n 2 /dev/nvme[1,2]n1 -R +mdadm -C /dev/md/vol -l 0 -n 2 /dev/nvme[1,2]n1 --assume-clean -R +mdadm -a /dev/md127 /dev/nvme3n1 +mdadm -a /dev/md127 /dev/nvme4n1 +mdadm -G /dev/md126 -l 10 +reboot + +Fixes: 27550b13297a ("imsm: add support for literal RAID 10") +Signed-off-by: Blazej Kucman +--- + super-intel.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index 4988eef1..b7b030a2 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1327,6 +1327,19 @@ static void update_imsm_raid_level(struct imsm_map *map, int new_level) + return; + } + ++ /* ++ * RAID0 to RAID10 migration. ++ * Due to the compatibility with VROC UEFI must be maintained, this case must be handled ++ * separately, because the map does not have an updated number of disks. ++ */ ++ if (map->raid_level == IMSM_T_RAID0) { ++ if (map->num_members == 2) ++ map->raid_level = IMSM_T_RAID1; ++ else ++ map->raid_level = IMSM_T_RAID10; ++ return; ++ } ++ + if (map->num_members == 4) { + if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1) + return; +-- +2.41.0 + diff --git a/0028-Allow-RAID0-to-be-created-with-v0.90-metadata-161.patch b/0028-Allow-RAID0-to-be-created-with-v0.90-metadata-161.patch new file mode 100644 index 0000000..65489a5 --- /dev/null +++ b/0028-Allow-RAID0-to-be-created-with-v0.90-metadata-161.patch @@ -0,0 +1,193 @@ +From 6ce7f21bb822fd0125f78434d9fbf6c3db524892 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 4 Apr 2025 11:56:04 +1100 +Subject: [PATCH 28/37] Allow RAID0 to be created with v0.90 metadata #161 + +It is not currently possible to create a RAID0 with 0.90 metadata. +This is because 0.90 cannot specify the layout of RAID0 (it is +traditionally ignored) and different kernels do different things with +RAID0 layouts. + +However it should be possible to use --layout=dangerous as that +acknowledges the risk. +It also should be possible to create a RAID0 with all devices the same +size because in that case all layouts are identical. + +The metadata handler can only check that all devices are the same size +quite late - in write_init_super(). By that time the default is +currently set - set to a value that super0 cannot handle. + +So this patch delays the setting of the default value and leave it for +the metadata handler (or for the Build handler). + +super1 selects ORIG in that case. +intel and ddf don't support non-uniform RAID0 so they don't need any +change. +super0 now checks the sizes of devices if the default RAID0 layout was +requested and rejects the request in they are not the same. + +validiate_geometry0 now allows "dangerous" layouts for raid0. + +Signed-off-by: NeilBrown +--- + Build.c | 4 ++++ + Create.c | 2 +- + maps.c | 2 +- + mdadm.h | 1 + + super0.c | 34 +++++++++++++++++++++++++++++++++- + super1.c | 4 ++++ + tests/00raid0 | 4 ++-- + 7 files changed, 46 insertions(+), 5 deletions(-) + +diff --git a/Build.c b/Build.c +index 70aab7a0..9eb85a13 100644 +--- a/Build.c ++++ b/Build.c +@@ -103,6 +103,10 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, + s->chunk = 64; + array.chunk_size = s->chunk*1024; + array.layout = s->layout; ++ ++ if (array.level == 0 && array.layout == UnSet) ++ /* Raid0 leaves default to metadata handler. That is us. */ ++ array.layout = RAID0_ORIG_LAYOUT; + if (md_set_array_info(mdfd, &array)) { + pr_err("md_set_array_info() failed for %s: %s\n", chosen_name, strerror(errno)); + goto abort; +diff --git a/Create.c b/Create.c +index fd6c9215..2b181dbf 100644 +--- a/Create.c ++++ b/Create.c +@@ -77,7 +77,7 @@ int default_layout(struct supertype *st, int level, int verbose) + layout = 0; + break; + case 0: +- layout = RAID0_ORIG_LAYOUT; ++ /* Leave unset - metadata handlers choose default */ + break; + case 10: + layout = 0x102; /* near=2, far=1 */ +diff --git a/maps.c b/maps.c +index 17f8b54d..2181b4ac 100644 +--- a/maps.c ++++ b/maps.c +@@ -81,7 +81,7 @@ mapping_t r0layout[] = { + { "alternate", RAID0_ALT_MULTIZONE_LAYOUT}, + { "1", 1}, /* aka ORIG */ + { "2", 2}, /* aka ALT */ +- { "dangerous", 0}, ++ { "dangerous", RAID0_DANGEROUS_LAYOUT}, + { NULL, UnSet}, + }; + +diff --git a/mdadm.h b/mdadm.h +index e84c341c..0ea83ad3 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -2003,6 +2003,7 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { + #endif + + enum r0layout { ++ RAID0_DANGEROUS_LAYOUT = 0, /* layout depends on kernel version */ + RAID0_ORIG_LAYOUT = 1, + RAID0_ALT_MULTIZONE_LAYOUT = 2, + }; +diff --git a/super0.c b/super0.c +index ff4905b9..4a462bdc 100644 +--- a/super0.c ++++ b/super0.c +@@ -837,6 +837,7 @@ struct devinfo { + int fd; + char *devname; + mdu_disk_info_t disk; ++ unsigned long long dev_size; + struct devinfo *next; + }; + +@@ -866,6 +867,10 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo, + di->devname = devname; + di->disk = *dinfo; + di->next = NULL; ++ ++ if (is_fd_valid(fd)) ++ get_dev_size(fd, NULL, &di->dev_size); ++ + *dip = di; + + return 0; +@@ -929,6 +934,33 @@ static int write_init_super0(struct supertype *st) + int rv = 0; + struct devinfo *di; + ++ if (sb->level == 0 && sb->layout == UnSet) { ++ /* Without requesting a dangerous (0) layout ++ * we can only allow this RAID0 if all devices are ++ * the same size ++ */ ++ unsigned long long chunks = 0; ++ unsigned long chunk_sectors = sb->chunk_size >> 9; ++ ++ for (di = st->info; di; di = di->next) { ++ unsigned long long this_chunks; ++ ++ this_chunks = st->ss->avail_size(st, di->dev_size, 0) / chunk_sectors; ++ ++ if (chunks == 0) { ++ chunks = this_chunks; ++ continue; ++ } ++ ++ if (this_chunks != chunks) { ++ pr_err("Need explicit layout=dangerous to create 0.90 raid0 on non-uniform sized devices\n"); ++ return 1; ++ } ++ } ++ /* looks safe */ ++ sb->layout = 0; ++ } ++ + for (di = st->info ; di && ! rv ; di = di->next) { + + if (di->disk.state & (1 << MD_DISK_FAULTY)) +@@ -1321,7 +1353,7 @@ static int validate_geometry0(struct supertype *st, int level, + if (*chunk == UnSet) + *chunk = DEFAULT_CHUNK; + +- if (level == 0 && layout != UnSet) { ++ if (level == 0 && layout != UnSet && layout != RAID0_DANGEROUS_LAYOUT) { + if (verbose) + pr_err("0.90 metadata does not support layouts for RAID0\n"); + return 0; +diff --git a/super1.c b/super1.c +index c828b682..fb93f462 100644 +--- a/super1.c ++++ b/super1.c +@@ -1677,6 +1677,10 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, + sizeof(sb->set_name) - namelen); + } + ++ if (info->level == 0 && info->layout == UnSet) ++ /* Metadata chooses default layout for RAID0 */ ++ info->layout = RAID0_ORIG_LAYOUT; ++ + sb->ctime = __cpu_to_le64((unsigned long long)time(0)); + sb->level = __cpu_to_le32(info->level); + sb->layout = __cpu_to_le32(info->layout); +diff --git a/tests/00raid0 b/tests/00raid0 +index 6407c320..94abcd49 100644 +--- a/tests/00raid0 ++++ b/tests/00raid0 +@@ -6,8 +6,8 @@ check raid0 + testdev $md0 3 $mdsize2_l 512 + mdadm -S $md0 + +-# verify raid0 with layouts fail for 0.90 +-mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 ++# verify raid0 with explicit layouts fail for 0.90 ++mdadm -CR $md0 -e0.90 -l0 --layout=original -n4 $dev0 $dev1 $dev2 $dev3 + check opposite_result + + # now with no superblock +-- +2.41.0 + diff --git a/0029-Update-tests.yml.patch b/0029-Update-tests.yml.patch new file mode 100644 index 0000000..e905aba --- /dev/null +++ b/0029-Update-tests.yml.patch @@ -0,0 +1,45 @@ +From b532421e747d75223c6f7a065fb643d2d318011c Mon Sep 17 00:00:00 2001 +From: Paul Luse +Date: Thu, 24 Apr 2025 07:30:10 -0700 +Subject: [PATCH 29/37] Update tests.yml + +Signed-off-by: Paul Luse +--- + .github/workflows/tests.yml | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml +index ce940108..6f8e2b8e 100644 +--- a/.github/workflows/tests.yml ++++ b/.github/workflows/tests.yml +@@ -31,9 +31,15 @@ jobs: + - name: 'Prepare machine' + run: | + cd .. +- vagrant halt ++ vagrant snapshot restore clean_vm_v42 ++ echo "FYI vagrant restore command finished with exit code: $?" ++ sleep 2 + vagrant status + vagrant up ++ sleep 2 ++ vagrant ssh -c "sudo timedatectl set-timezone UTC && \ ++ sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1" ++ echo "FYI vagrant time command finished with exit code: $?" + + - name: 'Run tests' + id: testing +@@ -69,9 +75,7 @@ jobs: + runs-on: self-hosted + needs: [upstream_tests] + steps: +- - name: Restore clean VM ++ - name: Halt VM + run: | + cd .. +- vagrant up +- vagrant ssh -c "sudo mdadm -Ss" + vagrant halt +-- +2.41.0 + diff --git a/0030-Update-tests.yml.patch b/0030-Update-tests.yml.patch new file mode 100644 index 0000000..d545af7 --- /dev/null +++ b/0030-Update-tests.yml.patch @@ -0,0 +1,26 @@ +From 07bde560b71a2f6e36de5bc6f24e07e761c1c83b Mon Sep 17 00:00:00 2001 +From: Paul Luse +Date: Thu, 24 Apr 2025 08:38:29 -0700 +Subject: [PATCH 30/37] Update tests.yml + +Signed-off-by: Paul Luse +--- + .github/workflows/tests.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml +index 6f8e2b8e..b4c156c0 100644 +--- a/.github/workflows/tests.yml ++++ b/.github/workflows/tests.yml +@@ -65,7 +65,7 @@ jobs: + if: ${{ steps.testing.outcome == 'failure' }} + run: | + cd .. +- sudo rm /home/ci/actions-runner/_work/mdadm/logs/*.log ++ sudo rm -rf /home/ci/actions-runner/_work/mdadm/logs/*.log + + - name: "Set failed" + if: ${{ steps.testing.outcome == 'failure' }} +-- +2.41.0 + diff --git a/0031-Update-tests.yml.patch b/0031-Update-tests.yml.patch new file mode 100644 index 0000000..e455753 --- /dev/null +++ b/0031-Update-tests.yml.patch @@ -0,0 +1,26 @@ +From affe2168b807ccd48f00dc9e021196a5e2e83870 Mon Sep 17 00:00:00 2001 +From: Paul Luse +Date: Thu, 24 Apr 2025 08:41:15 -0700 +Subject: [PATCH 31/37] Update tests.yml + +Signed-off-by: Paul Luse +--- + .github/workflows/tests.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml +index b4c156c0..9b361571 100644 +--- a/.github/workflows/tests.yml ++++ b/.github/workflows/tests.yml +@@ -37,7 +37,7 @@ jobs: + vagrant status + vagrant up + sleep 2 +- vagrant ssh -c "sudo timedatectl set-timezone UTC && \ ++ vagrant ssh -c "uname -r && sudo timedatectl set-timezone UTC && \ + sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1" + echo "FYI vagrant time command finished with exit code: $?" + +-- +2.41.0 + diff --git a/0032-Update-tests.yml.patch b/0032-Update-tests.yml.patch new file mode 100644 index 0000000..fb0e546 --- /dev/null +++ b/0032-Update-tests.yml.patch @@ -0,0 +1,29 @@ +From 5fd2f5da6fe7995190627f8a7bd9f6ff90aad1d4 Mon Sep 17 00:00:00 2001 +From: Paul Luse +Date: Thu, 24 Apr 2025 09:03:32 -0700 +Subject: [PATCH 32/37] Update tests.yml + +Signed-off-by: Paul Luse +--- + .github/workflows/tests.yml | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml +index 9b361571..2556fccf 100644 +--- a/.github/workflows/tests.yml ++++ b/.github/workflows/tests.yml +@@ -37,9 +37,8 @@ jobs: + vagrant status + vagrant up + sleep 2 +- vagrant ssh -c "uname -r && sudo timedatectl set-timezone UTC && \ +- sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1" +- echo "FYI vagrant time command finished with exit code: $?" ++ vagrant ssh -c "uname -r" ++ echo "FYI vagrant uname command finished with exit code: $?" + + - name: 'Run tests' + id: testing +-- +2.41.0 + diff --git a/0033-This-is-a-test-for-CI-do-not-merge.patch b/0033-This-is-a-test-for-CI-do-not-merge.patch new file mode 100644 index 0000000..d6a10ce --- /dev/null +++ b/0033-This-is-a-test-for-CI-do-not-merge.patch @@ -0,0 +1,22 @@ +From 97ee409451a7191d3d2861b6718f79116f80b4ec Mon Sep 17 00:00:00 2001 +From: Paul E Luse +Date: Thu, 24 Apr 2025 18:22:54 +0200 +Subject: [PATCH 33/37] This is a test for CI, do not merge + +Signed-off-by: Paul E Luse +--- + README.md | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/README.md b/README.md +index 029e0ee2..426e3512 100644 +--- a/README.md ++++ b/README.md +@@ -1,3 +1,4 @@ ++test + **mdadm** is a utility used to create and manage **software RAID** devices implemented through + **Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats: + +-- +2.41.0 + diff --git a/0034-Update-README.md.patch b/0034-Update-README.md.patch new file mode 100644 index 0000000..36b8d8f --- /dev/null +++ b/0034-Update-README.md.patch @@ -0,0 +1,24 @@ +From f5ff81d14fdd34f770120a057804d6067fd5035b Mon Sep 17 00:00:00 2001 +From: Paul Luse +Date: Thu, 24 Apr 2025 09:48:56 -0700 +Subject: [PATCH 34/37] Update README.md + +Needed to remove the word "test" as part of testing updated CI workflow. + +Signed-off-by: Paul Luse +--- + README.md | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/README.md b/README.md +index 426e3512..029e0ee2 100644 +--- a/README.md ++++ b/README.md +@@ -1,4 +1,3 @@ +-test + **mdadm** is a utility used to create and manage **software RAID** devices implemented through + **Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats: + +-- +2.41.0 + diff --git a/0035-mdadm-Remove-klibc-and-uclibc-support.patch b/0035-mdadm-Remove-klibc-and-uclibc-support.patch new file mode 100644 index 0000000..7ebd8da --- /dev/null +++ b/0035-mdadm-Remove-klibc-and-uclibc-support.patch @@ -0,0 +1,183 @@ +From bd648e3bec3d883d2f4addea84ac1ac8790c75e9 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 7 Mar 2025 11:38:48 +0100 +Subject: [PATCH 35/37] mdadm: Remove klibc and uclibc support + +Klibc compilation is not working for at least 3 years because of +following error: +mdadm.h:1912:15: error: unknown type name 'sighandler_t' + +It will have a conflict with le/be_to_cpu() functions family provided by +asm/byteorder.h which will be included with raid/md_p.h. Therefore we +need to remove support for it. Also, remove uclibc because it is not actively +maintained. + +Remove klibc and uclibc targets from Makefile and special klibc code. +Targets can be removed safely because using CC is recommended. + +Signed-off-by: Mariusz Tkaczyk +--- + Makefile | 34 +++------------------------------- + README.md | 3 --- + mdadm.h | 37 +------------------------------------ + 3 files changed, 4 insertions(+), 70 deletions(-) + +diff --git a/Makefile b/Makefile +index bcd092de..387e4a56 100644 +--- a/Makefile ++++ b/Makefile +@@ -31,16 +31,6 @@ + # define "CXFLAGS" to give extra flags to CC. + # e.g. make CXFLAGS=-O to optimise + CXFLAGS ?=-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE +-TCC = tcc +-UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found ) +-#DIET_GCC = diet gcc +-# sorry, but diet-libc doesn't know about posix_memalign, +-# so we cannot use it any more. +-DIET_GCC = gcc -DHAVE_STDINT_H +- +-KLIBC=/home/src/klibc/klibc-0.77 +- +-KLIBC_GCC = gcc -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIBC)/linux/include -I$(KLIBC)/klibc/arch/i386/include -I$(KLIBC)/klibc/include/bits32 + + ifdef COVERITY + COVERITY_FLAGS=-include coverity-gcc-hack.h +@@ -225,8 +215,6 @@ everything: all swap_super test_stripe raid6check \ + mdadm.Os mdadm.O2 man + 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.. + + %.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(COVERITY_FLAGS) -o $@ -c $< +@@ -237,13 +225,6 @@ mdadm : $(OBJS) | check_rundir + mdadm.static : $(OBJS) $(STATICOBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -static -o mdadm.static $(OBJS) $(STATICOBJS) $(LDLIBS) + +-mdadm.tcc : $(SRCS) $(INCL) +- $(TCC) -o mdadm.tcc $(SRCS) +- +-mdadm.klibc : $(SRCS) $(INCL) +- rm -f $(OBJS) +- $(CC) -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIBC)/linux/include -I$(KLIBC)/klibc/arch/i386/include -I$(KLIBC)/klibc/include/bits32 $(CFLAGS) $(SRCS) +- + mdadm.Os : $(SRCS) $(INCL) + $(CC) -o mdadm.Os $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) $(LDLIBS) + +@@ -298,15 +279,6 @@ install : install-bin install-man install-udev + install-static : mdadm.static install-man + $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm + +-install-tcc : mdadm.tcc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm +- +-install-uclibc : mdadm.uclibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm +- +-install-klibc : mdadm.klibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm +- + install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 + $(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8 + $(INSTALL) -D -m 644 mdmon.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 +@@ -354,9 +326,9 @@ test: mdadm mdmon test_stripe swap_super raid6check + + clean : + rm -f mdadm mdmon $(OBJS) $(MON_OBJS) $(STATICOBJS) core *.man \ +- mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej *.alt \ +- .merge_file_* mdadm.Os mdadm.O2 mdmon.O2 swap_super init.cpio.gz \ +- mdadm.uclibc.static test_stripe raid6check raid6check.o mdmon mdadm.8 ++ mdadm.static *.orig *.porig *.rej *.alt merge_file_* \ ++ mdadm.Os mdadm.O2 mdmon.O2 swap_super init.cpio.gz \ ++ test_stripe raid6check raid6check.o mdmon mdadm.8 + rm -rf cov-int + + dist : clean +diff --git a/README.md b/README.md +index 029e0ee2..ba611ec5 100644 +--- a/README.md ++++ b/README.md +@@ -135,9 +135,6 @@ List of installation targets: + + The following targets are deprecated and should not be used: + - `install-static` +-- `install-tcc` +-- `install-uclibc` +-- `install-klibc` + + # License + +diff --git a/mdadm.h b/mdadm.h +index 0ea83ad3..592bd1ba 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -43,6 +43,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); + #include + #include + #include ++#include + #include + #include + #include +@@ -189,7 +190,6 @@ struct dlm_lksb { + ((x) & 0x00000000ff000000ULL) << 8 | \ + ((x) & 0x000000ff00000000ULL) >> 8) + +-#if !defined(__KLIBC__) + #if BYTE_ORDER == LITTLE_ENDIAN + #define __cpu_to_le16(_x) (unsigned int)(_x) + #define __cpu_to_le32(_x) (unsigned int)(_x) +@@ -221,7 +221,6 @@ struct dlm_lksb { + #else + # error "unknown endianness." + #endif +-#endif /* __KLIBC__ */ + + /* + * Partially stolen from include/linux/unaligned/packed_struct.h +@@ -1530,40 +1529,6 @@ extern void sysfsline(char *line); + struct stat64; + #endif + +-#define HAVE_NFTW we assume +-#define HAVE_FTW +- +-#ifdef __UCLIBC__ +-# include +-# ifndef __UCLIBC_HAS_LFS__ +-# define lseek64 lseek +-# endif +-# ifndef __UCLIBC_HAS_FTW__ +-# undef HAVE_FTW +-# undef HAVE_NFTW +-# endif +-#endif +- +-#ifdef __dietlibc__ +-# undef HAVE_NFTW +-#endif +- +-#if defined(__KLIBC__) +-# undef HAVE_NFTW +-# undef HAVE_FTW +-#endif +- +-#ifndef HAVE_NFTW +-# define FTW_PHYS 1 +-# ifndef HAVE_FTW +- struct FTW {}; +-# endif +-#endif +- +-#ifdef HAVE_FTW +-# include +-#endif +- + extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s); + + extern int Manage_ro(char *devname, int fd, int readonly); +-- +2.41.0 + diff --git a/0036-mdadm-include-asm-byteorder.h.patch b/0036-mdadm-include-asm-byteorder.h.patch new file mode 100644 index 0000000..9f9c3cd --- /dev/null +++ b/0036-mdadm-include-asm-byteorder.h.patch @@ -0,0 +1,96 @@ +From 696207860f408534651db89c5b40133f5903fa25 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 7 Mar 2025 12:10:58 +0100 +Subject: [PATCH 36/37] mdadm: include asm/byteorder.h + +It will be included by raid/md_p.h anyway. Include it directly and +remove custom functions. It is not a problem now. + +Signed-off-by: Mariusz Tkaczyk +--- + mdadm.h | 55 +------------------------------------------------------ + 1 file changed, 1 insertion(+), 54 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 592bd1ba..7471cedc 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -34,6 +34,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); + #endif + + #include ++#include + #include + #include + #include +@@ -85,7 +86,6 @@ struct dlm_lksb { + #endif + + #include +-/*#include */ + #include + #include + #include +@@ -169,59 +169,6 @@ struct dlm_lksb { + #include "msg.h" + #include "mdadm_status.h" + +-#include +-/* Redhat don't like to #include , and +- * some time include isn't enough, +- * and there is no standard conversion function so... */ +-/* And dietlibc doesn't think byteswap is ok, so.. */ +-/* #include */ +-#define __mdadm_bswap_16(x) (((x) & 0x00ffU) << 8 | \ +- ((x) & 0xff00U) >> 8) +-#define __mdadm_bswap_32(x) (((x) & 0x000000ffU) << 24 | \ +- ((x) & 0xff000000U) >> 24 | \ +- ((x) & 0x0000ff00U) << 8 | \ +- ((x) & 0x00ff0000U) >> 8) +-#define __mdadm_bswap_64(x) (((x) & 0x00000000000000ffULL) << 56 | \ +- ((x) & 0xff00000000000000ULL) >> 56 | \ +- ((x) & 0x000000000000ff00ULL) << 40 | \ +- ((x) & 0x00ff000000000000ULL) >> 40 | \ +- ((x) & 0x0000000000ff0000ULL) << 24 | \ +- ((x) & 0x0000ff0000000000ULL) >> 24 | \ +- ((x) & 0x00000000ff000000ULL) << 8 | \ +- ((x) & 0x000000ff00000000ULL) >> 8) +- +-#if BYTE_ORDER == LITTLE_ENDIAN +-#define __cpu_to_le16(_x) (unsigned int)(_x) +-#define __cpu_to_le32(_x) (unsigned int)(_x) +-#define __cpu_to_le64(_x) (unsigned long long)(_x) +-#define __le16_to_cpu(_x) (unsigned int)(_x) +-#define __le32_to_cpu(_x) (unsigned int)(_x) +-#define __le64_to_cpu(_x) (unsigned long long)(_x) +- +-#define __cpu_to_be16(_x) __mdadm_bswap_16(_x) +-#define __cpu_to_be32(_x) __mdadm_bswap_32(_x) +-#define __cpu_to_be64(_x) __mdadm_bswap_64(_x) +-#define __be16_to_cpu(_x) __mdadm_bswap_16(_x) +-#define __be32_to_cpu(_x) __mdadm_bswap_32(_x) +-#define __be64_to_cpu(_x) __mdadm_bswap_64(_x) +-#elif BYTE_ORDER == BIG_ENDIAN +-#define __cpu_to_le16(_x) __mdadm_bswap_16(_x) +-#define __cpu_to_le32(_x) __mdadm_bswap_32(_x) +-#define __cpu_to_le64(_x) __mdadm_bswap_64(_x) +-#define __le16_to_cpu(_x) __mdadm_bswap_16(_x) +-#define __le32_to_cpu(_x) __mdadm_bswap_32(_x) +-#define __le64_to_cpu(_x) __mdadm_bswap_64(_x) +- +-#define __cpu_to_be16(_x) (unsigned int)(_x) +-#define __cpu_to_be32(_x) (unsigned int)(_x) +-#define __cpu_to_be64(_x) (unsigned long long)(_x) +-#define __be16_to_cpu(_x) (unsigned int)(_x) +-#define __be32_to_cpu(_x) (unsigned int)(_x) +-#define __be64_to_cpu(_x) (unsigned long long)(_x) +-#else +-# error "unknown endianness." +-#endif +- + /* + * Partially stolen from include/linux/unaligned/packed_struct.h + */ +-- +2.41.0 + diff --git a/0037-mdadm-use-kernel-raid-headers.patch b/0037-mdadm-use-kernel-raid-headers.patch new file mode 100644 index 0000000..82dd150 --- /dev/null +++ b/0037-mdadm-use-kernel-raid-headers.patch @@ -0,0 +1,346 @@ +From f5889f9a1b8753a1472dfef9d025da2bae395239 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 10 Mar 2025 11:16:28 +0100 +Subject: [PATCH 37/37] mdadm: use kernel raid headers + +For a years we redefined these headers in mdadm. We should reuse headers +exported by kernel to integrate driver and mdadm better. +Include them and remove mdadm owned headers. + +There are 3 defines not available in kernel headers, so define them +directly but put them in ifndef guard to make them transparent later. + +Use MD_FEATURE_CLUSTERED instead of MD_FEATURE_BITMAP_VERSIONED. The +value is same, kernel define has different name. + +Signed-off-by: Mariusz Tkaczyk +--- + Create.c | 2 - + Detail.c | 2 - + Examine.c | 2 - + Grow.c | 6 --- + Kill.c | 2 - + Manage.c | 2 - + Query.c | 2 - + mdadm.h | 16 ++++++- + mdmonitor.c | 2 - + super1.c | 126 ++-------------------------------------------------- + udev.c | 2 - + 11 files changed, 17 insertions(+), 147 deletions(-) + +diff --git a/Create.c b/Create.c +index 2b181dbf..de90b0b8 100644 +--- a/Create.c ++++ b/Create.c +@@ -23,8 +23,6 @@ + */ + + #include "mdadm.h" +-#include "md_u.h" +-#include "md_p.h" + #include "udev.h" + #include "xmalloc.h" + +diff --git a/Detail.c b/Detail.c +index b804a624..3802ef8f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -23,8 +23,6 @@ + */ + + #include "mdadm.h" +-#include "md_p.h" +-#include "md_u.h" + #include "xmalloc.h" + + #include +diff --git a/Examine.c b/Examine.c +index 036b7a56..9c8564be 100644 +--- a/Examine.c ++++ b/Examine.c +@@ -24,8 +24,6 @@ + + #include "dlink.h" + #include "mdadm.h" +-#include "md_u.h" +-#include "md_p.h" + #include "xmalloc.h" + + #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) +diff --git a/Grow.c b/Grow.c +index 53b0b387..30eaa3c6 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -30,12 +30,6 @@ + #include + #include + +-#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) +-#error no endian defined +-#endif +-#include "md_u.h" +-#include "md_p.h" +- + int restore_backup(struct supertype *st, + struct mdinfo *content, + int working_disks, +diff --git a/Kill.c b/Kill.c +index 43c9abed..9f05a1ac 100644 +--- a/Kill.c ++++ b/Kill.c +@@ -26,8 +26,6 @@ + */ + + #include "mdadm.h" +-#include "md_u.h" +-#include "md_p.h" + + int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) + { +diff --git a/Manage.c b/Manage.c +index 034eb00c..22b1f52b 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -23,8 +23,6 @@ + */ + + #include "mdadm.h" +-#include "md_u.h" +-#include "md_p.h" + #include "udev.h" + #include "xmalloc.h" + +diff --git a/Query.c b/Query.c +index aedb4ce7..72f49a4e 100644 +--- a/Query.c ++++ b/Query.c +@@ -23,8 +23,6 @@ + */ + + #include "mdadm.h" +-#include "md_p.h" +-#include "md_u.h" + + int Query(char *dev) + { +diff --git a/mdadm.h b/mdadm.h +index 7471cedc..ce9c216b 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -163,8 +163,20 @@ struct dlm_lksb { + #define GROW_SERVICE "mdadm-grow-continue" + #endif /* GROW_SERVICE */ + +-#include "md_u.h" +-#include "md_p.h" ++#include ++#include ++ ++/* These defines might be missing in raid headers*/ ++#ifndef MD_SB_BLOCK_CONTAINER_RESHAPE ++#define MD_SB_BLOCK_CONTAINER_RESHAPE 3 ++#endif ++#ifndef MD_SB_BLOCK_VOLUME ++#define MD_SB_BLOCK_VOLUME 4 ++#endif ++#ifndef MD_DISK_REPLACEMENT ++#define MD_DISK_REPLACEMENT 17 ++#endif ++ + #include "bitmap.h" + #include "msg.h" + #include "mdadm_status.h" +diff --git a/mdmonitor.c b/mdmonitor.c +index d1cfbf94..d51617cd 100644 +--- a/mdmonitor.c ++++ b/mdmonitor.c +@@ -23,8 +23,6 @@ + */ + + #include "mdadm.h" +-#include "md_p.h" +-#include "md_u.h" + #include "udev.h" + #include "xmalloc.h" + +diff --git a/super1.c b/super1.c +index fb93f462..84d73573 100644 +--- a/super1.c ++++ b/super1.c +@@ -26,92 +26,6 @@ + #include "mdadm.h" + #include "xmalloc.h" + +-/* +- * The version-1 superblock : +- * All numeric fields are little-endian. +- * +- * total size: 256 bytes plus 2 per device. +- * 1K allows 384 devices. +- */ +-struct mdp_superblock_1 { +- /* constant array information - 128 bytes */ +- __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ +- __u32 major_version; /* 1 */ +- __u32 feature_map; /* 0 for now */ +- __u32 pad0; /* always set to 0 when writing */ +- +- __u8 set_uuid[16]; /* user-space generated. */ +- char set_name[32]; /* set and interpreted by user-space */ +- +- __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ +- __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ +- __u32 layout; /* used for raid5, raid6, raid10, and raid0 */ +- __u64 size; /* used size of component devices, in 512byte sectors */ +- +- __u32 chunksize; /* in 512byte sectors */ +- __u32 raid_disks; +- union { +- __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts +- * NOTE: signed, so bitmap can be before superblock +- * only meaningful of feature_map[0] is set. +- */ +- +- /* only meaningful when feature_map[MD_FEATURE_PPL] is set */ +- struct { +- __s16 offset; /* sectors from start of superblock that ppl starts */ +- __u16 size; /* ppl size in sectors */ +- } ppl; +- }; +- +- /* These are only valid with feature bit '4' */ +- __u32 new_level; /* new level we are reshaping to */ +- __u64 reshape_position; /* next address in array-space for reshape */ +- __u32 delta_disks; /* change in number of raid_disks */ +- __u32 new_layout; /* new layout */ +- __u32 new_chunk; /* new chunk size (sectors) */ +- __u32 new_offset; /* signed number to add to data_offset in new +- * layout. 0 == no-change. This can be +- * different on each device in the array. +- */ +- +- /* constant this-device information - 64 bytes */ +- __u64 data_offset; /* sector start of data, often 0 */ +- __u64 data_size; /* sectors in this device that can be used for data */ +- __u64 super_offset; /* sector start of this superblock */ +- union { +- __u64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */ +- __u64 journal_tail;/* journal tail of journal device (from data_offset) */ +- }; +- __u32 dev_number; /* permanent identifier of this device - not role in raid */ +- __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */ +- __u8 device_uuid[16]; /* user-space setable, ignored by kernel */ +- __u8 devflags; /* per-device flags. Only one defined...*/ +-#define WriteMostly1 1 /* mask for writemostly flag in above */ +-#define FailFast1 2 /* Device should get FailFast requests */ +- /* bad block log. If there are any bad blocks the feature flag is set. +- * if offset and size are non-zero, that space is reserved and available. +- */ +- __u8 bblog_shift; /* shift from sectors to block size for badblock list */ +- __u16 bblog_size; /* number of sectors reserved for badblock list */ +- __u32 bblog_offset; /* sector offset from superblock to bblog, signed */ +- +- /* array state information - 64 bytes */ +- __u64 utime; /* 40 bits second, 24 bits microseconds */ +- __u64 events; /* incremented when superblock updated */ +- __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ +- __u32 sb_csum; /* checksum upto dev_roles[max_dev] */ +- __u32 max_dev; /* size of dev_roles[] array to consider */ +- __u8 pad3[64-32]; /* set to 0 when writing */ +- +- /* device state information. Indexed by dev_number. +- * 2 bytes per device +- * Note there are no per-device state flags. State information is rolled +- * into the 'roles' value. If a device is spare or faulty, then it doesn't +- * have a meaningful role. +- */ +- __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */ +-}; +- + #define MAX_SB_SIZE 4096 + /* bitmap super size is 256, but we round up to a sector for alignment */ + #define BM_SUPER_SIZE 512 +@@ -126,40 +40,6 @@ struct misc_dev_info { + #define MULTIPLE_PPL_AREA_SIZE_SUPER1 (1024 * 1024) /* Size of the whole + * mutliple PPL area + */ +-/* feature_map bits */ +-#define MD_FEATURE_BITMAP_OFFSET 1 +-#define MD_FEATURE_RECOVERY_OFFSET 2 /* recovery_offset is present and +- * must be honoured +- */ +-#define MD_FEATURE_RESHAPE_ACTIVE 4 +-#define MD_FEATURE_BAD_BLOCKS 8 /* badblock list is not empty */ +-#define MD_FEATURE_REPLACEMENT 16 /* This device is replacing an +- * active device with same 'role'. +- * 'recovery_offset' is also set. +- */ +-#define MD_FEATURE_RESHAPE_BACKWARDS 32 /* Reshape doesn't change number +- * of devices, but is going +- * backwards anyway. +- */ +-#define MD_FEATURE_NEW_OFFSET 64 /* new_offset must be honoured */ +-#define MD_FEATURE_BITMAP_VERSIONED 256 /* bitmap version number checked properly */ +-#define MD_FEATURE_JOURNAL 512 /* support write journal */ +-#define MD_FEATURE_PPL 1024 /* support PPL */ +-#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */ +-#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in RAID0 */ +-#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ +- |MD_FEATURE_RECOVERY_OFFSET \ +- |MD_FEATURE_RESHAPE_ACTIVE \ +- |MD_FEATURE_BAD_BLOCKS \ +- |MD_FEATURE_REPLACEMENT \ +- |MD_FEATURE_RESHAPE_BACKWARDS \ +- |MD_FEATURE_NEW_OFFSET \ +- |MD_FEATURE_BITMAP_VERSIONED \ +- |MD_FEATURE_JOURNAL \ +- |MD_FEATURE_PPL \ +- |MD_FEATURE_MULTIPLE_PPLS \ +- |MD_FEATURE_RAID0_LAYOUT \ +- ) + + static int role_from_sb(struct mdp_superblock_1 *sb) + { +@@ -319,7 +199,7 @@ static int awrite(struct align_fd *afd, void *buf, int len) + static inline unsigned int md_feature_any_ppl_on(__u32 feature_map) + { + return ((__cpu_to_le32(feature_map) & +- (MD_FEATURE_PPL | MD_FEATURE_MUTLIPLE_PPLS))); ++ (MD_FEATURE_PPL | MD_FEATURE_MULTIPLE_PPLS))); + } + + static inline unsigned int choose_ppl_space(int chunk) +@@ -1483,7 +1363,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + } + case UOPT_NO_PPL: + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | +- MD_FEATURE_MUTLIPLE_PPLS); ++ MD_FEATURE_MULTIPLE_PPLS); + break; + case UOPT_DEVICESIZE: + if (__le64_to_cpu(sb->super_offset) >= +@@ -2650,7 +2530,7 @@ add_internal_bitmap1(struct supertype *st, + bms->nodes = __cpu_to_le32(st->nodes); + if (st->nodes) + sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | +- MD_FEATURE_BITMAP_VERSIONED); ++ MD_FEATURE_CLUSTERED); + if (st->cluster_name) { + len = sizeof(bms->cluster_name); + strncpy((char *)bms->cluster_name, st->cluster_name, len); +diff --git a/udev.c b/udev.c +index 88a99781..961ca970 100644 +--- a/udev.c ++++ b/udev.c +@@ -20,8 +20,6 @@ + + #include "mdadm.h" + #include "udev.h" +-#include "md_p.h" +-#include "md_u.h" + #include "xmalloc.h" + + #include +-- +2.41.0 + diff --git a/SOURCES/0171-mdadm-enable-sync-file-for-udev-rules.patch b/0038-mdadm-enable-sync-file-for-udev-rules.patch similarity index 78% rename from SOURCES/0171-mdadm-enable-sync-file-for-udev-rules.patch rename to 0038-mdadm-enable-sync-file-for-udev-rules.patch index 93e0b91..59ff123 100644 --- a/SOURCES/0171-mdadm-enable-sync-file-for-udev-rules.patch +++ b/0038-mdadm-enable-sync-file-for-udev-rules.patch @@ -97,10 +97,11 @@ Signed-off-by: Nigel Croxon Incremental.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) -diff --git mdadm-4.2/Create.c mdadm-4.2-fix/Create.c ---- mdadm-4.2/Create.c 2025-06-05 06:17:32.656879914 -0400 -+++ mdadm-4.2-fix/Create.c 2025-06-05 07:40:05.583074551 -0400 -@@ -1321,8 +1321,8 @@ +diff --git a/Create.c b/Create.c +index de90b0b8e781..420b9136c2c2 100644 +--- a/Create.c ++++ b/Create.c +@@ -1316,8 +1316,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, } else { pr_err("not starting array - not enough devices.\n"); } @@ -108,29 +109,38 @@ diff --git mdadm-4.2/Create.c mdadm-4.2-fix/Create.c close(mdfd); + udev_unblock(); sysfs_uevent(&info, "change"); - return 0; + dev_policy_free(custom_pols); -diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c ---- mdadm-4.2/Incremental.c 2025-06-05 06:17:32.789874082 -0400 -+++ mdadm-4.2-fix/Incremental.c 2025-06-05 07:44:27.126170772 -0400 -@@ -29,6 +29,7 @@ - */ +diff --git a/Incremental.c b/Incremental.c +index 228d2bdd5de2..ba3810e6157f 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -30,6 +30,7 @@ #include "mdadm.h" + #include "xmalloc.h" +#include "udev.h" + #include #include - #include -@@ -296,7 +297,7 @@ +@@ -286,7 +287,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, /* Couldn't find an existing array, maybe make a new one */ - mdfd = create_mddev(match ? match->devname : NULL, -- name_to_use, c->autof, trustworthy, chosen_name, 0); -+ name_to_use, c->autof, trustworthy, chosen_name, 1); + mdfd = create_mddev(match ? match->devname : NULL, name_to_use, trustworthy, +- chosen_name, 0); ++ chosen_name, 1); if (mdfd < 0) goto out_unlock; -@@ -474,7 +475,6 @@ +@@ -447,7 +448,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + info.array.working_disks = 0; + for (d = sra->devs; d; d=d->next) + info.array.working_disks ++; +- + } + if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) + md_devname = chosen_name + DEV_MD_DIR_LEN; +@@ -464,7 +464,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c, if (is_container(info.array.level)) { char devnm[32]; /* Try to assemble within the container */ @@ -138,7 +148,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c if (!c->export && c->verbose >= 0) pr_err("container %s now has %d device%s\n", chosen_name, info.array.working_disks, -@@ -486,6 +486,8 @@ +@@ -476,6 +475,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, if (st->ss->load_container) rv = st->ss->load_container(st, mdfd, NULL); close(mdfd); @@ -147,7 +157,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c sysfs_free(sra); if (!rv) rv = Incremental_container(st, chosen_name, c, NULL); -@@ -494,6 +496,7 @@ +@@ -484,6 +485,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, * so that it can eg. try to rebuild degraded array */ if (st->ss->external) ping_monitor(devnm); @@ -155,7 +165,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c return rv; } -@@ -630,7 +633,11 @@ +@@ -606,7 +608,11 @@ out: close(mdfd); if (policy) dev_policy_free(policy); @@ -168,16 +178,16 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c return rv; out_unlock: map_unlock(&map); -@@ -1577,7 +1584,7 @@ - ra->name, - c->autof, - trustworthy, +@@ -1561,7 +1567,7 @@ static int Incremental_container(struct supertype *st, char *devname, + trustworthy = LOCAL; + + mdfd = create_mddev(match ? match->devname : NULL, ra->name, trustworthy, - chosen_name, 0); + chosen_name, 1); if (!is_fd_valid(mdfd)) { pr_err("create_mddev failed with chosen name %s: %s.\n", -@@ -1597,6 +1604,8 @@ +@@ -1581,6 +1587,8 @@ static int Incremental_container(struct supertype *st, char *devname, map_free(map); map = NULL; close_fd(&mdfd); @@ -186,7 +196,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c } if (c->export && result) { char sep = '='; -@@ -1623,6 +1632,8 @@ +@@ -1607,6 +1615,8 @@ static int Incremental_container(struct supertype *st, char *devname, release: map_free(map); sysfs_free(list); @@ -195,3 +205,6 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c return rv; } +-- +2.50.1 + diff --git a/1001-mdadm-fix-IMSM-Raid-assembly-after-disk-link-failure.patch b/1001-mdadm-fix-IMSM-Raid-assembly-after-disk-link-failure.patch new file mode 100644 index 0000000..10ac374 --- /dev/null +++ b/1001-mdadm-fix-IMSM-Raid-assembly-after-disk-link-failure.patch @@ -0,0 +1,101 @@ +From ac4b50f616004d236f9d8676693cffcebbe0f8af Mon Sep 17 00:00:00 2001 +From: Richard Li +Date: Fri, 1 Aug 2025 22:02:00 +0000 +Subject: [PATCH] mdadm: Fix IMSM Raid assembly after disk link failure and + reboot +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch addresses a scenario observed in production where disk links +go down. After a system reboot, depending on which disk becomes +available first, the IMSM RAID array may either fully assemble or +come up with missing disks. + +Below is an example of the production case simulating disk link failures +and subsequent system reboot. + +(note: "echo "1" | sudo tee /sys/class/scsi_device/x:x:x:x/device/delete" +is used here to fail/unplug/disconnect disks) + +Raid Configuration: IMSM Raid1 with two disks + +- When sda is unplugged first, then sdb, and after reboot sdb is +reconnected first followed by sda, the container (/dev/md127) and +subarrays (/dev/md125, /dev/md126) correctly assemble and become active. +- However, when sda is reconnected first, then sdb, the subarrays fail to +fully reconstruct — sda remains missing from the assembled subarrays. + +This patch addresses this issue in monitor.c. Specifically, when an IMSM +RAID is detected and the faulty disk found does not yet exist +under /sys/block/CONTAINER_NAME (we do this check so the behavior of +"mdadm --fail" is not impacted), the disk will be marked as a spare +instead, allowing it to be reused during array reconstruction. + +The patch improves resilience by ensuring consistent array reconstruction +regardless of disk detection order. This aligns system behavior with +expected RAID redundancy and reduces risk of unnecessary manual recovery +steps after reboots in degraded hardware environments. + +Orabug: 38317486 +Signed-off-by: Richard Li +--- + monitor.c | 35 +++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +diff --git a/monitor.c b/monitor.c +index a4f707cc..02e1f1bc 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -394,6 +394,24 @@ static void signal_manager(void) + * - request a sync_action + * + */ ++static int find_disk_in_container(struct supertype *container, struct mdinfo *mdi) ++{ ++ struct mdinfo *fdi, *di; ++ ++ fdi = sysfs_read(-1, container->container_devnm, GET_DEVS); ++ if (!fdi) ++ return 0; ++ ++ for (di = fdi->devs; di; di = di->next) { ++ if (di->disk.major == mdi->disk.major && ++ di->disk.minor == mdi->disk.minor) { ++ dprintf("%d:%d found in container in sysfs\n", ++ mdi->disk.major, mdi->disk.minor); ++ return 1; ++ } ++ } ++ return 0; ++} + + #define ARRAY_DIRTY 1 + #define ARRAY_BUSY 2 +@@ -546,8 +564,21 @@ static int read_and_act(struct active_array *a, fd_set *fds) + */ + for (mdi = a->info.devs ; mdi ; mdi = mdi->next) { + if (mdi->curr_state & DS_FAULTY) { +- a->container->ss->set_disk(a, mdi->disk.raid_disk, +- mdi->curr_state); ++ /* Mark faulty disk as spare to allow it to be reused during IMSM array ++ * reconstruction. This fixes the issue when disks links go down ++ * and up againfter a reboot, IMSM RAID array may come up ++ * with missing disks. ++ */ ++ if (strcmp(a->container->ss->name, "imsm") == 0 && ++ !find_disk_in_container(a->container, mdi) && ++ !(mdi->curr_state & DS_SPARE)) { ++ dprintf("Marking %d:%d as spare for reuse\n", ++ mdi->disk.major, mdi->disk.minor); ++ a->container->ss->set_disk(a, mdi->disk.raid_disk, DS_SPARE); ++ } else { ++ a->container->ss->set_disk(a, mdi->disk.raid_disk, mdi->curr_state); ++ } ++ + check_degraded = 1; + if (mdi->curr_state & DS_BLOCKED) + mdi->next_state |= DS_UNBLOCK; +-- +2.47.1 + diff --git a/SOURCES/0001-Unify-error-message.patch b/SOURCES/0001-Unify-error-message.patch deleted file mode 100644 index 14dc69c..0000000 --- a/SOURCES/0001-Unify-error-message.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Tue, 15 Mar 2022 09:30:30 +0100 -Subject: [PATCH 01/83] Unify error message. - -Provide the same error message for the same error that can occur in Grow.c and super-intel.c. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - super-intel.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9c6fc95e..9a947204 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1001,8 +1001,8 @@ int remove_disks_for_takeover(struct supertype *st, - rv = 1; - sysfs_free(arrays); - if (rv) { -- pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm); -- pr_err("For this operation it MUST be single array in container\n"); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", st->devnm); - return rv; - } - } -diff --git a/super-intel.c b/super-intel.c -index d5fad102..5ffa7636 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - struct imsm_super *mpb = super->anchor; - - if (mpb->num_raid_devs > 1) { -- pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n", -- geo->dev_name); -+ pr_err("Error. Cannot perform operation on %s- for this operation " -+ "it MUST be single array in container\n", geo->dev_name); - change = -1; - } - } --- -2.38.1 - diff --git a/SOURCES/0002-mdadm-Fix-double-free.patch b/SOURCES/0002-mdadm-Fix-double-free.patch deleted file mode 100644 index e6b7d37..0000000 --- a/SOURCES/0002-mdadm-Fix-double-free.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 25 Mar 2022 12:48:59 +0100 -Subject: [PATCH 02/83] mdadm: Fix double free - -If there was a size mismatch after creation it would get fixed on grow -in imsm_fix_size_mismatch(), but due to double free "double free or corruption (fasttop)" -error occurs and grow cannot proceed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5ffa7636..6ff336ee 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - st->update_tail = &st->updates; - } else { - imsm_sync_metadata(st); -+ free(update); - } -- -- free(update); - } - ret_val = 0; - exit: --- -2.38.1 - diff --git a/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch b/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch deleted file mode 100644 index e43cdaa..0000000 --- a/SOURCES/0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch +++ /dev/null @@ -1,83 +0,0 @@ -From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Wed, 23 Mar 2022 15:05:19 +0100 -Subject: [PATCH 03/83] Grow_reshape: Add r0 grow size error message and update - man - -Grow size on r0 is not supported for imsm and native metadata. -Add proper error message. -Update man for proper use of --size. -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 6 ++++++ - mdadm.8.in | 19 ++++++++++++------- - 2 files changed, 18 insertions(+), 7 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 9a947204..aa72490b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1998,6 +1998,12 @@ int Grow_reshape(char *devname, int fd, - goto release; - } - -+ if (array.level == 0) { -+ pr_err("Component size change is not supported for RAID0\n"); -+ rv = 1; -+ goto release; -+ } -+ - if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, - devname, APPLY_METADATA_CHANGES, - c->verbose > 0)) { -diff --git a/mdadm.8.in b/mdadm.8.in -index be902dba..e2a42425 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -459,7 +459,8 @@ number of spare devices. - - .TP - .BR \-z ", " \-\-size= --Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6. -+Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10 -+and for RAID 0 on external metadata. - This must be a multiple of the chunk size, and must leave about 128Kb - of space at the end of the drive for the RAID superblock. - If this is not specified -@@ -478,10 +479,19 @@ To guard against this it can be useful to set the initial size - slightly smaller than the smaller device with the aim that it will - still be larger than any replacement. - -+This option can be used with -+.B \-\-create -+for determining initial size of an array. For external metadata, -+it can be used on a volume, but not on a container itself. -+Setting initial size of -+.B RAID 0 -+array is only valid for external metadata. -+ - This value can be set with - .B \-\-grow --for RAID level 1/4/5/6 though -+for RAID level 1/4/5/6/10 though - DDF arrays may not be able to support this. -+RAID 0 array size cannot be changed. - If the array was created with a size smaller than the currently - active drives, the extra space can be accessed using - .BR \-\-grow . -@@ -501,11 +511,6 @@ problems the array can be made bigger again with no loss with another - .B "\-\-grow \-\-size=" - command. - --This value cannot be used when creating a --.B CONTAINER --such as with DDF and IMSM metadata, though it perfectly valid when --creating an array inside a container. -- - .TP - .BR \-Z ", " \-\-array\-size= - This is only meaningful with --- -2.38.1 - diff --git a/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch b/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch deleted file mode 100644 index a755c53..0000000 --- a/SOURCES/0004-udev-adapt-rules-to-systemd-v247.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 14 Jan 2022 16:44:33 +0100 -Subject: [PATCH 04/83] udev: adapt rules to systemd v247 - -New events have been added in kernel 4.14 ("bind" and "unbind"). -Systemd maintainer suggests to modify "add|change" branches. -This patches implements their suggestions. There is no issue yet because -new event types are not used in md. - -Please see systemd announcement for details[1]. - -[1] https://lists.freedesktop.org/archives/systemd-devel/2020-November/045646.html - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - udev-md-raid-arrays.rules | 2 +- - udev-md-raid-assembly.rules | 5 +++-- - udev-md-raid-safe-timeouts.rules | 2 +- - 3 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 13c9076e..2967ace1 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -3,7 +3,7 @@ - SUBSYSTEM!="block", GOTO="md_end" - - # handle md arrays --ACTION!="add|change", GOTO="md_end" -+ACTION=="remove", GOTO="md_end" - KERNEL!="md*", GOTO="md_end" - - # partitions have no md/{array_state,metadata_version}, but should not -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index d668cddd..39b4344b 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -30,8 +30,9 @@ LABEL="md_inc" - - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' --ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" -+ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" -+ - ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" - ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" - -diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules -index 12bdcaa8..2e185cee 100644 ---- a/udev-md-raid-safe-timeouts.rules -+++ b/udev-md-raid-safe-timeouts.rules -@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end" - - IMPORT{program}="/sbin/mdadm --examine --export $devnode" - --ACTION=="add|change", \ -+ACTION!="remove", \ - ENV{ID_FS_TYPE}=="linux_raid_member", \ - ENV{MD_LEVEL}=="raid[1-9]*", \ - TEST=="/sys/block/$parent/device/timeout", \ --- -2.38.1 - diff --git a/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch b/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch deleted file mode 100644 index dd04b8c..0000000 --- a/SOURCES/0005-Replace-error-prone-signal-with-sigaction.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Mon, 21 Feb 2022 13:05:20 +0100 -Subject: [PATCH 05/83] Replace error prone signal() with sigaction() - -Up to this date signal() was used which implementation could vary [1]. -Sigaction() call is preferred. This commit introduces replacement -from signal() to sigaction() by the use of signal_s() wrapper. -Also remove redundant signal.h header includes. - -[1] https://man7.org/linux/man-pages/man2/signal.2.html - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - Monitor.c | 5 +++-- - managemon.c | 1 - - mdadm.h | 22 ++++++++++++++++++++++ - mdmon.c | 1 - - monitor.c | 1 - - probe_roms.c | 6 +++--- - raid6check.c | 25 +++++++++++++++---------- - util.c | 1 - - 9 files changed, 45 insertions(+), 21 deletions(-) - -diff --git a/Grow.c b/Grow.c -index aa72490b..18c5719b 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -26,7 +26,6 @@ - #include - #include - #include --#include - #include - - #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN) -@@ -3566,7 +3565,8 @@ started: - fd = -1; - mlockall(MCL_FUTURE); - -- signal(SIGTERM, catch_term); -+ if (signal_s(SIGTERM, catch_term) == SIG_ERR) -+ goto release; - - if (st->ss->external) { - /* metadata handler takes it from here */ -diff --git a/Monitor.c b/Monitor.c -index 30c031a2..c0ab5412 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -26,7 +26,6 @@ - #include "md_p.h" - #include "md_u.h" - #include --#include - #include - #include - #ifndef NO_LIBUDEV -@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) - if (mp) { - FILE *mdstat; - char hname[256]; -+ - gethostname(hname, sizeof(hname)); -- signal(SIGPIPE, SIG_IGN); -+ signal_s(SIGPIPE, SIG_IGN); -+ - if (info->mailfrom) - fprintf(mp, "From: %s\n", info->mailfrom); - else -diff --git a/managemon.c b/managemon.c -index bb7334cf..0e9bdf00 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -106,7 +106,6 @@ - #include "mdmon.h" - #include - #include --#include - - static void close_aa(struct active_array *aa) - { -diff --git a/mdadm.h b/mdadm.h -index c7268a71..26e7e5cd 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - #include - #include - #include -+#include - /* Newer glibc requires sys/sysmacros.h directly for makedev() */ - #include - #ifdef __dietlibc__ -@@ -1729,6 +1730,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) - return &ent->metadata_version[10+strlen(container)+1]; - } - -+/** -+ * signal_s() - Wrapper for sigaction() with signal()-like interface. -+ * @sig: The signal to set the signal handler to. -+ * @handler: The signal handler. -+ * -+ * Return: previous handler or SIG_ERR on failure. -+ */ -+static inline sighandler_t signal_s(int sig, sighandler_t handler) -+{ -+ struct sigaction new_act; -+ struct sigaction old_act; -+ -+ new_act.sa_handler = handler; -+ new_act.sa_flags = 0; -+ -+ if (sigaction(sig, &new_act, &old_act) == 0) -+ return old_act.sa_handler; -+ -+ return SIG_ERR; -+} -+ - #ifdef DEBUG - #define dprintf(fmt, arg...) \ - fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) -diff --git a/mdmon.c b/mdmon.c -index c71e62c6..5570574b 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -56,7 +56,6 @@ - #include - #include - #include --#include - #include - #ifdef USE_PTHREADS - #include -diff --git a/monitor.c b/monitor.c -index e0d3be67..b877e595 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -22,7 +22,6 @@ - #include "mdmon.h" - #include - #include --#include - - static char *array_states[] = { - "clear", "inactive", "suspended", "readonly", "read-auto", -diff --git a/probe_roms.c b/probe_roms.c -index 7ea04c7a..94c80c2c 100644 ---- a/probe_roms.c -+++ b/probe_roms.c -@@ -22,7 +22,6 @@ - #include "probe_roms.h" - #include "mdadm.h" - #include --#include - #include - #include - #include -@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val) - - void probe_roms_exit(void) - { -- signal(SIGBUS, SIG_DFL); -+ signal_s(SIGBUS, SIG_DFL); -+ - if (rom_fd >= 0) { - close(rom_fd); - rom_fd = -1; -@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align) - if (roms_init()) - return -1; - -- if (signal(SIGBUS, sigbus) == SIG_ERR) -+ if (signal_s(SIGBUS, sigbus) == SIG_ERR) - rc = -1; - if (rc == 0) { - fd = open("/dev/mem", O_RDONLY); -diff --git a/raid6check.c b/raid6check.c -index a8e6005b..99477761 100644 ---- a/raid6check.c -+++ b/raid6check.c -@@ -24,7 +24,6 @@ - - #include "mdadm.h" - #include --#include - #include - - #define CHECK_PAGE_BITS (12) -@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size) - } - - int lock_stripe(struct mdinfo *info, unsigned long long start, -- int chunk_size, int data_disks, sighandler_t *sig) { -+ int chunk_size, int data_disks, sighandler_t *sig) -+{ - int rv; -+ -+ sig[0] = signal_s(SIGTERM, SIG_IGN); -+ sig[1] = signal_s(SIGINT, SIG_IGN); -+ sig[2] = signal_s(SIGQUIT, SIG_IGN); -+ -+ if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR) -+ return 1; -+ - if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - return 2; - } - -- sig[0] = signal(SIGTERM, SIG_IGN); -- sig[1] = signal(SIGINT, SIG_IGN); -- sig[2] = signal(SIGQUIT, SIG_IGN); -- - rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks); - rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks); - return rv * 256; - } - --int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) { -+int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) -+{ - int rv; - rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL); - rv |= sysfs_set_num(info, NULL, "suspend_hi", 0); - rv |= sysfs_set_num(info, NULL, "suspend_lo", 0); - -- signal(SIGQUIT, sig[2]); -- signal(SIGINT, sig[1]); -- signal(SIGTERM, sig[0]); -+ signal_s(SIGQUIT, sig[2]); -+ signal_s(SIGINT, sig[1]); -+ signal_s(SIGTERM, sig[0]); - - if(munlockall() != 0) - return 3; -diff --git a/util.c b/util.c -index 3d05d074..cc94f96e 100644 ---- a/util.c -+++ b/util.c -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - #include - - --- -2.38.1 - diff --git a/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch b/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch deleted file mode 100644 index bee28ac..0000000 --- a/SOURCES/0006-mdadm-Respect-config-file-location-in-man.patch +++ /dev/null @@ -1,1533 +0,0 @@ -From e9dd5644843e2013a7dd1a8a5da2b9fa35837416 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:04 +0100 -Subject: [PATCH 06/83] mdadm: Respect config file location in man - -Default config file location could differ depending on OS (e.g. Debian family). -This patch takes default config file into consideration when creating mdadm.man -file as well as mdadm.conf.man. - -Rename mdadm.conf.5 to mdadm.conf.5.in. Now mdadm.conf.5 is generated automatically. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - .gitignore | 1 + - Makefile | 7 +- - mdadm.8.in | 16 +- - mdadm.conf.5 | 706 ------------------------------------------------ - mdadm.conf.5.in | 706 ++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 721 insertions(+), 715 deletions(-) - delete mode 100644 mdadm.conf.5 - create mode 100644 mdadm.conf.5.in - -diff --git a/.gitignore b/.gitignore -index 217fe76d..8d791c6f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -3,6 +3,7 @@ - /*-stamp - /mdadm - /mdadm.8 -+/mdadm.conf.5 - /mdadm.udeb - /mdassemble - /mdmon -diff --git a/Makefile b/Makefile -index 2a51d813..bf126033 100644 ---- a/Makefile -+++ b/Makefile -@@ -227,7 +227,12 @@ raid6check : raid6check.o mdadm.h $(CHECK_OBJS) - - mdadm.8 : mdadm.8.in - sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' \ -- -e 's,{MAP_PATH},$(MAP_PATH),g' mdadm.8.in > mdadm.8 -+ -e 's,{MAP_PATH},$(MAP_PATH),g' -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.8.in > mdadm.8 -+ -+mdadm.conf.5 : mdadm.conf.5.in -+ sed -e 's,{CONFFILE},$(CONFFILE),g' \ -+ -e 's,{CONFFILE2},$(CONFFILE2),g' mdadm.conf.5.in > mdadm.conf.5 - - mdadm.man : mdadm.8 - man -l mdadm.8 > mdadm.man -diff --git a/mdadm.8.in b/mdadm.8.in -index e2a42425..8b21ffd4 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -267,13 +267,13 @@ the exact meaning of this option in different contexts. - .TP - .BR \-c ", " \-\-config= - Specify the config file or directory. Default is to use --.B /etc/mdadm.conf -+.B {CONFFILE} - and --.BR /etc/mdadm.conf.d , -+.BR {CONFFILE}.d , - or if those are missing then --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - and --.BR /etc/mdadm/mdadm.conf.d . -+.BR {CONFFILE2}.d . - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2014,9 +2014,9 @@ The config file is only used if explicitly named with - or requested with (a possibly implicit) - .BR \-\-scan . - In the later case, --.B /etc/mdadm.conf -+.B {CONFFILE} - or --.B /etc/mdadm/mdadm.conf -+.B {CONFFILE2} - is used. - - If -@@ -3344,7 +3344,7 @@ uses this to find arrays when - is given in Misc mode, and to monitor array reconstruction - on Monitor mode. - --.SS /etc/mdadm.conf -+.SS {CONFFILE} (or {CONFFILE2}) - - The config file lists which devices may be scanned to see if - they contain MD super block, and gives identifying information -@@ -3352,7 +3352,7 @@ they contain MD super block, and gives identifying information - .BR mdadm.conf (5) - for more details. - --.SS /etc/mdadm.conf.d -+.SS {CONFFILE}.d (or {CONFFILE2}.d) - - A directory containing configuration files which are read in lexical - order. -diff --git a/mdadm.conf.5 b/mdadm.conf.5 -deleted file mode 100644 -index 74a21c5f..00000000 ---- a/mdadm.conf.5 -+++ /dev/null -@@ -1,706 +0,0 @@ --.\" Copyright Neil Brown and others. --.\" This program is free software; you can redistribute it and/or modify --.\" it under the terms of the GNU General Public License as published by --.\" the Free Software Foundation; either version 2 of the License, or --.\" (at your option) any later version. --.\" See file COPYING in distribution for details. --.TH MDADM.CONF 5 --.SH NAME --mdadm.conf \- configuration for management of Software RAID with mdadm --.SH SYNOPSIS --/etc/mdadm.conf --.SH DESCRIPTION --.PP --.I mdadm --is a tool for creating, managing, and monitoring RAID devices using the --.B md --driver in Linux. --.PP --Some common tasks, such as assembling all arrays, can be simplified --by describing the devices and arrays in this configuration file. -- --.SS SYNTAX --The file should be seen as a collection of words separated by white --space (space, tab, or newline). --Any word that beings with a hash sign (#) starts a comment and that --word together with the remainder of the line is ignored. -- --Spaces can be included in a word using quotation characters. Either --single quotes --.RB ( ' ) --or double quotes (\fB"\fP) --may be used. All the characters from one quotation character to --next identical character are protected and will not be used to --separate words to start new quoted strings. To include a single quote --it must be between double quotes. To include a double quote it must --be between single quotes. -- --Any line that starts with white space (space or tab) is treated as --though it were a continuation of the previous line. -- --Empty lines are ignored, but otherwise each (non continuation) line --must start with a keyword as listed below. The keywords are case --insensitive and can be abbreviated to 3 characters. -- --The keywords are: --.TP --.B DEVICE --A --.B device --line lists the devices (whole devices or partitions) that might contain --a component of an MD array. When looking for the components of an --array, --.I mdadm --will scan these devices (or any devices listed on the command line). -- --The --.B device --line may contain a number of different devices (separated by spaces) --and each device name can contain wild cards as defined by --.BR glob (7). -- --Also, there may be several device lines present in the file. -- --Alternatively, a --.B device --line can contain either or both of the words --.B containers --and --.BR partitions . --The word --.B containers --will cause --.I mdadm --to look for assembled CONTAINER arrays and included them as a source --for assembling further arrays. -- --The word --.I partitions --will cause --.I mdadm --to read --.I /proc/partitions --and include all devices and partitions found therein. --.I mdadm --does not use the names from --.I /proc/partitions --but only the major and minor device numbers. It scans --.I /dev --to find the name that matches the numbers. -- --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -- --For example: --.IP --DEVICE /dev/hda* /dev/hdc* --.br --DEV /dev/sd* --.br --DEVICE /dev/disk/by-path/pci* --.br --DEVICE partitions -- --.TP --.B ARRAY --The ARRAY lines identify actual arrays. The second word on the line --may be the name of the device where the array is normally --assembled, such as --.B /dev/md1 --or --.BR /dev/md/backup . --If the name does not start with a slash --.RB (' / '), --it is treated as being in --.BR /dev/md/ . --Alternately the word --.B --(complete with angle brackets) can be given in which case any array --which matches the rest of the line will never be automatically assembled. --If no device name is given, --.I mdadm --will use various heuristics to determine an appropriate name. -- --Subsequent words identify the array, or identify the array as a member --of a group. If multiple identities are given, --then a component device must match ALL identities to be considered a --match. Each identity word has a tag, and equals sign, and some value. --The tags are: --.RS 4 --.TP --.B uuid= --The value should be a 128 bit uuid in hexadecimal, with punctuation --interspersed if desired. This must match the uuid stored in the --superblock. --.TP --.B name= --The value should be a simple textual name as was given to --.I mdadm --when the array was created. This must match the name stored in the --superblock on a device for that device to be included in the array. --Not all superblock formats support names. --.TP --.B super\-minor= --The value is an integer which indicates the minor number that was --stored in the superblock when the array was created. When an array is --created as /dev/mdX, then the minor number X is stored. --.TP --.B devices= --The value is a comma separated list of device names or device name --patterns. --Only devices with names which match one entry in the list will be used --to assemble the array. Note that the devices --listed there must also be listed on a DEVICE line. --.TP --.B level= --The value is a RAID level. This is not normally used to --identify an array, but is supported so that the output of -- --.B "mdadm \-\-examine \-\-scan" -- --can be use directly in the configuration file. --.TP --.B num\-devices= --The value is the number of devices in a complete active array. As with --.B level= --this is mainly for compatibility with the output of -- --.BR "mdadm \-\-examine \-\-scan" . -- --.TP --.B spares= --The value is a number of spare devices to expect the array to have. --The sole use of this keyword and value is as follows: --.B mdadm \-\-monitor --will report an array if it is found to have fewer than this number of --spares when --.B \-\-monitor --starts or when --.B \-\-oneshot --is used. -- --.TP --.B spare\-group= --The value is a textual name for a group of arrays. All arrays with --the same --.B spare\-group --name are considered to be part of the same group. The significance of --a group of arrays is that --.I mdadm --will, when monitoring the arrays, move a spare drive from one array in --a group to another array in that group if the first array had a failed --or missing drive but no spare. -- --.TP --.B auto= --This option is rarely needed with mdadm-3.0, particularly if use with --the Linux kernel v2.6.28 or later. --It tells --.I mdadm --whether to use partitionable array or non-partitionable arrays and, --in the absence of --.IR udev , --how many partition devices to create. From 2.6.28 all md array --devices are partitionable, hence this option is not needed. -- --The value of this option can be "yes" or "md" to indicate that a --traditional, non-partitionable md array should be created, or "mdp", --"part" or "partition" to indicate that a partitionable md array (only --available in linux 2.6 and later) should be used. This later set can --also have a number appended to indicate how many partitions to create --device files for, e.g. --.BR auto=mdp5 . --The default is 4. -- --.TP --.B bitmap= --The option specifies a file in which a write-intent bitmap should be --found. When assembling the array, --.I mdadm --will provide this file to the --.B md --driver as the bitmap file. This has the same function as the --.B \-\-bitmap\-file --option to --.BR \-\-assemble . -- --.TP --.B metadata= --Specify the metadata format that the array has. This is mainly --recognised for comparability with the output of --.BR "mdadm \-Es" . -- --.TP --.B container= --Specify that this array is a member array of some container. The --value given can be either a path name in /dev, or a UUID of the --container array. -- --.TP --.B member= --Specify that this array is a member array of some container. Each --type of container has some way to enumerate member arrays, often a --simple sequence number. The value identifies which member of a --container the array is. It will usually accompany a "container=" word. --.RE -- --.TP --.B MAILADDR --The --.B mailaddr --line gives an E-mail address that alerts should be --sent to when --.I mdadm --is running in --.B \-\-monitor --mode (and was given the --.B \-\-scan --option). There should only be one --.B MAILADDR --line and it should have only one address. Any subsequent addresses --are silently ignored. -- --.TP --.B MAILFROM --The --.B mailfrom --line (which can only be abbreviated to at least 5 characters) gives an --address to appear in the "From" address for alert mails. This can be --useful if you want to explicitly set a domain, as the default from --address is "root" with no domain. All words on this line are --catenated with spaces to form the address. -- --Note that this value cannot be set via the --.I mdadm --commandline. It is only settable via the config file. -- --.TP --.B PROGRAM --The --.B program --line gives the name of a program to be run when --.B "mdadm \-\-monitor" --detects potentially interesting events on any of the arrays that it --is monitoring. This program gets run with two or three arguments, they --being the Event, the md device, and possibly the related component --device. -- --There should only be one --.B program --line and it should be give only one program. -- -- --.TP --.B CREATE --The --.B create --line gives default values to be used when creating arrays, new members --of arrays, and device entries for arrays. --These include: -- --.RS 4 --.TP --.B owner= --.TP --.B group= --These can give user/group ids or names to use instead of system --defaults (root/wheel or root/disk). --.TP --.B mode= --An octal file mode such as 0660 can be given to override the default --of 0600. --.TP --.B auto= --This corresponds to the --.B \-\-auto --flag to mdadm. Give --.BR yes , --.BR md , --.BR mdp , --.B part --\(em possibly followed by a number of partitions \(em to indicate how --missing device entries should be created. -- --.TP --.B metadata= --The name of the metadata format to use if none is explicitly given. --This can be useful to impose a system-wide default of version-1 superblocks. -- --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- --.TP --.B names=yes --Since Linux 2.6.29 it has been possible to create --.B md --devices with a name like --.B md_home --rather than just a number, like --.BR md3 . --.I mdadm --will use the numeric alternative by default as other tools that interact --with md arrays may expect only numbers. --If --.B names=yes --is given in --.I mdadm.conf --then --.I mdadm --will use a name when appropriate. --If --.B names=no --is given, then non-numeric --.I md --device names will not be used even if the default changes in a future --release of --.IR mdadm . -- --.TP --.B bbl=no --By default, --.I mdadm --will reserve space for a bad block list (bbl) on all devices --included in or added to any array that supports them. Setting --.B bbl=no --will prevent this, so newly added devices will not have a bad --block log. --.RE -- --.TP --.B HOMEHOST --The --.B homehost --line gives a default value for the --.B \-\-homehost= --option to mdadm. There should normally be only one other word on the line. --It should either be a host name, or one of the special words --.BR , --.B --and --.BR . --If --.B --is given, then the --.BR gethostname ( 2 ) --systemcall is used to get the host name. This is the default. -- --If --.B --is given, then a flag is set so that when arrays are being --auto-assembled the checking of the recorded --.I homehost --is disabled. --If --.B --is given it is also possible to give an explicit name which will be --used when creating arrays. This is the only case when there can be --more that one other word on the --.B HOMEHOST --line. If there are other words, or other --.B HOMEHOST --lines, they are silently ignored. -- --If --.B --is given, then the default of using --.BR gethostname ( 2 ) --is over-ridden and no homehost name is assumed. -- --When arrays are created, this host name will be stored in the --metadata. When arrays are assembled using auto-assembly, arrays which --do not record the correct homehost name in their metadata will be --assembled using a "foreign" name. A "foreign" name alway ends with a --digit string preceded by an underscore to differentiate it --from any possible local name. e.g. --.B /dev/md/1_1 --or --.BR /dev/md/home_0 . --.TP --.B AUTO --A list of names of metadata format can be given, each preceded by a --plus or minus sign. Also the word --.I homehost --is allowed as is --.I all --preceded by plus or minus sign. --.I all --is usually last. -- --When --.I mdadm --is auto-assembling an array, either via --.I \-\-assemble --or --.I \-\-incremental --and it finds metadata of a given type, it checks that metadata type --against those listed in this line. The first match wins, where --.I all --matches anything. --If a match is found that was preceded by a plus sign, the auto --assembly is allowed. If the match was preceded by a minus sign, the --auto assembly is disallowed. If no match is found, the auto assembly --is allowed. -- --If the metadata indicates that the array was created for --.I this --host, and the word --.I homehost --appears before any other match, then the array is treated as a valid --candidate for auto-assembly. -- --This can be used to disable all auto-assembly (so that only arrays --explicitly listed in mdadm.conf or on the command line are assembled), --or to disable assembly of certain metadata types which might be --handled by other software. It can also be used to disable assembly of --all foreign arrays - normally such arrays are assembled but given a --non-deterministic name in --.BR /dev/md/ . -- --The known metadata types are --.BR 0.90 , --.BR 1.x , --.BR ddf , --.BR imsm . -- --.B AUTO --should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -- --.TP --.B POLICY --This is used to specify what automatic behavior is allowed on devices --newly appearing in the system and provides a way of marking spares that can --be moved to other arrays as well as the migration domains. --.I Domain --can be defined through --.I policy --line by specifying a domain name for a number of paths from --.BR /dev/disk/by-path/ . --A device may belong to several domains. The domain of an array is a union --of domains of all devices in that array. A spare can be automatically --moved from one array to another if the set of the destination array's --.I domains --contains all the --.I domains --of the new disk or if both arrays have the same --.IR spare-group . -- --To update hot plug configuration it is necessary to execute --.B mdadm \-\-udev\-rules --command after changing the config file -- --Keywords used in the --.I POLICY --line and supported values are: -- --.RS 4 --.TP --.B domain= --any arbitrary string --.TP --.B metadata= --0.9 1.x ddf or imsm --.TP --.B path= --file glob matching anything from --.B /dev/disk/by-path --.TP --.B type= --either --.B disk --or --.BR part . --.TP --.B action= --include, re-add, spare, spare-same-slot, or force-spare --.TP --.B auto= --yes, no, or homehost. -- --.P --The --.I action --item determines the automatic behavior allowed for devices matching the --.I path --and --.I type --in the same line. If a device matches several lines with different --.I actions --then the most permissive will apply. The ordering of policy lines --is irrelevant to the end result. --.TP --.B include --allows adding a disk to an array if metadata on that disk matches that array --.TP --.B re\-add --will include the device in the array if it appears to be a current member --or a member that was recently removed and the array has a --write-intent-bitmap to allow the --.B re\-add --functionality. --.TP --.B spare --as above and additionally: if the device is bare it can --become a spare if there is any array that it is a candidate for based --on domains and metadata. --.TP --.B spare\-same\-slot --as above and additionally if given slot was used by an array that went --degraded recently and the device plugged in has no metadata then it will --be automatically added to that array (or it's container) --.TP --.B force\-spare --as above and the disk will become a spare in remaining cases --.RE -- --.TP --.B PART-POLICY --This is similar to --.B POLICY --and accepts the same keyword assignments. It allows a consistent set --of policies to applied to each of the partitions of a device. -- --A --.B PART-POLICY --line should set --.I type=disk --and identify the path to one or more disk devices. Each partition on --these disks will be treated according to the --.I action= --setting from this line. If a --.I domain --is set in the line, then the domain associated with each patition will --be based on the domain, but with --.RB \(dq -part N\(dq --appended, when N is the partition number for the partition that was --found. -- --.TP --.B SYSFS --The --.B SYSFS --line lists custom values of MD device's sysfs attributes which will be --stored in sysfs after the array is assembled. Multiple lines are allowed and each --line has to contain the uuid or the name of the device to which it relates. --.RS 4 --.TP --.B uuid= --hexadecimal identifier of MD device. This has to match the uuid stored in the --superblock. --.TP --.B name= --name of the MD device as was given to --.I mdadm --when the array was created. It will be ignored if --.B uuid --is not empty. --.RE -- --.TP --.B MONITORDELAY --The --.B monitordelay --line gives a delay in seconds --.I mdadm --shall wait before pooling md arrays --when --.I mdadm --is running in --.B \-\-monitor --mode. --.B \-d/\-\-delay --command line argument takes precedence over the config file -- --.SH EXAMPLE --DEVICE /dev/sd[bcdjkl]1 --.br --DEVICE /dev/hda1 /dev/hdb1 -- --# /dev/md0 is known by its UUID. --.br --ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 --.br --# /dev/md1 contains all devices with a minor number of --.br --# 1 in the superblock. --.br --ARRAY /dev/md1 superminor=1 --.br --# /dev/md2 is made from precisely these two devices --.br --ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -- --# /dev/md4 and /dev/md5 are a spare-group and spares --.br --# can be moved between them --.br --ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df --.br -- spare\-group=group1 --.br --ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 --.br -- spare\-group=group1 --.br --# /dev/md/home is created if need to be a partitionable md array --.br --# any spare device number is allocated. --.br --ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b --.br -- auto=part --.br --# The name of this array contains a space. --.br --ARRAY /dev/md9 name='Data Storage' --.sp --POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* --.br -- action=spare --.br --POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* --.br -- action=include --.br --# One domain comprising of devices attached to specified paths is defined. --.br --# Bare device matching first path will be made an imsm spare on hot plug. --.br --# If more than one array is created on devices belonging to domain1 and --.br --# one of them becomes degraded, then any imsm spare matching any path for --.br --# given domain name can be migrated. --.br --MAILADDR root@mydomain.tld --.br --PROGRAM /usr/sbin/handle\-mdadm\-events --.br --CREATE group=system mode=0640 auto=part\-8 --.br --HOMEHOST --.br --AUTO +1.x homehost \-all --.br --SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 --.br --SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 --sync_speed_max=1000000 --.br --MONITORDELAY 60 -- --.SH SEE ALSO --.BR mdadm (8), --.BR md (4). -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -new file mode 100644 -index 00000000..83edd008 ---- /dev/null -+++ b/mdadm.conf.5.in -@@ -0,0 +1,706 @@ -+.\" Copyright Neil Brown and others. -+.\" This program is free software; you can redistribute it and/or modify -+.\" it under the terms of the GNU General Public License as published by -+.\" the Free Software Foundation; either version 2 of the License, or -+.\" (at your option) any later version. -+.\" See file COPYING in distribution for details. -+.TH MDADM.CONF 5 -+.SH NAME -+mdadm.conf \- configuration for management of Software RAID with mdadm -+.SH SYNOPSIS -+{CONFFILE} -+.SH DESCRIPTION -+.PP -+.I mdadm -+is a tool for creating, managing, and monitoring RAID devices using the -+.B md -+driver in Linux. -+.PP -+Some common tasks, such as assembling all arrays, can be simplified -+by describing the devices and arrays in this configuration file. -+ -+.SS SYNTAX -+The file should be seen as a collection of words separated by white -+space (space, tab, or newline). -+Any word that beings with a hash sign (#) starts a comment and that -+word together with the remainder of the line is ignored. -+ -+Spaces can be included in a word using quotation characters. Either -+single quotes -+.RB ( ' ) -+or double quotes (\fB"\fP) -+may be used. All the characters from one quotation character to -+next identical character are protected and will not be used to -+separate words to start new quoted strings. To include a single quote -+it must be between double quotes. To include a double quote it must -+be between single quotes. -+ -+Any line that starts with white space (space or tab) is treated as -+though it were a continuation of the previous line. -+ -+Empty lines are ignored, but otherwise each (non continuation) line -+must start with a keyword as listed below. The keywords are case -+insensitive and can be abbreviated to 3 characters. -+ -+The keywords are: -+.TP -+.B DEVICE -+A -+.B device -+line lists the devices (whole devices or partitions) that might contain -+a component of an MD array. When looking for the components of an -+array, -+.I mdadm -+will scan these devices (or any devices listed on the command line). -+ -+The -+.B device -+line may contain a number of different devices (separated by spaces) -+and each device name can contain wild cards as defined by -+.BR glob (7). -+ -+Also, there may be several device lines present in the file. -+ -+Alternatively, a -+.B device -+line can contain either or both of the words -+.B containers -+and -+.BR partitions . -+The word -+.B containers -+will cause -+.I mdadm -+to look for assembled CONTAINER arrays and included them as a source -+for assembling further arrays. -+ -+The word -+.I partitions -+will cause -+.I mdadm -+to read -+.I /proc/partitions -+and include all devices and partitions found therein. -+.I mdadm -+does not use the names from -+.I /proc/partitions -+but only the major and minor device numbers. It scans -+.I /dev -+to find the name that matches the numbers. -+ -+If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+ -+For example: -+.IP -+DEVICE /dev/hda* /dev/hdc* -+.br -+DEV /dev/sd* -+.br -+DEVICE /dev/disk/by-path/pci* -+.br -+DEVICE partitions -+ -+.TP -+.B ARRAY -+The ARRAY lines identify actual arrays. The second word on the line -+may be the name of the device where the array is normally -+assembled, such as -+.B /dev/md1 -+or -+.BR /dev/md/backup . -+If the name does not start with a slash -+.RB (' / '), -+it is treated as being in -+.BR /dev/md/ . -+Alternately the word -+.B -+(complete with angle brackets) can be given in which case any array -+which matches the rest of the line will never be automatically assembled. -+If no device name is given, -+.I mdadm -+will use various heuristics to determine an appropriate name. -+ -+Subsequent words identify the array, or identify the array as a member -+of a group. If multiple identities are given, -+then a component device must match ALL identities to be considered a -+match. Each identity word has a tag, and equals sign, and some value. -+The tags are: -+.RS 4 -+.TP -+.B uuid= -+The value should be a 128 bit uuid in hexadecimal, with punctuation -+interspersed if desired. This must match the uuid stored in the -+superblock. -+.TP -+.B name= -+The value should be a simple textual name as was given to -+.I mdadm -+when the array was created. This must match the name stored in the -+superblock on a device for that device to be included in the array. -+Not all superblock formats support names. -+.TP -+.B super\-minor= -+The value is an integer which indicates the minor number that was -+stored in the superblock when the array was created. When an array is -+created as /dev/mdX, then the minor number X is stored. -+.TP -+.B devices= -+The value is a comma separated list of device names or device name -+patterns. -+Only devices with names which match one entry in the list will be used -+to assemble the array. Note that the devices -+listed there must also be listed on a DEVICE line. -+.TP -+.B level= -+The value is a RAID level. This is not normally used to -+identify an array, but is supported so that the output of -+ -+.B "mdadm \-\-examine \-\-scan" -+ -+can be use directly in the configuration file. -+.TP -+.B num\-devices= -+The value is the number of devices in a complete active array. As with -+.B level= -+this is mainly for compatibility with the output of -+ -+.BR "mdadm \-\-examine \-\-scan" . -+ -+.TP -+.B spares= -+The value is a number of spare devices to expect the array to have. -+The sole use of this keyword and value is as follows: -+.B mdadm \-\-monitor -+will report an array if it is found to have fewer than this number of -+spares when -+.B \-\-monitor -+starts or when -+.B \-\-oneshot -+is used. -+ -+.TP -+.B spare\-group= -+The value is a textual name for a group of arrays. All arrays with -+the same -+.B spare\-group -+name are considered to be part of the same group. The significance of -+a group of arrays is that -+.I mdadm -+will, when monitoring the arrays, move a spare drive from one array in -+a group to another array in that group if the first array had a failed -+or missing drive but no spare. -+ -+.TP -+.B auto= -+This option is rarely needed with mdadm-3.0, particularly if use with -+the Linux kernel v2.6.28 or later. -+It tells -+.I mdadm -+whether to use partitionable array or non-partitionable arrays and, -+in the absence of -+.IR udev , -+how many partition devices to create. From 2.6.28 all md array -+devices are partitionable, hence this option is not needed. -+ -+The value of this option can be "yes" or "md" to indicate that a -+traditional, non-partitionable md array should be created, or "mdp", -+"part" or "partition" to indicate that a partitionable md array (only -+available in linux 2.6 and later) should be used. This later set can -+also have a number appended to indicate how many partitions to create -+device files for, e.g. -+.BR auto=mdp5 . -+The default is 4. -+ -+.TP -+.B bitmap= -+The option specifies a file in which a write-intent bitmap should be -+found. When assembling the array, -+.I mdadm -+will provide this file to the -+.B md -+driver as the bitmap file. This has the same function as the -+.B \-\-bitmap\-file -+option to -+.BR \-\-assemble . -+ -+.TP -+.B metadata= -+Specify the metadata format that the array has. This is mainly -+recognised for comparability with the output of -+.BR "mdadm \-Es" . -+ -+.TP -+.B container= -+Specify that this array is a member array of some container. The -+value given can be either a path name in /dev, or a UUID of the -+container array. -+ -+.TP -+.B member= -+Specify that this array is a member array of some container. Each -+type of container has some way to enumerate member arrays, often a -+simple sequence number. The value identifies which member of a -+container the array is. It will usually accompany a "container=" word. -+.RE -+ -+.TP -+.B MAILADDR -+The -+.B mailaddr -+line gives an E-mail address that alerts should be -+sent to when -+.I mdadm -+is running in -+.B \-\-monitor -+mode (and was given the -+.B \-\-scan -+option). There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. -+ -+.TP -+.B MAILFROM -+The -+.B mailfrom -+line (which can only be abbreviated to at least 5 characters) gives an -+address to appear in the "From" address for alert mails. This can be -+useful if you want to explicitly set a domain, as the default from -+address is "root" with no domain. All words on this line are -+catenated with spaces to form the address. -+ -+Note that this value cannot be set via the -+.I mdadm -+commandline. It is only settable via the config file. -+ -+.TP -+.B PROGRAM -+The -+.B program -+line gives the name of a program to be run when -+.B "mdadm \-\-monitor" -+detects potentially interesting events on any of the arrays that it -+is monitoring. This program gets run with two or three arguments, they -+being the Event, the md device, and possibly the related component -+device. -+ -+There should only be one -+.B program -+line and it should be give only one program. -+ -+ -+.TP -+.B CREATE -+The -+.B create -+line gives default values to be used when creating arrays, new members -+of arrays, and device entries for arrays. -+These include: -+ -+.RS 4 -+.TP -+.B owner= -+.TP -+.B group= -+These can give user/group ids or names to use instead of system -+defaults (root/wheel or root/disk). -+.TP -+.B mode= -+An octal file mode such as 0660 can be given to override the default -+of 0600. -+.TP -+.B auto= -+This corresponds to the -+.B \-\-auto -+flag to mdadm. Give -+.BR yes , -+.BR md , -+.BR mdp , -+.B part -+\(em possibly followed by a number of partitions \(em to indicate how -+missing device entries should be created. -+ -+.TP -+.B metadata= -+The name of the metadata format to use if none is explicitly given. -+This can be useful to impose a system-wide default of version-1 superblocks. -+ -+.TP -+.B symlinks=no -+Normally when creating devices in -+.B /dev/md/ -+.I mdadm -+will create a matching symlink from -+.B /dev/ -+with a name starting -+.B md -+or -+.BR md_ . -+Give -+.B symlinks=no -+to suppress this symlink creation. -+ -+.TP -+.B names=yes -+Since Linux 2.6.29 it has been possible to create -+.B md -+devices with a name like -+.B md_home -+rather than just a number, like -+.BR md3 . -+.I mdadm -+will use the numeric alternative by default as other tools that interact -+with md arrays may expect only numbers. -+If -+.B names=yes -+is given in -+.I mdadm.conf -+then -+.I mdadm -+will use a name when appropriate. -+If -+.B names=no -+is given, then non-numeric -+.I md -+device names will not be used even if the default changes in a future -+release of -+.IR mdadm . -+ -+.TP -+.B bbl=no -+By default, -+.I mdadm -+will reserve space for a bad block list (bbl) on all devices -+included in or added to any array that supports them. Setting -+.B bbl=no -+will prevent this, so newly added devices will not have a bad -+block log. -+.RE -+ -+.TP -+.B HOMEHOST -+The -+.B homehost -+line gives a default value for the -+.B \-\-homehost= -+option to mdadm. There should normally be only one other word on the line. -+It should either be a host name, or one of the special words -+.BR , -+.B -+and -+.BR . -+If -+.B -+is given, then the -+.BR gethostname ( 2 ) -+systemcall is used to get the host name. This is the default. -+ -+If -+.B -+is given, then a flag is set so that when arrays are being -+auto-assembled the checking of the recorded -+.I homehost -+is disabled. -+If -+.B -+is given it is also possible to give an explicit name which will be -+used when creating arrays. This is the only case when there can be -+more that one other word on the -+.B HOMEHOST -+line. If there are other words, or other -+.B HOMEHOST -+lines, they are silently ignored. -+ -+If -+.B -+is given, then the default of using -+.BR gethostname ( 2 ) -+is over-ridden and no homehost name is assumed. -+ -+When arrays are created, this host name will be stored in the -+metadata. When arrays are assembled using auto-assembly, arrays which -+do not record the correct homehost name in their metadata will be -+assembled using a "foreign" name. A "foreign" name alway ends with a -+digit string preceded by an underscore to differentiate it -+from any possible local name. e.g. -+.B /dev/md/1_1 -+or -+.BR /dev/md/home_0 . -+.TP -+.B AUTO -+A list of names of metadata format can be given, each preceded by a -+plus or minus sign. Also the word -+.I homehost -+is allowed as is -+.I all -+preceded by plus or minus sign. -+.I all -+is usually last. -+ -+When -+.I mdadm -+is auto-assembling an array, either via -+.I \-\-assemble -+or -+.I \-\-incremental -+and it finds metadata of a given type, it checks that metadata type -+against those listed in this line. The first match wins, where -+.I all -+matches anything. -+If a match is found that was preceded by a plus sign, the auto -+assembly is allowed. If the match was preceded by a minus sign, the -+auto assembly is disallowed. If no match is found, the auto assembly -+is allowed. -+ -+If the metadata indicates that the array was created for -+.I this -+host, and the word -+.I homehost -+appears before any other match, then the array is treated as a valid -+candidate for auto-assembly. -+ -+This can be used to disable all auto-assembly (so that only arrays -+explicitly listed in mdadm.conf or on the command line are assembled), -+or to disable assembly of certain metadata types which might be -+handled by other software. It can also be used to disable assembly of -+all foreign arrays - normally such arrays are assembled but given a -+non-deterministic name in -+.BR /dev/md/ . -+ -+The known metadata types are -+.BR 0.90 , -+.BR 1.x , -+.BR ddf , -+.BR imsm . -+ -+.B AUTO -+should be given at most once. Subsequent lines are silently ignored. -+Thus an earlier config file in a config directory will over-ride -+the setting in a later config file. -+ -+.TP -+.B POLICY -+This is used to specify what automatic behavior is allowed on devices -+newly appearing in the system and provides a way of marking spares that can -+be moved to other arrays as well as the migration domains. -+.I Domain -+can be defined through -+.I policy -+line by specifying a domain name for a number of paths from -+.BR /dev/disk/by-path/ . -+A device may belong to several domains. The domain of an array is a union -+of domains of all devices in that array. A spare can be automatically -+moved from one array to another if the set of the destination array's -+.I domains -+contains all the -+.I domains -+of the new disk or if both arrays have the same -+.IR spare-group . -+ -+To update hot plug configuration it is necessary to execute -+.B mdadm \-\-udev\-rules -+command after changing the config file -+ -+Keywords used in the -+.I POLICY -+line and supported values are: -+ -+.RS 4 -+.TP -+.B domain= -+any arbitrary string -+.TP -+.B metadata= -+0.9 1.x ddf or imsm -+.TP -+.B path= -+file glob matching anything from -+.B /dev/disk/by-path -+.TP -+.B type= -+either -+.B disk -+or -+.BR part . -+.TP -+.B action= -+include, re-add, spare, spare-same-slot, or force-spare -+.TP -+.B auto= -+yes, no, or homehost. -+ -+.P -+The -+.I action -+item determines the automatic behavior allowed for devices matching the -+.I path -+and -+.I type -+in the same line. If a device matches several lines with different -+.I actions -+then the most permissive will apply. The ordering of policy lines -+is irrelevant to the end result. -+.TP -+.B include -+allows adding a disk to an array if metadata on that disk matches that array -+.TP -+.B re\-add -+will include the device in the array if it appears to be a current member -+or a member that was recently removed and the array has a -+write-intent-bitmap to allow the -+.B re\-add -+functionality. -+.TP -+.B spare -+as above and additionally: if the device is bare it can -+become a spare if there is any array that it is a candidate for based -+on domains and metadata. -+.TP -+.B spare\-same\-slot -+as above and additionally if given slot was used by an array that went -+degraded recently and the device plugged in has no metadata then it will -+be automatically added to that array (or it's container) -+.TP -+.B force\-spare -+as above and the disk will become a spare in remaining cases -+.RE -+ -+.TP -+.B PART-POLICY -+This is similar to -+.B POLICY -+and accepts the same keyword assignments. It allows a consistent set -+of policies to applied to each of the partitions of a device. -+ -+A -+.B PART-POLICY -+line should set -+.I type=disk -+and identify the path to one or more disk devices. Each partition on -+these disks will be treated according to the -+.I action= -+setting from this line. If a -+.I domain -+is set in the line, then the domain associated with each patition will -+be based on the domain, but with -+.RB \(dq -part N\(dq -+appended, when N is the partition number for the partition that was -+found. -+ -+.TP -+.B SYSFS -+The -+.B SYSFS -+line lists custom values of MD device's sysfs attributes which will be -+stored in sysfs after the array is assembled. Multiple lines are allowed and each -+line has to contain the uuid or the name of the device to which it relates. -+.RS 4 -+.TP -+.B uuid= -+hexadecimal identifier of MD device. This has to match the uuid stored in the -+superblock. -+.TP -+.B name= -+name of the MD device as was given to -+.I mdadm -+when the array was created. It will be ignored if -+.B uuid -+is not empty. -+.RE -+ -+.TP -+.B MONITORDELAY -+The -+.B monitordelay -+line gives a delay in seconds -+.I mdadm -+shall wait before pooling md arrays -+when -+.I mdadm -+is running in -+.B \-\-monitor -+mode. -+.B \-d/\-\-delay -+command line argument takes precedence over the config file -+ -+.SH EXAMPLE -+DEVICE /dev/sd[bcdjkl]1 -+.br -+DEVICE /dev/hda1 /dev/hdb1 -+ -+# /dev/md0 is known by its UUID. -+.br -+ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 -+.br -+# /dev/md1 contains all devices with a minor number of -+.br -+# 1 in the superblock. -+.br -+ARRAY /dev/md1 superminor=1 -+.br -+# /dev/md2 is made from precisely these two devices -+.br -+ARRAY /dev/md2 devices=/dev/hda1,/dev/hdb1 -+ -+# /dev/md4 and /dev/md5 are a spare-group and spares -+.br -+# can be moved between them -+.br -+ARRAY /dev/md4 uuid=b23f3c6d:aec43a9f:fd65db85:369432df -+.br -+ spare\-group=group1 -+.br -+ARRAY /dev/md5 uuid=19464854:03f71b1b:e0df2edd:246cc977 -+.br -+ spare\-group=group1 -+.br -+# /dev/md/home is created if need to be a partitionable md array -+.br -+# any spare device number is allocated. -+.br -+ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b -+.br -+ auto=part -+.br -+# The name of this array contains a space. -+.br -+ARRAY /dev/md9 name='Data Storage' -+.sp -+POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* -+.br -+ action=spare -+.br -+POLICY domain=domain1 metadata=imsm path=pci-0000:04:00.0-scsi-[01]* -+.br -+ action=include -+.br -+# One domain comprising of devices attached to specified paths is defined. -+.br -+# Bare device matching first path will be made an imsm spare on hot plug. -+.br -+# If more than one array is created on devices belonging to domain1 and -+.br -+# one of them becomes degraded, then any imsm spare matching any path for -+.br -+# given domain name can be migrated. -+.br -+MAILADDR root@mydomain.tld -+.br -+PROGRAM /usr/sbin/handle\-mdadm\-events -+.br -+CREATE group=system mode=0640 auto=part\-8 -+.br -+HOMEHOST -+.br -+AUTO +1.x homehost \-all -+.br -+SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 -+.br -+SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 -+sync_speed_max=1000000 -+.br -+MONITORDELAY 60 -+ -+.SH SEE ALSO -+.BR mdadm (8), -+.BR md (4). --- -2.38.1 - diff --git a/SOURCES/0007-mdadm-Update-ReadMe.patch b/SOURCES/0007-mdadm-Update-ReadMe.patch deleted file mode 100644 index a143a22..0000000 --- a/SOURCES/0007-mdadm-Update-ReadMe.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:05 +0100 -Subject: [PATCH 07/83] mdadm: Update ReadMe - -Instead of hardcoded config file path give reference to config manual. - -Add missing monitordelay and homecluster parameters. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 81399765..8f873c48 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -613,7 +613,6 @@ char Help_incr[] = - ; - - char Help_config[] = --"The /etc/mdadm.conf config file:\n\n" - " The config file contains, apart from blank lines and comment lines that\n" - " start with a hash(#), array lines, device lines, and various\n" - " configuration lines.\n" -@@ -636,10 +635,12 @@ char Help_config[] = - " than a device must match all of them to be considered.\n" - "\n" - " Other configuration lines include:\n" --" mailaddr, mailfrom, program used for --monitor mode\n" --" create, auto used when creating device names in /dev\n" --" homehost, policy, part-policy used to guide policy in various\n" --" situations\n" -+" mailaddr, mailfrom, program, monitordelay used for --monitor mode\n" -+" create, auto used when creating device names in /dev\n" -+" homehost, homecluster, policy, part-policy used to guide policy in various\n" -+" situations\n" -+"\n" -+"For more details see mdadm.conf(5).\n" - "\n" - ; - --- -2.38.1 - diff --git a/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch b/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch deleted file mode 100644 index 0109e9a..0000000 --- a/SOURCES/0008-mdadm-Update-config-man-regarding-default-files-and-.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:06 +0100 -Subject: [PATCH 08/83] mdadm: Update config man regarding default files and - multi-keyword behavior - -Simplify default and alternative config file and directory location references -from mdadm(8) as references to mdadm.conf(5). Add FILE section in config man -and explain order and conditions in which default and alternative config files -and directories are used. - -Update config man behavior regarding parsing order when multiple keywords/config -files are involved. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 30 +++++++++-------------- - mdadm.conf.5.in | 65 ++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 71 insertions(+), 24 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 8b21ffd4..0be02e4a 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. Default is to use --.B {CONFFILE} --and --.BR {CONFFILE}.d , --or if those are missing then --.B {CONFFILE2} --and --.BR {CONFFILE2}.d . -+Specify the config file or directory. If not specified, default config file -+and default conf.d directory will be used. See -+.BR mdadm.conf (5) -+for more details. -+ - If the config file given is - .B "partitions" - then nothing will be read, but -@@ -2013,11 +2010,9 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, --.B {CONFFILE} --or --.B {CONFFILE2} --is used. -+In the later case, default config file is used. See -+.BR mdadm.conf (5) -+for more details. - - If - .B \-\-scan -@@ -3346,16 +3341,15 @@ on Monitor mode. - - .SS {CONFFILE} (or {CONFFILE2}) - --The config file lists which devices may be scanned to see if --they contain MD super block, and gives identifying information --(e.g. UUID) about known MD arrays. See -+Default config file. See - .BR mdadm.conf (5) - for more details. - - .SS {CONFFILE}.d (or {CONFFILE2}.d) - --A directory containing configuration files which are read in lexical --order. -+Default directory containing configuration files. See -+.BR mdadm.conf (5) -+for more details. - - .SS {MAP_PATH} - When -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index 83edd008..dd331a6a 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -88,7 +88,8 @@ but only the major and minor device numbers. It scans - .I /dev - to find the name that matches the numbers. - --If no DEVICE line is present, then "DEVICE partitions containers" is assumed. -+If no DEVICE line is present in any config file, -+then "DEVICE partitions containers" is assumed. - - For example: - .IP -@@ -272,6 +273,10 @@ catenated with spaces to form the address. - Note that this value cannot be set via the - .I mdadm - commandline. It is only settable via the config file. -+There should only be one -+.B MAILADDR -+line and it should have only one address. Any subsequent addresses -+are silently ignored. - - .TP - .B PROGRAM -@@ -286,7 +291,8 @@ device. - - There should only be one - .B program --line and it should be give only one program. -+line and it should be given only one program. Any subsequent programs -+are silently ignored. - - - .TP -@@ -295,7 +301,14 @@ The - .B create - line gives default values to be used when creating arrays, new members - of arrays, and device entries for arrays. --These include: -+ -+There should only be one -+.B create -+line. Any subsequent lines will override the previous settings. -+ -+Keywords used in the -+.I CREATE -+line and supported values are: - - .RS 4 - .TP -@@ -475,8 +488,8 @@ The known metadata types are - - .B AUTO - should be given at most once. Subsequent lines are silently ignored. --Thus an earlier config file in a config directory will over-ride --the setting in a later config file. -+Thus a later config file in a config directory will not overwrite -+the setting in an earlier config file. - - .TP - .B POLICY -@@ -594,6 +607,7 @@ The - line lists custom values of MD device's sysfs attributes which will be - stored in sysfs after the array is assembled. Multiple lines are allowed and each - line has to contain the uuid or the name of the device to which it relates. -+Lines are applied in reverse order. - .RS 4 - .TP - .B uuid= -@@ -621,7 +635,46 @@ is running in - .B \-\-monitor - mode. - .B \-d/\-\-delay --command line argument takes precedence over the config file -+command line argument takes precedence over the config file. -+ -+If multiple -+.B MINITORDELAY -+lines are provided, only first non-zero value is considered. -+ -+.SH FILES -+ -+.SS {CONFFILE} -+ -+The default config file location, used when -+.I mdadm -+is running without --config option. -+ -+.SS {CONFFILE}.d -+ -+The default directory with config files. Used when -+.I mdadm -+is running without --config option, after successful reading of the -+.B {CONFFILE} -+default config file. Files in that directory -+are read in lexical order. -+ -+ -+.SS {CONFFILE2} -+ -+Alternative config file that is read, when -+.I mdadm -+is running without --config option and the -+.B {CONFFILE} -+default config file was not opened successfully. -+ -+.SS {CONFFILE2}.d -+ -+The alternative directory with config files. Used when -+.I mdadm -+is runninng without --config option, after reading the -+.B {CONFFILE2} -+alternative config file whether it was successful or not. Files in -+that directory are read in lexical order. - - .SH EXAMPLE - DEVICE /dev/sd[bcdjkl]1 --- -2.38.1 - diff --git a/SOURCES/0009-mdadm-Update-config-manual.patch b/SOURCES/0009-mdadm-Update-config-manual.patch deleted file mode 100644 index 08599d5..0000000 --- a/SOURCES/0009-mdadm-Update-config-manual.patch +++ /dev/null @@ -1,45 +0,0 @@ -From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 18 Mar 2022 09:26:07 +0100 -Subject: [PATCH 09/83] mdadm: Update config manual - -Add missing HOMECLUSTER keyword description. - -Signed-off-by: Lukasz Florczak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.conf.5.in | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index dd331a6a..cd4e6a9d 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -439,6 +439,23 @@ from any possible local name. e.g. - .B /dev/md/1_1 - or - .BR /dev/md/home_0 . -+ -+.TP -+.B HOMECLUSTER -+The -+.B homcluster -+line gives a default value for the -+.B \-\-homecluster= -+option to mdadm. It specifies the cluster name for the md device. -+The md device can be assembled only on the cluster which matches -+the name specified. If -+.B homcluster -+is not provided, mdadm tries to detect the cluster name automatically. -+ -+There should only be one -+.B homecluster -+line. Any subsequent lines will be silently ignored. -+ - .TP - .B AUTO - A list of names of metadata format can be given, each preceded by a --- -2.38.1 - diff --git a/SOURCES/0010-Create-Build-use-default_layout.patch b/SOURCES/0010-Create-Build-use-default_layout.patch deleted file mode 100644 index 7f9791b..0000000 --- a/SOURCES/0010-Create-Build-use-default_layout.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:32 +0100 -Subject: [PATCH 10/83] Create, Build: use default_layout() - -This code is duplicated for Build mode so make default_layout() extern -and use it. Simplify the function structure. - -It introduced change for Build mode, now for raid0 RAID0_ORIG_LAYOUT -will be returned same as for Create. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Build.c | 23 +------------------ - Create.c | 67 ++++++++++++++++++++++++++++++++++---------------------- - mdadm.h | 1 + - 3 files changed, 43 insertions(+), 48 deletions(-) - -diff --git a/Build.c b/Build.c -index 962c2e37..8d6f6f58 100644 ---- a/Build.c -+++ b/Build.c -@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - - if (s->layout == UnSet) -- switch(s->level) { -- default: /* no layout */ -- s->layout = 0; -- break; -- case 10: -- s->layout = 0x102; /* near=2, far=1 */ -- if (c->verbose > 0) -- pr_err("layout defaults to n1\n"); -- break; -- case 5: -- case 6: -- s->layout = map_name(r5layout, "default"); -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, s->layout)); -- break; -- case LEVEL_FAULTY: -- s->layout = map_name(faultylayout, "default"); -- -- if (c->verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout)); -- break; -- } -+ s->layout = default_layout(NULL, s->level, c->verbose); - - /* We need to create the device. It can have no name. */ - map_lock(&map); -diff --git a/Create.c b/Create.c -index 0ff1922d..9ea19de0 100644 ---- a/Create.c -+++ b/Create.c -@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk) - return 0; - } - --static int default_layout(struct supertype *st, int level, int verbose) -+/** -+ * default_layout() - Get default layout for level. -+ * @st: metadata requested, could be NULL. -+ * @level: raid level requested. -+ * @verbose: verbose level. -+ * -+ * Try to ask metadata handler first, otherwise use global defaults. -+ * -+ * Return: Layout or &UnSet, return value meaning depends of level used. -+ */ -+int default_layout(struct supertype *st, int level, int verbose) - { - int layout = UnSet; -+ mapping_t *layout_map = NULL; -+ char *layout_name = NULL; - - if (st && st->ss->default_geometry) - st->ss->default_geometry(st, &level, &layout, NULL); - -- if (layout == UnSet) -- switch(level) { -- default: /* no layout */ -- layout = 0; -- break; -- case 0: -- layout = RAID0_ORIG_LAYOUT; -- break; -- case 10: -- layout = 0x102; /* near=2, far=1 */ -- if (verbose > 0) -- pr_err("layout defaults to n2\n"); -- break; -- case 5: -- case 6: -- layout = map_name(r5layout, "default"); -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(r5layout, layout)); -- break; -- case LEVEL_FAULTY: -- layout = map_name(faultylayout, "default"); -+ if (layout != UnSet) -+ return layout; - -- if (verbose > 0) -- pr_err("layout defaults to %s\n", map_num(faultylayout, layout)); -- break; -- } -+ switch (level) { -+ default: /* no layout */ -+ layout = 0; -+ break; -+ case 0: -+ layout = RAID0_ORIG_LAYOUT; -+ break; -+ case 10: -+ layout = 0x102; /* near=2, far=1 */ -+ layout_name = "n2"; -+ break; -+ case 5: -+ case 6: -+ layout_map = r5layout; -+ break; -+ case LEVEL_FAULTY: -+ layout_map = faultylayout; -+ break; -+ } -+ -+ if (layout_map) { -+ layout = map_name(layout_map, "default"); -+ layout_name = map_num(layout_map, layout); -+ } -+ if (layout_name && verbose > 0) -+ pr_err("layout defaults to %s\n", layout_name); - - return layout; - } -diff --git a/mdadm.h b/mdadm.h -index 26e7e5cd..cd72e711 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1512,6 +1512,7 @@ extern int get_linux_version(void); - extern int mdadm_version(char *version); - extern unsigned long long parse_size(char *size); - extern int parse_uuid(char *str, int uuid[4]); -+int default_layout(struct supertype *st, int level, int verbose); - extern int is_near_layout_10(int layout); - extern int parse_layout_10(char *layout); - extern int parse_layout_faulty(char *layout); --- -2.38.1 - diff --git a/SOURCES/0011-mdadm-add-map_num_s.patch b/SOURCES/0011-mdadm-add-map_num_s.patch deleted file mode 100644 index ee2c755..0000000 --- a/SOURCES/0011-mdadm-add-map_num_s.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 20 Jan 2022 13:18:33 +0100 -Subject: [PATCH 11/83] mdadm: add map_num_s() - -map_num() returns NULL if key is not defined. This patch adds -alternative, non NULL version for cases where NULL is not expected. - -There are many printf() calls where map_num() is called on variable -without NULL verification. It works, even if NULL is passed because -gcc is able to ignore NULL argument quietly but the behavior is -undefined. For safety reasons such usages will use map_num_s() now. -It is a potential point of regression. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Assemble.c | 6 ++---- - Create.c | 2 +- - Detail.c | 4 ++-- - Grow.c | 16 ++++++++-------- - Query.c | 4 ++-- - maps.c | 24 ++++++++++++++++++++++++ - mdadm.c | 20 ++++++++++---------- - mdadm.h | 2 +- - super-ddf.c | 6 +++--- - super-intel.c | 2 +- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 9 +++++---- - 13 files changed, 61 insertions(+), 38 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 704b8293..9eac9ce0 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c, - struct assembly_array_info *arr) - { - int raid_disks = arr->preexist_cnt + arr->new_cnt; -- char *status_msg = map_num(assemble_statuses, status); -+ char *status_msg = map_num_s(assemble_statuses, status); - - if (c->export && result) - *result |= status; -@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c, - fprintf(stderr, " (%d new)", arr->new_cnt); - if (arr->exp_cnt) - fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt); -- if (status_msg) -- fprintf(stderr, " %s", status_msg); -- fprintf(stderr, ".\n"); -+ fprintf(stderr, " %s.\n", status_msg); - } - - static int name_matches(char *found, char *required, char *homehost, int require_homehost) -diff --git a/Create.c b/Create.c -index 9ea19de0..c84c1ac8 100644 ---- a/Create.c -+++ b/Create.c -@@ -83,7 +83,7 @@ int default_layout(struct supertype *st, int level, int verbose) - - if (layout_map) { - layout = map_name(layout_map, "default"); -- layout_name = map_num(layout_map, layout); -+ layout_name = map_num_s(layout_map, layout); - } - if (layout_name && verbose > 0) - pr_err("layout defaults to %s\n", layout_name); -diff --git a/Detail.c b/Detail.c -index 95d4cc70..ce7a8445 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c) - if (array.state & (1 << MD_SB_CLEAN)) { - if ((array.level == 0) || - (array.level == LEVEL_LINEAR)) -- arrayst = map_num(sysfs_array_states, -- sra->array_state); -+ arrayst = map_num_s(sysfs_array_states, -+ sra->array_state); - else - arrayst = "clean"; - } else { -diff --git a/Grow.c b/Grow.c -index 18c5719b..8a242b0f 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -547,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && - s->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Operation not supported for consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 1; - } - -@@ -578,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - - if (sra->consistency_policy == (unsigned)s->consistency_policy) { - pr_err("Consistency policy is already %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC && - sra->consistency_policy != CONSISTENCY_POLICY_PPL) { - pr_err("Current consistency policy is %s, cannot change to %s\n", -- map_num(consistency_policies, sra->consistency_policy), -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, sra->consistency_policy), -+ map_num_s(consistency_policies, s->consistency_policy)); - ret = 1; - goto free_info; - } -@@ -704,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - ret = sysfs_set_str(sra, NULL, "consistency_policy", -- map_num(consistency_policies, -- s->consistency_policy)); -+ map_num_s(consistency_policies, -+ s->consistency_policy)); - if (ret) - pr_err("Failed to change array consistency policy\n"); - -@@ -2241,7 +2241,7 @@ size_change_error: - info.new_layout = UnSet; - if (info.array.level == 6 && info.new_level == UnSet) { - char l[40], *h; -- strcpy(l, map_num(r6layout, info.array.layout)); -+ strcpy(l, map_num_s(r6layout, info.array.layout)); - h = strrchr(l, '-'); - if (h && strcmp(h, "-6") == 0) { - *h = 0; -@@ -2266,7 +2266,7 @@ size_change_error: - info.new_layout = info.array.layout; - else if (info.array.level == 5 && info.new_level == 6) { - char l[40]; -- strcpy(l, map_num(r5layout, info.array.layout)); -+ strcpy(l, map_num_s(r5layout, info.array.layout)); - strcat(l, "-6"); - info.new_layout = map_name(r6layout, l); - } else { -diff --git a/Query.c b/Query.c -index 23fbf8aa..adcd231e 100644 ---- a/Query.c -+++ b/Query.c -@@ -93,7 +93,7 @@ int Query(char *dev) - else { - printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n", - dev, human_size_brief(larray_size,IEC), -- map_num(pers, level), raid_disks, -+ map_num_s(pers, level), raid_disks, - spare_disks, spare_disks == 1 ? "" : "s"); - } - st = guess_super(fd); -@@ -131,7 +131,7 @@ int Query(char *dev) - dev, - info.disk.number, info.array.raid_disks, - activity, -- map_num(pers, info.array.level), -+ map_num_s(pers, info.array.level), - mddev); - if (st->ss == &super0) - put_md_name(mddev); -diff --git a/maps.c b/maps.c -index a4fd2797..20fcf719 100644 ---- a/maps.c -+++ b/maps.c -@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = { - { NULL, ARRAY_UNKNOWN_STATE } - }; - -+/** -+ * map_num_s() - Safer alternative of map_num() function. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Shall be used only if key existence is quaranted. -+ * -+ * Return: Pointer to name of the element. -+ */ -+char *map_num_s(mapping_t *map, int num) -+{ -+ char *ret = map_num(map, num); -+ -+ assert(ret); -+ return ret; -+} -+ -+/** -+ * map_num() - get element name by key. -+ * @map: map to search. -+ * @num: key to match. -+ * -+ * Return: Pointer to name of the element or NULL. -+ */ - char *map_num(mapping_t *map, int num) - { - while (map->name) { -diff --git a/mdadm.c b/mdadm.c -index 26299b2e..be40686c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -280,8 +280,8 @@ int main(int argc, char *argv[]) - else - fprintf(stderr, "-%c", opt); - fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n", -- map_num(modes, newmode), -- map_num(modes, mode)); -+ map_num_s(modes, newmode), -+ map_num_s(modes, mode)); - exit(2); - } else if (!mode && newmode) { - mode = newmode; -@@ -544,7 +544,7 @@ int main(int argc, char *argv[]) - switch(s.level) { - default: - pr_err("layout not meaningful for %s arrays.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - case UnSet: - pr_err("raid level must be given before layout.\n"); -@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[]) - if (option_index > 0) - pr_err(":option --%s not valid in %s mode\n", - long_options[option_index].name, -- map_num(modes, mode)); -+ map_num_s(modes, mode)); - else - pr_err("option -%c not valid in %s mode\n", -- opt, map_num(modes, mode)); -+ opt, map_num_s(modes, mode)); - exit(2); - - } -@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[]) - if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--write-journal is not supported with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[]) - s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - if (s.level <= 0) { - pr_err("--consistency-policy not meaningful with level %s.\n", -- map_num(pers, s.level)); -+ map_num_s(pers, s.level)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL && - !s.journaldisks) { - pr_err("--write-journal is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.consistency_policy == CONSISTENCY_POLICY_PPL && - s.level != 5) { -@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[]) - (!s.bitmap_file || - strcmp(s.bitmap_file, "none") == 0)) { - pr_err("--bitmap is required for consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } else if (s.bitmap_file && - strcmp(s.bitmap_file, "none") != 0 && - s.consistency_policy != CONSISTENCY_POLICY_BITMAP && - s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { - pr_err("--bitmap is not compatible with consistency policy: %s\n", -- map_num(consistency_policies, s.consistency_policy)); -+ map_num_s(consistency_policies, s.consistency_policy)); - exit(2); - } - } -diff --git a/mdadm.h b/mdadm.h -index cd72e711..09915a00 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -770,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, - #endif - - #define SYSLOG_FACILITY LOG_DAEMON -- -+extern char *map_num_s(mapping_t *map, int num); - extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], -diff --git a/super-ddf.c b/super-ddf.c -index 3f304cdc..8cda23a7 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb) - printf("\n"); - printf(" unit[%d] : %d\n", i, be16_to_cpu(ve->unit)); - printf(" state[%d] : %s, %s%s\n", i, -- map_num(ddf_state, ve->state & 7), -+ map_num_s(ddf_state, ve->state & 7), - (ve->state & DDF_state_morphing) ? "Morphing, ": "", - (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent"); - printf(" init state[%d] : %s\n", i, -- map_num(ddf_init_state, ve->init_state&DDF_initstate_mask)); -+ map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask)); - printf(" access[%d] : %s\n", i, -- map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); -+ map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6)); - printf(" Name[%d] : %.16s\n", i, ve->name); - examine_vd(i, sb, ve->guid); - } -diff --git a/super-intel.c b/super-intel.c -index 6ff336ee..ba3bd41f 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, - free(dev); - free(dv); - pr_err("imsm does not support consistency policy %s\n", -- map_num(consistency_policies, s->consistency_policy)); -+ map_num_s(consistency_policies, s->consistency_policy)); - return 0; - } - -diff --git a/super0.c b/super0.c -index b79b97a9..61c9ec1d 100644 ---- a/super0.c -+++ b/super0.c -@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st) - { - mdp_super_t *sb = st->sb; - -- printf("MD_LEVEL=%s\n", map_num(pers, sb->level)); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level)); - printf("MD_DEVICES=%d\n", sb->raid_disks); - if (sb->minor_version >= 90) - printf("MD_UUID=%08x:%08x:%08x:%08x\n", -diff --git a/super1.c b/super1.c -index a12a5bc8..e3e2f954 100644 ---- a/super1.c -+++ b/super1.c -@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st) - int len = 32; - int layout; - -- printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level))); -+ printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level))); - printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks)); - for (i = 0; i < 32; i++) - if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { -diff --git a/sysfs.c b/sysfs.c -index 2995713d..0d98a65f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) - if (info->array.level < 0) - return 0; /* FIXME */ - rv |= sysfs_set_str(info, NULL, "level", -- map_num(pers, info->array.level)); -+ map_num_s(pers, info->array.level)); - if (info->reshape_active && info->delta_disks != UnSet) - raid_disks -= info->delta_disks; - rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks); -@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers) - } - - if (info->consistency_policy == CONSISTENCY_POLICY_PPL) { -- if (sysfs_set_str(info, NULL, "consistency_policy", -- map_num(consistency_policies, -- info->consistency_policy))) { -+ char *policy = map_num_s(consistency_policies, -+ info->consistency_policy); -+ -+ if (sysfs_set_str(info, NULL, "consistency_policy", policy)) { - pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n"); - info->consistency_policy = CONSISTENCY_POLICY_RESYNC; - } --- -2.38.1 - diff --git a/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch b/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch deleted file mode 100644 index 088b803..0000000 --- a/SOURCES/0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Tue, 15 Feb 2022 21:34:15 +0800 -Subject: [PATCH 012/125] mdadm/systemd: remove KillMode=none from service file - -For mdadm's systemd configuration, current systemd KillMode is "none" in -following service files, -- mdadm-grow-continue@.service -- mdmon@.service - -This "none" mode is strongly againsted by systemd developers (see man 5 -systemd.kill for "KillMode=" section), and is considering to remove in -future systemd version. - -As systemd developer explained in disuccsion, the systemd kill process -is, -1. send the signal specified by KillSignal= to the list of processes (if - any), TERM is the default -2. wait until either the target of process(es) exit or a timeout expires -3. if the timeout expires send the signal specified by FinalKillSignal=, - KILL is the default - -For "control-group", all remaining processes will receive the SIGTERM -signal (by default) and if there are still processes after a period f -time, they will get the SIGKILL signal. - -For "mixed", only the main process will receive the SIGTERM signal, and -if there are still processes after a period of time, all remaining -processes (including the main one) will receive the SIGKILL signal. - -From the above comment, currently KillMode=control-group is a proper -kill mode. Since control-gropu is the default kill mode, the fix can be -simply removing KillMode=none line from the service file, then the -default mode will take effect. - -Signed-off-by: Coly Li -Cc: Benjamin Brunner -Cc: Franck Bui -Cc: Jes Sorensen -Cc: Mariusz Tkaczyk -Cc: Neil Brown -Cc: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - systemd/mdmon@.service | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 5c667d2a..9fdc8ec7 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 85a3a7c5..77533958 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -25,4 +25,3 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none --- -2.38.1 - diff --git a/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch b/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch deleted file mode 100644 index 77324cf..0000000 --- a/SOURCES/0013-mdmon-Stop-parsing-duplicate-options.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 13 May 2022 09:19:42 +0200 -Subject: [PATCH 13/83] mdmon: Stop parsing duplicate options - -Introduce new function is_duplicate_opt() to check if given option -was already used and prevent setting it again along with an error -message. - -Move parsing above in_initrd() check to be able to detect --offroot -option duplicates. - -Now help option is executed after parsing to prevent executing commands -like: 'mdmon --help --ndlksnlksajndfjksndafasj'. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 44 +++++++++++++++++++++++++++++++++++--------- - 1 file changed, 35 insertions(+), 9 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 5570574b..c057da63 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -288,6 +288,15 @@ void usage(void) - exit(2); - } - -+static bool is_duplicate_opt(const int opt, const int set_val, const char *long_name) -+{ -+ if (opt == set_val) { -+ pr_err("--%s option duplicated!\n", long_name); -+ return true; -+ } -+ return false; -+} -+ - static int mdmon(char *devnm, int must_fork, int takeover); - - int main(int argc, char *argv[]) -@@ -299,6 +308,7 @@ int main(int argc, char *argv[]) - int all = 0; - int takeover = 0; - int dofork = 1; -+ bool help = false; - static struct option options[] = { - {"all", 0, NULL, 'a'}, - {"takeover", 0, NULL, 't'}, -@@ -308,37 +318,50 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -- if (in_initrd()) { -- /* -- * set first char of argv[0] to @. This is used by -- * systemd to signal that the task was launched from -- * initrd/initramfs and should be preserved during shutdown -- */ -- argv[0][0] = '@'; -- } -- - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -+ if (is_duplicate_opt(all, 1, "all")) -+ exit(1); - container_name = argv[optind-1]; - all = 1; - break; - case 't': -+ if (is_duplicate_opt(takeover, 1, "takeover")) -+ exit(1); - takeover = 1; - break; - case 'F': -+ if (is_duplicate_opt(dofork, 0, "foreground")) -+ exit(1); - dofork = 0; - break; - case OffRootOpt: -+ if (is_duplicate_opt(argv[0][0], '@', "offroot")) -+ exit(1); - argv[0][0] = '@'; - break; - case 'h': -+ if (is_duplicate_opt(help, true, "help")) -+ exit(1); -+ help = true; -+ break; - default: - usage(); - break; - } - } - -+ -+ if (in_initrd()) { -+ /* -+ * set first char of argv[0] to @. This is used by -+ * systemd to signal that the task was launched from -+ * initrd/initramfs and should be preserved during shutdown -+ */ -+ argv[0][0] = '@'; -+ } -+ - if (all == 0 && container_name == NULL) { - if (argv[optind]) - container_name = argv[optind]; -@@ -353,6 +376,9 @@ int main(int argc, char *argv[]) - if (strcmp(container_name, "/proc/mdstat") == 0) - all = 1; - -+ if (help) -+ usage(); -+ - if (all) { - struct mdstat_ent *mdstat, *e; - int container_len = strlen(container_name); --- -2.38.1 - diff --git a/SOURCES/0014-Grow-block-n-on-external-volumes.patch b/SOURCES/0014-Grow-block-n-on-external-volumes.patch deleted file mode 100644 index 4e6a874..0000000 --- a/SOURCES/0014-Grow-block-n-on-external-volumes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 19 May 2022 09:16:08 +0200 -Subject: [PATCH 14/83] Grow: block -n on external volumes. - -Performing --raid-devices on external metadata volume should be blocked -as it causes unwanted behaviour. - -Eg. Performing -mdadm -G /dev/md/volume -l10 -n4 -on r0_d2 inside 4 disk container, returns -mdadm: Need 2 spares to avoid degraded array, only have 0. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/Grow.c b/Grow.c -index 8a242b0f..f6efbc48 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1892,6 +1892,14 @@ int Grow_reshape(char *devname, int fd, - - if (retval) { - pr_err("Cannot read superblock for %s\n", devname); -+ close(cfd); -+ free(subarray); -+ return 1; -+ } -+ -+ if (s->raiddisks && subarray) { -+ pr_err("--raid-devices operation can be performed on a container only\n"); -+ close(cfd); - free(subarray); - return 1; - } --- -2.38.1 - diff --git a/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch b/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch deleted file mode 100644 index 51a9e0f..0000000 --- a/SOURCES/0015-Incremental-Fix-possible-memory-and-resource-leaks.patch +++ /dev/null @@ -1,90 +0,0 @@ -From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:11:25 +0200 -Subject: [PATCH 15/83] Incremental: Fix possible memory and resource leaks - -map allocated through map_by_uuid() is not freed if mdfd is invalid. -In addition mdfd is not closed, and mdinfo list is not freed too. - -Signed-off-by: Mateusz Grzonka -Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc -Signed-off-by: Jes Sorensen ---- - Incremental.c | 32 +++++++++++++++++++++++--------- - 1 file changed, 23 insertions(+), 9 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index a57fc323..4d0cd9d6 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1499,7 +1499,7 @@ static int Incremental_container(struct supertype *st, char *devname, - return 0; - } - for (ra = list ; ra ; ra = ra->next) { -- int mdfd; -+ int mdfd = -1; - char chosen_name[1024]; - struct map_ent *mp; - struct mddev_ident *match = NULL; -@@ -1514,6 +1514,12 @@ static int Incremental_container(struct supertype *st, char *devname, - - if (mp) { - mdfd = open_dev(mp->devnm); -+ if (!is_fd_valid(mdfd)) { -+ pr_err("failed to open %s: %s.\n", -+ mp->devnm, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - if (mp->path) - strcpy(chosen_name, mp->path); - else -@@ -1573,21 +1579,25 @@ static int Incremental_container(struct supertype *st, char *devname, - c->autof, - trustworthy, - chosen_name, 0); -+ -+ if (!is_fd_valid(mdfd)) { -+ pr_err("create_mddev failed with chosen name %s: %s.\n", -+ chosen_name, strerror(errno)); -+ rv = 2; -+ goto release; -+ } - } -- if (only && (!mp || strcmp(mp->devnm, only) != 0)) -- continue; - -- if (mdfd < 0) { -- pr_err("failed to open %s: %s.\n", -- chosen_name, strerror(errno)); -- return 2; -+ if (only && (!mp || strcmp(mp->devnm, only) != 0)) { -+ close_fd(&mdfd); -+ continue; - } - - assemble_container_content(st, mdfd, ra, c, - chosen_name, &result); - map_free(map); - map = NULL; -- close(mdfd); -+ close_fd(&mdfd); - } - if (c->export && result) { - char sep = '='; -@@ -1610,7 +1620,11 @@ static int Incremental_container(struct supertype *st, char *devname, - } - printf("\n"); - } -- return 0; -+ -+release: -+ map_free(map); -+ sysfs_free(list); -+ return rv; - } - - static void run_udisks(char *arg1, char *arg2) --- -2.38.1 - diff --git a/SOURCES/0016-Mdmonitor-Fix-segfault.patch b/SOURCES/0016-Mdmonitor-Fix-segfault.patch deleted file mode 100644 index 61c64ab..0000000 --- a/SOURCES/0016-Mdmonitor-Fix-segfault.patch +++ /dev/null @@ -1,98 +0,0 @@ -From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:12 +0200 -Subject: [PATCH 16/83] Mdmonitor: Fix segfault - -Mdadm with "--monitor" parameter requires md device -as an argument to be monitored. If given argument is -not a md device, error shall be returned. Previously -it was not checked and invalid argument caused -segmentation fault. This commit adds checking -that devices passed to mdmonitor are md devices. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 10 +++++++++- - mdadm.h | 1 + - mdopen.c | 17 +++++++++++++++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index c0ab5412..4e5802b5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -182,6 +182,7 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ - st = xcalloc(1, sizeof *st); - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); -@@ -190,6 +191,8 @@ int Monitor(struct mddev_dev *devlist, - strcpy(strcpy(st->devname, "/dev/md/"), - mdlist->devname); - } -+ if (!is_mddev(mdlist->devname)) -+ return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -203,7 +206,12 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_dev *dv; - - for (dv = devlist; dv; dv = dv->next) { -- struct state *st = xcalloc(1, sizeof *st); -+ struct state *st; -+ -+ if (!is_mddev(dv->devname)) -+ return 1; -+ -+ st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); - st->devname = xstrdup(dv->devname); - st->next = statelist; -diff --git a/mdadm.h b/mdadm.h -index 09915a00..d53df169 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1636,6 +1636,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy, - #define FOREIGN 2 - #define METADATA 3 - extern int open_mddev(char *dev, int report_errors); -+extern int is_mddev(char *dev); - extern int open_container(int fd); - extern int metadata_container_matches(char *metadata, char *devnm); - extern int metadata_subdev_matches(char *metadata, char *devnm); -diff --git a/mdopen.c b/mdopen.c -index 245be537..d18c9319 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -475,6 +475,23 @@ int open_mddev(char *dev, int report_errors) - return mdfd; - } - -+/** -+ * is_mddev() - check that file name passed is an md device. -+ * @dev: file name that has to be checked. -+ * Return: 1 if file passed is an md device, 0 if not. -+ */ -+int is_mddev(char *dev) -+{ -+ int fd = open_mddev(dev, 1); -+ -+ if (fd >= 0) { -+ close(fd); -+ return 1; -+ } -+ -+ return 0; -+} -+ - char *find_free_devnm(int use_partitions) - { - static char devnm[32]; --- -2.38.1 - diff --git a/SOURCES/0017-Mdmonitor-Improve-logging-method.patch b/SOURCES/0017-Mdmonitor-Improve-logging-method.patch deleted file mode 100644 index 3c7eed2..0000000 --- a/SOURCES/0017-Mdmonitor-Improve-logging-method.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Mon, 6 Jun 2022 12:32:13 +0200 -Subject: [PATCH 17/83] Mdmonitor: Improve logging method - -Change logging, and as a result, mdmonitor in verbose -mode will report its configuration. - -Signed-off-by: Kinga Tanska -Signed-off-by: Oleksandr Shchirskyi -Signed-off-by: Jes Sorensen ---- - Monitor.c | 25 ++++++++++++++----------- - 1 file changed, 14 insertions(+), 11 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 4e5802b5..6ca1ebe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -136,24 +136,27 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -- if (!mailaddr) { -+ if (!mailaddr) - mailaddr = conf_get_mailaddr(); -- if (mailaddr && ! c->scan) -- pr_err("Monitor using email address \"%s\" from config file\n", -- mailaddr); -- } -- mailfrom = conf_get_mailfrom(); - -- if (!alert_cmd) { -+ if (!alert_cmd) - alert_cmd = conf_get_program(); -- if (alert_cmd && !c->scan) -- pr_err("Monitor using program \"%s\" from config file\n", -- alert_cmd); -- } -+ -+ mailfrom = conf_get_mailfrom(); -+ - if (c->scan && !mailaddr && !alert_cmd && !dosyslog) { - pr_err("No mail address or alert command - not monitoring.\n"); - return 1; - } -+ -+ if (c->verbose) { -+ pr_err("Monitor is started with delay %ds\n", c->delay); -+ if (mailaddr) -+ pr_err("Monitor using email address %s\n", mailaddr); -+ if (alert_cmd) -+ pr_err("Monitor using program %s\n", alert_cmd); -+ } -+ - info.alert_cmd = alert_cmd; - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; --- -2.38.1 - diff --git a/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch b/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch deleted file mode 100644 index 24db49f..0000000 --- a/SOURCES/0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 11:59:34 +0200 -Subject: [PATCH 18/83] Fix possible NULL ptr dereferences and memory leaks - -In Assemble there was a NULL check for sra variable, -which effectively didn't stop the execution in every case. -That might have resulted in a NULL pointer dereference. - -Also in super-ddf, mu variable was set to NULL for some condition, -and then immidiately dereferenced. -Additionally some memory wasn't freed as well. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 ++++++- - super-ddf.c | 9 +++++++-- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 9eac9ce0..4b213560 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1982,7 +1982,12 @@ int assemble_container_content(struct supertype *st, int mdfd, - } - - sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); -- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { -+ if (sra == NULL) { -+ pr_err("Failed to read sysfs parameters\n"); -+ return 1; -+ } -+ -+ if (strcmp(sra->text_version, content->text_version) != 0) { - if (content->array.major_version == -1 && - content->array.minor_version == -2 && - c->readonly && -diff --git a/super-ddf.c b/super-ddf.c -index 8cda23a7..abbc8b09 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -5125,13 +5125,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - */ - vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk, - &n_bvd, &vcl); -- if (vc == NULL) -+ if (vc == NULL) { -+ free(rv); - return NULL; -+ } - - mu = xmalloc(sizeof(*mu)); - if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) { - free(mu); -- mu = NULL; -+ free(rv); -+ return NULL; - } - - mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count; -@@ -5161,6 +5164,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, - pr_err("BUG: can't find disk %d (%d/%d)\n", - di->disk.raid_disk, - di->disk.major, di->disk.minor); -+ free(mu); -+ free(rv); - return NULL; - } - vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum; --- -2.38.1 - diff --git a/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch b/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch deleted file mode 100644 index 12dd070..0000000 --- a/SOURCES/0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 13 Jun 2022 12:00:09 +0200 -Subject: [PATCH 19/83] imsm: Remove possibility for get_imsm_dev to return - NULL - -Returning NULL from get_imsm_dev or __get_imsm_dev will cause segfault. -Guarantee that it never happens. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - super-intel.c | 153 +++++++++++++++++++++++++------------------------- - 1 file changed, 78 insertions(+), 75 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index ba3bd41f..3788feb9 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -851,6 +851,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update) - return inf; - } - -+/** -+ * __get_imsm_dev() - Get device with index from imsm_super. -+ * @mpb: &imsm_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - { - int offset; -@@ -858,30 +873,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) - void *_mpb = mpb; - - if (index >= mpb->num_raid_devs) -- return NULL; -+ goto error; - - /* devices start after all disks */ - offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb; - -- for (i = 0; i <= index; i++) -+ for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0)) - if (i == index) - return _mpb + offset; -- else -- offset += sizeof_imsm_dev(_mpb + offset, 0); -- -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in imsm_super\n", index); -+ abort(); - } - -+/** -+ * get_imsm_dev() - Get device with index from intel_super. -+ * @super: &intel_super pointer, not NULL. -+ * @index: Device index. -+ * -+ * Function works as non-NULL, aborting in such a case, -+ * when NULL would be returned. -+ * -+ * Device index should be in range 0 up to num_raid_devs. -+ * Function assumes the index was already verified. -+ * Index must be valid, otherwise abort() is called. -+ * -+ * Return: Pointer to corresponding imsm_dev. -+ * -+ */ - static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index) - { - struct intel_dev *dv; - - if (index >= super->anchor->num_raid_devs) -- return NULL; -+ goto error; -+ - for (dv = super->devlist; dv; dv = dv->next) - if (dv->index == index) - return dv->dev; -- return NULL; -+error: -+ pr_err("cannot find imsm_dev with index %u in intel_super\n", index); -+ abort(); - } - - static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr -@@ -4364,8 +4396,7 @@ int check_mpb_migr_compatibility(struct intel_super *super) - for (i = 0; i < super->anchor->num_raid_devs; i++) { - struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i); - -- if (dev_iter && -- dev_iter->vol.migr_state == 1 && -+ if (dev_iter->vol.migr_state == 1 && - dev_iter->vol.migr_type == MIGR_GEN_MIGR) { - /* This device is migrating */ - map0 = get_imsm_map(dev_iter, MAP_0); -@@ -4514,8 +4545,6 @@ static void clear_hi(struct intel_super *super) - } - for (i = 0; i < mpb->num_raid_devs; ++i) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- if (!dev) -- return; - for (n = 0; n < 2; ++n) { - struct imsm_map *map = get_imsm_map(dev, n); - if (!map) -@@ -5836,7 +5865,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_dev *_dev = __get_imsm_dev(mpb, 0); - - _disk = __get_imsm_disk(mpb, dl->index); -- if (!_dev || !_disk) { -+ if (!_disk) { - pr_err("BUG mpb setup error\n"); - return 1; - } -@@ -6171,10 +6200,10 @@ static int write_super_imsm(struct supertype *st, int doclose) - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = __get_imsm_dev(mpb, i); - struct imsm_dev *dev2 = get_imsm_dev(super, i); -- if (dev && dev2) { -- imsm_copy_dev(dev, dev2); -- mpb_size += sizeof_imsm_dev(dev, 0); -- } -+ -+ imsm_copy_dev(dev, dev2); -+ mpb_size += sizeof_imsm_dev(dev, 0); -+ - if (is_gen_migration(dev2)) - clear_migration_record = 0; - } -@@ -9033,29 +9062,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed) - __u8 state; - - dev2 = get_imsm_dev(cont->sb, dev_idx); -- if (dev2) { -- state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -- if (state == IMSM_T_STATE_FAILED) { -- map = get_imsm_map(dev2, MAP_0); -- if (!map) -- return 1; -- for (slot = 0; slot < map->num_members; slot++) { -- /* -- * Check if failed disks are deleted from intel -- * disk list or are marked to be deleted -- */ -- idx = get_imsm_disk_idx(dev2, slot, MAP_X); -- idisk = get_imsm_dl_disk(cont->sb, idx); -- /* -- * Do not rebuild the array if failed disks -- * from failed sub-array are not removed from -- * container. -- */ -- if (idisk && -- is_failed(&idisk->disk) && -- (idisk->action != DISK_REMOVE)) -- return 0; -- } -+ -+ state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0); -+ if (state == IMSM_T_STATE_FAILED) { -+ map = get_imsm_map(dev2, MAP_0); -+ for (slot = 0; slot < map->num_members; slot++) { -+ /* -+ * Check if failed disks are deleted from intel -+ * disk list or are marked to be deleted -+ */ -+ idx = get_imsm_disk_idx(dev2, slot, MAP_X); -+ idisk = get_imsm_dl_disk(cont->sb, idx); -+ /* -+ * Do not rebuild the array if failed disks -+ * from failed sub-array are not removed from -+ * container. -+ */ -+ if (idisk && -+ is_failed(&idisk->disk) && -+ (idisk->action != DISK_REMOVE)) -+ return 0; - } - } - return 1; -@@ -10089,7 +10115,6 @@ static void imsm_process_update(struct supertype *st, - int victim = u->dev_idx; - struct active_array *a; - struct intel_dev **dp; -- struct imsm_dev *dev; - - /* sanity check that we are not affecting the uuid of - * active arrays, or deleting an active array -@@ -10105,8 +10130,7 @@ static void imsm_process_update(struct supertype *st, - * is active in the container, so checking - * mpb->num_raid_devs is just extra paranoia - */ -- dev = get_imsm_dev(super, victim); -- if (a || !dev || mpb->num_raid_devs == 1) { -+ if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) { - dprintf("failed to delete subarray-%d\n", victim); - break; - } -@@ -10140,7 +10164,7 @@ static void imsm_process_update(struct supertype *st, - if (a->info.container_member == target) - break; - dev = get_imsm_dev(super, u->dev_idx); -- if (a || !dev || !check_name(super, name, 1)) { -+ if (a || !check_name(super, name, 1)) { - dprintf("failed to rename subarray-%d\n", target); - break; - } -@@ -10169,10 +10193,6 @@ static void imsm_process_update(struct supertype *st, - struct imsm_update_rwh_policy *u = (void *)update->buf; - int target = u->dev_idx; - struct imsm_dev *dev = get_imsm_dev(super, target); -- if (!dev) { -- dprintf("could not find subarray-%d\n", target); -- break; -- } - - if (dev->rwh_policy != u->new_policy) { - dev->rwh_policy = u->new_policy; -@@ -11397,8 +11417,10 @@ static int imsm_create_metadata_update_for_migration( - { - struct intel_super *super = st->sb; - int update_memory_size; -+ int current_chunk_size; - struct imsm_update_reshape_migration *u; -- struct imsm_dev *dev; -+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); - int previous_level = -1; - - dprintf("(enter) New Level = %i\n", geo->level); -@@ -11415,23 +11437,15 @@ static int imsm_create_metadata_update_for_migration( - u->new_disks[0] = -1; - u->new_chunksize = -1; - -- dev = get_imsm_dev(super, u->subdev); -- if (dev) { -- struct imsm_map *map; -+ current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2; - -- map = get_imsm_map(dev, MAP_0); -- if (map) { -- int current_chunk_size = -- __le16_to_cpu(map->blocks_per_strip) / 2; -- -- if (geo->chunksize != current_chunk_size) { -- u->new_chunksize = geo->chunksize / 1024; -- dprintf("imsm: chunk size change from %i to %i\n", -- current_chunk_size, u->new_chunksize); -- } -- previous_level = map->raid_level; -- } -+ if (geo->chunksize != current_chunk_size) { -+ u->new_chunksize = geo->chunksize / 1024; -+ dprintf("imsm: chunk size change from %i to %i\n", -+ current_chunk_size, u->new_chunksize); - } -+ previous_level = map->raid_level; -+ - if (geo->level == 5 && previous_level == 0) { - struct mdinfo *spares = NULL; - -@@ -12519,9 +12533,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st) - unsigned long long offset; - struct dl *d; - -- if (!dev) -- return -1; -- - if (dev->rwh_policy != RWH_BITMAP) - return 0; - -@@ -12567,16 +12578,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp, - return -1; - - dev = get_imsm_dev(super, vol_idx); -- -- if (!dev) { -- dprintf("cannot find the device for volume index %d\n", -- vol_idx); -- return -1; -- } - dev->rwh_policy = RWH_BITMAP; -- - *chunkp = calculate_bitmap_chunksize(st, dev); -- - return 0; - } - --- -2.38.1 - diff --git a/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch b/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch deleted file mode 100644 index f51c730..0000000 --- a/SOURCES/0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001 -From: Nigel Croxon -Date: Mon, 18 Apr 2022 13:44:23 -0400 -Subject: [PATCH 20/83] Revert "mdadm: fix coredump of mdadm --monitor -r" - -This reverts commit 546047688e1c64638f462147c755b58119cabdc8. - -The change from commit mdadm: fix coredump of mdadm ---monitor -r broke the printing of the return message when -passing -r to mdadm --manage, the removal of a device from -an array. - -If the current code reverts this commit, both issues are -still fixed. - -The original problem reported that the fix tried to address -was: The --monitor -r option requires a parameter, -otherwise a null pointer will be manipulated when -converting to integer data, and a core dump will appear. - -The original problem was really fixed with: -60815698c0a Refactor parse_num and use it to parse optarg. -Which added a check for NULL in 'optarg' before moving it -to the 'increments' variable. - -New issue: When trying to remove a device using the short -argument -r, instead of the long argument --remove, the -output is empty. The problem started when commit -546047688e1c was added. - -Steps to Reproduce: -1. create/assemble /dev/md0 device -2. mdadm --manage /dev/md0 -r /dev/vdxx - -Actual results: -Nothing, empty output, nothing happens, the device is still -connected to the array. - -The output should have stated "mdadm: hot remove failed -for /dev/vdxx: Device or resource busy", if the device was -still active. Or it should remove the device and print -a message: - -mdadm: set /dev/vdd faulty in /dev/md0 -mdadm: hot removed /dev/vdd from /dev/md0 - -The following commit should be reverted as it breaks -mdadm --manage -r. - -commit 546047688e1c64638f462147c755b58119cabdc8 -Author: Wu Guanghao -Date: Mon Aug 16 15:24:51 2021 +0800 -mdadm: fix coredump of mdadm --monitor -r - --Nigel - -Signed-off-by: Nigel Croxon -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 8f873c48..bec1be9a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -81,11 +81,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - * found, it is started. - */ - --char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k"; -+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; -+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:"; - - struct option long_options[] = { - {"manage", 0, 0, ManageOpt}, --- -2.38.1 - diff --git a/SOURCES/0021-util-replace-ioctl-use-with-function.patch b/SOURCES/0021-util-replace-ioctl-use-with-function.patch deleted file mode 100644 index 56ee5e8..0000000 --- a/SOURCES/0021-util-replace-ioctl-use-with-function.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 21 Jun 2022 00:10:39 +0800 -Subject: [PATCH 21/83] util: replace ioctl use with function - -Replace using of ioctl calling to get md array info with -special function prepared to it. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util.c b/util.c -index cc94f96e..38f0420e 100644 ---- a/util.c -+++ b/util.c -@@ -267,7 +267,7 @@ int md_array_active(int fd) - * GET_ARRAY_INFO doesn't provide access to the proper state - * information, so fallback to a basic check for raid_disks != 0 - */ -- ret = ioctl(fd, GET_ARRAY_INFO, &array); -+ ret = md_get_array_info(fd, &array); - } - - return !ret; --- -2.38.1 - diff --git a/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch b/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch deleted file mode 100644 index 88bba83..0000000 --- a/SOURCES/0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Tue, 21 Jun 2022 00:10:40 +0800 -Subject: [PATCH 22/83] mdadm/super1: restore commit 45a87c2f31335 to fix - clustered slot issue - -Commit 9d67f6496c71 ("mdadm:check the nodes when operate clustered -array") modified assignment logic for st->nodes in write_bitmap1(), -which introduced bitmap slot issue: - -load_super1 didn't set up supertype.nodes, which made spare disk only -have one slot info. Then it triggered kernel md_bitmap_load_sb to get -wrong bitmap slot data. - -For fixing this issue, there are two methods: - -1> revert the related code of commit 9d67f6496c71. and restore the code - from former commit 45a87c2f31335 ("super1: add more checks for - NodeNumUpdate option"). - st->nodes value would be 0 & 1 under current code logic. i.e. - When adding a spare disk, there is no place to init st->nodes, and - the value is ZERO. - -2> keep 9d67f6496c71, add additional ->nodes handling in load_super1(), - let load_super1 to set st->nodes when bitmap is BITMAP_MAJOR_CLUSTERED. - Under current mdadm code logic, load_super1 will be called many - times, any new code in load_super1 will cost mdadm running more time. - And more reason is I prefer as much as possible to limit clustered - code spreading in every corner. - -So I used method <1> to fix this issue. - -How to trigger: - -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb -dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdc -mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb -mdadm -a /dev/md0 /dev/sdc -mdadm /dev/md0 --fail /dev/sda -mdadm /dev/md0 --remove /dev/sda -mdadm -Ss -mdadm -A /dev/md0 /dev/sdb /dev/sdc - -the output of current "mdadm -X /dev/sdc": -(there should be (by default) 4 slot info for correct output) -``` - Filename : /dev/sdc - Magic : 6d746962 - Version : 5 - UUID : a74642f8:a6b1fba8:58e1f8db:cfe7b082 - Events : 29 - Events Cleared : 0 - State : OK - Chunksize : 64 MB - Daemon : 5s flush period - Write Mode : Normal - Sync Size : 306176 (299.00 MiB 313.52 MB) - Bitmap : 5 bits (chunks), 5 dirty (100.0%) -``` - -And mdadm later operations will trigger kernel output error message: -(triggered by "mdadm -A /dev/md0 /dev/sdb /dev/sdc") -``` -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 1 -kernel: md-cluster: Could not gather bitmaps from slot 1 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2 -kernel: md-cluster: Could not gather bitmaps from slot 2 -kernel: md0: invalid bitmap file superblock: bad magic -kernel: md_bitmap_copy_from_slot can't get bitmap from slot 3 -kernel: md-cluster: Could not gather bitmaps from slot 3 -kernel: md-cluster: failed to gather all resyn infos -kernel: md0: detected capacity change from 0 to 612352 -``` - -Acked-by: Coly Li -Signed-off-by: Heming Zhao -Signed-off-by: Jes Sorensen ---- - super1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/super1.c b/super1.c -index e3e2f954..3a0c69fd 100644 ---- a/super1.c -+++ b/super1.c -@@ -2674,7 +2674,17 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update - } - - if (bms->version == BITMAP_MAJOR_CLUSTERED) { -- if (__cpu_to_le32(st->nodes) < bms->nodes) { -+ if (st->nodes == 1) { -+ /* the parameter for nodes is not valid */ -+ pr_err("Warning: cluster-md at least needs two nodes\n"); -+ return -EINVAL; -+ } else if (st->nodes == 0) { -+ /* -+ * parameter "--nodes" is not specified, (eg, add a disk to -+ * clustered raid) -+ */ -+ break; -+ } else if (__cpu_to_le32(st->nodes) < bms->nodes) { - /* - * Since the nodes num is not increased, no - * need to check the space enough or not, --- -2.38.1 - diff --git a/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch b/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch deleted file mode 100644 index ca1d015..0000000 --- a/SOURCES/0023-imsm-introduce-get_disk_slot_in_dev.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:41 +0800 -Subject: [PATCH 23/83] imsm: introduce get_disk_slot_in_dev() - -The routine was added to remove unnecessary get_imsm_dev() and -get_imsm_map() calls, used only to determine disk slot. - -Additionally, enum for IMSM return statues was added for further usage. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 47 ++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 36 insertions(+), 11 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 3788feb9..cd1f1e3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -366,6 +366,18 @@ struct migr_record { - }; - ASSERT_SIZE(migr_record, 128) - -+/** -+ * enum imsm_status - internal IMSM return values representation. -+ * @STATUS_OK: function succeeded. -+ * @STATUS_ERROR: General error ocurred (not specified). -+ * -+ * Typedefed to imsm_status_t. -+ */ -+typedef enum imsm_status { -+ IMSM_STATUS_ERROR = -1, -+ IMSM_STATUS_OK = 0, -+} imsm_status_t; -+ - struct md_list { - /* usage marker: - * 1: load metadata -@@ -1183,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord) - map->disk_ord_tbl[slot] = __cpu_to_le32(ord); - } - --static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) -+static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx) - { - int slot; - __u32 ord; -@@ -1194,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx) - return slot; - } - -- return -1; -+ return IMSM_STATUS_ERROR; - } - - static int get_imsm_raid_level(struct imsm_map *map) -@@ -1209,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map) - return map->raid_level; - } - -+/** -+ * get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev. -+ * @super: &intel_super pointer, not NULL. -+ * @dev_idx: imsm device index. -+ * @idx: disk index. -+ * -+ * Return: Slot on success, IMSM_STATUS_ERROR otherwise. -+ */ -+static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx, -+ const unsigned int idx) -+{ -+ struct imsm_dev *dev = get_imsm_dev(super, dev_idx); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); -+ -+ return get_imsm_disk_slot(map, idx); -+} -+ - static int cmp_extent(const void *av, const void *bv) - { - const struct extent *a = av; -@@ -1225,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super) - int memberships = 0; - int i; - -- for (i = 0; i < super->anchor->num_raid_devs; i++) { -- struct imsm_dev *dev = get_imsm_dev(super, i); -- struct imsm_map *map = get_imsm_map(dev, MAP_0); -- -- if (get_imsm_disk_slot(map, dl->index) >= 0) -+ for (i = 0; i < super->anchor->num_raid_devs; i++) -+ if (get_disk_slot_in_dev(super, i, dl->index) >= 0) - memberships++; -- } - - return memberships; - } -@@ -1941,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super) - - /* first map under migration */ - map = get_imsm_map(dev, MAP_0); -+ - if (map) - slot = get_imsm_disk_slot(map, super->disks->index); - if (map == NULL || slot > 1 || slot < 0) { -@@ -9655,10 +9681,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u, - /* count arrays using the victim in the metadata */ - found = 0; - for (a = active_array; a ; a = a->next) { -- dev = get_imsm_dev(super, a->info.container_member); -- map = get_imsm_map(dev, MAP_0); -+ int dev_idx = a->info.container_member; - -- if (get_imsm_disk_slot(map, victim) >= 0) -+ if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0) - found++; - } - --- -2.38.1 - diff --git a/SOURCES/0024-imsm-use-same-slot-across-container.patch b/SOURCES/0024-imsm-use-same-slot-across-container.patch deleted file mode 100644 index dc23b3c..0000000 --- a/SOURCES/0024-imsm-use-same-slot-across-container.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:42 +0800 -Subject: [PATCH 24/83] imsm: use same slot across container - -Autolayout relies on drives order on super->disks list, but -it is not quaranted by readdir() in sysfs_read(). As a result -drive could be put in different slot in second volume. - -Make it consistent by reffering to first volume, if exists. - -Use enum imsm_status to unify error handling. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 169 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 108 insertions(+), 61 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index cd1f1e3d..deef7c87 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7522,11 +7522,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 1; - } - --static int imsm_get_free_size(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * imsm_get_free_size() - get the biggest, common free space from members. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. -+ * -+ * @freesize is set to meaningful value, this can be @size, or calculated -+ * max free size. -+ * super->create_offset value is modified and set appropriately in -+ * merge_extends() for further creation. -+ */ -+static imsm_status_t imsm_get_free_size(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, -+ const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - struct dl *dl; - int i; -@@ -7570,12 +7586,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - /* chunk is in K */ - minsize = chunk * 2; - -- if (cnt < raiddisks || -- (super->orom && used && used != raiddisks) || -- maxsize < minsize || -- maxsize == 0) { -+ if (cnt < raiddisks || (super->orom && used && used != raiddisks) || -+ maxsize < minsize || maxsize == 0) { - pr_err("not enough devices with space to create array.\n"); -- return 0; /* No enough free spaces large enough */ -+ return IMSM_STATUS_ERROR; - } - - if (size == 0) { -@@ -7588,37 +7602,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, - } - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- - *freesize = size; - - dprintf("imsm: imsm_get_free_size() returns : %llu\n", size); - -- return 1; -+ return IMSM_STATUS_OK; - } - --static int reserve_space(struct supertype *st, int raiddisks, -- unsigned long long size, int chunk, -- unsigned long long *freesize) -+/** -+ * autolayout_imsm() - automatically layout a new volume. -+ * @super: &intel_super pointer, not NULL. -+ * @raiddisks: number of raid disks. -+ * @size: requested size, could be 0 (means max size). -+ * @chunk: requested chunk. -+ * @freesize: pointer for returned size value. -+ * -+ * We are being asked to automatically layout a new volume based on the current -+ * contents of the container. If the parameters can be satisfied autolayout_imsm -+ * will record the disks, start offset, and will return size of the volume to -+ * be created. See imsm_get_free_size() for details. -+ * add_to_super() and getinfo_super() detect when autolayout is in progress. -+ * If first volume exists, slots are set consistently to it. -+ * -+ * Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise. -+ * -+ * Disks are marked for creation via dl->raiddisk. -+ */ -+static imsm_status_t autolayout_imsm(struct intel_super *super, -+ const int raiddisks, -+ unsigned long long size, const int chunk, -+ unsigned long long *freesize) - { -- struct intel_super *super = st->sb; -- struct dl *dl; -- int cnt; -- int rv = 0; -+ int curr_slot = 0; -+ struct dl *disk; -+ int vol_cnt = super->anchor->num_raid_devs; -+ imsm_status_t rv; - -- rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize); -- if (rv) { -- cnt = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- dl->raiddisk = cnt++; -- rv = 1; -+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); -+ if (rv != IMSM_STATUS_OK) -+ return IMSM_STATUS_ERROR; -+ -+ for (disk = super->disks; disk; disk = disk->next) { -+ if (!disk->e) -+ continue; -+ -+ if (curr_slot == raiddisks) -+ break; -+ -+ if (vol_cnt == 0) { -+ disk->raiddisk = curr_slot; -+ } else { -+ int _slot = get_disk_slot_in_dev(super, 0, disk->index); -+ -+ if (_slot == -1) { -+ pr_err("Disk %s is not used in first volume, aborting\n", -+ disk->devname); -+ return IMSM_STATUS_ERROR; -+ } -+ disk->raiddisk = _slot; -+ } -+ curr_slot++; - } - -- return rv; -+ return IMSM_STATUS_OK; - } - - static int validate_geometry_imsm(struct supertype *st, int level, int layout, -@@ -7654,35 +7700,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - } - - if (!dev) { -- if (st->sb) { -- struct intel_super *super = st->sb; -- if (!validate_geometry_imsm_orom(st->sb, level, layout, -- raiddisks, chunk, size, -- verbose)) -+ struct intel_super *super = st->sb; -+ -+ /* -+ * Autolayout mode, st->sb and freesize must be set. -+ */ -+ if (!super || !freesize) { -+ pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -+ return 1; -+ } -+ -+ if (!validate_geometry_imsm_orom(st->sb, level, layout, -+ raiddisks, chunk, size, -+ verbose)) -+ return 0; -+ -+ if (super->orom) { -+ imsm_status_t rv; -+ int count = count_volumes(super->hba, super->orom->dpa, -+ verbose); -+ if (super->orom->vphba <= count) { -+ pr_vrb("platform does not support more than %d raid volumes.\n", -+ super->orom->vphba); - return 0; -- /* we are being asked to automatically layout a -- * new volume based on the current contents of -- * the container. If the the parameters can be -- * satisfied reserve_space will record the disks, -- * start offset, and size of the volume to be -- * created. add_to_super and getinfo_super -- * detect when autolayout is in progress. -- */ -- /* assuming that freesize is always given when array is -- created */ -- if (super->orom && freesize) { -- int count; -- count = count_volumes(super->hba, -- super->orom->dpa, verbose); -- if (super->orom->vphba <= count) { -- pr_vrb("platform does not support more than %d raid volumes.\n", -- super->orom->vphba); -- return 0; -- } - } -- if (freesize) -- return reserve_space(st, raiddisks, size, -- *chunk, freesize); -+ -+ rv = autolayout_imsm(super, raiddisks, size, *chunk, -+ freesize); -+ if (rv != IMSM_STATUS_OK) -+ return 0; - } - return 1; - } -@@ -11538,7 +11584,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - unsigned long long current_size; - unsigned long long free_size; - unsigned long long max_size; -- int rv; -+ imsm_status_t rv; - - getinfo_super_imsm_volume(st, &info, NULL); - if (geo->level != info.array.level && geo->level >= 0 && -@@ -11657,9 +11703,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - } - /* check the maximum available size - */ -- rv = imsm_get_free_size(st, dev->vol.map->num_members, -- 0, chunk, &free_size); -- if (rv == 0) -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, -+ 0, chunk, &free_size); -+ -+ if (rv != IMSM_STATUS_OK) - /* Cannot find maximum available space - */ - max_size = 0; --- -2.38.1 - diff --git a/SOURCES/0025-imsm-block-changing-slots-during-creation.patch b/SOURCES/0025-imsm-block-changing-slots-during-creation.patch deleted file mode 100644 index 4c3b918..0000000 --- a/SOURCES/0025-imsm-block-changing-slots-during-creation.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 21 Jun 2022 00:10:43 +0800 -Subject: [PATCH 25/83] imsm: block changing slots during creation - -If user specifies drives for array creation, then slot order across -volumes is not preserved. -Ideally, it should be checked in validate_geometry() but it is not -possible in current implementation (order is determined later). -Add verification in add_to_super_imsm_volume() and throw error if -mismatch is detected. -IMSM allows to use only same members within container. -This is not hardware dependency but metadata limitation. -Therefore, 09-imsm-overlap test is removed. Testing it is pointless. -After this patch, creation in this scenario is blocked. Offset -verification is covered in other tests. - -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 33 ++++++++++++++++++++++----------- - tests/09imsm-overlap | 28 ---------------------------- - 2 files changed, 22 insertions(+), 39 deletions(-) - delete mode 100644 tests/09imsm-overlap - -diff --git a/super-intel.c b/super-intel.c -index deef7c87..8ffe485c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - struct imsm_map *map; - struct dl *dl, *df; - int slot; -+ int autolayout = 0; -+ -+ if (!is_fd_valid(fd)) -+ autolayout = 1; - - dev = get_imsm_dev(super, super->current_vol); - map = get_imsm_map(dev, MAP_0); -@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - return 1; - } - -- if (!is_fd_valid(fd)) { -- /* we're doing autolayout so grab the pre-marked (in -- * validate_geometry) raid_disk -- */ -- for (dl = super->disks; dl; dl = dl->next) -+ for (dl = super->disks; dl ; dl = dl->next) { -+ if (autolayout) { - if (dl->raiddisk == dk->raid_disk) - break; -- } else { -- for (dl = super->disks; dl ; dl = dl->next) -- if (dl->major == dk->major && -- dl->minor == dk->minor) -- break; -+ } else if (dl->major == dk->major && dl->minor == dk->minor) -+ break; - } - - if (!dl) { -- pr_err("%s is not a member of the same container\n", devname); -+ if (!autolayout) -+ pr_err("%s is not a member of the same container.\n", -+ devname); - return 1; - } - -+ if (!autolayout && super->current_vol > 0) { -+ int _slot = get_disk_slot_in_dev(super, 0, dl->index); -+ -+ if (_slot != dk->raid_disk) { -+ pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n", -+ dl->devname, _slot, dk->raid_disk); -+ pr_err("Raid members are in different order than for the first volume, aborting.\n"); -+ return 1; -+ } -+ } -+ - if (mpb->num_disks == 0) - if (!get_dev_sector_size(dl->fd, dl->devname, - &super->sector_size)) -diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap -deleted file mode 100644 -index ff5d2093..00000000 ---- a/tests/09imsm-overlap -+++ /dev/null -@@ -1,28 +0,0 @@ -- --. tests/env-imsm-template -- --# create raid arrays with varying degress of overlap --mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5 --imsm_check container 6 -- --size=1024 --level=1 --num_disks=2 --mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size --mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size --mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size --mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size --mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size -- --udevadm settle -- --offset=0 --imsm_check member $member0 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member1 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member2 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member3 $num_disks $level $size 1024 $offset --offset=$((offset+size+4096)) --imsm_check member $member4 $num_disks $level $size 1024 $offset --- -2.38.1 - diff --git a/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch b/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch deleted file mode 100644 index d593669..0000000 --- a/SOURCES/0026-mdadm-block-update-ppl-for-non-raid456-levels.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Wed, 15 Jun 2022 14:28:39 +0200 -Subject: [PATCH 26/83] mdadm: block update=ppl for non raid456 levels - -Option ppl should be used only for raid levels 4, 5 and 6. Cancel update -for other levels. - -Applied globally for imsm and ddf format. - -Additionally introduce is_level456() helper function. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 11 +++++------ - Grow.c | 2 +- - Manage.c | 14 ++++++++++++-- - mdadm.h | 11 +++++++++++ - super0.c | 2 +- - super1.c | 3 +-- - 6 files changed, 31 insertions(+), 12 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 4b213560..6df6bfbc 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content, - * devices in RAID4 or last devices in RAID4/5/6. - */ - delta = devices[j].i.delta_disks; -- if (devices[j].i.array.level >= 4 && -- devices[j].i.array.level <= 6 && -+ if (is_level456(devices[j].i.array.level) && - i/2 >= content->array.raid_disks - delta) - /* OK */; - else if (devices[j].i.array.level == 4 && -@@ -1226,8 +1225,7 @@ static int start_array(int mdfd, - fprintf(stderr, ".\n"); - } - if (content->reshape_active && -- content->array.level >= 4 && -- content->array.level <= 6) { -+ is_level456(content->array.level)) { - /* might need to increase the size - * of the stripe cache - default is 256 - */ -@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd, - int start_reshape; - char *avail; - int err; -- int is_raid456, is_clean, all_disks; -+ int is_clean, all_disks; -+ bool is_raid456; - - if (sysfs_init(content, mdfd, NULL)) { - pr_err("Unable to initialize sysfs\n"); -@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd, - content->array.state |= 1; - } - -- is_raid456 = (content->array.level >= 4 && content->array.level <= 6); -+ is_raid456 = is_level456(content->array.level); - is_clean = content->array.state & 1; - - if (enough(content->array.level, content->array.raid_disks, -diff --git a/Grow.c b/Grow.c -index f6efbc48..8c520d42 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) - } - - md_get_array_info(fd, &array); -- if (level == 0 && (array.level >= 4 && array.level <= 6)) { -+ if (level == 0 && is_level456(array.level)) { - /* To convert to RAID0 we need to fail and - * remove any non-data devices. */ - int found = 0; -diff --git a/Manage.c b/Manage.c -index f789e0c1..e5e6abe4 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * - unfreeze reshape - * - wait on 'sync_completed' for that point to be reached. - */ -- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) && -+ if (mdi && is_level456(mdi->array.level) && - sysfs_attribute_available(mdi, NULL, "sync_action") && - sysfs_attribute_available(mdi, NULL, "reshape_direction") && - sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 && -@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; -+ struct mdinfo *info = NULL; - - memset(st, 0, sizeof(*st)); - -@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -+ info = st->ss->container_content(st, subarray); -+ -+ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); -+ goto free_super; -+ } -+ - rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { -@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -- free_super: -+free_super: -+ if (info) -+ free(info); - st->ss->free_super(st); - close(fd); - -diff --git a/mdadm.h b/mdadm.h -index d53df169..974415b9 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -796,6 +796,17 @@ static inline int is_fd_valid(int fd) - return (fd > -1); - } - -+/** -+ * is_level456() - check whether given level is between inclusive 4 and 6. -+ * @level: level to check. -+ * -+ * Return: true if condition is met, false otherwise -+ */ -+static inline bool is_level456(int level) -+{ -+ return (level >= 4 && level <= 6); -+} -+ - /** - * close_fd() - verify, close and unset file descriptor. - * @fd: pointer to file descriptor. -diff --git a/super0.c b/super0.c -index 61c9ec1d..37f595ed 100644 ---- a/super0.c -+++ b/super0.c -@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int parity = sb->level == 6 ? 2 : 1; - rv = 0; - -- if (sb->level >= 4 && sb->level <= 6 && -+ if (is_level456(sb->level) && - sb->reshape_position % ( - sb->new_chunk/512 * - (sb->raid_disks - sb->delta_disks - parity))) { -diff --git a/super1.c b/super1.c -index 3a0c69fd..71af860c 100644 ---- a/super1.c -+++ b/super1.c -@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * So we reject a revert-reshape unless the - * alignment is good. - */ -- if (__le32_to_cpu(sb->level) >= 4 && -- __le32_to_cpu(sb->level) <= 6) { -+ if (is_level456(__le32_to_cpu(sb->level))) { - reshape_sectors = - __le64_to_cpu(sb->reshape_position); - reshape_chunk = __le32_to_cpu(sb->new_chunk); --- -2.38.1 - diff --git a/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch b/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch deleted file mode 100644 index 02bdf9c..0000000 --- a/SOURCES/0027-mdadm-Fix-array-size-mismatch-after-grow.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:47 +0200 -Subject: [PATCH 27/83] mdadm: Fix array size mismatch after grow - -imsm_fix_size_mismatch() is invoked to fix the problem, but it couldn't -proceed due to migration check. This patch allows for intended behavior. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/super-intel.c b/super-intel.c -index 8ffe485c..76b947f5 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11854,7 +11854,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - unsigned long long d_size = imsm_dev_size(dev); - int u_size; - -- if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR) -+ if (calc_size == d_size) - continue; - - /* There is a difference, confirm that imsm_dev_size is --- -2.38.1 - diff --git a/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch b/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch deleted file mode 100644 index 08688dd..0000000 --- a/SOURCES/0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Fri, 22 Jul 2022 08:43:48 +0200 -Subject: [PATCH 28/83] mdadm: Remove dead code in imsm_fix_size_mismatch - -imsm_create_metadata_update_for_size_change() that returns u_size value -could return 0 in the past. As its behavior changed, and returned value -is always the size of imsm_update_size_change structure, check for -u_size is no longer needed. - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 76b947f5..4ddfcf94 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11869,10 +11869,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index) - geo.size = d_size; - u_size = imsm_create_metadata_update_for_size_change(st, &geo, - &update); -- if (u_size < 1) { -- dprintf("imsm: Cannot prepare size change update\n"); -- goto exit; -- } - imsm_update_metadata_locally(st, update, u_size); - if (st->update_tail) { - append_metadata_update(st, update, u_size); --- -2.38.1 - diff --git a/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch b/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch deleted file mode 100644 index f337ff0..0000000 --- a/SOURCES/0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch +++ /dev/null @@ -1,40 +0,0 @@ -From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:10 +0200 -Subject: [PATCH 29/83] Monitor: use devname as char array instead of pointer - -Device name wasn't filled properly due to incorrect use of strcpy. -Strcpy was used twice. Firstly to fill devname with "/dev/md/" -and then to add chosen name. First strcpy result was overwritten by -second one (as a result instead of "/dev/md/" -was assigned). This commit changes this implementation to use snprintf -and devname with fixed size. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 6ca1ebe5..a5b11ae2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -190,9 +190,11 @@ int Monitor(struct mddev_dev *devlist, - if (mdlist->devname[0] == '/') - st->devname = xstrdup(mdlist->devname); - else { -- st->devname = xmalloc(8+strlen(mdlist->devname)+1); -- strcpy(strcpy(st->devname, "/dev/md/"), -- mdlist->devname); -+ /* length of "/dev/md/" + device name + terminating byte */ -+ size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -+ -+ st->devname = xcalloc(_len, sizeof(char)); -+ snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); - } - if (!is_mddev(mdlist->devname)) - return 1; --- -2.38.1 - diff --git a/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch b/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch deleted file mode 100644 index 7d3b4bc..0000000 --- a/SOURCES/0030-Monitor-use-snprintf-to-fill-device-name.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 14 Jul 2022 09:02:11 +0200 -Subject: [PATCH 30/83] Monitor: use snprintf to fill device name - -Safe string functions are propagated in Monitor.c. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Monitor.c | 37 ++++++++++++++----------------------- - 1 file changed, 14 insertions(+), 23 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index a5b11ae2..93f36ac0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,8 +33,8 @@ - #endif - - struct state { -- char *devname; -- char devnm[32]; /* to sync with mdstat info */ -+ char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -+ char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ - unsigned int utime; - int err; - char *spare_group; -@@ -45,9 +45,9 @@ struct state { - int devstate[MAX_DISKS]; - dev_t devid[MAX_DISKS]; - int percent; -- char parent_devnm[32]; /* For subarray, devnm of parent. -- * For others, "" -- */ -+ char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. -+ * For others, "" -+ */ - struct supertype *metadata; - struct state *subarray;/* for a container it is a link to first subarray - * for a subarray it is a link to next subarray -@@ -187,15 +187,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - - st = xcalloc(1, sizeof *st); -- if (mdlist->devname[0] == '/') -- st->devname = xstrdup(mdlist->devname); -- else { -- /* length of "/dev/md/" + device name + terminating byte */ -- size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX); -- -- st->devname = xcalloc(_len, sizeof(char)); -- snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname); -- } -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -+ "/dev/md/%s", basename(mdlist->devname)); - if (!is_mddev(mdlist->devname)) - return 1; - st->next = statelist; -@@ -218,7 +211,7 @@ int Monitor(struct mddev_dev *devlist, - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -- st->devname = xstrdup(dv->devname); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -301,7 +294,6 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->devname); - free(st->spare_group); - free(st); - } else -@@ -554,7 +546,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - goto disappeared; - - if (st->devnm[0] == 0) -- strcpy(st->devnm, fd2devnm(fd)); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", fd2devnm(fd)); - - for (mse2 = mdstat; mse2; mse2 = mse2->next) - if (strcmp(mse2->devnm, st->devnm) == 0) { -@@ -684,7 +676,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - strncmp(mse->metadata_version, "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, mse->metadata_version + 10); -+ snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10); - sl = strchr(st->parent_devnm, '/'); - if (sl) - *sl = 0; -@@ -772,14 +764,13 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - continue; - } - -- st->devname = xstrdup(name); -+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); - if ((fd = open(st->devname, O_RDONLY)) < 0 || - md_get_array_info(fd, &array) < 0) { - /* no such array */ - if (fd >= 0) - close(fd); - put_md_name(st->devname); -- free(st->devname); - if (st->metadata) { - st->metadata->ss->free_super(st->metadata); - free(st->metadata); -@@ -791,7 +782,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - st->next = *statelist; - st->err = 1; - st->from_auto = 1; -- strcpy(st->devnm, mse->devnm); -+ snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm); - st->percent = RESYNC_UNKNOWN; - st->expected_spares = -1; - if (mse->metadata_version && -@@ -799,8 +790,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - "external:", 9) == 0 && - is_subarray(mse->metadata_version+9)) { - char *sl; -- strcpy(st->parent_devnm, -- mse->metadata_version+10); -+ snprintf(st->parent_devnm, MD_NAME_MAX, -+ "%s", mse->metadata_version + 10); - sl = strchr(st->parent_devnm, '/'); - *sl = 0; - } else --- -2.38.1 - diff --git a/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch b/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch deleted file mode 100644 index de5e49e..0000000 --- a/SOURCES/0031-Makefile-Don-t-build-static-build-with-everything-an.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:06 -0600 -Subject: [PATCH 31/83] Makefile: Don't build static build with everything and - everything-test - -Running the test suite requires building everything, but it seems to be -difficult to build the static version of mdadm now seeing there -is no readily available static udev library. - -The test suite doesn't need the static binary so just don't build it -with the everything or everything-test targets. - -Leave the mdadm.static and install-static targets in place in case -someone still has a use case for the static binary. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index bf126033..ec1f99ed 100644 ---- a/Makefile -+++ b/Makefile -@@ -182,9 +182,9 @@ check_rundir: - echo "***** or set CHECK_RUN_DIR=0"; exit 1; \ - fi - --everything: all mdadm.static swap_super test_stripe raid6check \ -+everything: all swap_super test_stripe raid6check \ - mdadm.Os mdadm.O2 man --everything-test: all mdadm.static swap_super test_stripe \ -+everything-test: all swap_super test_stripe \ - mdadm.Os mdadm.O2 man - # mdadm.uclibc doesn't work on x86-64 - # mdadm.tcc doesn't work.. --- -2.38.1 - diff --git a/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch b/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch deleted file mode 100644 index ec2954d..0000000 --- a/SOURCES/0032-DDF-Cleanup-validate_geometry_ddf_container.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:07 -0600 -Subject: [PATCH 32/83] DDF: Cleanup validate_geometry_ddf_container() - -Move the function up so that the function declaration is not necessary -and remove the unused arguments to the function. - -No functional changes are intended but will help with a bug fix in the -next patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 88 ++++++++++++++++++++++++----------------------------- - 1 file changed, 39 insertions(+), 49 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index abbc8b09..9d867f69 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -503,13 +503,6 @@ struct ddf_super { - static int load_super_ddf_all(struct supertype *st, int fd, - void **sbp, char *devname); - static int get_svd_state(const struct ddf_super *, const struct vcl *); --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose); - - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, -@@ -3322,6 +3315,42 @@ static int reserve_space(struct supertype *st, int raiddisks, - return 1; - } - -+static int -+validate_geometry_ddf_container(struct supertype *st, -+ int level, int raiddisks, -+ unsigned long long data_offset, -+ char *dev, unsigned long long *freesize, -+ int verbose) -+{ -+ int fd; -+ unsigned long long ldsize; -+ -+ if (level != LEVEL_CONTAINER) -+ return 0; -+ if (!dev) -+ return 1; -+ -+ fd = dev_open(dev, O_RDONLY|O_EXCL); -+ if (fd < 0) { -+ if (verbose) -+ pr_err("ddf: Cannot open %s: %s\n", -+ dev, strerror(errno)); -+ return 0; -+ } -+ if (!get_dev_size(fd, dev, &ldsize)) { -+ close(fd); -+ return 0; -+ } -+ close(fd); -+ if (freesize) { -+ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -+ if (*freesize == 0) -+ return 0; -+ } -+ -+ return 1; -+} -+ - static int validate_geometry_ddf(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, -@@ -3347,11 +3376,9 @@ static int validate_geometry_ddf(struct supertype *st, - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { - /* Must be a fresh device to add to a container */ -- return validate_geometry_ddf_container(st, level, layout, -- raiddisks, *chunk, -- size, data_offset, dev, -- freesize, -- verbose); -+ return validate_geometry_ddf_container(st, level, raiddisks, -+ data_offset, dev, -+ freesize, verbose); - } - - if (!dev) { -@@ -3449,43 +3476,6 @@ static int validate_geometry_ddf(struct supertype *st, - return 1; - } - --static int --validate_geometry_ddf_container(struct supertype *st, -- int level, int layout, int raiddisks, -- int chunk, unsigned long long size, -- unsigned long long data_offset, -- char *dev, unsigned long long *freesize, -- int verbose) --{ -- int fd; -- unsigned long long ldsize; -- -- if (level != LEVEL_CONTAINER) -- return 0; -- if (!dev) -- return 1; -- -- fd = dev_open(dev, O_RDONLY|O_EXCL); -- if (fd < 0) { -- if (verbose) -- pr_err("ddf: Cannot open %s: %s\n", -- dev, strerror(errno)); -- return 0; -- } -- if (!get_dev_size(fd, dev, &ldsize)) { -- close(fd); -- return 0; -- } -- close(fd); -- if (freesize) { -- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS); -- if (*freesize == 0) -- return 0; -- } -- -- return 1; --} -- - static int validate_geometry_ddf_bvd(struct supertype *st, - int level, int layout, int raiddisks, - int *chunk, unsigned long long size, --- -2.38.1 - diff --git a/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch b/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch deleted file mode 100644 index 3a53577..0000000 --- a/SOURCES/0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:08 -0600 -Subject: [PATCH 33/83] DDF: Fix NULL pointer dereference in - validate_geometry_ddf() - -A relatively recent patch added a call to validate_geometry() in -Manage_add() that has level=LEVEL_CONTAINER and chunk=NULL. - -This causes some ddf tests to segfault which aborts the test suite. - -To fix this, avoid dereferencing chunk when the level is -LEVEL_CONTAINER or LEVEL_NONE. - -Fixes: 1f5d54a06df0 ("Manage: Call validate_geometry when adding drive to external container") -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d867f69..949e7d15 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3369,9 +3369,6 @@ static int validate_geometry_ddf(struct supertype *st, - * If given BVDs, we make an SVD, changing all the GUIDs in the process. - */ - -- if (*chunk == UnSet) -- *chunk = DEFAULT_CHUNK; -- - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; - if (level == LEVEL_CONTAINER) { -@@ -3381,6 +3378,9 @@ static int validate_geometry_ddf(struct supertype *st, - freesize, verbose); - } - -+ if (*chunk == UnSet) -+ *chunk = DEFAULT_CHUNK; -+ - if (!dev) { - mdu_array_info_t array = { - .level = level, --- -2.38.1 - diff --git a/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch b/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch deleted file mode 100644 index 2695f67..0000000 --- a/SOURCES/0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:09 -0600 -Subject: [PATCH 34/83] mdadm/Grow: Fix use after close bug by closing after - fork - -The test 07reshape-grow fails most of the time. But it succeeds around -1 in 5 times. When it does succeed, it causes the tests to die because -mdadm has segfaulted. - -The segfault was caused by mdadm attempting to repoen a file -descriptor that was already closed. The backtrace of the segfault -was: - - #0 __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:101 - #1 0x000056146e31d44b in devnm2devid (devnm=0x0) at util.c:956 - #2 0x000056146e31dab4 in open_dev_flags (devnm=0x0, flags=0) - at util.c:1072 - #3 0x000056146e31db22 in open_dev (devnm=0x0) at util.c:1079 - #4 0x000056146e3202e8 in reopen_mddev (mdfd=4) at util.c:2244 - #5 0x000056146e329f36 in start_array (mdfd=4, - mddev=0x7ffc55342450 "/dev/md0", content=0x7ffc55342860, - st=0x56146fc78660, ident=0x7ffc55342f70, best=0x56146fc6f5d0, - bestcnt=10, chosen_drive=0, devices=0x56146fc706b0, okcnt=5, - sparecnt=0, rebuilding_cnt=0, journalcnt=0, c=0x7ffc55342e90, - clean=1, avail=0x56146fc78720 "\001\001\001\001\001", - start_partial_ok=0, err_ok=0, was_forced=0) - at Assemble.c:1206 - #6 0x000056146e32c36e in Assemble (st=0x56146fc78660, - mddev=0x7ffc55342450 "/dev/md0", ident=0x7ffc55342f70, - devlist=0x56146fc6e2d0, c=0x7ffc55342e90) - at Assemble.c:1914 - #7 0x000056146e312ac9 in main (argc=11, argv=0x7ffc55343238) - at mdadm.c:1510 - -The file descriptor was closed early in Grow_continue(). The noted commit -moved the close() call to close the fd above the fork which caused the -parent process to return with a closed fd. - -This meant reshape_array() and Grow_continue() would return in the parent -with the fd forked. The fd would eventually be passed to reopen_mddev() -which returned an unhandled NULL from fd2devnm() which would then be -dereferenced in devnm2devid. - -Fix this by moving the close() call below the fork. This appears to -fix the 07revert-grow test. While we're at it, switch to using -close_fd() to invalidate the file descriptor. - -Fixes: 77b72fa82813 ("mdadm/Grow: prevent md's fd from being occupied during delayed time") -Cc: Alex Wu -Cc: BingJing Chang -Cc: Danny Shih -Cc: ChangSyun Peng -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8c520d42..97f22c75 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3514,7 +3514,6 @@ started: - return 0; - } - -- close(fd); - /* Now we just need to kick off the reshape and watch, while - * handling backups of the data... - * This is all done by a forked background process. -@@ -3535,6 +3534,9 @@ started: - break; - } - -+ /* Close unused file descriptor in the forked process */ -+ close_fd(&fd); -+ - /* If another array on the same devices is busy, the - * reshape will wait for them. This would mean that - * the first section that we suspend will stay suspended --- -2.38.1 - diff --git a/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch b/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch deleted file mode 100644 index ed09288..0000000 --- a/SOURCES/0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:10 -0600 -Subject: [PATCH 35/83] monitor: Avoid segfault when calling NULL - get_bad_blocks - -Not all struct superswitch implement a get_bad_blocks() function, -yet mdmon seems to call it without checking for NULL and thus -occasionally segfaults in the test 10ddf-geometry. - -Fix this by checking for NULL before calling it. - -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - monitor.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/monitor.c b/monitor.c -index b877e595..820a93d0 100644 ---- a/monitor.c -+++ b/monitor.c -@@ -311,6 +311,9 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi) - struct md_bb *bb; - int i; - -+ if (!ss->get_bad_blocks) -+ return -1; -+ - /* - * Get a list of bad blocks for an array, then read list of - * acknowledged bad blocks from kernel and compare it against metadata --- -2.38.1 - diff --git a/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch b/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch deleted file mode 100644 index f091c64..0000000 --- a/SOURCES/0036-mdadm-Fix-mdadm-r-remove-option-regression.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:11 -0600 -Subject: [PATCH 36/83] mdadm: Fix mdadm -r remove option regression - -The commit noted below globally adds a parameter to the -r option but missed -the fact that -r is used for another purpose: --remove. - -After that commit, a command such as: - - mdadm /dev/md0 -r /dev/loop0 - -will do nothing seeing the device parameter will be consumed as a -argument to the -r option; thus, there will only be one device -seen one the command line, devs_found will only be 1 and nothing will -happen. - -This caused the 01r5integ and 01raid6integ tests to hang indefinitely -as mdadm did not remove the failed device. With the device not removed, -it would not be readded. Then the loop waiting for the array status to -change would loop forever. - -This commit was recently reverted, but the legitimate fix for the -monitor operations was still not fixed. So add specific monitor -short ops to re-fix the --monitor -r option. - -Fixes: 546047688e1c ("mdadm: fix coredump of mdadm --monitor -r") -Fixes: 190dc029b141 ("Revert "mdadm: fix coredump of mdadm --monitor -r"") -Cc: Wu Guanghao -Cc: Mariusz Tkaczyk -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 + - mdadm.c | 1 + - mdadm.h | 1 + - 3 files changed, 3 insertions(+) - -diff --git a/ReadMe.c b/ReadMe.c -index bec1be9a..7518a32a 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -82,6 +82,7 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n"; - */ - - char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; -+char short_monitor_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k:"; - char short_bitmap_options[]= - "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:"; - char short_bitmap_auto_options[]= -diff --git a/mdadm.c b/mdadm.c -index be40686c..d0c5e6de 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -227,6 +227,7 @@ int main(int argc, char *argv[]) - shortopt = short_bitmap_auto_options; - break; - case 'F': newmode = MONITOR; -+ shortopt = short_monitor_options; - break; - case 'G': newmode = GROW; - shortopt = short_bitmap_options; -diff --git a/mdadm.h b/mdadm.h -index 974415b9..163f4a49 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -419,6 +419,7 @@ enum mode { - }; - - extern char short_options[]; -+extern char short_monitor_options[]; - extern char short_bitmap_options[]; - extern char short_bitmap_auto_options[]; - extern struct option long_options[]; --- -2.38.1 - diff --git a/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch b/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch deleted file mode 100644 index 60cafdb..0000000 --- a/SOURCES/0037-mdadm-Fix-optional-write-behind-parameter.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:12 -0600 -Subject: [PATCH 37/83] mdadm: Fix optional --write-behind parameter - -The commit noted below changed the behaviour of --write-behind to -require an argument. This broke the 06wrmostly test with the error: - - mdadm: Invalid value for maximum outstanding write-behind writes: (null). - Must be between 0 and 16383. - -To fix this, check if optarg is NULL before parising it, as the origial -code did. - -Fixes: 60815698c0ac ("Refactor parse_num and use it to parse optarg.") -Cc: Mateusz Grzonka -Signed-off-by: Logan Gunthorpe -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdadm.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/mdadm.c b/mdadm.c -index d0c5e6de..56722ed9 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1201,8 +1201,9 @@ int main(int argc, char *argv[]) - case O(BUILD, WriteBehind): - case O(CREATE, WriteBehind): - s.write_behind = DEFAULT_MAX_WRITE_BEHIND; -- if (parse_num(&s.write_behind, optarg) != 0 || -- s.write_behind < 0 || s.write_behind > 16383) { -+ if (optarg && -+ (parse_num(&s.write_behind, optarg) != 0 || -+ s.write_behind < 0 || s.write_behind > 16383)) { - pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", - optarg); - exit(2); --- -2.38.1 - diff --git a/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch b/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch deleted file mode 100644 index 7794e18..0000000 --- a/SOURCES/0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7539254342bc591717b0051734cc6c09c1b88640 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:13 -0600 -Subject: [PATCH 38/83] tests/00raid0: add a test that validates raid0 with - layout fails for 0.9 - -329dfc28debb disallows the creation of raid0 with layouts for 0.9 -metadata. This test confirms the new behavior. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index 8bc18985..e6b21cc4 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -6,11 +6,9 @@ check raid0 - testdev $md0 3 $mdsize2_l 512 - mdadm -S $md0 - --# now with version-0.90 superblock -+# verify raid0 with layouts fail for 0.90 - mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 --check raid0 --testdev $md0 4 $mdsize0 512 --mdadm -S $md0 -+check opposite_result - - # now with no superblock - mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --- -2.38.1 - diff --git a/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch b/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch deleted file mode 100644 index d897fb1..0000000 --- a/SOURCES/0039-tests-fix-raid0-tests-for-0.90-metadata.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 14c2161edb77d7294199e8aa7daa9f9d1d0ad5d7 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:14 -0600 -Subject: [PATCH 39/83] tests: fix raid0 tests for 0.90 metadata - -Some of the test cases fail because raid0 creation fails with the error, -"0.90 metadata does not support layouts for RAID0" added by commit, -329dfc28debb. Fix some of the test cases by switching from raid0 to -linear level for 0.9 metadata where possible. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00raid0 | 4 ++-- - tests/00readonly | 4 ++++ - tests/03r0assem | 6 +++--- - tests/04r0update | 4 ++-- - tests/04update-metadata | 2 +- - 5 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/tests/00raid0 b/tests/00raid0 -index e6b21cc4..9b8896cb 100644 ---- a/tests/00raid0 -+++ b/tests/00raid0 -@@ -20,8 +20,8 @@ mdadm -S $md0 - # now same again with different chunk size - for chunk in 4 32 256 - do -- mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 -- check raid0 -+ mdadm -CR $md0 -e0.90 -l linear --chunk $chunk -n3 $dev0 $dev1 $dev2 -+ check linear - testdev $md0 3 $mdsize0 $chunk - mdadm -S $md0 - -diff --git a/tests/00readonly b/tests/00readonly -index 28b0fa13..39202487 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -4,6 +4,10 @@ for metadata in 0.9 1.0 1.1 1.2 - do - for level in linear raid0 raid1 raid4 raid5 raid6 raid10 - do -+ if [[ $metadata == "0.9" && $level == "raid0" ]]; -+ then -+ continue -+ fi - mdadm -CR $md0 -l $level -n 4 --metadata=$metadata \ - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync -diff --git a/tests/03r0assem b/tests/03r0assem -index 6744e322..44df0645 100644 ---- a/tests/03r0assem -+++ b/tests/03r0assem -@@ -68,9 +68,9 @@ mdadm -S $md2 - ### Now for version 0... - - mdadm --zero-superblock $dev0 $dev1 $dev2 --mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 --check raid0 --tst="testdev $md2 3 $mdsize0 512" -+mdadm -CR $md2 -llinear --metadata=0.90 -n3 $dev0 $dev1 $dev2 -+check linear -+tst="testdev $md2 3 $mdsize0 1" - $tst - - uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` -diff --git a/tests/04r0update b/tests/04r0update -index 73ee3b9f..b95efb06 100644 ---- a/tests/04r0update -+++ b/tests/04r0update -@@ -1,7 +1,7 @@ - - # create a raid0, re-assemble with a different super-minor --mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 --testdev $md0 3 $mdsize0 512 -+mdadm -CR -e 0.90 $md0 -llinear -n3 $dev0 $dev1 $dev2 -+testdev $md0 3 $mdsize0 1 - minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` - mdadm -S /dev/md0 - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 232fc1ff..08c14af7 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -8,7 +8,7 @@ set -xe - - dlist="$dev0 $dev1 $dev2 $dev3" - --for ls in raid0/4 linear/4 raid1/1 raid5/3 raid6/2 -+for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} - mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist --- -2.38.1 - diff --git a/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch b/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch deleted file mode 100644 index 12b291b..0000000 --- a/SOURCES/0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From de045db607b1ac4b70fc2a8878463e029c2ab1dc Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:15 -0600 -Subject: [PATCH 40/83] tests/04update-metadata: avoid passing chunk size to - raid1 - -'04update-metadata' test fails with error, "specifying chunk size is -forbidden for this level" added by commit, 5b30a34aa4b5e. Hence, -correcting the test to ignore passing chunk size to raid1. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -[logang@deltatee.com: fix if/then style and dropped unrelated hunk] -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/04update-metadata | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/tests/04update-metadata b/tests/04update-metadata -index 08c14af7..2b72a303 100644 ---- a/tests/04update-metadata -+++ b/tests/04update-metadata -@@ -11,7 +11,11 @@ dlist="$dev0 $dev1 $dev2 $dev3" - for ls in linear/4 raid1/1 raid5/3 raid6/2 - do - s=${ls#*/} l=${ls%/*} -- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist -+ if [[ $l == 'raid1' ]]; then -+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist -+ else -+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist -+ fi - testdev $md0 $s 19904 64 - mdadm -S $md0 - mdadm -A $md0 --update=metadata $dlist --- -2.38.1 - diff --git a/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch b/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch deleted file mode 100644 index e6b9bba..0000000 --- a/SOURCES/0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a2c832465fc75202e244327b2081231dfa974617 Mon Sep 17 00:00:00 2001 -From: Sudhakar Panneerselvam -Date: Wed, 22 Jun 2022 14:25:16 -0600 -Subject: [PATCH 41/83] tests/02lineargrow: clear the superblock at every - iteration - -This fixes 02lineargrow test as prior metadata causes --add operation -to misbehave. - -Signed-off-by: Sudhakar Panneerselvam -Signed-off-by: Himanshu Madhani -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/02lineargrow | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/tests/02lineargrow b/tests/02lineargrow -index e05c219d..595bf9f2 100644 ---- a/tests/02lineargrow -+++ b/tests/02lineargrow -@@ -20,4 +20,6 @@ do - testdev $md0 3 $sz 1 - - mdadm -S $md0 -+ mdadm --zero /dev/loop2 -+ mdadm --zero /dev/loop3 - done --- -2.38.1 - diff --git a/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch b/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch deleted file mode 100644 index 63f72dc..0000000 --- a/SOURCES/0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch +++ /dev/null @@ -1,88 +0,0 @@ -From a7bfcc716e235664dfb3b6c5a9590273e611ac72 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:17 -0600 -Subject: [PATCH 42/83] mdadm/test: Add a mode to repeat specified tests - -Many tests fail infrequently or rarely. To help find these, add -an option to run the tests multiple times by specifying --loop=N. - -If --loop=0 is specified, the test will be looped forever. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 36 ++++++++++++++++++++++++------------ - 1 file changed, 24 insertions(+), 12 deletions(-) - -diff --git a/test b/test -index 711a3c7a..da6db5e0 100755 ---- a/test -+++ b/test -@@ -10,6 +10,7 @@ devlist= - - savelogs=0 - exitonerror=1 -+loop=1 - prefix='[0-9][0-9]' - - # use loop devices by default if doesn't specify --dev -@@ -117,6 +118,7 @@ do_help() { - --logdir=directory Directory to save all logfiles in - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests -+ --loop=N Run tests N times (0 to run forever) - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -211,6 +213,9 @@ parse_args() { - --keep-going | --no-error ) - exitonerror=0 - ;; -+ --loop=* ) -+ loop="${i##*=}" -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -263,19 +268,26 @@ main() { - echo "Testing on linux-$(uname -r) kernel" - [ "$savelogs" == "1" ] && - echo "Saving logs to $logdir" -- if [ "x$TESTLIST" != "x" ] -- then -- for script in ${TESTLIST[@]} -- do -- do_test $testdir/$script -- done -- else -- for script in $testdir/$prefix $testdir/$prefix*[^~] -- do -- do_test $script -- done -- fi - -+ while true; do -+ if [ "x$TESTLIST" != "x" ] -+ then -+ for script in ${TESTLIST[@]} -+ do -+ do_test $testdir/$script -+ done -+ else -+ for script in $testdir/$prefix $testdir/$prefix*[^~] -+ do -+ do_test $script -+ done -+ fi -+ -+ let loop=$loop-1 -+ if [ "$loop" == "0" ]; then -+ break -+ fi -+ done - exit 0 - } - --- -2.38.1 - diff --git a/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch b/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch deleted file mode 100644 index 52fd3e9..0000000 --- a/SOURCES/0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 28520bf114b3b0515a48ff44fff4ecbe9ed6dfad Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:18 -0600 -Subject: [PATCH 43/83] mdadm/test: Mark and ignore broken test failures - -Add functionality to continue if a test marked as broken fails. - -To mark a test as broken, a file with the same name but with the suffix -'.broken' should exist. The first line in the file will be printed with -a KNOWN BROKEN message; the rest of the file can describe the how the -test is broken. - -Also adds --skip-broken and --skip-always-broken to skip all the tests -that have a .broken file or to skip all tests whose .broken file's first -line contains the keyword always. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - test | 37 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/test b/test -index da6db5e0..61d9ee83 100755 ---- a/test -+++ b/test -@@ -10,6 +10,8 @@ devlist= - - savelogs=0 - exitonerror=1 -+ctrl_c_error=0 -+skipbroken=0 - loop=1 - prefix='[0-9][0-9]' - -@@ -36,6 +38,7 @@ die() { - - ctrl_c() { - exitonerror=1 -+ ctrl_c_error=1 - } - - # mdadm always adds --quiet, and we want to see any unexpected messages -@@ -80,8 +83,21 @@ mdadm() { - do_test() { - _script=$1 - _basename=`basename $_script` -+ _broken=0 -+ - if [ -f "$_script" ] - then -+ if [ -f "${_script}.broken" ]; then -+ _broken=1 -+ _broken_msg=$(head -n1 "${_script}.broken" | tr -d '\n') -+ if [ "$skipbroken" == "all" ]; then -+ return -+ elif [ "$skipbroken" == "always" ] && -+ [[ "$_broken_msg" == *always* ]]; then -+ return -+ fi -+ fi -+ - rm -f $targetdir/stderr - # this might have been reset: restore the default. - echo 2000 > /proc/sys/dev/raid/speed_limit_max -@@ -98,10 +114,15 @@ do_test() { - else - save_log fail - _fail=1 -+ if [ "$_broken" == "1" ]; then -+ echo " (KNOWN BROKEN TEST: $_broken_msg)" -+ fi - fi - [ "$savelogs" == "1" ] && - mv -f $targetdir/log $logdir/$_basename.log -- [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1 -+ [ "$ctrl_c_error" == "1" ] && exit 1 -+ [ "$_fail" == "1" -a "$exitonerror" == "1" \ -+ -a "$_broken" == "0" ] && exit 1 - fi - } - -@@ -119,6 +140,8 @@ do_help() { - --save-logs Usually use with --logdir together - --keep-going | --no-error Don't stop on error, ie. run all tests - --loop=N Run tests N times (0 to run forever) -+ --skip-broken Skip tests that are known to be broken -+ --skip-always-broken Skip tests that are known to always fail - --dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk - --disks= Provide a bunch of physical devices for test - --volgroup=name LVM volume group for LVM test -@@ -216,6 +239,12 @@ parse_args() { - --loop=* ) - loop="${i##*=}" - ;; -+ --skip-broken ) -+ skipbroken=all -+ ;; -+ --skip-always-broken ) -+ skipbroken=always -+ ;; - --disable-multipath ) - unset MULTIPATH - ;; -@@ -279,7 +308,11 @@ main() { - else - for script in $testdir/$prefix $testdir/$prefix*[^~] - do -- do_test $script -+ case $script in -+ *.broken) ;; -+ *) -+ do_test $script -+ esac - done - fi - --- -2.38.1 - diff --git a/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch b/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch deleted file mode 100644 index 2484e1b..0000000 --- a/SOURCES/0044-tests-Add-broken-files-for-all-broken-tests.patch +++ /dev/null @@ -1,447 +0,0 @@ -From daa86d6634761796ada1f535c13e47fdd3cc95eb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 22 Jun 2022 14:25:19 -0600 -Subject: [PATCH 44/83] tests: Add broken files for all broken tests - -Each broken file contains the rough frequency of brokeness as well -as a brief explanation of what happens when it breaks. Estimates -of failure rates are not statistically significant and can vary -run to run. - -This is really just a view from my window. Tests were done on a -small VM with the default loop devices, not real hardware. We've -seen different kernel configurations can cause bugs to appear as well -(ie. different block schedulers). It may also be that different race -conditions will be seen on machines with different performance -characteristics. - -These annotations were done with the kernel currently in md/md-next: - - facef3b96c5b ("md: Notify sysfs sync_completed in md_reap_sync_thread()") - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/01r5integ.broken | 7 ++++ - tests/01raid6integ.broken | 7 ++++ - tests/04r5swap.broken | 7 ++++ - tests/07autoassemble.broken | 8 ++++ - tests/07autodetect.broken | 5 +++ - tests/07changelevelintr.broken | 9 +++++ - tests/07changelevels.broken | 9 +++++ - tests/07reshape5intr.broken | 45 ++++++++++++++++++++++ - tests/07revert-grow.broken | 31 +++++++++++++++ - tests/07revert-shrink.broken | 9 +++++ - tests/07testreshape5.broken | 12 ++++++ - tests/09imsm-assemble.broken | 6 +++ - tests/09imsm-create-fail-rebuild.broken | 5 +++ - tests/09imsm-overlap.broken | 7 ++++ - tests/10ddf-assemble-missing.broken | 6 +++ - tests/10ddf-fail-create-race.broken | 7 ++++ - tests/10ddf-fail-two-spares.broken | 5 +++ - tests/10ddf-incremental-wrong-order.broken | 9 +++++ - tests/14imsm-r1_2d-grow-r1_3d.broken | 5 +++ - tests/14imsm-r1_2d-takeover-r0_2d.broken | 6 +++ - tests/18imsm-r10_4d-takeover-r0_2d.broken | 5 +++ - tests/18imsm-r1_2d-takeover-r0_1d.broken | 6 +++ - tests/19raid6auto-repair.broken | 5 +++ - tests/19raid6repair.broken | 5 +++ - 24 files changed, 226 insertions(+) - create mode 100644 tests/01r5integ.broken - create mode 100644 tests/01raid6integ.broken - create mode 100644 tests/04r5swap.broken - create mode 100644 tests/07autoassemble.broken - create mode 100644 tests/07autodetect.broken - create mode 100644 tests/07changelevelintr.broken - create mode 100644 tests/07changelevels.broken - create mode 100644 tests/07reshape5intr.broken - create mode 100644 tests/07revert-grow.broken - create mode 100644 tests/07revert-shrink.broken - create mode 100644 tests/07testreshape5.broken - create mode 100644 tests/09imsm-assemble.broken - create mode 100644 tests/09imsm-create-fail-rebuild.broken - create mode 100644 tests/09imsm-overlap.broken - create mode 100644 tests/10ddf-assemble-missing.broken - create mode 100644 tests/10ddf-fail-create-race.broken - create mode 100644 tests/10ddf-fail-two-spares.broken - create mode 100644 tests/10ddf-incremental-wrong-order.broken - create mode 100644 tests/14imsm-r1_2d-grow-r1_3d.broken - create mode 100644 tests/14imsm-r1_2d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r10_4d-takeover-r0_2d.broken - create mode 100644 tests/18imsm-r1_2d-takeover-r0_1d.broken - create mode 100644 tests/19raid6auto-repair.broken - create mode 100644 tests/19raid6repair.broken - -diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken -new file mode 100644 -index 00000000..20737637 ---- /dev/null -+++ b/tests/01r5integ.broken -@@ -0,0 +1,7 @@ -+fails rarely -+ -+Fails about 1 in every 30 runs with a sha mismatch error: -+ -+ c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match -+ 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3 -+ missing -diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken -new file mode 100644 -index 00000000..1df735f0 ---- /dev/null -+++ b/tests/01raid6integ.broken -@@ -0,0 +1,7 @@ -+fails infrequently -+ -+Fails about 1 in 5 with a sha mismatch: -+ -+ 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match -+ a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and -+ /dev/loop3 missing -diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken -new file mode 100644 -index 00000000..e38987db ---- /dev/null -+++ b/tests/04r5swap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 has no superblock - assembly aborted -+ -+ ERROR: no recovery happening -diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken -new file mode 100644 -index 00000000..8be09407 ---- /dev/null -+++ b/tests/07autoassemble.broken -@@ -0,0 +1,8 @@ -+always fails -+ -+Prints lots of messages, but the array doesn't assemble. Error -+possibly related to: -+ -+ mdadm: /dev/md/1 is busy - skipping -+ mdadm: no recogniseable superblock on /dev/md/testing:0 -+ mdadm: /dev/md/2 is busy - skipping -diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken -new file mode 100644 -index 00000000..294954a1 ---- /dev/null -+++ b/tests/07autodetect.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ ERROR: no resync happening -diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken -new file mode 100644 -index 00000000..284b4906 ---- /dev/null -+++ b/tests/07changelevelintr.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: this change will reduce the size of the array. -+ use --grow --array-size first to truncate array. -+ e.g. mdadm --grow /dev/md0 --array-size 56832 -+ -+ ERROR: no reshape happening -diff --git a/tests/07changelevels.broken b/tests/07changelevels.broken -new file mode 100644 -index 00000000..9b930d93 ---- /dev/null -+++ b/tests/07changelevels.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: /dev/loop0 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop1 is smaller than given size. 18976K < 19968K + metadata -+ mdadm: /dev/loop2 is smaller than given size. 18976K < 19968K + metadata -+ -+ ERROR: /dev/md0 isn't a block device. -diff --git a/tests/07reshape5intr.broken b/tests/07reshape5intr.broken -new file mode 100644 -index 00000000..efe52a66 ---- /dev/null -+++ b/tests/07reshape5intr.broken -@@ -0,0 +1,45 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex -+held") -+ -+The new error is simply: -+ -+ ERROR: no reshape happening -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails infrequently -+ -+Fails roughly 1 in 4 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: cannot re-read metadata from /dev/loop6 - aborting -+ -+ ERROR: no reshape happening -+ -+Also have seen a random deadlock: -+ -+ INFO: task mdadm:109702 blocked for more than 30 seconds. -+ Not tainted 5.18.0-rc3-eid-vmlocalyes-dbg-00095-g3c2b5427979d #2040 -+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. -+ task:mdadm state:D stack: 0 pid:109702 ppid: 1 flags:0x00004000 -+ Call Trace: -+ -+ __schedule+0x67e/0x13b0 -+ schedule+0x82/0x110 -+ mddev_suspend+0x2e1/0x330 -+ suspend_lo_store+0xbd/0x140 -+ md_attr_store+0xcb/0x130 -+ sysfs_kf_write+0x89/0xb0 -+ kernfs_fop_write_iter+0x202/0x2c0 -+ new_sync_write+0x222/0x330 -+ vfs_write+0x3bc/0x4d0 -+ ksys_write+0xd9/0x180 -+ __x64_sys_write+0x43/0x50 -+ do_syscall_64+0x3b/0x90 -+ entry_SYSCALL_64_after_hwframe+0x44/0xae -diff --git a/tests/07revert-grow.broken b/tests/07revert-grow.broken -new file mode 100644 -index 00000000..9b6db86f ---- /dev/null -+++ b/tests/07revert-grow.broken -@@ -0,0 +1,31 @@ -+always fails -+ -+This patch, recently added to md-next causes the test to always fail: -+ -+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex held") -+ -+The errors are: -+ -+ mdadm: No active reshape to revert on /dev/loop0 -+ ERROR: active raid5 not found -+ -+Before the patch, the error seen is below. -+ -+-- -+ -+fails rarely -+ -+Fails about 1 in every 30 runs with errors: -+ -+ mdadm: Merging with already-assembled /dev/md/0 -+ mdadm: backup file /tmp/md-backup inaccessible: No such file or directory -+ mdadm: failed to add /dev/loop1 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop2 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop3 to /dev/md/0: Invalid argument -+ mdadm: failed to add /dev/loop0 to /dev/md/0: Invalid argument -+ mdadm: /dev/md/0 assembled from 1 drive - need all 5 to start it -+ (use --run to insist). -+ -+ grep: /sys/block/md*/md/sync_action: No such file or directory -+ -+ ERROR: active raid5 not found -diff --git a/tests/07revert-shrink.broken b/tests/07revert-shrink.broken -new file mode 100644 -index 00000000..c33c39ec ---- /dev/null -+++ b/tests/07revert-shrink.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ -+ mdadm: this change will reduce the size of the array. -+ use --grow --array-size first to truncate array. -+ e.g. mdadm --grow /dev/md0 --array-size 53760 -+ -+ ERROR: active raid5 not found -diff --git a/tests/07testreshape5.broken b/tests/07testreshape5.broken -new file mode 100644 -index 00000000..a8ce03e4 ---- /dev/null -+++ b/tests/07testreshape5.broken -@@ -0,0 +1,12 @@ -+always fails -+ -+Test seems to run 'test_stripe' at $dir directory, but $dir is never -+set. If $dir is adjusted to $PWD, the test still fails with: -+ -+ mdadm: /dev/loop2 is not suitable for this array. -+ mdadm: create aborted -+ ++ return 1 -+ ++ cmp -s -n 8192 /dev/md0 /tmp/RandFile -+ ++ echo cmp failed -+ cmp failed -+ ++ exit 2 -diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken -new file mode 100644 -index 00000000..a6d4d5cf ---- /dev/null -+++ b/tests/09imsm-assemble.broken -@@ -0,0 +1,6 @@ -+fails infrequently -+ -+Fails roughly 1 in 10 runs with errors: -+ -+ mdadm: /dev/loop2 is still in use, cannot remove. -+ /dev/loop2 removal from /dev/md/container should have succeeded -diff --git a/tests/09imsm-create-fail-rebuild.broken b/tests/09imsm-create-fail-rebuild.broken -new file mode 100644 -index 00000000..40c4b294 ---- /dev/null -+++ b/tests/09imsm-create-fail-rebuild.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ **Error**: Array size mismatch - expected 3072, actual 16384 -diff --git a/tests/09imsm-overlap.broken b/tests/09imsm-overlap.broken -new file mode 100644 -index 00000000..e7ccab76 ---- /dev/null -+++ b/tests/09imsm-overlap.broken -@@ -0,0 +1,7 @@ -+always fails -+ -+Fails with errors: -+ -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ **Error**: Offset mismatch - expected 15360, actual 0 -+ /dev/md/vol3 failed check -diff --git a/tests/10ddf-assemble-missing.broken b/tests/10ddf-assemble-missing.broken -new file mode 100644 -index 00000000..bfd8d103 ---- /dev/null -+++ b/tests/10ddf-assemble-missing.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with errors: -+ -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -diff --git a/tests/10ddf-fail-create-race.broken b/tests/10ddf-fail-create-race.broken -new file mode 100644 -index 00000000..6c0df023 ---- /dev/null -+++ b/tests/10ddf-fail-create-race.broken -@@ -0,0 +1,7 @@ -+usually fails -+ -+Fails about 9 out of 10 times with many errors: -+ -+ mdadm: cannot open MISSING: No such file or directory -+ ERROR: non-degraded array found -+ ERROR: disk 0 not marked as failed in meta data -diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken -new file mode 100644 -index 00000000..eeea56d9 ---- /dev/null -+++ b/tests/10ddf-fail-two-spares.broken -@@ -0,0 +1,5 @@ -+fails infrequently -+ -+Fails roughly 1 in 3 with error: -+ -+ ERROR: /dev/md/vol1 should be optimal in meta data -diff --git a/tests/10ddf-incremental-wrong-order.broken b/tests/10ddf-incremental-wrong-order.broken -new file mode 100644 -index 00000000..a5af3bab ---- /dev/null -+++ b/tests/10ddf-incremental-wrong-order.broken -@@ -0,0 +1,9 @@ -+always fails -+ -+Fails with errors: -+ ERROR: sha1sum of /dev/md/vol0 has changed -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10 -+ ERROR: unexpected number of online disks on /dev/loop10 -+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop8 -+ ERROR: unexpected number of online disks on /dev/loop8 -+ ERROR: sha1sum of /dev/md/vol0 has changed -diff --git a/tests/14imsm-r1_2d-grow-r1_3d.broken b/tests/14imsm-r1_2d-grow-r1_3d.broken -new file mode 100644 -index 00000000..4ef1d406 ---- /dev/null -+++ b/tests/14imsm-r1_2d-grow-r1_3d.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with error: -+ -+ mdadm/tests/func.sh: line 325: dvsize/chunk: division by 0 (error token is "chunk") -diff --git a/tests/14imsm-r1_2d-takeover-r0_2d.broken b/tests/14imsm-r1_2d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..89cd4e57 ---- /dev/null -+++ b/tests/14imsm-r1_2d-takeover-r0_2d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/18imsm-r10_4d-takeover-r0_2d.broken b/tests/18imsm-r10_4d-takeover-r0_2d.broken -new file mode 100644 -index 00000000..a27399f5 ---- /dev/null -+++ b/tests/18imsm-r10_4d-takeover-r0_2d.broken -@@ -0,0 +1,5 @@ -+fails rarely -+ -+Fails about 1 run in 100 with message: -+ -+ ERROR: size is wrong for /dev/md/vol0: 2 * 5120 (chunk=128) = 20480, not 0 -diff --git a/tests/18imsm-r1_2d-takeover-r0_1d.broken b/tests/18imsm-r1_2d-takeover-r0_1d.broken -new file mode 100644 -index 00000000..aa1982e6 ---- /dev/null -+++ b/tests/18imsm-r1_2d-takeover-r0_1d.broken -@@ -0,0 +1,6 @@ -+always fails -+ -+Fails with error: -+ -+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token -+ is "chunk") -diff --git a/tests/19raid6auto-repair.broken b/tests/19raid6auto-repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6auto-repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" -diff --git a/tests/19raid6repair.broken b/tests/19raid6repair.broken -new file mode 100644 -index 00000000..e91a1425 ---- /dev/null -+++ b/tests/19raid6repair.broken -@@ -0,0 +1,5 @@ -+always fails -+ -+Fails with: -+ -+ "should detect errors" --- -2.38.1 - diff --git a/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch b/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch deleted file mode 100644 index 74bf834..0000000 --- a/SOURCES/0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch +++ /dev/null @@ -1,316 +0,0 @@ -From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:36:02 +0200 -Subject: [PATCH 45/83] mdadm: Replace obsolete usleep with nanosleep - -According to POSIX.1-2001, usleep is considered obsolete. -Replace it with a wrapper that uses nanosleep, as recommended in man. -Add handy macros for conversions between msec, usec and nsec. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Assemble.c | 2 +- - Grow.c | 4 ++-- - Manage.c | 10 +++++----- - managemon.c | 8 ++++---- - mdadm.h | 4 ++++ - mdmon.c | 4 ++-- - super-intel.c | 6 +++--- - util.c | 42 +++++++++++++++++++++++++++++++++--------- - 8 files changed, 54 insertions(+), 26 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 6df6bfbc..be2160b4 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1947,7 +1947,7 @@ out: - break; - close(mdfd); - } -- usleep(usecs); -+ sleep_for(0, USEC_TO_NSEC(usecs), true); - usecs <<= 1; - } - } -diff --git a/Grow.c b/Grow.c -index 97f22c75..5780635a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -954,7 +954,7 @@ int start_reshape(struct mdinfo *sra, int already_running, - err = sysfs_set_str(sra, NULL, "sync_action", - "reshape"); - if (err) -- sleep(1); -+ sleep_for(1, 0, true); - } while (err && errno == EBUSY && cnt-- > 0); - } - return err; -@@ -5058,7 +5058,7 @@ int Grow_continue_command(char *devname, int fd, - } - st->ss->getinfo_super(st, content, NULL); - if (!content->reshape_active) -- sleep(3); -+ sleep_for(3, 0, true); - else - break; - } while (cnt-- > 0); -diff --git a/Manage.c b/Manage.c -index e5e6abe4..a142f8bd 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -244,7 +244,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - "array_state", - "inactive")) < 0 && - errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count--; - } - if (err) { -@@ -328,7 +328,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) { - /* must be in the critical section - wait a bit */ - delay -= 1; -- usleep(100000); -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } - - if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0) -@@ -405,7 +405,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - * quite started yet. Wait a bit and - * check 'sync_action' to see. - */ -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf)); - if (strncmp(buf, "reshape", 7) != 0) - break; -@@ -447,7 +447,7 @@ done: - count = 25; err = 0; - while (count && fd >= 0 && - (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - count --; - } - if (fd >= 0 && err) { -@@ -1105,7 +1105,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, - ret = sysfs_unique_holder(devnm, rdev); - if (ret < 2) - break; -- usleep(100 * 1000); /* 100ms */ -+ sleep_for(0, MSEC_TO_NSEC(100), true); - } while (--count > 0); - - if (ret == 0) { -diff --git a/managemon.c b/managemon.c -index 0e9bdf00..a7bfa8f6 100644 ---- a/managemon.c -+++ b/managemon.c -@@ -207,7 +207,7 @@ static void replace_array(struct supertype *container, - remove_old(); - while (pending_discard) { - while (discard_this == NULL) -- sleep(1); -+ sleep_for(1, 0, true); - remove_old(); - } - pending_discard = old; -@@ -568,7 +568,7 @@ static void manage_member(struct mdstat_ent *mdstat, - updates = NULL; - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - replace_array(container, a, newa); - if (sysfs_set_str(&a->info, NULL, -@@ -822,7 +822,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - if (msg->len <= 0) - while (update_queue_pending || update_queue) { - check_update_queue(container); -- usleep(15*1000); -+ sleep_for(0, MSEC_TO_NSEC(15), true); - } - - if (msg->len == 0) { /* ping_monitor */ -@@ -836,7 +836,7 @@ static void handle_message(struct supertype *container, struct metadata_update * - wakeup_monitor(); - - while (monitor_loop_cnt - cnt < 0) -- usleep(10 * 1000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - } else if (msg->len == -1) { /* ping_manager */ - struct mdstat_ent *mdstat = mdstat_read(1, 0); - -diff --git a/mdadm.h b/mdadm.h -index 163f4a49..add9c0b6 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1720,6 +1720,10 @@ extern int cluster_get_dlmlock(void); - extern int cluster_release_dlmlock(void); - extern void set_dlm_hooks(void); - -+#define MSEC_TO_NSEC(msec) ((msec) * 1000000) -+#define USEC_TO_NSEC(usec) ((usec) * 1000) -+extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+ - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) - #define ROUND_UP_PTR(ptr, base) ((typeof(ptr)) \ -diff --git a/mdmon.c b/mdmon.c -index c057da63..e9d035eb 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -99,7 +99,7 @@ static int clone_monitor(struct supertype *container) - if (rc) - return rc; - while (mon_tid == -1) -- usleep(10); -+ sleep_for(0, USEC_TO_NSEC(10), true); - pthread_attr_destroy(&attr); - - mgr_tid = syscall(SYS_gettid); -@@ -209,7 +209,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) - rv = kill(pid, SIGUSR1); - if (rv < 0) - break; -- usleep(200000); -+ sleep_for(0, MSEC_TO_NSEC(200), true); - } - } - -diff --git a/super-intel.c b/super-intel.c -index 4ddfcf94..4d82af3d 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5275,7 +5275,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d - /* retry the load if we might have raced against mdmon */ - if (err == 3 && devnm && mdmon_running(devnm)) - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - err = load_and_parse_mpb(dfd, s, NULL, keep_fd); - if (err != 3) - break; -@@ -5377,7 +5377,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) - - if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) { - for (retry = 0; retry < 3; retry++) { -- usleep(3000); -+ sleep_for(0, MSEC_TO_NSEC(3), true); - rv = load_and_parse_mpb(fd, super, devname, 0); - if (rv != 3) - break; -@@ -12084,7 +12084,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) - close(fd); - return 1; - } -- usleep(30000); -+ sleep_for(0, MSEC_TO_NSEC(30), true); - } else - break; - } while (retry--); -diff --git a/util.c b/util.c -index 38f0420e..ca48d976 100644 ---- a/util.c -+++ b/util.c -@@ -166,7 +166,7 @@ retry: - pr_err("error %d when get PW mode on lock %s\n", errno, str); - /* let's try several times if EAGAIN happened */ - if (dlm_lock_res->lksb.sb_status == EAGAIN && retry_count < 10) { -- sleep(10); -+ sleep_for(10, 0, true); - retry_count++; - goto retry; - } -@@ -1085,7 +1085,7 @@ int open_dev_excl(char *devnm) - int i; - int flags = O_RDWR; - dev_t devid = devnm2devid(devnm); -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - sprintf(buf, "%d:%d", major(devid), minor(devid)); - for (i = 0; i < 25; i++) { -@@ -1098,8 +1098,8 @@ int open_dev_excl(char *devnm) - } - if (errno != EBUSY) - return fd; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - return -1; -@@ -1123,7 +1123,7 @@ void wait_for(char *dev, int fd) - { - int i; - struct stat stb_want; -- long delay = 1000; -+ unsigned int delay = 1; // miliseconds - - if (fstat(fd, &stb_want) != 0 || - (stb_want.st_mode & S_IFMT) != S_IFBLK) -@@ -1135,8 +1135,8 @@ void wait_for(char *dev, int fd) - (stb.st_mode & S_IFMT) == S_IFBLK && - (stb.st_rdev == stb_want.st_rdev)) - return; -- usleep(delay); -- if (delay < 200000) -+ sleep_for(0, MSEC_TO_NSEC(delay), true); -+ if (delay < 200) - delay *= 2; - } - if (i == 25) -@@ -1821,7 +1821,7 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force) - while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - - return ret; - } -@@ -1834,7 +1834,7 @@ int sys_hot_remove_disk(int statefd, int force) - while ((ret = write(statefd, "remove", 6)) == -1 && - errno == EBUSY && - cnt-- > 0) -- usleep(10000); -+ sleep_for(0, MSEC_TO_NSEC(10), true); - return ret == 6 ? 0 : -1; - } - -@@ -2375,3 +2375,27 @@ out: - close(fd_zero); - return ret; - } -+ -+/** -+ * sleep_for() - Sleeps for specified time. -+ * @sec: Seconds to sleep for. -+ * @nsec: Nanoseconds to sleep for, has to be less than one second. -+ * @wake_after_interrupt: If set, wake up if interrupted. -+ * -+ * Function immediately returns if error different than EINTR occurs. -+ */ -+void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) -+{ -+ struct timespec delay = {.tv_sec = sec, .tv_nsec = nsec}; -+ -+ assert(nsec < MSEC_TO_NSEC(1000)); -+ -+ do { -+ errno = 0; -+ nanosleep(&delay, &delay); -+ if (errno != 0 && errno != EINTR) { -+ pr_err("Error sleeping for %us %ldns: %s\n", sec, nsec, strerror(errno)); -+ return; -+ } -+ } while (!wake_after_interrupt && errno == EINTR); -+} --- -2.38.1 - diff --git a/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch b/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch deleted file mode 100644 index 5872416..0000000 --- a/SOURCES/0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 39b381252c32275079344d30de18b76fda4bba26 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:45 -0600 -Subject: [PATCH 46/83] tests/00readonly: Run udevadm settle before setting ro - -In some recent kernel versions, 00readonly fails with: - - mdadm: failed to set readonly for /dev/md0: Device or resource busy - ERROR: array is not read-only! - -This was traced down to a race condition with udev holding a reference -to the block device at the same time as trying to set it read only. - -To fix this, call udevadm settle before setting the array read only. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - tests/00readonly | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/00readonly b/tests/00readonly -index 39202487..afe243b3 100644 ---- a/tests/00readonly -+++ b/tests/00readonly -@@ -12,6 +12,7 @@ do - $dev1 $dev2 $dev3 $dev4 --assume-clean - check nosync - check $level -+ udevadm settle - mdadm -ro $md0 - check readonly - state=$(cat /sys/block/md0/md/array_state) --- -2.38.1 - diff --git a/SOURCES/0047-tests-add-test-for-names.patch b/SOURCES/0047-tests-add-test-for-names.patch deleted file mode 100644 index 03aee00..0000000 --- a/SOURCES/0047-tests-add-test-for-names.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b7671c82010ffc04dfaecff2dd19ef8b2283e2b6 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:21 +0200 -Subject: [PATCH 47/83] tests: add test for names - -Current behavior is not documented and tested. This test is a base for -future improvements. It is enough to test it only with native metadata, -because it is generic code. Generated properties are passed to metadata -handler. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00createnames | 93 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 93 insertions(+) - create mode 100644 tests/00createnames - -diff --git a/tests/00createnames b/tests/00createnames -new file mode 100644 -index 00000000..64b81b92 ---- /dev/null -+++ b/tests/00createnames -@@ -0,0 +1,93 @@ -+set -x -e -+ -+# Test how and --name= are handled for create mode. -+# We need to check three properties, generated from those parameters: -+# - devnode name -+# - link in /dev/md/ (MD_DEVNAME property from --detail --export) -+# - name in metadata (MD_NAME property from --examine --export) -+ -+function _verify() { -+ local DEVNODE_NAME="$1" -+ local WANTED_LINK="$2" -+ local WANTED_NAME="$3" -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -+ exit 1 -+ fi -+ -+ if [[ "$WANTED_LINK" != "empty" ]]; then -+ local EXPECTED="MD_DEVNAME=$WANTED_LINK" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+ fi -+ -+ -+ local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get metadata from $dev0." -+ exit 1 -+ fi -+ -+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+} -+ -+function _create() { -+ local DEVNAME=$1 -+ local NAME=$2 -+ -+ if [[ -z "$NAME" ]]; then -+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -+ else -+ mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force -+ fi -+ -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot create device." -+ exit 1 -+ fi -+} -+ -+# The most trivial case. -+_create "/dev/md/name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+_create "name" -+_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# Use 'mdX' as name. -+_create "/dev/md/md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+_create "md0" -+_verify "/dev/md127" "md0" "md0" -+mdadm -S "/dev/md127" -+ -+# is used to create MD_DEVNAME but, name is used to create MD_NAME. -+_create "/dev/md/devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+_create "devnode" "name" -+_verify "/dev/md127" "devnode" "name" -+mdadm -S "/dev/md127" -+ -+# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. -+_create "/dev/md0" -+_verify "/dev/md0" "empty" "0" -+mdadm -S "/dev/md0" -+ -+# Devnode points to /dev/ directory and name is set. -+_create "/dev/md0" "name" -+_verify "/dev/md0" "empty" "name" -+mdadm -S "/dev/md0" --- -2.38.1 - diff --git a/SOURCES/0048-mdadm-remove-symlink-option.patch b/SOURCES/0048-mdadm-remove-symlink-option.patch deleted file mode 100644 index 1956e2b..0000000 --- a/SOURCES/0048-mdadm-remove-symlink-option.patch +++ /dev/null @@ -1,176 +0,0 @@ -From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:22 +0200 -Subject: [PATCH 48/83] mdadm: remove symlink option - -The option is not used. Remove it from code. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 1 - - config.c | 7 +------ - mdadm.8.in | 9 --------- - mdadm.c | 20 -------------------- - mdadm.conf.5.in | 15 --------------- - mdadm.h | 2 -- - 6 files changed, 1 insertion(+), 53 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7518a32a..7f94847e 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -147,7 +147,6 @@ struct option long_options[] = { - {"nofailfast",0, 0, NoFailFast}, - {"re-add", 0, 0, ReAdd}, - {"homehost", 1, 0, HomeHost}, -- {"symlinks", 1, 0, Symlinks}, - {"data-offset",1, 0, DataOffset}, - {"nodes",1, 0, Nodes}, /* also for --assemble */ - {"home-cluster",1, 0, ClusterName}, -diff --git a/config.c b/config.c -index 9c725457..dc1620c1 100644 ---- a/config.c -+++ b/config.c -@@ -194,7 +194,6 @@ struct mddev_dev *load_containers(void) - - struct createinfo createinfo = { - .autof = 2, /* by default, create devices with standard names */ -- .symlinks = 1, - .names = 0, /* By default, stick with numbered md devices. */ - .bblist = 1, /* Use a bad block list by default */ - #ifdef DEBIAN -@@ -310,11 +309,7 @@ static void createline(char *line) - if (!createinfo.supertype) - pr_err("metadata format %s unknown, ignoring\n", - w+9); -- } else if (strncasecmp(w, "symlinks=yes", 12) == 0) -- createinfo.symlinks = 1; -- else if (strncasecmp(w, "symlinks=no", 11) == 0) -- createinfo.symlinks = 0; -- else if (strncasecmp(w, "names=yes", 12) == 0) -+ } else if (strncasecmp(w, "names=yes", 12) == 0) - createinfo.names = 1; - else if (strncasecmp(w, "names=no", 11) == 0) - createinfo.names = 0; -diff --git a/mdadm.8.in b/mdadm.8.in -index 0be02e4a..f2736226 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -1048,11 +1048,6 @@ simultaneously. If not specified, this defaults to 4. - Specify journal device for the RAID-4/5/6 array. The journal device - should be a SSD with reasonable lifetime. - --.TP --.BR \-\-symlinks --Auto creation of symlinks in /dev to /dev/md, option --symlinks must --be 'no' or 'yes' and work with --create and --build. -- - .TP - .BR \-k ", " \-\-consistency\-policy= - Specify how the array maintains consistency in case of unexpected shutdown. -@@ -1405,10 +1400,6 @@ Reshape can be continued later using the - .B \-\-continue - option for the grow command. - --.TP --.BR \-\-symlinks --See this option under Create and Build options. -- - .SH For Manage mode: - - .TP -diff --git a/mdadm.c b/mdadm.c -index 56722ed9..180f7a9c 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -59,7 +59,6 @@ int main(int argc, char *argv[]) - struct mddev_dev *dv; - mdu_array_info_t array; - int devs_found = 0; -- char *symlinks = NULL; - int grow_continue = 0; - /* autof indicates whether and how to create device node. - * bottom 3 bits are style. Rest (when shifted) are number of parts -@@ -663,13 +662,6 @@ int main(int argc, char *argv[]) - case O(ASSEMBLE,Auto): /* auto-creation of device node */ - c.autof = parse_auto(optarg, "--auto flag", 0); - continue; -- -- case O(CREATE,Symlinks): -- case O(BUILD,Symlinks): -- case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */ -- symlinks = optarg; -- continue; -- - case O(BUILD,'f'): /* force honouring '-n 1' */ - case O(BUILD,Force): /* force honouring '-n 1' */ - case O(GROW,'f'): /* ditto */ -@@ -1325,18 +1317,6 @@ int main(int argc, char *argv[]) - exit(2); - } - -- if (symlinks) { -- struct createinfo *ci = conf_get_create_info(); -- -- if (strcasecmp(symlinks, "yes") == 0) -- ci->symlinks = 1; -- else if (strcasecmp(symlinks, "no") == 0) -- ci->symlinks = 0; -- else { -- pr_err("option --symlinks must be 'no' or 'yes'\n"); -- exit(2); -- } -- } - /* Ok, got the option parsing out of the way - * hopefully it's mostly right but there might be some stuff - * missing -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index cd4e6a9d..bc2295c2 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -338,21 +338,6 @@ missing device entries should be created. - The name of the metadata format to use if none is explicitly given. - This can be useful to impose a system-wide default of version-1 superblocks. - --.TP --.B symlinks=no --Normally when creating devices in --.B /dev/md/ --.I mdadm --will create a matching symlink from --.B /dev/ --with a name starting --.B md --or --.BR md_ . --Give --.B symlinks=no --to suppress this symlink creation. -- - .TP - .B names=yes - Since Linux 2.6.29 it has been possible to create -diff --git a/mdadm.h b/mdadm.h -index add9c0b6..93e72786 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -394,7 +394,6 @@ struct createinfo { - int gid; - int autof; - int mode; -- int symlinks; - int names; - int bblist; - struct supertype *supertype; -@@ -442,7 +441,6 @@ enum special_options { - BackupFile, - HomeHost, - AutoHomeHost, -- Symlinks, - AutoDetect, - Waitclean, - DetailPlatform, --- -2.38.1 - diff --git a/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch b/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch deleted file mode 100644 index 5dca508..0000000 --- a/SOURCES/0049-mdadm-move-data_offset-to-struct-shape.patch +++ /dev/null @@ -1,232 +0,0 @@ -From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Tue, 19 Jul 2022 14:48:23 +0200 -Subject: [PATCH 49/83] mdadm: move data_offset to struct shape - -Data offset is a shape property so move it there to remove additional -parameter from some functions. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Create.c | 16 ++++++++-------- - Grow.c | 7 +++---- - mdadm.c | 20 +++++++++----------- - mdadm.h | 5 ++--- - 4 files changed, 22 insertions(+), 26 deletions(-) - -diff --git a/Create.c b/Create.c -index c84c1ac8..e06ec2ae 100644 ---- a/Create.c -+++ b/Create.c -@@ -95,7 +95,7 @@ int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, unsigned long long data_offset) -+ struct context *c) - { - /* - * Create a new raid array. -@@ -288,7 +288,7 @@ int Create(struct supertype *st, char *mddev, - newsize = s->size * 2; - if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, - &s->chunk, s->size*2, -- data_offset, NULL, -+ s->data_offset, NULL, - &newsize, s->consistency_policy, - c->verbose >= 0)) - return 1; -@@ -323,10 +323,10 @@ int Create(struct supertype *st, char *mddev, - info.array.working_disks = 0; - dnum = 0; - for (dv = devlist; dv; dv = dv->next) -- if (data_offset == VARIABLE_OFFSET) -+ if (s->data_offset == VARIABLE_OFFSET) - dv->data_offset = INVALID_SECTORS; - else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) { - char *dname = dv->devname; -@@ -342,7 +342,7 @@ int Create(struct supertype *st, char *mddev, - missing_disks ++; - continue; - } -- if (data_offset == VARIABLE_OFFSET) { -+ if (s->data_offset == VARIABLE_OFFSET) { - doff = strchr(dname, ':'); - if (doff) { - *doff++ = 0; -@@ -350,7 +350,7 @@ int Create(struct supertype *st, char *mddev, - } else - dv->data_offset = INVALID_SECTORS; - } else -- dv->data_offset = data_offset; -+ dv->data_offset = s->data_offset; - - dfd = open(dname, O_RDONLY); - if (dfd < 0) { -@@ -535,7 +535,7 @@ int Create(struct supertype *st, char *mddev, - if (!st->ss->validate_geometry(st, s->level, s->layout, - s->raiddisks, - &s->chunk, minsize*2, -- data_offset, -+ s->data_offset, - NULL, NULL, - s->consistency_policy, 0)) { - pr_err("devices too large for RAID level %d\n", s->level); -@@ -754,7 +754,7 @@ int Create(struct supertype *st, char *mddev, - } - } - if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid, -- data_offset)) -+ s->data_offset)) - goto abort_locked; - - total_slots = info.array.nr_disks; -diff --git a/Grow.c b/Grow.c -index 5780635a..868bdc3a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1775,7 +1775,6 @@ static int reshape_container(char *container, char *devname, - - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s) - { - /* Make some changes in the shape of an array. -@@ -1821,7 +1820,7 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (data_offset != INVALID_SECTORS && array.level != 10 && -+ if (s->data_offset != INVALID_SECTORS && array.level != 10 && - (array.level < 4 || array.level > 6)) { - pr_err("--grow --data-offset not yet supported\n"); - return 1; -@@ -2179,7 +2178,7 @@ size_change_error: - if ((s->level == UnSet || s->level == array.level) && - (s->layout_str == NULL) && - (s->chunk == 0 || s->chunk == array.chunk_size) && -- data_offset == INVALID_SECTORS && -+ s->data_offset == INVALID_SECTORS && - (s->raiddisks == 0 || s->raiddisks == array.raid_disks)) { - /* Nothing more to do */ - if (!changed && c->verbose >= 0) -@@ -2379,7 +2378,7 @@ size_change_error: - } - sync_metadata(st); - rv = reshape_array(container, fd, devname, st, &info, c->force, -- devlist, data_offset, c->backup_file, -+ devlist, s->data_offset, c->backup_file, - c->verbose, 0, 0, 0); - frozen = 0; - } -diff --git a/mdadm.c b/mdadm.c -index 180f7a9c..845e4466 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -49,7 +49,6 @@ int main(int argc, char *argv[]) - int i; - - unsigned long long array_size = 0; -- unsigned long long data_offset = INVALID_SECTORS; - struct mddev_ident ident; - char *configfile = NULL; - int devmode = 0; -@@ -79,6 +78,7 @@ int main(int argc, char *argv[]) - .layout = UnSet, - .bitmap_chunk = UnSet, - .consistency_policy = CONSISTENCY_POLICY_UNKNOWN, -+ .data_offset = INVALID_SECTORS, - }; - - char sys_hostname[256]; -@@ -479,15 +479,15 @@ int main(int argc, char *argv[]) - - case O(CREATE,DataOffset): - case O(GROW,DataOffset): -- if (data_offset != INVALID_SECTORS) { -+ if (s.data_offset != INVALID_SECTORS) { - pr_err("data-offset may only be specified one. Second value is %s.\n", optarg); - exit(2); - } - if (mode == CREATE && strcmp(optarg, "variable") == 0) -- data_offset = VARIABLE_OFFSET; -+ s.data_offset = VARIABLE_OFFSET; - else -- data_offset = parse_size(optarg); -- if (data_offset == INVALID_SECTORS) { -+ s.data_offset = parse_size(optarg); -+ if (s.data_offset == INVALID_SECTORS) { - pr_err("invalid data-offset: %s\n", - optarg); - exit(2); -@@ -1416,7 +1416,7 @@ int main(int argc, char *argv[]) - exit(1); - } - -- if (c.backup_file && data_offset != INVALID_SECTORS) { -+ if (c.backup_file && s.data_offset != INVALID_SECTORS) { - pr_err("--backup-file and --data-offset are incompatible\n"); - exit(2); - } -@@ -1587,8 +1587,7 @@ int main(int argc, char *argv[]) - - rv = Create(ss, devlist->devname, - ident.name, ident.uuid_set ? ident.uuid : NULL, -- devs_found-1, devlist->next, -- &s, &c, data_offset); -+ devs_found - 1, devlist->next, &s, &c); - break; - case MISC: - if (devmode == 'E') { -@@ -1706,10 +1705,9 @@ int main(int argc, char *argv[]) - c.verbose); - else if (s.size > 0 || s.raiddisks || s.layout_str || - s.chunk != 0 || s.level != UnSet || -- data_offset != INVALID_SECTORS) { -+ s.data_offset != INVALID_SECTORS) { - rv = Grow_reshape(devlist->devname, mdfd, -- devlist->next, -- data_offset, &c, &s); -+ devlist->next, &c, &s); - } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { - rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); - } else if (array_size == 0) -diff --git a/mdadm.h b/mdadm.h -index 93e72786..adb7cdaa 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -595,6 +595,7 @@ struct shape { - int assume_clean; - int write_behind; - unsigned long long size; -+ unsigned long long data_offset; - int consistency_policy; - }; - -@@ -1431,7 +1432,6 @@ extern int Grow_addbitmap(char *devname, int fd, - struct context *c, struct shape *s); - extern int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, -- unsigned long long data_offset, - struct context *c, struct shape *s); - extern int Grow_restart(struct supertype *st, struct mdinfo *info, - int *fdlist, int cnt, char *backup_file, int verbose); -@@ -1462,8 +1462,7 @@ extern int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, - struct shape *s, -- struct context *c, -- unsigned long long data_offset); -+ struct context *c); - - extern int Detail(char *dev, struct context *c); - extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); --- -2.38.1 - diff --git a/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch b/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch deleted file mode 100644 index c319da2..0000000 --- a/SOURCES/0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 27 Jul 2022 15:52:46 -0600 -Subject: [PATCH 50/83] mdadm: Don't open md device for CREATE and ASSEMBLE - -The mdadm command tries to open the md device for most modes, first -thing, no matter what. When running to create or assemble an array, -in most cases, the md device will not exist, the open call will fail -and everything will proceed correctly. - -However, when running tests, a create or assembly command may be run -shortly after stopping an array and the old md device file may still -be around. Then, if create_on_open is set in the kernel, a new md -device will be created when mdadm does its initial open. - -When mdadm gets around to creating the new device with the new_array -parameter it issues this error: - - mdadm: Fail to create md0 when using - /sys/module/md_mod/parameters/new_array, fallback to creation via node - -This is because an mddev was already created by the kernel with the -earlier open() call and thus the new one being created will fail with -EEXIST. The mdadm command will still successfully be created due to -falling back to the node creation method. However, the error message -itself will fail any test that's running it. - -This issue is a race condition that is very rare, but a recent change -in the kernel caused this to happen more frequently: about 1 in 50 -times. - -To fix this, don't bother trying to open the md device for CREATE, -ASSEMBLE and BUILD commands, as the file descriptor will never be used -anyway even if it is successfully openned. The mdfd has not been used -for these commands since: - - 7f91af49ad09 ("Delay creation of array devices for assemble/build/create") - -The checks that were done on the open device can be changed to being -done with stat. - -Side note: it would be nice to disable create_on_open as well to help -solve this, but it seems the work for this was never finished. By default, -mdadm will create using the old node interface when a name is specified -unless the user specifically puts names=yes in a config file, which -doesn't seem to be common or desirable to require this.. - -Signed-off-by: Logan Gunthorpe -Signed-off-by: Jes Sorensen ---- - lib.c | 12 ++++++++++++ - mdadm.c | 40 ++++++++++++++++++++-------------------- - mdadm.h | 1 + - 3 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/lib.c b/lib.c -index 7e3e3d47..e395b28d 100644 ---- a/lib.c -+++ b/lib.c -@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st) - return devid2devnm(st->st_rdev); - } - -+bool stat_is_md_dev(struct stat *st) -+{ -+ if ((S_IFMT & st->st_mode) != S_IFBLK) -+ return false; -+ if (major(st->st_rdev) == MD_MAJOR) -+ return true; -+ if (major(st->st_rdev) == (unsigned)get_mdp_major()) -+ return true; -+ -+ return false; -+} -+ - char *fd2devnm(int fd) - { - struct stat stb; -diff --git a/mdadm.c b/mdadm.c -index 845e4466..972adb52 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1329,6 +1329,9 @@ int main(int argc, char *argv[]) - - if (mode == MANAGE || mode == BUILD || mode == CREATE || - mode == GROW || (mode == ASSEMBLE && ! c.scan)) { -+ struct stat stb; -+ int ret; -+ - if (devs_found < 1) { - pr_err("an md device must be given in this mode\n"); - exit(2); -@@ -1341,6 +1344,12 @@ int main(int argc, char *argv[]) - mdfd = open_mddev(devlist->devname, 1); - if (mdfd < 0) - exit(1); -+ -+ ret = fstat(mdfd, &stb); -+ if (ret) { -+ pr_err("fstat failed on %s.\n", devlist->devname); -+ exit(1); -+ } - } else { - char *bname = basename(devlist->devname); - -@@ -1348,30 +1357,21 @@ int main(int argc, char *argv[]) - pr_err("Name %s is too long.\n", devlist->devname); - exit(1); - } -- /* non-existent device is OK */ -- mdfd = open_mddev(devlist->devname, 0); -- } -- if (mdfd == -2) { -- pr_err("device %s exists but is not an md array.\n", devlist->devname); -- exit(1); -- } -- if ((int)ident.super_minor == -2) { -- struct stat stb; -- if (mdfd < 0) { -+ -+ ret = stat(devlist->devname, &stb); -+ if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -- devlist->devname); -+ devlist->devname); -+ exit(1); -+ } -+ -+ if (!ret && !stat_is_md_dev(&stb)) { -+ pr_err("device %s exists but is not an md array.\n", devlist->devname); - exit(1); - } -- fstat(mdfd, &stb); -- ident.super_minor = minor(stb.st_rdev); -- } -- if (mdfd >= 0 && mode != MANAGE && mode != GROW) { -- /* We don't really want this open yet, we just might -- * have wanted to check some things -- */ -- close(mdfd); -- mdfd = -1; - } -+ if (ident.super_minor == -2) -+ ident.super_minor = minor(stb.st_rdev); - } - - if (s.raiddisks) { -diff --git a/mdadm.h b/mdadm.h -index adb7cdaa..8208b81e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1672,6 +1672,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - extern char *stat2kname(struct stat *st); - extern char *fd2kname(int fd); - extern char *stat2devnm(struct stat *st); -+bool stat_is_md_dev(struct stat *st); - extern char *fd2devnm(int fd); - extern void udev_block(char *devnm); - extern void udev_unblock(void); --- -2.38.1 - diff --git a/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch b/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch deleted file mode 100644 index 8fe5894..0000000 --- a/SOURCES/0051-Grow-Split-Grow_reshape-into-helper-function.patch +++ /dev/null @@ -1,231 +0,0 @@ -From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 28 Jul 2022 20:20:53 +0800 -Subject: [PATCH 51/83] Grow: Split Grow_reshape into helper function - -Grow_reshape should be split into helper functions given its size. -- Add helper function for preparing reshape on external metadata. -- Close cfd file descriptor. - -Signed-off-by: Mateusz Kusiak -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 125 ++++++++++++++++++++++++++++++-------------------------- - mdadm.h | 1 + - util.c | 14 +++++++ - 3 files changed, 81 insertions(+), 59 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 868bdc3a..0f07a894 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname, - char *backup_file, int verbose, - int forked, int restart, int freeze_reshape); - -+/** -+ * prepare_external_reshape() - prepares update on external metadata if supported. -+ * @devname: Device name. -+ * @subarray: Subarray. -+ * @st: Supertype. -+ * @container: Container. -+ * @cfd: Container file descriptor. -+ * -+ * Function checks that the requested reshape is supported on external metadata, -+ * and performs an initial check that the container holds the pre-requisite -+ * spare devices (mdmon owns final validation). -+ * -+ * Return: 0 on success, else 1 -+ */ -+static int prepare_external_reshape(char *devname, char *subarray, -+ struct supertype *st, char *container, -+ const int cfd) -+{ -+ struct mdinfo *cc = NULL; -+ struct mdinfo *content = NULL; -+ -+ if (st->ss->load_container(st, cfd, NULL)) { -+ pr_err("Cannot read superblock for %s\n", devname); -+ return 1; -+ } -+ -+ if (!st->ss->container_content) -+ return 1; -+ -+ cc = st->ss->container_content(st, subarray); -+ for (content = cc; content ; content = content->next) { -+ /* -+ * check if reshape is allowed based on metadata -+ * indications stored in content.array.status -+ */ -+ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) || -+ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) { -+ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -+ devname, container); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) { -+ pr_err("Operation not supported when ppl consistency policy is enabled\n"); -+ goto error; -+ } -+ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) { -+ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n"); -+ goto error; -+ } -+ } -+ sysfs_free(cc); -+ if (mdmon_running(container)) -+ st->update_tail = &st->updates; -+ return 0; -+error: -+ sysfs_free(cc); -+ return 1; -+} -+ - int Grow_reshape(char *devname, int fd, - struct mddev_dev *devlist, - struct context *c, struct shape *s) -@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd, - struct supertype *st; - char *subarray = NULL; - -- int frozen; -+ int frozen = 0; - int changed = 0; - char *container = NULL; - int cfd = -1; -@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd, - int added_disks; - - struct mdinfo info; -- struct mdinfo *sra; -+ struct mdinfo *sra = NULL; - - if (md_get_array_info(fd, &array) < 0) { - pr_err("%s is not an active md array - aborting\n", -@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd, - } - } - -- /* in the external case we need to check that the requested reshape is -- * supported, and perform an initial check that the container holds the -- * pre-requisite spare devices (mdmon owns final validation) -- */ - if (st->ss->external) { -- int retval; -- - if (subarray) { - container = st->container_devnm; - cfd = open_dev_excl(st->container_devnm); -@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- retval = st->ss->load_container(st, cfd, NULL); -- -- if (retval) { -- pr_err("Cannot read superblock for %s\n", devname); -- close(cfd); -+ rv = prepare_external_reshape(devname, subarray, st, -+ container, cfd); -+ if (rv > 0) { - free(subarray); -- return 1; -+ close(cfd); -+ goto release; - } - - if (s->raiddisks && subarray) { -@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd, - free(subarray); - return 1; - } -- -- /* check if operation is supported for metadata handler */ -- if (st->ss->container_content) { -- struct mdinfo *cc = NULL; -- struct mdinfo *content = NULL; -- -- cc = st->ss->container_content(st, subarray); -- for (content = cc; content ; content = content->next) { -- int allow_reshape = 1; -- -- /* check if reshape is allowed based on metadata -- * indications stored in content.array.status -- */ -- if (content->array.state & -- (1 << MD_SB_BLOCK_VOLUME)) -- allow_reshape = 0; -- if (content->array.state & -- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE)) -- allow_reshape = 0; -- if (!allow_reshape) { -- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n", -- devname, container); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_PPL) { -- pr_err("Operation not supported when ppl consistency policy is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- if (content->consistency_policy == -- CONSISTENCY_POLICY_BITMAP) { -- pr_err("Operation not supported when write-intent bitmap is enabled\n"); -- sysfs_free(cc); -- free(subarray); -- return 1; -- } -- } -- sysfs_free(cc); -- } -- if (mdmon_running(container)) -- st->update_tail = &st->updates; - } - - added_disks = 0; -diff --git a/mdadm.h b/mdadm.h -index 8208b81e..941a5f38 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev); - extern bool is_dev_alive(char *path); - extern int get_mdp_major(void); - extern int get_maj_min(char *dev, int *major, int *minor); -+extern bool is_bit_set(int *val, unsigned char index); - extern int dev_open(char *dev, int flags); - extern int open_dev(char *devnm); - extern void reopen_mddev(int mdfd); -diff --git a/util.c b/util.c -index ca48d976..26ffdcea 100644 ---- a/util.c -+++ b/util.c -@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor) - *e == 0); - } - -+/** -+ * is_bit_set() - get bit value by index. -+ * @val: value. -+ * @index: index of the bit (LSB numbering). -+ * -+ * Return: bit value. -+ */ -+bool is_bit_set(int *val, unsigned char index) -+{ -+ if ((*val) & (1 << index)) -+ return true; -+ return false; -+} -+ - int dev_open(char *dev, int flags) - { - /* like 'open', but if 'dev' matches %d:%d, create a temp --- -2.38.1 - diff --git a/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch b/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch deleted file mode 100644 index 52d08b8..0000000 --- a/SOURCES/0052-Assemble-check-if-device-is-container-before-schedul.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 19 Aug 2022 02:55:46 +0200 -Subject: [PATCH 52/83] Assemble: check if device is container before - scheduling force-clean update - -Up to now using assemble with force flag making each array as clean. -Force-clean should not be done for the container. This commit add -check if device is different than container before cleaning. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Assemble.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index be2160b4..1dd82a8c 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1809,10 +1809,9 @@ try_again: - } - #endif - } -- if (c->force && !clean && -+ if (c->force && !clean && content->array.level != LEVEL_CONTAINER && - !enough(content->array.level, content->array.raid_disks, -- content->array.layout, clean, -- avail)) { -+ content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", - devices[chosen_drive].devname, c->verbose, - 0, NULL); --- -2.38.1 - diff --git a/SOURCES/0053-super1-report-truncated-device.patch b/SOURCES/0053-super1-report-truncated-device.patch deleted file mode 100644 index 35cbd4b..0000000 --- a/SOURCES/0053-super1-report-truncated-device.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Fri, 26 Aug 2022 08:55:56 +1000 -Subject: [PATCH 53/83] super1: report truncated device - -When the metadata is at the start of the device, it is possible that it -describes a device large than the one it is actually stored on. When -this happens, report it loudly in --examine. - -.... - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE -.... - -Also report in --assemble so that the failure which the kernel will -report will be explained. - -mdadm: Device /dev/sdb is not large enough for data described in superblock -mdadm: no RAID superblock on /dev/sdb -mdadm: /dev/sdb has no superblock - assembly aborted - -Scenario can be demonstrated as follows: - -mdadm: Note: this array has metadata at the start and - may not be suitable as a boot device. If you plan to - store '/boot' on this device please ensure that - your boot-loader understands md/v1.x metadata, or use - --metadata=0.90 -mdadm: Defaulting to version 1.2 metadata -mdadm: array /dev/md/test started. -mdadm: stopped /dev/md/test - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL - State : clean TRUNCATED DEVICE - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - super1.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - -diff --git a/super1.c b/super1.c -index 71af860c..58345e68 100644 ---- a/super1.c -+++ b/super1.c -@@ -406,12 +406,18 @@ static void examine_super1(struct supertype *st, char *homehost) - - st->ss->getinfo_super(st, &info, NULL); - if (info.space_after != 1 && -- !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) -- printf(" Unused Space : before=%llu sectors, after=%llu sectors\n", -- info.space_before, info.space_after); -- -- printf(" State : %s\n", -- (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); -+ !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { -+ printf(" Unused Space : before=%llu sectors, ", -+ info.space_before); -+ if (info.space_after < INT64_MAX) -+ printf("after=%llu sectors\n", info.space_after); -+ else -+ printf("after=-%llu sectors DEVICE TOO SMALL\n", -+ UINT64_MAX - info.space_after); -+ } -+ printf(" State : %s%s\n", -+ (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); - for (i=0; i<16; i++) { - if ((i&3)==0 && i != 0) -@@ -2206,6 +2212,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - tst.ss = &super1; - for (tst.minor_version = 0; tst.minor_version <= 2; - tst.minor_version++) { -+ tst.ignore_hw_compat = st->ignore_hw_compat; - switch(load_super1(&tst, fd, devname)) { - case 0: super = tst.sb; - if (bestvers == -1 || -@@ -2312,7 +2319,6 @@ static int load_super1(struct supertype *st, int fd, char *devname) - free(super); - return 2; - } -- st->sb = super; - - bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); - -@@ -2322,6 +2328,21 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); - -+ if (st->minor_version >= 1 && -+ st->ignore_hw_compat == 0 && -+ (dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size)) -+ || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->data_size)))) { -+ if (devname) -+ pr_err("Device %s is not large enough for data described in superblock\n", -+ devname); -+ free(super); -+ return 2; -+ } -+ st->sb = super; -+ - /* Now check on the bitmap superblock */ - if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0) - return 0; --- -2.38.1 - diff --git a/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch b/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch deleted file mode 100644 index c37276f..0000000 --- a/SOURCES/0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Fri, 12 Aug 2022 16:52:12 +0200 -Subject: [PATCH 54/83] mdadm: Correct typos, punctuation and grammar in man - -Signed-off-by: Mateusz Grzonka -Reviewed-by: Wol -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 178 ++++++++++++++++++++++++++--------------------------- - 1 file changed, 88 insertions(+), 90 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index f2736226..70c79d1e 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -158,7 +158,7 @@ adding new spares and removing faulty devices. - .B Misc - This is an 'everything else' mode that supports operations on active - arrays, operations on component devices such as erasing old superblocks, and --information gathering operations. -+information-gathering operations. - .\"This mode allows operations on independent devices such as examine MD - .\"superblocks, erasing old superblocks and stopping active arrays. - -@@ -231,12 +231,12 @@ mode to be assumed. - - .TP - .BR \-h ", " \-\-help --Display general help message or, after one of the above options, a -+Display a general help message or, after one of the above options, a - mode-specific help message. - - .TP - .B \-\-help\-options --Display more detailed help about command line parsing and some commonly -+Display more detailed help about command-line parsing and some commonly - used options. - - .TP -@@ -266,7 +266,7 @@ the exact meaning of this option in different contexts. - - .TP - .BR \-c ", " \-\-config= --Specify the config file or directory. If not specified, default config file -+Specify the config file or directory. If not specified, the default config file - and default conf.d directory will be used. See - .BR mdadm.conf (5) - for more details. -@@ -379,7 +379,7 @@ When creating an array, the - .B homehost - will be recorded in the metadata. For version-1 superblocks, it will - be prefixed to the array name. For version-0.90 superblocks, part of --the SHA1 hash of the hostname will be stored in the later half of the -+the SHA1 hash of the hostname will be stored in the latter half of the - UUID. - - When reporting information about an array, any array which is tagged -@@ -388,7 +388,7 @@ for the given homehost will be reported as such. - When using Auto-Assemble, only arrays tagged for the given homehost - will be allowed to use 'local' names (i.e. not ending in '_' followed - by a digit string). See below under --.BR "Auto Assembly" . -+.BR "Auto-Assembly" . - - The special name "\fBany\fP" can be used as a wild card. If an array - is created with -@@ -403,7 +403,7 @@ When - .I mdadm - needs to print the name for a device it normally finds the name in - .B /dev --which refers to the device and is shortest. When a path component is -+which refers to the device and is the shortest. When a path component is - given with - .B \-\-prefer - .I mdadm -@@ -478,9 +478,9 @@ still be larger than any replacement. - - This option can be used with - .B \-\-create --for determining initial size of an array. For external metadata, -+for determining the initial size of an array. For external metadata, - it can be used on a volume, but not on a container itself. --Setting initial size of -+Setting the initial size of - .B RAID 0 - array is only valid for external metadata. - -@@ -545,20 +545,20 @@ Clustered arrays do not support this parameter yet. - - .TP - .BR \-c ", " \-\-chunk= --Specify chunk size of kilobytes. The default when creating an -+Specify chunk size in kilobytes. The default when creating an - array is 512KB. To ensure compatibility with earlier versions, the - default when building an array with no persistent metadata is 64KB. - This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10. - - RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power --of 2. In any case it must be a multiple of 4KB. -+of 2, with minimal chunk size being 4KB. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, - Megabytes, Gigabytes or Terabytes respectively. - - .TP - .BR \-\-rounding= --Specify rounding factor for a Linear array. The size of each -+Specify the rounding factor for a Linear array. The size of each - component will be rounded down to a multiple of this size. - This is a synonym for - .B \-\-chunk -@@ -655,7 +655,8 @@ option to set subsequent failure modes. - and "flush" will clear any persistent faults. - - The layout options for RAID10 are one of 'n', 'o' or 'f' followed --by a small number. The default is 'n2'. The supported options are: -+by a small number signifying the number of copies of each datablock. -+The default is 'n2'. The supported options are: - - .I 'n' - signals 'near' copies. Multiple copies of one data block are at -@@ -673,7 +674,7 @@ signals 'far' copies - (multiple copies have very different offsets). - See md(4) for more detail about 'near', 'offset', and 'far'. - --The number is the number of copies of each datablock. 2 is normal, 3 -+As for the number of copies of each data block, 2 is normal, 3 - can be useful. This number can be at most equal to the number of - devices in the array. It does not need to divide evenly into that - number (e.g. it is perfectly legal to have an 'n2' layout for an array -@@ -684,7 +685,7 @@ A bug introduced in Linux 3.14 means that RAID0 arrays - started using a different layout. This could lead to - data corruption. Since Linux 5.4 (and various stable releases that received - backports), the kernel will not accept such an array unless --a layout is explictly set. It can be set to -+a layout is explicitly set. It can be set to - .RB ' original ' - or - .RB ' alternate '. -@@ -760,13 +761,13 @@ or by selecting a different consistency policy with - - .TP - .BR \-\-bitmap\-chunk= --Set the chunksize of the bitmap. Each bit corresponds to that many -+Set the chunk size of the bitmap. Each bit corresponds to that many - Kilobytes of storage. --When using a file based bitmap, the default is to use the smallest --size that is at-least 4 and requires no more than 2^21 chunks. -+When using a file-based bitmap, the default is to use the smallest -+size that is at least 4 and requires no more than 2^21 chunks. - When using an - .B internal --bitmap, the chunksize defaults to 64Meg, or larger if necessary to -+bitmap, the chunk size defaults to 64Meg, or larger if necessary to - fit the bitmap into the available space. - - A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, -@@ -840,7 +841,7 @@ can be used with that command to avoid the automatic resync. - .BR \-\-backup\-file= - This is needed when - .B \-\-grow --is used to increase the number of raid-devices in a RAID5 or RAID6 if -+is used to increase the number of raid devices in a RAID5 or RAID6 if - there are no spare devices available, or to shrink, change RAID level - or layout. See the GROW MODE section below on RAID\-DEVICES CHANGES. - The file must be stored on a separate device, not on the RAID array -@@ -879,7 +880,7 @@ When creating an array, - .B \-\-data\-offset - can be specified as - .BR variable . --In the case each member device is expected to have a offset appended -+In the case each member device is expected to have an offset appended - to the name, separated by a colon. This makes it possible to recreate - exactly an array which has varying data offsets (as can happen when - different versions of -@@ -943,7 +944,7 @@ Insist that - .I mdadm - accept the geometry and layout specified without question. Normally - .I mdadm --will not allow creation of an array with only one device, and will try -+will not allow the creation of an array with only one device, and will try - to create a RAID5 array with one missing drive (as this makes the - initial resync work faster). With - .BR \-\-force , -@@ -1004,7 +1005,7 @@ number added, e.g. - If the md device name is in a 'standard' format as described in DEVICE - NAMES, then it will be created, if necessary, with the appropriate - device number based on that name. If the device name is not in one of these --formats, then a unused device number will be allocated. The device -+formats, then an unused device number will be allocated. The device - number will be considered unused if there is no active array for that - number, and there is no entry in /dev for that number and with a - non-standard name. Names that are not in 'standard' format are only -@@ -1032,25 +1033,25 @@ then - .B \-\-add - can be used to add some extra devices to be included in the array. - In most cases this is not needed as the extra devices can be added as --spares first, and then the number of raid-disks can be changed. --However for RAID0, it is not possible to add spares. So to increase -+spares first, and then the number of raid disks can be changed. -+However, for RAID0 it is not possible to add spares. So to increase - the number of devices in a RAID0, it is necessary to set the new - number of devices, and to add the new devices, in the same command. - - .TP - .BR \-\-nodes --Only works when the array is for clustered environment. It specifies -+Only works when the array is created for a clustered environment. It specifies - the maximum number of nodes in the cluster that will use this device - simultaneously. If not specified, this defaults to 4. - - .TP - .BR \-\-write-journal - Specify journal device for the RAID-4/5/6 array. The journal device --should be a SSD with reasonable lifetime. -+should be an SSD with a reasonable lifetime. - - .TP - .BR \-k ", " \-\-consistency\-policy= --Specify how the array maintains consistency in case of unexpected shutdown. -+Specify how the array maintains consistency in the case of an unexpected shutdown. - Only relevant for RAID levels with redundancy. - Currently supported options are: - .RS -@@ -1058,7 +1059,7 @@ Currently supported options are: - .TP - .B resync - Full resync is performed and all redundancy is regenerated when the array is --started after unclean shutdown. -+started after an unclean shutdown. - - .TP - .B bitmap -@@ -1067,8 +1068,8 @@ Resync assisted by a write-intent bitmap. Implicitly selected when using - - .TP - .B journal --For RAID levels 4/5/6, journal device is used to log transactions and replay --after unclean shutdown. Implicitly selected when using -+For RAID levels 4/5/6, the journal device is used to log transactions and replay -+after an unclean shutdown. Implicitly selected when using - .BR \-\-write\-journal . - - .TP -@@ -1237,7 +1238,7 @@ This can be useful if - reports a different "Preferred Minor" to - .BR \-\-detail . - In some cases this update will be performed automatically --by the kernel driver. In particular the update happens automatically -+by the kernel driver. In particular, the update happens automatically - at the first write to an array with redundancy (RAID level 1 or - greater) on a 2.6 (or later) kernel. - -@@ -1277,7 +1278,7 @@ For version-1 superblocks, this involves updating the name. - The - .B home\-cluster - option will change the cluster name as recorded in the superblock and --bitmap. This option only works for clustered environment. -+bitmap. This option only works for a clustered environment. - - The - .B resync -@@ -1390,10 +1391,10 @@ This option should be used with great caution. - - .TP - .BR \-\-freeze\-reshape --Option is intended to be used in start-up scripts during initrd boot phase. --When array under reshape is assembled during initrd phase, this option --stops reshape after reshape critical section is being restored. This happens --before file system pivot operation and avoids loss of file system context. -+This option is intended to be used in start-up scripts during the initrd boot phase. -+When the array under reshape is assembled during the initrd phase, this option -+stops the reshape after the reshape-critical section has been restored. This happens -+before the file system pivot operation and avoids loss of filesystem context. - Losing file system context would cause reshape to be broken. - - Reshape can be continued later using the -@@ -1437,9 +1438,9 @@ re\-add a device that was previously removed from an array. - If the metadata on the device reports that it is a member of the - array, and the slot that it used is still vacant, then the device will - be added back to the array in the same position. This will normally --cause the data for that device to be recovered. However based on the -+cause the data for that device to be recovered. However, based on the - event count on the device, the recovery may only require sections that --are flagged a write-intent bitmap to be recovered or may not require -+are flagged by a write-intent bitmap to be recovered or may not require - any recovery at all. - - When used on an array that has no metadata (i.e. it was built with -@@ -1447,13 +1448,12 @@ When used on an array that has no metadata (i.e. it was built with - it will be assumed that bitmap-based recovery is enough to make the - device fully consistent with the array. - --When used with v1.x metadata, - .B \-\-re\-add --can be accompanied by -+can also be accompanied by - .BR \-\-update=devicesize , - .BR \-\-update=bbl ", or" - .BR \-\-update=no\-bbl . --See the description of these option when used in Assemble mode for an -+See descriptions of these options when used in Assemble mode for an - explanation of their use. - - If the device name given is -@@ -1480,7 +1480,7 @@ Add a device as a spare. This is similar to - except that it does not attempt - .B \-\-re\-add - first. The device will be added as a spare even if it looks like it --could be an recent member of the array. -+could be a recent member of the array. - - .TP - .BR \-r ", " \-\-remove -@@ -1497,12 +1497,12 @@ and names like - .B set-A - can be given to - .BR \-\-remove . --The first causes all failed device to be removed. The second causes -+The first causes all failed devices to be removed. The second causes - any device which is no longer connected to the system (i.e an 'open' - returns - .BR ENXIO ) - to be removed. --The third will remove a set as describe below under -+The third will remove a set as described below under - .BR \-\-fail . - - .TP -@@ -1519,7 +1519,7 @@ For RAID10 arrays where the number of copies evenly divides the number - of devices, the devices can be conceptually divided into sets where - each set contains a single complete copy of the data on the array. - Sometimes a RAID10 array will be configured so that these sets are on --separate controllers. In this case all the devices in one set can be -+separate controllers. In this case, all the devices in one set can be - failed by giving a name like - .B set\-A - or -@@ -1549,9 +1549,9 @@ This can follow a list of - .B \-\-replace - devices. The devices listed after - .B \-\-with --will be preferentially used to replace the devices listed after -+will preferentially be used to replace the devices listed after - .BR \-\-replace . --These device must already be spare devices in the array. -+These devices must already be spare devices in the array. - - .TP - .BR \-\-write\-mostly -@@ -1574,8 +1574,8 @@ the device is found or :missing in case the device is not found. - - .TP - .BR \-\-add-journal --Add journal to an existing array, or recreate journal for RAID-4/5/6 array --that lost a journal device. To avoid interrupting on-going write opertions, -+Add a journal to an existing array, or recreate journal for a RAID-4/5/6 array -+that lost a journal device. To avoid interrupting ongoing write operations, - .B \-\-add-journal - only works for array in Read-Only state. - -@@ -1631,9 +1631,9 @@ Print details of one or more md devices. - .TP - .BR \-\-detail\-platform - Print details of the platform's RAID capabilities (firmware / hardware --topology) for a given metadata format. If used without argument, mdadm -+topology) for a given metadata format. If used without an argument, mdadm - will scan all controllers looking for their capabilities. Otherwise, mdadm --will only look at the controller specified by the argument in form of an -+will only look at the controller specified by the argument in the form of an - absolute filepath or a link, e.g. - .IR /sys/devices/pci0000:00/0000:00:1f.2 . - -@@ -1742,8 +1742,8 @@ the block where the superblock would be is overwritten even if it - doesn't appear to be valid. - - .B Note: --Be careful to call \-\-zero\-superblock with clustered raid, make sure --array isn't used or assembled in other cluster node before execute it. -+Be careful when calling \-\-zero\-superblock with clustered raid. Make sure -+the array isn't used or assembled in another cluster node before executing it. - - .TP - .B \-\-kill\-subarray= -@@ -1790,7 +1790,7 @@ For each md device given, or each device in /proc/mdstat if - is given, arrange for the array to be marked clean as soon as possible. - .I mdadm - will return with success if the array uses external metadata and we --successfully waited. For native arrays this returns immediately as the -+successfully waited. For native arrays, this returns immediately as the - kernel handles dirty-clean transitions at shutdown. No action is taken - if safe-mode handling is disabled. - -@@ -1830,7 +1830,7 @@ uses to help track which arrays are currently being assembled. - - .TP - .BR \-\-run ", " \-R --Run any array assembled as soon as a minimal number of devices are -+Run any array assembled as soon as a minimal number of devices is - available, rather than waiting until all expected devices are present. - - .TP -@@ -1860,7 +1860,7 @@ Only used with \-\-fail. The 'path' given will be recorded so that if - a new device appears at the same location it can be automatically - added to the same array. This allows the failed device to be - automatically replaced by a new device without metadata if it appears --at specified path. This option is normally only set by a -+at specified path. This option is normally only set by an - .I udev - script. - -@@ -1961,7 +1961,7 @@ Usage: - .PP - This usage assembles one or more RAID arrays from pre-existing components. - For each array, mdadm needs to know the md device, the identity of the --array, and a number of component-devices. These can be found in a number of ways. -+array, and the number of component devices. These can be found in a number of ways. - - In the first usage example (without the - .BR \-\-scan ) -@@ -2001,7 +2001,7 @@ The config file is only used if explicitly named with - .B \-\-config - or requested with (a possibly implicit) - .BR \-\-scan . --In the later case, default config file is used. See -+In the latter case, the default config file is used. See - .BR mdadm.conf (5) - for more details. - -@@ -2039,14 +2039,14 @@ detects that udev is not configured, it will create the devices in - .B /dev - itself. - --In Linux kernels prior to version 2.6.28 there were two distinctly --different types of md devices that could be created: one that could be -+In Linux kernels prior to version 2.6.28 there were two distinct -+types of md devices that could be created: one that could be - partitioned using standard partitioning tools and one that could not. --Since 2.6.28 that distinction is no longer relevant as both type of -+Since 2.6.28 that distinction is no longer relevant as both types of - devices can be partitioned. - .I mdadm - will normally create the type that originally could not be partitioned --as it has a well defined major number (9). -+as it has a well-defined major number (9). - - Prior to 2.6.28, it is important that mdadm chooses the correct type - of array device to use. This can be controlled with the -@@ -2066,7 +2066,7 @@ can also be given in the configuration file as a word starting - .B auto= - on the ARRAY line for the relevant array. - --.SS Auto Assembly -+.SS Auto-Assembly - When - .B \-\-assemble - is used with -@@ -2122,11 +2122,11 @@ See - .IR mdadm.conf (5) - for further details. - --Note: Auto assembly cannot be used for assembling and activating some -+Note: Auto-assembly cannot be used for assembling and activating some - arrays which are undergoing reshape. In particular as the - .B backup\-file --cannot be given, any reshape which requires a backup-file to continue --cannot be started by auto assembly. An array which is growing to more -+cannot be given, any reshape which requires a backup file to continue -+cannot be started by auto-assembly. An array which is growing to more - devices and has passed the critical section can be assembled using - auto-assembly. - -@@ -2233,7 +2233,7 @@ When creating a partition based array, using - .I mdadm - with version-1.x metadata, the partition type should be set to - .B 0xDA --(non fs-data). This type selection allows for greater precision since -+(non fs-data). This type of selection allows for greater precision since - using any other [RAID auto-detect (0xFD) or a GNU/Linux partition (0x83)], - might create problems in the event of array recovery through a live cdrom. - -@@ -2249,7 +2249,7 @@ when creating a v0.90 array will silently override any - setting. - .\"If the - .\".B \-\-size --.\"option is given, it is not necessary to list any component-devices in this command. -+.\"option is given, it is not necessary to list any component devices in this command. - .\"They can be added later, before a - .\".B \-\-run. - .\"If no -@@ -2263,7 +2263,7 @@ requested with the - .B \-\-bitmap - option or a different consistency policy is selected with the - .B \-\-consistency\-policy --option. In any case space for a bitmap will be reserved so that one -+option. In any case, space for a bitmap will be reserved so that one - can be added later with - .BR "\-\-grow \-\-bitmap=internal" . - -@@ -2313,7 +2313,7 @@ will firstly mark - as faulty in - .B /dev/md0 - and will then remove it from the array and finally add it back --in as a spare. However only one md array can be affected by a single -+in as a spare. However, only one md array can be affected by a single - command. - - When a device is added to an active array, mdadm checks to see if it -@@ -2458,14 +2458,14 @@ config file to be examined. - If the device contains RAID metadata, a file will be created in the - .I directory - and the metadata will be written to it. The file will be the same --size as the device and have the metadata written in the file at the --same locate that it exists in the device. However the file will be "sparse" so -+size as the device and will have the metadata written at the -+same location as it exists in the device. However, the file will be "sparse" so - that only those blocks containing metadata will be allocated. The - total space used will be small. - --The file name used in the -+The filename used in the - .I directory --will be the base name of the device. Further if any links appear in -+will be the base name of the device. Further, if any links appear in - .I /dev/disk/by-id - which point to the device, then hard links to the file will be created - in -@@ -2567,7 +2567,7 @@ and if the destination array has a failed drive but no spares. - - If any devices are listed on the command line, - .I mdadm --will only monitor those devices. Otherwise all arrays listed in the -+will only monitor those devices, otherwise, all arrays listed in the - configuration file will be monitored. Further, if - .B \-\-scan - is given, then any other md devices that appear in -@@ -2624,10 +2624,10 @@ check, repair). (syslog priority: Warning) - .BI Rebuild NN - Where - .I NN --is a two-digit number (ie. 05, 48). This indicates that rebuild --has passed that many percent of the total. The events are generated --with fixed increment since 0. Increment size may be specified with --a commandline option (default is 20). (syslog priority: Warning) -+is a two-digit number (eg. 05, 48). This indicates that the rebuild -+has reached that percentage of the total. The events are generated -+at a fixed increment from 0. The increment size may be specified with -+a command-line option (the default is 20). (syslog priority: Warning) - - .TP - .B RebuildFinished -@@ -2735,8 +2735,8 @@ When - detects that an array in a spare group has fewer active - devices than necessary for the complete array, and has no spare - devices, it will look for another array in the same spare group that --has a full complement of working drive and a spare. It will then --attempt to remove the spare from the second drive and add it to the -+has a full complement of working drives and a spare. It will then -+attempt to remove the spare from the second array and add it to the - first. - If the removal succeeds but the adding fails, then it is added back to - the original array. -@@ -2750,10 +2750,8 @@ and then follow similar steps as above if a matching spare is found. - .SH GROW MODE - The GROW mode is used for changing the size or shape of an active - array. --For this to work, the kernel must support the necessary change. --Various types of growth are being added during 2.6 development. - --Currently the supported changes include -+During the kernel 2.6 era the following changes were added: - .IP \(bu 4 - change the "size" attribute for RAID1, RAID4, RAID5 and RAID6. - .IP \(bu 4 -@@ -2796,8 +2794,8 @@ use more than half of a spare device for backup space. - - .SS SIZE CHANGES - Normally when an array is built the "size" is taken from the smallest --of the drives. If all the small drives in an arrays are, one at a --time, removed and replaced with larger drives, then you could have an -+of the drives. If all the small drives in an arrays are, over time, -+removed and replaced with larger drives, then you could have an - array of large drives with only a small amount used. In this - situation, changing the "size" with "GROW" mode will allow the extra - space to start being used. If the size is increased in this way, a -@@ -2812,7 +2810,7 @@ after growing, or to reduce its size - .B prior - to shrinking the array. - --Also the size of an array cannot be changed while it has an active -+Also, the size of an array cannot be changed while it has an active - bitmap. If an array has a bitmap, it must be removed before the size - can be changed. Once the change is complete a new bitmap can be created. - -@@ -2892,7 +2890,7 @@ long time. A - is required. If the array is not simultaneously being grown or - shrunk, so that the array size will remain the same - for example, - reshaping a 3-drive RAID5 into a 4-drive RAID6 - the backup file will --be used not just for a "cricital section" but throughout the reshape -+be used not just for a "critical section" but throughout the reshape - operation, as described below under LAYOUT CHANGES. - - .SS CHUNK-SIZE AND LAYOUT CHANGES -@@ -2910,7 +2908,7 @@ slowly. - If the reshape is interrupted for any reason, this backup file must be - made available to - .B "mdadm --assemble" --so the array can be reassembled. Consequently the file cannot be -+so the array can be reassembled. Consequently, the file cannot be - stored on the device being reshaped. - - --- -2.38.1 - diff --git a/SOURCES/0055-Manage-Block-unsafe-member-failing.patch b/SOURCES/0055-Manage-Block-unsafe-member-failing.patch deleted file mode 100644 index 290c56f..0000000 --- a/SOURCES/0055-Manage-Block-unsafe-member-failing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Thu, 18 Aug 2022 11:47:21 +0200 -Subject: [PATCH 55/83] Manage: Block unsafe member failing - -Kernel may or may not block mdadm from removing member device if it -will cause arrays failed state. It depends on raid personality -implementation in kernel. -Add verification on requested removal path (#mdadm --set-faulty -command). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 52 insertions(+), 1 deletion(-) - -diff --git a/Manage.c b/Manage.c -index a142f8bd..b1d0e630 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1285,6 +1285,50 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv, - return -1; - } - -+/** -+ * is_remove_safe() - Check if remove is safe. -+ * @array: Array info. -+ * @fd: Array file descriptor. -+ * @devname: Name of device to remove. -+ * @verbose: Verbose. -+ * -+ * The function determines if array will be operational -+ * after removing &devname. -+ * -+ * Return: True if array will be operational, false otherwise. -+ */ -+bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose) -+{ -+ dev_t devid = devnm2devid(devname + 5); -+ struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE); -+ -+ if (!mdi) { -+ if (verbose) -+ pr_err("Failed to read sysfs attributes for %s\n", devname); -+ return false; -+ } -+ -+ char *avail = xcalloc(array->raid_disks, sizeof(char)); -+ -+ for (mdi = mdi->devs; mdi; mdi = mdi->next) { -+ if (mdi->disk.raid_disk < 0) -+ continue; -+ if (!(mdi->disk.state & (1 << MD_DISK_SYNC))) -+ continue; -+ if (makedev(mdi->disk.major, mdi->disk.minor) == devid) -+ continue; -+ avail[mdi->disk.raid_disk] = 1; -+ } -+ sysfs_free(mdi); -+ -+ bool is_enough = enough(array->level, array->raid_disks, -+ array->layout, (array->state & 1), -+ avail); -+ -+ free(avail); -+ return is_enough; -+} -+ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - char *update, int force) -@@ -1598,7 +1642,14 @@ int Manage_subdevs(char *devname, int fd, - break; - - case 'f': /* set faulty */ -- /* FIXME check current member */ -+ if (!is_remove_safe(&array, fd, dv->devname, verbose)) { -+ pr_err("Cannot remove %s from %s, array will be failed.\n", -+ dv->devname, devname); -+ if (sysfd >= 0) -+ close(sysfd); -+ goto abort; -+ } -+ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch b/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch deleted file mode 100644 index ad36a25..0000000 --- a/SOURCES/0056-Monitor-Fix-statelist-memory-leaks.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001 -From: Pawel Baldysiak -Date: Thu, 1 Sep 2022 11:20:31 +0200 -Subject: [PATCH 56/83] Monitor: Fix statelist memory leaks - -Free statelist in error path in Monitor initialization. - -Signed-off-by: Pawel Baldysiak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 40 +++++++++++++++++++++++++++++++--------- - 1 file changed, 31 insertions(+), 9 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 93f36ac0..b4e954c6 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - int test, struct alert_info *info); - static void try_spare_migration(struct state *statelist, struct alert_info *info); - static void link_containers_with_subarrays(struct state *list); -+static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -@@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist, - */ - - struct state *statelist = NULL; -- struct state *st2; - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -@@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -+ if (!is_mddev(mdlist->devname)) { -+ free_statelist(statelist); -+ return 1; -+ } - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), - "/dev/md/%s", basename(mdlist->devname)); -- if (!is_mddev(mdlist->devname)) -- return 1; - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) -+ if (!is_mddev(dv->devname)) { -+ free_statelist(statelist); - return 1; -+ } - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -@@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist, - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { - *stp = st->next; -- free(st->spare_group); -+ if (st->spare_group) -+ free(st->spare_group); -+ - free(st); - } else - stp = &st->next; - } - } -- for (st2 = statelist; st2; st2 = statelist) { -- statelist = st2->next; -- free(st2); -- } -+ -+ free_statelist(statelist); - - if (pidfile) - unlink(pidfile); -@@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list) - } - } - -+/** -+ * free_statelist() - Frees statelist. -+ * @statelist: statelist to free -+ */ -+static void free_statelist(struct state *statelist) -+{ -+ struct state *tmp = NULL; -+ -+ while (statelist) { -+ if (statelist->spare_group) -+ free(statelist->spare_group); -+ -+ tmp = statelist; -+ statelist = statelist->next; -+ free(tmp); -+ } -+} -+ - #ifndef NO_LIBUDEV - /* function: check_udev_activity - * Description: Function waits for udev to finish --- -2.38.1 - diff --git a/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch b/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch deleted file mode 100644 index 79a3262..0000000 --- a/SOURCES/0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ea7a02a3294aae223e1329aed5da7f4aa3ac05c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= -Date: Wed, 31 Aug 2022 19:57:29 +0200 -Subject: [PATCH 57/83] mdadm: added support for Intel Alderlake RST on VMD - platform -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Alderlake RST on VMD uses RstVmdV UEFI variable name, so detect it. - -Signed-off-by: Oldřich Jedlička -Reviewed-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index 5a8729e7..757f0b1b 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -512,7 +512,8 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) - #define AHCI_PROP "RstSataV" - #define AHCI_SSATA_PROP "RstsSatV" - #define AHCI_TSATA_PROP "RsttSatV" --#define VMD_PROP "RstUefiV" -+#define VROC_VMD_PROP "RstUefiV" -+#define RST_VMD_PROP "RstVmdV" - - #define VENDOR_GUID \ - EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) -@@ -605,6 +606,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - struct orom_entry *ret; - static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP, - AHCI_TSATA_PROP}; -+ static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP}; - unsigned long i; - - if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) -@@ -636,10 +638,16 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - - break; - case SYS_DEV_VMD: -- if (!read_efi_variable(&orom, sizeof(orom), VMD_PROP, -- VENDOR_GUID)) -- break; -- return NULL; -+ for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { -+ if (!read_efi_variable(&orom, sizeof(orom), -+ vmd_efivars[i], VENDOR_GUID)) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(vmd_efivars)) -+ return NULL; -+ -+ break; - default: - return NULL; - } --- -2.38.1 - diff --git a/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch b/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch deleted file mode 100644 index 6e1a179..0000000 --- a/SOURCES/0058-mdadm-Add-Documentation-entries-to-systemd-services.patch +++ /dev/null @@ -1,111 +0,0 @@ -From ea109700563d93704ebdc540c7770d874369f667 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:33 +0200 -Subject: [PATCH 58/83] mdadm: Add Documentation entries to systemd services - -Add documentation section. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdadm-last-resort@.service | 1 + - systemd/mdcheck_continue.service | 3 ++- - systemd/mdcheck_start.service | 1 + - systemd/mdmon@.service | 1 + - systemd/mdmonitor-oneshot.service | 1 + - systemd/mdmonitor.service | 1 + - 7 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9fdc8ec7..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -8,6 +8,7 @@ - [Unit] - Description=Manage MD Reshape on /dev/%I - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - ExecStart=BINDIR/mdadm --grow --continue /dev/%I -diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service -index efeb3f63..e9381125 100644 ---- a/systemd/mdadm-last-resort@.service -+++ b/systemd/mdadm-last-resort@.service -@@ -2,6 +2,7 @@ - Description=Activate md array %I even though degraded - DefaultDependencies=no - ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index 854317f1..f5324905 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -7,7 +7,8 @@ - - [Unit] - Description=MD array scrubbing - continuation --ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* -+ConditionPathExistsGlob=/var/lib/mdcheck/MD_UUID_* -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 3bb3d130..703a6583 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array scrubbing - Wants=mdcheck_continue.timer -+Documentation=man:mdadm(8) - - [Service] - Type=oneshot -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 77533958..97a1acd9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -9,6 +9,7 @@ - Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target -+Documentation=man:mdmon(8) - - [Service] - # mdmon should never complain due to lack of a platform, -diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service -index 373955a2..ba86b44e 100644 ---- a/systemd/mdmonitor-oneshot.service -+++ b/systemd/mdmonitor-oneshot.service -@@ -7,6 +7,7 @@ - - [Unit] - Description=Reminder for degraded MD arrays -+Documentation=man:mdadm(8) - - [Service] - Environment=MDADM_MONITOR_ARGS=--scan -diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service -index 46f7b880..9c364785 100644 ---- a/systemd/mdmonitor.service -+++ b/systemd/mdmonitor.service -@@ -8,6 +8,7 @@ - [Unit] - Description=MD array monitor - DefaultDependencies=no -+Documentation=man:mdadm(8) - - [Service] - Environment= MDADM_MONITOR_ARGS=--scan --- -2.38.1 - diff --git a/SOURCES/0059-ReadMe-fix-command-line-help.patch b/SOURCES/0059-ReadMe-fix-command-line-help.patch deleted file mode 100644 index 837a339..0000000 --- a/SOURCES/0059-ReadMe-fix-command-line-help.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f7cbd810b639eb946ba1b3bddb1faefb9696de42 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Fri, 9 Sep 2022 15:50:34 +0200 -Subject: [PATCH 59/83] ReadMe: fix command-line help - -Make command-line help consistent with manual page. -Copied from Debian. - -Cc: Felix Lechner -Signed-off-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 7f94847e..50a5e36d 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -477,7 +477,7 @@ char Help_assemble[] = - ; - - char Help_manage[] = --"Usage: mdadm arraydevice options component devices...\n" -+"Usage: mdadm [mode] arraydevice [options] \n" - "\n" - "This usage is for managing the component devices within an array.\n" - "The --manage option is not needed and is assumed if the first argument\n" --- -2.38.1 - diff --git a/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch b/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch deleted file mode 100644 index 7b2b6b2..0000000 --- a/SOURCES/0060-mdadm-replace-container-level-checking-with-inline.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 6f2af6a48c541f207cb727a31fb86de2cd04fc21 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 2 Sep 2022 08:49:23 +0200 -Subject: [PATCH 60/83] mdadm: replace container level checking with inline - -To unify all containers checks in code, is_container() function is -added and propagated. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Assemble.c | 7 +++---- - Create.c | 6 +++--- - Grow.c | 6 +++--- - Incremental.c | 4 ++-- - mdadm.h | 14 ++++++++++++++ - super-ddf.c | 6 +++--- - super-intel.c | 4 ++-- - super0.c | 2 +- - super1.c | 2 +- - sysfs.c | 2 +- - 10 files changed, 33 insertions(+), 20 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 1dd82a8c..8b0af0c9 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1120,7 +1120,7 @@ static int start_array(int mdfd, - i/2, mddev); - } - -- if (content->array.level == LEVEL_CONTAINER) { -+ if (is_container(content->array.level)) { - sysfs_rules_apply(mddev, content); - if (c->verbose >= 0) { - pr_err("Container %s has been assembled with %d drive%s", -@@ -1549,8 +1549,7 @@ try_again: - */ - trustworthy = LOCAL; - -- if (name[0] == 0 && -- content->array.level == LEVEL_CONTAINER) { -+ if (!name[0] && is_container(content->array.level)) { - name = content->text_version; - trustworthy = METADATA; - } -@@ -1809,7 +1808,7 @@ try_again: - } - #endif - } -- if (c->force && !clean && content->array.level != LEVEL_CONTAINER && -+ if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { - change += st->ss->update_super(st, content, "force-array", -diff --git a/Create.c b/Create.c -index e06ec2ae..953e7372 100644 ---- a/Create.c -+++ b/Create.c -@@ -487,7 +487,7 @@ int Create(struct supertype *st, char *mddev, - st->minor_version >= 1) - /* metadata at front */ - warn |= check_partitions(fd, dname, 0, 0); -- else if (s->level == 1 || s->level == LEVEL_CONTAINER || -+ else if (s->level == 1 || is_container(s->level) || - (s->level == 0 && s->raiddisks == 1)) - /* partitions could be meaningful */ - warn |= check_partitions(fd, dname, freesize*2, s->size*2); -@@ -997,7 +997,7 @@ int Create(struct supertype *st, char *mddev, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && s->level != LEVEL_CONTAINER && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info.uuid, 0)) { - map_update(&map, fd2devnm(mdfd), - info_new.text_version, -@@ -1040,7 +1040,7 @@ int Create(struct supertype *st, char *mddev, - map_unlock(&map); - free(infos); - -- if (s->level == LEVEL_CONTAINER) { -+ if (is_container(s->level)) { - /* No need to start. But we should signal udev to - * create links */ - sysfs_uevent(&info, "change"); -diff --git a/Grow.c b/Grow.c -index 0f07a894..e362403a 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -2175,7 +2175,7 @@ size_change_error: - devname, s->size); - } - changed = 1; -- } else if (array.level != LEVEL_CONTAINER) { -+ } else if (!is_container(array.level)) { - s->size = get_component_size(fd)/2; - if (s->size == 0) - s->size = array.size; -@@ -2231,7 +2231,7 @@ size_change_error: - info.component_size = s->size*2; - info.new_level = s->level; - info.new_chunk = s->chunk * 1024; -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - info.delta_disks = UnSet; - info.array.raid_disks = s->raiddisks; - } else if (s->raiddisks) -@@ -2344,7 +2344,7 @@ size_change_error: - printf("layout for %s set to %d\n", - devname, array.layout); - } -- } else if (array.level == LEVEL_CONTAINER) { -+ } else if (is_container(array.level)) { - /* This change is to be applied to every array in the - * container. This is only needed when the metadata imposes - * restraints of the various arrays in the container. -diff --git a/Incremental.c b/Incremental.c -index 4d0cd9d6..5a5f4c4c 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -244,7 +244,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - c->autof = ci->autof; - - name_to_use = info.name; -- if (name_to_use[0] == 0 && info.array.level == LEVEL_CONTAINER) { -+ if (name_to_use[0] == 0 && is_container(info.array.level)) { - name_to_use = info.text_version; - trustworthy = METADATA; - } -@@ -472,7 +472,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - - /* 7/ Is there enough devices to possibly start the array? */ - /* 7a/ if not, finish with success. */ -- if (info.array.level == LEVEL_CONTAINER) { -+ if (is_container(info.array.level)) { - char devnm[32]; - /* Try to assemble within the container */ - sysfs_uevent(sra, "change"); -diff --git a/mdadm.h b/mdadm.h -index 941a5f38..3673494e 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1924,3 +1924,17 @@ enum r0layout { - * This is true for native and DDF, IMSM allows 16. - */ - #define MD_NAME_MAX 32 -+ -+/** -+ * is_container() - check if @level is &LEVEL_CONTAINER -+ * @level: level value -+ * -+ * return: -+ * 1 if level is equal to &LEVEL_CONTAINER, 0 otherwise. -+ */ -+static inline int is_container(const int level) -+{ -+ if (level == LEVEL_CONTAINER) -+ return 1; -+ return 0; -+} -diff --git a/super-ddf.c b/super-ddf.c -index 949e7d15..9d1e3b94 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -3325,7 +3325,7 @@ validate_geometry_ddf_container(struct supertype *st, - int fd; - unsigned long long ldsize; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -3371,7 +3371,7 @@ static int validate_geometry_ddf(struct supertype *st, - - if (level == LEVEL_NONE) - level = LEVEL_CONTAINER; -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - /* Must be a fresh device to add to a container */ - return validate_geometry_ddf_container(st, level, raiddisks, - data_offset, dev, -@@ -3488,7 +3488,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, - struct dl *dl; - unsigned long long maxsize; - /* ddf/bvd supports lots of things, but not containers */ -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("DDF cannot create a container within an container\n"); - return 0; -diff --git a/super-intel.c b/super-intel.c -index 4d82af3d..b0565610 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6727,7 +6727,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, - struct intel_super *super = NULL; - int rv = 0; - -- if (level != LEVEL_CONTAINER) -+ if (!is_container(level)) - return 0; - if (!dev) - return 1; -@@ -7692,7 +7692,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - * if given unused devices create a container - * if given given devices in a container create a member volume - */ -- if (level == LEVEL_CONTAINER) -+ if (is_container(level)) - /* Must be a fresh device to add to a container */ - return validate_geometry_imsm_container(st, level, raiddisks, - data_offset, dev, -diff --git a/super0.c b/super0.c -index 37f595ed..93876e2e 100644 ---- a/super0.c -+++ b/super0.c -@@ -1273,7 +1273,7 @@ static int validate_geometry0(struct supertype *st, int level, - if (get_linux_version() < 3001000) - tbmax = 2; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("0.90 metadata does not support containers\n"); - return 0; -diff --git a/super1.c b/super1.c -index 58345e68..0b505a7e 100644 ---- a/super1.c -+++ b/super1.c -@@ -2830,7 +2830,7 @@ static int validate_geometry1(struct supertype *st, int level, - unsigned long long overhead; - int fd; - -- if (level == LEVEL_CONTAINER) { -+ if (is_container(level)) { - if (verbose) - pr_err("1.x metadata does not support containers\n"); - return 0; -diff --git a/sysfs.c b/sysfs.c -index 0d98a65f..ca1d888f 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -763,7 +763,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume) - - rv = sysfs_set_num(sra, sd, "offset", sd->data_offset); - rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2); -- if (sra->array.level != LEVEL_CONTAINER) { -+ if (!is_container(sra->array.level)) { - if (sra->consistency_policy == CONSISTENCY_POLICY_PPL) { - rv |= sysfs_set_num(sra, sd, "ppl_sector", sd->ppl_sector); - rv |= sysfs_set_num(sra, sd, "ppl_size", sd->ppl_size); --- -2.38.1 - diff --git a/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch b/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch deleted file mode 100644 index 062ecdf..0000000 --- a/SOURCES/0061-Mdmonitor-Omit-non-md-devices.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8b668d4aa3305af5963162b7499b128bd71f8f29 Mon Sep 17 00:00:00 2001 -From: Lukasz Florczak -Date: Thu, 22 Sep 2022 08:29:50 +0200 -Subject: [PATCH 61/83] Mdmonitor: Omit non-md devices - -Fix segfault commit [1] introduced check whether given device is -mddevice, but it happend to terminate Mdmonitor if at least one of given -devices didn't fulfill that condition. In result Mdmonitor service was -no longer started on boot (with --scan option) when config contained some -non-existent array entry. - -This commit introduces ommiting non-md devices so scan option can still -be used when config is wrong and allow Mdmonitor service to run on boot. - -Giving a list of devices to monitor containing non-existing or -non-md devices will result in monitoring only confirmed mddevices. - -[1] https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=e702f392959d1c2ad2089e595b52235ed97b4e18 - -Signed-off-by: Lukasz Florczak -Signed-off-by: Jes Sorensen ---- - Monitor.c | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index b4e954c6..7d7dc4d2 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -185,10 +185,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - if (strcasecmp(mdlist->devname, "") == 0) - continue; -- if (!is_mddev(mdlist->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(mdlist->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -@@ -208,10 +206,8 @@ int Monitor(struct mddev_dev *devlist, - for (dv = devlist; dv; dv = dv->next) { - struct state *st; - -- if (!is_mddev(dv->devname)) { -- free_statelist(statelist); -- return 1; -- } -+ if (!is_mddev(dv->devname)) -+ continue; - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); --- -2.38.1 - diff --git a/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch b/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch deleted file mode 100644 index c7562e7..0000000 --- a/SOURCES/0062-Mdmonitor-Split-alert-into-separate-functions.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 3698867194f27fdd7824b8bdd172d619a2c087cc Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 7 Sep 2022 14:56:49 +0200 -Subject: [PATCH 62/83] Mdmonitor: Split alert() into separate functions - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 186 ++++++++++++++++++++++++++++-------------------------- - 1 file changed, 95 insertions(+), 91 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 7d7dc4d2..0036e8cd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -66,7 +66,7 @@ struct alert_info { - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(char *event, char *dev, char *disc, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); - static int check_array(struct state *st, struct mdstat_ent *mdstat, - int test, struct alert_info *info, - int increments, char *prefer); -@@ -407,111 +407,115 @@ static void write_autorebuild_pid() - } - } - --static void alert(char *event, char *dev, char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ int pid = fork(); -+ -+ switch (pid) { -+ default: -+ waitpid(pid, NULL, 0); -+ break; -+ case -1: -+ pr_err("Cannot fork to execute alert command"); -+ break; -+ case 0: -+ execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ exit(2); -+ } -+} -+ -+static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ -+ FILE *mp, *mdstat; -+ char hname[256]; -+ char buf[BUFSIZ]; -+ int n; -+ -+ mp = popen(Sendmail, "w"); -+ if (!mp) { -+ pr_err("Cannot open pipe stream for sendmail.\n"); -+ return; -+ } -+ -+ gethostname(hname, sizeof(hname)); -+ signal(SIGPIPE, SIG_IGN); -+ if (info->mailfrom) -+ fprintf(mp, "From: %s\n", info->mailfrom); -+ else -+ fprintf(mp, "From: %s monitoring \n", Name); -+ fprintf(mp, "To: %s\n", info->mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "This is an automatically generated mail message. \n"); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ -+ if (disc && disc[0] != ' ') -+ fprintf(mp, -+ "It could be related to component device %s.\n\n", disc); -+ if (disc && disc[0] == ' ') -+ fprintf(mp, "Extra information:%s.\n\n", disc); -+ -+ mdstat = fopen("/proc/mdstat", "r"); -+ if (!mdstat) { -+ pr_err("Cannot open /proc/mdstat\n"); -+ pclose(mp); -+ return; -+ } -+ -+ fprintf(mp, "The /proc/mdstat file currently contains the following:\n\n"); -+ while ((n = fread(buf, 1, sizeof(buf), mdstat)) > 0) -+ n = fwrite(buf, 1, n, mp); -+ fclose(mdstat); -+ pclose(mp); -+} -+ -+static void log_event_to_syslog(const char *event, const char *dev, const char *disc) - { - int priority; -+ /* Log at a different severity depending on the event. -+ * -+ * These are the critical events: */ -+ if (strncmp(event, "Fail", 4) == 0 || -+ strncmp(event, "Degrade", 7) == 0 || -+ strncmp(event, "DeviceDisappeared", 17) == 0) -+ priority = LOG_CRIT; -+ /* Good to know about, but are not failures: */ -+ else if (strncmp(event, "Rebuild", 7) == 0 || -+ strncmp(event, "MoveSpare", 9) == 0 || -+ strncmp(event, "Spares", 6) != 0) -+ priority = LOG_WARNING; -+ /* Everything else: */ -+ else -+ priority = LOG_INFO; - -+ if (disc && disc[0] != ' ') -+ syslog(priority, -+ "%s event detected on md device %s, component device %s", event, dev, disc); -+ else if (disc) -+ syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ else -+ syslog(priority, "%s event detected on md device %s", event, dev); -+} -+ -+static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+{ - if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) { -- int pid = fork(); -- switch(pid) { -- default: -- waitpid(pid, NULL, 0); -- break; -- case -1: -- break; -- case 0: -- execl(info->alert_cmd, info->alert_cmd, -- event, dev, disc, NULL); -- exit(2); -- } -- } -+ if (info->alert_cmd) -+ execute_alert_cmd(event, dev, disc, info); -+ - if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- FILE *mp = popen(Sendmail, "w"); -- if (mp) { -- FILE *mdstat; -- char hname[256]; -- -- gethostname(hname, sizeof(hname)); -- signal_s(SIGPIPE, SIG_IGN); -- -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -- else -- fprintf(mp, "From: %s monitoring \n", -- Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", -- event, dev, hname); -- -- fprintf(mp, -- "This is an automatically generated mail message from %s\n", Name); -- fprintf(mp, "running on %s\n\n", hname); -- -- fprintf(mp, -- "A %s event had been detected on md device %s.\n\n", event, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -- -- fprintf(mp, "Faithfully yours, etc.\n"); -- -- mdstat = fopen("/proc/mdstat", "r"); -- if (mdstat) { -- char buf[8192]; -- int n; -- fprintf(mp, -- "\nP.S. The /proc/mdstat file currently contains the following:\n\n"); -- while ((n = fread(buf, 1, sizeof(buf), -- mdstat)) > 0) -- n = fwrite(buf, 1, n, mp); -- fclose(mdstat); -- } -- pclose(mp); -- } -+ send_event_email(event, dev, disc, info); - } - -- /* log the event to syslog maybe */ -- if (info->dosyslog) { -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -- else if (disc) -- syslog(priority, -- "%s event detected on md device %s: %s", -- event, dev, disc); -- else -- syslog(priority, -- "%s event detected on md device %s", -- event, dev); -- } -+ if (info->dosyslog) -+ log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, --- -2.38.1 - diff --git a/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch b/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch deleted file mode 100644 index d993d9d..0000000 --- a/SOURCES/0063-Monitor-block-if-monitor-modes-are-combined.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f40ac0e7e6043361ad12e9db97c07e56c3977cf6 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:57 +0100 -Subject: [PATCH 63/83] Monitor: block if monitor modes are combined. - -Block monitoring start if --scan mode and MD devices list are combined. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Monitor.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/Monitor.c b/Monitor.c -index 0036e8cd..188cb8be 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -123,7 +123,7 @@ int Monitor(struct mddev_dev *devlist, - * and if we can get_disk_info and find a name - * Then we hot-remove and hot-add to the other array - * -- * If devlist is NULL, then we can monitor everything because --scan -+ * If devlist is NULL, then we can monitor everything if --scan - * was given. We get an initial list from config file and add anything - * that appears in /proc/mdstat - */ -@@ -136,6 +136,11 @@ int Monitor(struct mddev_dev *devlist, - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -+ if (devlist && c->scan) { -+ pr_err("Devices list and --scan option cannot be combined - not monitoring.\n"); -+ return 1; -+ } -+ - if (!mailaddr) - mailaddr = conf_get_mailaddr(); - --- -2.38.1 - diff --git a/SOURCES/0064-Update-mdadm-Monitor-manual.patch b/SOURCES/0064-Update-mdadm-Monitor-manual.patch deleted file mode 100644 index 15f52e1..0000000 --- a/SOURCES/0064-Update-mdadm-Monitor-manual.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 725e37cd14866906ba28c970394b9f7a4cd97413 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Mon, 19 Dec 2022 11:21:58 +0100 -Subject: [PATCH 64/83] Update mdadm Monitor manual. - -- describe monitor work modes, -- clarify the turning off condition, -- describe the mdmonitor.service as a prefered management way. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 71 ++++++++++++++++++++++++++++++++++++++---------------- - 1 file changed, 50 insertions(+), 21 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 70c79d1e..64f71ed1 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -2548,13 +2548,33 @@ Usage: - .I options... devices... - - .PP --This usage causes -+Monitor option can work in two modes: -+.IP \(bu 4 -+system wide mode, follow all md devices based on -+.B /proc/mdstat, -+.IP \(bu 4 -+follow only specified MD devices in command line. -+.PP -+ -+.B \-\-scan - -+indicates system wide mode. Option causes the -+.I monitor -+to track all md devices that appear in -+.B /proc/mdstat. -+If it is not set, then at least one -+.B device -+must be specified. -+ -+Monitor usage causes - .I mdadm - to periodically poll a number of md arrays and to report on any events - noticed. --.I mdadm --will never exit once it decides that there are arrays to be checked, --so it should normally be run in the background. -+ -+In both modes, -+.I monitor -+will work as long as there is an active array with redundancy and it is defined to follow (for -+.B \-\-scan -+every array is followed). - - As well as reporting events, - .I mdadm -@@ -2565,15 +2585,6 @@ or - .B domain - and if the destination array has a failed drive but no spares. - --If any devices are listed on the command line, --.I mdadm --will only monitor those devices, otherwise, all arrays listed in the --configuration file will be monitored. Further, if --.B \-\-scan --is given, then any other md devices that appear in --.B /proc/mdstat --will also be monitored. -- - The result of monitoring the arrays is the generation of events. - These events are passed to a separate program (if specified) and may - be mailed to a given E-mail address. -@@ -2586,16 +2597,34 @@ device if relevant (such as a component device that has failed). - - If - .B \-\-scan --is given, then a program or an E-mail address must be specified on the --command line or in the config file. If neither are available, then -+is given, then a -+.B program -+or an -+.B e-mail -+address must be specified on the -+command line or in the config file. If neither are available, then - .I mdadm - will not monitor anything. --Without --.B \-\-scan, --.I mdadm --will continue monitoring as long as something was found to monitor. If --no program or email is given, then each event is reported to --.BR stdout . -+For devices given directly in command line, without -+.B program -+or -+.B email -+specified, each event is reported to -+.BR stdout. -+ -+Note: For systems where -+.If mdadm monitor -+is configured via systemd, -+.B mdmonitor(mdmonitor.service) -+should be configured. The service is designed to be primary solution for array monitoring, -+it is configured to work in system wide mode. -+It is automatically started and stopped according to current state and types of MD arrays in system. -+The service may require additional configuration, like -+.B e-mail -+or -+.B delay. -+That should be done in -+.B mdadm.conf. - - The different events are: - --- -2.38.1 - diff --git a/SOURCES/0065-Grow-fix-possible-memory-leak.patch b/SOURCES/0065-Grow-fix-possible-memory-leak.patch deleted file mode 100644 index 07d9fb6..0000000 --- a/SOURCES/0065-Grow-fix-possible-memory-leak.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 434b3b9bb96a76dc12f693b64cf23b581781e20b Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Tue, 20 Dec 2022 12:07:51 +0100 -Subject: [PATCH 65/83] Grow: fix possible memory leak. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Grow.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index e362403a..b73ec2ae 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -432,6 +432,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); -+ free(mdi); - return 1; - } - fd2 = dev_open(dv, O_RDWR); -@@ -453,8 +454,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - pr_err("failed to load super-block.\n"); - } - close(fd2); -- if (rv) -+ if (rv) { -+ free(mdi); - return 1; -+ } - } - if (offset_setable) { - st->ss->getinfo_super(st, mdi, NULL); --- -2.38.1 - diff --git a/SOURCES/0066-mdadm-create-ident_init.patch b/SOURCES/0066-mdadm-create-ident_init.patch deleted file mode 100644 index 32d374b..0000000 --- a/SOURCES/0066-mdadm-create-ident_init.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 7fcbfd7c620e2dcd3b539d18e93cb503ee3a8a62 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Wed, 21 Dec 2022 12:50:17 +0100 -Subject: [PATCH 66/83] mdadm: create ident_init() - -Add a wrapper for repeated initializations in mdadm.c and config.c. -Move includes up. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 45 +++++++++++++++++++++++++++++---------------- - mdadm.c | 16 ++-------------- - mdadm.h | 7 +++++-- - 3 files changed, 36 insertions(+), 32 deletions(-) - -diff --git a/config.c b/config.c -index dc1620c1..eeedd0c6 100644 ---- a/config.c -+++ b/config.c -@@ -119,6 +119,34 @@ int match_keyword(char *word) - return -1; - } - -+/** -+ * ident_init() - Set defaults. -+ * @ident: ident pointer, not NULL. -+ */ -+inline void ident_init(struct mddev_ident *ident) -+{ -+ assert(ident); -+ -+ ident->assembled = false; -+ ident->autof = 0; -+ ident->bitmap_fd = -1; -+ ident->bitmap_file = NULL; -+ ident->container = NULL; -+ ident->devices = NULL; -+ ident->devname = NULL; -+ ident->level = UnSet; -+ ident->member = NULL; -+ ident->name[0] = 0; -+ ident->next = NULL; -+ ident->raid_disks = UnSet; -+ ident->spare_group = NULL; -+ ident->spare_disks = 0; -+ ident->st = NULL; -+ ident->super_minor = UnSet; -+ ident->uuid[0] = 0; -+ ident->uuid_set = 0; -+} -+ - struct conf_dev { - struct conf_dev *next; - char *name; -@@ -363,22 +391,7 @@ void arrayline(char *line) - struct mddev_ident mis; - struct mddev_ident *mi; - -- mis.uuid_set = 0; -- mis.super_minor = UnSet; -- mis.level = UnSet; -- mis.raid_disks = UnSet; -- mis.spare_disks = 0; -- mis.devices = NULL; -- mis.devname = NULL; -- mis.spare_group = NULL; -- mis.autof = 0; -- mis.next = NULL; -- mis.st = NULL; -- mis.bitmap_fd = -1; -- mis.bitmap_file = NULL; -- mis.name[0] = 0; -- mis.container = NULL; -- mis.member = NULL; -+ ident_init(&mis); - - for (w = dl_next(line); w != line; w = dl_next(w)) { - if (w[0] == '/' || strchr(w, '=') == NULL) { -diff --git a/mdadm.c b/mdadm.c -index 972adb52..74fdec31 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,25 +107,13 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- ident.uuid_set = 0; -- ident.level = UnSet; -- ident.raid_disks = UnSet; -- ident.super_minor = UnSet; -- ident.devices = 0; -- ident.spare_group = NULL; -- ident.autof = 0; -- ident.st = NULL; -- ident.bitmap_fd = -1; -- ident.bitmap_file = NULL; -- ident.name[0] = 0; -- ident.container = NULL; -- ident.member = NULL; -- - if (get_linux_version() < 2006015) { - pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); - exit(1); - } - -+ ident_init(&ident); -+ - while ((option_index = -1), - (opt = getopt_long(argc, argv, shortopt, long_options, - &option_index)) != -1) { -diff --git a/mdadm.h b/mdadm.h -index 3673494e..23ffe977 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -33,8 +33,10 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); - # endif - #endif - -+#include - #include - #include -+#include - #include - #include - #include -@@ -1552,6 +1554,8 @@ extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name); - -+extern void ident_init(struct mddev_ident *ident); -+ - extern int parse_auto(char *str, char *msg, int config); - extern struct mddev_ident *conf_get_ident(char *dev); - extern struct mddev_dev *conf_get_devs(void); -@@ -1779,8 +1783,7 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler) - #define dprintf_cont(fmt, arg...) \ - ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) - #endif --#include --#include -+ - static inline int xasprintf(char **strp, const char *fmt, ...) { - va_list ap; - int ret; --- -2.38.1 - diff --git a/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch b/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch deleted file mode 100644 index faa7113..0000000 --- a/SOURCES/0067-mdadm-Add-option-validation-for-update-subarray.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 2568ce89ea5c26225e8984733adc2ea7559d853a Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:15 +0100 -Subject: [PATCH 67/83] mdadm: Add option validation for --update-subarray - -Subset of options available for "--update" is not same as for "--update-subarray". -Define maps and enum for update options and use them instead of direct comparisons. -Add proper error message. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - ReadMe.c | 31 +++++++++++++++++ - maps.c | 31 +++++++++++++++++ - mdadm.c | 104 +++++++++++++++++-------------------------------------- - mdadm.h | 32 ++++++++++++++++- - 4 files changed, 124 insertions(+), 74 deletions(-) - -diff --git a/ReadMe.c b/ReadMe.c -index 50a5e36d..bd8d50d2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -655,3 +655,34 @@ char *mode_help[mode_count] = { - [GROW] = Help_grow, - [INCREMENTAL] = Help_incr, - }; -+ -+/** -+ * fprint_update_options() - Print valid update options depending on the mode. -+ * @outf: File (output stream) -+ * @update_mode: Used to distinguish update and update_subarray -+ */ -+void fprint_update_options(FILE *outf, enum update_opt update_mode) -+{ -+ int counter = UOPT_NAME, breakpoint = UOPT_HELP; -+ mapping_t *map = update_options; -+ -+ if (!outf) -+ return; -+ if (update_mode == UOPT_SUBARRAY_ONLY) { -+ breakpoint = UOPT_SUBARRAY_ONLY; -+ fprintf(outf, "Valid --update options for update-subarray are:\n\t"); -+ } else -+ fprintf(outf, "Valid --update options are:\n\t"); -+ while (map->num) { -+ if (map->num >= breakpoint) -+ break; -+ fprintf(outf, "'%s', ", map->name); -+ if (counter % 5 == 0) -+ fprintf(outf, "\n\t"); -+ counter++; -+ map++; -+ } -+ if ((counter - 1) % 5) -+ fprintf(outf, "\n"); -+ fprintf(outf, "\r"); -+} -diff --git a/maps.c b/maps.c -index 20fcf719..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -165,6 +165,37 @@ mapping_t sysfs_array_states[] = { - { "broken", ARRAY_BROKEN }, - { NULL, ARRAY_UNKNOWN_STATE } - }; -+/** -+ * mapping_t update_options - stores supported update options. -+ */ -+mapping_t update_options[] = { -+ { "name", UOPT_NAME }, -+ { "ppl", UOPT_PPL }, -+ { "no-ppl", UOPT_NO_PPL }, -+ { "bitmap", UOPT_BITMAP }, -+ { "no-bitmap", UOPT_NO_BITMAP }, -+ { "sparc2.2", UOPT_SPARC22 }, -+ { "super-minor", UOPT_SUPER_MINOR }, -+ { "summaries", UOPT_SUMMARIES }, -+ { "resync", UOPT_RESYNC }, -+ { "uuid", UOPT_UUID }, -+ { "homehost", UOPT_HOMEHOST }, -+ { "home-cluster", UOPT_HOME_CLUSTER }, -+ { "nodes", UOPT_NODES }, -+ { "devicesize", UOPT_DEVICESIZE }, -+ { "bbl", UOPT_BBL }, -+ { "no-bbl", UOPT_NO_BBL }, -+ { "force-no-bbl", UOPT_FORCE_NO_BBL }, -+ { "metadata", UOPT_METADATA }, -+ { "revert-reshape", UOPT_REVERT_RESHAPE }, -+ { "layout-original", UOPT_LAYOUT_ORIGINAL }, -+ { "layout-alternate", UOPT_LAYOUT_ALTERNATE }, -+ { "layout-unspecified", UOPT_LAYOUT_UNSPECIFIED }, -+ { "byteorder", UOPT_BYTEORDER }, -+ { "help", UOPT_HELP }, -+ { "?", UOPT_HELP }, -+ { NULL, UOPT_UNDEFINED} -+}; - - /** - * map_num_s() - Safer alternative of map_num() function. -diff --git a/mdadm.c b/mdadm.c -index 74fdec31..f5f505fe 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -100,7 +100,7 @@ int main(int argc, char *argv[]) - char *dump_directory = NULL; - - int print_help = 0; -- FILE *outf; -+ FILE *outf = NULL; - - int mdfd = -1; - int locked = 0; -@@ -723,7 +723,11 @@ int main(int argc, char *argv[]) - continue; - - case O(ASSEMBLE,'U'): /* update the superblock */ -- case O(MISC,'U'): -+ case O(MISC,'U'): { -+ enum update_opt updateopt = map_name(update_options, c.update); -+ enum update_opt print_mode = UOPT_HELP; -+ const char *error_addon = "update option"; -+ - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", - c.update, optarg); -@@ -733,83 +737,37 @@ int main(int argc, char *argv[]) - pr_err("Only subarrays can be updated in misc mode\n"); - exit(2); - } -+ - c.update = optarg; -- if (strcmp(c.update, "sparc2.2") == 0) -- continue; -- if (strcmp(c.update, "super-minor") == 0) -- continue; -- if (strcmp(c.update, "summaries") == 0) -- continue; -- if (strcmp(c.update, "resync") == 0) -- continue; -- if (strcmp(c.update, "uuid") == 0) -- continue; -- if (strcmp(c.update, "name") == 0) -- continue; -- if (strcmp(c.update, "homehost") == 0) -- continue; -- if (strcmp(c.update, "home-cluster") == 0) -- continue; -- if (strcmp(c.update, "nodes") == 0) -- continue; -- if (strcmp(c.update, "devicesize") == 0) -- continue; -- if (strcmp(c.update, "bitmap") == 0) -- continue; -- if (strcmp(c.update, "no-bitmap") == 0) -- continue; -- if (strcmp(c.update, "bbl") == 0) -- continue; -- if (strcmp(c.update, "no-bbl") == 0) -- continue; -- if (strcmp(c.update, "force-no-bbl") == 0) -- continue; -- if (strcmp(c.update, "ppl") == 0) -- continue; -- if (strcmp(c.update, "no-ppl") == 0) -- continue; -- if (strcmp(c.update, "metadata") == 0) -- continue; -- if (strcmp(c.update, "revert-reshape") == 0) -- continue; -- if (strcmp(c.update, "layout-original") == 0 || -- strcmp(c.update, "layout-alternate") == 0 || -- strcmp(c.update, "layout-unspecified") == 0) -- continue; -- if (strcmp(c.update, "byteorder") == 0) { -+ -+ if (devmode == UpdateSubarray) { -+ print_mode = UOPT_SUBARRAY_ONLY; -+ error_addon = "update-subarray option"; -+ -+ if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -+ updateopt = UOPT_UNDEFINED; -+ } -+ -+ switch (updateopt) { -+ case UOPT_UNDEFINED: -+ pr_err("'--update=%s' is invalid %s. ", -+ c.update, error_addon); -+ outf = stderr; -+ case UOPT_HELP: -+ if (!outf) -+ outf = stdout; -+ fprint_update_options(outf, print_mode); -+ exit(outf == stdout ? 0 : 2); -+ case UOPT_BYTEORDER: - if (ss) { - pr_err("must not set metadata type with --update=byteorder.\n"); - exit(2); - } -- for(i = 0; !ss && superlist[i]; i++) -- ss = superlist[i]->match_metadata_desc( -- "0.swap"); -- if (!ss) { -- pr_err("INTERNAL ERROR cannot find 0.swap\n"); -- exit(2); -- } -- -- continue; -+ default: -+ break; - } -- if (strcmp(c.update,"?") == 0 || -- strcmp(c.update, "help") == 0) { -- outf = stdout; -- fprintf(outf, "%s: ", Name); -- } else { -- outf = stderr; -- fprintf(outf, -- "%s: '--update=%s' is invalid. ", -- Name, c.update); -- } -- fprintf(outf, "Valid --update options are:\n" -- " 'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n" -- " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n" -- " 'bitmap', 'no-bitmap', 'metadata', 'revert-reshape'\n" -- " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n" -- " 'layout-original', 'layout-alternate', 'layout-unspecified'\n" -- ); -- exit(outf == stdout ? 0 : 2); -- -+ continue; -+ } - case O(MANAGE,'U'): - /* update=devicesize is allowed with --re-add */ - if (devmode != 'A') { -diff --git a/mdadm.h b/mdadm.h -index 23ffe977..51f1db2d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -497,6 +497,36 @@ enum special_options { - ConsistencyPolicy, - }; - -+enum update_opt { -+ UOPT_NAME = 1, -+ UOPT_PPL, -+ UOPT_NO_PPL, -+ UOPT_BITMAP, -+ UOPT_NO_BITMAP, -+ UOPT_SUBARRAY_ONLY, -+ UOPT_SPARC22, -+ UOPT_SUPER_MINOR, -+ UOPT_SUMMARIES, -+ UOPT_RESYNC, -+ UOPT_UUID, -+ UOPT_HOMEHOST, -+ UOPT_HOME_CLUSTER, -+ UOPT_NODES, -+ UOPT_DEVICESIZE, -+ UOPT_BBL, -+ UOPT_NO_BBL, -+ UOPT_FORCE_NO_BBL, -+ UOPT_METADATA, -+ UOPT_REVERT_RESHAPE, -+ UOPT_LAYOUT_ORIGINAL, -+ UOPT_LAYOUT_ALTERNATE, -+ UOPT_LAYOUT_UNSPECIFIED, -+ UOPT_BYTEORDER, -+ UOPT_HELP, -+ UOPT_UNDEFINED -+}; -+extern void fprint_update_options(FILE *outf, enum update_opt update_mode); -+ - enum prefix_standard { - JEDEC, - IEC -@@ -777,7 +807,7 @@ extern char *map_num(mapping_t *map, int num); - extern int map_name(mapping_t *map, char *name); - extern mapping_t r0layout[], r5layout[], r6layout[], - pers[], modes[], faultylayout[]; --extern mapping_t consistency_policies[], sysfs_array_states[]; -+extern mapping_t consistency_policies[], sysfs_array_states[], update_options[]; - - extern char *map_dev_preferred(int major, int minor, int create, - char *prefer); --- -2.38.1 - diff --git a/SOURCES/0068-Fix-update-subarray-on-active-volume.patch b/SOURCES/0068-Fix-update-subarray-on-active-volume.patch deleted file mode 100644 index 7c1c4bc..0000000 --- a/SOURCES/0068-Fix-update-subarray-on-active-volume.patch +++ /dev/null @@ -1,54 +0,0 @@ -From db10eab68e652f141169b7240e057d110d626c3d Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:16 +0100 -Subject: [PATCH 68/83] Fix --update-subarray on active volume - -Options: bitmap, ppl and name should not be updated when array is active. -Those features are mutually exclusive and share the same data area in IMSM (danger of overwriting by kernel). -Remove check for active subarrays from super-intel. -Since ddf is not supported, apply it globally for all options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Manage.c | 7 +++++++ - super-intel.c | 5 ----- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/Manage.c b/Manage.c -index b1d0e630..5a9ea316 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1745,6 +1745,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -+ if (is_subarray_active(subarray, st->devnm)) { -+ if (verbose >= 0) -+ pr_err("Subarray %s in %s is active, cannot update %s\n", -+ subarray, dev, update); -+ goto free_super; -+ } -+ - if (mdmon_running(st->devnm)) - st->update_tail = &st->updates; - -diff --git a/super-intel.c b/super-intel.c -index b0565610..5f93f3d3 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7914,11 +7914,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - char *ep; - int vol; - -- if (is_subarray_active(subarray, st->devnm)) { -- pr_err("Unable to update name of active subarray\n"); -- return 2; -- } -- - if (!check_name(super, name, 0)) - return 2; - --- -2.38.1 - diff --git a/SOURCES/0069-Add-code-specific-update-options-to-enum.patch b/SOURCES/0069-Add-code-specific-update-options-to-enum.patch deleted file mode 100644 index 57386f5..0000000 --- a/SOURCES/0069-Add-code-specific-update-options-to-enum.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2257de106cbf17a7f1df33a10cfd2be0d5a064cb Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:17 +0100 -Subject: [PATCH 69/83] Add code specific update options to enum. - -Some of update options aren't taken from user input, but are hard-coded -as strings. -Include those options in enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - maps.c | 21 +++++++++++++++++++++ - mdadm.h | 15 +++++++++++++++ - 2 files changed, 36 insertions(+) - -diff --git a/maps.c b/maps.c -index b586679a..c59036f1 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,6 +194,27 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -+ /* -+ * Those enries are temporary and will be removed in this patchset. -+ * -+ * Before update_super:update can be changed to enum, -+ * all update_super sub-functions must be adapted first. -+ * Update options will be passed as string (as it is for now), -+ * and then mapped, so all options must be handled temporarily. -+ * -+ * Those options code specific and should not be accessible for user. -+ */ -+ { "force-one", UOPT_SPEC_FORCE_ONE }, -+ { "force-array", UOPT_SPEC_FORCE_ARRAY }, -+ { "assemble", UOPT_SPEC_ASSEMBLE }, -+ { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -+ { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -+ { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -+ { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -+ { "readwrite", UOPT_SPEC_READWRITE }, -+ { "failfast", UOPT_SPEC_FAILFAST }, -+ { "nofailfast", UOPT_SPEC_NOFAILFAST }, -+ { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 51f1db2d..31db25f5 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -523,6 +523,21 @@ enum update_opt { - UOPT_LAYOUT_UNSPECIFIED, - UOPT_BYTEORDER, - UOPT_HELP, -+ UOPT_USER_ONLY, -+ /* -+ * Code specific options, cannot be set by the user -+ */ -+ UOPT_SPEC_FORCE_ONE, -+ UOPT_SPEC_FORCE_ARRAY, -+ UOPT_SPEC_ASSEMBLE, -+ UOPT_SPEC_LINEAR_GROW_NEW, -+ UOPT_SPEC_LINEAR_GROW_UPDATE, -+ UOPT_SPEC__RESHAPE_PROGRESS, -+ UOPT_SPEC_WRITEMOSTLY, -+ UOPT_SPEC_READWRITE, -+ UOPT_SPEC_FAILFAST, -+ UOPT_SPEC_NOFAILFAST, -+ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - UOPT_UNDEFINED - }; - extern void fprint_update_options(FILE *outf, enum update_opt update_mode); --- -2.38.1 - diff --git a/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch b/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch deleted file mode 100644 index 7a6d213..0000000 --- a/SOURCES/0070-super-ddf-Remove-update_super_ddf.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 35aa44c549290e22f285896684c704acb53b7717 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:18 +0100 -Subject: [PATCH 70/83] super-ddf: Remove update_super_ddf. - -This is not supported by ddf. -It hides errors by returning success status for some updates. -Remove update_super_dff(). - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 70 ----------------------------------------------------- - 1 file changed, 70 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 9d1e3b94..309812df 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -2139,75 +2139,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha - } - } - --static int update_super_ddf(struct supertype *st, struct mdinfo *info, -- char *update, -- char *devname, int verbose, -- int uuid_set, char *homehost) --{ -- /* For 'assemble' and 'force' we need to return non-zero if any -- * change was made. For others, the return value is ignored. -- * Update options are: -- * force-one : This device looks a bit old but needs to be included, -- * update age info appropriately. -- * assemble: clear any 'faulty' flag to allow this device to -- * be assembled. -- * force-array: Array is degraded but being forced, mark it clean -- * if that will be needed to assemble it. -- * -- * newdev: not used ???? -- * grow: Array has gained a new device - this is currently for -- * linear only -- * resync: mark as dirty so a resync will happen. -- * uuid: Change the uuid of the array to match what is given -- * homehost: update the recorded homehost -- * name: update the name - preserving the homehost -- * _reshape_progress: record new reshape_progress position. -- * -- * Following are not relevant for this version: -- * sparc2.2 : update from old dodgey metadata -- * super-minor: change the preferred_minor number -- * summaries: update redundant counters. -- */ -- int rv = 0; --// struct ddf_super *ddf = st->sb; --// struct vd_config *vd = find_vdcr(ddf, info->container_member); --// struct virtual_entry *ve = find_ve(ddf); -- -- /* we don't need to handle "force-*" or "assemble" as -- * there is no need to 'trick' the kernel. When the metadata is -- * first updated to activate the array, all the implied modifications -- * will just happen. -- */ -- -- if (strcmp(update, "grow") == 0) { -- /* FIXME */ -- } else if (strcmp(update, "resync") == 0) { --// info->resync_checkpoint = 0; -- } else if (strcmp(update, "homehost") == 0) { -- /* homehost is stored in controller->vendor_data, -- * or it is when we are the vendor -- */ --// if (info->vendor_is_local) --// strcpy(ddf->controller.vendor_data, homehost); -- rv = -1; -- } else if (strcmp(update, "name") == 0) { -- /* name is stored in virtual_entry->name */ --// memset(ve->name, ' ', 16); --// strncpy(ve->name, info->name, 16); -- rv = -1; -- } else if (strcmp(update, "_reshape_progress") == 0) { -- /* We don't support reshape yet */ -- } else if (strcmp(update, "assemble") == 0 ) { -- /* Do nothing, just succeed */ -- rv = 0; -- } else -- rv = -1; -- --// update_all_csum(ddf); -- -- return rv; --} -- - static void make_header_guid(char *guid) - { - be32 stamp; -@@ -5211,7 +5142,6 @@ struct superswitch super_ddf = { - .match_home = match_home_ddf, - .uuid_from_super= uuid_from_super_ddf, - .getinfo_super = getinfo_super_ddf, -- .update_super = update_super_ddf, - - .avail_size = avail_size_ddf, - --- -2.38.1 - diff --git a/SOURCES/0071-super0-refactor-the-code-for-enum.patch b/SOURCES/0071-super0-refactor-the-code-for-enum.patch deleted file mode 100644 index f01c534..0000000 --- a/SOURCES/0071-super0-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0a9e39383d3bf63e1f5cf10f64200083a1af8091 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:19 +0100 -Subject: [PATCH 71/83] super0: refactor the code for enum - -It prepares update_super0 for change context->update to enum. -Change if else statements to switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super0.c | 102 ++++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 63 insertions(+), 39 deletions(-) - -diff --git a/super0.c b/super0.c -index 93876e2e..d9f5bff4 100644 ---- a/super0.c -+++ b/super0.c -@@ -502,19 +502,39 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update = "uuid"; -+ update_enum = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- if (strcmp(update, "sparc2.2")==0 ) { -+ switch (update_enum) { -+ case UOPT_UUID: -+ if (!uuid_set && homehost) { -+ char buf[20]; -+ memcpy(info->uuid+2, -+ sha1_buffer(homehost, strlen(homehost), buf), -+ 8); -+ } -+ sb->set_uuid0 = info->uuid[0]; -+ sb->set_uuid1 = info->uuid[1]; -+ sb->set_uuid2 = info->uuid[2]; -+ sb->set_uuid3 = info->uuid[3]; -+ if (sb->state & (1<uuid, uuid, 16); -+ } -+ break; -+ case UOPT_SPARC22: { - /* 2.2 sparc put the events in the wrong place - * So we copy the tail of the superblock - * up 4 bytes before continuing -@@ -527,12 +547,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (verbose >= 0) - pr_err("adjusting superblock of %s for 2.2/sparc compatibility.\n", - devname); -- } else if (strcmp(update, "super-minor") ==0) { -+ break; -+ } -+ case UOPT_SUPER_MINOR: - sb->md_minor = info->array.md_minor; - if (verbose > 0) - pr_err("updating superblock of %s with minor number %d\n", - devname, info->array.md_minor); -- } else if (strcmp(update, "summaries") == 0) { -+ break; -+ case UOPT_SUMMARIES: { - unsigned int i; - /* set nr_disks, active_disks, working_disks, - * failed_disks, spare_disks based on disks[] -@@ -559,7 +582,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->spare_disks++; - } else if (i >= sb->raid_disks && sb->disks[i].number == 0) - sb->disks[i].state = 0; -- } else if (strcmp(update, "force-one")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: { - /* Not enough devices for a working array, so - * bring this one up-to-date. - */ -@@ -569,7 +594,9 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - if (sb->events_hi != ehi || - sb->events_lo != elo) - rv = 1; -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ } -+ case UOPT_SPEC_FORCE_ARRAY: - /* degraded array and 'force' requested, so - * maybe need to mark it 'clean' - */ -@@ -579,7 +606,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->state |= (1 << MD_SB_CLEAN); - rv = 1; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int wonly = sb->disks[d].state & (1<disks[d].state & (1<reshape_position = info->reshape_progress; - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: - memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0])); - sb->disks[info->disk.number].number = info->disk.number; - sb->disks[info->disk.number].major = info->disk.major; -@@ -617,7 +647,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; - sb->this_disk = sb->disks[info->disk.number]; -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: - sb->raid_disks = info->array.raid_disks; - sb->nr_disks = info->array.nr_disks; - sb->active_disks = info->array.active_disks; -@@ -628,29 +659,15 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->disks[info->disk.number].minor = info->disk.minor; - sb->disks[info->disk.number].raid_disk = info->disk.raid_disk; - sb->disks[info->disk.number].state = info->disk.state; -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -+ break; -+ case UOPT_RESYNC: -+ /* -+ * make sure resync happens -+ */ - sb->state &= ~(1<recovery_cp = 0; -- } else if (strcmp(update, "uuid") == 0) { -- if (!uuid_set && homehost) { -- char buf[20]; -- char *hash = sha1_buffer(homehost, -- strlen(homehost), -- buf); -- memcpy(info->uuid+2, hash, 8); -- } -- sb->set_uuid0 = info->uuid[0]; -- sb->set_uuid1 = info->uuid[1]; -- sb->set_uuid2 = info->uuid[2]; -- sb->set_uuid3 = info->uuid[3]; -- if (sb->state & (1<uuid, uuid, 16); -- } -- } else if (strcmp(update, "metadata") == 0) { -+ break; -+ case UOPT_METADATA: - /* Create some v1.0 metadata to match ours but make the - * ctime bigger. Also update info->array.*_version. - * We need to arrange that store_super writes out -@@ -670,7 +687,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - uuid_from_super0(st, info->uuid); - st->other = super1_make_v0(st, info, st->sb); - } -- } else if (strcmp(update, "revert-reshape") == 0) { -+ break; -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (sb->minor_version <= 90) - pr_err("No active reshape to revert on %s\n", -@@ -702,16 +720,22 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - sb->new_chunk = sb->chunk_size; - sb->chunk_size = tmp; - } -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->state &= ~(1<reshape_position = info->reshape_progress; -- else if (strcmp(update, "writemostly")==0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->state |= (1<state &= ~(1<sb_csum = calc_sb0_csum(sb); - return rv; --- -2.38.1 - diff --git a/SOURCES/0072-super1-refactor-the-code-for-enum.patch b/SOURCES/0072-super1-refactor-the-code-for-enum.patch deleted file mode 100644 index bd164b8..0000000 --- a/SOURCES/0072-super1-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 7e8daba8b7937716dce8ea28298a4e2e72cb829e Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:20 +0100 -Subject: [PATCH 72/83] super1: refactor the code for enum - -It prepares update_super1 for change context->update to enum. -Change if else statements into switch. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super1.c | 152 +++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 91 insertions(+), 61 deletions(-) - -diff --git a/super1.c b/super1.c -index 0b505a7e..b0a97016 100644 ---- a/super1.c -+++ b/super1.c -@@ -1218,30 +1218,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ enum update_opt update_enum = map_name(update_options, update); - -- if (strcmp(update, "homehost") == 0 && -- homehost) { -- /* Note that 'homehost' is special as it is really -+ if (update_enum == UOPT_HOMEHOST && homehost) { -+ /* -+ * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update = "name"; -+ update_enum = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- strncpy(info->name, c+1, 31 - (c-sb->set_name)); -+ snprintf(info->name, sizeof(info->name), "%s", c+1); - else -- strncpy(info->name, sb->set_name, 32); -- info->name[32] = 0; -+ snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- if (strcmp(update, "force-one")==0) { -+ switch (update_enum) { -+ case UOPT_NAME: { -+ int namelen; -+ -+ if (!info->name[0]) -+ snprintf(info->name, sizeof(info->name), "%d", info->array.md_minor); -+ memset(sb->set_name, 0, sizeof(sb->set_name)); -+ -+ namelen = strnlen(homehost, MD_NAME_MAX) + 1 + strnlen(info->name, MD_NAME_MAX); -+ if (homehost && -+ strchr(info->name, ':') == NULL && -+ namelen < MD_NAME_MAX) { -+ strcpy(sb->set_name, homehost); -+ strcat(sb->set_name, ":"); -+ strcat(sb->set_name, info->name); -+ } else { -+ namelen = min((int)strnlen(info->name, MD_NAME_MAX), -+ (int)sizeof(sb->set_name) - 1); -+ memcpy(sb->set_name, info->name, namelen); -+ memset(&sb->set_name[namelen], '\0', -+ sizeof(sb->set_name) - namelen); -+ } -+ break; -+ } -+ case UOPT_SPEC_FORCE_ONE: - /* Not enough devices for a working array, - * so bring this one up-to-date - */ - if (sb->events != __cpu_to_le64(info->events)) - rv = 1; - sb->events = __cpu_to_le64(info->events); -- } else if (strcmp(update, "force-array")==0) { -+ break; -+ case UOPT_SPEC_FORCE_ARRAY: - /* Degraded array and 'force' requests to - * maybe need to mark it 'clean'. - */ -@@ -1254,7 +1279,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - rv = 1; - sb->resync_offset = MaxSector; - } -- } else if (strcmp(update, "assemble")==0) { -+ break; -+ case UOPT_SPEC_ASSEMBLE: { - int d = info->disk.number; - int want; - if (info->disk.state & (1<reshape_progress); - rv = 1; - } -- } else if (strcmp(update, "linear-grow-new") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_NEW: { - int i; - int fd; - int max = __le32_to_cpu(sb->max_dev); -@@ -1330,7 +1358,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - ds - __le64_to_cpu(sb->data_offset)); - } - } -- } else if (strcmp(update, "linear-grow-update") == 0) { -+ break; -+ } -+ case UOPT_SPEC_LINEAR_GROW_UPDATE: { - int max = __le32_to_cpu(sb->max_dev); - int i = info->disk.number; - if (max > MAX_DEVS || i > MAX_DEVS) -@@ -1342,19 +1372,20 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -- } else if (strcmp(update, "resync") == 0) { -- /* make sure resync happens */ -- sb->resync_offset = 0ULL; -- } else if (strcmp(update, "uuid") == 0) { -+ break; -+ } -+ case UOPT_UUID: - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - - if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) - memcpy(bms->uuid, sb->set_uuid, 16); -- } else if (strcmp(update, "no-bitmap") == 0) { -+ break; -+ case UOPT_NO_BITMAP: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); - if (bms->version == BITMAP_MAJOR_CLUSTERED && !IsBitmapDirty(devname)) - sb->resync_offset = MaxSector; -- } else if (strcmp(update, "bbl") == 0) { -+ break; -+ case UOPT_BBL: { - /* only possible if there is room after the bitmap, or if - * there is no bitmap - */ -@@ -1383,14 +1414,12 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - bb_offset = bitmap_offset + bm_sectors; - while (bb_offset < (long)sb_offset + 8 + 32*2 && - bb_offset + 8+8 <= (long)data_offset) -- /* too close to bitmap, and room to grow */ - bb_offset += 8; - if (bb_offset + 8 <= (long)data_offset) { - sb->bblog_size = __cpu_to_le16(8); - sb->bblog_offset = __cpu_to_le32(bb_offset); - } - } else { -- /* 1.0 - Put bbl just before super block */ - if (bm_sectors && bitmap_offset < 0) - space = -bitmap_offset - bm_sectors; - else -@@ -1401,7 +1430,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_offset = __cpu_to_le32((unsigned)-8); - } - } -- } else if (strcmp(update, "no-bbl") == 0) { -+ break; -+ } -+ case UOPT_NO_BBL: - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) - pr_err("Cannot remove active bbl from %s\n",devname); - else { -@@ -1409,12 +1440,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->bblog_shift = 0; - sb->bblog_offset = 0; - } -- } else if (strcmp(update, "force-no-bbl") == 0) { -+ break; -+ case UOPT_FORCE_NO_BBL: - sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_BAD_BLOCKS); - sb->bblog_size = 0; - sb->bblog_shift = 0; - sb->bblog_offset = 0; -- } else if (strcmp(update, "ppl") == 0) { -+ break; -+ case UOPT_PPL: { - unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); - unsigned long long data_offset = __le64_to_cpu(sb->data_offset); - unsigned long long data_size = __le64_to_cpu(sb->data_size); -@@ -1464,37 +1497,26 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->ppl.offset = __cpu_to_le16(offset); - sb->ppl.size = __cpu_to_le16(space); - sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); -- } else if (strcmp(update, "no-ppl") == 0) { -+ break; -+ } -+ case UOPT_NO_PPL: - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | - MD_FEATURE_MUTLIPLE_PPLS); -- } else if (strcmp(update, "name") == 0) { -- if (info->name[0] == 0) -- sprintf(info->name, "%d", info->array.md_minor); -- memset(sb->set_name, 0, sizeof(sb->set_name)); -- if (homehost && -- strchr(info->name, ':') == NULL && -- strlen(homehost)+1+strlen(info->name) < 32) { -- strcpy(sb->set_name, homehost); -- strcat(sb->set_name, ":"); -- strcat(sb->set_name, info->name); -- } else { -- int namelen; -- -- namelen = min((int)strlen(info->name), -- (int)sizeof(sb->set_name) - 1); -- memcpy(sb->set_name, info->name, namelen); -- memset(&sb->set_name[namelen], '\0', -- sizeof(sb->set_name) - namelen); -- } -- } else if (strcmp(update, "devicesize") == 0 && -- __le64_to_cpu(sb->super_offset) < -- __le64_to_cpu(sb->data_offset)) { -- /* set data_size to device size less data_offset */ -+ break; -+ case UOPT_DEVICESIZE: -+ if (__le64_to_cpu(sb->super_offset) >= -+ __le64_to_cpu(sb->data_offset)) -+ break; -+ /* -+ * set data_size to device size less data_offset -+ */ - struct misc_dev_info *misc = (struct misc_dev_info*) - (st->sb + MAX_SB_SIZE + BM_SUPER_SIZE); - sb->data_size = __cpu_to_le64( - misc->device_size - __le64_to_cpu(sb->data_offset)); -- } else if (strncmp(update, "revert-reshape", 14) == 0) { -+ break; -+ case UOPT_SPEC_REVERT_RESHAPE_NOBACKUP: -+ case UOPT_REVERT_RESHAPE: - rv = -2; - if (!(sb->feature_map & - __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) -@@ -1512,7 +1534,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (strcmp(update, "revert-reshape-nobackup") == 0 && -+ if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1575,32 +1597,40 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - } - done:; - } -- } else if (strcmp(update, "_reshape_progress") == 0) -+ break; -+ case UOPT_SPEC__RESHAPE_PROGRESS: - sb->reshape_position = __cpu_to_le64(info->reshape_progress); -- else if (strcmp(update, "writemostly") == 0) -+ break; -+ case UOPT_SPEC_WRITEMOSTLY: - sb->devflags |= WriteMostly1; -- else if (strcmp(update, "readwrite") == 0) -+ break; -+ case UOPT_SPEC_READWRITE: - sb->devflags &= ~WriteMostly1; -- else if (strcmp(update, "failfast") == 0) -+ break; -+ case UOPT_SPEC_FAILFAST: - sb->devflags |= FailFast1; -- else if (strcmp(update, "nofailfast") == 0) -+ break; -+ case UOPT_SPEC_NOFAILFAST: - sb->devflags &= ~FailFast1; -- else if (strcmp(update, "layout-original") == 0 || -- strcmp(update, "layout-alternate") == 0 || -- strcmp(update, "layout-unspecified") == 0) { -+ break; -+ case UOPT_LAYOUT_ORIGINAL: -+ case UOPT_LAYOUT_ALTERNATE: -+ case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname?:"", update); -+ devname ?: "", map_num(update_options, update_enum)); - rv = -1; -- } else if (strcmp(update, "layout-unspecified") == 0) { -+ } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); -+ sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } -- } else -+ break; -+ default: - rv = -1; -+ } - - sb->sb_csum = calc_sb_1_csum(sb); - --- -2.38.1 - diff --git a/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch b/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch deleted file mode 100644 index 6756297..0000000 --- a/SOURCES/0073-super-intel-refactor-the-code-for-enum.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 4345e135c4c7dd04bb15bad140dfc4747f677738 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:21 +0100 -Subject: [PATCH 73/83] super-intel: refactor the code for enum - -It prepares super-intel for change context->update to enum. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - super-intel.c | 37 +++++++++++++++++++++++++------------ - 1 file changed, 25 insertions(+), 12 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5f93f3d3..85fb7f17 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3930,7 +3930,8 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- if (strcmp(update, "uuid") == 0) { -+ switch (map_name(update_options, update)) { -+ case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really - * allow an explicit uuid to be given. And it is hard to reliably -@@ -3954,10 +3955,14 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - } - if (rv == 0) - mpb->orig_family_num = info->uuid[0]; -- } else if (strcmp(update, "assemble") == 0) -+ break; -+ case UOPT_SPEC_ASSEMBLE: - rv = 0; -- else -+ break; -+ default: - rv = -1; -+ break; -+ } - - /* successful update? recompute checksum */ - if (rv == 0) -@@ -7889,17 +7894,25 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) - return 0; - } - --static int get_rwh_policy_from_update(char *update) -+/** -+ * get_rwh_policy_from_update() - Get the rwh policy for update option. -+ * @update: Update option. -+ */ -+static int get_rwh_policy_from_update(enum update_opt update) - { -- if (strcmp(update, "ppl") == 0) -+ switch (update) { -+ case UOPT_PPL: - return RWH_MULTIPLE_DISTRIBUTED; -- else if (strcmp(update, "no-ppl") == 0) -+ case UOPT_NO_PPL: - return RWH_MULTIPLE_OFF; -- else if (strcmp(update, "bitmap") == 0) -+ case UOPT_BITMAP: - return RWH_BITMAP; -- else if (strcmp(update, "no-bitmap") == 0) -+ case UOPT_NO_BITMAP: - return RWH_OFF; -- return -1; -+ default: -+ break; -+ } -+ return UOPT_UNDEFINED; - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -@@ -7909,7 +7922,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (strcmp(update, "name") == 0) { -+ if (map_name(update_options, update) == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7943,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(update) != -1) { -+ } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7951,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(update); -+ new_policy = get_rwh_policy_from_update(map_name(update_options, update)); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); --- -2.38.1 - diff --git a/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch b/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch deleted file mode 100644 index c9e186e..0000000 --- a/SOURCES/0074-Change-update-to-enum-in-update_super-and-update_sub.patch +++ /dev/null @@ -1,424 +0,0 @@ -From 03312b5240438ffc3b63114bdc87e911222f01e5 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:22 +0100 -Subject: [PATCH 74/83] Change update to enum in update_super and - update_subarray - -Use already existing enum, change update_super and update_subarray -update to enum globally. -Refactor function references also. -Remove code specific options from update_options. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 14 +++++++++----- - Examine.c | 2 +- - Grow.c | 9 +++++---- - Manage.c | 14 ++++++++------ - maps.c | 21 --------------------- - mdadm.h | 12 +++++++++--- - super-intel.c | 16 ++++++++-------- - super0.c | 9 ++++----- - super1.c | 17 ++++++++--------- - 9 files changed, 52 insertions(+), 62 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 8b0af0c9..dba910cd 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -695,12 +695,16 @@ static int load_devices(struct devs *devices, char *devmap, - } else if (strcmp(c->update, "revert-reshape") == 0 && - c->invalid_backup) - err = tst->ss->update_super(tst, content, -- "revert-reshape-nobackup", -+ UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- err = tst->ss->update_super(tst, content, c->update, -+ /* -+ * Mapping is temporary, will be removed in this patchset -+ */ -+ err = tst->ss->update_super(tst, content, -+ map_name(update_options, c->update), - devname, c->verbose, - ident->uuid_set, - c->homehost); -@@ -960,7 +964,7 @@ static int force_array(struct mdinfo *content, - continue; - } - content->events = devices[most_recent].i.events; -- tst->ss->update_super(tst, content, "force-one", -+ tst->ss->update_super(tst, content, UOPT_SPEC_FORCE_ONE, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - -@@ -1788,7 +1792,7 @@ try_again: - if (!(devices[j].i.array.state & 1)) - clean = 0; - -- if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, -+ if (st->ss->update_super(st, &devices[j].i, UOPT_SPEC_ASSEMBLE, NULL, - c->verbose, 0, NULL)) { - if (c->force) { - if (c->verbose >= 0) -@@ -1811,7 +1815,7 @@ try_again: - if (c->force && !clean && !is_container(content->array.level) && - !enough(content->array.level, content->array.raid_disks, - content->array.layout, clean, avail)) { -- change += st->ss->update_super(st, content, "force-array", -+ change += st->ss->update_super(st, content, UOPT_SPEC_FORCE_ARRAY, - devices[chosen_drive].devname, c->verbose, - 0, NULL); - was_forced = 1; -diff --git a/Examine.c b/Examine.c -index 9574a3cc..c9605a60 100644 ---- a/Examine.c -+++ b/Examine.c -@@ -117,7 +117,7 @@ int Examine(struct mddev_dev *devlist, - } - - if (c->SparcAdjust) -- st->ss->update_super(st, NULL, "sparc2.2", -+ st->ss->update_super(st, NULL, UOPT_SPARC22, - devlist->devname, 0, 0, NULL); - /* Ok, its good enough to try, though the checksum could be wrong */ - -diff --git a/Grow.c b/Grow.c -index b73ec2ae..82d5d2ea 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -196,7 +196,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.disk.minor = minor(rdev); - info.disk.raid_disk = d; - info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); -- if (st->ss->update_super(st, &info, "linear-grow-new", newdev, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_NEW, newdev, - 0, 0, NULL) != 0) { - pr_err("Preparing new metadata failed on %s\n", newdev); - close(nfd); -@@ -254,7 +254,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) - info.array.active_disks = nd+1; - info.array.working_disks = nd+1; - -- if (st->ss->update_super(st, &info, "linear-grow-update", dv, -+ if (st->ss->update_super(st, &info, UOPT_SPEC_LINEAR_GROW_UPDATE, dv, - 0, 0, NULL) != 0) { - pr_err("Updating metadata failed on %s\n", dv); - close(fd2); -@@ -668,7 +668,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - goto free_info; - } - -- ret = st->ss->update_super(st, sra, "ppl", -+ ret = st->ss->update_super(st, sra, UOPT_PPL, - devname, - c->verbose, 0, NULL); - if (ret) { -@@ -4950,7 +4950,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, - continue; - st->ss->getinfo_super(st, &dinfo, NULL); - dinfo.reshape_progress = info->reshape_progress; -- st->ss->update_super(st, &dinfo, "_reshape_progress", -+ st->ss->update_super(st, &dinfo, -+ UOPT_SPEC__RESHAPE_PROGRESS, - NULL,0, 0, NULL); - st->ss->store_super(st, fdlist[j]); - st->ss->free_super(st); -diff --git a/Manage.c b/Manage.c -index 5a9ea316..87b8aa0c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -605,6 +605,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -+ enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -666,23 +667,23 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - - if (dv->writemostly == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "writemostly", -+ dev_st, NULL, UOPT_SPEC_WRITEMOSTLY, - devname, verbose, 0, NULL); - if (dv->writemostly == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "readwrite", -+ dev_st, NULL, UOPT_SPEC_READWRITE, - devname, verbose, 0, NULL); - if (dv->failfast == FlagSet) - rv = dev_st->ss->update_super( -- dev_st, NULL, "failfast", -+ dev_st, NULL, UOPT_SPEC_FAILFAST, - devname, verbose, 0, NULL); - if (dv->failfast == FlagClear) - rv = dev_st->ss->update_super( -- dev_st, NULL, "nofailfast", -+ dev_st, NULL, UOPT_SPEC_NOFAILFAST, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update, -+ dev_st, NULL, update_enum, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -1731,6 +1732,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -+ enum update_opt update_enum = map_name(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1762,7 +1764,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update, ident); -+ rv = st->ss->update_subarray(st, subarray, update_enum, ident); - - if (rv) { - if (verbose >= 0) -diff --git a/maps.c b/maps.c -index c59036f1..b586679a 100644 ---- a/maps.c -+++ b/maps.c -@@ -194,27 +194,6 @@ mapping_t update_options[] = { - { "byteorder", UOPT_BYTEORDER }, - { "help", UOPT_HELP }, - { "?", UOPT_HELP }, -- /* -- * Those enries are temporary and will be removed in this patchset. -- * -- * Before update_super:update can be changed to enum, -- * all update_super sub-functions must be adapted first. -- * Update options will be passed as string (as it is for now), -- * and then mapped, so all options must be handled temporarily. -- * -- * Those options code specific and should not be accessible for user. -- */ -- { "force-one", UOPT_SPEC_FORCE_ONE }, -- { "force-array", UOPT_SPEC_FORCE_ARRAY }, -- { "assemble", UOPT_SPEC_ASSEMBLE }, -- { "linear-grow-new", UOPT_SPEC_LINEAR_GROW_NEW }, -- { "linear-grow-update", UOPT_SPEC_LINEAR_GROW_UPDATE }, -- { "_reshape_progress", UOPT_SPEC__RESHAPE_PROGRESS }, -- { "writemostly", UOPT_SPEC_WRITEMOSTLY }, -- { "readwrite", UOPT_SPEC_READWRITE }, -- { "failfast", UOPT_SPEC_FAILFAST }, -- { "nofailfast", UOPT_SPEC_NOFAILFAST }, -- { "revert-reshape-nobackup", UOPT_SPEC_REVERT_RESHAPE_NOBACKUP }, - { NULL, UOPT_UNDEFINED} - }; - -diff --git a/mdadm.h b/mdadm.h -index 31db25f5..5dc94390 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1011,7 +1011,7 @@ extern struct superswitch { - * it will resume going in the opposite direction. - */ - int (*update_super)(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost); - -@@ -1137,9 +1137,15 @@ extern struct superswitch { - /* Permit subarray's to be deleted from inactive containers */ - int (*kill_subarray)(struct supertype *st, - char *subarray_id); /* optional */ -- /* Permit subarray's to be modified */ -+ /** -+ * update_subarray() - Permit subarray to be modified. -+ * @st: Supertype. -+ * @subarray: Subarray name. -+ * @update: Update option. -+ * @ident: Optional identifiers. -+ */ - int (*update_subarray)(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident); /* optional */ -+ enum update_opt update, struct mddev_ident *ident); - /* Check if reshape is supported for this external format. - * st is obtained from super_by_fd() where st->subarray[0] is - * initialized to indicate if reshape is being performed at the -diff --git a/super-intel.c b/super-intel.c -index 85fb7f17..1f5f6eda 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3893,8 +3893,8 @@ struct mdinfo *getinfo_super_disks_imsm(struct supertype *st) - } - - static int update_super_imsm(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -- int uuid_set, char *homehost) -+ enum update_opt update, char *devname, -+ int verbose, int uuid_set, char *homehost) - { - /* For 'assemble' and 'force' we need to return non-zero if any - * change was made. For others, the return value is ignored. -@@ -3930,7 +3930,7 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info, - - mpb = super->anchor; - -- switch (map_name(update_options, update)) { -+ switch (update) { - case UOPT_UUID: - /* We take this to mean that the family_num should be updated. - * However that is much smaller than the uuid so we cannot really -@@ -6538,7 +6538,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, - if (mdmon_running(st->container_devnm)) - st->update_tail = &st->updates; - -- if (st->ss->update_subarray(st, subarray, "ppl", NULL)) { -+ if (st->ss->update_subarray(st, subarray, UOPT_PPL, NULL)) { - pr_err("Failed to update subarray %s\n", - subarray); - } else { -@@ -7916,13 +7916,13 @@ static int get_rwh_policy_from_update(enum update_opt update) - } - - static int update_subarray_imsm(struct supertype *st, char *subarray, -- char *update, struct mddev_ident *ident) -+ enum update_opt update, struct mddev_ident *ident) - { - /* update the subarray currently referenced by ->current_vol */ - struct intel_super *super = st->sb; - struct imsm_super *mpb = super->anchor; - -- if (map_name(update_options, update) == UOPT_NAME) { -+ if (update == UOPT_NAME) { - char *name = ident->name; - char *ep; - int vol; -@@ -7956,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - } - super->updates_pending++; - } -- } else if (get_rwh_policy_from_update(map_name(update_options, update)) != UOPT_UNDEFINED) { -+ } else if (get_rwh_policy_from_update(update) != UOPT_UNDEFINED) { - int new_policy; - char *ep; - int vol = strtoul(subarray, &ep, 10); -@@ -7964,7 +7964,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - if (*ep != '\0' || vol >= super->anchor->num_raid_devs) - return 2; - -- new_policy = get_rwh_policy_from_update(map_name(update_options, update)); -+ new_policy = get_rwh_policy_from_update(update); - - if (st->update_tail) { - struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); -diff --git a/super0.c b/super0.c -index d9f5bff4..a7c5f813 100644 ---- a/super0.c -+++ b/super0.c -@@ -491,7 +491,7 @@ static struct mdinfo *container_content0(struct supertype *st, char *subarray) - } - - static int update_super0(struct supertype *st, struct mdinfo *info, -- char *update, -+ enum update_opt update, - char *devname, int verbose, - int uuid_set, char *homehost) - { -@@ -502,20 +502,19 @@ static int update_super0(struct supertype *st, struct mdinfo *info, - int rv = 0; - int uuid[4]; - mdp_super_t *sb = st->sb; -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * note that 'homehost' is special as it is really - * a "uuid" update. - */ - uuid_set = 0; -- update_enum = UOPT_UUID; -+ update = UOPT_UUID; - info->uuid[0] = sb->set_uuid0; - info->uuid[1] = sb->set_uuid1; - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_UUID: - if (!uuid_set && homehost) { - char buf[20]; -diff --git a/super1.c b/super1.c -index b0a97016..f7020320 100644 ---- a/super1.c -+++ b/super1.c -@@ -1208,7 +1208,7 @@ static struct mdinfo *container_content1(struct supertype *st, char *subarray) - } - - static int update_super1(struct supertype *st, struct mdinfo *info, -- char *update, char *devname, int verbose, -+ enum update_opt update, char *devname, int verbose, - int uuid_set, char *homehost) - { - /* NOTE: for 'assemble' and 'force' we need to return non-zero -@@ -1218,15 +1218,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -- enum update_opt update_enum = map_name(update_options, update); - -- if (update_enum == UOPT_HOMEHOST && homehost) { -+ if (update == UOPT_HOMEHOST && homehost) { - /* - * Note that 'homehost' is special as it is really - * a "name" update. - */ - char *c; -- update_enum = UOPT_NAME; -+ update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) - snprintf(info->name, sizeof(info->name), "%s", c+1); -@@ -1234,7 +1233,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - snprintf(info->name, sizeof(info->name), "%s", sb->set_name); - } - -- switch (update_enum) { -+ switch (update) { - case UOPT_NAME: { - int namelen; - -@@ -1534,7 +1533,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - * If that couldn't happen, the "-nobackup" version - * will be used. - */ -- if (update_enum == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && -+ if (update == UOPT_SPEC_REVERT_RESHAPE_NOBACKUP && - sb->reshape_position == 0 && - (__le32_to_cpu(sb->delta_disks) > 0 || - (__le32_to_cpu(sb->delta_disks) == 0 && -@@ -1618,14 +1617,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - case UOPT_LAYOUT_UNSPECIFIED: - if (__le32_to_cpu(sb->level) != 0) { - pr_err("%s: %s only supported for RAID0\n", -- devname ?: "", map_num(update_options, update_enum)); -+ devname ?: "", map_num(update_options, update)); - rv = -1; -- } else if (update_enum == UOPT_LAYOUT_UNSPECIFIED) { -+ } else if (update == UOPT_LAYOUT_UNSPECIFIED) { - sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); - sb->layout = 0; - } else { - sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); -- sb->layout = __cpu_to_le32(update_enum == UOPT_LAYOUT_ORIGINAL ? 1 : 2); -+ sb->layout = __cpu_to_le32(update == UOPT_LAYOUT_ORIGINAL ? 1 : 2); - } - break; - default: --- -2.38.1 - diff --git a/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch b/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch deleted file mode 100644 index d4b20ff..0000000 --- a/SOURCES/0075-Manage-Incremental-code-refactor-string-to-enum.patch +++ /dev/null @@ -1,279 +0,0 @@ -From f2e8393bd7223c419aaa33c45feeb5c75440b986 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:23 +0100 -Subject: [PATCH 75/83] Manage&Incremental: code refactor, string to enum - -Prepare Manage and Incremental for later changing context->update to enum. -Change update from string to enum in multiple functions and pass enum -where already possible. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Grow.c | 8 ++++---- - Incremental.c | 8 ++++---- - Manage.c | 35 +++++++++++++++++------------------ - mdadm.c | 23 ++++++++++++++++++----- - mdadm.h | 4 ++-- - 5 files changed, 45 insertions(+), 33 deletions(-) - -diff --git a/Grow.c b/Grow.c -index 82d5d2ea..8f5cf07d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -605,12 +605,12 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha - } - - if (subarray) { -- char *update; -+ enum update_opt update; - - if (s->consistency_policy == CONSISTENCY_POLICY_PPL) -- update = "ppl"; -+ update = UOPT_PPL; - else -- update = "no-ppl"; -+ update = UOPT_NO_PPL; - - sprintf(container_dev, "/dev/%s", st->container_devnm); - -@@ -3243,7 +3243,7 @@ static int reshape_array(char *container, int fd, char *devname, - * level and frozen, we can safely add them. - */ - if (devlist) { -- if (Manage_subdevs(devname, fd, devlist, verbose, 0, NULL, 0)) -+ if (Manage_subdevs(devname, fd, devlist, verbose, 0, UOPT_UNDEFINED, 0)) - goto release; - } - -diff --git a/Incremental.c b/Incremental.c -index 5a5f4c4c..ff3548c0 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1025,7 +1025,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, - close(dfd); - *dfdp = -1; - rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - close(mdfd); - } - if (verbose > 0) { -@@ -1666,7 +1666,7 @@ static void remove_from_member_array(struct mdstat_ent *memb, - - if (subfd >= 0) { - rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, -- 0, NULL, 0); -+ 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - if (sysfs_init(&mmdi, -1, memb->devnm)) - pr_err("unable to initialize sysfs for: %s\n", -@@ -1758,7 +1758,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - free_mdstat(mdstat); - } else { - rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - if (rv & 2) { - /* Failed due to EBUSY, try to stop the array. - * Give udisks a chance to unmount it first. -@@ -1770,7 +1770,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - devlist.disposition = 'r'; - rv = Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, NULL, 0); -+ verbose, 0, UOPT_UNDEFINED, 0); - end: - close(mdfd); - free_mdstat(ent); -diff --git a/Manage.c b/Manage.c -index 87b8aa0c..594e3d2c 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -598,14 +598,12 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) - - int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *dev_st, struct supertype *tst, -- unsigned long rdev, -- char *update, char *devname, int verbose, -- mdu_array_info_t *array) -+ unsigned long rdev, enum update_opt update, -+ char *devname, int verbose, mdu_array_info_t *array) - { - struct mdinfo mdi; - int duuid[4]; - int ouuid[4]; -- enum update_opt update_enum = map_name(update_options, update); - - dev_st->ss->getinfo_super(dev_st, &mdi, NULL); - dev_st->ss->uuid_from_super(dev_st, ouuid); -@@ -683,7 +681,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - devname, verbose, 0, NULL); - if (update) - rv = dev_st->ss->update_super( -- dev_st, NULL, update_enum, -+ dev_st, NULL, update, - devname, verbose, 0, NULL); - if (rv == 0) - rv = dev_st->ss->store_super(dev_st, tfd); -@@ -715,8 +713,8 @@ skip_re_add: - int Manage_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *tst, mdu_array_info_t *array, - int force, int verbose, char *devname, -- char *update, unsigned long rdev, unsigned long long array_size, -- int raid_slot) -+ enum update_opt update, unsigned long rdev, -+ unsigned long long array_size, int raid_slot) - { - unsigned long long ldsize; - struct supertype *dev_st; -@@ -1332,7 +1330,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force) -+ enum update_opt update, int force) - { - /* Do something to each dev. - * devmode can be -@@ -1727,12 +1725,13 @@ int autodetect(void) - return rv; - } - --int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int verbose) -+int Update_subarray(char *dev, char *subarray, enum update_opt update, -+ struct mddev_ident *ident, int verbose) - { - struct supertype supertype, *st = &supertype; - int fd, rv = 2; - struct mdinfo *info = NULL; -- enum update_opt update_enum = map_name(update_options, update); -+ char *update_verb = map_num(update_options, update); - - memset(st, 0, sizeof(*st)); - -@@ -1750,7 +1749,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - if (is_subarray_active(subarray, st->devnm)) { - if (verbose >= 0) - pr_err("Subarray %s in %s is active, cannot update %s\n", -- subarray, dev, update); -+ subarray, dev, update_verb); - goto free_super; - } - -@@ -1759,23 +1758,23 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident - - info = st->ss->container_content(st, subarray); - -- if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) { -+ if (update == UOPT_PPL && !is_level456(info->array.level)) { - pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n"); - goto free_super; - } - -- rv = st->ss->update_subarray(st, subarray, update_enum, ident); -+ rv = st->ss->update_subarray(st, subarray, update, ident); - - if (rv) { - if (verbose >= 0) - pr_err("Failed to update %s of subarray-%s in %s\n", -- update, subarray, dev); -+ update_verb, subarray, dev); - } else if (st->update_tail) - flush_metadata_updates(st); - else - st->ss->sync_metadata(st); - -- if (rv == 0 && strcmp(update, "name") == 0 && verbose >= 0) -+ if (rv == 0 && update == UOPT_NAME && verbose >= 0) - pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n", - subarray, dev); - -@@ -1816,10 +1815,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - sprintf(devname, "%d:%d", major(devid), minor(devid)); - - devlist.disposition = 'r'; -- if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { -+ if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, UOPT_UNDEFINED, 0) == 0) { - devlist.disposition = 'a'; - if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, -- NULL, 0) == 0) { -+ UOPT_UNDEFINED, 0) == 0) { - /* make sure manager is aware of changes */ - ping_manager(to_devname); - ping_manager(from_devname); -@@ -1829,7 +1828,7 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) - } - else - Manage_subdevs(from_devname, fd2, &devlist, -- -1, 0, NULL, 0); -+ -1, 0, UOPT_UNDEFINED, 0); - } - close(fd1); - close(fd2); -diff --git a/mdadm.c b/mdadm.c -index f5f505fe..d06e2820 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1402,10 +1402,22 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found>1) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- c.update, c.force); -+ if (!rv && devs_found > 1) { -+ /* -+ * This is temporary and will be removed in next patches -+ * Null c.update will cause segfault -+ */ -+ if (c.update) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ map_name(update_options, c.update), -+ c.force); -+ else -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, c.test, -+ UOPT_UNDEFINED, -+ c.force); -+ } - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1931,7 +1943,8 @@ static int misc_list(struct mddev_dev *devlist, - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- c->update, ident, c->verbose); -+ map_name(update_options, c->update), -+ ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 5dc94390..924f4b63 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1478,7 +1478,7 @@ extern int Manage_stop(char *devname, int fd, int quiet, - int will_retry); - extern int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, -- char *update, int force); -+ enum update_opt update, int force); - extern int autodetect(void); - extern int Grow_Add_device(char *devname, int fd, char *newdev); - extern int Grow_addbitmap(char *devname, int fd, -@@ -1532,7 +1532,7 @@ extern int Monitor(struct mddev_dev *devlist, - - extern int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl); - extern int Kill_subarray(char *dev, char *subarray, int verbose); --extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet); -+extern int Update_subarray(char *dev, char *subarray, enum update_opt update, struct mddev_ident *ident, int quiet); - extern int Wait(char *dev); - extern int WaitClean(char *dev, int verbose); - extern int SetAction(char *dev, char *action); --- -2.38.1 - diff --git a/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch b/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch deleted file mode 100644 index a18f8d1..0000000 --- a/SOURCES/0076-Change-char-to-enum-in-context-update-refactor-code.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 3a87fa67112dc2c2c3664aeecd0b49cb4b6ceaa9 Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:35:24 +0100 -Subject: [PATCH 76/83] Change char* to enum in context->update & refactor code - -Storing update option in string is bad for frequent comparisons and -error prone. -Replace char array with enum so already existing enum is passed around -instead of string. -Adapt code to changes. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Assemble.c | 40 +++++++++++++++++----------------------- - mdadm.c | 52 +++++++++++++++++++--------------------------------- - mdadm.h | 2 +- - 3 files changed, 37 insertions(+), 57 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index dba910cd..49804941 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -135,17 +135,17 @@ static int ident_matches(struct mddev_ident *ident, - struct mdinfo *content, - struct supertype *tst, - char *homehost, int require_homehost, -- char *update, char *devname) -+ enum update_opt update, char *devname) - { - -- if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) && -+ if (ident->uuid_set && update != UOPT_UUID && - same_uuid(content->uuid, ident->uuid, tst->ss->swapuuid)==0 && - memcmp(content->uuid, uuid_zero, sizeof(int[4])) != 0) { - if (devname) - pr_err("%s has wrong uuid.\n", devname); - return 0; - } -- if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && -+ if (ident->name[0] && update != UOPT_NAME && - name_matches(content->name, ident->name, homehost, require_homehost)==0) { - if (devname) - pr_err("%s has wrong name.\n", devname); -@@ -648,11 +648,10 @@ static int load_devices(struct devs *devices, char *devmap, - int err; - fstat(mdfd, &stb2); - -- if (strcmp(c->update, "uuid") == 0 && !ident->uuid_set) -+ if (c->update == UOPT_UUID && !ident->uuid_set) - random_uuid((__u8 *)ident->uuid); - -- if (strcmp(c->update, "ppl") == 0 && -- ident->bitmap_fd >= 0) { -+ if (c->update == UOPT_PPL && ident->bitmap_fd >= 0) { - pr_err("PPL is not compatible with bitmap\n"); - close(mdfd); - free(devices); -@@ -684,34 +683,30 @@ static int load_devices(struct devs *devices, char *devmap, - strcpy(content->name, ident->name); - content->array.md_minor = minor(stb2.st_rdev); - -- if (strcmp(c->update, "byteorder") == 0) -+ if (c->update == UOPT_BYTEORDER) - err = 0; -- else if (strcmp(c->update, "home-cluster") == 0) { -+ else if (c->update == UOPT_HOME_CLUSTER) { - tst->cluster_name = c->homecluster; - err = tst->ss->write_bitmap(tst, dfd, NameUpdate); -- } else if (strcmp(c->update, "nodes") == 0) { -+ } else if (c->update == UOPT_NODES) { - tst->nodes = c->nodes; - err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate); -- } else if (strcmp(c->update, "revert-reshape") == 0 && -- c->invalid_backup) -+ } else if (c->update == UOPT_REVERT_RESHAPE && c->invalid_backup) - err = tst->ss->update_super(tst, content, - UOPT_SPEC_REVERT_RESHAPE_NOBACKUP, - devname, c->verbose, - ident->uuid_set, - c->homehost); - else -- /* -- * Mapping is temporary, will be removed in this patchset -- */ - err = tst->ss->update_super(tst, content, -- map_name(update_options, c->update), -+ c->update, - devname, c->verbose, - ident->uuid_set, - c->homehost); - if (err < 0) { - if (err == -1) - pr_err("--update=%s not understood for %s metadata\n", -- c->update, tst->ss->name); -+ map_num(update_options, c->update), tst->ss->name); - tst->ss->free_super(tst); - free(tst); - close(mdfd); -@@ -721,7 +716,7 @@ static int load_devices(struct devs *devices, char *devmap, - *stp = st; - return -1; - } -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - !ident->uuid_set) { - ident->uuid_set = 1; - memcpy(ident->uuid, content->uuid, 16); -@@ -730,7 +725,7 @@ static int load_devices(struct devs *devices, char *devmap, - pr_err("Could not re-write superblock on %s.\n", - devname); - -- if (strcmp(c->update, "uuid")==0 && -+ if (c->update == UOPT_UUID && - ident->bitmap_fd >= 0 && !bitmap_done) { - if (bitmap_update_uuid(ident->bitmap_fd, - content->uuid, -@@ -1188,8 +1183,7 @@ static int start_array(int mdfd, - pr_err("%s: Need a backup file to complete reshape of this array.\n", - mddev); - pr_err("Please provided one with \"--backup-file=...\"\n"); -- if (c->update && -- strcmp(c->update, "revert-reshape") == 0) -+ if (c->update == UOPT_REVERT_RESHAPE) - pr_err("(Don't specify --update=revert-reshape again, that part succeeded.)\n"); - return 1; - } -@@ -1487,7 +1481,7 @@ try_again: - */ - if (map_lock(&map)) - pr_err("failed to get exclusive lock on mapfile - continue anyway...\n"); -- if (c->update && strcmp(c->update,"uuid") == 0) -+ if (c->update == UOPT_UUID) - mp = NULL; - else - mp = map_by_uuid(&map, content->uuid); -@@ -1634,7 +1628,7 @@ try_again: - goto out; - } - -- if (c->update && strcmp(c->update, "byteorder")==0) -+ if (c->update == UOPT_BYTEORDER) - st->minor_version = 90; - - st->ss->getinfo_super(st, content, NULL); -@@ -1902,7 +1896,7 @@ try_again: - /* First, fill in the map, so that udev can find our name - * as soon as we become active. - */ -- if (c->update && strcmp(c->update, "metadata")==0) { -+ if (c->update == UOPT_METADATA) { - content->array.major_version = 1; - content->array.minor_version = 0; - strcpy(content->text_version, "1.0"); -diff --git a/mdadm.c b/mdadm.c -index d06e2820..57e8e6fa 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -724,13 +724,12 @@ int main(int argc, char *argv[]) - - case O(ASSEMBLE,'U'): /* update the superblock */ - case O(MISC,'U'): { -- enum update_opt updateopt = map_name(update_options, c.update); - enum update_opt print_mode = UOPT_HELP; - const char *error_addon = "update option"; - - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } - if (mode == MISC && !c.subarray) { -@@ -738,20 +737,20 @@ int main(int argc, char *argv[]) - exit(2); - } - -- c.update = optarg; -+ c.update = map_name(update_options, optarg); - - if (devmode == UpdateSubarray) { - print_mode = UOPT_SUBARRAY_ONLY; - error_addon = "update-subarray option"; - -- if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP) -- updateopt = UOPT_UNDEFINED; -+ if (c.update > UOPT_SUBARRAY_ONLY && c.update < UOPT_HELP) -+ c.update = UOPT_UNDEFINED; - } - -- switch (updateopt) { -+ switch (c.update) { - case UOPT_UNDEFINED: - pr_err("'--update=%s' is invalid %s. ", -- c.update, error_addon); -+ optarg, error_addon); - outf = stderr; - case UOPT_HELP: - if (!outf) -@@ -776,14 +775,14 @@ int main(int argc, char *argv[]) - } - if (c.update) { - pr_err("Can only update one aspect of superblock, both %s and %s given.\n", -- c.update, optarg); -+ map_num(update_options, c.update), optarg); - exit(2); - } -- c.update = optarg; -- if (strcmp(c.update, "devicesize") != 0 && -- strcmp(c.update, "bbl") != 0 && -- strcmp(c.update, "force-no-bbl") != 0 && -- strcmp(c.update, "no-bbl") != 0) { -+ c.update = map_name(update_options, optarg); -+ if (c.update != UOPT_DEVICESIZE && -+ c.update != UOPT_BBL && -+ c.update != UOPT_NO_BBL && -+ c.update != UOPT_FORCE_NO_BBL) { - pr_err("only 'devicesize', 'bbl', 'no-bbl', and 'force-no-bbl' can be updated with --re-add\n"); - exit(2); - } -@@ -1357,7 +1356,7 @@ int main(int argc, char *argv[]) - } - } - -- if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) { -+ if (c.update && c.update == UOPT_NODES && c.nodes == 0) { - pr_err("Please specify nodes number with --nodes\n"); - exit(1); - } -@@ -1402,22 +1401,10 @@ int main(int argc, char *argv[]) - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); -- if (!rv && devs_found > 1) { -- /* -- * This is temporary and will be removed in next patches -- * Null c.update will cause segfault -- */ -- if (c.update) -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- map_name(update_options, c.update), -- c.force); -- else -- rv = Manage_subdevs(devlist->devname, mdfd, -- devlist->next, c.verbose, c.test, -- UOPT_UNDEFINED, -- c.force); -- } -+ if (!rv && devs_found > 1) -+ rv = Manage_subdevs(devlist->devname, mdfd, -+ devlist->next, c.verbose, -+ c.test, c.update, c.force); - if (!rv && c.readonly < 0) - rv = Manage_ro(devlist->devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -@@ -1937,14 +1924,13 @@ static int misc_list(struct mddev_dev *devlist, - rv |= Kill_subarray(dv->devname, c->subarray, c->verbose); - continue; - case UpdateSubarray: -- if (c->update == NULL) { -+ if (!c->update) { - pr_err("-U/--update must be specified with --update-subarray\n"); - rv |= 1; - continue; - } - rv |= Update_subarray(dv->devname, c->subarray, -- map_name(update_options, c->update), -- ident, c->verbose); -+ c->update, ident, c->verbose); - continue; - case Dump: - rv |= Dump_metadata(dv->devname, dump_directory, c, ss); -diff --git a/mdadm.h b/mdadm.h -index 924f4b63..13f8b4cb 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -616,7 +616,7 @@ struct context { - int export; - int test; - char *subarray; -- char *update; -+ enum update_opt update; - int scan; - int SparcAdjust; - int autof; --- -2.38.1 - diff --git a/SOURCES/0077-mdmon-fix-segfault.patch b/SOURCES/0077-mdmon-fix-segfault.patch deleted file mode 100644 index 980ceda..0000000 --- a/SOURCES/0077-mdmon-fix-segfault.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 9b429fc0a4ffd7028b3b336589d38e32fb9045dc Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:21 +0100 -Subject: [PATCH 77/83] mdmon: fix segfault - -Mdmon crashes if stat2devnm returns null. -Use open_mddev to check if device is mddevice and get name using -fd2devnm. -Refactor container name handling. - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - Makefile | 2 +- - mdmon.c | 26 ++++++++++++-------------- - 2 files changed, 13 insertions(+), 15 deletions(-) - -diff --git a/Makefile b/Makefile -index ec1f99ed..5eac1a4e 100644 ---- a/Makefile -+++ b/Makefile -@@ -160,7 +160,7 @@ SRCS = $(patsubst %.o,%.c,$(OBJS)) - - INCL = mdadm.h part.h bitmap.h - --MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \ -+MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o config.o mapfile.o mdopen.o\ - policy.o lib.o \ - Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ - super-mbr.o super-gpt.o \ -diff --git a/mdmon.c b/mdmon.c -index e9d035eb..ecf52dc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -363,14 +363,14 @@ int main(int argc, char *argv[]) - } - - if (all == 0 && container_name == NULL) { -- if (argv[optind]) -- container_name = argv[optind]; -+ if (argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ container_name = argv[optind]; -+ } - } - -- if (container_name == NULL) -- usage(); -- -- if (argc - optind > 1) -+ if (container_name == NULL || argc - optind > 1) - usage(); - - if (strcmp(container_name, "/proc/mdstat") == 0) -@@ -402,21 +402,19 @@ int main(int argc, char *argv[]) - free_mdstat(mdstat); - - return status; -- } else if (strncmp(container_name, "md", 2) == 0) { -- int id = devnm2devid(container_name); -- if (id) -- devnm = container_name; - } else { -- struct stat st; -+ int mdfd = open_mddev(container_name, 1); - -- if (stat(container_name, &st) == 0) -- devnm = xstrdup(stat2devnm(&st)); -+ if (mdfd < 0) -+ return 1; -+ devnm = fd2devnm(mdfd); -+ close(mdfd); - } - - if (!devnm) { - pr_err("%s is not a valid md device name\n", - container_name); -- exit(1); -+ return 1; - } - return mdmon(devnm, dofork && do_fork(), takeover); - } --- -2.38.1 - diff --git a/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch b/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch deleted file mode 100644 index b371d39..0000000 --- a/SOURCES/0078-util-remove-obsolete-code-from-get_md_name.patch +++ /dev/null @@ -1,116 +0,0 @@ -From b938519e7719c992dae2d61c796c45fe49e6b71b Mon Sep 17 00:00:00 2001 -From: Mateusz Kusiak -Date: Mon, 2 Jan 2023 09:46:22 +0100 -Subject: [PATCH 78/83] util: remove obsolete code from get_md_name - -get_md_name() is used only with mdstat entries. -Remove dead code and simplyfy function. - -Remove redundadnt checks from mdmon.c - -Signed-off-by: Mateusz Kusiak -Signed-off-by: Jes Sorensen ---- - mdmon.c | 8 +++----- - util.c | 51 +++++++++++++++++---------------------------------- - 2 files changed, 20 insertions(+), 39 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index ecf52dc8..60ba3182 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -366,7 +366,7 @@ int main(int argc, char *argv[]) - if (argv[optind]) { - container_name = get_md_name(argv[optind]); - if (!container_name) -- container_name = argv[optind]; -+ return 1; - } - } - -@@ -403,11 +403,9 @@ int main(int argc, char *argv[]) - - return status; - } else { -- int mdfd = open_mddev(container_name, 1); -- -- if (mdfd < 0) -- return 1; -+ int mdfd = open_mddev(container_name, 0); - devnm = fd2devnm(mdfd); -+ - close(mdfd); - } - -diff --git a/util.c b/util.c -index 26ffdcea..9cd89fa4 100644 ---- a/util.c -+++ b/util.c -@@ -968,47 +968,30 @@ dev_t devnm2devid(char *devnm) - return 0; - } - -+/** -+ * get_md_name() - Get main dev node of the md device. -+ * @devnm: Md device name or path. -+ * -+ * Function checks if the full name was passed and returns md name -+ * if it is the MD device. -+ * -+ * Return: Main dev node of the md device or NULL if not found. -+ */ - char *get_md_name(char *devnm) - { -- /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ -- /* if dev < 0, want /dev/md/d%d or find mdp in /proc/devices ... */ -- -- static char devname[50]; -+ static char devname[NAME_MAX]; - struct stat stb; -- dev_t rdev = devnm2devid(devnm); -- char *dn; - -- if (rdev == 0) -- return 0; -- if (strncmp(devnm, "md_", 3) == 0) { -- snprintf(devname, sizeof(devname), "/dev/md/%s", -- devnm + 3); -- if (stat(devname, &stb) == 0 && -- (S_IFMT&stb.st_mode) == S_IFBLK && (stb.st_rdev == rdev)) -- return devname; -- } -- snprintf(devname, sizeof(devname), "/dev/%s", devnm); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -+ if (strncmp(devnm, "/dev/", 5) == 0) -+ snprintf(devname, sizeof(devname), "%s", devnm); -+ else -+ snprintf(devname, sizeof(devname), "/dev/%s", devnm); - -- snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2); -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -+ if (!is_mddev(devname)) -+ return NULL; -+ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK) - return devname; - -- dn = map_dev(major(rdev), minor(rdev), 0); -- if (dn) -- return dn; -- snprintf(devname, sizeof(devname), "/dev/.tmp.%s", devnm); -- if (mknod(devname, S_IFBLK | 0600, rdev) == -1) -- if (errno != EEXIST) -- return NULL; -- -- if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && -- (stb.st_rdev == rdev)) -- return devname; -- unlink(devname); - return NULL; - } - --- -2.38.1 - diff --git a/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch b/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch deleted file mode 100644 index f888a09..0000000 --- a/SOURCES/0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 24d329fc97a64ec185ef27e59730f3f058c09029 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Thu, 5 Jan 2023 00:29:20 +0800 -Subject: [PATCH 79/83] mdadm/udev: Don't handle change event on raw devices - -The raw devices are ready when add event happpens and the raid -can be assembled. So there is no need to handle change events. -And it can cause some inconvenient problems. - -For example, the OS is installed on md0(/root) and md1(/home). -md0 and md1 are created on partitions. When it wants to re-install -OS, anaconda can't clear the storage configure. It deletes one -partition and does some jobs. The change event happens. Now -the raid device is assembled again. It can't delete the other -partitions. - -So in this patch, we don't handle change event on raw devices -anymore. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - udev-md-raid-assembly.rules | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules -index 39b4344b..d4a7f0a5 100644 ---- a/udev-md-raid-assembly.rules -+++ b/udev-md-raid-assembly.rules -@@ -11,6 +11,11 @@ SUBSYSTEM!="block", GOTO="md_inc_end" - ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end" - - # handle potential components of arrays (the ones supported by md) -+# For member devices which are md/dm devices, we don't need to -+# handle add event. Because md/dm devices need to do some init jobs. -+# Then the change event happens. -+# When adding md/dm devices, ID_FS_TYPE can only be linux_raid_member -+# after change event happens. - ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc" - - # "noiswmd" on kernel command line stops mdadm from handling -@@ -28,6 +33,9 @@ GOTO="md_inc_end" - - LABEL="md_inc" - -+# Bare disks are ready when add event happens, the raid can be assembled. -+ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end" -+ - # remember you can limit what gets auto/incrementally assembled by - # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' - ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}" --- -2.38.1 - diff --git a/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch b/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch deleted file mode 100644 index e2c1179..0000000 --- a/SOURCES/0080-Manage-do-not-check-array-state-when-drive-is-remove.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b3e7b7eb1dfedd7cbd9a3800e884941f67d94c96 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:42 +0100 -Subject: [PATCH 80/83] Manage: do not check array state when drive is removed - -Array state doesn't need to be checked when drive is -removed, but until now clean state was required. Result -of the is_remove_safe() function will be independent -from array state. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Manage.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 594e3d2c..4d6e54b1 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1321,8 +1321,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - sysfs_free(mdi); - - bool is_enough = enough(array->level, array->raid_disks, -- array->layout, (array->state & 1), -- avail); -+ array->layout, 1, avail); - - free(avail); - return is_enough; --- -2.38.1 - diff --git a/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch b/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch deleted file mode 100644 index 4e0169c..0000000 --- a/SOURCES/0081-incremental-manage-do-not-verify-if-remove-is-safe.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 461fae7e7809670d286cc19aac5bfa861c29f93a Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 27 Dec 2022 06:50:43 +0100 -Subject: [PATCH 81/83] incremental, manage: do not verify if remove is safe - -Function is_remove_safe() was introduced to verify if removing -member device won't cause failed state of the array. This -verification should be used only with set-faulty command. Add -special mode indicating that Incremental removal was executed. -If this mode is used do not execute is_remove_safe() routine. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Incremental.c | 2 +- - Manage.c | 7 ++++--- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index ff3548c0..09b94b9f 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1744,7 +1744,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - - memset(&devlist, 0, sizeof(devlist)); - devlist.devname = devname; -- devlist.disposition = 'f'; -+ devlist.disposition = 'I'; - /* for a container, we must fail each member array */ - if (ent->metadata_version && - strncmp(ent->metadata_version, "external:", 9) == 0) { -diff --git a/Manage.c b/Manage.c -index 4d6e54b1..6184d3f7 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1494,8 +1494,9 @@ int Manage_subdevs(char *devname, int fd, - /* Assume this is a kernel-internal name like 'sda1' */ - int found = 0; - char dname[55]; -- if (dv->disposition != 'r' && dv->disposition != 'f') { -- pr_err("%s only meaningful with -r or -f, not -%c\n", -+ if (dv->disposition != 'r' && dv->disposition != 'f' && -+ dv->disposition != 'I') { -+ pr_err("%s only meaningful with -r, -f or -I, not -%c\n", - dv->devname, dv->disposition); - goto abort; - } -@@ -1647,7 +1648,7 @@ int Manage_subdevs(char *devname, int fd, - close(sysfd); - goto abort; - } -- -+ case 'I': /* incremental fail */ - if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || - (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, - rdev))) { --- -2.38.1 - diff --git a/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch b/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch deleted file mode 100644 index 0035c89..0000000 --- a/SOURCES/0082-super-intel-make-freesize-not-required-for-chunk-siz.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 071f839ea549e2a384cd13bba445245cd87e48b1 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Fri, 28 Oct 2022 04:51:17 +0200 -Subject: [PATCH 82/83] super-intel: make freesize not required for chunk size - migration - -Freesize is needed to be set for migrations where size of RAID could -be changed - expand. It tells how many free space is determined for -members. In chunk size migartion freesize is not needed to be set, -pointer shouldn't be checked if exists. This commit moves check to -condition which contains size calculations, instead of checking it -always at the first step. -Fix return value when superblock is not set. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - super-intel.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 1f5f6eda..89fac626 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7719,11 +7719,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - struct intel_super *super = st->sb; - - /* -- * Autolayout mode, st->sb and freesize must be set. -+ * Autolayout mode, st->sb must be set. - */ -- if (!super || !freesize) { -- pr_vrb("freesize and superblock must be set for autolayout, aborting\n"); -- return 1; -+ if (!super) { -+ pr_vrb("superblock must be set for autolayout, aborting\n"); -+ return 0; - } - - if (!validate_geometry_imsm_orom(st->sb, level, layout, -@@ -7731,7 +7731,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, - verbose)) - return 0; - -- if (super->orom) { -+ if (super->orom && freesize) { - imsm_status_t rv; - int count = count_volumes(super->hba, super->orom->dpa, - verbose); --- -2.38.1 - diff --git a/SOURCES/0083-manage-move-comment-with-function-description.patch b/SOURCES/0083-manage-move-comment-with-function-description.patch deleted file mode 100644 index 091854f..0000000 --- a/SOURCES/0083-manage-move-comment-with-function-description.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 36a707824eb1dafbb990f5daf1cbbe0e37dbbefb Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 5 Jan 2023 06:31:25 +0100 -Subject: [PATCH 83/83] manage: move comment with function description - -Move the function description from the function body to outside -to obey kernel coding style. - -Signed-off-by: Kinga Tanska -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Manage.c | 72 ++++++++++++++++++++++++++++++++++---------------------- - 1 file changed, 44 insertions(+), 28 deletions(-) - -diff --git a/Manage.c b/Manage.c -index 6184d3f7..fde6aba3 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1327,38 +1327,54 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const - return is_enough; - } - -+/** -+ * Manage_subdevs() - Execute operation depending on devmode. -+ * -+ * @devname: name of the device. -+ * @fd: file descriptor. -+ * @devlist: list of sub-devices to manage. -+ * @verbose: verbose level. -+ * @test: test flag. -+ * @update: type of update. -+ * @force: force flag. -+ * -+ * This function executes operation defined by devmode -+ * for each dev from devlist. -+ * Devmode can be: -+ * 'a' - add the device -+ * 'S' - add the device as a spare - don't try re-add -+ * 'j' - add the device as a journal device -+ * 'A' - re-add the device -+ * 'r' - remove the device: HOT_REMOVE_DISK -+ * device can be 'faulty' or 'detached' in which case all -+ * matching devices are removed. -+ * 'f' - set the device faulty SET_DISK_FAULTY -+ * device can be 'detached' in which case any device that -+ * is inaccessible will be marked faulty. -+ * 'I' - remove device by using incremental fail -+ * which is executed when device is removed surprisingly. -+ * 'R' - mark this device as wanting replacement. -+ * 'W' - this device is added if necessary and activated as -+ * a replacement for a previous 'R' device. -+ * ----- -+ * 'w' - 'W' will be changed to 'w' when it is paired with -+ * a 'R' device. If a 'W' is found while walking the list -+ * it must be unpaired, and is an error. -+ * 'M' - this is created by a 'missing' target. It is a slight -+ * variant on 'A' -+ * 'F' - Another variant of 'A', where the device was faulty -+ * so must be removed from the array first. -+ * 'c' - confirm the device as found (for clustered environments) -+ * -+ * For 'f' and 'r', the device can also be a kernel-internal -+ * name such as 'sdb'. -+ * -+ * Return: 0 on success, otherwise 1 or 2. -+ */ - int Manage_subdevs(char *devname, int fd, - struct mddev_dev *devlist, int verbose, int test, - enum update_opt update, int force) - { -- /* Do something to each dev. -- * devmode can be -- * 'a' - add the device -- * 'S' - add the device as a spare - don't try re-add -- * 'j' - add the device as a journal device -- * 'A' - re-add the device -- * 'r' - remove the device: HOT_REMOVE_DISK -- * device can be 'faulty' or 'detached' in which case all -- * matching devices are removed. -- * 'f' - set the device faulty SET_DISK_FAULTY -- * device can be 'detached' in which case any device that -- * is inaccessible will be marked faulty. -- * 'R' - mark this device as wanting replacement. -- * 'W' - this device is added if necessary and activated as -- * a replacement for a previous 'R' device. -- * ----- -- * 'w' - 'W' will be changed to 'w' when it is paired with -- * a 'R' device. If a 'W' is found while walking the list -- * it must be unpaired, and is an error. -- * 'M' - this is created by a 'missing' target. It is a slight -- * variant on 'A' -- * 'F' - Another variant of 'A', where the device was faulty -- * so must be removed from the array first. -- * 'c' - confirm the device as found (for clustered environments) -- * -- * For 'f' and 'r', the device can also be a kernel-internal -- * name such as 'sdb'. -- */ - mdu_array_info_t array; - unsigned long long array_size; - struct mddev_dev *dv; --- -2.38.1 - diff --git a/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch b/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch deleted file mode 100644 index 493a0e9..0000000 --- a/SOURCES/0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 28a083955c6f58f8e582734c8c82aff909a7d461 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 2 Feb 2023 08:56:31 +0100 -Subject: [PATCH 084/125] Revert "mdadm/systemd: remove KillMode=none from - service file" - -This reverts commit 52c67fcdd6dadc4138ecad73e65599551804d445. - -The functionality is marked as deprecated but we don't have alternative -solution yet. Shutdown hangs if OS is installed on external array: - -task:umount state:D stack: 0 pid: 6285 ppid: flags:0x00004084 -Call Trace: -__schedule+0x2d1/0x830 -? finish_wait+0x80/0x80 -schedule+0x35/0xa0 -md_write_start+0x14b/0x220 -? finish_wait+0x80/0x80 -raid1_make_request+0x3c/0x90 [raid1] -md_handle_request+0x128/0x1b0 -md_make_request+0x5b/0xb0 -generic_make_request_no_check+0x202/0x330 -submit_bio+0x3c/0x160 - -Use it until new solution is implemented. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 + - systemd/mdmon@.service | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 64b8254a..9ccadca3 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,3 +15,4 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null -+KillMode=none -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 97a1acd9..cb6482d9 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -26,3 +26,4 @@ Type=forking - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid -+KillMode=none --- -2.38.1 - diff --git a/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch b/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch deleted file mode 100644 index d0ff1ff..0000000 --- a/SOURCES/0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001 -From: Heming Zhao -Date: Thu, 23 Feb 2023 22:39:39 +0800 -Subject: [PATCH 085/125] Grow: fix can't change bitmap type from none to - clustered. - -Commit a042210648ed ("disallow create or grow clustered bitmap with -writemostly set") introduced this bug. We should use 'true' logic not -'== 0' to deny setting up clustered array under WRITEMOSTLY condition. - -How to trigger - -``` -~/mdadm # ./mdadm -Ss && ./mdadm --zero-superblock /dev/sd{a,b} -~/mdadm # ./mdadm -C /dev/md0 -l mirror -b clustered -e 1.2 -n 2 \ -/dev/sda /dev/sdb --assume-clean -mdadm: array /dev/md0 started. -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=none -~/mdadm # ./mdadm --grow /dev/md0 --bitmap=clustered -mdadm: /dev/md0 disks marked write-mostly are not supported with clustered bitmap -``` - -Signed-off-by: Heming Zhao -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Grow.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Grow.c b/Grow.c -index 8f5cf07d..bb5fe45c 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -429,7 +429,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - dv = map_dev(disk.major, disk.minor, 1); - if (!dv) - continue; -- if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) && -+ if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) && - (strcmp(s->bitmap_file, "clustered") == 0)) { - pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); - free(mdi); --- -2.38.1 - diff --git a/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch b/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch deleted file mode 100644 index 766874b..0000000 --- a/SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch +++ /dev/null @@ -1,76 +0,0 @@ -From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001 -From: Li Xiao Keng -Date: Mon, 27 Feb 2023 11:12:07 +0800 -Subject: [PATCH 086/125] Fix NULL dereference in super_by_fd - -When we create 100 partitions (major is 259 not 254) in a raid device, -mdadm may coredump: - -Core was generated by `/usr/sbin/mdadm --detail --export /dev/md1p7'. -Program terminated with signal SIGSEGV, Segmentation fault. -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -74 VPCMPEQ (%rdi), %ymm0, %ymm1 -(gdb) bt -#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74 -#1 0x00007fbb9a7e4139 in __strcpy_chk (dest=dest@entry=0x55d55d6a13ac "", src=0x0, destlen=destlen@entry=32) at strcpy_chk.c:28 -#2 0x000055d55ba1766d in strcpy (__src=, __dest=0x55d55d6a13ac "") at /usr/include/bits/string_fortified.h:79 -#3 super_by_fd (fd=fd@entry=3, subarrayp=subarrayp@entry=0x7fff44dfcc48) at util.c:1289 -#4 0x000055d55ba273a6 in Detail (dev=0x7fff44dfef0b "/dev/md1p7", c=0x7fff44dfe440) at Detail.c:101 -#5 0x000055d55ba0de61 in misc_list (c=, ss=, dump_directory=, ident=, devlist=) at mdadm.c:1959 -#6 main (argc=, argv=) at mdadm.c:1629 - -The direct cause is fd2devnm returning NULL, so add a check. - -Signed-off-by: Li Xiao Keng -Signed-off-by: Wu Guang Hao -Acked-by: Coly Li -Acked-by: Coly Li > -Signed-off-by: Jes Sorensen ---- - mapfile.c | 4 ++++ - util.c | 7 ++++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/mapfile.c b/mapfile.c -index 6b2207dd..ac351768 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -292,6 +292,10 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) - struct map_ent *map_by_devnm(struct map_ent **map, char *devnm) - { - struct map_ent *mp; -+ -+ if (!devnm) -+ return NULL; -+ - if (!*map) - map_read(map); - -diff --git a/util.c b/util.c -index 9cd89fa4..8c7f3fd5 100644 ---- a/util.c -+++ b/util.c -@@ -1160,6 +1160,11 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - int i; - char *subarray = NULL; - char container[32] = ""; -+ char *devnm = NULL; -+ -+ devnm = fd2devnm(fd); -+ if (!devnm) -+ return NULL; - - sra = sysfs_read(fd, NULL, GET_VERSION); - -@@ -1205,7 +1210,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) - if (subarrayp) - *subarrayp = subarray; - strcpy(st->container_devnm, container); -- strcpy(st->devnm, fd2devnm(fd)); -+ strncpy(st->devnm, devnm, MD_NAME_MAX - 1); - } else - free(subarray); - --- -2.38.1 - diff --git a/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch b/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch deleted file mode 100644 index 6819fba..0000000 --- a/SOURCES/0087-Mdmonitor-Make-alert_info-global.patch +++ /dev/null @@ -1,369 +0,0 @@ -From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:26:59 +0100 -Subject: [PATCH 087/125] Mdmonitor: Make alert_info global - -Move information about --test flag and hostname into alert_info. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Monitor.c | 124 +++++++++++++++++++++++++++--------------------------- - 1 file changed, 61 insertions(+), 63 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 188cb8be..9ef4dab8 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -58,21 +58,20 @@ struct state { - }; - - struct alert_info { -+ char hostname[HOST_NAME_MAX]; - char *mailaddr; - char *mailfrom; - char *alert_cmd; - int dosyslog; --}; -+ int test; -+} info; - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info); --static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *info, -- int increments, char *prefer); --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info); --static void try_spare_migration(struct state *statelist, struct alert_info *info); -+static void alert(const char *event, const char *dev, const char *disc); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); -+static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); - #ifndef NO_LIBUDEV -@@ -132,7 +131,6 @@ int Monitor(struct mddev_dev *devlist, - int finished = 0; - struct mdstat_ent *mdstat = NULL; - char *mailfrom; -- struct alert_info info; - struct mddev_ident *mdlist; - int delay_for_event = c->delay; - -@@ -166,6 +164,13 @@ int Monitor(struct mddev_dev *devlist, - info.mailaddr = mailaddr; - info.mailfrom = mailfrom; - info.dosyslog = dosyslog; -+ info.test = c->test; -+ -+ if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { -+ pr_err("Cannot get hostname.\n"); -+ return 1; -+ } -+ info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ - if (check_one_sharer(c->scan)) -@@ -241,8 +246,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat = mdstat_read(oneshot ? 0 : 1, 0); - - for (st = statelist; st; st = st->next) { -- if (check_array(st, mdstat, c->test, &info, -- increments, c->prefer)) -+ if (check_array(st, mdstat, increments, c->prefer)) - anydegraded = 1; - /* for external arrays, metadata is filled for - * containers only -@@ -255,15 +259,14 @@ int Monitor(struct mddev_dev *devlist, - - /* now check if there are any new devices found in mdstat */ - if (c->scan) -- new_found = add_new_arrays(mdstat, &statelist, c->test, -- &info); -+ new_found = add_new_arrays(mdstat, &statelist); - - /* If an array has active < raid && spare == 0 && spare_group != NULL - * Look for another array with spare > 0 and active == raid and same spare_group - * if found, choose a device and hotremove/hotadd - */ - if (share && anydegraded) -- try_spare_migration(statelist, &info); -+ try_spare_migration(statelist); - if (!new_found) { - if (oneshot) - break; -@@ -294,7 +297,7 @@ int Monitor(struct mddev_dev *devlist, - mdstat_close(); - } - } -- c->test = 0; -+ info.test = 0; - - for (stp = &statelist; (st = *stp) != NULL; ) { - if (st->from_auto && st->err > 5) { -@@ -412,7 +415,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void execute_alert_cmd(const char *event, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -424,15 +427,14 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void send_event_email(const char *event, const char *dev, const char *disc) - { - FILE *mp, *mdstat; -- char hname[256]; - char buf[BUFSIZ]; - int n; - -@@ -442,14 +444,13 @@ static void send_event_email(const char *event, const char *dev, const char *dis - return; - } - -- gethostname(hname, sizeof(hname)); - signal(SIGPIPE, SIG_IGN); -- if (info->mailfrom) -- fprintf(mp, "From: %s\n", info->mailfrom); -+ if (info.mailfrom) -+ fprintf(mp, "From: %s\n", info.mailfrom); - else - fprintf(mp, "From: %s monitoring \n", Name); -- fprintf(mp, "To: %s\n", info->mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); -+ fprintf(mp, "To: %s\n", info.mailaddr); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); - fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); - -@@ -501,37 +502,36 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - syslog(priority, "%s event detected on md device %s", event, dev); - } - --static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info) -+static void alert(const char *event, const char *dev, const char *disc) - { -- if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) { -+ if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { - time_t now = time(0); - - printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, - event, dev, disc?disc:"unknown device"); - } -- if (info->alert_cmd) -- execute_alert_cmd(event, dev, disc, info); -+ if (info.alert_cmd) -+ execute_alert_cmd(event, dev, disc); - -- if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 || -+ if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || - strncmp(event, "Test", 4) == 0 || - strncmp(event, "Spares", 6) == 0 || - strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc, info); -+ send_event_email(event, dev, disc); - } - -- if (info->dosyslog) -+ if (info.dosyslog) - log_event_to_syslog(event, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -- int test, struct alert_info *ainfo, - int increments, char *prefer) - { - /* Update the state 'st' to reflect any changes shown in mdstat, - * or found by directly examining the array, and return - * '1' if the array is degraded, or '0' if it is optimal (or dead). - */ -- struct { int state, major, minor; } info[MAX_DISKS]; -+ struct { int state, major, minor; } disks_info[MAX_DISKS]; - struct mdinfo *sra = NULL; - mdu_array_info_t array; - struct mdstat_ent *mse = NULL, *mse2; -@@ -545,8 +545,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int is_container = 0; - unsigned long redundancy_only_flags = 0; - -- if (test) -- alert("TestMessage", dev, NULL, ainfo); -+ if (info.test) -+ alert("TestMessage", dev, NULL); - - retval = 0; - -@@ -595,7 +595,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); -+ alert("DeviceDisappeared", dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +612,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL, ainfo); -+ alert("NewArray", st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,14 +625,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL, ainfo); -+ alert("DegradedArray", dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL, ainfo); -+ alert("SparesMissing", dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL, ainfo); -+ alert("RebuildStarted", dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - char percentalert[18]; -@@ -647,7 +647,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(percentalert, sizeof(percentalert), - "Rebuild%02d", mse->percent); - -- alert(percentalert, dev, NULL, ainfo); -+ alert(percentalert, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +660,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt, ainfo); -+ alert("RebuildFinished", dev, cnt); - } else -- alert("RebuildFinished", dev, NULL, ainfo); -+ alert("RebuildFinished", dev, NULL); - } - st->percent = mse->percent; - -@@ -671,13 +671,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - mdu_disk_info_t disc; - disc.number = i; - if (md_get_disk_info(fd, &disc) >= 0) { -- info[i].state = disc.state; -- info[i].major = disc.major; -- info[i].minor = disc.minor; -+ disks_info[i].state = disc.state; -+ disks_info[i].major = disc.major; -+ disks_info[i].minor = disc.minor; - if (disc.major || disc.minor) - remaining_disks --; - } else -- info[i].major = info[i].minor = 0; -+ disks_info[i].major = disks_info[i].minor = 0; - } - last_disk = i; - -@@ -700,13 +700,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - int change; - char *dv = NULL; - disc.number = i; -- if (i < last_disk && (info[i].major || info[i].minor)) { -- newstate = info[i].state; -- dv = map_dev_preferred(info[i].major, info[i].minor, 1, -+ if (i < last_disk && (disks_info[i].major || disks_info[i].minor)) { -+ newstate = disks_info[i].state; -+ dv = map_dev_preferred(disks_info[i].major, disks_info[i].minor, 1, - prefer); - disc.state = newstate; -- disc.major = info[i].major; -- disc.minor = info[i].minor; -+ disc.major = disks_info[i].major; -+ disc.minor = disks_info[i].minor; - } else - newstate = (1 << MD_DISK_REMOVED); - -@@ -716,14 +716,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv, ainfo); -+ alert("Fail", dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv, ainfo); -+ alert("FailSpare", dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv, ainfo); -+ alert("SpareActive", dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,13 +747,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL, ainfo); -+ alert("DeviceDisappeared", dev, NULL); - st->err++; - goto out; - } - --static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, -- int test, struct alert_info *info) -+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - { - struct mdstat_ent *mse; - int new_found = 0; -@@ -806,8 +805,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, - } else - st->parent_devnm[0] = 0; - *statelist = st; -- if (test) -- alert("TestMessage", st->devname, NULL, info); -+ if (info.test) -+ alert("TestMessage", st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -971,7 +970,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to, - return dev; - } - --static void try_spare_migration(struct state *statelist, struct alert_info *info) -+static void try_spare_migration(struct state *statelist) - { - struct state *from; - struct state *st; -@@ -1030,8 +1029,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, -- from->devname, info); -+ alert("MoveSpare", to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch b/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch deleted file mode 100644 index 770d3d1..0000000 --- a/SOURCES/0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch +++ /dev/null @@ -1,313 +0,0 @@ -From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:00 +0100 -Subject: [PATCH 088/125] Mdmonitor: Pass events to alert() using enums instead - of strings - -Add events enum, and mapping_t struct, that maps them to strings, so -that enums are passed around instead of strings. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 136 +++++++++++++++++++++++++++++++++--------------------- - 1 file changed, 83 insertions(+), 53 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 9ef4dab8..029e9efd 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,8 @@ - #include - #endif - -+#define EVENT_NAME_MAX 32 -+ - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ - char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ -@@ -65,10 +67,43 @@ struct alert_info { - int dosyslog; - int test; - } info; -+ -+enum event { -+ EVENT_SPARE_ACTIVE = 0, -+ EVENT_NEW_ARRAY, -+ EVENT_MOVE_SPARE, -+ EVENT_TEST_MESSAGE, -+ EVENT_REBUILD_STARTED, -+ EVENT_REBUILD, -+ EVENT_REBUILD_FINISHED, -+ EVENT_SPARES_MISSING, -+ EVENT_DEVICE_DISAPPEARED, -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_UNKNOWN -+}; -+ -+mapping_t events_map[] = { -+ {"SpareActive", EVENT_SPARE_ACTIVE}, -+ {"NewArray", EVENT_NEW_ARRAY}, -+ {"MoveSpare", EVENT_MOVE_SPARE}, -+ {"TestMessage", EVENT_TEST_MESSAGE}, -+ {"RebuildStarted", EVENT_REBUILD_STARTED}, -+ {"Rebuild", EVENT_REBUILD}, -+ {"RebuildFinished", EVENT_REBUILD_FINISHED}, -+ {"SparesMissing", EVENT_SPARES_MISSING}, -+ {"DeviceDisappeared", EVENT_DEVICE_DISAPPEARED}, -+ {"Fail", EVENT_FAIL}, -+ {"FailSpare", EVENT_FAIL_SPARE}, -+ {"DegradedArray", EVENT_DEGRADED_ARRAY}, -+ {NULL, EVENT_UNKNOWN} -+}; -+ - static int make_daemon(char *pidfile); - static int check_one_sharer(int scan); - static void write_autorebuild_pid(void); --static void alert(const char *event, const char *dev, const char *disc); -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); - static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); -@@ -415,7 +450,7 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event, const char *dev, const char *disc) -+static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) - { - int pid = fork(); - -@@ -427,12 +462,12 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event, const char *dev, const char *disc) -+static void send_event_email(const char *event_name, const char *dev, const char *disc) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -450,9 +485,9 @@ static void send_event_email(const char *event, const char *dev, const char *dis - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); - fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev); -+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); - - if (disc && disc[0] != ' ') - fprintf(mp, -@@ -474,20 +509,20 @@ static void send_event_email(const char *event, const char *dev, const char *dis - pclose(mp); - } - --static void log_event_to_syslog(const char *event, const char *dev, const char *disc) -+static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) - { - int priority; - /* Log at a different severity depending on the event. - * - * These are the critical events: */ -- if (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Degrade", 7) == 0 || -- strncmp(event, "DeviceDisappeared", 17) == 0) -+ if (event_enum == EVENT_FAIL || -+ event_enum == EVENT_DEGRADED_ARRAY || -+ event_enum == EVENT_DEVICE_DISAPPEARED) - priority = LOG_CRIT; - /* Good to know about, but are not failures: */ -- else if (strncmp(event, "Rebuild", 7) == 0 || -- strncmp(event, "MoveSpare", 9) == 0 || -- strncmp(event, "Spares", 6) != 0) -+ else if (event_enum == EVENT_REBUILD || -+ event_enum == EVENT_MOVE_SPARE || -+ event_enum == EVENT_SPARES_MISSING) - priority = LOG_WARNING; - /* Everything else: */ - else -@@ -495,33 +530,37 @@ static void log_event_to_syslog(const char *event, const char *dev, const char * - - if (disc && disc[0] != ' ') - syslog(priority, -- "%s event detected on md device %s, component device %s", event, dev, disc); -+ "%s event detected on md device %s, component device %s", -+ event_name, dev, disc); - else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event, dev, disc); -+ syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); - else -- syslog(priority, "%s event detected on md device %s", event, dev); -+ syslog(priority, "%s event detected on md device %s", event_name, dev); - } - --static void alert(const char *event, const char *dev, const char *disc) -+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) - { -- if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) { -- time_t now = time(0); -+ char event_name[EVENT_NAME_MAX]; - -- printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, -- event, dev, disc?disc:"unknown device"); -+ if (event_enum == EVENT_REBUILD) { -+ snprintf(event_name, sizeof(event_name), "%s%02d", -+ map_num_s(events_map, EVENT_REBUILD), progress); -+ } else { -+ snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); - } -+ - if (info.alert_cmd) -- execute_alert_cmd(event, dev, disc); -+ execute_alert_cmd(event_name, dev, disc); - -- if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 || -- strncmp(event, "Test", 4) == 0 || -- strncmp(event, "Spares", 6) == 0 || -- strncmp(event, "Degrade", 7) == 0)) { -- send_event_email(event, dev, disc); -+ if (info.mailaddr && (event_enum == EVENT_FAIL || -+ event_enum == EVENT_TEST_MESSAGE || -+ event_enum == EVENT_SPARES_MISSING || -+ event_enum == EVENT_DEGRADED_ARRAY)) { -+ send_event_email(event_name, dev, disc); - } - - if (info.dosyslog) -- log_event_to_syslog(event, dev, disc); -+ log_event_to_syslog(event_enum, event_name, dev, disc); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -546,7 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert("TestMessage", dev, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, dev, NULL); - - retval = 0; - -@@ -595,7 +634,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert("DeviceDisappeared", dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); - st->err++; - goto out; - } -@@ -612,7 +651,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert("NewArray", st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -625,29 +664,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert("DegradedArray", dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert("SparesMissing", dev, NULL); -+ alert(EVENT_SPARES_MISSING, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert("RebuildStarted", dev, NULL); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { -- char percentalert[18]; -- /* -- * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) -- */ -- - if((mse->percent / increments) == 0) -- snprintf(percentalert, sizeof(percentalert), -- "RebuildStarted"); -+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL); - else -- snprintf(percentalert, sizeof(percentalert), -- "Rebuild%02d", mse->percent); -- -- alert(percentalert, dev, NULL); -+ alert(EVENT_REBUILD, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -660,9 +690,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert("RebuildFinished", dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); - } else -- alert("RebuildFinished", dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -716,14 +746,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert("Fail", dev, dv); -+ alert(EVENT_FAIL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert("FailSpare", dev, dv); -+ alert(EVENT_FAIL_SPARE, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert("SpareActive", dev, dv); -+ alert(EVENT_SPARE_ACTIVE, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -747,7 +777,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert("DeviceDisappeared", dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); - st->err++; - goto out; - } -@@ -806,7 +836,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert("TestMessage", st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1029,7 +1059,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert("MoveSpare", to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0089-Mdmonitor-Add-helper-functions.patch b/SOURCES/0089-Mdmonitor-Add-helper-functions.patch deleted file mode 100644 index 930b63a..0000000 --- a/SOURCES/0089-Mdmonitor-Add-helper-functions.patch +++ /dev/null @@ -1,406 +0,0 @@ -From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:01 +0100 -Subject: [PATCH 089/125] Mdmonitor: Add helper functions - -Add functions: -- is_email_event(), -- get_syslog_event_priority(), -- sprint_event_message(), -with kernel style comments containing more detailed descriptions. - -Also update event syslog priorities to be consistent with man. MoveSpare event was described in man as priority info, while implemented as warning. Move event data into a struct, so that it is passed between different functions if needed. -Sort function declarations alphabetically and remove redundant alert() declaration. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 228 +++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 158 insertions(+), 70 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 029e9efd..39598ba0 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -73,10 +73,12 @@ enum event { - EVENT_NEW_ARRAY, - EVENT_MOVE_SPARE, - EVENT_TEST_MESSAGE, -+ __SYSLOG_PRIORITY_WARNING, - EVENT_REBUILD_STARTED, - EVENT_REBUILD, - EVENT_REBUILD_FINISHED, - EVENT_SPARES_MISSING, -+ __SYSLOG_PRIORITY_CRITICAL, - EVENT_DEVICE_DISAPPEARED, - EVENT_FAIL, - EVENT_FAIL_SPARE, -@@ -100,18 +102,31 @@ mapping_t events_map[] = { - {NULL, EVENT_UNKNOWN} - }; - --static int make_daemon(char *pidfile); --static int check_one_sharer(int scan); --static void write_autorebuild_pid(void); --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc); --static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+struct event_data { -+ enum event event_enum; -+ /* -+ * @event_name: Rebuild event name must be in form "RebuildXX", where XX is rebuild progress. -+ */ -+ char event_name[EVENT_NAME_MAX]; -+ char message[BUFSIZ]; -+ const char *description; -+ const char *dev; -+ const char *disc; -+}; -+ - static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist); - static void try_spare_migration(struct state *statelist); - static void link_containers_with_subarrays(struct state *list); - static void free_statelist(struct state *statelist); -+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer); -+static int check_one_sharer(int scan); - #ifndef NO_LIBUDEV - static int check_udev_activity(void); - #endif -+static void link_containers_with_subarrays(struct state *list); -+static int make_daemon(char *pidfile); -+static void try_spare_migration(struct state *statelist); -+static void write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -450,7 +465,80 @@ static void write_autorebuild_pid() - } - } - --static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc) -+#define BASE_MESSAGE "%s event detected on md device %s" -+#define COMPONENT_DEVICE_MESSAGE ", component device %s" -+#define DESCRIPTION_MESSAGE ": %s" -+/* -+ * sprint_event_message() - Writes basic message about detected event to destination ptr. -+ * @dest: message destination, should be at least the size of BUFSIZ -+ * @data: event data -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int sprint_event_message(char *dest, const struct event_data *data) -+{ -+ if (!dest || !data) -+ return 1; -+ -+ if (data->disc && data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->disc, data->description); -+ else if (data->disc) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE, -+ data->event_name, data->dev, data->disc); -+ else if (data->description) -+ snprintf(dest, BUFSIZ, BASE_MESSAGE DESCRIPTION_MESSAGE, -+ data->event_name, data->dev, data->description); -+ else -+ snprintf(dest, BUFSIZ, BASE_MESSAGE, data->event_name, data->dev); -+ -+ return 0; -+} -+ -+/* -+ * get_syslog_event_priority() - Determines event priority. -+ * @event_enum: event to be checked -+ * -+ * Return: LOG_CRIT, LOG_WARNING or LOG_INFO -+ */ -+static int get_syslog_event_priority(const enum event event_enum) -+{ -+ if (event_enum > __SYSLOG_PRIORITY_CRITICAL) -+ return LOG_CRIT; -+ if (event_enum > __SYSLOG_PRIORITY_WARNING) -+ return LOG_WARNING; -+ return LOG_INFO; -+} -+ -+/* -+ * is_email_event() - Determines whether email for event should be sent or not. -+ * @event_enum: event to be checked -+ * -+ * Return: true if email should be sent, false otherwise -+ */ -+static bool is_email_event(const enum event event_enum) -+{ -+ static const enum event email_events[] = { -+ EVENT_FAIL, -+ EVENT_FAIL_SPARE, -+ EVENT_DEGRADED_ARRAY, -+ EVENT_SPARES_MISSING, -+ EVENT_TEST_MESSAGE -+ }; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(email_events); ++i) { -+ if (event_enum == email_events[i]) -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * execute_alert_cmd() - Forks and executes command provided as alert_cmd. -+ * @data: event data -+ */ -+static void execute_alert_cmd(const struct event_data *data) - { - int pid = fork(); - -@@ -462,12 +550,16 @@ static void execute_alert_cmd(const char *event_name, const char *dev, const cha - pr_err("Cannot fork to execute alert command"); - break; - case 0: -- execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL); -+ execl(info.alert_cmd, info.alert_cmd, data->event_name, data->dev, data->disc, NULL); - exit(2); - } - } - --static void send_event_email(const char *event_name, const char *dev, const char *disc) -+/* -+ * send_event_email() - Sends an email about event detected by monitor. -+ * @data: event data -+ */ -+static void send_event_email(const struct event_data *data) - { - FILE *mp, *mdstat; - char buf[BUFSIZ]; -@@ -485,15 +577,9 @@ static void send_event_email(const char *event_name, const char *dev, const char - else - fprintf(mp, "From: %s monitoring \n", Name); - fprintf(mp, "To: %s\n", info.mailaddr); -- fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname); -- fprintf(mp, "This is an automatically generated mail message. \n"); -- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev); -- -- if (disc && disc[0] != ' ') -- fprintf(mp, -- "It could be related to component device %s.\n\n", disc); -- if (disc && disc[0] == ' ') -- fprintf(mp, "Extra information:%s.\n\n", disc); -+ fprintf(mp, "Subject: %s event on %s:%s\n\n", data->event_name, data->dev, info.hostname); -+ fprintf(mp, "This is an automatically generated mail message.\n"); -+ fprintf(mp, "%s\n", data->message); - - mdstat = fopen("/proc/mdstat", "r"); - if (!mdstat) { -@@ -509,58 +595,60 @@ static void send_event_email(const char *event_name, const char *dev, const char - pclose(mp); - } - --static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc) -+/* -+ * log_event_to_syslog() - Logs an event into syslog. -+ * @data: event data -+ */ -+static void log_event_to_syslog(const struct event_data *data) - { - int priority; -- /* Log at a different severity depending on the event. -- * -- * These are the critical events: */ -- if (event_enum == EVENT_FAIL || -- event_enum == EVENT_DEGRADED_ARRAY || -- event_enum == EVENT_DEVICE_DISAPPEARED) -- priority = LOG_CRIT; -- /* Good to know about, but are not failures: */ -- else if (event_enum == EVENT_REBUILD || -- event_enum == EVENT_MOVE_SPARE || -- event_enum == EVENT_SPARES_MISSING) -- priority = LOG_WARNING; -- /* Everything else: */ -- else -- priority = LOG_INFO; -- -- if (disc && disc[0] != ' ') -- syslog(priority, -- "%s event detected on md device %s, component device %s", -- event_name, dev, disc); -- else if (disc) -- syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc); -- else -- syslog(priority, "%s event detected on md device %s", event_name, dev); -+ -+ priority = get_syslog_event_priority(data->event_enum); -+ -+ syslog(priority, "%s\n", data->message); - } - --static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc) -+/* -+ * alert() - Alerts about the monitor event. -+ * @event_enum: event to be sent -+ * @description: event description -+ * @progress: rebuild progress -+ * @dev: md device name -+ * @disc: component device -+ * -+ * If needed function executes alert command, sends an email or logs event to syslog. -+ */ -+static void alert(const enum event event_enum, const char *description, const uint8_t progress, -+ const char *dev, const char *disc) - { -- char event_name[EVENT_NAME_MAX]; -+ struct event_data data = {.dev = dev, .disc = disc, .description = description}; -+ -+ if (!dev) -+ return; - - if (event_enum == EVENT_REBUILD) { -- snprintf(event_name, sizeof(event_name), "%s%02d", -+ snprintf(data.event_name, sizeof(data.event_name), "%s%02d", - map_num_s(events_map, EVENT_REBUILD), progress); - } else { -- snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum)); -+ snprintf(data.event_name, sizeof(data.event_name), "%s", map_num_s(events_map, event_enum)); - } - -- if (info.alert_cmd) -- execute_alert_cmd(event_name, dev, disc); -+ data.event_enum = event_enum; - -- if (info.mailaddr && (event_enum == EVENT_FAIL || -- event_enum == EVENT_TEST_MESSAGE || -- event_enum == EVENT_SPARES_MISSING || -- event_enum == EVENT_DEGRADED_ARRAY)) { -- send_event_email(event_name, dev, disc); -+ if (sprint_event_message(data.message, &data) != 0) { -+ pr_err("Cannot create event message.\n"); -+ return; - } -+ pr_err("%s\n", data.message); -+ -+ if (info.alert_cmd) -+ execute_alert_cmd(&data); -+ -+ if (info.mailaddr && is_email_event(event_enum)) -+ send_event_email(&data); - - if (info.dosyslog) -- log_event_to_syslog(event_enum, event_name, dev, disc); -+ log_event_to_syslog(&data); - } - - static int check_array(struct state *st, struct mdstat_ent *mdstat, -@@ -585,7 +673,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - unsigned long redundancy_only_flags = 0; - - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, dev, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, dev, NULL); - - retval = 0; - -@@ -634,7 +722,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - */ - if (sra->array.level == 0 || sra->array.level == -1) { - if (!st->err && !st->from_config) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level"); -+ alert(EVENT_DEVICE_DISAPPEARED, "Wrong-Level", 0, dev, NULL); - st->err++; - goto out; - } -@@ -651,7 +739,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - st->percent = RESYNC_NONE; - new_array = 1; - if (!is_container) -- alert(EVENT_NEW_ARRAY, 0, st->devname, NULL); -+ alert(EVENT_NEW_ARRAY, NULL, 0, st->devname, NULL); - } - - if (st->utime == array.utime && st->failed == sra->array.failed_disks && -@@ -664,20 +752,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - } - if (st->utime == 0 && /* new array */ - mse->pattern && strchr(mse->pattern, '_') /* degraded */) -- alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL); -+ alert(EVENT_DEGRADED_ARRAY, NULL, 0, dev, NULL); - - if (st->utime == 0 && /* new array */ st->expected_spares > 0 && - sra->array.spare_disks < st->expected_spares) -- alert(EVENT_SPARES_MISSING, 0, dev, NULL); -+ alert(EVENT_SPARES_MISSING, NULL, 0, dev, NULL); - if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && - mse->percent >= 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - if (st->percent >= 0 && mse->percent >= 0 && - (mse->percent / increments) > (st->percent / increments)) { - if((mse->percent / increments) == 0) -- alert(EVENT_REBUILD_STARTED, 0, dev, NULL); -+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL); - else -- alert(EVENT_REBUILD, mse->percent, dev, NULL); -+ alert(EVENT_REBUILD, NULL, mse->percent, dev, NULL); - } - - if (mse->percent == RESYNC_NONE && st->percent >= 0) { -@@ -690,9 +778,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - snprintf(cnt, sizeof(cnt), - " mismatches found: %d (on raid level %d)", - sra->mismatch_cnt, sra->array.level); -- alert(EVENT_REBUILD_FINISHED, 0, dev, cnt); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, cnt); - } else -- alert(EVENT_REBUILD_FINISHED, 0, dev, NULL); -+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, NULL); - } - st->percent = mse->percent; - -@@ -746,14 +834,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - change = newstate ^ st->devstate[i]; - if (st->utime && change && !st->err && !new_array) { - if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_FAIL, 0, dev, dv); -+ alert(EVENT_FAIL, NULL, 0, dev, dv); - else if ((newstate & (1 << MD_DISK_FAULTY)) && - (disc.major || disc.minor) && - st->devid[i] == makedev(disc.major, - disc.minor)) -- alert(EVENT_FAIL_SPARE, 0, dev, dv); -+ alert(EVENT_FAIL_SPARE, NULL, 0, dev, dv); - else if ((newstate&change) & (1 << MD_DISK_SYNC)) -- alert(EVENT_SPARE_ACTIVE, 0, dev, dv); -+ alert(EVENT_SPARE_ACTIVE, NULL, 0, dev, dv); - } - st->devstate[i] = newstate; - st->devid[i] = makedev(disc.major, disc.minor); -@@ -777,7 +865,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, - - disappeared: - if (!st->err && !is_container) -- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL); -+ alert(EVENT_DEVICE_DISAPPEARED, NULL, 0, dev, NULL); - st->err++; - goto out; - } -@@ -836,7 +924,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - st->parent_devnm[0] = 0; - *statelist = st; - if (info.test) -- alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL); -+ alert(EVENT_TEST_MESSAGE, NULL, 0, st->devname, NULL); - new_found = 1; - } - return new_found; -@@ -1059,7 +1147,7 @@ static void try_spare_migration(struct state *statelist) - if (devid > 0 && - move_spare(from->devname, to->devname, - devid)) { -- alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname); -+ alert(EVENT_MOVE_SPARE, NULL, 0, to->devname, from->devname); - break; - } - } --- -2.38.1 - diff --git a/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch b/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch deleted file mode 100644 index 294f8af..0000000 --- a/SOURCES/0090-Add-helpers-to-determine-whether-directories-or-file.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:02 +0100 -Subject: [PATCH 090/125] Add helpers to determine whether directories or files - are soft links - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.h | 2 ++ - util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/mdadm.h b/mdadm.h -index 13f8b4cb..1674ce13 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1777,6 +1777,8 @@ extern void set_dlm_hooks(void); - #define MSEC_TO_NSEC(msec) ((msec) * 1000000) - #define USEC_TO_NSEC(usec) ((usec) * 1000) - extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); -+extern bool is_directory(const char *path); -+extern bool is_file(const char *path); - - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) -diff --git a/util.c b/util.c -index 8c7f3fd5..7fc881bf 100644 ---- a/util.c -+++ b/util.c -@@ -2401,3 +2401,48 @@ void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt) - } - } while (!wake_after_interrupt && errno == EINTR); - } -+ -+/* is_directory() - Checks if directory provided by path is indeed a regular directory. -+ * @path: directory path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a directory, false if not -+ */ -+bool is_directory(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISDIR(st.st_mode)) -+ return false; -+ -+ return true; -+} -+ -+/* -+ * is_file() - Checks if file provided by path is indeed a regular file. -+ * @path: file path to be checked -+ * -+ * Doesn't accept symlinks. -+ * -+ * Return: true if is a file, false if not -+ */ -+bool is_file(const char *path) -+{ -+ struct stat st; -+ -+ if (lstat(path, &st) != 0) { -+ pr_err("%s: %s\n", strerror(errno), path); -+ return false; -+ } -+ -+ if (!S_ISREG(st.st_mode)) -+ return false; -+ -+ return true; -+} --- -2.38.1 - diff --git a/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch b/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch deleted file mode 100644 index 84b4e63..0000000 --- a/SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:03 +0100 -Subject: [PATCH 091/125] Mdmonitor: Refactor write_autorebuild_pid() - -Add better error handling and check for symlinks when opening MDMON_DIR. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 55 ++++++++++++++++++++++++++++++++++++------------------- - 1 file changed, 36 insertions(+), 19 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 39598ba0..14a2dfe5 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -33,6 +33,7 @@ - #endif - - #define EVENT_NAME_MAX 32 -+#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - - struct state { - char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -@@ -126,7 +127,7 @@ static int check_udev_activity(void); - static void link_containers_with_subarrays(struct state *list); - static int make_daemon(char *pidfile); - static void try_spare_migration(struct state *statelist); --static void write_autorebuild_pid(void); -+static int write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, - char *mailaddr, char *alert_cmd, -@@ -234,7 +235,8 @@ int Monitor(struct mddev_dev *devlist, - } - - if (share) -- write_autorebuild_pid(); -+ if (write_autorebuild_pid() != 0) -+ return 1; - - if (devlist == NULL) { - mdlist = conf_get_ident(NULL); -@@ -440,29 +442,44 @@ static int check_one_sharer(int scan) - return 0; - } - --static void write_autorebuild_pid() -+/* -+ * write_autorebuild_pid() - Writes pid to autorebuild.pid file. -+ * -+ * Return: 0 on success, 1 on error -+ */ -+static int write_autorebuild_pid(void) - { -- char path[PATH_MAX]; -- int pid; -- FILE *fp = NULL; -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -+ FILE *fp; -+ int fd; - - if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) { -- pr_err("Can't create autorebuild.pid file\n"); -- } else { -- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ pr_err("%s: %s\n", strerror(errno), MDMON_DIR); -+ return 1; -+ } - -- if (fd >= 0) -- fp = fdopen(fd, "w"); -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ return 1; -+ } - -- if (!fp) -- pr_err("Can't create autorebuild.pid file\n"); -- else { -- pid = getpid(); -- fprintf(fp, "%d\n", pid); -- fclose(fp); -- } -+ fd = open(AUTOREBUILD_PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0700); -+ -+ if (fd < 0) { -+ pr_err("Error opening %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; - } -+ -+ fp = fdopen(fd, "w"); -+ -+ if (!fp) { -+ pr_err("Error opening fd for %s file.\n", AUTOREBUILD_PID_PATH); -+ return 1; -+ } -+ -+ fprintf(fp, "%d\n", getpid()); -+ -+ fclose(fp); -+ return 0; - } - - #define BASE_MESSAGE "%s event detected on md device %s" --- -2.38.1 - diff --git a/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch b/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch deleted file mode 100644 index f8708a1..0000000 --- a/SOURCES/0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 2 Feb 2023 12:27:04 +0100 -Subject: [PATCH 092/125] Mdmonitor: Refactor check_one_sharer() for better - error handling - -Also check if autorebuild.pid is a symlink, which we shouldn't accept. - -Signed-off-by: Mateusz Grzonka -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Monitor.c | 89 ++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 62 insertions(+), 27 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 14a2dfe5..44918184 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -32,6 +32,7 @@ - #include - #endif - -+#define TASK_COMM_LEN 16 - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - -@@ -224,7 +225,7 @@ int Monitor(struct mddev_dev *devlist, - info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ -- if (check_one_sharer(c->scan)) -+ if (check_one_sharer(c->scan) == 2) - return 1; - } - -@@ -406,39 +407,73 @@ static int make_daemon(char *pidfile) - return -1; - } - -+/* -+ * check_one_sharer() - Checks for other mdmon processes running. -+ * -+ * Return: -+ * 0 - no other processes running, -+ * 1 - warning, -+ * 2 - error, or when scan mode is enabled, and one mdmon process already exists -+ */ - static int check_one_sharer(int scan) - { - int pid; -- FILE *comm_fp; -- FILE *fp; -+ FILE *fp, *comm_fp; - char comm_path[PATH_MAX]; -- char path[PATH_MAX]; -- char comm[20]; -- -- sprintf(path, "%s/autorebuild.pid", MDMON_DIR); -- fp = fopen(path, "r"); -- if (fp) { -- if (fscanf(fp, "%d", &pid) != 1) -- pid = -1; -- snprintf(comm_path, sizeof(comm_path), -- "/proc/%d/comm", pid); -- comm_fp = fopen(comm_path, "r"); -- if (comm_fp) { -- if (fscanf(comm_fp, "%19s", comm) && -- strncmp(basename(comm), Name, strlen(Name)) == 0) { -- if (scan) { -- pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); -- fclose(comm_fp); -- fclose(fp); -- return 1; -- } else { -- pr_err("Warning: One autorebuild process already running.\n"); -- } -- } -+ char comm[TASK_COMM_LEN]; -+ -+ if (!is_directory(MDMON_DIR)) { -+ pr_err("%s is not a regular directory.\n", MDMON_DIR); -+ return 2; -+ } -+ -+ if (access(AUTOREBUILD_PID_PATH, F_OK) != 0) -+ return 0; -+ -+ if (!is_file(AUTOREBUILD_PID_PATH)) { -+ pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH); -+ return 2; -+ } -+ -+ fp = fopen(AUTOREBUILD_PID_PATH, "r"); -+ if (!fp) { -+ pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH); -+ return 2; -+ } -+ -+ if (fscanf(fp, "%d", &pid) != 1) { -+ pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH); -+ fclose(fp); -+ return 2; -+ } -+ -+ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid); -+ -+ comm_fp = fopen(comm_path, "r"); -+ if (!comm_fp) { -+ dprintf("Warning: Cannot open %s, continuing\n", comm_path); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (fscanf(comm_fp, "%15s", comm) == 0) { -+ dprintf("Warning: Cannot read comm from %s, continuing\n", comm_path); -+ fclose(comm_fp); -+ fclose(fp); -+ return 1; -+ } -+ -+ if (strncmp(basename(comm), Name, strlen(Name)) == 0) { -+ if (scan) { -+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); - fclose(comm_fp); -+ fclose(fp); -+ return 2; - } -- fclose(fp); -+ pr_err("Warning: One autorebuild process already running.\n"); - } -+ fclose(comm_fp); -+ fclose(fp); - return 0; - } - --- -2.38.1 - diff --git a/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch b/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch deleted file mode 100644 index dee708a..0000000 --- a/SOURCES/0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Sat, 4 Mar 2023 00:21:30 +0800 -Subject: [PATCH 093/125] util.c: reorder code lines in parse_layout_faulty() - -Resort the code lines in parse_layout_faulty() to make it more -comfortable, no logic change. - -Signed-off-by: Coly Li -Reviewed-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - util.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/util.c b/util.c -index 7fc881bf..b0b7aec4 100644 ---- a/util.c -+++ b/util.c -@@ -421,12 +421,15 @@ int parse_layout_10(char *layout) - - int parse_layout_faulty(char *layout) - { -+ int ln, mode; -+ char *m; -+ - if (!layout) - return -1; -+ - /* Parse the layout string for 'faulty' */ -- int ln = strcspn(layout, "0123456789"); -- char *m = xstrdup(layout); -- int mode; -+ ln = strcspn(layout, "0123456789"); -+ m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); - if (mode == UnSet) --- -2.38.1 - diff --git a/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch b/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch deleted file mode 100644 index 255d195..0000000 --- a/SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:31 +0800 -Subject: [PATCH 094/125] util.c: fix memleak in parse_layout_faulty() - -char *m is allocated by xstrdup but not free() before return, will cause -a memory leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - util.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util.c b/util.c -index b0b7aec4..9f1e1f7c 100644 ---- a/util.c -+++ b/util.c -@@ -432,6 +432,8 @@ int parse_layout_faulty(char *layout) - m = xstrdup(layout); - m[ln] = 0; - mode = map_name(faultylayout, m); -+ free(m); -+ - if (mode == UnSet) - return -1; - --- -2.38.1 - diff --git a/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch b/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch deleted file mode 100644 index f3d9846..0000000 --- a/SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch +++ /dev/null @@ -1,31 +0,0 @@ -From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:32 +0800 -Subject: [PATCH 095/125] Detail.c: fix memleak in Detail() - -char *sysdev = xstrdup() but not free() in for loop, will cause memory -leak - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Detail.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Detail.c b/Detail.c -index ce7a8445..4ef26460 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -303,6 +303,7 @@ int Detail(char *dev, struct context *c) - if (path) - printf("MD_DEVICE_%s_DEV=%s\n", - sysdev, path); -+ free(sysdev); - } - } - goto out; --- -2.38.1 - diff --git a/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch b/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch deleted file mode 100644 index 2561c51..0000000 --- a/SOURCES/0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:33 +0800 -Subject: [PATCH 096/125] isuper-intel.c: fix double free in load_imsm_mpb() - -In load_imsm_mpb() there is potential double free issue on super->buf. - -The first location to free super->buf is from get_super_block() <== -load_and_parse_mpb() <== load_imsm_mpb(): - 4514 if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE, - 4515 MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - 4516 pr_err("could not allocate migr_rec buffer\n"); - 4517 free(super->buf); - 4518 return 2; - 4519 } - -If the above error condition happens, super->buf is freed and value 2 -is returned to get_super_block() eventually. Then in the following code -block inside load_imsm_mpb(), - 5289 error: - 5290 if (!err) { - 5291 s->next = *super_list; - 5292 *super_list = s; - 5293 } else { - 5294 if (s) - 5295 free_imsm(s); - 5296 close_fd(&dfd); - 5297 } -at line 5295 when free_imsm() is called, super->buf is freed again from -the call chain free_imsm() <== __free_imsm(), in following code block, - 4651 if (super->buf) { - 4652 free(super->buf); - 4653 super->buf = NULL; - 4654 } - -This patch sets super->buf as NULL after line 4517 in load_imsm_mpb() -to avoid the potential double free(). - -(Coly Li helps to re-compose the commit log) - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/super-intel.c b/super-intel.c -index 89fac626..4a3da847 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -4515,6 +4515,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) - MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) { - pr_err("could not allocate migr_rec buffer\n"); - free(super->buf); -+ super->buf = NULL; - return 2; - } - super->clean_migration_record_by_mdmon = 0; --- -2.38.1 - diff --git a/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch b/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch deleted file mode 100644 index dbd5eeb..0000000 --- a/SOURCES/0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:34 +0800 -Subject: [PATCH 097/125] super-intel.c: fix memleak in - find_disk_attached_hba() - -If disk_path = diskfd_to_devpath(), we need free(disk_path) before -return, otherwise there will be a memory leak - -Signed-off-by: Wu Guanghao -Reviewed-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-intel.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 4a3da847..e155a8ae 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -713,12 +713,12 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) - - for (elem = list; elem; elem = elem->next) - if (path_attached_to_hba(disk_path, elem->path)) -- return elem; -+ break; - - if (disk_path != devname) - free(disk_path); - -- return NULL; -+ return elem; - } - - static int find_intel_hba_capability(int fd, struct intel_super *super, --- -2.38.1 - diff --git a/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch b/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch deleted file mode 100644 index d31b162..0000000 --- a/SOURCES/0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001 -From: Wu Guanghao -Date: Sat, 4 Mar 2023 00:21:35 +0800 -Subject: [PATCH 098/125] super-ddf.c: fix memleak in get_vd_num_of_subarray() - -sra = sysfs_read() should be free before return in -get_vd_num_of_subarray() - -Signed-off-by: Wu Guanghao -Acked-by: Mariusz Tkaczyk -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index 309812df..b86c6acd 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1592,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st) - sra = sysfs_read(-1, st->devnm, GET_VERSION); - if (!sra || sra->array.major_version != -1 || - sra->array.minor_version != -2 || -- !is_subarray(sra->text_version)) -+ !is_subarray(sra->text_version)) { -+ if (sra) -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - sub = strchr(sra->text_version + 1, '/'); - if (sub != NULL) - vcnum = strtoul(sub + 1, &end, 10); - if (sub == NULL || *sub == '\0' || *end != '\0' || -- vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) -+ vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) { -+ sysfs_free(sra); - return DDF_NOTFOUND; -+ } - - return vcnum; - } --- -2.38.1 - diff --git a/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch b/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch deleted file mode 100644 index dacf428..0000000 --- a/SOURCES/0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:29 -0700 -Subject: [PATCH 099/125] Create: goto abort_locked instead of return 1 in - error path - -The return 1 after the fstat_is_blkdev() check should be replaced -with an error return that goes through the error path to unlock -resources locked by this function. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index 953e7372..2e8203ec 100644 ---- a/Create.c -+++ b/Create.c -@@ -939,7 +939,7 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- return 1; -+ goto abort_locked; - inf->disk.major = major(rdev); - inf->disk.minor = minor(rdev); - } --- -2.38.1 - diff --git a/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch b/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch deleted file mode 100644 index a813d87..0000000 --- a/SOURCES/0100-Create-remove-safe_mode_delay-local-variable.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:30 -0700 -Subject: [PATCH 100/125] Create: remove safe_mode_delay local variable - -All .getinfo_super() call sets the info.safe_mode_delay variables -to a constant value, so no matter what the current state is -that function will always set it to the same value. - -Create() calls .getinfo_super() multiple times while creating the array. -The value is stored in a local variable for every disk in the loop -to add disks (so the last disc call takes precedence). The local -variable is then used in the call to sysfs_set_safemode(). - -This can be simplified by using info.safe_mode_delay directly. The info -variable had .getinfo_super() called on it early in the function so, by the -reasoning above, it will have the same value as the local variable which -can thus be removed. - -Doing this allows for factoring out code from Create() in a subsequent -patch. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 2e8203ec..8ded81dc 100644 ---- a/Create.c -+++ b/Create.c -@@ -137,7 +137,6 @@ int Create(struct supertype *st, char *mddev, - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -- unsigned long safe_mode_delay = 0; - char chosen_name[1024]; - struct map_ent *map = NULL; - unsigned long long newsize; -@@ -952,7 +951,6 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - st->ss->getinfo_super(st, inf, NULL); -- safe_mode_delay = inf->safe_mode_delay; - - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", -@@ -1065,7 +1063,7 @@ int Create(struct supertype *st, char *mddev, - "readonly"); - break; - } -- sysfs_set_safemode(&info, safe_mode_delay); -+ sysfs_set_safemode(&info, info.safe_mode_delay); - if (err) { - pr_err("failed to activate array.\n"); - ioctl(mdfd, STOP_ARRAY, NULL); --- -2.38.1 - diff --git a/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch b/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch deleted file mode 100644 index 6546497..0000000 --- a/SOURCES/0101-Create-Factor-out-add_disks-helpers.patch +++ /dev/null @@ -1,452 +0,0 @@ -From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:31 -0700 -Subject: [PATCH 101/125] Create: Factor out add_disks() helpers - -The Create function is massive with a very large number of variables. -Reading and understanding the function is almost impossible. To help -with this, factor out the two pass loop that adds the disks to the array. - -This moves about 160 lines into three new helper functions and removes -a bunch of local variables from the main Create function. The main new -helper function add_disks() does the two pass loop and calls into -add_disk_to_super() and update_metadata(). Factoring out the -latter two helpers also helps to reduce a ton of indentation. - -No functional changes intended. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 382 +++++++++++++++++++++++++++++++------------------------ - 1 file changed, 213 insertions(+), 169 deletions(-) - -diff --git a/Create.c b/Create.c -index 8ded81dc..6a044664 100644 ---- a/Create.c -+++ b/Create.c -@@ -91,6 +91,214 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, -+ struct supertype *st, struct mddev_dev *dv, -+ struct mdinfo *info, int have_container, int major_num) -+{ -+ dev_t rdev; -+ int fd; -+ -+ if (dv->disposition == 'j') { -+ info->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -+ info->disk.state = (1<disk.raid_disk < s->raiddisks) { -+ info->disk.state = (1<disk.state = 0; -+ } -+ -+ if (dv->writemostly == FlagSet) { -+ if (major_num == BITMAP_MAJOR_CLUSTERED) { -+ pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -+ return 1; -+ } else { -+ info->disk.state |= (1<failfast == FlagSet) -+ info->disk.state |= (1<ss->external && st->container_devnm[0]) -+ fd = open(dv->devname, O_RDWR); -+ else -+ fd = open(dv->devname, O_RDWR|O_EXCL); -+ -+ if (fd < 0) { -+ pr_err("failed to open %s after earlier success - aborting\n", -+ dv->devname); -+ return 1; -+ } -+ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -+ return 1; -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ if (fd >= 0) -+ remove_partitions(fd); -+ if (st->ss->add_to_super(st, &info->disk, fd, dv->devname, -+ dv->data_offset)) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ st->ss->getinfo_super(st, info, NULL); -+ -+ if (have_container && c->verbose > 0) -+ pr_err("Using %s for device %d\n", -+ map_dev(info->disk.major, info->disk.minor, 0), -+ info->disk.number); -+ -+ if (!have_container) { -+ /* getinfo_super might have lost these ... */ -+ info->disk.major = major(rdev); -+ info->disk.minor = minor(rdev); -+ } -+ -+ return 0; -+} -+ -+static int update_metadata(int mdfd, struct shape *s, struct supertype *st, -+ struct map_ent **map, struct mdinfo *info, -+ char *chosen_name) -+{ -+ struct mdinfo info_new; -+ struct map_ent *me = NULL; -+ -+ /* check to see if the uuid has changed due to these -+ * metadata changes, and if so update the member array -+ * and container uuid. Note ->write_init_super clears -+ * the subarray cursor such that ->getinfo_super once -+ * again returns container info. -+ */ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ if (st->ss->external && is_container(s->level) && -+ !same_uuid(info_new.uuid, info->uuid, 0)) { -+ map_update(map, fd2devnm(mdfd), -+ info_new.text_version, -+ info_new.uuid, chosen_name); -+ me = map_by_devnm(map, st->container_devnm); -+ } -+ -+ if (st->ss->write_init_super(st)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* -+ * Before activating the array, perform extra steps -+ * required to configure the internal write-intent -+ * bitmap. -+ */ -+ if (info_new.consistency_policy == CONSISTENCY_POLICY_BITMAP && -+ st->ss->set_bitmap && st->ss->set_bitmap(st, info)) { -+ st->ss->free_super(st); -+ return 1; -+ } -+ -+ /* update parent container uuid */ -+ if (me) { -+ char *path = xstrdup(me->path); -+ -+ st->ss->getinfo_super(st, &info_new, NULL); -+ map_update(map, st->container_devnm, info_new.text_version, -+ info_new.uuid, path); -+ free(path); -+ } -+ -+ flush_metadata_updates(st); -+ st->ss->free_super(st); -+ -+ return 0; -+} -+ -+static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, -+ struct context *c, struct supertype *st, -+ struct map_ent **map, struct mddev_dev *devlist, -+ int total_slots, int have_container, int insert_point, -+ int major_num, char *chosen_name) -+{ -+ struct mddev_dev *moved_disk = NULL; -+ int pass, raid_disk_num, dnum; -+ struct mddev_dev *dv; -+ struct mdinfo *infos; -+ int ret = 0; -+ -+ infos = xmalloc(sizeof(*infos) * total_slots); -+ enable_fds(total_slots); -+ for (pass = 1; pass <= 2; pass++) { -+ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -+ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -+ if (dnum >= total_slots) -+ abort(); -+ if (dnum == insert_point) { -+ raid_disk_num += 1; -+ moved_disk = dv; -+ continue; -+ } -+ if (strcasecmp(dv->devname, "missing") == 0) { -+ raid_disk_num += 1; -+ continue; -+ } -+ if (have_container) -+ moved_disk = NULL; -+ if (have_container && dnum < total_slots - 1) -+ /* repeatedly use the container */ -+ moved_disk = dv; -+ -+ switch(pass) { -+ case 1: -+ infos[dnum] = *info; -+ infos[dnum].disk.number = dnum; -+ infos[dnum].disk.raid_disk = raid_disk_num++; -+ -+ if (dv->disposition == 'j') -+ raid_disk_num--; -+ -+ ret = add_disk_to_super(mdfd, s, c, st, dv, -+ &infos[dnum], have_container, -+ major_num); -+ if (ret) -+ goto out; -+ -+ break; -+ case 2: -+ infos[dnum].errors = 0; -+ -+ ret = add_disk(mdfd, st, info, &infos[dnum]); -+ if (ret) { -+ pr_err("ADD_NEW_DISK for %s failed: %s\n", -+ dv->devname, strerror(errno)); -+ if (errno == EINVAL && -+ info->array.level == 0) { -+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -+ pr_err("Either upgrade, or use --layout=dangerous\n"); -+ } -+ goto out; -+ } -+ break; -+ } -+ if (!have_container && -+ dv == moved_disk && dnum != insert_point) break; -+ } -+ -+ if (pass == 1) { -+ ret = update_metadata(mdfd, s, st, map, info, -+ chosen_name); -+ if (ret) -+ goto out; -+ } -+ } -+ -+out: -+ free(infos); -+ return ret; -+} -+ - int Create(struct supertype *st, char *mddev, - char *name, int *uuid, - int subdevs, struct mddev_dev *devlist, -@@ -117,7 +325,7 @@ int Create(struct supertype *st, char *mddev, - unsigned long long minsize = 0, maxsize = 0; - char *mindisc = NULL; - char *maxdisc = NULL; -- int dnum, raid_disk_num; -+ int dnum; - struct mddev_dev *dv; - dev_t rdev; - int fail = 0, warn = 0; -@@ -126,14 +334,13 @@ int Create(struct supertype *st, char *mddev, - int missing_disks = 0; - int insert_point = subdevs * 2; /* where to insert a missing drive */ - int total_slots; -- int pass; - int rv; - int bitmap_fd; - int have_container = 0; - int container_fd = -1; - int need_mdmon = 0; - unsigned long long bitmapsize; -- struct mdinfo info, *infos; -+ struct mdinfo info; - int did_default = 0; - int do_default_layout = 0; - int do_default_chunk = 0; -@@ -869,174 +1076,11 @@ int Create(struct supertype *st, char *mddev, - } - } - -- infos = xmalloc(sizeof(*infos) * total_slots); -- enable_fds(total_slots); -- for (pass = 1; pass <= 2; pass++) { -- struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */ -- -- for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; -- dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { -- int fd; -- struct mdinfo *inf = &infos[dnum]; -- -- if (dnum >= total_slots) -- abort(); -- if (dnum == insert_point) { -- raid_disk_num += 1; -- moved_disk = dv; -- continue; -- } -- if (strcasecmp(dv->devname, "missing") == 0) { -- raid_disk_num += 1; -- continue; -- } -- if (have_container) -- moved_disk = NULL; -- if (have_container && dnum < info.array.raid_disks - 1) -- /* repeatedly use the container */ -- moved_disk = dv; -- -- switch(pass) { -- case 1: -- *inf = info; -- -- inf->disk.number = dnum; -- inf->disk.raid_disk = raid_disk_num++; -- -- if (dv->disposition == 'j') { -- inf->disk.raid_disk = MD_DISK_ROLE_JOURNAL; -- inf->disk.state = (1<disk.raid_disk < s->raiddisks) -- inf->disk.state = (1<disk.state = 0; -- -- if (dv->writemostly == FlagSet) { -- if (major_num == BITMAP_MAJOR_CLUSTERED) { -- pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname); -- goto abort_locked; -- } else -- inf->disk.state |= (1<failfast == FlagSet) -- inf->disk.state |= (1<ss->external && -- st->container_devnm[0]) -- fd = open(dv->devname, O_RDWR); -- else -- fd = open(dv->devname, O_RDWR|O_EXCL); -- -- if (fd < 0) { -- pr_err("failed to open %s after earlier success - aborting\n", -- dv->devname); -- goto abort_locked; -- } -- if (!fstat_is_blkdev(fd, dv->devname, &rdev)) -- goto abort_locked; -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- if (fd >= 0) -- remove_partitions(fd); -- if (st->ss->add_to_super(st, &inf->disk, -- fd, dv->devname, -- dv->data_offset)) { -- ioctl(mdfd, STOP_ARRAY, NULL); -- goto abort_locked; -- } -- st->ss->getinfo_super(st, inf, NULL); -- -- if (have_container && c->verbose > 0) -- pr_err("Using %s for device %d\n", -- map_dev(inf->disk.major, -- inf->disk.minor, -- 0), dnum); -- -- if (!have_container) { -- /* getinfo_super might have lost these ... */ -- inf->disk.major = major(rdev); -- inf->disk.minor = minor(rdev); -- } -- break; -- case 2: -- inf->errors = 0; -- -- rv = add_disk(mdfd, st, &info, inf); -- -- if (rv) { -- pr_err("ADD_NEW_DISK for %s failed: %s\n", -- dv->devname, strerror(errno)); -- if (errno == EINVAL && -- info.array.level == 0) { -- pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); -- pr_err("Either upgrade, or use --layout=dangerous\n"); -- } -- goto abort_locked; -- } -- break; -- } -- if (!have_container && -- dv == moved_disk && dnum != insert_point) break; -- } -- if (pass == 1) { -- struct mdinfo info_new; -- struct map_ent *me = NULL; -- -- /* check to see if the uuid has changed due to these -- * metadata changes, and if so update the member array -- * and container uuid. Note ->write_init_super clears -- * the subarray cursor such that ->getinfo_super once -- * again returns container info. -- */ -- st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && !is_container(s->level) && -- !same_uuid(info_new.uuid, info.uuid, 0)) { -- map_update(&map, fd2devnm(mdfd), -- info_new.text_version, -- info_new.uuid, chosen_name); -- me = map_by_devnm(&map, st->container_devnm); -- } -- -- if (st->ss->write_init_super(st)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- /* -- * Before activating the array, perform extra steps -- * required to configure the internal write-intent -- * bitmap. -- */ -- if (info_new.consistency_policy == -- CONSISTENCY_POLICY_BITMAP && -- st->ss->set_bitmap && -- st->ss->set_bitmap(st, &info)) { -- st->ss->free_super(st); -- goto abort_locked; -- } -- -- /* update parent container uuid */ -- if (me) { -- char *path = xstrdup(me->path); -- -- st->ss->getinfo_super(st, &info_new, NULL); -- map_update(&map, st->container_devnm, -- info_new.text_version, -- info_new.uuid, path); -- free(path); -- } -+ if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots, -+ have_container, insert_point, major_num, chosen_name)) -+ goto abort_locked; - -- flush_metadata_updates(st); -- st->ss->free_super(st); -- } -- } - map_unlock(&map); -- free(infos); - - if (is_container(s->level)) { - /* No need to start. But we should signal udev to --- -2.38.1 - diff --git a/SOURCES/0102-mdadm-Introduce-pr_info.patch b/SOURCES/0102-mdadm-Introduce-pr_info.patch deleted file mode 100644 index 4059e20..0000000 --- a/SOURCES/0102-mdadm-Introduce-pr_info.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:32 -0700 -Subject: [PATCH 102/125] mdadm: Introduce pr_info() - -Feedback was given to avoid informational pr_err() calls that print -to stderr, even though that's done all through out the code. - -Using printf() directly doesn't maintain the same format (an "mdadm" -prefix on every line. - -So introduce pr_info() which prints to stdout with the same format -and use it for a couple informational pr_err() calls in Create(). - -Future work can make this call used in more cases. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Acked-by: Paul Menzel -Signed-off-by: Jes Sorensen ---- - Create.c | 7 ++++--- - mdadm.h | 2 ++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/Create.c b/Create.c -index 6a044664..4acda30c 100644 ---- a/Create.c -+++ b/Create.c -@@ -984,11 +984,12 @@ int Create(struct supertype *st, char *mddev, - - mdi = sysfs_read(-1, devnm, GET_VERSION); - -- pr_err("Creating array inside %s container %s\n", -+ pr_info("Creating array inside %s container %s\n", - mdi?mdi->text_version:"managed", devnm); - sysfs_free(mdi); - } else -- pr_err("Defaulting to version %s metadata\n", info.text_version); -+ pr_info("Defaulting to version %s metadata\n", -+ info.text_version); - } - - map_update(&map, fd2devnm(mdfd), info.text_version, -@@ -1145,7 +1146,7 @@ int Create(struct supertype *st, char *mddev, - ioctl(mdfd, RESTART_ARRAY_RW, NULL); - } - if (c->verbose >= 0) -- pr_err("array %s started.\n", mddev); -+ pr_info("array %s started.\n", mddev); - if (st->ss->external && st->container_devnm[0]) { - if (need_mdmon) - start_mdmon(st->container_devnm); -diff --git a/mdadm.h b/mdadm.h -index 1674ce13..4336be4d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1854,6 +1854,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { - #endif - #define cont_err(fmt ...) fprintf(stderr, " " fmt) - -+#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args) -+ - void *xmalloc(size_t len); - void *xrealloc(void *ptr, size_t len); - void *xcalloc(size_t num, size_t size); --- -2.38.1 - diff --git a/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch b/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch deleted file mode 100644 index 2f39174..0000000 --- a/SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:33 -0700 -Subject: [PATCH 103/125] mdadm: Add --write-zeros option for Create - -Add the --write-zeros option for Create which will send a write zeros -request to all the disks before assembling the array. After zeroing -the array, the disks will be in a known clean state and the initial -sync may be skipped. - -Writing zeroes is best used when there is a hardware offload method -to zero the data. But even still, zeroing can take several minutes on -a large device. Because of this, all disks are zeroed in parallel using -their own forked process and a message is printed to the user. The main -process will proceed only after all the zeroing processes have completed -successfully. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - Create.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - ReadMe.c | 2 + - mdadm.c | 9 +++ - mdadm.h | 5 ++ - 4 files changed, 190 insertions(+), 2 deletions(-) - -diff --git a/Create.c b/Create.c -index 4acda30c..bbe9e13d 100644 ---- a/Create.c -+++ b/Create.c -@@ -26,6 +26,10 @@ - #include "md_u.h" - #include "md_p.h" - #include -+#include -+#include -+#include -+#include - - static int round_size_and_verify(unsigned long long *size, int chunk) - { -@@ -91,9 +95,149 @@ int default_layout(struct supertype *st, int level, int verbose) - return layout; - } - -+static pid_t write_zeroes_fork(int fd, struct shape *s, struct supertype *st, -+ struct mddev_dev *dv) -+ -+{ -+ const unsigned long long req_size = 1 << 30; -+ unsigned long long offset_bytes, size_bytes, sz; -+ sigset_t sigset; -+ int ret = 0; -+ pid_t pid; -+ -+ size_bytes = KIB_TO_BYTES(s->size); -+ -+ /* -+ * If size_bytes is zero, this is a zoned raid array where -+ * each disk is of a different size and uses its full -+ * disk. Thus zero the entire disk. -+ */ -+ if (!size_bytes && !get_dev_size(fd, dv->devname, &size_bytes)) -+ return -1; -+ -+ if (dv->data_offset != INVALID_SECTORS) -+ offset_bytes = SEC_TO_BYTES(dv->data_offset); -+ else -+ offset_bytes = SEC_TO_BYTES(st->data_offset); -+ -+ pr_info("zeroing data from %lld to %lld on: %s\n", -+ offset_bytes, size_bytes, dv->devname); -+ -+ pid = fork(); -+ if (pid < 0) { -+ pr_err("Could not fork to zero disks: %s\n", strerror(errno)); -+ return pid; -+ } else if (pid != 0) { -+ return pid; -+ } -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_UNBLOCK, &sigset, NULL); -+ -+ while (size_bytes) { -+ /* -+ * Split requests to the kernel into 1GB chunks seeing the -+ * fallocate() call is not interruptible and blocking a -+ * ctrl-c for several minutes is not desirable. -+ * -+ * 1GB is chosen as a compromise: the user may still have -+ * to wait several seconds if they ctrl-c on devices that -+ * zero slowly, but will reduce the number of requests -+ * required and thus the overhead on devices that perform -+ * better. -+ */ -+ sz = size_bytes; -+ if (sz >= req_size) -+ sz = req_size; -+ -+ if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE, -+ offset_bytes, sz)) { -+ pr_err("zeroing %s failed: %s\n", dv->devname, -+ strerror(errno)); -+ ret = 1; -+ break; -+ } -+ -+ offset_bytes += sz; -+ size_bytes -= sz; -+ } -+ -+ exit(ret); -+} -+ -+static int wait_for_zero_forks(int *zero_pids, int count) -+{ -+ int wstatus, ret = 0, i, sfd, wait_count = 0; -+ struct signalfd_siginfo fdsi; -+ bool interrupted = false; -+ sigset_t sigset; -+ ssize_t s; -+ -+ for (i = 0; i < count; i++) -+ if (zero_pids[i]) -+ wait_count++; -+ if (!wait_count) -+ return 0; -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigaddset(&sigset, SIGCHLD); -+ sigprocmask(SIG_BLOCK, &sigset, NULL); -+ -+ sfd = signalfd(-1, &sigset, 0); -+ if (sfd < 0) { -+ pr_err("Unable to create signalfd: %s\n", strerror(errno)); -+ return 1; -+ } -+ -+ while (1) { -+ s = read(sfd, &fdsi, sizeof(fdsi)); -+ if (s != sizeof(fdsi)) { -+ pr_err("Invalid signalfd read: %s\n", strerror(errno)); -+ close(sfd); -+ return 1; -+ } -+ -+ if (fdsi.ssi_signo == SIGINT) { -+ printf("\n"); -+ pr_info("Interrupting zeroing processes, please wait...\n"); -+ interrupted = true; -+ } else if (fdsi.ssi_signo == SIGCHLD) { -+ if (!--wait_count) -+ break; -+ } -+ } -+ -+ close(sfd); -+ -+ for (i = 0; i < count; i++) { -+ if (!zero_pids[i]) -+ continue; -+ -+ waitpid(zero_pids[i], &wstatus, 0); -+ zero_pids[i] = 0; -+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus)) -+ ret = 1; -+ } -+ -+ if (interrupted) { -+ pr_err("zeroing interrupted!\n"); -+ return 1; -+ } -+ -+ if (ret) -+ pr_err("zeroing failed!\n"); -+ else -+ pr_info("zeroing finished\n"); -+ -+ return ret; -+} -+ - static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - struct supertype *st, struct mddev_dev *dv, -- struct mdinfo *info, int have_container, int major_num) -+ struct mdinfo *info, int have_container, int major_num, -+ int *zero_pid) - { - dev_t rdev; - int fd; -@@ -148,6 +292,14 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c, - } - st->ss->getinfo_super(st, info, NULL); - -+ if (fd >= 0 && s->write_zeroes) { -+ *zero_pid = write_zeroes_fork(fd, s, st, dv); -+ if (*zero_pid <= 0) { -+ ioctl(mdfd, STOP_ARRAY, NULL); -+ return 1; -+ } -+ } -+ - if (have_container && c->verbose > 0) - pr_err("Using %s for device %d\n", - map_dev(info->disk.major, info->disk.minor, 0), -@@ -224,10 +376,23 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - { - struct mddev_dev *moved_disk = NULL; - int pass, raid_disk_num, dnum; -+ int zero_pids[total_slots]; - struct mddev_dev *dv; - struct mdinfo *infos; -+ sigset_t sigset, orig_sigset; - int ret = 0; - -+ /* -+ * Block SIGINT so the main thread will always wait for the -+ * zeroing processes when being interrupted. Otherwise the -+ * zeroing processes will finish their work in the background -+ * keeping the disk busy. -+ */ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGINT); -+ sigprocmask(SIG_BLOCK, &sigset, &orig_sigset); -+ memset(zero_pids, 0, sizeof(zero_pids)); -+ - infos = xmalloc(sizeof(*infos) * total_slots); - enable_fds(total_slots); - for (pass = 1; pass <= 2; pass++) { -@@ -261,7 +426,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - - ret = add_disk_to_super(mdfd, s, c, st, dv, - &infos[dnum], have_container, -- major_num); -+ major_num, &zero_pids[dnum]); - if (ret) - goto out; - -@@ -287,6 +452,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - if (pass == 1) { -+ ret = wait_for_zero_forks(zero_pids, total_slots); -+ if (ret) -+ goto out; -+ - ret = update_metadata(mdfd, s, st, map, info, - chosen_name); - if (ret) -@@ -295,7 +464,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s, - } - - out: -+ if (ret) -+ wait_for_zero_forks(zero_pids, total_slots); - free(infos); -+ sigprocmask(SIG_SETMASK, &orig_sigset, NULL); - return ret; - } - -diff --git a/ReadMe.c b/ReadMe.c -index bd8d50d2..db251ed2 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -138,6 +138,7 @@ struct option long_options[] = { - {"size", 1, 0, 'z'}, - {"auto", 1, 0, Auto}, /* also for --assemble */ - {"assume-clean",0,0, AssumeClean }, -+ {"write-zeroes",0,0, WriteZeroes }, - {"metadata", 1, 0, 'e'}, /* superblock format */ - {"bitmap", 1, 0, Bitmap}, - {"bitmap-chunk", 1, 0, BitmapChunk}, -@@ -390,6 +391,7 @@ char Help_create[] = - " --write-journal= : Specify journal device for RAID-4/5/6 array\n" - " --consistency-policy= : Specify the policy that determines how the array\n" - " -k : maintains consistency in case of unexpected shutdown.\n" -+" --write-zeroes : Write zeroes to the disks before creating. This will bypass initial sync.\n" - "\n" - ; - -diff --git a/mdadm.c b/mdadm.c -index 57e8e6fa..4685ad6b 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -590,6 +590,10 @@ int main(int argc, char *argv[]) - s.assume_clean = 1; - continue; - -+ case O(CREATE, WriteZeroes): -+ s.write_zeroes = 1; -+ continue; -+ - case O(GROW,'n'): - case O(CREATE,'n'): - case O(BUILD,'n'): /* number of raid disks */ -@@ -1251,6 +1255,11 @@ int main(int argc, char *argv[]) - } - } - -+ if (s.write_zeroes && !s.assume_clean) { -+ pr_info("Disk zeroing requested, setting --assume-clean to skip resync\n"); -+ s.assume_clean = 1; -+ } -+ - if (!mode && devs_found) { - mode = MISC; - devmode = 'Q'; -diff --git a/mdadm.h b/mdadm.h -index 4336be4d..b9127f9a 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -275,6 +275,9 @@ static inline void __put_unaligned32(__u32 val, void *p) - - #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -+#define KIB_TO_BYTES(x) ((x) << 10) -+#define SEC_TO_BYTES(x) ((x) << 9) -+ - extern const char Name[]; - - struct md_bb_entry { -@@ -435,6 +438,7 @@ extern char Version[], Usage[], Help[], OptionHelp[], - */ - enum special_options { - AssumeClean = 300, -+ WriteZeroes, - BitmapChunk, - WriteBehind, - ReAdd, -@@ -640,6 +644,7 @@ struct shape { - int bitmap_chunk; - char *bitmap_file; - int assume_clean; -+ bool write_zeroes; - int write_behind; - unsigned long long size; - unsigned long long data_offset; --- -2.38.1 - diff --git a/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch b/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch deleted file mode 100644 index 441aef2..0000000 --- a/SOURCES/0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c918cf2af993b55bca9f396c79713e54d3f8b6fb Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:34 -0700 -Subject: [PATCH 104/125] tests/00raid5-zero: Introduce test to exercise - --write-zeros. - -Attempt to create a raid5 array with --write-zeros. If it is successful -check the array to ensure it is in sync. - -If it is unsuccessful and an unsupported error is printed, skip the -test. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - tests/00raid5-zero | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - create mode 100644 tests/00raid5-zero - -diff --git a/tests/00raid5-zero b/tests/00raid5-zero -new file mode 100644 -index 00000000..7d0f05a1 ---- /dev/null -+++ b/tests/00raid5-zero -@@ -0,0 +1,12 @@ -+ -+if mdadm -CfR $md0 -l 5 -n3 $dev0 $dev1 $dev2 --write-zeroes ; then -+ check nosync -+ echo check > /sys/block/md0/md/sync_action; -+ check wait -+elif grep "zeroing [^ ]* failed: Operation not supported" \ -+ $targetdir/stderr; then -+ echo "write-zeros not supported, skipping" -+else -+ echo >&2 "ERROR: mdadm return failure without not supported message" -+ exit 1 -+fi --- -2.38.1 - diff --git a/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch b/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch deleted file mode 100644 index 16a0e3f..0000000 --- a/SOURCES/0105-manpage-Add-write-zeroes-option-to-manpage.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001 -From: Logan Gunthorpe -Date: Wed, 1 Mar 2023 13:41:35 -0700 -Subject: [PATCH 105/125] manpage: Add --write-zeroes option to manpage - -Document the new --write-zeroes option in the manpage. - -Signed-off-by: Logan Gunthorpe -Acked-by: Kinga Tanska -Reviewed-by: Xiao Ni -Reviewed-by: Chaitanya Kulkarni -Acked-by: Coly Li -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 64f71ed1..6f0f6c13 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -837,6 +837,22 @@ array is resynced at creation. From Linux version 3.0, - .B \-\-assume\-clean - can be used with that command to avoid the automatic resync. - -+.TP -+.BR \-\-write-zeroes -+When creating an array, send write zeroes requests to all the block -+devices. This should zero the data area on all disks such that the -+initial sync is not necessary and, if successfull, will behave -+as if -+.B \-\-assume\-clean -+was specified. -+.IP -+This is intended for use with devices that have hardware offload for -+zeroing, but despite this zeroing can still take several minutes for -+large disks. Thus a message is printed before and after zeroing and -+each disk is zeroed in parallel with the others. -+.IP -+This is only meaningful with --create. -+ - .TP - .BR \-\-backup\-file= - This is needed when -@@ -1370,7 +1386,7 @@ and - .B layout\-alternate - options are for RAID0 arrays with non-uniform devices size that were in - use before Linux 5.4. If the array was being used with Linux 3.13 or --earlier, then to assemble the array on a new kernel, -+earlier, then to assemble the array on a new kernel, - .B \-\-update=layout\-original - must be given. If the array was created and used with a kernel from Linux 3.14 to - Linux 5.3, then --- -2.38.1 - diff --git a/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch b/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch deleted file mode 100644 index 13765d8..0000000 --- a/SOURCES/0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Wed, 18 Jan 2023 00:32:36 -0800 -Subject: [PATCH 106/125] Define alignof using _Alignof when using C11 or newer - -WG14 N2350 made very clear that it is an UB having type definitions -within "offsetof" [1]. This patch enhances the implementation of macro -alignof_slot to use builtin "_Alignof" to avoid undefined behavior on -when using std=c11 or newer - -clang 16+ has started to flag this [2] - -Fixes build when using -std >= gnu11 and using clang16+ - -Older compilers gcc < 4.9 or clang < 8 has buggy _Alignof even though it -may support C11, exclude those compilers too - -[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm -[2] https://reviews.llvm.org/D133574 - -Upstream-Status: Pending -Signed-off-by: Khem Raj -Signed-off-by: Jes Sorensen ---- - sha1.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/sha1.c b/sha1.c -index 89b32f46..1e4ad5d9 100644 ---- a/sha1.c -+++ b/sha1.c -@@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) - if (len >= 64) - { - #if !_STRING_ARCH_unaligned --# define alignof(type) offsetof (struct { char c; type x; }, x) -+/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 -+ . -+ clang versions < 8.0.0 have the same bug. */ -+# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ -+ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ -+ && !defined __clang__) \ -+ || (defined __clang__ && __clang_major__ < 8)) -+# define alignof(type) offsetof (struct { char c; type x; }, x) -+# else -+# define alignof(type) _Alignof(type) -+# endif - # define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) --- -2.38.1 - diff --git a/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch b/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch deleted file mode 100644 index 20f2755..0000000 --- a/SOURCES/0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch +++ /dev/null @@ -1,41 +0,0 @@ -From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 107/125] Use existence of /etc/initrd-release to detect - initrd. - -Since v183, systemd has used the existence of /etc/initrd-release to -detect if it is running in an initrd, rather than looking at the magic -number of the root filesystem's device. It is time for mdadm to do the -same. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - util.c | 10 +--------- - 1 file changed, 1 insertion(+), 9 deletions(-) - -diff --git a/util.c b/util.c -index 9f1e1f7c..509fb43e 100644 ---- a/util.c -+++ b/util.c -@@ -2227,15 +2227,7 @@ int continue_via_systemd(char *devnm, char *service_name) - - int in_initrd(void) - { -- /* This is based on similar function in systemd. */ -- struct statfs s; -- /* statfs.f_type is signed long on s390x and MIPS, causing all -- sorts of sign extension problems with RAMFS_MAGIC being -- defined as 0x858458f6 */ -- return statfs("/", &s) >= 0 && -- ((unsigned long)s.f_type == TMPFS_MAGIC || -- ((unsigned long)s.f_type & 0xFFFFFFFFUL) == -- ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL)); -+ return access("/etc/initrd-release", F_OK) >= 0; - } - - void reopen_mddev(int mdfd) --- -2.38.1 - diff --git a/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch b/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch deleted file mode 100644 index 0926a9d..0000000 --- a/SOURCES/0108-mdmon-don-t-test-both-all-and-container_name.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 108/125] mdmon: don't test both 'all' and 'container_name'. - -If 'all' is not set, then container_name must be NULL, as nothing else -can set it. So simplify the test to ignore container_name. -This makes the purpose of the code more obvious. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdmon.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index 60ba3182..f8fd2f0f 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -352,7 +352,6 @@ int main(int argc, char *argv[]) - } - } - -- - if (in_initrd()) { - /* - * set first char of argv[0] to @. This is used by -@@ -362,12 +361,10 @@ int main(int argc, char *argv[]) - argv[0][0] = '@'; - } - -- if (all == 0 && container_name == NULL) { -- if (argv[optind]) { -- container_name = get_md_name(argv[optind]); -- if (!container_name) -- return 1; -- } -+ if (!all && argv[optind]) { -+ container_name = get_md_name(argv[optind]); -+ if (!container_name) -+ return 1; - } - - if (container_name == NULL || argc - optind > 1) --- -2.38.1 - diff --git a/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch b/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch deleted file mode 100644 index b2822c8..0000000 --- a/SOURCES/0109-mdmon-change-systemd-unit-file-to-use-foreground.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 109/125] mdmon: change systemd unit file to use --foreground - -There is no value in mdmon forking when it is running under systemd - -systemd can still track it anyway. - -So add --foreground option, and remove "Type=forking". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index cb6482d9..bba9b0eb 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -20,8 +20,7 @@ Environment=IMSM_NO_PLATFORM=1 - # 'takeover'. As the '--offroot --takeover' don't hurt when - # not necessary, are are useful with root-on-md in dracut, - # have them always present. --ExecStart=BINDIR/mdmon --offroot --takeover %I --Type=forking -+ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # Don't set the PIDFile. It isn't necessary (systemd can work - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. --- -2.38.1 - diff --git a/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch b/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch deleted file mode 100644 index d1cde02..0000000 --- a/SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 110/125] mdmon: Remove need for KillMode=none - -mdmon needs to keep running during the switchroot out of (at boot) and -then back into (at shutdown) the initrd. It runs until a new mdmon -takes over. - -Killmode=none is used to achieve this, with the help of --offroot which -sets argv[0][0] to '@' which systemd understands. - -This is needed because mdmon is currently run in system-mdmon.slice -which conflicts with shutdown.target so without Killmode=none mdmon -would get killed early in shutdown when system.mdmon.slice is removed. - -As described in systemd.service(5), this conflict with shutdown can be -resolved by explicitly requesting system.slice, which is a natural -counterpart to DefaultDependencies=no. - -So add that, and also add IgnoreOnIsolate=true to avoid another possible -source of an early death. With these we no longer need KillMode=none -which the systemd developers have marked as "deprecated". - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - systemd/mdmon@.service | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index bba9b0eb..303ad05c 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -10,6 +10,9 @@ Description=MD Metadata Monitor on /dev/%I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -+# Allow mdmon to keep running after switchroot, until a new -+# instance is started. -+IgnoreOnIsolate=true - - [Service] - # mdmon should never complain due to lack of a platform, -@@ -25,4 +28,6 @@ ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I - # it out) and systemd will remove it when transitioning from - # initramfs to rootfs. - #PIDFile=/run/mdadm/%I.pid --KillMode=none -+# The default slice is system-mdmon.slice which Conflicts -+# with shutdown, causing mdmon to exit early. So use system.slice. -+Slice=system.slice --- -2.38.1 - diff --git a/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch b/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch deleted file mode 100644 index 96fedb3..0000000 --- a/SOURCES/0111-mdmon-Improve-switchroot-interactions.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 13 Mar 2023 14:42:58 +1100 -Subject: [PATCH 111/125] mdmon: Improve switchroot interactions. - -We need a new mdmon@mdfoo instance to run in the root filesystem after -switch root, as /sys and /dev are removed from the initrd. - -systemd will not start a new unit with the same name running while the -old unit is still active, and we want the two mdmon processes to overlap -in time to avoid any risk of deadlock, which can happen when a write is -attempted with no mdmon running. - -So we need a different unit name in the initrd than in the root. Apart -from the name, everything else should be the same. - -This is easily achieved using a different instance name as the -mdmon@.service unit file already supports multiple instances (for -different arrays). - -So start "mdmon@mdfoo.service" from root, but -"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which -circumstance is the case by looking for /etc/initrd-release. -continue_from_systemd() is enhanced so that the "initrd-" prefix can be -requested. - -Teach mdmon that a container name like "initrd/foo" should be treated -just like "foo". Note that systemd passes the instance name -"initrd-foo" as "initrd/foo". - -We don't need a similar mechanism at shutdown because dracut runs -"mdmon --takeover --all" when appropriate. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - Grow.c | 4 ++-- - mdadm.h | 2 +- - mdmon.c | 7 ++++++- - systemd/mdmon@.service | 2 +- - udev-md-raid-arrays.rules | 3 ++- - util.c | 7 ++++--- - 6 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/Grow.c b/Grow.c -index bb5fe45c..06001f2d 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -3516,7 +3516,7 @@ started: - - if (!forked) - if (continue_via_systemd(container ?: sra->sys_name, -- GROW_SERVICE)) { -+ GROW_SERVICE, NULL)) { - free(fdlist); - free(offsets); - sysfs_free(sra); -@@ -3714,7 +3714,7 @@ int reshape_container(char *container, char *devname, - ping_monitor(container); - - if (!forked && !freeze_reshape) -- if (continue_via_systemd(container, GROW_SERVICE)) -+ if (continue_via_systemd(container, GROW_SERVICE, NULL)) - return 0; - - switch (forked ? 0 : fork()) { -diff --git a/mdadm.h b/mdadm.h -index b9127f9a..1e518276 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1608,7 +1608,7 @@ extern int same_dev(char *one, char *two); - extern int compare_paths (char* path1,char* path2); - extern void enable_fds(int devices); - extern void manage_fork_fds(int close_all); --extern int continue_via_systemd(char *devnm, char *service_name); -+extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); - -diff --git a/mdmon.c b/mdmon.c -index f8fd2f0f..096b4d76 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -362,7 +362,12 @@ int main(int argc, char *argv[]) - } - - if (!all && argv[optind]) { -- container_name = get_md_name(argv[optind]); -+ static const char prefix[] = "initrd/"; -+ container_name = argv[optind]; -+ if (strncmp(container_name, prefix, -+ sizeof(prefix) - 1) == 0) -+ container_name += sizeof(prefix)-1; -+ container_name = get_md_name(container_name); - if (!container_name) - return 1; - } -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 303ad05c..23a375f6 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -6,7 +6,7 @@ - # (at your option) any later version. - - [Unit] --Description=MD Metadata Monitor on /dev/%I -+Description=MD Metadata Monitor on %I - DefaultDependencies=no - Before=initrd-switch-root.target - Documentation=man:mdmon(8) -diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules -index 2967ace1..4e64b249 100644 ---- a/udev-md-raid-arrays.rules -+++ b/udev-md-raid-arrays.rules -@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" - - # Tell systemd to run mdmon for our container, if we need it. - ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" --ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" -+ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service" -+ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" - ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" - - LABEL="md_end" -diff --git a/util.c b/util.c -index 509fb43e..d70ca43b 100644 ---- a/util.c -+++ b/util.c -@@ -1916,6 +1916,7 @@ int start_mdmon(char *devnm) - int len; - pid_t pid; - int status; -+ char *prefix = in_initrd() ? "initrd-" : ""; - char pathbuf[1024]; - char *paths[4] = { - pathbuf, -@@ -1926,7 +1927,7 @@ int start_mdmon(char *devnm) - - if (check_env("MDADM_NO_MDMON")) - return 0; -- if (continue_via_systemd(devnm, MDMON_SERVICE)) -+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix)) - return 0; - - /* That failed, try running mdmon directly */ -@@ -2197,7 +2198,7 @@ void manage_fork_fds(int close_all) - * 1- if systemd service has been started - * 0- otherwise - */ --int continue_via_systemd(char *devnm, char *service_name) -+int continue_via_systemd(char *devnm, char *service_name, char *prefix) - { - int pid, status; - char pathbuf[1024]; -@@ -2209,7 +2210,7 @@ int continue_via_systemd(char *devnm, char *service_name) - case 0: - manage_fork_fds(1); - snprintf(pathbuf, sizeof(pathbuf), -- "%s@%s.service", service_name, devnm); -+ "%s@%s%s.service", service_name, prefix ?: "", devnm); - status = execl("/usr/bin/systemctl", "systemctl", "restart", - pathbuf, NULL); - status = execl("/bin/systemctl", "systemctl", "restart", --- -2.38.1 - diff --git a/SOURCES/0112-mdopen-always-try-create_named_array.patch b/SOURCES/0112-mdopen-always-try-create_named_array.patch deleted file mode 100644 index 6d857ad..0000000 --- a/SOURCES/0112-mdopen-always-try-create_named_array.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Tue, 14 Mar 2023 11:06:25 +1100 -Subject: [PATCH 112/125] mdopen: always try create_named_array() - -mdopen() will use create_named_array() to ask the kernel to create the -given md array, but only if it is given a number or name. -If it is NOT given a name and is required to choose one itself using -find_free_devnm() it does NOT use create_named_array(). - -On kernels with CONFIG_BLOCK_LEGACY_AUTOLOAD not set, this can result in -failure to assemble an array. This can particularly seen when the -"name" of the array begins with a host name different to the name of the -host running the command. - -So add the missing call to create_named_array(). - -Link: https://bugzilla.kernel.org/show_bug.cgi?id=217074 -Signed-off-by: NeilBrown -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdopen.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/mdopen.c b/mdopen.c -index d18c9319..810f79a3 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - } - if (block_udev) - udev_block(devnm); -+ create_named_array(devnm); - } - - sprintf(devname, "/dev/%s", devnm); --- -2.38.1 - diff --git a/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch b/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch deleted file mode 100644 index 1a510f1..0000000 --- a/SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001 -From: NeilBrown -Date: Mon, 20 Mar 2023 14:43:54 +1100 -Subject: [PATCH 113/125] Improvements for IMSM_NO_PLATFORM testing. - -Factor out IMSM_NO_PLATFORM testing into a single function that caches -the result. - -Allow mdmon to explicitly set the result to "1" so that we don't need -the ENV var in the unit file - -Check if the kernel command line contains "mdadm.imsm.test=1" and in -that case assert NO_PLATFORM. This simplifies testing in a virtual -machine. - -Signed-off-by: NeilBrown -Signed-off-by: Jes Sorensen ---- - mdadm.8.in | 5 +++++ - mdadm.h | 2 ++ - mdmon.c | 6 ++++++ - super-intel.c | 45 +++++++++++++++++++++++++++++++++++++++--- - systemd/mdmon@.service | 3 --- - 5 files changed, 55 insertions(+), 6 deletions(-) - -diff --git a/mdadm.8.in b/mdadm.8.in -index 6f0f6c13..b7159509 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -3197,6 +3197,11 @@ environment. This can be useful for testing or for disaster - recovery. You should be aware that interoperability may be - compromised by setting this value. - -+These change can also be suppressed by adding -+.B mdadm.imsm.test=1 -+to the kernel command line. This makes it easy to test IMSM -+code in a virtual machine that doesn't have IMSM virtual hardware. -+ - .TP - .B MDADM_GROW_ALLOW_OLD - If an array is stopped while it is performing a reshape and that -diff --git a/mdadm.h b/mdadm.h -index 1e518276..0d995445 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1263,6 +1263,8 @@ extern struct superswitch super0, super1; - extern struct superswitch super_imsm, super_ddf; - extern struct superswitch mbr, gpt; - -+void imsm_set_no_platform(int v); -+ - struct metadata_update { - int len; - char *buf; -diff --git a/mdmon.c b/mdmon.c -index 096b4d76..cef5bbc8 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -318,6 +318,12 @@ int main(int argc, char *argv[]) - {NULL, 0, NULL, 0} - }; - -+ /* -+ * mdmon should never complain due to lack of a platform, -+ * that is mdadm's job if at all. -+ */ -+ imsm_set_no_platform(1); -+ - while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) { - switch (opt) { - case 'a': -diff --git a/super-intel.c b/super-intel.c -index e155a8ae..a5c86cb2 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -20,6 +20,7 @@ - #define HAVE_STDINT_H 1 - #include "mdadm.h" - #include "mdmon.h" -+#include "dlink.h" - #include "sha1.h" - #include "platform-intel.h" - #include -@@ -629,6 +630,44 @@ static const char *_sys_dev_type[] = { - [SYS_DEV_VMD] = "VMD" - }; - -+static int no_platform = -1; -+ -+static int check_no_platform(void) -+{ -+ static const char search[] = "mdadm.imsm.test=1"; -+ FILE *fp; -+ -+ if (no_platform >= 0) -+ return no_platform; -+ -+ if (check_env("IMSM_NO_PLATFORM")) { -+ no_platform = 1; -+ return 1; -+ } -+ fp = fopen("/proc/cmdline", "r"); -+ if (fp) { -+ char *l = conf_line(fp); -+ char *w = l; -+ -+ do { -+ if (strcmp(w, search) == 0) -+ no_platform = 1; -+ w = dl_next(w); -+ } while (w != l); -+ free_line(l); -+ fclose(fp); -+ if (no_platform >= 0) -+ return no_platform; -+ } -+ no_platform = 0; -+ return 0; -+} -+ -+void imsm_set_no_platform(int v) -+{ -+ no_platform = v; -+} -+ - const char *get_sys_dev_type(enum sys_dev_type type) - { - if (type >= SYS_DEV_MAX) -@@ -2699,7 +2738,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - int result=1; - - if (enumerate_only) { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - list = find_intel_devices(); - if (!list) -@@ -4722,7 +4761,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de - devname); - return 1; - } -- if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) { -+ if (!is_fd_valid(fd) || check_no_platform()) { - super->orom = NULL; - super->hba = NULL; - return 0; -@@ -10697,7 +10736,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks, - ******************************************************************************/ - int validate_container_imsm(struct mdinfo *info) - { -- if (check_env("IMSM_NO_PLATFORM")) -+ if (check_no_platform()) - return 0; - - struct sys_dev *idev; -diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service -index 23a375f6..020cc7e1 100644 ---- a/systemd/mdmon@.service -+++ b/systemd/mdmon@.service -@@ -15,9 +15,6 @@ Documentation=man:mdmon(8) - IgnoreOnIsolate=true - - [Service] --# mdmon should never complain due to lack of a platform, --# that is mdadm's job if at all. --Environment=IMSM_NO_PLATFORM=1 - # The mdmon starting in the initramfs (with dracut at least) - # cannot see sysfs after root is mounted, so we will have to - # 'takeover'. As the '--offroot --takeover' don't hurt when --- -2.38.1 - diff --git a/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch b/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch deleted file mode 100644 index 4db3370..0000000 --- a/SOURCES/0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9b6e3b43381245cb128ad98bf117a565ce5defe5 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:13:18 +0100 -Subject: [PATCH 114/125] Revert "Revert "mdadm/systemd: remove KillMode=none - from service file"" - -This reverts commit 28a083955c6f58f8e582734c8c82aff909a7d461. - -Resolved by commit 723d1df4946e ("mdmon: Improve switchroot -interactions.") We are ready to drop it. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - systemd/mdadm-grow-continue@.service | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service -index 9ccadca3..64b8254a 100644 ---- a/systemd/mdadm-grow-continue@.service -+++ b/systemd/mdadm-grow-continue@.service -@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I - StandardInput=null - StandardOutput=null - StandardError=null --KillMode=none --- -2.38.1 - diff --git a/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch b/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch deleted file mode 100644 index d533d8b..0000000 --- a/SOURCES/0115-Create-Fix-checking-for-container-in-update_metadata.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Thu, 23 Mar 2023 12:50:00 +0100 -Subject: [PATCH 115/125] Create: Fix checking for container in update_metadata - -The commit 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -introduced a regression that caused timeouts and udev failing to create -links. - -Steps to reproduce the issue were as following: -$ mdadm -CR imsm -e imsm -n4 /dev/nvme[0-3]n1 -$ mdadm -CR vol -l5 -n4 /dev/nvme[0-3]n1 --assume-clean - -I found the check for container was wrong because negation was missing. - -Fixes: 8a4ce2c05386 ("Create: Factor out add_disks() helpers") -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Create.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Create.c b/Create.c -index bbe9e13d..0911bf92 100644 ---- a/Create.c -+++ b/Create.c -@@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st, - * again returns container info. - */ - st->ss->getinfo_super(st, &info_new, NULL); -- if (st->ss->external && is_container(s->level) && -+ if (st->ss->external && !is_container(s->level) && - !same_uuid(info_new.uuid, info->uuid, 0)) { - map_update(map, fd2devnm(mdfd), - info_new.text_version, --- -2.38.1 - diff --git a/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch b/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch deleted file mode 100644 index ca8176c..0000000 --- a/SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 890212d6800646153210ac264ce73035cc7dd5cc Mon Sep 17 00:00:00 2001 -From: miaoguanqin -Date: Tue, 4 Apr 2023 19:31:24 +0800 -Subject: [PATCH 116/125] Fix null pointer for incremental in mdadm - -when we excute mdadm --assemble, udev-md-raid-assembly.rules is triggered. -Then we stop array, we found an coredump for mdadm --incremental.func -stack are as follows: - -#0 enough (level=10, raid_disks=4, layout=258, clean=1, - avail=avail@entry=0x0) at util.c:555 -#1 0x0000562170c26965 in Incremental (devlist=, - c=, st=0x5621729b6dc0) at Incremental.c:514 -#2 0x0000562170bfb6ff in main (argc=, - argv=) at mdadm.c:1762 - -func enough() use array avail,avail allocate space in func count_active, -it may not alloc space, causing a coredump.We fix this coredump. - -Signed-off-by: Guanqin Miao -Signed-off-by: lixiaokeng -Signed-off-by: Jes Sorensen ---- - Incremental.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Incremental.c b/Incremental.c -index 09b94b9f..49a71f72 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -507,6 +507,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - GET_OFFSET | GET_SIZE)); - active_disks = count_active(st, sra, mdfd, &avail, &info); - -+ if (!avail) -+ goto out_unlock; -+ - journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); - - if (info.consistency_policy == CONSISTENCY_POLICY_PPL) --- -2.38.1 - diff --git a/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch b/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch deleted file mode 100644 index cf61c2d..0000000 --- a/SOURCES/0117-super1-fix-truncation-check-for-journal-device.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1c6f2a1dbfe17df14dd5b062fc53a60c5c387e47 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Sat, 1 Apr 2023 23:01:35 +0300 -Subject: [PATCH 117/125] super1: fix truncation check for journal device - -The journal device can be smaller than the component devices. - -Fixes: 171e9743881e ("super1: report truncated device") -Signed-off-by: Hristo Venev -Signed-off-by: Jes Sorensen ---- - super1.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/super1.c b/super1.c -index f7020320..44d6ecad 100644 ---- a/super1.c -+++ b/super1.c -@@ -2359,8 +2359,9 @@ static int load_super1(struct supertype *st, int fd, char *devname) - - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && -- (dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size)) -+ ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) - || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { --- -2.38.1 - diff --git a/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch b/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch deleted file mode 100644 index 889471f..0000000 --- a/SOURCES/0118-Fix-some-cases-eyesore-formatting.patch +++ /dev/null @@ -1,433 +0,0 @@ -From d3bb888d885fc96fc6239fbf6c22c63143eba461 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:40:42 -0400 -Subject: [PATCH 118/125] Fix some cases eyesore formatting - -Summary: No functional change .... just make it more readable. - -Signed-off-by: Jes Sorensen ---- - super1.c | 117 ++++++++++++++++++++++++++++--------------------------- - 1 file changed, 60 insertions(+), 57 deletions(-) - -diff --git a/super1.c b/super1.c -index 44d6ecad..1d20ef55 100644 ---- a/super1.c -+++ b/super1.c -@@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - unsigned int disk_csum, csum; - unsigned long long newcsum; - int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2; -- unsigned int *isuper = (unsigned int*)sb; -+ unsigned int *isuper = (unsigned int *)sb; - - /* make sure I can count... */ - if (offsetof(struct mdp_superblock_1,data_offset) != 128 || -@@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb) - disk_csum = sb->sb_csum; - sb->sb_csum = 0; - newcsum = 0; -- for (; size>=4; size -= 4 ) { -+ for (; size >= 4; size -= 4) { - newcsum += __le32_to_cpu(*isuper); - isuper++; - } -@@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk) - static void examine_super1(struct supertype *st, char *homehost) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - time_t atime; - unsigned int d; - int role; -@@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost) - printf(".0\n"); - printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map)); - printf(" Array UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) printf(":"); -+ for (i = 0; i < 16; i++) { -+ if ((i & 3) == 0 && i != 0) -+ printf(":"); - printf("%02x", sb->set_uuid[i]); - } - printf("\n"); -@@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost) - UINT64_MAX - info.space_after); - } - printf(" State : %s%s\n", -- (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean", -+ (__le64_to_cpu(sb->resync_offset) + 1) ? "active":"clean", - (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : ""); - printf(" Device UUID : "); -- for (i=0; i<16; i++) { -- if ((i&3)==0 && i != 0) -+ for (i = 0; i < 16; i++) { -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This turns out to just be confusing */ - printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number)); -- for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--) -+ for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--) - if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE) - break; - for (d = 0; d < i; d++) { -@@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost) - #if 0 - /* This is confusing too */ - faulty = 0; -- for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { -+ for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { - int role = __le16_to_cpu(sb->dev_roles[i]); - if (role == MD_DISK_ROLE_FAULTY) - faulty++; -@@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost) - if (inconsistent) { - printf("WARNING Array state is inconsistent - each number should appear only once\n"); - for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) -- if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY) -+ if (__le16_to_cpu(sb->dev_roles[d]) >= -+ MD_DISK_ROLE_FAULTY) - printf(" %d:-", d); - else -- printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d])); -+ printf(" %d:%d", d, -+ __le16_to_cpu(sb->dev_roles[d])); - printf("\n"); - } - } -@@ -659,7 +662,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) - printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks)); - printf("UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3)==0 && i != 0) -+ if ((i & 3)==0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -713,7 +716,7 @@ static void export_examine_super1(struct supertype *st) - } - printf("MD_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -722,7 +725,7 @@ static void export_examine_super1(struct supertype *st) - __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL); - printf("MD_DEV_UUID="); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->device_uuid[i]); - } -@@ -812,7 +815,7 @@ static int copy_metadata1(struct supertype *st, int from, int to) - /* have the header, can calculate - * correct bitmap bytes */ - bitmap_super_t *bms; -- bms = (void*)buf; -+ bms = (void *)buf; - bytes = calc_bitmap_size(bms, 512); - if (n > bytes) - n = bytes; -@@ -867,7 +870,7 @@ err: - static void detail_super1(struct supertype *st, char *homehost, char *subarray) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int i; - int l = homehost ? strlen(homehost) : 0; - -@@ -880,7 +883,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray) - printf("\n Cluster Name : %-64s", bms->cluster_name); - printf("\n UUID : "); - for (i = 0; i < 16; i++) { -- if ((i&3) == 0 && i != 0) -+ if ((i & 3) == 0 && i != 0) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -@@ -939,7 +942,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) - } - - size = __le16_to_cpu(sb->bblog_size)* 512; -- if (posix_memalign((void**)&bbl, 4096, size) != 0) { -+ if (posix_memalign((void **)&bbl, 4096, size) != 0) { - pr_err("could not allocate badblocks list\n"); - return 0; - } -@@ -987,7 +990,7 @@ static int match_home1(struct supertype *st, char *homehost) - static void uuid_from_super1(struct supertype *st, int uuid[4]) - { - struct mdp_superblock_1 *super = st->sb; -- char *cuuid = (char*)uuid; -+ char *cuuid = (char *)uuid; - int i; - for (i = 0; i < 16; i++) - cuuid[i] = super->set_uuid[i]; -@@ -996,9 +999,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) - static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - { - struct mdp_superblock_1 *sb = st->sb; -- struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE); - struct misc_dev_info *misc = -- (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE); - int working = 0; - unsigned int i; - unsigned int role; -@@ -1166,7 +1169,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - info->recovery_blocked = info->reshape_active; - - if (map) -- for (i=0; imax_dev); i++) { - role = __le16_to_cpu(sb->dev_roles[i]); -@@ -1217,7 +1220,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - */ - int rv = 0; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - - if (update == UOPT_HOMEHOST && homehost) { - /* -@@ -1228,9 +1231,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - update = UOPT_NAME; - c = strchr(sb->set_name, ':'); - if (c) -- snprintf(info->name, sizeof(info->name), "%s", c+1); -+ snprintf(info->name, sizeof(info->name), "%s", c + 1); - else -- snprintf(info->name, sizeof(info->name), "%s", sb->set_name); -+ snprintf(info->name, sizeof(info->name), "%s", -+ sb->set_name); - } - - switch (update) { -@@ -1331,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->dev_number = __cpu_to_le32(i); - - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - if (i > max) - return -2; - -@@ -1350,8 +1354,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); - } else { -- ds -= 8*2; -- ds &= ~(unsigned long long)(4*2-1); -+ ds -= 8 * 2; -+ ds &= ~(unsigned long long)(4 * 2 - 1); - sb->super_offset = __cpu_to_le64(ds); - sb->data_size = __cpu_to_le64( - ds - __le64_to_cpu(sb->data_offset)); -@@ -1367,7 +1371,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - if (i > max) - return -2; - if (i == max) -- sb->max_dev = __cpu_to_le32(max+1); -+ sb->max_dev = __cpu_to_le32(max + 1); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - sb->dev_roles[info->disk.number] = - __cpu_to_le16(info->disk.raid_disk); -@@ -1645,7 +1649,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - char defname[10]; - int sbsize; - -- if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 0; - } -@@ -1679,8 +1683,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - name = defname; - } - if (homehost && -- strchr(name, ':')== NULL && -- strlen(homehost)+1+strlen(name) < 32) { -+ strchr(name, ':') == NULL && -+ strlen(homehost) + 1 + strlen(name) < 32) { - strcpy(sb->set_name, homehost); - strcat(sb->set_name, ":"); - strcat(sb->set_name, name); -@@ -1759,7 +1763,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, - - if (dk->number >= (int)__le32_to_cpu(sb->max_dev) && - __le32_to_cpu(sb->max_dev) < MAX_DEVS) -- sb->max_dev = __cpu_to_le32(dk->number+1); -+ sb->max_dev = __cpu_to_le32(dk->number + 1); - - sb->dev_number = __cpu_to_le32(dk->number); - sb->devflags = 0; /* don't copy another disks flags */ -@@ -1840,8 +1844,8 @@ static int store_super1(struct supertype *st, int fd) - return 4; - - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { -- struct bitmap_super_s *bm = (struct bitmap_super_s*) -- (((char*)sb)+MAX_SB_SIZE); -+ struct bitmap_super_s *bm; -+ bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE); - if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { - locate_bitmap1(st, fd, 0); - if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm)) -@@ -1928,7 +1932,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) - - init_afd(&afd, fd); - -- if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) { -+ if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) { - pr_err("Could not allocate memory for the meta block.\n"); - return 1; - } -@@ -2197,7 +2201,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst, - return 1; - - if (!first) { -- if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2310,7 +2314,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 1; - } - -- if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) { -+ if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) { - pr_err("could not allocate superblock\n"); - return 1; - } -@@ -2349,10 +2353,10 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 2; - } - -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - - misc = (struct misc_dev_info*) -- (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE); -+ (((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE); - misc->device_size = dsize; - if (st->data_offset == INVALID_SECTORS) - st->data_offset = __le64_to_cpu(super->data_offset); -@@ -2360,9 +2364,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - if (st->minor_version >= 1 && - st->ignore_hw_compat == 0 && - ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL && -- dsize < (__le64_to_cpu(super->data_offset) + -- __le64_to_cpu(super->size))) -- || -+ dsize < (__le64_to_cpu(super->data_offset) + -+ __le64_to_cpu(super->size))) || - dsize < (__le64_to_cpu(super->data_offset) + - __le64_to_cpu(super->data_size)))) { - if (devname) -@@ -2391,8 +2394,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) - return 0; - - no_bitmap: -- super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) -- & ~MD_FEATURE_BITMAP_OFFSET); -+ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) & -+ ~MD_FEATURE_BITMAP_OFFSET); - return 0; - } - -@@ -2450,7 +2453,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, - if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) { - /* hot-add. allow for actual size of bitmap */ - struct bitmap_super_s *bsb; -- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); -+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE); - bmspace = calc_bitmap_size(bsb, 4096) >> 9; - } else if (md_feature_any_ppl_on(super->feature_map)) { - bmspace = __le16_to_cpu(super->ppl.size); -@@ -2519,7 +2522,7 @@ add_internal_bitmap1(struct supertype *st, - int creating = 0; - int len; - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int uuid[4]; - - if (__le64_to_cpu(sb->data_size) == 0) -@@ -2607,10 +2610,10 @@ add_internal_bitmap1(struct supertype *st, - max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8; - - min_chunk = 4096; /* sub-page chunks don't work yet.. */ -- bits = (size*512)/min_chunk +1; -+ bits = (size * 512) / min_chunk + 1; - while (bits > max_bits) { - min_chunk *= 2; -- bits = (bits+1)/2; -+ bits = (bits + 1) / 2; - } - if (chunk == UnSet) { - /* For practical purpose, 64Meg is a good -@@ -2628,8 +2631,8 @@ add_internal_bitmap1(struct supertype *st, - /* start bitmap on a 4K boundary with enough space for - * the bitmap - */ -- bits = (size*512) / chunk + 1; -- room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096; -+ bits = (size * 512) / chunk + 1; -+ room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096; - room *= 8; /* convert 4K blocks to sectors */ - offset = -room - bbl_size; - } -@@ -2683,7 +2686,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - - offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset); - if (node_num) { -- bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9; - offset += bm_sectors_per_node * node_num; - } -@@ -2696,7 +2699,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num) - static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update) - { - struct mdp_superblock_1 *sb = st->sb; -- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); -+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE); - int rv = 0; - void *buf; - int towrite, n, len; -@@ -2970,16 +2973,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 - - copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); - sprintf(sb->set_name, "%d", sb0->md_minor); -- sb->ctime = __cpu_to_le32(info->array.ctime+1); -+ sb->ctime = __cpu_to_le32(info->array.ctime + 1); - sb->level = __cpu_to_le32(info->array.level); - sb->layout = __cpu_to_le32(info->array.layout); - sb->size = __cpu_to_le64(info->component_size); -- sb->chunksize = __cpu_to_le32(info->array.chunk_size/512); -+ sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512); - sb->raid_disks = __cpu_to_le32(info->array.raid_disks); - if (info->array.level > 0) - sb->data_size = sb->size; - else -- sb->data_size = st->ss->avail_size(st, st->devsize/512, 0); -+ sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0); - sb->resync_offset = MaxSector; - sb->max_dev = __cpu_to_le32(MD_SB_DISKS); - sb->dev_number = __cpu_to_le32(info->disk.number); --- -2.38.1 - diff --git a/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch b/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch deleted file mode 100644 index 486f799..0000000 --- a/SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch +++ /dev/null @@ -1,136 +0,0 @@ -From f8d2c4286a92b7acb7872271a401ad1efe336096 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 10 Apr 2023 11:45:34 -0400 -Subject: [PATCH 119/125] Bump minimum kernel version to 2.6.32 - -Summary: At this point it probably is reasonable to drop support for -anything prior to 3.10. - -Signed-off-by: Jes Sorensen ---- - Create.c | 5 ----- - Grow.c | 16 ---------------- - Manage.c | 17 ----------------- - mdadm.c | 4 ++-- - super1.c | 5 ----- - 5 files changed, 2 insertions(+), 45 deletions(-) - -diff --git a/Create.c b/Create.c -index 0911bf92..aa0472dd 100644 ---- a/Create.c -+++ b/Create.c -@@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev, - break; - case LEVEL_LINEAR: - /* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */ -- if (get_linux_version() < 2006016 && s->chunk == 0) { -- s->chunk = 64; -- if (c->verbose > 0) -- pr_err("chunk size defaults to 64K\n"); -- } - break; - case 1: - case LEVEL_FAULTY: -diff --git a/Grow.c b/Grow.c -index 06001f2d..8fa97875 100644 ---- a/Grow.c -+++ b/Grow.c -@@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) - return NULL; - } - -- if (re->after.data_disks == re->before.data_disks && -- get_linux_version() < 2006032) -- return "in-place reshape is not safe before 2.6.32 - sorry."; -- -- if (re->after.data_disks < re->before.data_disks && -- get_linux_version() < 2006030) -- return "reshape to fewer devices is not supported before 2.6.30 - sorry."; -- - re->backup_blocks = compute_backup_blocks( - info->new_chunk, info->array.chunk_size, - re->after.data_disks, re->before.data_disks); -@@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd, - return 1; - } - -- if (s->raiddisks && s->raiddisks < array.raid_disks && -- array.level > 1 && get_linux_version() < 2006032 && -- !check_env("MDADM_FORCE_FEWER")) { -- pr_err("reducing the number of devices is not safe before Linux 2.6.32\n" -- " Please use a newer kernel\n"); -- return 1; -- } -- - if (array.level > 1 && s->size > 1 && - (unsigned long long) (array.chunk_size / 1024) > s->size) { - pr_err("component size must be larger than chunk size.\n"); -diff --git a/Manage.c b/Manage.c -index fde6aba3..f54de7c6 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -461,17 +461,6 @@ done: - goto out; - } - -- if (get_linux_version() < 2006028) { -- /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array -- * was stopped, so We'll do it here just to be sure. Drop any -- * partitions as well... -- */ -- if (fd >= 0) -- ioctl(fd, BLKRRPART, 0); -- if (mdi) -- sysfs_uevent(mdi, "change"); -- } -- - if (devnm[0] && use_udev()) { - struct map_ent *mp = map_by_devnm(&map, devnm); - remove_devices(devnm, mp ? mp->path : NULL); -@@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, - * though. - */ - mdu_disk_info_t disc; -- /* re-add doesn't work for version-1 superblocks -- * before 2.6.18 :-( -- */ -- if (array->major_version == 1 && -- get_linux_version() <= 2006018) -- goto skip_re_add; - disc.number = mdi.disk.number; - if (md_get_disk_info(fd, &disc) != 0 || - disc.major != 0 || disc.minor != 0) -diff --git a/mdadm.c b/mdadm.c -index 4685ad6b..2296911d 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -107,8 +107,8 @@ int main(int argc, char *argv[]) - - srandom(time(0) ^ getpid()); - -- if (get_linux_version() < 2006015) { -- pr_err("This version of mdadm does not support kernels older than 2.6.15\n"); -+ if (get_linux_version() < 2006032) { -+ pr_err("This version of mdadm does not support kernels older than 2.6.32\n"); - exit(1); - } - -diff --git a/super1.c b/super1.c -index 1d20ef55..938c3a68 100644 ---- a/super1.c -+++ b/super1.c -@@ -2033,11 +2033,6 @@ static int write_init_super1(struct supertype *st) - /* same array, so preserve events and - * dev_number */ - sb->events = refsb->events; -- /* bugs in 2.6.17 and earlier mean the -- * dev_number chosen in Manage must be preserved -- */ -- if (get_linux_version() >= 2006018) -- sb->dev_number = refsb->dev_number; - } - free_super1(refst); - } --- -2.38.1 - diff --git a/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch b/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch deleted file mode 100644 index 4160281..0000000 --- a/SOURCES/0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 7 Apr 2023 08:45:28 +0800 -Subject: [PATCH 120/125] Remove the config files in mdcheck_start|continue - service - -We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files. -And mdcheck doesn't use any configs from the config file. So we can remove -the dependencies. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - systemd/mdcheck_continue.service | 2 -- - systemd/mdcheck_start.service | 2 -- - 2 files changed, 4 deletions(-) - -diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service -index f5324905..70892a1f 100644 ---- a/systemd/mdcheck_continue.service -+++ b/systemd/mdcheck_continue.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} -diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service -index 703a6583..fc4fc438 100644 ---- a/systemd/mdcheck_start.service -+++ b/systemd/mdcheck_start.service -@@ -13,6 +13,4 @@ Documentation=man:mdadm(8) - [Service] - Type=oneshot - Environment="MDADM_CHECK_DURATION=6 hours" --EnvironmentFile=-/run/sysconfig/mdadm --ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh - ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} --- -2.38.1 - diff --git a/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch b/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch deleted file mode 100644 index 047c45e..0000000 --- a/SOURCES/0121-mdadm-define-DEV_MD_DIR.patch +++ /dev/null @@ -1,347 +0,0 @@ -From b9ce7ab0218c550488587fdad5708628d6a5ffc2 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:14 +0100 -Subject: [PATCH 121/125] mdadm: define DEV_MD_DIR - -It is used many times. Additionally define _LEN to avoid repeated -strlen() calls when length is needed. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Create.c | 7 +++---- - Detail.c | 9 ++++----- - Incremental.c | 4 ++-- - Monitor.c | 32 ++++++++++++++++++-------------- - config.c | 10 +++++----- - lib.c | 2 +- - mapfile.c | 12 ++++++------ - mdadm.h | 8 ++++++++ - mdopen.c | 6 +++--- - super-ddf.c | 2 +- - super-intel.c | 2 +- - super1.c | 3 +-- - sysfs.c | 2 +- - 13 files changed, 54 insertions(+), 45 deletions(-) - -diff --git a/Create.c b/Create.c -index aa0472dd..ea6a4745 100644 ---- a/Create.c -+++ b/Create.c -@@ -1024,10 +1024,9 @@ int Create(struct supertype *st, char *mddev, - * it could be in conflict with already existing device - * e.g. container, array - */ -- if (strncmp(chosen_name, "/dev/md/", 8) == 0 && -- map_by_name(&map, chosen_name+8) != NULL) { -- pr_err("Array name %s is in use already.\n", -- chosen_name); -+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 && -+ map_by_name(&map, chosen_name + DEV_MD_DIR_LEN)) { -+ pr_err("Array name %s is in use already.\n", chosen_name); - close(mdfd); - map_unlock(&map); - udev_unblock(); -diff --git a/Detail.c b/Detail.c -index 4ef26460..206d88e3 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -254,10 +254,9 @@ int Detail(char *dev, struct context *c) - fname_from_uuid(st, info, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf + 5); - mp = map_by_uuid(&map, info->uuid); -- if (mp && mp->path && -- strncmp(mp->path, "/dev/md/", 8) == 0) { -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - printf("MD_DEVNAME="); -- print_escape(mp->path + 8); -+ print_escape(mp->path + DEV_MD_DIR_LEN); - putchar('\n'); - } - -@@ -273,9 +272,9 @@ int Detail(char *dev, struct context *c) - printf("MD_UUID=%s\n", nbuf+5); - } - if (mp && mp->path && -- strncmp(mp->path, "/dev/md/", 8) == 0) { -+ strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - printf("MD_DEVNAME="); -- print_escape(mp->path+8); -+ print_escape(mp->path + DEV_MD_DIR_LEN); - putchar('\n'); - } - map_free(map); -diff --git a/Incremental.c b/Incremental.c -index 49a71f72..59b850f1 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -460,8 +460,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - info.array.working_disks ++; - - } -- if (strncmp(chosen_name, "/dev/md/", 8) == 0) -- md_devname = chosen_name+8; -+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ md_devname = chosen_name + DEV_MD_DIR_LEN; - else - md_devname = chosen_name; - if (c->export) { -diff --git a/Monitor.c b/Monitor.c -index 44918184..3273f2fb 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -36,9 +36,18 @@ - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" - -+/** -+ * struct state - external array or container properties. -+ * @devname: has length of %DEV_MD_DIR + device name + terminating byte -+ * @devnm: to sync with mdstat info -+ * @parent_devnm: or subarray, devnm of parent, for others, "" -+ * @subarray: for a container it is a link to first subarray, for a subarray it is a link to next -+ * subarray in the same container -+ * @parent: for a subarray it is a link to its container -+ */ - struct state { -- char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/ -- char devnm[MD_NAME_MAX]; /* to sync with mdstat info */ -+ char devname[MD_NAME_MAX + sizeof(DEV_MD_DIR)]; -+ char devnm[MD_NAME_MAX]; - unsigned int utime; - int err; - char *spare_group; -@@ -49,15 +58,10 @@ struct state { - int devstate[MAX_DISKS]; - dev_t devid[MAX_DISKS]; - int percent; -- char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent. -- * For others, "" -- */ -+ char parent_devnm[MD_NAME_MAX]; - struct supertype *metadata; -- struct state *subarray;/* for a container it is a link to first subarray -- * for a subarray it is a link to next subarray -- * in the same container */ -- struct state *parent; /* for a subarray it is a link to its container -- */ -+ struct state *subarray; -+ struct state *parent; - struct state *next; - }; - -@@ -252,8 +256,8 @@ int Monitor(struct mddev_dev *devlist, - continue; - - st = xcalloc(1, sizeof *st); -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), -- "/dev/md/%s", basename(mdlist->devname)); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s", -+ basename(mdlist->devname)); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -274,7 +278,7 @@ int Monitor(struct mddev_dev *devlist, - - st = xcalloc(1, sizeof *st); - mdlist = conf_get_ident(dv->devname); -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", dv->devname); - st->next = statelist; - st->devnm[0] = 0; - st->percent = RESYNC_UNKNOWN; -@@ -942,7 +946,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) - continue; - } - -- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name); -+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", name); - if ((fd = open(st->devname, O_RDONLY)) < 0 || - md_get_array_info(fd, &array) < 0) { - /* no such array */ -diff --git a/config.c b/config.c -index eeedd0c6..59d5bfb6 100644 ---- a/config.c -+++ b/config.c -@@ -405,7 +405,7 @@ void arrayline(char *line) - * or anything that doesn't start '/' or '<' - */ - if (strcasecmp(w, "") == 0 || -- strncmp(w, "/dev/md/", 8) == 0 || -+ strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || - (strncmp(w, "/dev/md", 7) == 0 && - is_number(w + 7)) || -@@ -1102,13 +1102,13 @@ int devname_matches(char *name, char *match) - * mdNN with NN - * then just strcmp - */ -- if (strncmp(name, "/dev/md/", 8) == 0) -- name += 8; -+ if (strncmp(name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ name += DEV_MD_DIR_LEN; - else if (strncmp(name, "/dev/", 5) == 0) - name += 5; - -- if (strncmp(match, "/dev/md/", 8) == 0) -- match += 8; -+ if (strncmp(match, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ match += DEV_MD_DIR_LEN; - else if (strncmp(match, "/dev/", 5) == 0) - match += 5; - -diff --git a/lib.c b/lib.c -index e395b28d..65ea51e0 100644 ---- a/lib.c -+++ b/lib.c -@@ -313,7 +313,7 @@ char *map_dev_preferred(int major, int minor, int create, - - for (p = devlist; p; p = p->next) - if (p->major == major && p->minor == minor) { -- if (strncmp(p->name, "/dev/md/",8) == 0 || -+ if (strncmp(p->name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (prefer && strstr(p->name, prefer))) { - if (preferred == NULL || - strlen(p->name) < strlen(preferred)) -diff --git a/mapfile.c b/mapfile.c -index ac351768..34fea179 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -320,9 +320,9 @@ struct map_ent *map_by_name(struct map_ent **map, char *name) - for (mp = *map ; mp ; mp = mp->next) { - if (!mp->path) - continue; -- if (strncmp(mp->path, "/dev/md/", 8) != 0) -+ if (strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) - continue; -- if (strcmp(mp->path+8, name) != 0) -+ if (strcmp(mp->path + DEV_MD_DIR_LEN, name) != 0) - continue; - if (!mddev_busy(mp->devnm)) { - mp->bad = 1; -@@ -413,7 +413,7 @@ void RebuildMap(void) - devid = devnm2devid(md->devnm); - path = map_dev(major(devid), minor(devid), 0); - if (path == NULL || -- strncmp(path, "/dev/md/", 8) != 0) { -+ strncmp(path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) { - /* We would really like a name that provides - * an MD_DEVNAME for udev. - * The name needs to be unique both in /dev/md/ -@@ -434,7 +434,7 @@ void RebuildMap(void) - if (match && match->devname && match->devname[0] == '/') { - path = match->devname; - if (path[0] != '/') { -- strcpy(namebuf, "/dev/md/"); -+ strcpy(namebuf, DEV_MD_DIR); - strcat(namebuf, path); - path = namebuf; - } -@@ -478,10 +478,10 @@ void RebuildMap(void) - - while (conflict) { - if (unum >= 0) -- sprintf(namebuf, "/dev/md/%s%s%d", -+ sprintf(namebuf, DEV_MD_DIR "%s%s%d", - name, sep, unum); - else -- sprintf(namebuf, "/dev/md/%s", -+ sprintf(namebuf, DEV_MD_DIR "%s", - name); - unum++; - if (lstat(namebuf, &stb) != 0 && -diff --git a/mdadm.h b/mdadm.h -index 0d995445..67d73f96 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -100,6 +100,14 @@ struct dlm_lksb { - #define DEFAULT_BITMAP_DELAY 5 - #define DEFAULT_MAX_WRITE_BEHIND 256 - -+/* DEV_MD_DIR points to named MD devices directory. -+ * DEV_MD_DIR_LEN is a length with Null byte excluded. -+ */ -+#ifndef DEV_MD_DIR -+#define DEV_MD_DIR "/dev/md/" -+#define DEV_MD_DIR_LEN (sizeof(DEV_MD_DIR) - 1) -+#endif /* DEV_MD_DIR */ -+ - /* MAP_DIR should be somewhere that persists across the pivotroot - * from early boot to late boot. - * /run seems to have emerged as the best standard. -diff --git a/mdopen.c b/mdopen.c -index 810f79a3..6c3bdb6a 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -188,12 +188,12 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - parts = autof >> 3; - autof &= 7; - -- strcpy(chosen, "/dev/md/"); -+ strcpy(chosen, DEV_MD_DIR); - cname = chosen + strlen(chosen); - - if (dev) { -- if (strncmp(dev, "/dev/md/", 8) == 0) { -- strcpy(cname, dev+8); -+ if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -+ strcpy(cname, dev + DEV_MD_DIR_LEN); - } else if (strncmp(dev, "/dev/", 5) == 0) { - char *e = dev + strlen(dev); - while (e > dev && isdigit(e[-1])) -diff --git a/super-ddf.c b/super-ddf.c -index b86c6acd..7213284e 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1648,7 +1648,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) - fname_from_uuid(st, &info, nbuf1, ':'); - _ddf_array_name(namebuf, ddf, i); - printf("ARRAY%s%s container=%s member=%d UUID=%s\n", -- namebuf[0] == '\0' ? "" : " /dev/md/", namebuf, -+ namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf, - nbuf+5, i, nbuf1+5); - } - } -diff --git a/super-intel.c b/super-intel.c -index a5c86cb2..aaf6659e 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -2309,7 +2309,7 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose) - super->current_vol = i; - getinfo_super_imsm(st, &info, NULL); - fname_from_uuid(st, &info, nbuf1, ':'); -- printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n", -+ printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n", - dev->volume, nbuf + 5, i, nbuf1 + 5); - } - } -diff --git a/super1.c b/super1.c -index 938c3a68..856b0208 100644 ---- a/super1.c -+++ b/super1.c -@@ -645,8 +645,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) - - printf("ARRAY "); - if (nm) { -- printf("/dev/md/"); -- print_escape(nm); -+ printf(DEV_MD_DIR "%s", nm); - putchar(' '); - } - if (verbose && c) -diff --git a/sysfs.c b/sysfs.c -index ca1d888f..94d02f53 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -1114,7 +1114,7 @@ void sysfsline(char *line) - if (strncasecmp(w, "name=", 5) == 0) { - char *devname = w + 5; - -- if (strncmp(devname, "/dev/md/", 8) == 0) { -+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { - if (sr->devname) - pr_err("Only give one device per SYSFS line: %s\n", - devname); --- -2.38.1 - diff --git a/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch b/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch deleted file mode 100644 index 645aa62..0000000 --- a/SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0f8347d4f6588ee6ded55af3e307418cee286a6f Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:15 +0100 -Subject: [PATCH 122/125] mdadm: define DEV_NUM_PREF - -Use define instead of inlines. Add _LEN define. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 4 ++-- - mdadm.h | 8 ++++++++ - mdopen.c | 10 +++++----- - 3 files changed, 15 insertions(+), 7 deletions(-) - -diff --git a/config.c b/config.c -index 59d5bfb6..f44cc1d3 100644 ---- a/config.c -+++ b/config.c -@@ -407,8 +407,8 @@ void arrayline(char *line) - if (strcasecmp(w, "") == 0 || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || -- (strncmp(w, "/dev/md", 7) == 0 && -- is_number(w + 7)) || -+ (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -+ is_number(w + DEV_NUM_PREF_LEN)) || - (strncmp(w, "/dev/md_d", 9) == 0 && - is_number(w + 9))) { - /* This is acceptable */; -diff --git a/mdadm.h b/mdadm.h -index 67d73f96..f2e70baa 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -100,6 +100,14 @@ struct dlm_lksb { - #define DEFAULT_BITMAP_DELAY 5 - #define DEFAULT_MAX_WRITE_BEHIND 256 - -+/* DEV_NUM_PREF is a subpath to numbered MD devices, e.g. /dev/md1 or directory name. -+ * DEV_NUM_PREF_LEN is a length with Null byte excluded. -+ */ -+#ifndef DEV_NUM_PREF -+#define DEV_NUM_PREF "/dev/md" -+#define DEV_NUM_PREF_LEN (sizeof(DEV_NUM_PREF) - 1) -+#endif /* DEV_NUM_PREF */ -+ - /* DEV_MD_DIR points to named MD devices directory. - * DEV_MD_DIR_LEN is a length with Null byte excluded. - */ -diff --git a/mdopen.c b/mdopen.c -index 6c3bdb6a..d3022a54 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -412,11 +412,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - make_parts(devname, parts); - - if (strcmp(chosen, devname) != 0) { -- if (mkdir("/dev/md",0700) == 0) { -- if (chown("/dev/md", ci->uid, ci->gid)) -- perror("chown /dev/md"); -- if (chmod("/dev/md", ci->mode| ((ci->mode>>2) & 0111))) -- perror("chmod /dev/md"); -+ if (mkdir(DEV_NUM_PREF, 0700) == 0) { -+ if (chown(DEV_NUM_PREF, ci->uid, ci->gid)) -+ perror("chown " DEV_NUM_PREF); -+ if (chmod(DEV_NUM_PREF, ci->mode | ((ci->mode >> 2) & 0111))) -+ perror("chmod " DEV_NUM_PREF); - } - - if (dev && strcmp(chosen, dev) == 0) --- -2.38.1 - diff --git a/SOURCES/0123-mdadm-define-is_devname_ignore.patch b/SOURCES/0123-mdadm-define-is_devname_ignore.patch deleted file mode 100644 index 3526be2..0000000 --- a/SOURCES/0123-mdadm-define-is_devname_ignore.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 7b3b691ba69b909ea8c172aae693fa2a6938fd14 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:16 +0100 -Subject: [PATCH 123/125] mdadm: define is_devname_ignore() - -Use function instead of direct checks across code. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Incremental.c | 6 ++---- - Monitor.c | 2 +- - config.c | 16 ++++++++++++++-- - mdadm.c | 5 ++--- - mdadm.h | 1 + - 5 files changed, 20 insertions(+), 10 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index 59b850f1..f13ce027 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -202,8 +202,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - if (!match && rv == 2) - goto out; - -- if (match && match->devname && -- strcasecmp(match->devname, "") == 0) { -+ if (match && match->devname && is_devname_ignore(match->devname) == true) { - if (c->verbose >= 0) - pr_err("array containing %s is explicitly ignored by mdadm.conf\n", - devname); -@@ -1567,8 +1566,7 @@ static int Incremental_container(struct supertype *st, char *devname, - break; - } - -- if (match && match->devname && -- strcasecmp(match->devname, "") == 0) { -+ if (match && match->devname && is_devname_ignore(match->devname) == true) { - if (c->verbose > 0) - pr_err("array %s/%s is explicitly ignored by mdadm.conf\n", - match->container, match->member); -diff --git a/Monitor.c b/Monitor.c -index 3273f2fb..66175968 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -250,7 +250,7 @@ int Monitor(struct mddev_dev *devlist, - - if (mdlist->devname == NULL) - continue; -- if (strcasecmp(mdlist->devname, "") == 0) -+ if (is_devname_ignore(mdlist->devname) == true) - continue; - if (!is_mddev(mdlist->devname)) - continue; -diff --git a/config.c b/config.c -index f44cc1d3..e61c0496 100644 ---- a/config.c -+++ b/config.c -@@ -119,6 +119,18 @@ int match_keyword(char *word) - return -1; - } - -+/** -+ * is_devname_ignore() - check if &devname is a special "" keyword. -+ */ -+bool is_devname_ignore(char *devname) -+{ -+ static const char keyword[] = ""; -+ -+ if (strcasecmp(devname, keyword) == 0) -+ return true; -+ return false; -+} -+ - /** - * ident_init() - Set defaults. - * @ident: ident pointer, not NULL. -@@ -404,7 +416,7 @@ void arrayline(char *line) - * - * or anything that doesn't start '/' or '<' - */ -- if (strcasecmp(w, "") == 0 || -+ if (is_devname_ignore(w) == true || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || - (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -@@ -571,7 +583,7 @@ void homehostline(char *line) - char *w; - - for (w = dl_next(line); w != line; w = dl_next(w)) { -- if (strcasecmp(w, "") == 0) -+ if (is_devname_ignore(w) == true) - require_homehost = 0; - else if (home_host == NULL) { - if (strcasecmp(w, "") == 0) -diff --git a/mdadm.c b/mdadm.c -index 2296911d..076b45e0 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -154,7 +154,7 @@ int main(int argc, char *argv[]) - continue; - - case HomeHost: -- if (strcasecmp(optarg, "") == 0) -+ if (is_devname_ignore(optarg) == true) - c.require_homehost = 0; - else - c.homehost = optarg; -@@ -1749,8 +1749,7 @@ static int scan_assemble(struct supertype *ss, - int r; - if (a->assembled) - continue; -- if (a->devname && -- strcasecmp(a->devname, "") == 0) -+ if (a->devname && is_devname_ignore(a->devname) == true) - continue; - - r = Assemble(ss, a->devname, -diff --git a/mdadm.h b/mdadm.h -index f2e70baa..0932c2d3 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1650,6 +1650,7 @@ extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); -+extern bool is_devname_ignore(char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); - extern int devname_matches(char *name, char *match); - extern struct mddev_ident *conf_match(struct supertype *st, --- -2.38.1 - diff --git a/SOURCES/0124-mdadm-numbered-names-verification.patch b/SOURCES/0124-mdadm-numbered-names-verification.patch deleted file mode 100644 index a3e94f0..0000000 --- a/SOURCES/0124-mdadm-numbered-names-verification.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 25aa7329141c0b28d8811671627f0f5c5dc22273 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 23 Mar 2023 17:50:17 +0100 -Subject: [PATCH 124/125] mdadm: numbered names verification - -New functions added to remove literals and make the code reusable. -Use parse_num() instead of is_numer(). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 17 ++--------------- - lib.c | 2 +- - mdadm.h | 4 +++- - util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 50 insertions(+), 17 deletions(-) - -diff --git a/config.c b/config.c -index e61c0496..450880e3 100644 ---- a/config.c -+++ b/config.c -@@ -385,17 +385,6 @@ void devline(char *line) - struct mddev_ident *mddevlist = NULL; - struct mddev_ident **mddevlp = &mddevlist; - --static int is_number(char *w) --{ -- /* check if there are 1 or more digits and nothing else */ -- int digits = 0; -- while (*w && isdigit(*w)) { -- digits++; -- w++; -- } -- return (digits && ! *w); --} -- - void arrayline(char *line) - { - char *w; -@@ -419,10 +408,8 @@ void arrayline(char *line) - if (is_devname_ignore(w) == true || - strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || - (w[0] != '/' && w[0] != '<') || -- (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 && -- is_number(w + DEV_NUM_PREF_LEN)) || -- (strncmp(w, "/dev/md_d", 9) == 0 && -- is_number(w + 9))) { -+ is_devname_md_numbered(w) == true || -+ is_devname_md_d_numbered(w) == true) { - /* This is acceptable */; - if (mis.devname) - pr_err("only give one device per ARRAY line: %s and %s\n", -diff --git a/lib.c b/lib.c -index 65ea51e0..fe5c8d2c 100644 ---- a/lib.c -+++ b/lib.c -@@ -570,7 +570,7 @@ void free_line(char *line) - * - * Return: 0 on success, 1 otherwise. - */ --int parse_num(int *dest, char *num) -+int parse_num(int *dest, const char *num) - { - char *c = NULL; - long temp; -diff --git a/mdadm.h b/mdadm.h -index 0932c2d3..83f2cf7f 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1601,7 +1601,7 @@ int default_layout(struct supertype *st, int level, int verbose); - extern int is_near_layout_10(int layout); - extern int parse_layout_10(char *layout); - extern int parse_layout_faulty(char *layout); --extern int parse_num(int *dest, char *num); -+extern int parse_num(int *dest, const char *num); - extern int parse_cluster_confirm_arg(char *inp, char **devname, int *slot); - extern int check_ext2(int fd, char *name); - extern int check_reiser(int fd, char *name); -@@ -1651,6 +1651,8 @@ extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); - extern bool is_devname_ignore(char *devname); -+extern bool is_devname_md_numbered(const char *devname); -+extern bool is_devname_md_d_numbered(const char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); - extern int devname_matches(char *name, char *match); - extern struct mddev_ident *conf_match(struct supertype *st, -diff --git a/util.c b/util.c -index d70ca43b..fa378eba 100644 ---- a/util.c -+++ b/util.c -@@ -973,6 +973,50 @@ dev_t devnm2devid(char *devnm) - return 0; - } - -+/** -+ * is_devname_numbered() - helper for numbered devname verification. -+ * @devname: path or name to check. -+ * @pref: expected devname prefix. -+ * @pref_len: prefix len. -+ */ -+static bool is_devname_numbered(const char *devname, const char *pref, const int pref_len) -+{ -+ int val; -+ -+ assert(devname && pref); -+ -+ if (strncmp(devname, pref, pref_len) != 0) -+ return false; -+ -+ if (parse_num(&val, devname + pref_len) != 0) -+ return false; -+ -+ if (val > 127) -+ return false; -+ -+ return true; -+} -+ -+/** -+ * is_devname_md_numbered() - check if &devname is numbered MD device (md). -+ * @devname: path or name to check. -+ */ -+bool is_devname_md_numbered(const char *devname) -+{ -+ return is_devname_numbered(devname, DEV_NUM_PREF, DEV_NUM_PREF_LEN); -+} -+ -+/** -+ * is_devname_md_d_numbered() - check if &devname is secondary numbered MD device (md_d). -+ * @devname: path or name to check. -+ */ -+bool is_devname_md_d_numbered(const char *devname) -+{ -+ static const char d_dev[] = DEV_NUM_PREF "_d"; -+ -+ return is_devname_numbered(devname, d_dev, sizeof(d_dev) - 1); -+} -+ - /** - * get_md_name() - Get main dev node of the md device. - * @devnm: Md device name or path. --- -2.38.1 - diff --git a/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch b/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch deleted file mode 100644 index 4866fe3..0000000 --- a/SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 75350d87c86001c47076e1f62478079bdc072223 Mon Sep 17 00:00:00 2001 -From: Kevin Friedberg -Date: Wed, 15 Feb 2023 23:41:34 -0500 -Subject: [PATCH 125/125] enable RAID for SATA under VMD - -Detect when a SATA controller has been mapped under Intel Alderlake RST -VMD, so that it can use the VMD controller's RAID capabilities. Create -new device type SYS_DEV_SATA_VMD and list separate controller to prevent -mixing with the NVMe SYS_DEV_VMD devices on the same VMD domain. - -Signed-off-by: Kevin Friedberg -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 21 ++++++++++++++++++--- - platform-intel.h | 1 + - super-intel.c | 28 ++++++++++++++++++---------- - 3 files changed, 37 insertions(+), 13 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index 757f0b1b..914164c0 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -64,9 +64,10 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - - if (strcmp(driver, "isci") == 0) - type = SYS_DEV_SAS; -- else if (strcmp(driver, "ahci") == 0) -+ else if (strcmp(driver, "ahci") == 0) { -+ vmd = find_driver_devices("pci", "vmd"); - type = SYS_DEV_SATA; -- else if (strcmp(driver, "nvme") == 0) { -+ } else if (strcmp(driver, "nvme") == 0) { - /* if looking for nvme devs, first look for vmd */ - vmd = find_driver_devices("pci", "vmd"); - type = SYS_DEV_NVME; -@@ -115,6 +116,17 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - free(rp); - } - -+ /* change sata type if under a vmd controller */ -+ if (type == SYS_DEV_SATA) { -+ struct sys_dev *dev; -+ char *rp = realpath(path, NULL); -+ for (dev = vmd; dev; dev = dev->next) { -+ if ((strncmp(dev->path, rp, strlen(dev->path)) == 0)) -+ type = SYS_DEV_SATA_VMD; -+ } -+ free(rp); -+ } -+ - /* if it's not Intel device or mark as VMD connected - skip it. */ - if (devpath_to_vendor(path) != 0x8086 || skip == 1) - continue; -@@ -166,7 +178,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) - } - closedir(driver_dir); - -- if (vmd) { -+ /* nvme vmd needs a list separate from sata vmd */ -+ if (vmd && type == SYS_DEV_NVME) { - if (list) - list->next = vmd; - else -@@ -273,6 +286,7 @@ struct sys_dev *find_intel_devices(void) - free_sys_dev(&intel_devices); - - isci = find_driver_devices("pci", "isci"); -+ /* Searching for AHCI will return list of SATA and SATA VMD controllers */ - ahci = find_driver_devices("pci", "ahci"); - /* Searching for NVMe will return list of NVMe and VMD controllers */ - nvme = find_driver_devices("pci", "nvme"); -@@ -638,6 +652,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) - - break; - case SYS_DEV_VMD: -+ case SYS_DEV_SATA_VMD: - for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) { - if (!read_efi_variable(&orom, sizeof(orom), - vmd_efivars[i], VENDOR_GUID)) -diff --git a/platform-intel.h b/platform-intel.h -index 6238d23f..2c0f4e39 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -196,6 +196,7 @@ enum sys_dev_type { - SYS_DEV_SATA, - SYS_DEV_NVME, - SYS_DEV_VMD, -+ SYS_DEV_SATA_VMD, - SYS_DEV_MAX - }; - -diff --git a/super-intel.c b/super-intel.c -index aaf6659e..ae0f4a8c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -627,7 +627,8 @@ static const char *_sys_dev_type[] = { - [SYS_DEV_SAS] = "SAS", - [SYS_DEV_SATA] = "SATA", - [SYS_DEV_NVME] = "NVMe", -- [SYS_DEV_VMD] = "VMD" -+ [SYS_DEV_VMD] = "VMD", -+ [SYS_DEV_SATA_VMD] = "SATA VMD" - }; - - static int no_platform = -1; -@@ -2598,6 +2599,8 @@ static void print_found_intel_controllers(struct sys_dev *elem) - - if (elem->type == SYS_DEV_VMD) - fprintf(stderr, "VMD domain"); -+ else if (elem->type == SYS_DEV_SATA_VMD) -+ fprintf(stderr, "SATA VMD domain"); - else - fprintf(stderr, "RAID controller"); - -@@ -2768,8 +2771,9 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - if (!find_imsm_capability(hba)) { - char buf[PATH_MAX]; - pr_err("imsm capabilities not found for controller: %s (type %s)\n", -- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path, -- get_sys_dev_type(hba->type)); -+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ? -+ vmd_domain_to_controller(hba, buf) : -+ hba->path, get_sys_dev_type(hba->type)); - continue; - } - result = 0; -@@ -2822,11 +2826,12 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle - - printf(" I/O Controller : %s (%s)\n", - hba->path, get_sys_dev_type(hba->type)); -- if (hba->type == SYS_DEV_SATA) { -+ if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) { - host_base = ahci_get_port_count(hba->path, &port_count); - if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { - if (verbose > 0) -- pr_err("failed to enumerate ports on SATA controller at %s.\n", hba->pci_id); -+ pr_err("failed to enumerate ports on %s controller at %s.\n", -+ get_sys_dev_type(hba->type), hba->pci_id); - result |= 2; - } - } -@@ -2856,7 +2861,8 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) - if (!find_imsm_capability(hba) && verbose > 0) { - char buf[PATH_MAX]; - pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n", -- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path); -+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ? -+ vmd_domain_to_controller(hba, buf) : hba->path); - } - else - result = 0; -@@ -2865,7 +2871,7 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) - const struct orom_entry *entry; - - for (entry = orom_entries; entry; entry = entry->next) { -- if (entry->type == SYS_DEV_VMD) { -+ if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_SATA_VMD) { - for (hba = list; hba; hba = hba->next) - print_imsm_capability_export(&entry->orom); - continue; -@@ -4782,10 +4788,12 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de - " but the container is assigned to Intel(R) %s %s (", - devname, - get_sys_dev_type(hba_name->type), -- hba_name->type == SYS_DEV_VMD ? "domain" : "RAID controller", -+ hba_name->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ? -+ "domain" : "RAID controller", - hba_name->pci_id ? : "Err!", - get_sys_dev_type(super->hba->type), -- hba->type == SYS_DEV_VMD ? "domain" : "RAID controller"); -+ hba->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ? -+ "domain" : "RAID controller"); - - while (hba) { - fprintf(stderr, "%s", hba->pci_id ? : "Err!"); -@@ -11274,7 +11282,7 @@ static const char *imsm_get_disk_controller_domain(const char *path) - hba = find_disk_attached_hba(-1, path); - if (hba && hba->type == SYS_DEV_SAS) - drv = "isci"; -- else if (hba && hba->type == SYS_DEV_SATA) -+ else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD)) - drv = "ahci"; - else if (hba && hba->type == SYS_DEV_VMD) - drv = "vmd"; --- -2.38.1 - diff --git a/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch b/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch deleted file mode 100644 index 1719f33..0000000 --- a/SOURCES/0126-imsm-Fix-possible-segfault-in-check_no_platform.patch +++ /dev/null @@ -1,33 +0,0 @@ -From cf1577bf54afe76b77ecaa62df25901739ca8ae9 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 5 Jul 2023 16:34:56 +0200 -Subject: [PATCH 126/165] imsm: Fix possible segfault in check_no_platform() - -conf_line() may return NULL, which is not handled and might cause -segfault. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - super-intel.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/super-intel.c b/super-intel.c -index ae0f4a8c..4ef33d31 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -650,6 +650,11 @@ static int check_no_platform(void) - char *l = conf_line(fp); - char *w = l; - -+ if (l == NULL) { -+ fclose(fp); -+ return 0; -+ } -+ - do { - if (strcmp(w, search) == 0) - no_platform = 1; --- -2.40.1 - diff --git a/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch b/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch deleted file mode 100644 index c5bc8fc..0000000 --- a/SOURCES/0127-imsm-move-sum_extents-calculations-to-merge_extents.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 9bc426fa1f236b8cad518431574a54fc60718739 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:33 +0200 -Subject: [PATCH 127/165] imsm: move sum_extents calculations to - merge_extents() - -This logic is only used by merge_extents() code, there is no need to pass -it as parameter. Move it up. Add proper description. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 37 +++++++++++++++++++------------------ - 1 file changed, 19 insertions(+), 18 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 4ef33d31..26b20313 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6882,21 +6882,31 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents) - return end - base_start; - } - --static unsigned long long merge_extents(struct intel_super *super, int sum_extents) -+/** merge_extents() - analyze extents and get max common free size. -+ * @super: Intel metadata, not NULL. -+ * -+ * Build a composite disk with all known extents and generate a new maxsize -+ * given the "all disks in an array must share a common start offset" -+ * constraint. -+ * -+ * Return: Max free space or 0 on failure. -+ */ -+static unsigned long long merge_extents(struct intel_super *super) - { -- /* build a composite disk with all known extents and generate a new -- * 'maxsize' given the "all disks in an array must share a common start -- * offset" constraint -- */ -- struct extent *e = xcalloc(sum_extents, sizeof(*e)); -+ struct extent *e; - struct dl *dl; - int i, j; -- int start_extent; -+ int start_extent, sum_extents = 0; - unsigned long long pos; - unsigned long long start = 0; - unsigned long long maxsize; - unsigned long reserve; - -+ for (dl = super->disks; dl; dl = dl->next) -+ if (dl->e) -+ sum_extents += dl->extent_cnt; -+ e = xcalloc(sum_extents, sizeof(struct extent)); -+ - /* coalesce and sort all extents. also, check to see if we need to - * reserve space between member arrays - */ -@@ -7555,13 +7565,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 0; - } - -- /* count total number of extents for merge */ -- i = 0; -- for (dl = super->disks; dl; dl = dl->next) -- if (dl->e) -- i += dl->extent_cnt; -- -- maxsize = merge_extents(super, i); -+ maxsize = merge_extents(super); - - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -@@ -7615,7 +7619,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - struct imsm_super *mpb = super->anchor; - struct dl *dl; - int i; -- int extent_cnt; - struct extent *e; - unsigned long long maxsize; - unsigned long long minsize; -@@ -7624,7 +7627,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - - /* find the largest common start free region of the possible disks */ - used = 0; -- extent_cnt = 0; - cnt = 0; - for (dl = super->disks; dl; dl = dl->next) { - dl->raiddisk = -1; -@@ -7645,11 +7647,10 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - ; - dl->e = e; - dl->extent_cnt = i; -- extent_cnt += i; - cnt++; - } - -- maxsize = merge_extents(super, extent_cnt); -+ maxsize = merge_extents(super); - minsize = size; - if (size == 0) - /* chunk is in K */ --- -2.40.1 - diff --git a/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch b/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch deleted file mode 100644 index ed43855..0000000 --- a/SOURCES/0128-imsm-imsm_get_free_size-refactor.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 5f027b9357c011ca0421400e258a777d97f18d17 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:34 +0200 -Subject: [PATCH 128/165] imsm: imsm_get_free_size() refactor. - -Move minsize calculations up. Add error message if free size is too small. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 27 ++++++++++++++------------- - 1 file changed, 14 insertions(+), 13 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 26b20313..16a30ba7 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7600,7 +7600,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - * @super: &intel_super pointer, not NULL. - * @raiddisks: number of raid disks. - * @size: requested size, could be 0 (means max size). -- * @chunk: requested chunk. -+ * @chunk: requested chunk size in KiB. - * @freesize: pointer for returned size value. - * - * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR. -@@ -7620,14 +7620,15 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - struct dl *dl; - int i; - struct extent *e; -+ int cnt = 0; -+ int used = 0; - unsigned long long maxsize; -- unsigned long long minsize; -- int cnt; -- int used; -+ unsigned long long minsize = size; -+ -+ if (minsize == 0) -+ minsize = chunk * 2; - - /* find the largest common start free region of the possible disks */ -- used = 0; -- cnt = 0; - for (dl = super->disks; dl; dl = dl->next) { - dl->raiddisk = -1; - -@@ -7651,14 +7652,14 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - } - - maxsize = merge_extents(super); -- minsize = size; -- if (size == 0) -- /* chunk is in K */ -- minsize = chunk * 2; -+ if (maxsize < minsize) { -+ pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n", -+ maxsize, minsize); -+ return IMSM_STATUS_ERROR; -+ } - -- if (cnt < raiddisks || (super->orom && used && used != raiddisks) || -- maxsize < minsize || maxsize == 0) { -- pr_err("not enough devices with space to create array.\n"); -+ if (cnt < raiddisks || (super->orom && used && used != raiddisks)) { -+ pr_err("imsm: Not enough devices with space to create array.\n"); - return IMSM_STATUS_ERROR; - } - --- -2.40.1 - diff --git a/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch b/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch deleted file mode 100644 index 50d1d36..0000000 --- a/SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 78c8028b331c8e281554d43fde4d46e9cb4a227e Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:35 +0200 -Subject: [PATCH 129/165] imsm: introduce round_member_size_to_mb() - -Extract rounding logic to separate function. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 31 +++++++++++++++++++++---------- - 1 file changed, 21 insertions(+), 10 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 16a30ba7..36171107 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -1644,17 +1644,29 @@ static int is_journal(struct imsm_disk *disk) - return (disk->status & JOURNAL_DISK) == JOURNAL_DISK; - } - --/* round array size down to closest MB and ensure it splits evenly -- * between members -+/** -+ * round_member_size_to_mb()- Round given size to closest MiB. -+ * @size: size to round in sectors. - */ --static unsigned long long round_size_to_mb(unsigned long long size, unsigned int -- disk_count) -+static inline unsigned long long round_member_size_to_mb(unsigned long long size) - { -- size /= disk_count; -- size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; -- size *= disk_count; -+ return (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT; -+} - -- return size; -+/** -+ * round_size_to_mb()- Round given size. -+ * @array_size: size to round in sectors. -+ * @disk_count: count of data members. -+ * -+ * Get size per each data member and round it to closest MiB to ensure that data -+ * splits evenly between members. -+ * -+ * Return: Array size, rounded down. -+ */ -+static inline unsigned long long round_size_to_mb(unsigned long long array_size, -+ unsigned int disk_count) -+{ -+ return round_member_size_to_mb(array_size / disk_count) * disk_count; - } - - static int able_to_resync(int raid_level, int missing_disks) -@@ -11810,8 +11822,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - } else { - /* round size due to metadata compatibility - */ -- geo->size = (geo->size >> SECT_PER_MB_SHIFT) -- << SECT_PER_MB_SHIFT; -+ geo->size = round_member_size_to_mb(geo->size); - dprintf("Prepare update for size change to %llu\n", - geo->size ); - if (current_size >= geo->size) { --- -2.40.1 - diff --git a/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch b/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch deleted file mode 100644 index 6e5359e..0000000 --- a/SOURCES/0130-imsm-move-expand-verification-code-into-new-function.patch +++ /dev/null @@ -1,238 +0,0 @@ -From cbaa7904a175628a294ed54b4de6c52afa4f830d Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:36 +0200 -Subject: [PATCH 130/165] imsm: move expand verification code into new function - -The code here is too complex. Move it to separate function and -simplify it. Add more error messages. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 187 +++++++++++++++++++++++++++----------------------- - 1 file changed, 101 insertions(+), 86 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 36171107..5bd70356 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -11643,6 +11643,102 @@ static void imsm_update_metadata_locally(struct supertype *st, - } - } - -+/** -+ * imsm_analyze_expand() - check expand properties and calculate new size. -+ * @st: imsm supertype. -+ * @geo: new geometry params. -+ * @array: array info. -+ * @direction: reshape direction. -+ * -+ * Obtain free space after the &array and verify if expand to requested size is -+ * possible. If geo->size is set to %MAX_SIZE, assume that max free size is -+ * requested. -+ * -+ * Return: -+ * On success %IMSM_STATUS_OK is returned, geo->size and geo->raid_disks are -+ * updated. -+ * On error, %IMSM_STATUS_ERROR is returned. -+ */ -+static imsm_status_t imsm_analyze_expand(struct supertype *st, -+ struct geo_params *geo, -+ struct mdinfo *array, -+ int direction) -+{ -+ struct intel_super *super = st->sb; -+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol); -+ struct imsm_map *map = get_imsm_map(dev, MAP_0); -+ int data_disks = imsm_num_data_members(map); -+ -+ unsigned long long current_size; -+ unsigned long long free_size; -+ unsigned long long new_size; -+ unsigned long long max_size; -+ -+ const int chunk_kib = geo->chunksize / 1024; -+ imsm_status_t rv; -+ -+ if (direction == ROLLBACK_METADATA_CHANGES) { -+ /** -+ * Accept size for rollback only. -+ */ -+ new_size = geo->size * 2; -+ goto success; -+ } -+ -+ if (super->current_vol + 1 != super->anchor->num_raid_devs) { -+ pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n", -+ super->current_vol, st->devnm); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (data_disks == 0) { -+ pr_err("imsm: Cannot retrieve data disks.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ current_size = array->custom_array_size / data_disks; -+ -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size); -+ if (rv != IMSM_STATUS_OK) { -+ pr_err("imsm: Cannot find free space for expand.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ max_size = round_member_size_to_mb(free_size + current_size); -+ -+ if (geo->size == MAX_SIZE) -+ new_size = max_size; -+ else -+ new_size = round_member_size_to_mb(geo->size * 2); -+ -+ if (new_size == 0) { -+ pr_err("imsm: Rounded requested size is 0.\n"); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size > max_size) { -+ pr_err("imsm: Rounded requested size (%llu) is larger than free space available (%llu).\n", -+ new_size, max_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size == current_size) { -+ pr_err("imsm: Rounded requested size (%llu) is same as current size (%llu).\n", -+ new_size, current_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+ if (new_size < current_size) { -+ pr_err("imsm: Size reduction is not supported, rounded requested size (%llu) is smaller than current (%llu).\n", -+ new_size, current_size); -+ return IMSM_STATUS_ERROR; -+ } -+ -+success: -+ dprintf("imsm: New size per member is %llu.\n", new_size); -+ geo->size = data_disks * new_size; -+ geo->raid_disks = dev->vol.map->num_members; -+ return IMSM_STATUS_OK; -+} -+ - /*************************************************************************** - * Function: imsm_analyze_change - * Description: Function analyze change for single volume -@@ -11663,13 +11759,6 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - int devNumChange = 0; - /* imsm compatible layout value for array geometry verification */ - int imsm_layout = -1; -- int data_disks; -- struct imsm_dev *dev; -- struct imsm_map *map; -- struct intel_super *super; -- unsigned long long current_size; -- unsigned long long free_size; -- unsigned long long max_size; - imsm_status_t rv; - - getinfo_super_imsm_volume(st, &info, NULL); -@@ -11752,94 +11841,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, - geo->chunksize = info.array.chunk_size; - } - -- chunk = geo->chunksize / 1024; -- -- super = st->sb; -- dev = get_imsm_dev(super, super->current_vol); -- map = get_imsm_map(dev, MAP_0); -- data_disks = imsm_num_data_members(map); -- /* compute current size per disk member -- */ -- current_size = info.custom_array_size / data_disks; -- -- if (geo->size > 0 && geo->size != MAX_SIZE) { -- /* align component size -- */ -- geo->size = imsm_component_size_alignment_check( -- get_imsm_raid_level(dev->vol.map), -- chunk * 1024, super->sector_size, -- geo->size * 2); -- if (geo->size == 0) { -- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is 0).\n", -- current_size); -- goto analyse_change_exit; -- } -- } -- -- if (current_size != geo->size && geo->size > 0) { -+ if (geo->size > 0) { - if (change != -1) { - pr_err("Error. Size change should be the only one at a time.\n"); - change = -1; - goto analyse_change_exit; - } -- if ((super->current_vol + 1) != super->anchor->num_raid_devs) { -- pr_err("Error. The last volume in container can be expanded only (%i/%s).\n", -- super->current_vol, st->devnm); -- goto analyse_change_exit; -- } -- /* check the maximum available size -- */ -- rv = imsm_get_free_size(super, dev->vol.map->num_members, -- 0, chunk, &free_size); - -+ rv = imsm_analyze_expand(st, geo, &info, direction); - if (rv != IMSM_STATUS_OK) -- /* Cannot find maximum available space -- */ -- max_size = 0; -- else { -- max_size = free_size + current_size; -- /* align component size -- */ -- max_size = imsm_component_size_alignment_check( -- get_imsm_raid_level(dev->vol.map), -- chunk * 1024, super->sector_size, -- max_size); -- } -- if (geo->size == MAX_SIZE) { -- /* requested size change to the maximum available size -- */ -- if (max_size == 0) { -- pr_err("Error. Cannot find maximum available space.\n"); -- change = -1; -- goto analyse_change_exit; -- } else -- geo->size = max_size; -- } -- -- if (direction == ROLLBACK_METADATA_CHANGES) { -- /* accept size for rollback only -- */ -- } else { -- /* round size due to metadata compatibility -- */ -- geo->size = round_member_size_to_mb(geo->size); -- dprintf("Prepare update for size change to %llu\n", -- geo->size ); -- if (current_size >= geo->size) { -- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is %llu).\n", -- current_size, geo->size); -- goto analyse_change_exit; -- } -- if (max_size && geo->size > max_size) { -- pr_err("Error. Requested size is larger than maximum available size (maximum available size is %llu, requested size /rounded/ is %llu).\n", -- max_size, geo->size); -- goto analyse_change_exit; -- } -- } -- geo->size *= data_disks; -- geo->raid_disks = dev->vol.map->num_members; -+ goto analyse_change_exit; - change = CH_ARRAY_SIZE; - } -+ -+ chunk = geo->chunksize / 1024; - if (!validate_geometry_imsm(st, - geo->level, - imsm_layout, --- -2.40.1 - diff --git a/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch b/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch deleted file mode 100644 index 10faec5..0000000 --- a/SOURCES/0131-imsm-return-free-space-after-volume-for-expand.patch +++ /dev/null @@ -1,214 +0,0 @@ -From aa19fdd45b2ba474f6a51a6d4b8f3c44ef19dafd Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:37 +0200 -Subject: [PATCH 131/165] imsm: return free space after volume for expand - -merge_extends() routine searches for the biggest free space. For expand, -it works only in standard cases where the last volume is expanded and -the free space is determined after the last volume. -Add volume index to extent struct and use that do determine size after -super->current_vol during expand. - -Limitation to last volume is no longer needed. It unblocks scenarios -where kill-subarray is used to remove first volume and later it is -recreated (now it is the second volume, even if it is placed before -existing one). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 71 +++++++++++++++++++++++++++------------------------ - 1 file changed, 37 insertions(+), 34 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index 5bd70356..e249d925 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -499,8 +499,15 @@ struct intel_disk { - struct intel_disk *next; - }; - -+/** -+ * struct extent - reserved space details. -+ * @start: start offset. -+ * @size: size of reservation, set to 0 for metadata reservation. -+ * @vol: index of the volume, meaningful if &size is set. -+ */ - struct extent { - unsigned long long start, size; -+ int vol; - }; - - /* definitions of reshape process types */ -@@ -1539,9 +1546,10 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - int get_minimal_reservation) - { - /* find a list of used extents on the given physical device */ -- struct extent *rv, *e; -- int i; - int memberships = count_memberships(dl, super); -+ struct extent *rv = xcalloc(memberships + 1, sizeof(struct extent)); -+ struct extent *e = rv; -+ int i; - __u32 reservation; - - /* trim the reserved area for spares, so they can join any array -@@ -1553,9 +1561,6 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - else - reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS; - -- rv = xcalloc(sizeof(struct extent), (memberships + 1)); -- e = rv; -- - for (i = 0; i < super->anchor->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); - struct imsm_map *map = get_imsm_map(dev, MAP_0); -@@ -1563,6 +1568,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl, - if (get_imsm_disk_slot(map, dl->index) >= 0) { - e->start = pba_of_lba0(map); - e->size = per_dev_array_size(map); -+ e->vol = i; - e++; - } - } -@@ -6894,24 +6900,26 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents) - return end - base_start; - } - --/** merge_extents() - analyze extents and get max common free size. -+/** merge_extents() - analyze extents and get free size. - * @super: Intel metadata, not NULL. -+ * @expanding: if set, we are expanding &super->current_vol. - * -- * Build a composite disk with all known extents and generate a new maxsize -- * given the "all disks in an array must share a common start offset" -- * constraint. -+ * Build a composite disk with all known extents and generate a size given the -+ * "all disks in an array must share a common start offset" constraint. -+ * If a volume is expanded, then return free space after the volume. - * -- * Return: Max free space or 0 on failure. -+ * Return: Free space or 0 on failure. - */ --static unsigned long long merge_extents(struct intel_super *super) -+static unsigned long long merge_extents(struct intel_super *super, const bool expanding) - { - struct extent *e; - struct dl *dl; -- int i, j; -- int start_extent, sum_extents = 0; -- unsigned long long pos; -+ int i, j, pos_vol_idx = -1; -+ int extent_idx = 0; -+ int sum_extents = 0; -+ unsigned long long pos = 0; - unsigned long long start = 0; -- unsigned long long maxsize; -+ unsigned long long maxsize = 0; - unsigned long reserve; - - for (dl = super->disks; dl; dl = dl->next) -@@ -6936,26 +6944,26 @@ static unsigned long long merge_extents(struct intel_super *super) - j = 0; - while (i < sum_extents) { - e[j].start = e[i].start; -+ e[j].vol = e[i].vol; - e[j].size = find_size(e, &i, sum_extents); - j++; - if (e[j-1].size == 0) - break; - } - -- pos = 0; -- maxsize = 0; -- start_extent = 0; - i = 0; - do { -- unsigned long long esize; -+ unsigned long long esize = e[i].start - pos; - -- esize = e[i].start - pos; -- if (esize >= maxsize) { -+ if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) { - maxsize = esize; - start = pos; -- start_extent = i; -+ extent_idx = i; - } -+ - pos = e[i].start + e[i].size; -+ pos_vol_idx = e[i].vol; -+ - i++; - } while (e[i-1].size); - free(e); -@@ -6966,7 +6974,7 @@ static unsigned long long merge_extents(struct intel_super *super) - /* FIXME assumes volume at offset 0 is the first volume in a - * container - */ -- if (start_extent > 0) -+ if (extent_idx > 0) - reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */ - else - reserve = 0; -@@ -7577,7 +7585,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, - return 0; - } - -- maxsize = merge_extents(super); -+ maxsize = merge_extents(super, false); - - if (mpb->num_raid_devs > 0 && size && size != maxsize) - pr_err("attempting to create a second volume with size less then remaining space.\n"); -@@ -7626,7 +7634,8 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - const int raiddisks, - unsigned long long size, - const int chunk, -- unsigned long long *freesize) -+ unsigned long long *freesize, -+ bool expanding) - { - struct imsm_super *mpb = super->anchor; - struct dl *dl; -@@ -7663,7 +7672,7 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super, - cnt++; - } - -- maxsize = merge_extents(super); -+ maxsize = merge_extents(super, expanding); - if (maxsize < minsize) { - pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n", - maxsize, minsize); -@@ -7721,7 +7730,7 @@ static imsm_status_t autolayout_imsm(struct intel_super *super, - int vol_cnt = super->anchor->num_raid_devs; - imsm_status_t rv; - -- rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize); -+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize, false); - if (rv != IMSM_STATUS_OK) - return IMSM_STATUS_ERROR; - -@@ -11685,19 +11694,13 @@ static imsm_status_t imsm_analyze_expand(struct supertype *st, - goto success; - } - -- if (super->current_vol + 1 != super->anchor->num_raid_devs) { -- pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n", -- super->current_vol, st->devnm); -- return IMSM_STATUS_ERROR; -- } -- - if (data_disks == 0) { - pr_err("imsm: Cannot retrieve data disks.\n"); - return IMSM_STATUS_ERROR; - } - current_size = array->custom_array_size / data_disks; - -- rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size); -+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size, true); - if (rv != IMSM_STATUS_OK) { - pr_err("imsm: Cannot find free space for expand.\n"); - return IMSM_STATUS_ERROR; --- -2.40.1 - diff --git a/SOURCES/0132-imsm-fix-free-space-calculations.patch b/SOURCES/0132-imsm-fix-free-space-calculations.patch deleted file mode 100644 index fe3025f..0000000 --- a/SOURCES/0132-imsm-fix-free-space-calculations.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 1dea84ae38288fbefa04d9fda2b3f36c21a9e1bd Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 29 May 2023 15:52:38 +0200 -Subject: [PATCH 132/165] imsm: fix free space calculations - -Between two volumes or between last volume and metadata at least -IMSM_RESERVED_SECTORS gap must exist. Currently the gap can be doubled -because metadata reservation contains IMSM_RESERVED_SECTORS too. - -Divide reserve variable into pre_reservation and post_reservation to be -more flexible and decide separately if each reservation is needed. - -Pre_reservation is needed only when a volume is created and it is not a -real first volume in a container (we can check that by extent_idx). -This type of reservation is not needed for expand. - -Post_reservation is not needed only if real last volume is created or -expanded because reservation is done with the metadata. - -The volume index in metadata cannot be trusted, because the real volume -order can be reversed. It is safer to use extent table, it is sorted by -start position. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-intel.c | 50 ++++++++++++++++++++++++++++++-------------------- - 1 file changed, 30 insertions(+), 20 deletions(-) - -diff --git a/super-intel.c b/super-intel.c -index e249d925..824c1356 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -6919,8 +6919,11 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - int sum_extents = 0; - unsigned long long pos = 0; - unsigned long long start = 0; -- unsigned long long maxsize = 0; -- unsigned long reserve; -+ unsigned long long free_size = 0; -+ -+ unsigned long pre_reservation = 0; -+ unsigned long post_reservation = IMSM_RESERVED_SECTORS; -+ unsigned long reservation_size; - - for (dl = super->disks; dl; dl = dl->next) - if (dl->e) -@@ -6955,8 +6958,8 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - do { - unsigned long long esize = e[i].start - pos; - -- if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) { -- maxsize = esize; -+ if (expanding ? pos_vol_idx == super->current_vol : esize >= free_size) { -+ free_size = esize; - start = pos; - extent_idx = i; - } -@@ -6966,28 +6969,35 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex - - i++; - } while (e[i-1].size); -- free(e); - -- if (maxsize == 0) -+ if (free_size == 0) { -+ dprintf("imsm: Cannot find free size.\n"); -+ free(e); - return 0; -+ } - -- /* FIXME assumes volume at offset 0 is the first volume in a -- * container -- */ -- if (extent_idx > 0) -- reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */ -- else -- reserve = 0; -+ if (!expanding && extent_idx != 0) -+ /* -+ * Not a real first volume in a container is created, pre_reservation is needed. -+ */ -+ pre_reservation = IMSM_RESERVED_SECTORS; - -- if (maxsize < reserve) -- return 0; -+ if (e[extent_idx].size == 0) -+ /* -+ * extent_idx points to the metadata, post_reservation is allready done. -+ */ -+ post_reservation = 0; -+ free(e); - -- super->create_offset = ~((unsigned long long) 0); -- if (start + reserve > super->create_offset) -- return 0; /* start overflows create_offset */ -- super->create_offset = start + reserve; -+ reservation_size = pre_reservation + post_reservation; -+ -+ if (free_size < reservation_size) { -+ dprintf("imsm: Reservation size is greater than free space.\n"); -+ return 0; -+ } - -- return maxsize - reserve; -+ super->create_offset = start + pre_reservation; -+ return free_size - reservation_size; - } - - static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks) --- -2.40.1 - diff --git a/SOURCES/0133-Add-secure-gethostname-wrapper.patch b/SOURCES/0133-Add-secure-gethostname-wrapper.patch deleted file mode 100644 index 19f6c36..0000000 --- a/SOURCES/0133-Add-secure-gethostname-wrapper.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 21e622f214a38c048c5689158bc6314a91a46e40 Mon Sep 17 00:00:00 2001 -From: Blazej Kucman -Date: Fri, 16 Jun 2023 21:45:55 +0200 -Subject: [PATCH 133/165] Add secure gethostname() wrapper - -gethostname() func does not ensure null-terminated string -if hostname is longer than buffer length. -For security, a function s_gethostname() has been added -to ensure that "\0" is added to the end of the buffer. -Previously this had to be handled in each place -of the gethostname() call. - -Signed-off-by: Blazej Kucman -Signed-off-by: Jes Sorensen ---- - Monitor.c | 3 +-- - lib.c | 19 +++++++++++++++++++ - mapfile.c | 3 +-- - mdadm.c | 3 +-- - mdadm.h | 1 + - super-ddf.c | 3 +-- - 6 files changed, 24 insertions(+), 8 deletions(-) - -diff --git a/Monitor.c b/Monitor.c -index 66175968..e74a0558 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -222,11 +222,10 @@ int Monitor(struct mddev_dev *devlist, - info.dosyslog = dosyslog; - info.test = c->test; - -- if (gethostname(info.hostname, sizeof(info.hostname)) != 0) { -+ if (s_gethostname(info.hostname, sizeof(info.hostname)) != 0) { - pr_err("Cannot get hostname.\n"); - return 1; - } -- info.hostname[sizeof(info.hostname) - 1] = '\0'; - - if (share){ - if (check_one_sharer(c->scan) == 2) -diff --git a/lib.c b/lib.c -index fe5c8d2c..8a4b48e0 100644 ---- a/lib.c -+++ b/lib.c -@@ -585,3 +585,22 @@ int parse_num(int *dest, const char *num) - *dest = temp; - return 0; - } -+ -+/** -+ * s_gethostname() - secure get hostname. Assure null-terminated string. -+ * -+ * @buf: buffer for hostname. -+ * @buf_len: buffer length. -+ * -+ * Return: gethostname() result. -+ */ -+int s_gethostname(char *buf, int buf_len) -+{ -+ assert(buf); -+ -+ int ret = gethostname(buf, buf_len); -+ -+ buf[buf_len - 1] = 0; -+ -+ return ret; -+} -diff --git a/mapfile.c b/mapfile.c -index 34fea179..f1f3ee2c 100644 ---- a/mapfile.c -+++ b/mapfile.c -@@ -363,8 +363,7 @@ void RebuildMap(void) - char *homehost = conf_get_homehost(&require_homehost); - - if (homehost == NULL || strcmp(homehost, "")==0) { -- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { -- sys_hostname[sizeof(sys_hostname)-1] = 0; -+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { - homehost = sys_hostname; - } - } -diff --git a/mdadm.c b/mdadm.c -index 076b45e0..e32598cb 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1340,8 +1340,7 @@ int main(int argc, char *argv[]) - if (c.homehost == NULL && c.require_homehost) - c.homehost = conf_get_homehost(&c.require_homehost); - if (c.homehost == NULL || strcasecmp(c.homehost, "") == 0) { -- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { -- sys_hostname[sizeof(sys_hostname)-1] = 0; -+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { - c.homehost = sys_hostname; - } - } -diff --git a/mdadm.h b/mdadm.h -index 83f2cf7f..f0ceeb78 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1805,6 +1805,7 @@ extern void set_dlm_hooks(void); - extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt); - extern bool is_directory(const char *path); - extern bool is_file(const char *path); -+extern int s_gethostname(char *buf, int buf_len); - - #define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1)) - #define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base)) -diff --git a/super-ddf.c b/super-ddf.c -index 7213284e..c5242654 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -2364,8 +2364,7 @@ static int init_super_ddf(struct supertype *st, - * Remaining 16 are serial number.... maybe a hostname would do? - */ - memcpy(ddf->controller.guid, T10, sizeof(T10)); -- gethostname(hostname, sizeof(hostname)); -- hostname[sizeof(hostname) - 1] = 0; -+ s_gethostname(hostname, sizeof(hostname)); - hostlen = strlen(hostname); - memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen); - for (i = strlen(T10) ; i+hostlen < 24; i++) --- -2.40.1 - diff --git a/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch b/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch deleted file mode 100644 index abe9ef6..0000000 --- a/SOURCES/0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1ab341e5ce0cb01a1533a2c36e5b69eabf12bf95 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 25 Aug 2023 20:55:41 +0800 -Subject: [PATCH 134/165] mdadm: Stop mdcheck_continue timer when mdcheck_start - service can finish check - -mdcheck_continue is triggered by mdcheck_start timer. It's used to -continue check action if the raid is too big and mdcheck_start -service can't finish check action. If mdcheck start can finish check -action, it doesn't need to mdcheck continue service anymore. So stop -it when mdcheck start service can finish check action. - -Signed-off-by: Xiao Ni -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - misc/mdcheck | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/misc/mdcheck b/misc/mdcheck -index 700c3e25..f87999d3 100644 ---- a/misc/mdcheck -+++ b/misc/mdcheck -@@ -140,7 +140,13 @@ do - echo $a > $fl - any=yes - done -- if [ -z "$any" ]; then exit 0; fi -+ # mdcheck_continue.timer is started by mdcheck_start.timer. -+ # When the check action can be finished in mdcheck_start.service, -+ # it doesn't need mdcheck_continue anymore. -+ if [ -z "$any" ]; then -+ systemctl stop mdcheck_continue.timer -+ exit 0; -+ fi - sleep 120 - done - --- -2.40.1 - diff --git a/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch b/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch deleted file mode 100644 index d7399c9..0000000 --- a/SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e9fb93af0f769d147a13e86ab4e5d0aeb935e9fc Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:34 +0800 -Subject: [PATCH 135/165] Fix memory leak in file Assemble - -When we test mdadm with asan, we found some memory leaks in Assemble.c -We fix these memory leaks based on code logic. - -v2: Set st = NULL before jumping to loop - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Assemble.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 49804941..61e8cd17 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -341,8 +341,10 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -- if (tst) -+ if (tst) { - tst->ss->free_super(tst); -+ free(tst); -+ } - return -1; - } - -@@ -417,6 +419,7 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -+ free(st); - return -1; - } - if (c->verbose > 0) -@@ -425,6 +428,8 @@ static int select_devices(struct mddev_dev *devlist, - - /* make sure we finished the loop */ - tmpdev = NULL; -+ free(st); -+ st = NULL; - goto loop; - } else { - content = *contentp; -@@ -533,6 +538,7 @@ static int select_devices(struct mddev_dev *devlist, - st->ss->free_super(st); - dev_policy_free(pol); - domain_free(domains); -+ free(tst); - return -1; - } - tmpdev->used = 1; -@@ -546,8 +552,10 @@ static int select_devices(struct mddev_dev *devlist, - } - dev_policy_free(pol); - pol = NULL; -- if (tst) -+ if (tst) { - tst->ss->free_super(tst); -+ free(tst); -+ } - } - - /* Check if we found some imsm spares but no members */ -@@ -839,6 +847,7 @@ static int load_devices(struct devs *devices, char *devmap, - close(mdfd); - free(devices); - free(devmap); -+ free(best); - *stp = st; - return -1; - } -@@ -1950,6 +1959,7 @@ out: - } else if (mdfd >= 0) - close(mdfd); - -+ free(best); - /* '2' means 'OK, but not started yet' */ - if (rv == -1) { - free(devices); --- -2.40.1 - diff --git a/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch b/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch deleted file mode 100644 index d4b1a83..0000000 --- a/SOURCES/0136-Fix-memory-leak-in-file-Kill.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8fd0c565b09ba449418d7d604ceba66313246152 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:35 +0800 -Subject: [PATCH 136/165] Fix memory leak in file Kill - -When we test mdadm with asan, we found some memory leaks in Kill.c -We fix these memory leaks based on code logic. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Kill.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/Kill.c b/Kill.c -index bfd0efdc..43c9abed 100644 ---- a/Kill.c -+++ b/Kill.c -@@ -41,6 +41,7 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - * 4 - failed to find a superblock. - */ - -+ bool free_super = false; - int fd, rv = 0; - - if (force) -@@ -52,8 +53,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - dev); - return 2; - } -- if (st == NULL) -+ if (st == NULL) { - st = guess_super(fd); -+ free_super = true; -+ } - if (st == NULL || st->ss->init_super == NULL) { - if (verbose >= 0) - pr_err("Unrecognised md component device - %s\n", dev); -@@ -77,6 +80,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl) - rv = 0; - } - } -+ if (free_super && st) { -+ st->ss->free_super(st); -+ free(st); -+ } - close(fd); - return rv; - } --- -2.40.1 - diff --git a/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch b/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch deleted file mode 100644 index 214c0e2..0000000 --- a/SOURCES/0137-Fix-memory-leak-in-file-Manage.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f6feb3fbb50f48c193e9e4d775a20aa20f7b47b3 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:36 +0800 -Subject: [PATCH 137/165] Fix memory leak in file Manage - -When we test mdadm with asan, we found some memory leaks in Manage.c -We fix these memory leaks based on code logic. - -v2: Fix free() of uninitialized 'tst' in abort path. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Manage.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/Manage.c b/Manage.c -index f54de7c6..f997b163 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) - if (verbose >= 0) - pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n", - devname); -+ sysfs_free(mdi); - return 1; - } - /* If this is an mdmon managed array, just write 'inactive' -@@ -801,8 +802,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - rdev, update, devname, - verbose, array); - dev_st->ss->free_super(dev_st); -- if (rv) -+ if (rv) { -+ free(dev_st); - return rv; -+ } -+ } -+ if (dev_st) { -+ dev_st->ss->free_super(dev_st); -+ free(dev_st); - } - } - if (dv->disposition == 'M') { -@@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd, - unsigned long long array_size; - struct mddev_dev *dv; - int tfd = -1; -- struct supertype *tst; -+ struct supertype *tst = NULL; - char *subarray = NULL; - int sysfd = -1; - int count = 0; /* number of actions taken */ -@@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd, - break; - } - } -+ free(tst); - if (frozen > 0) - sysfs_set_str(&info, NULL, "sync_action","idle"); - if (test && count == 0) -@@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd, - return 0; - - abort: -+ free(tst); - if (frozen > 0) - sysfs_set_str(&info, NULL, "sync_action","idle"); - return !test && busy ? 2 : 1; --- -2.40.1 - diff --git a/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch b/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch deleted file mode 100644 index 2cb9f7f..0000000 --- a/SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e62a561ee8b7157a2390eab215dcef6240bd7b03 Mon Sep 17 00:00:00 2001 -From: Guanqin Miao -Date: Mon, 24 Apr 2023 16:06:37 +0800 -Subject: [PATCH 138/165] Fix memory leak in file mdadm - -When we test mdadm with asan, we found some memory leaks in mdadm.c -We fix these memory leaks based on code logic. - -Signed-off-by: Guanqin Miao -Signed-off-by: Li Xiao Keng -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - mdadm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/mdadm.c b/mdadm.c -index e32598cb..22d1c53b 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1708,6 +1708,10 @@ int main(int argc, char *argv[]) - autodetect(); - break; - } -+ if (ss) { -+ ss->ss->free_super(ss); -+ free(ss); -+ } - if (locked) - cluster_release_dlmlock(); - close_fd(&mdfd); --- -2.40.1 - diff --git a/SOURCES/0139-Fix-unsafe-string-functions.patch b/SOURCES/0139-Fix-unsafe-string-functions.patch deleted file mode 100644 index 955b1bb..0000000 --- a/SOURCES/0139-Fix-unsafe-string-functions.patch +++ /dev/null @@ -1,116 +0,0 @@ -From dd5ab40204b1d78ec3bdbcfd5a38a8ffb72bdb50 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 11 May 2023 04:55:12 +0200 -Subject: [PATCH 139/165] Fix unsafe string functions - -Add string length limitations where necessary to -avoid buffer overflows. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - mdmon.c | 6 +++--- - mdopen.c | 4 ++-- - platform-intel.c | 2 +- - super-intel.c | 6 +++--- - 4 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/mdmon.c b/mdmon.c -index cef5bbc8..a2038fe6 100644 ---- a/mdmon.c -+++ b/mdmon.c -@@ -240,7 +240,7 @@ static int make_control_sock(char *devname) - return -1; - - addr.sun_family = PF_LOCAL; -- strcpy(addr.sun_path, path); -+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - umask(077); /* ensure no world write access */ - if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - close(sfd); -@@ -389,7 +389,7 @@ int main(int argc, char *argv[]) - - if (all) { - struct mdstat_ent *mdstat, *e; -- int container_len = strlen(container_name); -+ int container_len = strnlen(container_name, MD_NAME_MAX); - - /* launch an mdmon instance for each container found */ - mdstat = mdstat_read(0, 0); -@@ -472,7 +472,7 @@ static int mdmon(char *devnm, int must_fork, int takeover) - pfd[0] = pfd[1] = -1; - - container = xcalloc(1, sizeof(*container)); -- strcpy(container->devnm, devnm); -+ snprintf(container->devnm, MD_NAME_MAX, "%s", devnm); - container->arrays = NULL; - container->sock = -1; - -diff --git a/mdopen.c b/mdopen.c -index d3022a54..3daa71f9 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -193,14 +193,14 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - - if (dev) { - if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- strcpy(cname, dev + DEV_MD_DIR_LEN); -+ snprintf(cname, MD_NAME_MAX, "%s", dev + DEV_MD_DIR_LEN); - } else if (strncmp(dev, "/dev/", 5) == 0) { - char *e = dev + strlen(dev); - while (e > dev && isdigit(e[-1])) - e--; - if (e[0]) - num = strtoul(e, NULL, 10); -- strcpy(cname, dev+5); -+ snprintf(cname, MD_NAME_MAX, "%s", dev + 5); - cname[e-(dev+5)] = 0; - /* name *must* be mdXX or md_dXX in this context */ - if (num < 0 || -diff --git a/platform-intel.c b/platform-intel.c -index 914164c0..eb6e1b7e 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -214,7 +214,7 @@ struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path) - - static int devpath_to_ll(const char *dev_path, const char *entry, unsigned long long *val) - { -- char path[strlen(dev_path) + strlen(entry) + 2]; -+ char path[strnlen(dev_path, PATH_MAX) + strnlen(entry, PATH_MAX) + 2]; - int fd; - int n; - -diff --git a/super-intel.c b/super-intel.c -index 824c1356..ce813172 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -7043,7 +7043,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, - int fd = -1; - while (dev && !is_fd_valid(fd)) { - char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1); -- num = sprintf(path, "%s%s", "/dev/", dev->name); -+ num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name); - if (num > 0) - fd = open(path, O_RDONLY, 0); - if (num <= 0 || !is_fd_valid(fd)) { -@@ -7935,7 +7935,7 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id) - - if (i < current_vol) - continue; -- sprintf(subarray, "%u", i); -+ snprintf(subarray, sizeof(subarray), "%u", i); - if (is_subarray_active(subarray, st->devnm)) { - pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n", - current_vol, i); -@@ -11308,7 +11308,7 @@ static const char *imsm_get_disk_controller_domain(const char *path) - char *drv=NULL; - struct stat st; - -- strcpy(disk_path, disk_by_path); -+ strncpy(disk_path, disk_by_path, PATH_MAX); - strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1); - if (stat(disk_path, &st) == 0) { - struct sys_dev* hba; --- -2.40.1 - diff --git a/SOURCES/0140-platform-intel-limit-guid-length.patch b/SOURCES/0140-platform-intel-limit-guid-length.patch deleted file mode 100644 index 8ed03fa..0000000 --- a/SOURCES/0140-platform-intel-limit-guid-length.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5ccd457b29809bee442749b5f66ac27ebba4a72d Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Thu, 11 May 2023 04:55:13 +0200 -Subject: [PATCH 140/165] platform-intel: limit guid length - -Moving GUID_STR_MAX to header to use it as -a length limitation for snprintf function. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 3 --- - platform-intel.h | 5 ++++- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index eb6e1b7e..ef90c3fd 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -510,9 +510,6 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) - return get_orom_by_device_id(hba->dev_id); - } - --#define GUID_STR_MAX 37 /* according to GUID format: -- * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ -- - #define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ - ((struct efi_guid) \ - {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ -diff --git a/platform-intel.h b/platform-intel.h -index 2c0f4e39..ba97fb04 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -19,6 +19,9 @@ - #include - #include - -+/* according to GUID format: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ -+#define GUID_STR_MAX 37 -+ - /* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */ - struct imsm_orom { - __u8 signature[4]; -@@ -229,7 +232,7 @@ extern struct orom_entry *orom_entries; - - static inline char *guid_str(char *buf, struct efi_guid guid) - { -- sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", -+ snprintf(buf, GUID_STR_MAX, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - guid.b[3], guid.b[2], guid.b[1], guid.b[0], - guid.b[5], guid.b[4], guid.b[7], guid.b[6], - guid.b[8], guid.b[9], guid.b[10], guid.b[11], --- -2.40.1 - diff --git a/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch b/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch deleted file mode 100644 index be4cc37..0000000 --- a/SOURCES/0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 8d1114be8c0a307d251c24078833b029efabc448 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Wed, 5 Jul 2023 16:23:17 +0200 -Subject: [PATCH 141/165] imsm: Add reading vmd register for finding imsm - capability - -Currently mdadm does not find imsm capability when running inside VM. -This patch adds the possibility to read from vmd register and check for -capability, effectively allowing to use mdadm with imsm inside virtual machines. - -Additionally refactor find_imsm_capability() to make assignments in new -lines. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - platform-intel.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++- - platform-intel.h | 11 ++++- - super-intel.c | 11 +++-- - 3 files changed, 130 insertions(+), 6 deletions(-) - -diff --git a/platform-intel.c b/platform-intel.c -index ef90c3fd..ac282bc5 100644 ---- a/platform-intel.c -+++ b/platform-intel.c -@@ -700,6 +700,106 @@ const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba) - return &nvme_orom->orom; - } - -+#define VMD_REGISTER_OFFSET 0x3FC -+#define VMD_REGISTER_SKU_SHIFT 1 -+#define VMD_REGISTER_SKU_MASK (0x00000007) -+#define VMD_REGISTER_SKU_PREMIUM 2 -+#define MD_REGISTER_VER_MAJOR_SHIFT 4 -+#define MD_REGISTER_VER_MAJOR_MASK (0x0000000F) -+#define MD_REGISTER_VER_MINOR_SHIFT 8 -+#define MD_REGISTER_VER_MINOR_MASK (0x0000000F) -+ -+/* -+ * read_vmd_register() - Reads VMD register and writes contents to buff ptr -+ * @buff: buffer for vmd register data, should be the size of uint32_t -+ * -+ * Return: 0 on success, 1 on error -+ */ -+int read_vmd_register(uint32_t *buff, struct sys_dev *hba) -+{ -+ int fd; -+ char vmd_pci_config_path[PATH_MAX]; -+ -+ if (!vmd_domain_to_controller(hba, vmd_pci_config_path)) -+ return 1; -+ -+ strncat(vmd_pci_config_path, "/config", PATH_MAX - strnlen(vmd_pci_config_path, PATH_MAX)); -+ -+ fd = open(vmd_pci_config_path, O_RDONLY); -+ if (fd < 0) -+ return 1; -+ -+ if (pread(fd, buff, sizeof(uint32_t), VMD_REGISTER_OFFSET) != sizeof(uint32_t)) { -+ close(fd); -+ return 1; -+ } -+ close(fd); -+ return 0; -+} -+ -+/* -+ * add_vmd_orom() - Adds VMD orom cap to orom list, writes orom_entry ptr into vmd_orom -+ * @vmd_orom: pointer to orom entry pointer -+ * -+ * Return: 0 on success, 1 on error -+ */ -+int add_vmd_orom(struct orom_entry **vmd_orom, struct sys_dev *hba) -+{ -+ uint8_t sku; -+ uint32_t vmd_register_data; -+ struct imsm_orom vmd_orom_cap = { -+ .signature = IMSM_VMD_OROM_COMPAT_SIGNATURE, -+ .sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB | -+ IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB | -+ IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB, -+ .dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME, -+ .tds = IMSM_OROM_TOTAL_DISKS_VMD, -+ .vpa = IMSM_OROM_VOLUMES_PER_ARRAY, -+ .vphba = IMSM_OROM_VOLUMES_PER_HBA_VMD, -+ .attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK, -+ .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem | -+ IMSM_OROM_CAPABILITIES_TPV -+ }; -+ -+ if (read_vmd_register(&vmd_register_data, hba) != 0) -+ return 1; -+ -+ sku = (uint8_t)((vmd_register_data >> VMD_REGISTER_SKU_SHIFT) & -+ VMD_REGISTER_SKU_MASK); -+ -+ if (sku == VMD_REGISTER_SKU_PREMIUM) -+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | -+ IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5; -+ else -+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID_CNG; -+ -+ vmd_orom_cap.major_ver = (uint8_t) -+ ((vmd_register_data >> MD_REGISTER_VER_MAJOR_SHIFT) & -+ MD_REGISTER_VER_MAJOR_MASK); -+ vmd_orom_cap.minor_ver = (uint8_t) -+ ((vmd_register_data >> MD_REGISTER_VER_MINOR_SHIFT) & -+ MD_REGISTER_VER_MINOR_MASK); -+ -+ *vmd_orom = add_orom(&vmd_orom_cap); -+ -+ return 0; -+} -+ -+const struct imsm_orom *find_imsm_vmd(struct sys_dev *hba) -+{ -+ static struct orom_entry *vmd_orom; -+ -+ if (hba->type != SYS_DEV_VMD) -+ return NULL; -+ -+ if (!vmd_orom && add_vmd_orom(&vmd_orom, hba) != 0) -+ return NULL; -+ -+ add_orom_device_id(vmd_orom, hba->dev_id); -+ vmd_orom->type = SYS_DEV_VMD; -+ return &vmd_orom->orom; -+} -+ - const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) - { - const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id); -@@ -709,9 +809,19 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) - - if (hba->type == SYS_DEV_NVME) - return find_imsm_nvme(hba); -- if ((cap = find_imsm_efi(hba)) != NULL) -+ -+ cap = find_imsm_efi(hba); -+ if (cap) - return cap; -- if ((cap = find_imsm_hba_orom(hba)) != NULL) -+ -+ if (hba->type == SYS_DEV_VMD) { -+ cap = find_imsm_vmd(hba); -+ if (cap) -+ return cap; -+ } -+ -+ cap = find_imsm_hba_orom(hba); -+ if (cap) - return cap; - - return NULL; -diff --git a/platform-intel.h b/platform-intel.h -index ba97fb04..ce29d3da 100644 ---- a/platform-intel.h -+++ b/platform-intel.h -@@ -27,6 +27,7 @@ struct imsm_orom { - __u8 signature[4]; - #define IMSM_OROM_SIGNATURE "$VER" - #define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM" -+ #define IMSM_VMD_OROM_COMPAT_SIGNATURE "$VMD" - __u8 table_ver_major; /* Currently 2 (can change with future revs) */ - __u8 table_ver_minor; /* Currently 2 (can change with future revs) */ - __u16 major_ver; /* Example: 8 as in 8.6.0.1020 */ -@@ -68,11 +69,13 @@ struct imsm_orom { - __u16 tds; /* Total Disks Supported */ - #define IMSM_OROM_TOTAL_DISKS 6 - #define IMSM_OROM_TOTAL_DISKS_NVME 12 -+ #define IMSM_OROM_TOTAL_DISKS_VMD 48 - __u8 vpa; /* # Volumes Per Array supported */ - #define IMSM_OROM_VOLUMES_PER_ARRAY 2 - __u8 vphba; /* # Volumes Per Host Bus Adapter supported */ - #define IMSM_OROM_VOLUMES_PER_HBA 4 - #define IMSM_OROM_VOLUMES_PER_HBA_NVME 4 -+ #define IMSM_OROM_VOLUMES_PER_HBA_VMD 24 - /* Attributes supported. This should map to the - * attributes in the MPB. Also, lower 16 bits - * should match/duplicate RLC bits above. -@@ -185,7 +188,13 @@ static inline int imsm_orom_is_enterprise(const struct imsm_orom *orom) - static inline int imsm_orom_is_nvme(const struct imsm_orom *orom) - { - return memcmp(orom->signature, IMSM_NVME_OROM_COMPAT_SIGNATURE, -- sizeof(orom->signature)) == 0; -+ sizeof(orom->signature)) == 0; -+} -+ -+static inline int imsm_orom_is_vmd_without_efi(const struct imsm_orom *orom) -+{ -+ return memcmp(orom->signature, IMSM_VMD_OROM_COMPAT_SIGNATURE, -+ sizeof(orom->signature)) == 0; - } - - static inline int imsm_orom_has_tpv_support(const struct imsm_orom *orom) -diff --git a/super-intel.c b/super-intel.c -index ce813172..77b0066f 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -2672,9 +2672,14 @@ static void print_imsm_capability(const struct imsm_orom *orom) - else - printf("Rapid Storage Technology%s\n", - imsm_orom_is_enterprise(orom) ? " enterprise" : ""); -- if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) -- printf(" Version : %d.%d.%d.%d\n", orom->major_ver, -- orom->minor_ver, orom->hotfix_ver, orom->build); -+ if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) { -+ if (imsm_orom_is_vmd_without_efi(orom)) -+ printf(" Version : %d.%d\n", orom->major_ver, -+ orom->minor_ver); -+ else -+ printf(" Version : %d.%d.%d.%d\n", orom->major_ver, -+ orom->minor_ver, orom->hotfix_ver, orom->build); -+ } - printf(" RAID Levels :%s%s%s%s%s\n", - imsm_orom_has_raid0(orom) ? " raid0" : "", - imsm_orom_has_raid1(orom) ? " raid1" : "", --- -2.40.1 - diff --git a/SOURCES/0142-Add-compiler-defenses-flags.patch b/SOURCES/0142-Add-compiler-defenses-flags.patch deleted file mode 100644 index 6102288..0000000 --- a/SOURCES/0142-Add-compiler-defenses-flags.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 55a1150c7438afcb7756fccd49713ede20a58e4a Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Mon, 17 Jul 2023 15:19:10 +0200 -Subject: [PATCH 142/165] Add compiler defenses flags - -It is essential to avoid buffer overflows and similar bugs as much as -possible. - -According to Intel rules we are obligated to verify certain -compiler flags, so it will be much easier if they are added to the -Makefile. - -Add gcc flags for prevention of buffer overflows, format string vulnerabilities, -stack protection to prevent stack overwrites and aslr enablement through -fPIE. -Also make the flags configurable. - -The changes were verified on gcc versions 7.5, 8.3, 9.2, 10 and 12.2. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Jes Sorensen ---- - Makefile | 41 +++++++++++++++++++++++++++++------------ - 1 file changed, 29 insertions(+), 12 deletions(-) - -diff --git a/Makefile b/Makefile -index 5eac1a4e..b3aa36f6 100644 ---- a/Makefile -+++ b/Makefile -@@ -30,7 +30,7 @@ - - # define "CXFLAGS" to give extra flags to CC. - # e.g. make CXFLAGS=-O to optimise --CXFLAGS ?=-O2 -+CXFLAGS ?=-O2 -D_FORTIFY_SOURCE=2 - TCC = tcc - UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found ) - #DIET_GCC = diet gcc -@@ -50,14 +50,30 @@ ifeq ($(origin CC),default) - CC := $(CROSS_COMPILE)gcc - endif - CXFLAGS ?= -ggdb --CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -+CWFLAGS ?= -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIE -Warray-bounds - ifdef WARN_UNUSED --CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 -+CWFLAGS += -Wp -O3 - endif - --FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l) --ifneq "$(FALLTHROUGH)" "0" --CWFLAGS += -Wimplicit-fallthrough=0 -+ifeq ($(origin FALLTHROUGH), undefined) -+ FALLTHROUGH := $(shell gcc -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l) -+ ifneq "$(FALLTHROUGH)" "0" -+ CWFLAGS += -Wimplicit-fallthrough=0 -+ endif -+endif -+ -+ifeq ($(origin FORMATOVERFLOW), undefined) -+ FORMATOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l) -+ ifneq "$(FORMATOVERFLOW)" "0" -+ CWFLAGS += -Wformat-overflow -+ endif -+endif -+ -+ifeq ($(origin STRINGOPOVERFLOW), undefined) -+ STRINGOPOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l) -+ ifneq "$(STRINGOPOVERFLOW)" "0" -+ CWFLAGS += -Wstringop-overflow -+ endif - endif - - ifdef DEBIAN -@@ -116,10 +132,12 @@ CFLAGS += -DUSE_PTHREADS - MON_LDFLAGS += -pthread - endif - -+LDFLAGS = -Wl,-z,now,-z,noexecstack -+ - # If you want a static binary, you might uncomment these --# LDFLAGS = -static -+# LDFLAGS += -static - # STRIP = -s --LDLIBS = -ldl -+LDLIBS = -ldl -pie - - # To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS - ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS))) -@@ -209,14 +227,13 @@ mdadm.Os : $(SRCS) $(INCL) - $(CC) -o mdadm.Os $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) $(LDLIBS) - - mdadm.O2 : $(SRCS) $(INCL) mdmon.O2 -- $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(SRCS) $(LDLIBS) -+ $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 $(SRCS) $(LDLIBS) - - mdmon.O2 : $(MON_SRCS) $(INCL) mdmon.h -- $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) $(LDLIBS) -+ $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 $(MON_SRCS) $(LDLIBS) - --# use '-z now' to guarantee no dynamic linker interactions with the monitor thread - mdmon : $(MON_OBJS) | check_rundir -- $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -Wl,-z,now -o mdmon $(MON_OBJS) $(LDLIBS) -+ $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -o mdmon $(MON_OBJS) $(LDLIBS) - msg.o: msg.c msg.h - - test_stripe : restripe.c xmalloc.o mdadm.h --- -2.40.1 - diff --git a/SOURCES/0143-Assemble-fix-redundant-memory-free.patch b/SOURCES/0143-Assemble-fix-redundant-memory-free.patch deleted file mode 100644 index 4583718..0000000 --- a/SOURCES/0143-Assemble-fix-redundant-memory-free.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 024d652e16dd9e3bd1ecdfce4d6f7a8cb498ba42 Mon Sep 17 00:00:00 2001 -From: Kinga Tanska -Date: Tue, 12 Sep 2023 04:27:01 +0200 -Subject: [PATCH 143/165] Assemble: fix redundant memory free - -Commit e9fb93af0f76 ("Fix memory leak in file Assemble") -fixes few memory leaks in Assemble, but it introduces -problem with assembling RAID volume. It was caused by -clearing metadata too fast, not only on fail in -select_devices() function. -This commit removes redundant memory free. - -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Assemble.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 61e8cd17..5be58e40 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -428,8 +428,6 @@ static int select_devices(struct mddev_dev *devlist, - - /* make sure we finished the loop */ - tmpdev = NULL; -- free(st); -- st = NULL; - goto loop; - } else { - content = *contentp; --- -2.40.1 - diff --git a/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch b/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch deleted file mode 100644 index dbbd3c5..0000000 --- a/SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 7fe21767d3ab65a686518d2e36d18a07f535972e Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:19 +0800 -Subject: [PATCH 144/165] tests: add a new test for rdev lifetime - -This test add and remove a underlying disk to raid concurretly, verify -that the following problem is fixed: - -run mdadm test 23rdev-lifetime at Fri Apr 28 03:25:30 UTC 2023 -md: could not open device unknown-block(1,0). -sysfs: cannot create duplicate filename '/devices/virtual/block/md0/md/dev-ram0' -CPU: 26 PID: 10521 Comm: test Not tainted 6.3.0-rc2-00134-g7b3a8828043c #115 -Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/014 -Call Trace: - - dump_stack_lvl+0xe7/0x180 - dump_stack+0x18/0x30 - sysfs_warn_dup+0xa2/0xd0 - sysfs_create_dir_ns+0x119/0x140 - kobject_add_internal+0x143/0x4d0 - kobject_add_varg+0x35/0x70 - kobject_add+0x64/0xd0 - bind_rdev_to_array+0x254/0x840 [md_mod] - new_dev_store+0x14d/0x350 [md_mod] - md_attr_store+0xc1/0x1a0 [md_mod] - sysfs_kf_write+0x51/0x70 - kernfs_fop_write_iter+0x188/0x270 - vfs_write+0x27e/0x460 - ksys_write+0x85/0x180 - __x64_sys_write+0x21/0x30 - do_syscall_64+0x6c/0xe0 - entry_SYSCALL_64_after_hwframe+0x63/0xcd -RIP: 0033:0x7f26bacf5387 -Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 84 -RSP: 002b:00007ffe98d79e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 -RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f26bacf5387 -RDX: 0000000000000004 RSI: 000055bd10282bf0 RDI: 0000000000000001 -RBP: 000055bd10282bf0 R08: 000000000000000a R09: 00007f26bad8b4e0 -R10: 00007f26bad8b3e0 R11: 0000000000000246 R12: 0000000000000004 -R13: 00007f26badc8520 R14: 0000000000000004 R15: 00007f26badc8700 - - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/23rdev-lifetime | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 tests/23rdev-lifetime - -diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime -new file mode 100644 -index 00000000..1750b0db ---- /dev/null -+++ b/tests/23rdev-lifetime -@@ -0,0 +1,34 @@ -+devname=${dev0##*/} -+devt=`cat /sys/block/$devname/dev` -+pid="" -+runtime=2 -+ -+clean_up_test() { -+ pill -9 $pid -+ echo clear > /sys/block/md0/md/array_state -+} -+ -+trap 'clean_up_test' EXIT -+ -+add_by_sysfs() { -+ while true; do -+ echo $devt > /sys/block/md0/md/new_dev -+ done -+} -+ -+remove_by_sysfs(){ -+ while true; do -+ echo remove > /sys/block/md0/md/dev-${devname}/state -+ done -+} -+ -+echo md0 > /sys/module/md_mod/parameters/new_array || die "create md0 failed" -+ -+add_by_sysfs & -+pid="$pid $!" -+ -+remove_by_sysfs & -+pid="$pid $!" -+ -+sleep $runtime -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch b/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch deleted file mode 100644 index 39b38d2..0000000 --- a/SOURCES/0145-tests-support-to-skip-checking-dmesg.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0ef9465f6355db612e53afc32e3084721c3dd7c7 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:20 +0800 -Subject: [PATCH 145/165] tests: support to skip checking dmesg - -Prepare to add a regression test for raid10 that require error injection -to trigger error path, and kernel will complain about io error, checking -dmesg for error log will make it impossible to pass this test. - -Signed-off-by: Yu Kuai -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - test | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/test b/test -index 61d9ee83..b244453b 100755 ---- a/test -+++ b/test -@@ -107,8 +107,12 @@ do_test() { - echo -ne "$_script... " - if ( set -ex ; . $_script ) &> $targetdir/log - then -- dmesg | grep -iq "error\|call trace\|segfault" && -- die "dmesg prints errors when testing $_basename!" -+ if [ -f "${_script}.inject_error" ]; then -+ echo "dmesg checking is skipped because test inject error" -+ else -+ dmesg | grep -iq "error\|call trace\|segfault" && -+ die "dmesg prints errors when testing $_basename!" -+ fi - echo "succeeded" - _fail=0 - else --- -2.40.1 - diff --git a/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch b/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch deleted file mode 100644 index 04e4304..0000000 --- a/SOURCES/0146-tests-add-a-regression-test-for-raid10-deadlock.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 3973f65293ce69ddd7c19be9a7a796abfe80e370 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:21 +0800 -Subject: [PATCH 146/165] tests: add a regression test for raid10 deadlock - -The deadlock is described in [1], it's fixed first by [2], however, -it turns out this commit will trigger other problems[3], hence this -commit will be reverted and the deadlock is supposed to be fixed by [1]. - -[1] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/ -[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/ -[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-2-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/24raid10deadlock | 88 +++++++++++++++++++++++++++++ - tests/24raid10deadlock.inject_error | 0 - 2 files changed, 88 insertions(+) - create mode 100644 tests/24raid10deadlock - create mode 100644 tests/24raid10deadlock.inject_error - -diff --git a/tests/24raid10deadlock b/tests/24raid10deadlock -new file mode 100644 -index 00000000..ee330aa9 ---- /dev/null -+++ b/tests/24raid10deadlock -@@ -0,0 +1,88 @@ -+devs="$dev0 $dev1 $dev2 $dev3" -+runtime=120 -+pid="" -+action_pid="" -+ -+set_up_injection() -+{ -+ echo -1 > /sys/kernel/debug/fail_make_request/times -+ echo 1 > /sys/kernel/debug/fail_make_request/probability -+ echo 0 > /sys/kernel/debug/fail_make_request/verbose -+ echo 1 > /sys/block/${1##*/}/make-it-fail -+} -+ -+clean_up_injection() -+{ -+ echo 0 > /sys/block/${1##*/}/make-it-fail -+ echo 0 > /sys/kernel/debug/fail_make_request/times -+ echo 0 > /sys/kernel/debug/fail_make_request/probability -+ echo 2 > /sys/kernel/debug/fail_make_request/verbose -+} -+ -+test_rdev() -+{ -+ while true; do -+ mdadm -f $md0 $1 &> /dev/null -+ mdadm -r $md0 $1 &> /dev/null -+ mdadm --zero-superblock $1 &> /dev/null -+ mdadm -a $md0 $1 &> /dev/null -+ sleep $2 -+ done -+} -+ -+test_write_action() -+{ -+ while true; do -+ echo frozen > /sys/block/md0/md/sync_action -+ echo idle > /sys/block/md0/md/sync_action -+ sleep 0.1 -+ done -+} -+ -+set_up_test() -+{ -+ fio -h &> /dev/null || die "fio not found" -+ -+ # create a simple raid10 -+ mdadm -Cv -R -n 4 -l10 $md0 $devs || die "create raid10 failed" -+} -+ -+clean_up_test() -+{ -+ clean_up_injection $dev0 -+ pkill -9 fio -+ kill -9 $pid -+ kill -9 $action_pid -+ -+ sleep 1 -+ -+ if ps $action_pid | tail -1 | awk '{print $3}' | grep D; then -+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered" -+ fi -+ mdadm -S $md0 -+} -+ -+cat /sys/kernel/debug/fail_make_request/times || die "fault injection is not enabled" -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# backgroup io pressure -+fio -filename=$md0 -rw=randwrite -direct=1 -name=test -bs=4k -numjobs=16 -iodepth=16 & -+ -+# trigger add/remove device by io failure -+set_up_injection $dev0 -+test_rdev $dev0 2 & -+pid="$pid $!" -+ -+# add/remove device directly -+test_rdev $dev3 10 & -+pid="$pid $!" -+ -+test_write_action & -+action_pid="$!" -+ -+sleep $runtime -+ -+exit 0 -diff --git a/tests/24raid10deadlock.inject_error b/tests/24raid10deadlock.inject_error -new file mode 100644 -index 00000000..e69de29b --- -2.40.1 - diff --git a/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch b/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch deleted file mode 100644 index 78c5836..0000000 --- a/SOURCES/0147-tests-add-a-regression-test-for-raid456-deadlock.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 9d0fb58f3b1314678564b4ac7bfb19942acc8926 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:22 +0800 -Subject: [PATCH 147/165] tests: add a regression test for raid456 deadlock - -The deadlock is described in [1], as the last patch described, it's -fixed first by [2], however this fix will be reverted and the deadlock -is supposed to be fixed by [3]. - -[1] https://lore.kernel.org/linux-raid/5ed54ffc-ce82-bf66-4eff-390cb23bc1ac@molgen.mpg.de/T/#t -[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/ -[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/24raid456deadlock | 58 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 58 insertions(+) - create mode 100644 tests/24raid456deadlock - -diff --git a/tests/24raid456deadlock b/tests/24raid456deadlock -new file mode 100644 -index 00000000..80e6e97e ---- /dev/null -+++ b/tests/24raid456deadlock -@@ -0,0 +1,58 @@ -+devs="$dev0 $dev1 $dev2 $dev3 $dev4 $dev5" -+runtime=120 -+pid="" -+old=`cat /proc/sys/vm/dirty_background_ratio` -+ -+test_write_action() -+{ -+ while true; do -+ echo check > /sys/block/md0/md/sync_action &> /dev/null -+ sleep 0.1 -+ echo idle > /sys/block/md0/md/sync_action &> /dev/null -+ done -+} -+ -+test_write_back() -+{ -+ fio -filename=$md0 -bs=4k -rw=write -numjobs=1 -name=test \ -+ -time_based -runtime=$runtime &> /dev/null -+} -+ -+set_up_test() -+{ -+ fio -h &> /dev/null || die "fio not found" -+ -+ # create a simple raid6 -+ mdadm -Cv -R -n 6 -l6 $md0 $devs --assume-clean || die "create raid6 failed" -+ -+ # trigger dirty pages write back -+ echo 0 > /proc/sys/vm/dirty_background_ratio -+} -+ -+clean_up_test() -+{ -+ echo $old > /proc/sys/vm/dirty_background_ratio -+ -+ pkill -9 fio -+ kill -9 $pid -+ -+ sleep 1 -+ -+ if ps $pid | tail -1 | awk '{print $3}' | grep D; then -+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered" -+ fi -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+test_write_back & -+ -+test_write_action & -+pid="$!" -+ -+sleep $runtime -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch b/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch deleted file mode 100644 index a10b3b2..0000000 --- a/SOURCES/0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4db8a3d452daaf2def41ca45c36e36c5781627ac Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:23 +0800 -Subject: [PATCH 148/165] tests: add a regression test that raid456 can't - assemble - -If recovery is interrupted and reshape is started, then this array can't -assemble anymore. The problem is supposed to be fixed by [1]. - -[1] https://lore.kernel.org/linux-raid/20230529031045.1760883-1-yukuai1@huaweicloud.com/ - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-while-recovery | 32 ++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - create mode 100644 tests/25raid456-reshape-while-recovery - -diff --git a/tests/25raid456-reshape-while-recovery b/tests/25raid456-reshape-while-recovery -new file mode 100644 -index 00000000..b9f871f2 ---- /dev/null -+++ b/tests/25raid456-reshape-while-recovery -@@ -0,0 +1,32 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# set up replacement -+echo want_replacement > /sys/block/md0/md/rd0/state -+sleep 1 -+ -+# trigger reshape -+echo frozen > /sys/block/md0/md/sync_action -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# reassemeble array -+mdadm -S $md0 || die "can't stop array" -+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch b/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch deleted file mode 100644 index 3d52868..0000000 --- a/SOURCES/0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8d45abd0c317d3f4971b779b4f8d1e33b5490dac Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:24 +0800 -Subject: [PATCH 149/165] tests: add a regression test that raid456 can't - assemble again - -This is a regression test for commit 0aecb06e2249 ("md/raid5: don't allow -replacement while reshape is in progress"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-recovery-while-reshape | 33 ++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - create mode 100644 tests/25raid456-recovery-while-reshape - -diff --git a/tests/25raid456-recovery-while-reshape b/tests/25raid456-recovery-while-reshape -new file mode 100644 -index 00000000..3f6251bf ---- /dev/null -+++ b/tests/25raid456-recovery-while-reshape -@@ -0,0 +1,33 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# set up replacement -+echo frozen > /sys/block/md0/md/sync_action -+echo want_replacement > /sys/block/md0/md/rd0/state -+echo reshape > /sys/block/md0/md/sync_action -+sleep 1 -+ -+# reassemeble array -+mdadm -S $md0 || die "can't stop array" -+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch b/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch deleted file mode 100644 index 20f0272..0000000 --- a/SOURCES/0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 481433482942c2ee2990965af394eff059990901 Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:25 +0800 -Subject: [PATCH 150/165] tests: add a regression test that reshape can corrupt - data - -This is a regression test for commit 1544e95c6dd8 ("md: fix data -corruption for raid456 when reshape restart while grow up"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-corrupt-data | 35 ++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - create mode 100644 tests/25raid456-reshape-corrupt-data - -diff --git a/tests/25raid456-reshape-corrupt-data b/tests/25raid456-reshape-corrupt-data -new file mode 100644 -index 00000000..fdb875fb ---- /dev/null -+++ b/tests/25raid456-reshape-corrupt-data -@@ -0,0 +1,35 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array" -+ mkfs.xfs -f $md0 || die "mkfs failed" -+ xfs_ncheck $md0 || die "check fs failed" -+} -+ -+clean_up_test() -+{ -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+echo 1000 > /sys/block/md0/md/sync_speed_max -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# stop and start reshape -+echo frozen > /sys/block/md0/md/sync_action -+echo system > /sys/block/md0/md/sync_speed_max -+echo reshape > /sys/block/md0/md/sync_action -+ -+mdadm -W $md0 -+ -+# check if data is corrupted -+xfs_ncheck $md0 || die "data is corrupted after reshape" -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch b/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch deleted file mode 100644 index ab916c5..0000000 --- a/SOURCES/0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c6c7bce5a3064ac9d2956ae42ecab27f2e33dc2b Mon Sep 17 00:00:00 2001 -From: Yu Kuai -Date: Mon, 29 May 2023 21:28:26 +0800 -Subject: [PATCH 151/165] tests: add a regression test for raid456 deadlock - again - -This is a regression test for commit ("md/raid5: fix a deadlock in the -case that reshape is interrupted"). - -Signed-off-by: Yu Kuai -Signed-off-by: Jes Sorensen ---- - tests/25raid456-reshape-deadlock | 34 ++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 tests/25raid456-reshape-deadlock - -diff --git a/tests/25raid456-reshape-deadlock b/tests/25raid456-reshape-deadlock -new file mode 100644 -index 00000000..bfa0cc56 ---- /dev/null -+++ b/tests/25raid456-reshape-deadlock -@@ -0,0 +1,34 @@ -+devs="$dev0 $dev1 $dev2" -+ -+set_up_test() -+{ -+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed" -+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array" -+ echo 1000 > /sys/block/md0/md/sync_speed_max -+} -+ -+clean_up_test() -+{ -+ echo idle > /sys/block/md0/md/sync_action -+ mdadm -S $md0 -+} -+ -+trap 'clean_up_test' EXIT -+ -+set_up_test || die "set up test failed" -+ -+# trigger reshape -+mdadm --grow -l 6 $md0 -+sleep 1 -+ -+# stop reshape -+echo frozen > /sys/block/md0/md/sync_action -+ -+# read accross reshape -+dd if=$md0 of=/dev/NULL bs=1m count=100 iflag=direct &> /dev/null & -+sleep 2 -+ -+# suspend array -+echo 1 > /sys/block/md0/md/suspend_lo -+ -+exit 0 --- -2.40.1 - diff --git a/SOURCES/0152-tests-create-names_template.patch b/SOURCES/0152-tests-create-names_template.patch deleted file mode 100644 index a3db688..0000000 --- a/SOURCES/0152-tests-create-names_template.patch +++ /dev/null @@ -1,193 +0,0 @@ -From d5fee8654e41dc4067dfdc3312542f1f43ebe884 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:45 +0200 -Subject: [PATCH 152/165] tests: create names_template - -Create templates directory and names_template. Move code from -00createnames. This code will be reused for 00confnames in next patch. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00createnames | 86 +++++++--------------------------- - tests/templates/names_template | 53 +++++++++++++++++++++ - 2 files changed, 70 insertions(+), 69 deletions(-) - create mode 100644 tests/templates/names_template - -diff --git a/tests/00createnames b/tests/00createnames -index 64b81b92..064eeef2 100644 ---- a/tests/00createnames -+++ b/tests/00createnames -@@ -1,93 +1,41 @@ - set -x -e -+. tests/templates/names_template - - # Test how and --name= are handled for create mode. --# We need to check three properties, generated from those parameters: --# - devnode name --# - link in /dev/md/ (MD_DEVNAME property from --detail --export) --# - name in metadata (MD_NAME property from --examine --export) -- --function _verify() { -- local DEVNODE_NAME="$1" -- local WANTED_LINK="$2" -- local WANTED_NAME="$3" -- -- local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -- if [[ "$?" != "0" ]]; then -- echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -- exit 1 -- fi -- -- if [[ "$WANTED_LINK" != "empty" ]]; then -- local EXPECTED="MD_DEVNAME=$WANTED_LINK" -- if [[ "$RES" != "$EXPECTED" ]]; then -- echo "$RES doesn't match $EXPECTED." -- exit 1 -- fi -- fi -- -- -- local RES="$(mdadm -E --export $dev0 | grep MD_NAME)" -- if [[ "$?" != "0" ]]; then -- echo "Cannot get metadata from $dev0." -- exit 1 -- fi -- -- local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -- if [[ "$RES" != "$EXPECTED" ]]; then -- echo "$RES doesn't match $EXPECTED." -- exit 1 -- fi --} -- --function _create() { -- local DEVNAME=$1 -- local NAME=$2 -- -- if [[ -z "$NAME" ]]; then -- mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -- else -- mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force -- fi -- -- if [[ "$?" != "0" ]]; then -- echo "Cannot create device." -- exit 1 -- fi --} - - # The most trivial case. --_create "/dev/md/name" --_verify "/dev/md127" "name" "name" -+names_create "/dev/md/name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - --_create "name" --_verify "/dev/md127" "name" "name" -+names_create "name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # Use 'mdX' as name. --_create "/dev/md/md0" --_verify "/dev/md127" "md0" "md0" -+names_create "/dev/md/md0" -+names_verify "/dev/md127" "md0" "md0" - mdadm -S "/dev/md127" - --_create "md0" --_verify "/dev/md127" "md0" "md0" -+names_create "md0" -+names_verify "/dev/md127" "md0" "md0" - mdadm -S "/dev/md127" - - # is used to create MD_DEVNAME but, name is used to create MD_NAME. --_create "/dev/md/devnode" "name" --_verify "/dev/md127" "devnode" "name" -+names_create "/dev/md/devnode" "name" -+names_verify "/dev/md127" "devnode" "name" - mdadm -S "/dev/md127" - --_create "devnode" "name" --_verify "/dev/md127" "devnode" "name" -+names_create "devnode" "name" -+names_verify "/dev/md127" "devnode" "name" - mdadm -S "/dev/md127" - - # Devnode points to /dev/ directory. MD_DEVNAME doesn't exist. --_create "/dev/md0" --_verify "/dev/md0" "empty" "0" -+names_create "/dev/md0" -+names_verify "/dev/md0" "empty" "0" - mdadm -S "/dev/md0" - - # Devnode points to /dev/ directory and name is set. --_create "/dev/md0" "name" --_verify "/dev/md0" "empty" "name" -+names_create "/dev/md0" "name" -+names_verify "/dev/md0" "empty" "name" - mdadm -S "/dev/md0" -diff --git a/tests/templates/names_template b/tests/templates/names_template -new file mode 100644 -index 00000000..9f09be9e ---- /dev/null -+++ b/tests/templates/names_template -@@ -0,0 +1,53 @@ -+# NAME is optional. Testing with native 1.2 superblock. -+function names_create() { -+ local DEVNAME=$1 -+ local NAME=$2 -+ -+ if [[ -z "$NAME" ]]; then -+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -+ else -+ mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force -+ fi -+ -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot create device." -+ exit 1 -+ fi -+} -+ -+# Three properties to check: -+# - devnode name -+# - link in /dev/md/ (MD_DEVNAME property from --detail --export) -+# - name in metadata (MD_NAME property from --detail --export)- that works only with 1.2 sb. -+function names_verify() { -+ local DEVNODE_NAME="$1" -+ local WANTED_LINK="$2" -+ local WANTED_NAME="$3" -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." -+ exit 1 -+ fi -+ -+ if [[ "$WANTED_LINK" != "empty" ]]; then -+ local EXPECTED="MD_DEVNAME=$WANTED_LINK" -+ fi -+ -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+ -+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_NAME)" -+ if [[ "$?" != "0" ]]; then -+ echo "Cannot get metadata from $dev0." -+ exit 1 -+ fi -+ -+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME" -+ if [[ "$RES" != "$EXPECTED" ]]; then -+ echo "$RES doesn't match $EXPECTED." -+ exit 1 -+ fi -+} --- -2.40.1 - diff --git a/SOURCES/0153-tests-create-00confnames.patch b/SOURCES/0153-tests-create-00confnames.patch deleted file mode 100644 index 1534d93..0000000 --- a/SOURCES/0153-tests-create-00confnames.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 569a23425939e4bfc7b4d7f871d8510bb968f892 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:46 +0200 -Subject: [PATCH 153/165] tests: create 00confnames - -The test is an attempt to document current implementation of devnode -and name handling for config entries. It is focused on incremental- -default way of array assembling on boot. -The expectations are aligned to current implementation for native -metadata because it is the most complicated scenario- both variables -can be set. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - tests/00confnames | 107 +++++++++++++++++++++++++++++++++ - tests/templates/names_template | 20 ++++++ - 2 files changed, 127 insertions(+) - create mode 100644 tests/00confnames - -diff --git a/tests/00confnames b/tests/00confnames -new file mode 100644 -index 00000000..25a7127b ---- /dev/null -+++ b/tests/00confnames -@@ -0,0 +1,107 @@ -+set -x -e -+. tests/templates/names_template -+ -+# Test how and from config are handled during Incremental assemblation. -+# 1-6 only tests (no in config). -+# 6-10 and combinations are tested. -+# 11-13 corner cases. -+ -+names_create "/dev/md/name" -+local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)" -+[[ "$_UUID" == "" ]] && echo "Cannot obtain UUID for $DEVNODE_NAME" && exit 1 -+ -+ -+# 1. definition consistent with metadata name. -+names_make_conf $_UUID "/dev/md/name" "empty" $config -+mdadm -S "/dev/md127" -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 2. Same as 1, but use short name form of . -+names_make_conf $_UUID "name" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 3. Same as 1, but use different than metadata provides. -+names_make_conf $_UUID "/dev/md/other" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "other" "name" -+mdadm -S "/dev/md127" -+ -+# 4. Same as 3, but use short name form of . -+names_make_conf $_UUID "other" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "other" "name" -+mdadm -S "/dev/md127" -+ -+# 5. Force particular node creation by setting to /dev/mdX. Link is not created in this -+# case. -+names_make_conf $_UUID "/dev/md4" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md4" "empty" "name" -+mdadm -S "/dev/md4" -+ -+# 6. set to /dev/mdX, same as in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "/dev/md22" "name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 7. set to /dev/mdX, different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "/dev/md8" "other" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 8. Both and different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "devnode" "other_name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 9. set to metadata name, different than in metadata. -+# Metadata name and default node used - controversial. Current behavior documented. -+names_make_conf $_UUID "name" "other_name" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 10. Bad set, no . -+# Metadata name and default node used - expected. -+names_make_conf $_UUID "/im/bad/devname" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 11. with some special symbols and locales, no . -+# It needs to wait a while for timeout because udev cannot create a link - known issue. -+names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "tźż-\.,<>st+-" "name" -+mdadm -S "/dev/md127" -+ -+# 12. No and set. -+# Metadata name and default node used - expected. -+names_make_conf $_UUID "empty" "empty" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 13. No , set to /dev/mdX. -+# Entry should be ignored, it is not ignored but result is good anyway. -+names_make_conf $_UUID "empty" "/dev/md12" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -+ -+# 13. No , with special symbols and locales. -+# Entry should be ignored, it is not ignored but result is good anyway. -+names_make_conf $_UUID "empty" "./\śćń#&" $config -+mdadm -I $dev0 --config=$config -+names_verify "/dev/md127" "name" "name" -+mdadm -S "/dev/md127" -diff --git a/tests/templates/names_template b/tests/templates/names_template -index 9f09be9e..8d2b5c81 100644 ---- a/tests/templates/names_template -+++ b/tests/templates/names_template -@@ -51,3 +51,23 @@ function names_verify() { - exit 1 - fi - } -+ -+# Generate ARRAYLINE for tested array. -+names_make_conf() { -+ local UUID="$1" -+ local WANTED_DEVNAME="$2" -+ local WANTED_NAME="$3" -+ local CONF="$4" -+ -+ local LINE="ARRAY metadata=1.2 UUID=$UUID" -+ -+ if [[ "$WANTED_DEVNAME" != "empty" ]]; then -+ LINE="$LINE $WANTED_DEVNAME" -+ fi -+ -+ if [[ "$WANTED_NAME" != "empty" ]]; then -+ LINE="$LINE name=$WANTED_NAME" -+ fi -+ -+ echo $LINE > $CONF -+} --- -2.40.1 - diff --git a/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch b/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch deleted file mode 100644 index 14ca30e..0000000 --- a/SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 330c07f8e4d26f4f2d068e11f09c9df8a3380087 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:47 +0200 -Subject: [PATCH 154/165] mdadm: set ident.devname if applicable - -This patch tries to propagate the usage of struct mddev_ident for cmdline -where it is applicable. To avoid regression, this value is derived -from devlist->devname for applicable modes only. -As a result, the whole structure is passed to some functions. It produces -some changes for Build, Create and Assemble. -No functional changes intended. - -The goal of the change is to unify devname validation which is done in -next patches. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Build.c | 21 +++++++++------------ - Create.c | 35 ++++++++++++++++------------------ - mdadm.c | 57 +++++++++++++++++++++++++------------------------------- - mdadm.h | 13 +++++-------- - 4 files changed, 55 insertions(+), 71 deletions(-) - -diff --git a/Build.c b/Build.c -index 8d6f6f58..657ab315 100644 ---- a/Build.c -+++ b/Build.c -@@ -24,8 +24,8 @@ - - #include "mdadm.h" - --int Build(char *mddev, struct mddev_dev *devlist, -- struct shape *s, struct context *c) -+int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, -+ struct context *c) - { - /* Build a linear or raid0 arrays without superblocks - * We cannot really do any checks, we just do it. -@@ -75,13 +75,12 @@ int Build(char *mddev, struct mddev_dev *devlist, - - /* We need to create the device. It can have no name. */ - map_lock(&map); -- mdfd = create_mddev(mddev, NULL, c->autof, LOCAL, -+ mdfd = create_mddev(ident->devname, NULL, c->autof, LOCAL, - chosen_name, 0); - if (mdfd < 0) { - map_unlock(&map); - return 1; - } -- mddev = chosen_name; - - map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name); - map_unlock(&map); -@@ -93,7 +92,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - array.nr_disks = s->raiddisks; - array.raid_disks = s->raiddisks; - array.md_minor = 0; -- if (fstat_is_blkdev(mdfd, mddev, &rdev)) -+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev)) - array.md_minor = minor(rdev); - array.not_persistent = 1; - array.state = 0; /* not clean, but no errors */ -@@ -108,8 +107,7 @@ int Build(char *mddev, struct mddev_dev *devlist, - array.chunk_size = s->chunk*1024; - array.layout = s->layout; - if (md_set_array_info(mdfd, &array)) { -- pr_err("md_set_array_info() failed for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("md_set_array_info() failed for %s: %s\n", chosen_name, strerror(errno)); - goto abort; - } - -@@ -178,8 +176,8 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - if (bitmap_fd >= 0) { - if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { -- pr_err("Cannot set bitmap file for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, -+ strerror(errno)); - goto abort; - } - } -@@ -193,9 +191,8 @@ int Build(char *mddev, struct mddev_dev *devlist, - } - - if (c->verbose >= 0) -- pr_err("array %s built and started.\n", -- mddev); -- wait_for(mddev, mdfd); -+ pr_err("array %s built and started.\n", chosen_name); -+ wait_for(chosen_name, mdfd); - close(mdfd); - return 0; - -diff --git a/Create.c b/Create.c -index ea6a4745..a280c7bc 100644 ---- a/Create.c -+++ b/Create.c -@@ -471,11 +471,8 @@ out: - return ret; - } - --int Create(struct supertype *st, char *mddev, -- char *name, int *uuid, -- int subdevs, struct mddev_dev *devlist, -- struct shape *s, -- struct context *c) -+int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, -+ struct mddev_dev *devlist, struct shape *s, struct context *c) - { - /* - * Create a new raid array. -@@ -497,6 +494,8 @@ int Create(struct supertype *st, char *mddev, - unsigned long long minsize = 0, maxsize = 0; - char *mindisc = NULL; - char *maxdisc = NULL; -+ char *name = ident->name; -+ int *uuid = ident->uuid_set == 1 ? ident->uuid : NULL; - int dnum; - struct mddev_dev *dv; - dev_t rdev; -@@ -1015,7 +1014,7 @@ int Create(struct supertype *st, char *mddev, - - /* We need to create the device */ - map_lock(&map); -- mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1); -+ mdfd = create_mddev(ident->devname, ident->name, c->autof, LOCAL, chosen_name, 1); - if (mdfd < 0) { - map_unlock(&map); - return 1; -@@ -1032,7 +1031,6 @@ int Create(struct supertype *st, char *mddev, - udev_unblock(); - return 1; - } -- mddev = chosen_name; - - memset(&inf, 0, sizeof(inf)); - md_get_array_info(mdfd, &inf); -@@ -1050,7 +1048,7 @@ int Create(struct supertype *st, char *mddev, - * with, but it chooses to trust me instead. Sigh - */ - info.array.md_minor = 0; -- if (fstat_is_blkdev(mdfd, mddev, &rdev)) -+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev)) - info.array.md_minor = minor(rdev); - info.array.not_persistent = 0; - -@@ -1102,8 +1100,8 @@ int Create(struct supertype *st, char *mddev, - info.array.layout = s->layout; - info.array.chunk_size = s->chunk*1024; - -- if (name == NULL || *name == 0) { -- /* base name on mddev */ -+ if (*name == 0) { -+ /* base name on devname */ - /* /dev/md0 -> 0 - * /dev/md_d0 -> d0 - * /dev/md_foo -> foo -@@ -1113,15 +1111,16 @@ int Create(struct supertype *st, char *mddev, - * /dev/mdhome -> home - */ - /* FIXME compare this with rules in create_mddev */ -- name = strrchr(mddev, '/'); -+ name = strrchr(chosen_name, '/'); -+ - if (name) { - name++; - if (strncmp(name, "md_", 3) == 0 && -- strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */) -+ strlen(name) > 3 && (name - chosen_name) == 5 /* /dev/ */) - name += 3; - else if (strncmp(name, "md", 2) == 0 && - strlen(name) > 2 && isdigit(name[2]) && -- (name-mddev) == 5 /* /dev/ */) -+ (name - chosen_name) == 5 /* /dev/ */) - name += 2; - } - } -@@ -1215,8 +1214,7 @@ int Create(struct supertype *st, char *mddev, - } - rv = set_array_info(mdfd, st, &info); - if (rv) { -- pr_err("failed to set array info for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("failed to set array info for %s: %s\n", chosen_name, strerror(errno)); - goto abort_locked; - } - -@@ -1237,8 +1235,7 @@ int Create(struct supertype *st, char *mddev, - goto abort_locked; - } - if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { -- pr_err("Cannot set bitmap file for %s: %s\n", -- mddev, strerror(errno)); -+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, strerror(errno)); - goto abort_locked; - } - } -@@ -1254,7 +1251,7 @@ int Create(struct supertype *st, char *mddev, - * create links */ - sysfs_uevent(&info, "change"); - if (c->verbose >= 0) -- pr_err("container %s prepared.\n", mddev); -+ pr_err("container %s prepared.\n", chosen_name); - wait_for(chosen_name, mdfd); - } else if (c->runstop == 1 || subdevs >= s->raiddisks) { - if (st->ss->external) { -@@ -1312,7 +1309,7 @@ int Create(struct supertype *st, char *mddev, - ioctl(mdfd, RESTART_ARRAY_RW, NULL); - } - if (c->verbose >= 0) -- pr_info("array %s started.\n", mddev); -+ pr_info("array %s started.\n", chosen_name); - if (st->ss->external && st->container_devnm[0]) { - if (need_mdmon) - start_mdmon(st->container_devnm); -diff --git a/mdadm.c b/mdadm.c -index 22d1c53b..0a56ed26 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1290,37 +1290,39 @@ int main(int argc, char *argv[]) - pr_err("an md device must be given in this mode\n"); - exit(2); - } -+ ident.devname = devlist->devname; -+ - if ((int)ident.super_minor == -2 && c.autof) { - pr_err("--super-minor=dev is incompatible with --auto\n"); - exit(2); - } - if (mode == MANAGE || mode == GROW) { -- mdfd = open_mddev(devlist->devname, 1); -+ mdfd = open_mddev(ident.devname, 1); - if (mdfd < 0) - exit(1); - - ret = fstat(mdfd, &stb); - if (ret) { -- pr_err("fstat failed on %s.\n", devlist->devname); -+ pr_err("fstat failed on %s.\n", ident.devname); - exit(1); - } - } else { -- char *bname = basename(devlist->devname); -+ char *bname = basename(ident.devname); - - if (strlen(bname) > MD_NAME_MAX) { -- pr_err("Name %s is too long.\n", devlist->devname); -+ pr_err("Name %s is too long.\n", ident.devname); - exit(1); - } - -- ret = stat(devlist->devname, &stb); -+ ret = stat(ident.devname, &stb); - if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -- devlist->devname); -+ ident.devname); - exit(1); - } - - if (!ret && !stat_is_md_dev(&stb)) { -- pr_err("device %s exists but is not an md array.\n", devlist->devname); -+ pr_err("device %s exists but is not an md array.\n", ident.devname); - exit(1); - } - } -@@ -1408,17 +1410,17 @@ int main(int argc, char *argv[]) - case MANAGE: - /* readonly, add/remove, readwrite, runstop */ - if (c.readonly > 0) -- rv = Manage_ro(devlist->devname, mdfd, c.readonly); -+ rv = Manage_ro(ident.devname, mdfd, c.readonly); - if (!rv && devs_found > 1) -- rv = Manage_subdevs(devlist->devname, mdfd, -+ rv = Manage_subdevs(ident.devname, mdfd, - devlist->next, c.verbose, - c.test, c.update, c.force); - if (!rv && c.readonly < 0) -- rv = Manage_ro(devlist->devname, mdfd, c.readonly); -+ rv = Manage_ro(ident.devname, mdfd, c.readonly); - if (!rv && c.runstop > 0) -- rv = Manage_run(devlist->devname, mdfd, &c); -+ rv = Manage_run(ident.devname, mdfd, &c); - if (!rv && c.runstop < 0) -- rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0); -+ rv = Manage_stop(ident.devname, mdfd, c.verbose, 0); - break; - case ASSEMBLE: - if (!c.scan && c.runstop == -1) { -@@ -1428,22 +1430,19 @@ int main(int argc, char *argv[]) - ident.super_minor == UnSet && ident.name[0] == 0 && - !c.scan) { - /* Only a device has been given, so get details from config file */ -- struct mddev_ident *array_ident = conf_get_ident(devlist->devname); -+ struct mddev_ident *array_ident = conf_get_ident(ident.devname); - if (array_ident == NULL) { -- pr_err("%s not identified in config file.\n", -- devlist->devname); -+ pr_err("%s not identified in config file.\n", ident.devname); - rv |= 1; - if (mdfd >= 0) - close(mdfd); - } else { - if (array_ident->autof == 0) - array_ident->autof = c.autof; -- rv |= Assemble(ss, devlist->devname, array_ident, -- NULL, &c); -+ rv |= Assemble(ss, ident.devname, array_ident, NULL, &c); - } - } else if (!c.scan) -- rv = Assemble(ss, devlist->devname, &ident, -- devlist->next, &c); -+ rv = Assemble(ss, ident.devname, &ident, devlist->next, &c); - else if (devs_found > 0) { - if (c.update && devs_found > 1) { - pr_err("can only update a single array at a time\n"); -@@ -1501,7 +1500,7 @@ int main(int argc, char *argv[]) - break; - } - } -- rv = Build(devlist->devname, devlist->next, &s, &c); -+ rv = Build(&ident, devlist->next, &s, &c); - break; - case CREATE: - if (c.delay == 0) -@@ -1538,9 +1537,7 @@ int main(int argc, char *argv[]) - break; - } - -- rv = Create(ss, devlist->devname, -- ident.name, ident.uuid_set ? ident.uuid : NULL, -- devs_found - 1, devlist->next, &s, &c); -+ rv = Create(ss, &ident, devs_found - 1, devlist->next, &s, &c); - break; - case MISC: - if (devmode == 'E') { -@@ -1637,8 +1634,7 @@ int main(int argc, char *argv[]) - break; - } - for (dv = devlist->next; dv; dv = dv->next) { -- rv = Grow_Add_device(devlist->devname, mdfd, -- dv->devname); -+ rv = Grow_Add_device(ident.devname, mdfd, dv->devname); - if (rv) - break; - } -@@ -1651,18 +1647,15 @@ int main(int argc, char *argv[]) - } - if (c.delay == 0) - c.delay = DEFAULT_BITMAP_DELAY; -- rv = Grow_addbitmap(devlist->devname, mdfd, &c, &s); -+ rv = Grow_addbitmap(ident.devname, mdfd, &c, &s); - } else if (grow_continue) -- rv = Grow_continue_command(devlist->devname, -- mdfd, c.backup_file, -- c.verbose); -+ rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose); - else if (s.size > 0 || s.raiddisks || s.layout_str || - s.chunk != 0 || s.level != UnSet || - s.data_offset != INVALID_SECTORS) { -- rv = Grow_reshape(devlist->devname, mdfd, -- devlist->next, &c, &s); -+ rv = Grow_reshape(ident.devname, mdfd, devlist->next, &c, &s); - } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { -- rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); -+ rv = Grow_consistency_policy(ident.devname, mdfd, &c, &s); - } else if (array_size == 0) - pr_err("no changes to --grow\n"); - break; -diff --git a/mdadm.h b/mdadm.h -index f0ceeb78..5678eb11 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1531,14 +1531,11 @@ extern int Assemble(struct supertype *st, char *mddev, - struct mddev_dev *devlist, - struct context *c); - --extern int Build(char *mddev, struct mddev_dev *devlist, -- struct shape *s, struct context *c); -- --extern int Create(struct supertype *st, char *mddev, -- char *name, int *uuid, -- int subdevs, struct mddev_dev *devlist, -- struct shape *s, -- struct context *c); -+extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, -+ struct context *c); -+ -+extern int Create(struct supertype *st, struct mddev_ident *ident, int subdevs, -+ struct mddev_dev *devlist, struct shape *s, struct context *c); - - extern int Detail(char *dev, struct context *c); - extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path); --- -2.40.1 - diff --git a/SOURCES/0155-mdadm-refactor-ident-name-handling.patch b/SOURCES/0155-mdadm-refactor-ident-name-handling.patch deleted file mode 100644 index 423b876..0000000 --- a/SOURCES/0155-mdadm-refactor-ident-name-handling.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 67417d9222c505103357191bb0e0ae300892e8a9 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:48 +0200 -Subject: [PATCH 155/165] mdadm: refactor ident->name handling - -Create dedicated setter for name in mddev_ident and propagate it. -Following changes are made: -- move duplicated code from config.c and mdadm.c into new function. -- Add error enum in mdadm.h. -- Use MD_NAME_MAX instead of hardcoded value in mddev_ident. -- Use secure functions. -- Add more detailed verification of the name. -- make error messages reusable for cmdline and config: - - for cmdline, these are errors so use pr_err(). - - for config, these are just warnings, so use pr_info(). - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------ - lib.c | 18 +++++++++++++ - mdadm.c | 12 +++------ - mdadm.h | 20 ++++++++++----- - 4 files changed, 104 insertions(+), 23 deletions(-) - -diff --git a/config.c b/config.c -index 450880e3..a9a0b4f7 100644 ---- a/config.c -+++ b/config.c -@@ -131,6 +131,34 @@ bool is_devname_ignore(char *devname) - return false; - } - -+/** -+ * ident_log() - generate and write message to the user. -+ * @param_name: name of the property. -+ * @value: value of the property. -+ * @reason: meaningful description. -+ * @cmdline: context dependent actions, see below. -+ * -+ * The function is made to provide similar error handling for both config and cmdline. The behavior -+ * is configurable via @cmdline. Message has following format: -+ * "Value "@value" cannot be set for @param_name. Reason: @reason." -+ * -+ * If cmdline is on: -+ * - message is written to stderr. -+ * otherwise: -+ * - message is written to stdout. -+ * - "Value ignored" is added at the end of the message. -+ */ -+static void ident_log(const char *param_name, const char *value, const char *reason, -+ const bool cmdline) -+{ -+ if (cmdline == true) -+ pr_err("Value \"%s\" cannot be set as %s. Reason: %s.\n", value, param_name, -+ reason); -+ else -+ pr_info("Value \"%s\" cannot be set as %s. Reason: %s. Value ignored.\n", value, -+ param_name, reason); -+} -+ - /** - * ident_init() - Set defaults. - * @ident: ident pointer, not NULL. -@@ -159,6 +187,46 @@ inline void ident_init(struct mddev_ident *ident) - ident->uuid_set = 0; - } - -+/** -+ * _ident_set_name()- set name in &mddev_ident. -+ * @ident: pointer to &mddev_ident. -+ * @name: name to be set. -+ * @cmdline: context dependent actions. -+ * -+ * If criteria passed, set name in @ident. -+ * -+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -+ */ -+static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *name, -+ const bool cmdline) -+{ -+ assert(name); -+ assert(ident); -+ -+ const char *prop_name = "name"; -+ -+ if (ident->name[0]) { -+ ident_log(prop_name, name, "Already defined", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) { -+ ident_log(prop_name, name, "Too long or empty", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); -+ return MDADM_STATUS_SUCCESS; -+} -+ -+/** -+ * ident_set_name()- exported, for cmdline. -+ */ -+mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name) -+{ -+ return _ident_set_name(ident, name, true); -+} -+ - struct conf_dev { - struct conf_dev *next; - char *name; -@@ -444,14 +512,7 @@ void arrayline(char *line) - mis.super_minor = minor; - } - } else if (strncasecmp(w, "name=", 5) == 0) { -- if (mis.name[0]) -- pr_err("only specify name once, %s ignored.\n", -- w); -- else if (strlen(w + 5) > 32) -- pr_err("name too long, ignoring %s\n", w); -- else -- strcpy(mis.name, w + 5); -- -+ _ident_set_name(&mis, w + 5, false); - } else if (strncasecmp(w, "bitmap=", 7) == 0) { - if (mis.bitmap_file) - pr_err("only specify bitmap file once. %s ignored\n", -diff --git a/lib.c b/lib.c -index 8a4b48e0..03198e2d 100644 ---- a/lib.c -+++ b/lib.c -@@ -27,6 +27,24 @@ - #include - #include - -+/** -+ * is_string_lq() - Check if string length with NULL byte is lower or equal to requested. -+ * @str: string to check. -+ * @max_len: max length. -+ * -+ * @str length must be bigger than 0 and be lower or equal @max_len, including termination byte. -+ */ -+bool is_string_lq(const char * const str, size_t max_len) -+{ -+ assert(str); -+ -+ size_t _len = strnlen(str, max_len); -+ -+ if (_len > 0 && _len < max_len) -+ return true; -+ return false; -+} -+ - bool is_dev_alive(char *path) - { - if (!path) -diff --git a/mdadm.c b/mdadm.c -index 0a56ed26..8bc9304e 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -690,20 +690,14 @@ int main(int argc, char *argv[]) - case O(CREATE,'N'): - case O(ASSEMBLE,'N'): - case O(MISC,'N'): -- if (ident.name[0]) { -- pr_err("name cannot be set twice. Second value %s.\n", optarg); -- exit(2); -- } - if (mode == MISC && !c.subarray) { - pr_err("-N/--name only valid with --update-subarray in misc mode\n"); - exit(2); - } -- if (strlen(optarg) > 32) { -- pr_err("name '%s' is too long, 32 chars max.\n", -- optarg); -+ -+ if (ident_set_name(&ident, optarg) != MDADM_STATUS_SUCCESS) - exit(2); -- } -- strcpy(ident.name, optarg); -+ - continue; - - case O(ASSEMBLE,'m'): /* super-minor for array */ -diff --git a/mdadm.h b/mdadm.h -index 5678eb11..bbf386d6 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -294,6 +294,11 @@ static inline void __put_unaligned32(__u32 val, void *p) - #define KIB_TO_BYTES(x) ((x) << 10) - #define SEC_TO_BYTES(x) ((x) << 9) - -+/** -+ * This is true for native and DDF, IMSM allows 16. -+ */ -+#define MD_NAME_MAX 32 -+ - extern const char Name[]; - - struct md_bb_entry { -@@ -425,6 +430,12 @@ struct spare_criteria { - unsigned int sector_size; - }; - -+typedef enum mdadm_status { -+ MDADM_STATUS_SUCCESS = 0, -+ MDADM_STATUS_ERROR, -+ MDADM_STATUS_UNDEF, -+} mdadm_status_t; -+ - enum mode { - ASSEMBLE=1, - BUILD, -@@ -593,7 +604,7 @@ struct mddev_ident { - - int uuid_set; - int uuid[4]; -- char name[33]; -+ char name[MD_NAME_MAX + 1]; - - int super_minor; - -@@ -1609,6 +1620,7 @@ extern int check_partitions(int fd, char *dname, - extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); - extern int stat_is_blkdev(char *devname, dev_t *rdev); - -+extern bool is_string_lq(const char * const str, size_t max_len); - extern bool is_dev_alive(char *path); - extern int get_mdp_major(void); - extern int get_maj_min(char *dev, int *major, int *minor); -@@ -1626,6 +1638,7 @@ extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); -+extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name); - - extern int parse_auto(char *str, char *msg, int config); - extern struct mddev_ident *conf_get_ident(char *dev); -@@ -2002,11 +2015,6 @@ enum r0layout { - /* And another special number needed for --data_offset=variable */ - #define VARIABLE_OFFSET 3 - --/** -- * This is true for native and DDF, IMSM allows 16. -- */ --#define MD_NAME_MAX 32 -- - /** - * is_container() - check if @level is &LEVEL_CONTAINER - * @level: level value --- -2.40.1 - diff --git a/SOURCES/0156-mdadm-define-ident_set_devname.patch b/SOURCES/0156-mdadm-define-ident_set_devname.patch deleted file mode 100644 index 8c7441b..0000000 --- a/SOURCES/0156-mdadm-define-ident_set_devname.patch +++ /dev/null @@ -1,249 +0,0 @@ -From ae5f13a971bc309e0e25087421119b86daf2e510 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:49 +0200 -Subject: [PATCH 156/165] mdadm: define ident_set_devname() - -Use dedicated set method for ident->devname. Now, devname validation -is done early for modes where device is created (Build, Create and -Assemble). The rules, used for devname validation are derived from -config file. - -It could cause regression with execeptional cases where existing device -has name which doesn't match criteria for Manage and Grow modes. It is -low risk and those modes are not omitted from early devname validation. -Use can used main numbered devnode to avoid this problem. -Messages exposed to user are changed so it might cause a regression -in negative scenarios. Error codes are not changed. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - config.c | 102 +++++++++++++++++++++++++-------- - mdadm.c | 10 +--- - mdadm.h | 3 +- - tests/00createnames | 3 + - tests/templates/names_template | 7 +++ - 5 files changed, 92 insertions(+), 33 deletions(-) - -diff --git a/config.c b/config.c -index a9a0b4f7..a0424845 100644 ---- a/config.c -+++ b/config.c -@@ -122,7 +122,7 @@ int match_keyword(char *word) - /** - * is_devname_ignore() - check if &devname is a special "" keyword. - */ --bool is_devname_ignore(char *devname) -+bool is_devname_ignore(const char *devname) - { - static const char keyword[] = ""; - -@@ -187,6 +187,74 @@ inline void ident_init(struct mddev_ident *ident) - ident->uuid_set = 0; - } - -+/** -+ * _ident_set_devname()- verify devname and set it in &mddev_ident. -+ * @ident: pointer to &mddev_ident. -+ * @devname: devname to be set. -+ * @cmdline: context dependent actions. If set, ignore keyword is not allowed. -+ * -+ * @devname can have following forms: -+ * '' keyword (if allowed) -+ * /dev/md{number} -+ * /dev/md_d{number} (legacy) -+ * /dev/md_{name} -+ * /dev/md/{name} -+ * {name} - anything that doesn't start from '/' or '<'. -+ * -+ * {name} must follow name's criteria. -+ * If criteria passed, duplicate memory and set devname in @ident. -+ * -+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -+ */ -+mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname, -+ const bool cmdline) -+{ -+ assert(ident); -+ assert(devname); -+ -+ static const char named_dev_pref[] = DEV_NUM_PREF "_"; -+ static const int named_dev_pref_size = sizeof(named_dev_pref) - 1; -+ const char *prop_name = "devname"; -+ const char *name; -+ -+ if (ident->devname) { -+ ident_log(prop_name, devname, "Already defined", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_devname_ignore(devname) == true) { -+ if (!cmdline) -+ goto pass; -+ -+ ident_log(prop_name, devname, "Special keyword is invalid in this context", -+ cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_devname_md_numbered(devname) == true || is_devname_md_d_numbered(devname) == true) -+ goto pass; -+ -+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ name = devname + DEV_MD_DIR_LEN; -+ else if (strncmp(devname, named_dev_pref, named_dev_pref_size) == 0) -+ name = devname + named_dev_pref_size; -+ else -+ name = devname; -+ -+ if (*name == '/' || *name == '<') { -+ ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ -+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) { -+ ident_log(prop_name, devname, "Invalid length", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+pass: -+ ident->devname = xstrdup(devname); -+ return MDADM_STATUS_SUCCESS; -+} -+ - /** - * _ident_set_name()- set name in &mddev_ident. - * @ident: pointer to &mddev_ident. -@@ -219,6 +287,14 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam - return MDADM_STATUS_SUCCESS; - } - -+/** -+ * ident_set_devname()- exported, for cmdline. -+ */ -+mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *name) -+{ -+ return _ident_set_devname(ident, name, true); -+} -+ - /** - * ident_set_name()- exported, for cmdline. - */ -@@ -464,29 +540,7 @@ void arrayline(char *line) - - for (w = dl_next(line); w != line; w = dl_next(w)) { - if (w[0] == '/' || strchr(w, '=') == NULL) { -- /* This names the device, or is ''. -- * The rules match those in create_mddev. -- * 'w' must be: -- * /dev/md/{anything} -- * /dev/mdNN -- * /dev/md_dNN -- * -- * or anything that doesn't start '/' or '<' -- */ -- if (is_devname_ignore(w) == true || -- strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 || -- (w[0] != '/' && w[0] != '<') || -- is_devname_md_numbered(w) == true || -- is_devname_md_d_numbered(w) == true) { -- /* This is acceptable */; -- if (mis.devname) -- pr_err("only give one device per ARRAY line: %s and %s\n", -- mis.devname, w); -- else -- mis.devname = w; -- }else { -- pr_err("%s is an invalid name for an md device - ignored.\n", w); -- } -+ _ident_set_devname(&mis, w, false); - } else if (strncasecmp(w, "uuid=", 5) == 0) { - if (mis.uuid_set) - pr_err("only specify uuid once, %s ignored.\n", -diff --git a/mdadm.c b/mdadm.c -index 8bc9304e..62f981df 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1284,7 +1284,8 @@ int main(int argc, char *argv[]) - pr_err("an md device must be given in this mode\n"); - exit(2); - } -- ident.devname = devlist->devname; -+ if (ident_set_devname(&ident, devlist->devname) != MDADM_STATUS_SUCCESS) -+ exit(1); - - if ((int)ident.super_minor == -2 && c.autof) { - pr_err("--super-minor=dev is incompatible with --auto\n"); -@@ -1301,13 +1302,6 @@ int main(int argc, char *argv[]) - exit(1); - } - } else { -- char *bname = basename(ident.devname); -- -- if (strlen(bname) > MD_NAME_MAX) { -- pr_err("Name %s is too long.\n", ident.devname); -- exit(1); -- } -- - ret = stat(ident.devname, &stb); - if (ident.super_minor == -2 && ret != 0) { - pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", -diff --git a/mdadm.h b/mdadm.h -index bbf386d6..49422e24 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1638,6 +1638,7 @@ extern void manage_fork_fds(int close_all); - extern int continue_via_systemd(char *devnm, char *service_name, char *prefix); - - extern void ident_init(struct mddev_ident *ident); -+extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname); - extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name); - - extern int parse_auto(char *str, char *msg, int config); -@@ -1660,7 +1661,7 @@ extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); --extern bool is_devname_ignore(char *devname); -+extern bool is_devname_ignore(const char *devname); - extern bool is_devname_md_numbered(const char *devname); - extern bool is_devname_md_d_numbered(const char *devname); - extern int conf_verify_devnames(struct mddev_ident *array_list); -diff --git a/tests/00createnames b/tests/00createnames -index 064eeef2..a95e7d2b 100644 ---- a/tests/00createnames -+++ b/tests/00createnames -@@ -39,3 +39,6 @@ mdadm -S "/dev/md0" - names_create "/dev/md0" "name" - names_verify "/dev/md0" "empty" "name" - mdadm -S "/dev/md0" -+ -+# Devnode is a special ignore keyword. Should be rejected. -+names_create "" "name", "true" -diff --git a/tests/templates/names_template b/tests/templates/names_template -index 8d2b5c81..6181bfaa 100644 ---- a/tests/templates/names_template -+++ b/tests/templates/names_template -@@ -2,6 +2,7 @@ - function names_create() { - local DEVNAME=$1 - local NAME=$2 -+ local NEG_TEST=$3 - - if [[ -z "$NAME" ]]; then - mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force -@@ -9,6 +10,12 @@ function names_create() { - mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force - fi - -+ if [[ "$NEG_TEST" == "true" ]]; then -+ [[ "$?" == "0" ]] && return 0 -+ echo "Negative verification failed" -+ exit 1 -+ fi -+ - if [[ "$?" != "0" ]]; then - echo "Cannot create device." - exit 1 --- -2.40.1 - diff --git a/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch b/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch deleted file mode 100644 index 50d2bbb..0000000 --- a/SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch +++ /dev/null @@ -1,471 +0,0 @@ -From e2eb503bd797908f515b58428b274f1ba6a05349 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Jun 2023 09:27:50 +0200 -Subject: [PATCH 157/165] mdadm: Follow POSIX Portable Character Set - -When the user creates a device with a name that contains whitespace, -mdadm timeouts and throws an error. This issue is caused by udev, which -truncates /dev/md link until the first whitespace. - -This patch introduces prohibition of characters other than A-Za-z0-9.-_ -in the device name. Also, it prohibits using leading "-" in device name, -so name won't be confused with cli parameter. -Set of allowed characters is taken from POSIX 3.280 Portable Character -Set. Also, device name length now is limited to NAME_MAX. - -In some places, there are other requirements for string length (e.g. size -up to MD_NAME_MAX for device name). This routine is made to follow POSIX -and other, more strict limitations should be checked separately. -We are aware of the risk of regression in exceptional cases (as -escape_devname function is removed) that should be fixed by updating -the array name. - -The POSIX validation is added for: -- 'name' parameter in every mode. -- first devlist entry, for Build, Create, Assemble, Manage, Grow. -- config entries, both devname and "name=". - -Additionally, some manual cleanups are made. - -Signed-off-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Detail.c | 17 ++++-------- - config.c | 13 ++++++--- - lib.c | 58 ++++++++++++++++++++++++++++----------- - mdadm.8.in | 70 ++++++++++++++++++++--------------------------- - mdadm.conf.5.in | 4 --- - mdadm.h | 2 +- - super-intel.c | 47 ++++++++++++++++--------------- - tests/00confnames | 4 +-- - 8 files changed, 113 insertions(+), 102 deletions(-) - -diff --git a/Detail.c b/Detail.c -index 206d88e3..57ac336f 100644 ---- a/Detail.c -+++ b/Detail.c -@@ -254,11 +254,9 @@ int Detail(char *dev, struct context *c) - fname_from_uuid(st, info, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf + 5); - mp = map_by_uuid(&map, info->uuid); -- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- printf("MD_DEVNAME="); -- print_escape(mp->path + DEV_MD_DIR_LEN); -- putchar('\n'); -- } -+ -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); - - if (st->ss->export_detail_super) - st->ss->export_detail_super(st); -@@ -271,12 +269,9 @@ int Detail(char *dev, struct context *c) - __fname_from_uuid(mp->uuid, 0, nbuf, ':'); - printf("MD_UUID=%s\n", nbuf+5); - } -- if (mp && mp->path && -- strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) { -- printf("MD_DEVNAME="); -- print_escape(mp->path + DEV_MD_DIR_LEN); -- putchar('\n'); -- } -+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) -+ printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN); -+ - map_free(map); - } - if (!c->no_devices && sra) { -diff --git a/config.c b/config.c -index a0424845..5f12a1f8 100644 ---- a/config.c -+++ b/config.c -@@ -199,9 +199,9 @@ inline void ident_init(struct mddev_ident *ident) - * /dev/md_d{number} (legacy) - * /dev/md_{name} - * /dev/md/{name} -- * {name} - anything that doesn't start from '/' or '<'. -+ * {name} - * -- * {name} must follow name's criteria. -+ * {name} must follow name's criteria and be POSIX compatible. - * If criteria passed, duplicate memory and set devname in @ident. - * - * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. -@@ -241,8 +241,8 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname - else - name = devname; - -- if (*name == '/' || *name == '<') { -- ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline); -+ if (is_name_posix_compatible(name) == false) { -+ ident_log(prop_name, name, "Not POSIX compatible", cmdline); - return MDADM_STATUS_ERROR; - } - -@@ -283,6 +283,11 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam - return MDADM_STATUS_ERROR; - } - -+ if (is_name_posix_compatible(name) == false) { -+ ident_log(prop_name, name, "Not POSIX compatible", cmdline); -+ return MDADM_STATUS_ERROR; -+ } -+ - snprintf(ident->name, MD_NAME_MAX + 1, "%s", name); - return MDADM_STATUS_SUCCESS; - } -diff --git a/lib.c b/lib.c -index 03198e2d..7ab59988 100644 ---- a/lib.c -+++ b/lib.c -@@ -483,24 +483,50 @@ void print_quoted(char *str) - putchar(q); - } - --void print_escape(char *str) -+/** -+ * is_alphanum() - Check if sign is letter or digit. -+ * @c: char to analyze. -+ * -+ * Similar to isalnum() but additional locales are excluded. -+ * -+ * Return: %true on success, %false otherwise. -+ */ -+bool is_alphanum(const char c) - { -- /* print str, but change space and tab to '_' -- * as is suitable for device names -- */ -- for (; *str; str++) { -- switch (*str) { -- case ' ': -- case '\t': -- putchar('_'); -- break; -- case '/': -- putchar('-'); -- break; -- default: -- putchar(*str); -- } -+ if (isupper(c) || islower(c) || isdigit(c) != 0) -+ return true; -+ return false; -+} -+ -+/** -+ * is_name_posix_compatible() - Check if name is POSIX compatible. -+ * @name: name to check. -+ * -+ * POSIX portable file name character set contains ASCII letters, -+ * digits, '_', '.', and '-'. Also forbid leading '-'. -+ * The length of the name cannot exceed NAME_MAX - 1 (ensure NULL ending). -+ * -+ * Return: %true on success, %false otherwise. -+ */ -+bool is_name_posix_compatible(const char * const name) -+{ -+ assert(name); -+ -+ char allowed_symbols[] = "-_."; -+ const char *n = name; -+ -+ if (!is_string_lq(name, NAME_MAX)) -+ return false; -+ -+ if (*n == '-') -+ return false; -+ -+ while (*n != '\0') { -+ if (!is_alphanum(*n) && !strchr(allowed_symbols, *n)) -+ return false; -+ n++; - } -+ return true; - } - - int check_env(char *name) -diff --git a/mdadm.8.in b/mdadm.8.in -index b7159509..3142436f 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -364,7 +364,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a - which is managed in a similar manner to DDF, and is supported by an - option-rom on some platforms: - .IP --.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html -+.B https://www.intel.com/content/www/us/en/support/products/122484 - .PP - .RE - -@@ -932,17 +932,14 @@ option will be ignored. - .BR \-N ", " \-\-name= - Set a - .B name --for the array. This is currently only effective when creating an --array with a version-1 superblock, or an array in a DDF container. --The name is a simple textual string that can be used to identify array --components when assembling. If name is needed but not specified, it --is taken from the basename of the device that is being created. --e.g. when creating --.I /dev/md/home --the --.B name --will default to --.IR home . -+for the array. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. This is effective when creating an array -+with a v1 metadata, or an external array. -+ -+If name is needed but not specified, it is taken from the basename of the device -+that is being created. See -+.BR "DEVICE NAMES" - - .TP - .BR \-R ", " \-\-run -@@ -1132,8 +1129,10 @@ is much safer. - - .TP - .BR \-N ", " \-\-name= --Specify the name of the array to assemble. This must be the name --that was specified when creating the array. It must either match -+Specify the name of the array to assemble. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. This must be the name -+that was specified when creating the array. It must either match - the name stored in the superblock exactly, or it must match - with the current - .I homehost -@@ -2179,14 +2178,17 @@ Usage: - .I md-device - .BI \-\-chunk= X - .BI \-\-level= Y --.br - .BI \-\-raid\-devices= Z - .I devices - - .PP --This usage will initialise a new md array, associate some devices with -+This usage will initialize a new md array, associate some devices with - it, and activate the array. - -+.I md-device -+is a new device. This could be standard name or chosen name. For details see: -+.BR "DEVICE NAMES" -+ - The named device will normally not exist when - .I "mdadm \-\-create" - is run, but will be created by -@@ -2227,24 +2229,6 @@ array. This feature can be overridden with the - .B \-\-force - option. - --When creating an array with version-1 metadata a name for the array is --required. --If this is not given with the --.B \-\-name --option, --.I mdadm --will choose a name based on the last component of the name of the --device being created. So if --.B /dev/md3 --is being created, then the name --.B 3 --will be chosen. --If --.B /dev/md/home --is being created, then the name --.B home --will be used. -- - When creating a partition based array, using - .I mdadm - with version-1.x metadata, the partition type should be set to -@@ -2429,12 +2413,10 @@ and - - The - .B name --option updates the subarray name in the metadata, it may not affect the --device node name or the device node symlink until the subarray is --re\-assembled. If updating --.B name --would change the UUID of an active subarray this operation is blocked, --and the command will end in an error. -+option updates the subarray name in the metadata. It must be -+.BR "POSIX PORTABLE NAME" -+compatible and cannot be longer than 32 chars. If successes, new value will be respected after -+next assembly. - - The - .B ppl -@@ -3395,6 +3377,10 @@ When - .B \-\-incremental - mode is used, this file gets a list of arrays currently being created. - -+.SH POSIX PORTABLE NAME -+A valid name can only consist of characters "A-Za-z0-9.-_". -+The name cannot start with a leading "-" and cannot exceed 255 chars. -+ - .SH DEVICE NAMES - - .I mdadm -@@ -3416,6 +3402,10 @@ can be given, or just the suffix of the second sort of name, such as - .I home - can be given. - -+In every style, raw name must be compatible with -+.BR "POSIX PORTABLE NAME" -+and has to be no longer than 32 chars. -+ - When - .I mdadm - chooses device names during auto-assembly or incremental assembly, it -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index bc2295c2..94e23dd0 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -717,10 +717,6 @@ ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b - .br - auto=part - .br --# The name of this array contains a space. --.br --ARRAY /dev/md9 name='Data Storage' --.sp - POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-* - .br - action=spare -diff --git a/mdadm.h b/mdadm.h -index 49422e24..9effb941 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1617,6 +1617,7 @@ extern int check_raid(int fd, char *name); - extern int check_partitions(int fd, char *dname, - unsigned long long freesize, - unsigned long long size); -+extern bool is_name_posix_compatible(const char *path); - extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); - extern int stat_is_blkdev(char *devname, dev_t *rdev); - -@@ -1657,7 +1658,6 @@ extern int conf_get_monitor_delay(void); - extern char *conf_line(FILE *file); - extern char *conf_word(FILE *file, int allow_key); - extern void print_quoted(char *str); --extern void print_escape(char *str); - extern int use_udev(void); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); -diff --git a/super-intel.c b/super-intel.c -index 77b0066f..05d3b056 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5561,40 +5561,37 @@ static void imsm_update_version_info(struct intel_super *super) - } - } - --static int check_name(struct intel_super *super, char *name, int quiet) -+/** -+ * imsm_check_name() - check imsm naming criteria. -+ * @super: &intel_super pointer, not NULL. -+ * @name: name to check. -+ * @verbose: verbose level. -+ * -+ * Name must be no longer than &MAX_RAID_SERIAL_LEN and must be unique across volumes. -+ * -+ * Returns: &true if @name matches, &false otherwise. -+ */ -+static bool imsm_is_name_allowed(struct intel_super *super, const char * const name, -+ const int verbose) - { - struct imsm_super *mpb = super->anchor; -- char *reason = NULL; -- char *start = name; -- size_t len = strlen(name); - int i; - -- if (len > 0) { -- while (isspace(start[len - 1])) -- start[--len] = 0; -- while (*start && isspace(*start)) -- ++start, --len; -- memmove(name, start, len + 1); -+ if (is_string_lq(name, MAX_RAID_SERIAL_LEN + 1) == false) { -+ pr_vrb("imsm: Name \"%s\" is too long\n", name); -+ return false; - } - -- if (len > MAX_RAID_SERIAL_LEN) -- reason = "must be 16 characters or less"; -- else if (len == 0) -- reason = "must be a non-empty string"; -- - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); - - if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) { -- reason = "already exists"; -- break; -+ pr_vrb("imsm: Name \"%s\" already exists\n", name); -+ return false; - } - } - -- if (reason && !quiet) -- pr_err("imsm volume name %s\n", reason); -- -- return !reason; -+ return true; - } - - static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, -@@ -5689,8 +5686,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, - } - } - -- if (!check_name(super, name, 0)) -+ if (imsm_is_name_allowed(super, name, 1) == false) - return 0; -+ - dv = xmalloc(sizeof(*dv)); - dev = xcalloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1)); - /* -@@ -8018,7 +8016,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, - char *ep; - int vol; - -- if (!check_name(super, name, 0)) -+ if (imsm_is_name_allowed(super, name, 1) == false) - return 2; - - vol = strtoul(subarray, &ep, 10); -@@ -10345,7 +10343,8 @@ static void imsm_process_update(struct supertype *st, - if (a->info.container_member == target) - break; - dev = get_imsm_dev(super, u->dev_idx); -- if (a || !check_name(super, name, 1)) { -+ -+ if (a || !dev || imsm_is_name_allowed(super, name, 0) == false) { - dprintf("failed to rename subarray-%d\n", target); - break; - } -diff --git a/tests/00confnames b/tests/00confnames -index 25a7127b..10823f01 100644 ---- a/tests/00confnames -+++ b/tests/00confnames -@@ -79,10 +79,10 @@ names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 11. with some special symbols and locales, no . --# It needs to wait a while for timeout because udev cannot create a link - known issue. -+# should be ignored. - names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config - mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "tźż-\.,<>st+-" "name" -+names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 12. No and set. --- -2.40.1 - diff --git a/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch b/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch deleted file mode 100644 index 68e1e6d..0000000 --- a/SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch +++ /dev/null @@ -1,128 +0,0 @@ -From ba489abd688bf70c83e70700aaaec5f5e90889c5 Mon Sep 17 00:00:00 2001 -From: Coly Li -Date: Mon, 14 Aug 2023 00:46:13 +0800 -Subject: [PATCH 158/165] Incremental: remove obsoleted calls to udisks - -Utility udisks is removed from udev upstream, calling this obsoleted -command in run_udisks() doesn't make any sense now. - -This patch removes the calls chain of udisks, which includes routines -run_udisk(), force_remove(), and 2 locations where force_remove() are -called. Considering force_remove() is removed with udisks util, it is -fair to remove Manage_stop() inside force_remove() as well. - -In the two modifications where calling force_remove() are removed, -the failure from Manage_subdevs() can be safely ignored, because, -1) udisks doesn't exist, no need to check the return value to umount - the file system by udisks and remove the component disk again. -2) After the 'I' inremental remove, there is another 'r' hot remove - following up. The first incremental remove is a best-try effort. - -Therefore in this patch, where force_remove() is removed, the return -value of calling Manage_subdevs() is not checked too. - -Signed-off-by: Coly Li -Reviewed-by: Mariusz Tkaczyk -Cc: Jes Sorensen -Signed-off-by: Jes Sorensen ---- - Incremental.c | 64 +++++++++++---------------------------------------- - 1 file changed, 13 insertions(+), 51 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index f13ce027..05b33c45 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1628,54 +1628,18 @@ release: - return rv; - } - --static void run_udisks(char *arg1, char *arg2) --{ -- int pid = fork(); -- int status; -- if (pid == 0) { -- manage_fork_fds(1); -- execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); -- execl("/bin/udisks", "udisks", arg1, arg2, NULL); -- exit(1); -- } -- while (pid > 0 && wait(&status) != pid) -- ; --} -- --static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose) --{ -- int rv; -- int devid = devnm2devid(devnm); -- -- run_udisks("--unmount", map_dev(major(devid), minor(devid), 0)); -- rv = Manage_stop(devnm, fd, verbose, 1); -- if (rv) { -- /* At least we can try to trigger a 'remove' */ -- sysfs_uevent(mdi, "remove"); -- if (verbose) -- pr_err("Fail to stop %s too.\n", devnm); -- } -- return rv; --} -- - static void remove_from_member_array(struct mdstat_ent *memb, - struct mddev_dev *devlist, int verbose) - { -- int rv; -- struct mdinfo mmdi; - int subfd = open_dev(memb->devnm); - - if (subfd >= 0) { -- rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose, -- 0, UOPT_UNDEFINED, 0); -- if (rv & 2) { -- if (sysfs_init(&mmdi, -1, memb->devnm)) -- pr_err("unable to initialize sysfs for: %s\n", -- memb->devnm); -- else -- force_remove(memb->devnm, subfd, &mmdi, -- verbose); -- } -+ /* -+ * Ignore the return value because it's necessary -+ * to handle failure condition here. -+ */ -+ Manage_subdevs(memb->devnm, subfd, devlist, verbose, -+ 0, UOPT_UNDEFINED, 0); - close(subfd); - } - } -@@ -1758,21 +1722,19 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) - } - free_mdstat(mdstat); - } else { -- rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, -- verbose, 0, UOPT_UNDEFINED, 0); -- if (rv & 2) { -- /* Failed due to EBUSY, try to stop the array. -- * Give udisks a chance to unmount it first. -+ /* -+ * This 'I' incremental remove is a try-best effort, -+ * the failure condition can be safely ignored -+ * because of the following up 'r' remove. - */ -- rv = force_remove(ent->devnm, mdfd, &mdi, verbose); -- goto end; -- } -+ Manage_subdevs(ent->devnm, mdfd, &devlist, -+ verbose, 0, UOPT_UNDEFINED, 0); - } - - devlist.disposition = 'r'; - rv = Manage_subdevs(ent->devnm, mdfd, &devlist, - verbose, 0, UOPT_UNDEFINED, 0); --end: -+ - close(mdfd); - free_mdstat(ent); - return rv; --- -2.40.1 - diff --git a/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch b/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch deleted file mode 100644 index 1493294..0000000 --- a/SOURCES/0159-mdadm-tests-Fix-regular-expression-failure.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 28fc84168646910a9271ebe1a12b1571e14f5900 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Thu, 7 Sep 2023 16:57:44 +0800 -Subject: [PATCH 159/165] mdadm/tests: Fix regular expression failure - -The test fails because of the regular expression. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - tests/06name | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/06name b/tests/06name -index 4d5e824d..86eaab69 100644 ---- a/tests/06name -+++ b/tests/06name -@@ -3,8 +3,8 @@ set -x - # create an array with a name - - mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1 --mdadm -E $dev0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1 --mdadm -D $md0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1 -+mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1 -+mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1 - mdadm -S $md0 - - mdadm -A $md0 --name="Fred" $devlist --- -2.40.1 - diff --git a/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch b/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch deleted file mode 100644 index 311f30a..0000000 --- a/SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch +++ /dev/null @@ -1,141 +0,0 @@ -From ed2c2cb3d440f3bd2692f1896446c4bcc703f05c Mon Sep 17 00:00:00 2001 -From: Li Xiao Keng -Date: Thu, 7 Sep 2023 19:37:44 +0800 -Subject: [PATCH 160/165] Fix race of "mdadm --add" and "mdadm --incremental" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There is a raid1 with sda and sdb. And we add sdc to this raid, -it may return -EBUSY. - -The main process of --add: -1. dev_open(sdc) in Manage_add -2. store_super1(st, di->fd) in write_init_super1 -3. fsync(fd) in store_super1 -4. close(di->fd) in write_init_super1 -5. ioctl(ADD_NEW_DISK) - -Step 2 and 3 will add sdc to metadata of raid1. There will be -udev(change of sdc) event after step4. Then "/usr/sbin/mdadm ---incremental --export $devnode --offroot $env{DEVLINKS}" -will be run, and the sdc will be added to the raid1. Then -step 5 will return -EBUSY because it checks if device isn't -claimed in md_import_device()->lock_rdev()->blkdev_get_by_dev() -->blkdev_get(). - -It will be confusing for users because sdc is added first time. -The "incremental" will get map_lock before add sdc to raid1. -So we add map_lock before write_init_super in "mdadm --add" -to fix the race of "add" and "incremental". - -Signed-off-by: Li Xiao Keng -Signed-off-by: Guanqin Miao -Reviewed-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - Manage.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/Manage.c b/Manage.c -index f997b163..075dd720 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -704,6 +704,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - struct supertype *dev_st; - int j; - mdu_disk_info_t disc; -+ struct map_ent *map = NULL; - - if (!get_dev_size(tfd, dv->devname, &ldsize)) { - if (dv->disposition == 'M') -@@ -907,6 +908,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - disc.raid_disk = 0; - } - -+ if (map_lock(&map)) -+ pr_err("failed to get exclusive lock on mapfile when add disk\n"); -+ - if (array->not_persistent==0) { - int dfd; - if (dv->disposition == 'j') -@@ -918,9 +922,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); - if (tst->ss->add_to_super(tst, &disc, dfd, - dv->devname, INVALID_SECTORS)) -- return -1; -+ goto unlock; - if (tst->ss->write_init_super(tst)) -- return -1; -+ goto unlock; - } else if (dv->disposition == 'A') { - /* this had better be raid1. - * As we are "--re-add"ing we must find a spare slot -@@ -978,14 +982,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - pr_err("add failed for %s: could not get exclusive access to container\n", - dv->devname); - tst->ss->free_super(tst); -- return -1; -+ goto unlock; - } - - /* Check if metadata handler is able to accept the drive */ - if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL, - 0, 0, dv->devname, NULL, 0, 1)) { - close(container_fd); -- return -1; -+ goto unlock; - } - - Kill(dv->devname, NULL, 0, -1, 0); -@@ -994,7 +998,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dv->devname, INVALID_SECTORS)) { - close(dfd); - close(container_fd); -- return -1; -+ goto unlock; - } - if (!mdmon_running(tst->container_devnm)) - tst->ss->sync_metadata(tst); -@@ -1005,7 +1009,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - dv->devname); - close(container_fd); - tst->ss->free_super(tst); -- return -1; -+ goto unlock; - } - sra->array.level = LEVEL_CONTAINER; - /* Need to set data_offset and component_size */ -@@ -1020,7 +1024,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - pr_err("add new device to external metadata failed for %s\n", dv->devname); - close(container_fd); - sysfs_free(sra); -- return -1; -+ goto unlock; - } - ping_monitor(devnm); - sysfs_free(sra); -@@ -1034,7 +1038,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - else - pr_err("add new device failed for %s as %d: %s\n", - dv->devname, j, strerror(errno)); -- return -1; -+ goto unlock; - } - if (dv->disposition == 'j') { - pr_err("Journal added successfully, making %s read-write\n", devname); -@@ -1045,7 +1049,11 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, - } - if (verbose >= 0) - pr_err("added %s\n", dv->devname); -+ map_unlock(&map); - return 1; -+unlock: -+ map_unlock(&map); -+ return -1; - } - - int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, --- -2.40.1 - diff --git a/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch b/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch deleted file mode 100644 index 7d00a5b..0000000 --- a/SOURCES/0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c32b4754014c1eec8cc0c025fad2e9b621486164 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Fri, 8 Sep 2023 16:44:35 +0800 -Subject: [PATCH 161/165] mdadm/tests: Don't run mknod before losetup - -Sometimes it can fail: -losetup: /var/tmp/mdtest0: failed to set up loop device: No such device or address -/dev/loop0 and /var/tmp/mdtest0 are already created before losetup. - -Because losetup can create device node by itself. So remove mknod. - -Signed-off-by: Xiao Ni -Signed-off-by: Jes Sorensen ---- - tests/func.sh | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tests/func.sh b/tests/func.sh -index 9710a53b..5053b012 100644 ---- a/tests/func.sh -+++ b/tests/func.sh -@@ -170,7 +170,6 @@ do_setup() { - dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1 - # make sure udev doesn't touch - mdadm --zero $targetdir/mdtest$d 2> /dev/null -- [ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d - if [ $d -eq 7 ] - then - losetup /dev/loop$d $targetdir/mdtest6 # for multipath use --- -2.40.1 - diff --git a/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch b/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch deleted file mode 100644 index 9c9ad6b..0000000 --- a/SOURCES/0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 246b4b40558f6f7f84882e9c34659f1b582944e2 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Wed, 11 Oct 2023 21:03:32 +0800 -Subject: [PATCH 162/165] mdadm/ddf: Abort when raid disk is smaller in - getinfo_super_ddf -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The metadata is corrupted when the raid_disk<0. So abort directly. -This also can avoid a building error: -super-ddf.c:1988:58: error: array subscript -1 is below array bounds of ‘struct phys_disk_entry[0]’ - -Suggested-by: Mariusz Tkaczyk -Ackedy-by: Xiao Ni -Acked-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super-ddf.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/super-ddf.c b/super-ddf.c -index c5242654..7571e3b7 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1984,12 +1984,14 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m - info->disk.number = be32_to_cpu(ddf->dlist->disk.refnum); - info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum); - -+ if (info->disk.raid_disk < 0) -+ return; -+ - info->data_offset = be64_to_cpu(ddf->phys-> - entries[info->disk.raid_disk]. - config_size); - info->component_size = ddf->dlist->size - info->data_offset; -- if (info->disk.raid_disk >= 0) -- pde = ddf->phys->entries + info->disk.raid_disk; -+ pde = ddf->phys->entries + info->disk.raid_disk; - if (pde && - !(be16_to_cpu(pde->state) & DDF_Failed) && - !(be16_to_cpu(pde->state) & DDF_Missing)) --- -2.40.1 - diff --git a/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch b/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch deleted file mode 100644 index f31d4c6..0000000 --- a/SOURCES/0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 6af520a5b4d91cd0fd32ab6361ff4519505c7f47 Mon Sep 17 00:00:00 2001 -From: Xiao Ni -Date: Tue, 17 Oct 2023 20:35:46 +0800 -Subject: [PATCH 163/165] mdadm/super1: Add MD_FEATURE_RAID0_LAYOUT if - kernel>=5.4 - -After and include kernel v5.4, it adds one feature bit MD_FEATURE_RAID0_LAYOUT. -It must need to specify a layout for raid0 with more than one zone. But for -raid0 with one zone, in fact it also has a defalut layout. - -Now for raid0 with one zone, *unknown* layout can be seen when running mdadm -D -command. It's the reason that mdadm doesn't set MD_FEATURE_RAID0_LAYOUT for -raid0 with one zone. Then in kernel space, super_1_validate sets mddev->layout -to -1 because of no MD_FEATURE_RAID0_LAYOUT. In fact, in raid0 io path, it -uses the default layout. Set raid0_need_layout to true if kernel_version<=v5.4. - -Fixes: 329dfc28debb ('Create: add support for RAID0 layouts.') -Signed-off-by: Xiao Ni -Reviewed-by: Mariusz Tkaczyk -Signed-off-by: Jes Sorensen ---- - super1.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/super1.c b/super1.c -index 856b0208..1da71b98 100644 ---- a/super1.c -+++ b/super1.c -@@ -1967,6 +1967,14 @@ fail_to_write: - return 1; - } - -+static bool has_raid0_layout(struct mdp_superblock_1 *sb) -+{ -+ if (sb->level == 0 && sb->layout != 0) -+ return true; -+ else -+ return false; -+} -+ - static int write_init_super1(struct supertype *st) - { - struct mdp_superblock_1 *sb = st->sb; -@@ -1978,12 +1986,17 @@ static int write_init_super1(struct supertype *st) - unsigned long long sb_offset; - unsigned long long data_offset; - long bm_offset; -- int raid0_need_layout = 0; -+ bool raid0_need_layout = false; -+ -+ /* Since linux kernel v5.4, raid0 always has a layout */ -+ if (has_raid0_layout(sb) && get_linux_version() >= 5004000) -+ raid0_need_layout = true; - - for (di = st->info; di; di = di->next) { - if (di->disk.state & (1 << MD_DISK_JOURNAL)) - sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); -- if (sb->level == 0 && sb->layout != 0) { -+ if (has_raid0_layout(sb) && !raid0_need_layout) { -+ - struct devinfo *di2 = st->info; - unsigned long long s1, s2; - s1 = di->dev_size; -@@ -1995,7 +2008,7 @@ static int write_init_super1(struct supertype *st) - s2 -= di2->data_offset; - s2 /= __le32_to_cpu(sb->chunksize); - if (s1 != s2) -- raid0_need_layout = 1; -+ raid0_need_layout = true; - } - } - --- -2.40.1 - diff --git a/SOURCES/0164-mdadm-remove-container_enough-logic.patch b/SOURCES/0164-mdadm-remove-container_enough-logic.patch deleted file mode 100644 index 2077aab..0000000 --- a/SOURCES/0164-mdadm-remove-container_enough-logic.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 4dde420fc3e24077ab926f79674eaae1b71de10b Mon Sep 17 00:00:00 2001 -From: Pawel Piatkowski -Date: Thu, 19 Oct 2023 16:35:24 +0200 -Subject: [PATCH 164/165] mdadm: remove container_enough logic - -Arrays without enough disk count will be assembled but not -started. -Now RAIDs will be assembled always (even if they are failed). -RAID devices in all states will be assembled and exposed -to mdstat. -This change affects only IMSM (for ddf it wasn't used, -container_enough was set to true always). -Removed this logic from incremental_container as well with -runstop checking because runstop condition is being verified -in assemble_container_content function. - -Signed-off-by: Pawel Piatkowski -Signed-off-by: Jes Sorensen ---- - Incremental.c | 11 ----------- - mdadm.h | 3 --- - super-ddf.c | 1 - - super-intel.c | 32 +------------------------------- - 4 files changed, 1 insertion(+), 46 deletions(-) - -diff --git a/Incremental.c b/Incremental.c -index 05b33c45..3551c65b 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1467,17 +1467,6 @@ static int Incremental_container(struct supertype *st, char *devname, - - st->ss->getinfo_super(st, &info, NULL); - -- if ((c->runstop > 0 && info.container_enough >= 0) || -- info.container_enough > 0) -- /* pass */; -- else { -- if (c->export) { -- printf("MD_STARTED=no\n"); -- } else if (c->verbose) -- pr_err("not enough devices to start the container\n"); -- return 0; -- } -- - match = conf_match(st, &info, devname, c->verbose, &rv); - if (match == NULL && rv == 2) - return rv; -diff --git a/mdadm.h b/mdadm.h -index 9effb941..b48e6f86 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -377,9 +377,6 @@ struct mdinfo { - int container_member; /* for assembling external-metatdata arrays - * This is to be used internally by metadata - * handler only */ -- int container_enough; /* flag external handlers can set to -- * indicate that subarrays have not enough (-1), -- * enough to start (0), or all expected disks (1) */ - char sys_name[32]; - struct mdinfo *devs; - struct mdinfo *next; -diff --git a/super-ddf.c b/super-ddf.c -index 7571e3b7..a87e3169 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1975,7 +1975,6 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m - info->array.ctime = DECADE + __be32_to_cpu(*cptr); - - info->array.chunk_size = 0; -- info->container_enough = 1; - - info->disk.major = 0; - info->disk.minor = 0; -diff --git a/super-intel.c b/super-intel.c -index 05d3b056..6bdd5c4c 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3806,7 +3806,6 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - struct intel_super *super = st->sb; - struct imsm_disk *disk; - int map_disks = info->array.raid_disks; -- int max_enough = -1; - int i; - struct imsm_super *mpb; - -@@ -3848,12 +3847,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- int failed, enough, j, missing = 0; -+ int j = 0; - struct imsm_map *map; -- __u8 state; - -- failed = imsm_count_failed(super, dev, MAP_0); -- state = imsm_check_degraded(super, dev, failed, MAP_0); - map = get_imsm_map(dev, MAP_0); - - /* any newly missing disks? -@@ -3868,36 +3864,10 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - if (!(ord & IMSM_ORD_REBUILD) && - get_imsm_missing(super, idx)) { -- missing = 1; - break; - } - } -- -- if (state == IMSM_T_STATE_FAILED) -- enough = -1; -- else if (state == IMSM_T_STATE_DEGRADED && -- (state != map->map_state || missing)) -- enough = 0; -- else /* we're normal, or already degraded */ -- enough = 1; -- if (is_gen_migration(dev) && missing) { -- /* during general migration we need all disks -- * that process is running on. -- * No new missing disk is allowed. -- */ -- max_enough = -1; -- enough = -1; -- /* no more checks necessary -- */ -- break; -- } -- /* in the missing/failed disk case check to see -- * if at least one array is runnable -- */ -- max_enough = max(max_enough, enough); - } -- dprintf("enough: %d\n", max_enough); -- info->container_enough = max_enough; - - if (super->disks) { - __u32 reserved = imsm_reserved_sectors(super, super->disks); --- -2.40.1 - diff --git a/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch b/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch deleted file mode 100644 index 0db1767..0000000 --- a/SOURCES/0165-Fix-assembling-RAID-volume-by-using-incremental.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d8d09c1633b2f06f88633ab960aa02b41a6bdfb6 Mon Sep 17 00:00:00 2001 -From: Pawel Piatkowski -Date: Thu, 19 Oct 2023 16:35:25 +0200 -Subject: [PATCH 165/165] Fix assembling RAID volume by using incremental - -After change "mdadm: remove container_enough logic" -IMSM volumes are started immediately. If volume is during -reshape, then it will be blocked by block_subarray() during -first mdadm -I . Assemble_container_content() for -next disk will see the change because metadata version from -sysfs and metadata doesn't match and will execute -sysfs_set_array again. Then it fails to set same -component_size, it is prohibited by kernel. - -If array is frozen then first sign from metadata version -is different ("/" vs "-"), so exclude it from comparison. -All we want is to double check that base properties are set -and we don't need to call sysfs_set_array again. - -Signed-off-by: Pawel Piatkowski -Signed-off-by: Jes Sorensen ---- - Assemble.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/Assemble.c b/Assemble.c -index 5be58e40..0557a007 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -1990,12 +1990,10 @@ int assemble_container_content(struct supertype *st, int mdfd, - return 1; - } - -- if (strcmp(sra->text_version, content->text_version) != 0) { -- if (content->array.major_version == -1 && -- content->array.minor_version == -2 && -- c->readonly && -- content->text_version[0] == '/') -- content->text_version[0] = '-'; -+ /* Fill sysfs properties only if they are not set. Determine it by checking text_version -+ * and ignoring special character on the first place. -+ */ -+ if (strcmp(sra->text_version + 1, content->text_version + 1) != 0) { - if (sysfs_set_array(content, 9003) != 0) { - sysfs_free(sra); - return 1; --- -2.40.1 - diff --git a/SOURCES/0166-Revert-mdadm-remove-container_enough-logic.patch b/SOURCES/0166-Revert-mdadm-remove-container_enough-logic.patch deleted file mode 100644 index 943fd9d..0000000 --- a/SOURCES/0166-Revert-mdadm-remove-container_enough-logic.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 476b00bdeeb6c004b3a758bd842b0fa9e4164508 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Mon, 5 Feb 2024 15:50:29 +0100 -Subject: [PATCH 1/1] Revert "mdadm: remove container_enough logic" - -Mentioned patch changes way of IMSM member arrays assembling, they are -updated by every new drive incremental processes. Previously, member -arrays were created and filled once, by last drive incremental process. - -We determined regressions with various impact. Unfortunately, initial -testing didn't show them. - -Regressions are connected to drive appearance order and may not be -reproducible on every configuration, there are at least two know -issues for now: - -- sysfs attributes are filled using old metadata if there is - outdated drive and it is enumerated first. - -- rebuild may be aborted and started from beginning after reboot, - if drive under rebuild is enumerated as the last one. - -This reverts commit 4dde420fc3e24077ab926f79674eaae1b71de10b. It fixes -checkpatch issues and reworks logic to remove empty "if" branch in -Incremental. - -Signed-off-by: Mariusz Tkaczyk ---- - Incremental.c | 9 +++++++++ - mdadm.h | 7 +++++++ - super-ddf.c | 1 + - super-intel.c | 32 +++++++++++++++++++++++++++++++- - 4 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/Incremental.c b/Incremental.c -index 6cbc164a27b9..30c07c037028 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -1467,6 +1467,15 @@ static int Incremental_container(struct supertype *st, char *devname, - - st->ss->getinfo_super(st, &info, NULL); - -+ if (info.container_enough < 0 || (info.container_enough == 0 && c->runstop < 1)) { -+ if (c->export) -+ printf("MD_STARTED=no\n"); -+ else if (c->verbose) -+ pr_err("Not enough devices to start the container.\n"); -+ -+ return 0; -+ } -+ - match = conf_match(st, &info, devname, c->verbose, &rv); - if (match == NULL && rv == 2) - return rv; -diff --git a/mdadm.h b/mdadm.h -index 709b6104c401..1f28b3e754be 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -377,6 +377,13 @@ struct mdinfo { - int container_member; /* for assembling external-metatdata arrays - * This is to be used internally by metadata - * handler only */ -+ /** -+ * flag external handlers can set to indicate that subarrays have: -+ * - not enough disks to start (-1), -+ * - enough disks to start (0), -+ * - all expected disks (1). -+ */ -+ int container_enough; - char sys_name[32]; - struct mdinfo *devs; - struct mdinfo *next; -diff --git a/super-ddf.c b/super-ddf.c -index a87e3169d325..7571e3b740c6 100644 ---- a/super-ddf.c -+++ b/super-ddf.c -@@ -1975,6 +1975,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m - info->array.ctime = DECADE + __be32_to_cpu(*cptr); - - info->array.chunk_size = 0; -+ info->container_enough = 1; - - info->disk.major = 0; - info->disk.minor = 0; -diff --git a/super-intel.c b/super-intel.c -index 6a664a2e58d3..dbea235dd4bd 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -3778,6 +3778,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - struct intel_super *super = st->sb; - struct imsm_disk *disk; - int map_disks = info->array.raid_disks; -+ int max_enough = -1; - int i; - struct imsm_super *mpb; - -@@ -3819,9 +3820,12 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - for (i = 0; i < mpb->num_raid_devs; i++) { - struct imsm_dev *dev = get_imsm_dev(super, i); -- int j = 0; -+ int failed, enough, j, missing = 0; - struct imsm_map *map; -+ __u8 state; - -+ failed = imsm_count_failed(super, dev, MAP_0); -+ state = imsm_check_degraded(super, dev, failed, MAP_0); - map = get_imsm_map(dev, MAP_0); - - /* any newly missing disks? -@@ -3836,11 +3840,37 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * - - if (!(ord & IMSM_ORD_REBUILD) && - get_imsm_missing(super, idx)) { -+ missing = 1; - break; - } - } -+ -+ if (state == IMSM_T_STATE_FAILED) -+ enough = -1; -+ else if (state == IMSM_T_STATE_DEGRADED && -+ (state != map->map_state || missing)) -+ enough = 0; -+ else /* we're normal, or already degraded */ -+ enough = 1; -+ if (is_gen_migration(dev) && missing) { -+ /* during general migration we need all disks -+ * that process is running on. -+ * No new missing disk is allowed. -+ */ -+ max_enough = -1; -+ enough = -1; -+ /* no more checks necessary -+ */ -+ break; -+ } -+ /* in the missing/failed disk case check to see -+ * if at least one array is runnable -+ */ -+ max_enough = max(max_enough, enough); - } - -+ info->container_enough = max_enough; -+ - if (super->disks) { - __u32 reserved = imsm_reserved_sectors(super, super->disks); - --- -2.32.0 (Apple Git-132) - diff --git a/SOURCES/0167-manage-adjust-checking-subarray-state-in-update_suba.patch b/SOURCES/0167-manage-adjust-checking-subarray-state-in-update_suba.patch deleted file mode 100644 index ed47f29..0000000 --- a/SOURCES/0167-manage-adjust-checking-subarray-state-in-update_suba.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 582945c2d3bbead4a71de521a392e292a4a84e24 Mon Sep 17 00:00:00 2001 -From: Pawel Piatkowski -Date: Wed, 20 Dec 2023 10:32:49 +0100 -Subject: [PATCH 1/1] manage: adjust checking subarray state in update_subarray - -Only changing bitmap related consistency_policy requires -subarray to be inactive. -consistency_policy with PPL or NO_PPL value can be changed on -active subarray. -It fixes regression introduced in commit -db10eab68e652f141169 ("Fix --update-subarray on active volume") - -Signed-off-by: Pawel Piatkowski -Signed-off-by: Mariusz Tkaczyk ---- - Manage.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/Manage.c b/Manage.c -index f0d4cb01..91532266 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -1749,6 +1749,7 @@ int Update_subarray(char *dev, char *subarray, enum update_opt update, - int fd, rv = 2; - struct mdinfo *info = NULL; - char *update_verb = map_num(update_options, update); -+ bool allow_active = update == UOPT_PPL || update == UOPT_NO_PPL; - - memset(st, 0, sizeof(*st)); - -@@ -1763,7 +1764,7 @@ int Update_subarray(char *dev, char *subarray, enum update_opt update, - goto free_super; - } - -- if (is_subarray_active(subarray, st->devnm)) { -+ if (!allow_active && is_subarray_active(subarray, st->devnm)) { - if (verbose >= 0) - pr_err("Subarray %s in %s is active, cannot update %s\n", - subarray, dev, update_verb); --- -2.40.1 - diff --git a/SOURCES/0168-super1-remove-support-for-name-in-config.patch b/SOURCES/0168-super1-remove-support-for-name-in-config.patch deleted file mode 100644 index 39aa777..0000000 --- a/SOURCES/0168-super1-remove-support-for-name-in-config.patch +++ /dev/null @@ -1,267 +0,0 @@ -From dcc22ae74a864358b812327a423435b541789a36 Mon Sep 17 00:00:00 2001 -From: Mariusz Tkaczyk -Date: Thu, 1 Feb 2024 12:32:41 +0100 -Subject: [PATCH 1/1] super1: remove support for name= in config - -Only super1 provides "name=" to config. It is recoreded in metadata -so there is no need to duplicate same information. -UUID is our main key. - -It is not used by Incremental and Assemble handles empty name well -because other supertypes don't set it in conf. - -Expectation that the name in config is same as in metadata is bug prone. -Config should be the place where use can define customized settings. - -Remove printing "name=" from mdadm config creation commands. Ignore -the name in config file to keep backward compatibility. Remove -description from man mdadm.conf. - -Update 00conftest because "name" is no longer accepted. -As the name is ignored, error for mdadm --detail is not printed. - -Reported-by: Stefan Fleischmann -Fixes: e2eb503bd797 ("mdadm: Follow POSIX Portable Character Set") -Signed-off-by: Mariusz Tkaczyk ---- - config.c | 12 ++---- - mdadm.conf.5.in | 7 --- - super1.c | 8 ---- - tests/00confnames | 79 ++++++---------------------------- - tests/templates/names_template | 7 +-- - 5 files changed, 19 insertions(+), 94 deletions(-) - -diff --git a/config.c b/config.c -index 9a04cae8..44f7dd2f 100644 ---- a/config.c -+++ b/config.c -@@ -262,6 +262,7 @@ pass: - * @cmdline: context dependent actions. - * - * If criteria passed, set name in @ident. -+ * Note: name is not used by config file, it for cmdline only. - * - * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR. - */ -@@ -571,7 +572,8 @@ void arrayline(char *line) - mis.super_minor = minor; - } - } else if (strncasecmp(w, "name=", 5) == 0) { -- _ident_set_name(&mis, w + 5, false); -+ /* Ignore name in confile */ -+ continue; - } else if (strncasecmp(w, "bitmap=", 7) == 0) { - if (mis.bitmap_file) - pr_err("only specify bitmap file once. %s ignored\n", -@@ -1279,13 +1281,7 @@ struct mddev_ident *conf_match(struct supertype *st, - array_list->devname); - continue; - } -- if (array_list->name[0] && -- strcasecmp(array_list->name, info->name) != 0) { -- if (verbose >= 2 && array_list->devname) -- pr_err("Name differs from %s.\n", -- array_list->devname); -- continue; -- } -+ - if (array_list->devices && devname && - !match_oneof(array_list->devices, devname)) { - if (verbose >= 2 && array_list->devname) -diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in -index 94e23dd0..787e51e9 100644 ---- a/mdadm.conf.5.in -+++ b/mdadm.conf.5.in -@@ -133,13 +133,6 @@ The value should be a 128 bit uuid in hexadecimal, with punctuation - interspersed if desired. This must match the uuid stored in the - superblock. - .TP --.B name= --The value should be a simple textual name as was given to --.I mdadm --when the array was created. This must match the name stored in the --superblock on a device for that device to be included in the array. --Not all superblock formats support names. --.TP - .B super\-minor= - The value is an integer which indicates the minor number that was - stored in the superblock when the array was created. When an array is -diff --git a/super1.c b/super1.c -index dfde4629..5fd2228e 100644 ---- a/super1.c -+++ b/super1.c -@@ -645,10 +645,6 @@ static void brief_examine_super1(struct supertype *st, int verbose) - printf(":"); - printf("%02x", sb->set_uuid[i]); - } -- if (sb->set_name[0]) { -- printf(" name="); -- print_quoted(sb->set_name); -- } - printf("\n"); - } - -@@ -875,10 +871,6 @@ static void brief_detail_super1(struct supertype *st, char *subarray) - struct mdp_superblock_1 *sb = st->sb; - int i; - -- if (sb->set_name[0]) { -- printf(" name="); -- print_quoted(sb->set_name); -- } - printf(" UUID="); - for (i = 0; i < 16; i++) { - if ((i & 3) == 0 && i != 0) -diff --git a/tests/00confnames b/tests/00confnames -index 10823f01..191a905f 100644 ---- a/tests/00confnames -+++ b/tests/00confnames -@@ -1,10 +1,8 @@ - set -x -e - . tests/templates/names_template - --# Test how and from config are handled during Incremental assemblation. --# 1-6 only tests (no in config). --# 6-10 and combinations are tested. --# 11-13 corner cases. -+# Test how is handled during Incremental assemblation with -+# config file and ARRAYLINE specified. - - names_create "/dev/md/name" - local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)" -@@ -12,96 +10,47 @@ local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)" - - - # 1. definition consistent with metadata name. --names_make_conf $_UUID "/dev/md/name" "empty" $config -+names_make_conf $_UUID "/dev/md/name" $config - mdadm -S "/dev/md127" - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 2. Same as 1, but use short name form of . --names_make_conf $_UUID "name" "empty" $config -+names_make_conf $_UUID "name" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - - # 3. Same as 1, but use different than metadata provides. --names_make_conf $_UUID "/dev/md/other" "empty" $config -+names_make_conf $_UUID "/dev/md/other" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "other" "name" - mdadm -S "/dev/md127" - - # 4. Same as 3, but use short name form of . --names_make_conf $_UUID "other" "empty" $config -+names_make_conf $_UUID "other" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "other" "name" - mdadm -S "/dev/md127" - --# 5. Force particular node creation by setting to /dev/mdX. Link is not created in this --# case. --names_make_conf $_UUID "/dev/md4" "empty" $config -+# 5. Force particular node creation by setting to /dev/mdX. -+# Link is not created in this case. -+names_make_conf $_UUID "/dev/md4" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md4" "empty" "name" - mdadm -S "/dev/md4" - --# 6. set to /dev/mdX, same as in metadata. --# Metadata name and default node used - controversial. Current behavior documented. --names_make_conf $_UUID "/dev/md22" "name" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 7. set to /dev/mdX, different than in metadata. --# Metadata name and default node used - controversial. Current behavior documented. --names_make_conf $_UUID "/dev/md8" "other" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 8. Both and different than in metadata. --# Metadata name and default node used - controversial. Current behavior documented. --names_make_conf $_UUID "devnode" "other_name" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 9. set to metadata name, different than in metadata. --# Metadata name and default node used - controversial. Current behavior documented. --names_make_conf $_UUID "name" "other_name" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 10. Bad set, no . --# Metadata name and default node used - expected. --names_make_conf $_UUID "/im/bad/devname" "empty" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 11. with some special symbols and locales, no . -+# 6. with some special symbols and locales. - # should be ignored. --names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 12. No and set. --# Metadata name and default node used - expected. --names_make_conf $_UUID "empty" "empty" $config --mdadm -I $dev0 --config=$config --names_verify "/dev/md127" "name" "name" --mdadm -S "/dev/md127" -- --# 13. No , set to /dev/mdX. --# Entry should be ignored, it is not ignored but result is good anyway. --names_make_conf $_UUID "empty" "/dev/md12" $config -+names_make_conf $_UUID "tźż-\.,<>st+-" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" - --# 13. No , with special symbols and locales. --# Entry should be ignored, it is not ignored but result is good anyway. --names_make_conf $_UUID "empty" "./\śćń#&" $config -+# 7. No set. -+# Metadata name and default node used. -+names_make_conf $_UUID "empty" $config - mdadm -I $dev0 --config=$config - names_verify "/dev/md127" "name" "name" - mdadm -S "/dev/md127" -diff --git a/tests/templates/names_template b/tests/templates/names_template -index 6181bfaa..1b6cd14b 100644 ---- a/tests/templates/names_template -+++ b/tests/templates/names_template -@@ -63,8 +63,7 @@ function names_verify() { - names_make_conf() { - local UUID="$1" - local WANTED_DEVNAME="$2" -- local WANTED_NAME="$3" -- local CONF="$4" -+ local CONF="$3" - - local LINE="ARRAY metadata=1.2 UUID=$UUID" - -@@ -72,9 +71,5 @@ names_make_conf() { - LINE="$LINE $WANTED_DEVNAME" - fi - -- if [[ "$WANTED_NAME" != "empty" ]]; then -- LINE="$LINE name=$WANTED_NAME" -- fi -- - echo $LINE > $CONF - } --- -2.41.0 - diff --git a/SOURCES/0169-Mdmonitor-Improve-udev-event-handling.patch b/SOURCES/0169-Mdmonitor-Improve-udev-event-handling.patch deleted file mode 100644 index 205500c..0000000 --- a/SOURCES/0169-Mdmonitor-Improve-udev-event-handling.patch +++ /dev/null @@ -1,564 +0,0 @@ -From 9935cf0f64f3f1e70e7840385e9838c30487dc64 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Tue, 21 Nov 2023 01:58:23 +0100 -Subject: [PATCH 1/2] Mdmonitor: Improve udev event handling - -Mdmonitor is waiting for udev queue to become empty. -Even if the queue becomes empty, udev might still be processing last event. -However we want to wait and wake up mdmonitor when udev finished -processing events.. - -Also, the udev queue interface is considered legacy and should not be -used outside of udev. - -Use udev monitor instead, and wake up mdmonitor on every event triggered -by udev for md block device. - -We need to generate more change events from kernel, because they are -missing in some situations, for example, when rebuild started. -This will be addressed in a separate patch. - -Move udev specific code into separate functions, and place them in udev.c file. -Also move use_udev() logic from lib.c into newly created file. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Makefile | 18 +++---- - Manage.c | 3 +- - Monitor.c | 137 ++++++++++++++++++------------------------------- - lib.c | 13 ----- - mdadm.h | 1 + - mdopen.c | 7 +-- - udev.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - udev.h | 37 ++++++++++++++ - 8 files changed, 253 insertions(+), 113 deletions(-) - create mode 100644 udev.c - create mode 100644 udev.h - -diff --git a/Makefile b/Makefile -index b3aa36f6..cbdba49a 100644 ---- a/Makefile -+++ b/Makefile -@@ -163,14 +163,14 @@ else - ECHO=: - endif - --OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o \ -- Manage.o Assemble.o Build.o \ -- Create.o Detail.o Examine.o Grow.o Monitor.o dlink.o Kill.o Query.o \ -- Incremental.o Dump.o \ -- mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \ -- super-mbr.o super-gpt.o \ -- restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \ -- platform-intel.o probe_roms.o crc32c.o -+OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o udev.o \ -+ Manage.o Assemble.o Build.o \ -+ Create.o Detail.o Examine.o Grow.o Monitor.o dlink.o Kill.o Query.o \ -+ Incremental.o Dump.o \ -+ mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \ -+ super-mbr.o super-gpt.o \ -+ restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \ -+ platform-intel.o probe_roms.o crc32c.o - - CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o - -@@ -179,7 +179,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 config.o mapfile.o mdopen.o\ -- policy.o lib.o \ -+ policy.o lib.o udev.o \ - Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \ - super-mbr.o super-gpt.o \ - super-ddf.o sha1.o crc32.o msg.o bitmap.o xmalloc.o \ -diff --git a/Manage.c b/Manage.c -index 075dd720..f0d4cb01 100644 ---- a/Manage.c -+++ b/Manage.c -@@ -25,6 +25,7 @@ - #include "mdadm.h" - #include "md_u.h" - #include "md_p.h" -+#include "udev.h" - #include - - int Manage_ro(char *devname, int fd, int readonly) -@@ -462,7 +463,7 @@ done: - goto out; - } - -- if (devnm[0] && use_udev()) { -+ if (devnm[0] && udev_is_available()) { - struct map_ent *mp = map_by_devnm(&map, devnm); - remove_devices(devnm, mp ? mp->path : NULL); - } -diff --git a/Monitor.c b/Monitor.c -index e74a0558..9a1f2514 100644 ---- a/Monitor.c -+++ b/Monitor.c -@@ -23,18 +23,17 @@ - */ - - #include "mdadm.h" -+#include "udev.h" - #include "md_p.h" - #include "md_u.h" - #include - #include - #include --#ifndef NO_LIBUDEV --#include --#endif - - #define TASK_COMM_LEN 16 - #define EVENT_NAME_MAX 32 - #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" -+#define FALLBACK_DELAY 5 - - /** - * struct state - external array or container properties. -@@ -126,12 +125,11 @@ 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 wait_for_events(int *delay_for_event, int c_delay); -+static void wait_for_events_mdstat(int *delay_for_event, int c_delay); - static int write_autorebuild_pid(void); - - int Monitor(struct mddev_dev *devlist, -@@ -326,32 +324,12 @@ int Monitor(struct mddev_dev *devlist, - if (!new_found) { - if (oneshot) - break; -- else if (!anyredundant) { -+ if (!anyredundant) { - pr_err("No array with redundancy detected, stopping\n"); - break; - } -- else { --#ifndef NO_LIBUDEV -- /* -- * Wait for udevd to finish new devices -- * processing. -- */ -- if (mdstat_wait(delay_for_event) && -- check_udev_activity()) -- pr_err("Error while waiting for UDEV to complete new devices processing\n"); --#else -- int wait_result = mdstat_wait(delay_for_event); -- /* -- * Give chance to process new device -- */ -- if (wait_result != 0) { -- if (c->delay > 5) -- delay_for_event = 5; -- } else -- delay_for_event = c->delay; --#endif -- mdstat_close(); -- } -+ -+ wait_for_events(&delay_for_event, c->delay); - } - info.test = 0; - -@@ -374,6 +352,49 @@ int Monitor(struct mddev_dev *devlist, - return 0; - } - -+/* -+ * wait_for_events() - Waits for events on md devices. -+ * @delay_for_event: pointer to current event delay -+ * @c_delay: delay from config -+ */ -+static void wait_for_events(int *delay_for_event, int c_delay) -+{ -+#ifndef NO_LIBUDEV -+ if (udev_is_available()) { -+ if (udev_wait_for_events(*delay_for_event) == UDEV_STATUS_ERROR) -+ pr_err("Error while waiting for udev events.\n"); -+ return; -+ } -+#endif -+ wait_for_events_mdstat(delay_for_event, c_delay); -+} -+ -+/* -+ * wait_for_events_mdstat() - Waits for events on mdstat. -+ * @delay_for_event: pointer to current event delay -+ * @c_delay: delay from config -+ */ -+static void wait_for_events_mdstat(int *delay_for_event, int c_delay) -+{ -+ int wait_result = mdstat_wait(*delay_for_event); -+ -+ if (wait_result < 0) { -+ pr_err("Error while waiting for events on mdstat.\n"); -+ return; -+ } -+ -+ /* -+ * Give chance to process new device -+ */ -+ if (wait_result != 0) { -+ if (c_delay > FALLBACK_DELAY) -+ *delay_for_event = FALLBACK_DELAY; -+ } else { -+ *delay_for_event = c_delay; -+ } -+ mdstat_close(); -+} -+ - static int make_daemon(char *pidfile) - { - /* Return: -@@ -1254,64 +1275,6 @@ static void free_statelist(struct state *statelist) - } - } - --#ifndef NO_LIBUDEV --/* function: check_udev_activity -- * Description: Function waits for udev to finish -- * events processing. -- * Returns: -- * 1 - detected error while opening udev -- * 2 - timeout -- * 0 - successfull completion -- */ --static int check_udev_activity(void) --{ -- struct udev *udev = NULL; -- struct udev_queue *udev_queue = NULL; -- int timeout_cnt = 30; -- int rc = 0; -- -- /* -- * In rare cases systemd may not have udevm, -- * in such cases just exit with rc 0 -- */ -- if (!use_udev()) -- goto out; -- -- udev = udev_new(); -- if (!udev) { -- rc = 1; -- goto out; -- } -- -- udev_queue = udev_queue_new(udev); -- if (!udev_queue) { -- rc = 1; -- goto out; -- } -- -- if (udev_queue_get_queue_is_empty(udev_queue)) -- goto out; -- -- while (!udev_queue_get_queue_is_empty(udev_queue)) { -- sleep(1); -- -- if (timeout_cnt) -- timeout_cnt--; -- else { -- rc = 2; -- goto out; -- } -- } -- --out: -- if (udev_queue) -- udev_queue_unref(udev_queue); -- if (udev) -- udev_unref(udev); -- return rc; --} --#endif -- - /* Not really Monitor but ... */ - int Wait(char *dev) - { -diff --git a/lib.c b/lib.c -index 7ab59988..cf2701cd 100644 ---- a/lib.c -+++ b/lib.c -@@ -539,19 +539,6 @@ int check_env(char *name) - return 0; - } - --int use_udev(void) --{ -- static int use = -1; -- struct stat stb; -- -- if (use < 0) { -- use = ((stat("/dev/.udev", &stb) == 0 || -- stat("/run/udev", &stb) == 0) && -- check_env("MDADM_NO_UDEV") == 0); -- } -- return use; --} -- - unsigned long GCD(unsigned long a, unsigned long b) - { - while (a != b) { -diff --git a/mdadm.h b/mdadm.h -index b48e6f86..9514cbe5 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1656,6 +1656,7 @@ extern char *conf_line(FILE *file); - extern char *conf_word(FILE *file, int allow_key); - extern void print_quoted(char *str); - extern int use_udev(void); -+extern void print_escape(char *str); - extern unsigned long GCD(unsigned long a, unsigned long b); - extern int conf_name_is_free(char *name); - extern bool is_devname_ignore(const char *devname); -diff --git a/mdopen.c b/mdopen.c -index 3daa71f9..f9b04e1c 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -23,6 +23,7 @@ - */ - - #include "mdadm.h" -+#include "udev.h" - #include "md_p.h" - #include - -@@ -176,7 +177,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - char devnm[32]; - char cbuf[400]; - -- if (!use_udev()) -+ if (!udev_is_available()) - block_udev = 0; - - if (chosen == NULL) -@@ -384,7 +385,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - * If we cannot detect udev, we need to make - * devices and links ourselves. - */ -- if (!use_udev()) { -+ if (!udev_is_available()) { - /* Make sure 'devname' exists and 'chosen' is a symlink to it */ - if (lstat(devname, &stb) == 0) { - /* Must be the correct device, else error */ -@@ -508,7 +509,7 @@ char *find_free_devnm(int use_partitions) - continue; - if (!conf_name_is_free(devnm)) - continue; -- if (!use_udev()) { -+ if (!udev_is_available()) { - /* make sure it is new to /dev too, at least as a - * non-standard */ - dev_t devid = devnm2devid(devnm); -diff --git a/udev.c b/udev.c -new file mode 100644 -index 00000000..2bac6921 ---- /dev/null -+++ b/udev.c -@@ -0,0 +1,150 @@ -+/* -+ * mdadm - manage Linux "md" devices aka RAID arrays. -+ * -+ * Copyright (C) 2022 Mateusz Grzonka -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include "mdadm.h" -+#include "udev.h" -+#include "md_p.h" -+#include "md_u.h" -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * udev_is_available() - Checks for udev in the system. -+ * -+ * Function looks whether udev directories are available and MDADM_NO_UDEV env defined. -+ * -+ * Return: -+ * true if udev is available, -+ * false if not -+ */ -+bool udev_is_available(void) -+{ -+ struct stat stb; -+ -+ if (stat("/dev/.udev", &stb) != 0 && -+ stat("/run/udev", &stb) != 0) -+ return false; -+ if (check_env("MDADM_NO_UDEV") == 1) -+ return false; -+ return true; -+} -+ -+#ifndef NO_LIBUDEV -+ -+static struct udev *udev; -+static struct udev_monitor *udev_monitor; -+ -+/* -+ * udev_release() - Drops references of udev and udev_monitor. -+ */ -+static void udev_release(void) -+{ -+ udev_monitor_unref(udev_monitor); -+ udev_unref(udev); -+} -+ -+/* -+ * udev_initialize() - Initializes udev and udev_monitor structures. -+ * -+ * Function initializes udev, udev_monitor, and sets udev_monitor filter for block devices. -+ * -+ * Return: -+ * UDEV_STATUS_SUCCESS on success -+ * UDEV_STATUS_ERROR on error -+ * UDEV_STATUS_ERROR_NO_UDEV when udev not available -+ */ -+static enum udev_status udev_initialize(void) -+{ -+ if (!udev_is_available()) { -+ pr_err("No udev.\n"); -+ return UDEV_STATUS_ERROR_NO_UDEV; -+ } -+ -+ udev = udev_new(); -+ if (!udev) { -+ pr_err("Cannot initialize udev.\n"); -+ return UDEV_STATUS_ERROR; -+ } -+ -+ udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); -+ if (!udev_monitor) { -+ pr_err("Cannot initialize udev monitor.\n"); -+ udev = udev_unref(udev); -+ return UDEV_STATUS_ERROR; -+ } -+ -+ if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", 0) < 0) { -+ pr_err("Cannot add udev monitor event filter for md devices.\n"); -+ udev_release(); -+ return UDEV_STATUS_ERROR; -+ } -+ if (udev_monitor_enable_receiving(udev_monitor) < 0) { -+ pr_err("Cannot enable receiving udev events through udev monitor.\n"); -+ udev_release(); -+ return UDEV_STATUS_ERROR; -+ } -+ atexit(udev_release); -+ return UDEV_STATUS_SUCCESS; -+} -+ -+/* -+ * udev_wait_for_events() - Waits for events from udev. -+ * @seconds: Timeout in seconds. -+ * -+ * Function waits udev events, wakes up on event or timeout. -+ * -+ * Return: -+ * UDEV_STATUS_SUCCESS on detected event -+ * UDEV_STATUS_TIMEOUT on timeout -+ * UDEV_STATUS_ERROR on error -+ */ -+enum udev_status udev_wait_for_events(int seconds) -+{ -+ int fd; -+ fd_set readfds; -+ struct timeval tv; -+ int ret; -+ -+ if (!udev || !udev_monitor) { -+ ret = udev_initialize(); -+ if (ret != UDEV_STATUS_SUCCESS) -+ return ret; -+ } -+ -+ fd = udev_monitor_get_fd(udev_monitor); -+ if (fd < 0) { -+ pr_err("Cannot access file descriptor associated with udev monitor.\n"); -+ return UDEV_STATUS_ERROR; -+ } -+ -+ FD_ZERO(&readfds); -+ FD_SET(fd, &readfds); -+ tv.tv_sec = seconds; -+ tv.tv_usec = 0; -+ -+ if (select(fd + 1, &readfds, NULL, NULL, &tv) > 0 && FD_ISSET(fd, &readfds)) -+ if (udev_monitor_receive_device(udev_monitor)) -+ return UDEV_STATUS_SUCCESS; /* event detected */ -+ return UDEV_STATUS_TIMEOUT; -+} -+#endif -diff --git a/udev.h b/udev.h -new file mode 100644 -index 00000000..33884861 ---- /dev/null -+++ b/udev.h -@@ -0,0 +1,37 @@ -+/* -+ * mdadm - manage Linux "md" devices aka RAID arrays. -+ * -+ * Copyright (C) 2022 Mateusz Grzonka -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#ifndef MONITOR_UDEV_H -+#define MONITOR_UDEV_H -+ -+enum udev_status { -+ UDEV_STATUS_ERROR_NO_UDEV = -2, -+ UDEV_STATUS_ERROR, -+ UDEV_STATUS_SUCCESS = 0, -+ UDEV_STATUS_TIMEOUT -+}; -+ -+bool udev_is_available(void); -+ -+#ifndef NO_LIBUDEV -+enum udev_status udev_wait_for_events(int seconds); -+#endif -+ -+#endif --- -2.41.0 - diff --git a/SOURCES/0170-udev-Move-udev_block-and-udev_unblock-into-udev.c.patch b/SOURCES/0170-udev-Move-udev_block-and-udev_unblock-into-udev.c.patch deleted file mode 100644 index 9555dde..0000000 --- a/SOURCES/0170-udev-Move-udev_block-and-udev_unblock-into-udev.c.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 9f376da6439b07dc93ae084ab576e133b9d8d839 Mon Sep 17 00:00:00 2001 -From: Mateusz Grzonka -Date: Tue, 21 Nov 2023 01:58:24 +0100 -Subject: [PATCH 2/2] udev: Move udev_block() and udev_unblock() into udev.c - -Add kernel style comments and better error handling. - -Signed-off-by: Mateusz Grzonka -Signed-off-by: Kinga Tanska -Signed-off-by: Jes Sorensen ---- - Create.c | 1 + - lib.c | 29 ----------------------------- - mdadm.h | 2 -- - mdopen.c | 12 ++++++------ - udev.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - udev.h | 3 +++ - 6 files changed, 54 insertions(+), 37 deletions(-) - -diff --git a/Create.c b/Create.c -index a280c7bc..ddd1a79b 100644 ---- a/Create.c -+++ b/Create.c -@@ -23,6 +23,7 @@ - */ - - #include "mdadm.h" -+#include "udev.h" - #include "md_u.h" - #include "md_p.h" - #include -diff --git a/lib.c b/lib.c -index cf2701cd..2b09293c 100644 ---- a/lib.c -+++ b/lib.c -@@ -204,35 +204,6 @@ char *fd2devnm(int fd) - return NULL; - } - --/* When we create a new array, we don't want the content to -- * be immediately examined by udev - it is probably meaningless. -- * So create /run/mdadm/creating-mdXXX and expect that a udev -- * rule will noticed this and act accordingly. -- */ --static char block_path[] = "/run/mdadm/creating-%s"; --static char *unblock_path = NULL; --void udev_block(char *devnm) --{ -- int fd; -- char *path = NULL; -- -- xasprintf(&path, block_path, devnm); -- fd = open(path, O_CREAT|O_RDWR, 0600); -- if (fd >= 0) { -- close(fd); -- unblock_path = path; -- } else -- free(path); --} -- --void udev_unblock(void) --{ -- if (unblock_path) -- unlink(unblock_path); -- free(unblock_path); -- unblock_path = NULL; --} -- - /* - * convert a major/minor pair for a block device into a name in /dev, if possible. - * On the first call, walk /dev collecting name. -diff --git a/mdadm.h b/mdadm.h -index 9514cbe5..8dcd8b86 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1765,8 +1765,6 @@ 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); - - extern int in_initrd(void); - -diff --git a/mdopen.c b/mdopen.c -index f9b04e1c..eaa59b59 100644 ---- a/mdopen.c -+++ b/mdopen.c -@@ -336,8 +336,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - devnm[0] = 0; - if (num < 0 && cname && ci->names) { - sprintf(devnm, "md_%s", cname); -- if (block_udev) -- udev_block(devnm); -+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS) -+ return -1; - if (!create_named_array(devnm)) { - devnm[0] = 0; - udev_unblock(); -@@ -345,8 +345,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - } - if (num >= 0) { - sprintf(devnm, "md%d", num); -- if (block_udev) -- udev_block(devnm); -+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS) -+ return -1; - if (!create_named_array(devnm)) { - devnm[0] = 0; - udev_unblock(); -@@ -369,8 +369,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, - return -1; - } - } -- if (block_udev) -- udev_block(devnm); -+ if (block_udev && udev_block(devnm) != UDEV_STATUS_SUCCESS) -+ return -1; - create_named_array(devnm); - } - -diff --git a/udev.c b/udev.c -index 2bac6921..bc4722b0 100644 ---- a/udev.c -+++ b/udev.c -@@ -28,6 +28,8 @@ - #include - #include - -+static char *unblock_path; -+ - /* - * udev_is_available() - Checks for udev in the system. - * -@@ -148,3 +150,45 @@ enum udev_status udev_wait_for_events(int seconds) - return UDEV_STATUS_TIMEOUT; - } - #endif -+ -+/* -+ * udev_block() - Block udev from examining newly created arrays. -+ * -+ * When array is created, we don't want udev to examine it immediately. -+ * Function creates /run/mdadm/creating-mdXXX and expects that udev rule -+ * will notice it and act accordingly. -+ * -+ * Return: -+ * UDEV_STATUS_SUCCESS when successfully blocked udev -+ * UDEV_STATUS_ERROR on error -+ */ -+enum udev_status udev_block(char *devnm) -+{ -+ int fd; -+ char *path = xcalloc(1, BUFSIZ); -+ -+ snprintf(path, BUFSIZ, "/run/mdadm/creating-%s", devnm); -+ -+ fd = open(path, O_CREAT | O_RDWR, 0600); -+ if (!is_fd_valid(fd)) { -+ pr_err("Cannot block udev, error creating blocking file.\n"); -+ pr_err("%s: %s\n", strerror(errno), path); -+ free(path); -+ return UDEV_STATUS_ERROR; -+ } -+ -+ close(fd); -+ unblock_path = path; -+ return UDEV_STATUS_SUCCESS; -+} -+ -+/* -+ * udev_unblock() - Unblock udev. -+ */ -+void udev_unblock(void) -+{ -+ if (unblock_path) -+ unlink(unblock_path); -+ free(unblock_path); -+ unblock_path = NULL; -+} -diff --git a/udev.h b/udev.h -index 33884861..ae0a3617 100644 ---- a/udev.h -+++ b/udev.h -@@ -34,4 +34,7 @@ bool udev_is_available(void); - enum udev_status udev_wait_for_events(int seconds); - #endif - -+enum udev_status udev_block(char *devnm); -+void udev_unblock(void); -+ - #endif --- -2.41.0 - diff --git a/SOURCES/0172-mdadm-Increase-number-limit-in-md-device-name-to-102.patch b/SOURCES/0172-mdadm-Increase-number-limit-in-md-device-name-to-102.patch deleted file mode 100644 index 9857686..0000000 --- a/SOURCES/0172-mdadm-Increase-number-limit-in-md-device-name-to-102.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f786072a3e2928766a9b4f1b7d3372a601c259ea Mon Sep 17 00:00:00 2001 -From: Shminderjit Singh -Date: Mon, 26 Aug 2024 10:06:50 +0000 -Subject: [PATCH 1/1] mdadm: Increase number limit in md device name to 1024. - -Updated the maximum device number in md device names from 127 to 1024. -The previous limit was causing issues in the automation framework. -This change ensures backward compatibility and allows for future -scalability. - -Fixes: 25aa7329141c ("mdadm: numbered names verification") -Signed-off-by: Shminderjit Singh ---- - util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util.c b/util.c -index 1cee0feb..2fc0e9f8 100644 ---- a/util.c -+++ b/util.c -@@ -1003,7 +1003,7 @@ static bool is_devname_numbered(const char *devname, const char *pref, const int - if (parse_num(&val, devname + pref_len) != 0) - return false; - -- if (val > 127) -+ if (val > 1024) - return false; - - return true; --- -2.48.1 - diff --git a/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch deleted file mode 100644 index 188b478..0000000 --- a/SOURCES/mdadm-2.5.2-static.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- mdadm-3.2.1/Makefile.static 2021-01-11 15:46:47.292126848 +0800 -+++ mdadm-3.2.1/Makefile 2021-01-11 15:46:10.720192519 +0800 -@@ -248,16 +248,16 @@ - install : install-bin install-man install-udev - - install-static : mdadm.static install-man -- $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm -+ $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static - - install-tcc : mdadm.tcc install-man -- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm -+ $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm.tcc - - install-uclibc : mdadm.uclibc install-man -- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm -+ $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm.uclibc - - install-klibc : mdadm.klibc install-man -- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm -+ $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm.klibc - - install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 - $(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8 diff --git a/SOURCES/mdadm-alloc-st-in-Assemble.patch b/SOURCES/mdadm-alloc-st-in-Assemble.patch deleted file mode 100644 index 1098ee0..0000000 --- a/SOURCES/mdadm-alloc-st-in-Assemble.patch +++ /dev/null @@ -1,183 +0,0 @@ -diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c ---- mdadm-4.2/Assemble.c 2025-10-25 11:46:59.647889913 +0800 -+++ mdadm-4.2-fix/Assemble.c 2025-10-25 11:37:18.437758159 +0800 -@@ -1337,10 +1337,8 @@ - return 1; - } - --int Assemble(struct supertype *st, char *mddev, -- struct mddev_ident *ident, -- struct mddev_dev *devlist, -- struct context *c) -+int Assemble(char *mddev, struct mddev_ident *ident, -+ struct mddev_dev *devlist, struct context *c) - { - /* - * The task of Assemble is to find a collection of -@@ -1427,6 +1425,7 @@ - char chosen_name[1024]; - struct map_ent *map = NULL; - struct map_ent *mp; -+ struct supertype *st = NULL; - - /* - * If any subdevs are listed, then any that don't -@@ -1447,6 +1446,15 @@ - return 1; - } - -+ if (c->metadata) { -+ for (i = 0; !st && superlist[i]; i++) -+ st = superlist[i]->match_metadata_desc(c->metadata); -+ if (!st) { -+ pr_err("unrecognised metadata identifier: %s\n", c->metadata); -+ return -EINVAL; -+ } -+ } -+ - if (devlist == NULL) - devlist = conf_get_devs(); - else if (mddev) -@@ -1468,11 +1476,15 @@ - st->ignore_hw_compat = 1; - num_devs = select_devices(devlist, ident, &st, &content, c, - inargv, auto_assem); -- if (num_devs < 0) -- return 1; -+ if (num_devs < 0) { -+ rv = 1; -+ goto free_st; -+ } - -- if (!st || !st->sb || !content) -- return 2; -+ if (!st || !st->sb || !content) { -+ rv = 2; -+ goto free_st; -+ } - - /* We have a full set of devices - we now need to find the - * array device. -@@ -1603,11 +1615,10 @@ - - if (content != &info) { - /* This is a member of a container. Try starting the array. */ -- int err; -- err = assemble_container_content(st, mdfd, content, c, -+ rv = assemble_container_content(st, mdfd, content, c, - chosen_name, NULL); - close(mdfd); -- return err; -+ goto free_st; - } - - /* Ok, no bad inconsistancy, we can try updating etc */ -@@ -1961,9 +1972,19 @@ - /* '2' means 'OK, but not started yet' */ - if (rv == -1) { - free(devices); -- return 1; -+ rv = 1; -+ goto free_st; - } -- return rv == 2 ? 0 : rv; -+ -+ if (rv == 2) -+ rv = 0; -+free_st: -+ if (st) { -+ st->ss->free_super(st); -+ free(st); -+ } -+ -+ return rv; - } - - int assemble_container_content(struct supertype *st, int mdfd, -diff -Naur mdadm-4.2/mdadm.c mdadm-4.2-fix/mdadm.c ---- mdadm-4.2/mdadm.c 2025-10-25 11:46:59.527825090 +0800 -+++ mdadm-4.2-fix/mdadm.c 2025-10-25 11:42:17.331226086 +0800 -@@ -71,6 +71,7 @@ - */ - struct context c = { - .require_homehost = 1, -+ .metadata = NULL, - }; - struct shape s = { - .journaldisks = 0, -@@ -402,6 +403,7 @@ - pr_err("unrecognised metadata identifier: %s\n", optarg); - exit(2); - } -+ c.metadata = optarg; - continue; - - case O(MANAGE,'W'): -@@ -1427,10 +1429,10 @@ - } else { - if (array_ident->autof == 0) - array_ident->autof = c.autof; -- rv |= Assemble(ss, ident.devname, array_ident, NULL, &c); -+ rv |= Assemble(ident.devname, array_ident, NULL, &c); - } - } else if (!c.scan) -- rv = Assemble(ss, ident.devname, &ident, devlist->next, &c); -+ rv = Assemble(ident.devname, &ident, devlist->next, &c); - else if (devs_found > 0) { - if (c.update && devs_found > 1) { - pr_err("can only update a single array at a time\n"); -@@ -1450,8 +1452,7 @@ - } - if (array_ident->autof == 0) - array_ident->autof = c.autof; -- rv |= Assemble(ss, dv->devname, array_ident, -- NULL, &c); -+ rv |= Assemble(dv->devname, array_ident, NULL, &c); - } - } else { - if (c.update) { -@@ -1736,8 +1737,7 @@ - if (a->devname && is_devname_ignore(a->devname) == true) - continue; - -- r = Assemble(ss, a->devname, -- a, NULL, c); -+ r = Assemble(a->devname, a, NULL, c); - if (r == 0) { - a->assembled = 1; - successes++; -@@ -1759,9 +1759,7 @@ - struct mddev_dev *devlist = conf_get_devs(); - acnt = 0; - do { -- rv2 = Assemble(ss, NULL, -- ident, -- devlist, c); -+ rv2 = Assemble(NULL, ident, devlist, c); - if (rv2 == 0) { - cnt++; - acnt++; -diff -Naur mdadm-4.2/mdadm.h mdadm-4.2-fix/mdadm.h ---- mdadm-4.2/mdadm.h 2025-10-25 11:46:59.716186280 +0800 -+++ mdadm-4.2-fix/mdadm.h 2025-10-25 11:43:13.999603357 +0800 -@@ -662,6 +662,7 @@ - char *action; - int nodes; - char *homecluster; -+ char *metadata; - }; - - struct shape { -@@ -1541,10 +1542,8 @@ - extern int Grow_continue_command(char *devname, int fd, - char *backup_file, int verbose); - --extern int Assemble(struct supertype *st, char *mddev, -- struct mddev_ident *ident, -- struct mddev_dev *devlist, -- struct context *c); -+extern int Assemble(char *mddev, struct mddev_ident *ident, -+ struct mddev_dev *devlist, struct context *c); - - extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s, - struct context *c); diff --git a/SOURCES/mdadm-cron b/SOURCES/mdadm-cron deleted file mode 100644 index 4e05d68..0000000 --- a/SOURCES/mdadm-cron +++ /dev/null @@ -1,3 +0,0 @@ -# Run system wide raid-check once a week on Sunday at 1am by default -0 1 * * Sun root /usr/sbin/raid-check - diff --git a/SOURCES/mdmonitor.init b/SOURCES/mdmonitor.init deleted file mode 100755 index 03f3e95..0000000 --- a/SOURCES/mdmonitor.init +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash -# -# mdmonitor This starts, stops, and reloads the mdadm-based -# software RAID monitoring and management facility -# -# chkconfig: 2345 15 85 -# description: software RAID monitoring and management -# config: /etc/mdadm.conf -# -# Copyright 2002 Red Hat, Inc. -# -### BEGIN INIT INFO -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start and stop the MD software RAID monitor -# Description: The mdmonitor service checks the status of all software -# RAID arrays on the system. In the event that any of the arrays -# transition into a degraded state, it notifies the system -# administrator. Other options are available, see the mdadm.conf -# and mdadm man pages for possible ways to configure this service. -### END INIT INFO - -PIDPATH=/var/run/mdadm -PIDFILE=/var/run/mdadm/mdadm.pid -PATH=/sbin:/usr/sbin:$PATH -RETVAL=0 -OPTIONS="--monitor --scan -f --pid-file=$PIDFILE" - -prog=mdmonitor - -# Source function library. -. /etc/rc.d/init.d/functions - - -usage () -{ - echo "Usage: service $prog {start|stop|status|restart|try-restart|force-reload}" - RETVAL=1 -} - - -start () -{ -# (Re)start mdmon to take over monitoring of mdmon started from the initrd - for i in /dev/md/*.pid; do - if [ -r $i ]; then - origprog="$prog"; prog="mdmon" - action $"Starting $prog: " /sbin/mdmon --takeover --all - prog="$origprog" - break - fi - done -# Make sure configuration file exists and has information we can use -# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor - [ -f /etc/mdadm.conf ] || return 6 - grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || return 6 - # Create our directory if it isn't there yet - if [ ! -d $PIDPATH ]; then - mkdir -m 0700 $PIDPATH >&/dev/null - RC=$? - [ -x /sbin/restorecon ] && /sbin/restorecon $PIDPATH - if [ $RC -ne 0 ]; then - echo -n "Failed to create /var/run/mdadm" - failure - echo - return 1 - fi - fi - if [ -f "$PIDFILE" ]; then - checkpid `cat $PIDFILE` && return 0 - fi - echo -n $"Starting $prog: " - cd / - daemon --user=root mdadm ${OPTIONS} - ret=$? - [ $ret -eq "0" ] && touch /var/lock/subsys/$prog - echo - return $ret -} - -stop () -{ - [ -f /var/lock/subsys/$prog ] || return 0 - echo -n "Killing $prog: " - killproc mdadm - echo - rm -f $PIDFILE - rm -f /var/lock/subsys/$prog -} - -restart () -{ - stop - start -} - -condrestart () -{ - [ -e /var/lock/subsys/$prog ] && restart || return 0 -} - - -case "$1" in - start|stop|restart|condrestart|try-restart|force-reload) - [ `id -u` != "0" ] && exit 4 ;; -esac - -case "$1" in - start) start; RETVAL=$? ;; - stop) stop; RETVAL=$? ;; - status) status -p $PIDFILE $prog ; RETVAL=$? ;; - restart) restart; RETVAL=$? ;; - reload) RETVAL=3 ;; - condrestart|try-restart|force-reload) condrestart; RETVAL=$? ;; - *) usage ; RETVAL=2 ;; -esac - -exit $RETVAL diff --git a/SOURCES/raid0-layout.patch b/SOURCES/raid0-layout.patch deleted file mode 100644 index 96161c0..0000000 --- a/SOURCES/raid0-layout.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- mdadm/super1-orig.c 2023-11-10 19:27:25.262178162 +0800 -+++ mdadm/super1.c 2023-11-10 19:28:25.991441827 +0800 -@@ -1988,8 +1988,7 @@ - long bm_offset; - bool raid0_need_layout = false; - -- /* Since linux kernel v5.4, raid0 always has a layout */ -- if (has_raid0_layout(sb) && get_linux_version() >= 5004000) -+ if (has_raid0_layout(sb)) - raid0_need_layout = true; - - for (di = st->info; di; di = di->next) { diff --git a/md-auto-readd.rule b/md-auto-readd.rule new file mode 100644 index 0000000..5ce29fb --- /dev/null +++ b/md-auto-readd.rule @@ -0,0 +1,27 @@ +# +# Enable/Disable - default is Disabled +# to disable this rule, GOTO="md_end" should be the first active command. +# to enable this rule, Comment out GOTO="md_end". +GOTO="md_end" + +# Required: MD arrays must have a bitmap for transient devices to +# be added back in the array. +# mdadm -CR /dev/md0 -l1 -n2 /dev/sd[ab] –bitmap=internal + +# Don't process any events if anaconda is running as anaconda brings up +# raid devices manually +ENV{ANACONDA}=="?*", GOTO="md_end" + +# Also don't process disks that are slated to be a multipath device +ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end" + +# We process add events on block devices (since they are ready as soon as +# they are added to the system) + +ACTION!="add", GOTO="md_end" +ENV{ID_FS_TYPE}!="linux_raid_member", GOTO="md_end" +SUBSYSTEM=="block", RUN{program}+="/usr/sbin/md-auto-readd.sh $devnode" + +# +# Land here to exit cleanly +LABEL="md_end" diff --git a/md-auto-readd.sh b/md-auto-readd.sh new file mode 100755 index 0000000..f15c482 --- /dev/null +++ b/md-auto-readd.sh @@ -0,0 +1,17 @@ +#!/usr/bin/bash +MDADM=/sbin/mdadm +DEVNAME=$1 + +export $(${MDADM} --examine --export ${DEVNAME}) +if [ -z "${MD_UUID}" ]; then + exit 1 +fi + +UUID_LINK=$(readlink /dev/disk/by-id/md-uuid-${MD_UUID}) +MD_DEVNAME=${UUID_LINK##*/} +export $(${MDADM} --detail --export /dev/${MD_DEVNAME}) +if [ -z "${MD_METADATA}" ] ; then + exit 1 +fi + +${MDADM} --manage /dev/${MD_DEVNAME} --re-add ${DEVNAME} --verbose diff --git a/mdadm-2.5.2-static.patch b/mdadm-2.5.2-static.patch new file mode 100644 index 0000000..44f38e6 --- /dev/null +++ b/mdadm-2.5.2-static.patch @@ -0,0 +1,11 @@ +--- mdadm/Makefile.orig 2025-04-30 05:17:02.238426018 -0400 ++++ mdadm/Makefile 2025-04-30 05:17:15.299183058 -0400 +@@ -277,7 +277,7 @@ + install : install-bin install-man install-udev + + install-static : mdadm.static install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static + + install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 + $(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8 diff --git a/mdadm-fix-building-errors.patch b/mdadm-fix-building-errors.patch new file mode 100644 index 0000000..03025ad --- /dev/null +++ b/mdadm-fix-building-errors.patch @@ -0,0 +1,64 @@ +From 46940fbca6df3ddffa71541e459a277d79584fc0 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 30 Apr 2025 06:47:08 -0400 +Subject: [PATCH 1/1] mdadm: fix building errors + +This is a rhel-only patch and this patch will be sent to upstream. + +Signed-off-by: Xiao Ni +--- + super-ddf.c | 9 +++++---- + super-intel.c | 2 +- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 6e7db924..285d3b8b 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1606,9 +1606,9 @@ static void examine_vd(int n, struct ddf_super *sb, char *guid) + map_num(ddf_sec_level, vc->srl) ?: "-unknown-"); + } + printf(" Device Size[%d] : %llu\n", n, +- be64_to_cpu(vc->blocks)/2); ++ (unsigned long long)(be64_to_cpu(vc->blocks)/2)); + printf(" Array Size[%d] : %llu\n", n, +- be64_to_cpu(vc->array_blocks)/2); ++ (unsigned long long)(be64_to_cpu(vc->array_blocks)/2)); + } + } + +@@ -1665,7 +1665,7 @@ static void examine_pds(struct ddf_super *sb) + printf(" %3d %08x ", i, + be32_to_cpu(pd->refnum)); + printf("%8lluK ", +- be64_to_cpu(pd->config_size)>>1); ++ (unsigned long long)be64_to_cpu(pd->config_size)>>1); + for (dl = sb->dlist; dl ; dl = dl->next) { + if (be32_eq(dl->disk.refnum, pd->refnum)) { + char *dv = map_dev(dl->major, dl->minor, 0); +@@ -2901,7 +2901,8 @@ static unsigned int find_unused_pde(const struct ddf_super *ddf) + static void _set_config_size(struct phys_disk_entry *pde, const struct dl *dl) + { + __u64 cfs, t; +- cfs = min(dl->size - 32*1024*2ULL, be64_to_cpu(dl->primary_lba)); ++ cfs = min((unsigned long long)dl->size - 32*1024*2ULL, ++ (unsigned long long)be64_to_cpu(dl->primary_lba)); + t = be64_to_cpu(dl->secondary_lba); + if (t != ~(__u64)0) + cfs = min(cfs, t); +diff --git a/super-intel.c b/super-intel.c +index b7b030a2..caa583d8 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2325,7 +2325,7 @@ static void export_examine_super_imsm(struct supertype *st) + printf("MD_LEVEL=container\n"); + printf("MD_UUID=%s\n", nbuf+5); + printf("MD_DEVICES=%u\n", mpb->num_disks); +- printf("MD_CREATION_TIME=%llu\n", __le64_to_cpu(mpb->creation_time)); ++ printf("MD_CREATION_TIME=%llu\n", (unsigned long long)__le64_to_cpu(mpb->creation_time)); + } + + static void detail_super_imsm(struct supertype *st, char *homehost, +-- +2.41.0 + diff --git a/SOURCES/mdadm-raid-check-sysconfig b/mdadm-raid-check-sysconfig old mode 100644 new mode 100755 similarity index 100% rename from SOURCES/mdadm-raid-check-sysconfig rename to mdadm-raid-check-sysconfig diff --git a/SOURCES/mdadm-udev.patch b/mdadm-udev.patch similarity index 100% rename from SOURCES/mdadm-udev.patch rename to mdadm-udev.patch diff --git a/mdadm-use-standard-libc-nftw.patch b/mdadm-use-standard-libc-nftw.patch new file mode 100644 index 0000000..c92cea8 --- /dev/null +++ b/mdadm-use-standard-libc-nftw.patch @@ -0,0 +1,53 @@ +commit e549ac6ab2ce5e7ec182310f8f5f2e41c6ac9233 +Author: Xiao Ni +Date: Wed May 7 18:06:59 2025 +0800 + + mdadm: use standard libc nftw + + commit bd648e3bec3d ("mdadm: Remove klibc and uclibc support") removes + macro HAVE_NFTW/HAVE_FTW and uses libc header ftw.h. But it leaves the + codes in lib.c which let mdadm command call nftw defined in lib.c. It + needs to remove these codes. + + The bug can be reproduced by: + mdadm -CR /dev/md0 --level raid5 --metadata=1.1 --chunk=32 --raid-disks 3 + --size 10000 /dev/loop1 /dev/loop2 /dev/loop3 + mdadm /dev/md0 --grow --chunk=64 + mdadm: /dev/md0: cannot open component -unknown- + + Fixes: bd648e3bec3d ("mdadm: Remove klibc and uclibc support") + Signed-off-by: Xiao Ni + +diff --git a/lib.c b/lib.c +index f36ae03a..eb6cc119 100644 +--- a/lib.c ++++ b/lib.c +@@ -245,28 +245,6 @@ int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s) + return 0; + } + +-#ifndef HAVE_NFTW +-#ifdef HAVE_FTW +-int add_dev_1(const char *name, const struct stat *stb, int flag) +-{ +- return add_dev(name, stb, flag, NULL); +-} +-int nftw(const char *path, +- int (*han)(const char *name, const struct stat *stb, +- int flag, struct FTW *s), int nopenfd, int flags) +-{ +- return ftw(path, add_dev_1, nopenfd); +-} +-#else +-int nftw(const char *path, +- int (*han)(const char *name, const struct stat *stb, +- int flag, struct FTW *s), int nopenfd, int flags) +-{ +- return 0; +-} +-#endif /* HAVE_FTW */ +-#endif /* HAVE_NFTW */ +- + /* + * Find a block device with the right major/minor number. + * If we find multiple names, choose the shortest. diff --git a/SOURCES/mdadm.conf b/mdadm.conf similarity index 100% rename from SOURCES/mdadm.conf rename to mdadm.conf diff --git a/SPECS/mdadm.spec b/mdadm.spec similarity index 68% rename from SPECS/mdadm.spec rename to mdadm.spec index dcffbf0..16cf318 100644 --- a/SPECS/mdadm.spec +++ b/mdadm.spec @@ -1,212 +1,82 @@ -Summary: The mdadm program controls Linux md devices (software RAID arrays) +%bcond abrt %{undefined rhel} + Name: mdadm -Version: 4.2 +Version: 4.4 # extraversion is used to define rhel internal version -%define extraversion 19 -Release: %{extraversion}%{?dist} -Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}%{?subversion:-%{subversion}}.tar.xz -Source1: mdmonitor.init -Source2: raid-check -Source3: mdadm-raid-check-sysconfig -Source4: mdadm-cron -Source5: mdmonitor.service -Source6: mdadm.conf -Source7: mdadm_event.conf -Source8: mdcheck - -Patch000: 0001-Unify-error-message.patch -Patch001: 0002-mdadm-Fix-double-free.patch -Patch002: 0003-Grow_reshape-Add-r0-grow-size-error-message-and-upda.patch -Patch003: 0004-udev-adapt-rules-to-systemd-v247.patch -Patch004: 0005-Replace-error-prone-signal-with-sigaction.patch -Patch005: 0006-mdadm-Respect-config-file-location-in-man.patch -Patch006: 0007-mdadm-Update-ReadMe.patch -Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch -Patch008: 0009-mdadm-Update-config-manual.patch -Patch009: 0010-Create-Build-use-default_layout.patch -Patch010: 0011-mdadm-add-map_num_s.patch -Patch011: 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch -Patch012: 0013-mdmon-Stop-parsing-duplicate-options.patch -Patch013: 0014-Grow-block-n-on-external-volumes.patch -Patch014: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch -Patch015: 0016-Mdmonitor-Fix-segfault.patch -Patch016: 0017-Mdmonitor-Improve-logging-method.patch -Patch017: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch -Patch018: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch -Patch019: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch -Patch020: 0021-util-replace-ioctl-use-with-function.patch -Patch021: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch -Patch022: 0023-imsm-introduce-get_disk_slot_in_dev.patch -Patch023: 0024-imsm-use-same-slot-across-container.patch -Patch024: 0025-imsm-block-changing-slots-during-creation.patch -Patch025: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch -Patch026: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch -Patch027: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch -Patch028: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch -Patch029: 0030-Monitor-use-snprintf-to-fill-device-name.patch -Patch030: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch -Patch031: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch -Patch032: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch -Patch033: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch -Patch034: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch -Patch035: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch -Patch036: 0037-mdadm-Fix-optional-write-behind-parameter.patch -Patch037: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch -Patch038: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch -Patch039: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch -Patch040: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch -Patch041: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch -Patch042: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch -Patch043: 0044-tests-Add-broken-files-for-all-broken-tests.patch -Patch044: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch -Patch045: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch -Patch046: 0047-tests-add-test-for-names.patch -Patch047: 0048-mdadm-remove-symlink-option.patch -Patch048: 0049-mdadm-move-data_offset-to-struct-shape.patch -Patch049: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch -Patch050: 0051-Grow-Split-Grow_reshape-into-helper-function.patch -Patch051: 0052-Assemble-check-if-device-is-container-before-schedul.patch -Patch052: 0053-super1-report-truncated-device.patch -Patch053: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch -Patch054: 0055-Manage-Block-unsafe-member-failing.patch -Patch055: 0056-Monitor-Fix-statelist-memory-leaks.patch -Patch056: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch -Patch057: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch -Patch058: 0059-ReadMe-fix-command-line-help.patch -Patch059: 0060-mdadm-replace-container-level-checking-with-inline.patch -Patch060: 0061-Mdmonitor-Omit-non-md-devices.patch -Patch061: 0062-Mdmonitor-Split-alert-into-separate-functions.patch -Patch062: 0063-Monitor-block-if-monitor-modes-are-combined.patch -Patch063: 0064-Update-mdadm-Monitor-manual.patch -Patch064: 0065-Grow-fix-possible-memory-leak.patch -Patch065: 0066-mdadm-create-ident_init.patch -Patch066: 0067-mdadm-Add-option-validation-for-update-subarray.patch -Patch067: 0068-Fix-update-subarray-on-active-volume.patch -Patch068: 0069-Add-code-specific-update-options-to-enum.patch -Patch069: 0070-super-ddf-Remove-update_super_ddf.patch -Patch070: 0071-super0-refactor-the-code-for-enum.patch -Patch071: 0072-super1-refactor-the-code-for-enum.patch -Patch072: 0073-super-intel-refactor-the-code-for-enum.patch -Patch073: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch -Patch074: 0075-Manage-Incremental-code-refactor-string-to-enum.patch -Patch075: 0076-Change-char-to-enum-in-context-update-refactor-code.patch -Patch076: 0077-mdmon-fix-segfault.patch -Patch077: 0078-util-remove-obsolete-code-from-get_md_name.patch -Patch078: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch -Patch079: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch -Patch080: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch -Patch081: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch -Patch082: 0083-manage-move-comment-with-function-description.patch -Patch083: 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch -Patch084: 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch -Patch085: 0086-Fix-NULL-dereference-in-super_by_fd.patch -Patch086: 0087-Mdmonitor-Make-alert_info-global.patch -Patch087: 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch -Patch088: 0089-Mdmonitor-Add-helper-functions.patch -Patch089: 0090-Add-helpers-to-determine-whether-directories-or-file.patch -Patch090: 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch -Patch091: 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch -Patch092: 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch -Patch093: 0094-util.c-fix-memleak-in-parse_layout_faulty.patch -Patch094: 0095-Detail.c-fix-memleak-in-Detail.patch -Patch095: 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch -Patch096: 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch -Patch097: 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch -Patch098: 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch -Patch099: 0100-Create-remove-safe_mode_delay-local-variable.patch -Patch100: 0101-Create-Factor-out-add_disks-helpers.patch -Patch101: 0102-mdadm-Introduce-pr_info.patch -Patch102: 0103-mdadm-Add-write-zeros-option-for-Create.patch -Patch103: 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch -Patch104: 0105-manpage-Add-write-zeroes-option-to-manpage.patch -Patch105: 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch -Patch106: 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch -Patch107: 0108-mdmon-don-t-test-both-all-and-container_name.patch -Patch108: 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch -Patch109: 0110-mdmon-Remove-need-for-KillMode-none.patch -Patch110: 0111-mdmon-Improve-switchroot-interactions.patch -Patch111: 0112-mdopen-always-try-create_named_array.patch -Patch112: 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch -Patch113: 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch -Patch114: 0115-Create-Fix-checking-for-container-in-update_metadata.patch -Patch115: 0116-Fix-null-pointer-for-incremental-in-mdadm.patch -Patch116: 0117-super1-fix-truncation-check-for-journal-device.patch -Patch117: 0118-Fix-some-cases-eyesore-formatting.patch -Patch118: 0119-Bump-minimum-kernel-version-to-2.6.32.patch -Patch119: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch -Patch120: 0121-mdadm-define-DEV_MD_DIR.patch -Patch121: 0122-mdadm-define-DEV_NUM_PREF.patch -Patch122: 0123-mdadm-define-is_devname_ignore.patch -Patch123: 0124-mdadm-numbered-names-verification.patch -Patch124: 0125-enable-RAID-for-SATA-under-VMD.patch -Patch125: 0126-imsm-Fix-possible-segfault-in-check_no_platform.patch -Patch126: 0127-imsm-move-sum_extents-calculations-to-merge_extents.patch -Patch127: 0128-imsm-imsm_get_free_size-refactor.patch -Patch128: 0129-imsm-introduce-round_member_size_to_mb.patch -Patch129: 0130-imsm-move-expand-verification-code-into-new-function.patch -Patch130: 0131-imsm-return-free-space-after-volume-for-expand.patch -Patch131: 0132-imsm-fix-free-space-calculations.patch -Patch132: 0133-Add-secure-gethostname-wrapper.patch -Patch133: 0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch -Patch134: 0135-Fix-memory-leak-in-file-Assemble.patch -Patch135: 0136-Fix-memory-leak-in-file-Kill.patch -Patch136: 0137-Fix-memory-leak-in-file-Manage.patch -Patch137: 0138-Fix-memory-leak-in-file-mdadm.patch -Patch138: 0139-Fix-unsafe-string-functions.patch -Patch139: 0140-platform-intel-limit-guid-length.patch -Patch140: 0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch -Patch141: 0142-Add-compiler-defenses-flags.patch -Patch142: 0143-Assemble-fix-redundant-memory-free.patch -Patch143: 0144-tests-add-a-new-test-for-rdev-lifetime.patch -Patch144: 0145-tests-support-to-skip-checking-dmesg.patch -Patch145: 0146-tests-add-a-regression-test-for-raid10-deadlock.patch -Patch146: 0147-tests-add-a-regression-test-for-raid456-deadlock.patch -Patch147: 0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch -Patch148: 0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch -Patch149: 0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch -Patch150: 0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch -Patch151: 0152-tests-create-names_template.patch -Patch152: 0153-tests-create-00confnames.patch -Patch153: 0154-mdadm-set-ident.devname-if-applicable.patch -Patch154: 0155-mdadm-refactor-ident-name-handling.patch -Patch155: 0156-mdadm-define-ident_set_devname.patch -Patch156: 0157-mdadm-Follow-POSIX-Portable-Character-Set.patch -Patch157: 0158-Incremental-remove-obsoleted-calls-to-udisks.patch -Patch158: 0159-mdadm-tests-Fix-regular-expression-failure.patch -Patch159: 0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch -Patch160: 0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch -Patch161: 0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch -Patch162: 0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch -Patch163: 0164-mdadm-remove-container_enough-logic.patch -Patch164: 0165-Fix-assembling-RAID-volume-by-using-incremental.patch -Patch165: 0166-Revert-mdadm-remove-container_enough-logic.patch -Patch166: 0167-manage-adjust-checking-subarray-state-in-update_suba.patch -Patch167: 0168-super1-remove-support-for-name-in-config.patch -Patch168: 0169-Mdmonitor-Improve-udev-event-handling.patch -Patch169: 0170-udev-Move-udev_block-and-udev_unblock-into-udev.c.patch -Patch170: 0171-mdadm-enable-sync-file-for-udev-rules.patch -Patch171: 0172-mdadm-Increase-number-limit-in-md-device-name-to-102.patch - -# RHEL customization patches -Patch200: mdadm-udev.patch -Patch201: mdadm-2.5.2-static.patch -Patch202: raid0-layout.patch -Patch203: mdadm-alloc-st-in-Assemble.patch - -URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ +%define extraversion 3 +Release: %{extraversion}.0.1%{?dist} +Summary: The mdadm program controls Linux md devices (software RAID arrays) +URL: https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git License: GPLv2+ -Group: System Environment/Base -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Obsoletes: mdctl,raidtools -Obsoletes: mdadm-sysvinit -Conflicts: dracut < 034-1 -Requires(post): systemd-units chkconfig coreutils -BuildRequires: systemd-units binutils-devel systemd-devel -Requires(preun): systemd-units -Requires(postun): systemd-units coreutils -Requires: libreport-filesystem -%define _hardened_build 1 +Source: https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/snapshot/%{name}-%{version}%{?subversion:-%{subversion}}.tar.gz +Source1: raid-check +Source2: mdadm-raid-check-sysconfig +Source3: mdmonitor.service +Source4: mdadm.conf +Source5: mdadm_event.conf +Source6: raid-check.timer +Source7: raid-check.service +Source8: mdcheck +Source9: md-auto-readd.rule +Source10: md-auto-readd.sh + +Patch000: 0001-Coverity-fixes-resources-leaks.patch +Patch001: 0002-Incremental-Document-workaround.patch +Patch002: 0003-sysfs-functions-for-writing-md-memb-state.patch +Patch003: 0004-Incremental-Simplify-remove-logic.patch +Patch004: 0005-checkpatch.conf-ignore-NEW_TYPEDEFS.patch +Patch005: 0006-mdadm-add-MAINTAINERS-file.patch +Patch006: 0007-mdadm.man-Remove-external-bitmap.patch +Patch007: 0008-Remove-freeze-reshape-logic.patch +Patch008: 0009-Detail-Export-reshape-status.patch +Patch009: 0010-mdadm-Do-not-start-reshape-before-switchroot.patch +Patch010: 0011-Better-error-messages-for-broken-reshape.patch +Patch011: 0012-Refactor-continue_via_systemd.patch +Patch012: 0013-mdadm-raid6check-add-xmalloc.h-to-raid6check.c.patch +Patch013: 0014-mdopen-add-sbin-path-to-env-PATH-when-call-system-mo.patch +Patch014: 0015-udev-persist-properties-of-MD-devices-after-switch_r.patch +Patch015: 0016-mdadm-fix-grow-with-add-for-linear.patch +Patch016: 0017-platform-intel-Disable-legacy-option-ROM-scan-on-UEF.patch +Patch017: 0018-super-ddf-Prevent-crash-when-handling-DDF-metadata.patch +Patch018: 0019-super-ddf-optimize-DDF-header-search-for-widely-used.patch +Patch019: 0020-bitmap.h-clear-__KERNEL__-based-headers.patch +Patch020: 0021-bitmap.h-Minor-fixes.patch +Patch021: 0022-Move-release-steps-to-documentation.patch +Patch022: 0023-Rework-MAINTAINERS-file.patch +Patch023: 0024-mdmon-imsm-fix-metadata-corruption-when-managing-new.patch +Patch024: 0025-Regression-fix-156.patch +Patch025: 0026-super1-Clear-extra-flags-when-initializing-metadata.patch +Patch026: 0027-imsm-Fix-RAID0-to-RAID10-migration.patch +Patch027: 0028-Allow-RAID0-to-be-created-with-v0.90-metadata-161.patch +Patch028: 0029-Update-tests.yml.patch +Patch029: 0030-Update-tests.yml.patch +Patch030: 0031-Update-tests.yml.patch +Patch031: 0032-Update-tests.yml.patch +Patch032: 0033-This-is-a-test-for-CI-do-not-merge.patch +Patch033: 0034-Update-README.md.patch +Patch034: 0035-mdadm-Remove-klibc-and-uclibc-support.patch +Patch035: 0036-mdadm-include-asm-byteorder.h.patch +Patch036: 0037-mdadm-use-kernel-raid-headers.patch +Patch037: mdadm-use-standard-libc-nftw.patch +Patch038: 0038-mdadm-enable-sync-file-for-udev-rules.patch + +# Fedora customization patches +Patch196: mdadm-fix-building-errors.patch +Patch197: mdadm-udev.patch +Patch198: mdadm-2.5.2-static.patch + +# Oracle patches +Patch1001: 1001-mdadm-fix-IMSM-Raid-assembly-after-disk-link-failure.patch + +BuildRequires: make +BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel +%if %{with abrt} +Requires: libreport-filesystem +%endif +Requires(post): systemd coreutils +Requires(preun): systemd +Requires(postun): systemd coreutils %description The mdadm program is used to create, manage, and monitor Linux MD (software @@ -219,239 +89,216 @@ file can be used to help with some common tasks. %autosetup -p1 -n %{name}-%{version}%{?subversion:_%{subversion}} %build +#If extraversion is defined, add EXTRAVERSION="%{extraversion}" make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" EXTRAVERSION="%{extraversion}" mdadm mdmon %install -rm -rf %{buildroot} -make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} install install-systemd -install -Dp -m 755 %{SOURCE2} %{buildroot}%{_sbindir}/raid-check -install -Dp -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/raid-check -install -Dp -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/cron.d/raid-check -mkdir -p -m 710 %{buildroot}/var/run/mdadm +make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} UDEVDIR=/usr/lib/udev/ install install-systemd +install -Dp -m 755 %{SOURCE1} %{buildroot}%{_sbindir}/raid-check +install -Dp -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/raid-check +mkdir -p -m 710 %{buildroot}/run/mdadm mkdir -p -m 700 %{buildroot}/usr/share/mdadm -mkdir -p -m 700 %{buildroot}/usr/lib/mdadm install -Dp -m 755 %{SOURCE8} %{buildroot}/usr/share/mdadm/mdcheck +install -Dp -m 644 %{SOURCE9} %{buildroot}%{_udevrulesdir}/66-md-auto-readd.rules +install -Dp -m 755 %{SOURCE10} %{buildroot}%{_sbindir}/md-auto-readd.sh # systemd mkdir -p %{buildroot}%{_unitdir} -install -m644 %{SOURCE5} %{buildroot}%{_unitdir} +install -m644 %{SOURCE3} %{buildroot}%{_unitdir} +install -m644 %{SOURCE6} %{buildroot}%{_unitdir} +install -m644 %{SOURCE7} %{buildroot}%{_unitdir} # tmpfile mkdir -p %{buildroot}%{_tmpfilesdir} -install -m 0644 %{SOURCE6} %{buildroot}%{_tmpfilesdir}/%{name}.conf +install -m 0644 %{SOURCE4} %{buildroot}%{_tmpfilesdir}/%{name}.conf mkdir -p %{buildroot}%{_localstatedir}/run/ -install -d -m 0710 %{buildroot}%{_localstatedir}/run/%{name}/ +install -d -m 0710 %{buildroot}/run/%{name}/ # abrt +%if %{with abrt} mkdir -p %{buildroot}/etc/libreport/events.d -install -m644 %{SOURCE7} %{buildroot}/etc/libreport/events.d - -%clean -rm -rf %{buildroot} +install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d +%endif %post -%systemd_post mdmonitor.service -/usr/bin/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || : +%systemd_post mdmonitor.service raid-check.timer +%{_bindir}/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || : %preun -%systemd_preun mdmonitor.service +%systemd_preun mdmonitor.service raid-check.timer %postun %systemd_postun_with_restart mdmonitor.service -%triggerun -- %{name} < 3.2.2-3 -%{_bindir}/systemd-sysv-convert --save mdmonitor >/dev/null 2>&1 || : -/bin/systemctl --no-reload enable mdmonitor.service >/dev/null 2>&1 || : -/sbin/chkconfig --del mdmonitor >/dev/null 2>&1 || : -/bin/systemctl try-restart mdmonitor.service >/dev/null 2>&1 || : - %files -%defattr(-,root,root,-) -%doc TODO ChangeLog mdadm.conf-example COPYING misc/* +%license COPYING +%doc documentation/mdadm.conf-example misc/* %{_udevrulesdir}/* %{_sbindir}/* %{_unitdir}/* %{_mandir}/man*/md* %{_prefix}/lib/systemd/system-shutdown/* -%config(noreplace) %{_sysconfdir}/cron.d/* %config(noreplace) %{_sysconfdir}/sysconfig/* -%dir %{_localstatedir}/run/%{name}/ +%dir /run/%{name}/ %config(noreplace) %{_tmpfilesdir}/%{name}.conf +%if %{with abrt} /etc/libreport/events.d/* +%endif /usr/share/mdadm/mdcheck %changelog -* Sat Oct 25 2025 Xiao Ni - 4.2-19 -- alloc superblock in Assemble -- Resolves: RHEL-82267 +* Tue Apr 07 2026 EL Errata - 4.4-3.0.1 +- mdadm: Fix IMSM Raid assembly after disk link failure and reboot. [Orabug: 38317486] -* Thu Jul 10 2025 John Pittman - 4.2-18 -- increase md device name number limit -- Resolves: RHEL-97802 - -* Thu Jun 5 2025 Xiao Ni - 4.2-17 +* Wed Nov 26 2025 Xiao Ni - 4.4-3 - enable sync file for udev rules -- Resolves: RHEL-59180 +- Resolves: RHEL-130890 -* Mon Oct 28 2024 Xiao Ni - 4.2-16 -- Remove name= support in config file -- Resolves RHEL-45608 +* Mon May 19 2025 Xiao Ni - 4.4-2 +- grow command can't update chunksize +- Resolves: RHEL-92288 -* Thu Mar 28 2024 Xiao Ni - 4.2-15 -- Fix update_subarray on active volume - missing patch -- Resolves RHEL-20833 +* Wed Apr 30 2025 Xiao Ni - 4.4-1 +- Update to mdadm 4.4 and latest upstream +- Resolves: RHEL-86676, RHEL-72803, RHEL-88793, RHEL-88791 -* Fri Mar 15 2024 Xiao Ni - 4.2-14 -- Revert "mdadm: remove container_enough logic" -- Resolves RHEL-26274 +* Tue Dec 3 2024 Xiao Ni - 4.3-5 +- Two create command problems +- Resolves: RHEL-69286, RHEL-68654 -* Fri Nov 10 2023 Xiao Ni - 4.2-13 -- Fix raid0 layout display problem -- Resolves RHEL-8372 +* Tue Oct 29 2024 Troy Dawson - 4.3-4.1 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Tue Nov 7 2023 Xiao Ni - 4.2-12 -- Fix rpminspect check error from gating test -- Resolves RHEL-15388 - -* Mon Nov 6 2023 Xiao Ni - 4.2-11 -- Update extraversion again -- Resolves RHEL-15388 - -* Mon Nov 6 2023 Xiao Ni - 4.2-10 -- Update extraversion -- Resolves RHEL-15388 - -* Sat Nov 4 2023 Xiao Ni - 4.2-9 +* Sat Oct 19 2024 Xiao Ni - 4.3-4 - Update to latest upstream -- Resolves RHEL-15388 +- Resolves: RHEL-59101 -* Tue May 16 2023 Xiao Ni - 4.2-9 -- Update to latest upstream and fix mdcheck service bug -- Resolves rhbz#2116418, rhbz#2150862, rhbz#2159584 +* Sun Aug 11 2024 Xiao Ni - 4.3-3 +- Fix coverity issue and update to latest upstream +- Resolves: RHEL-34533, RHEL-50776 -* Fri Jan 6 2023 Xiao Ni - 4.2-7 -- Update to latest to upstream to fix some bugs -- Resolves rhbz#2149307, rhbz#2149473, rhbz#2151208, rhbz#2127096 +* Tue Jul 16 2024 Michal Srb - 4.3-2.2 +- Avoid libreport dependency on RHEL +- Resolves: RHEL-45523 -* Thu Sep 8 2022 Xiao Ni - 4.2-6 -- Keep udev rule close to upstream and update to latest upstream -- Resolves rhbz#1991596, rhbz#2129088, rhbz#2107150 +* Mon Jun 24 2024 Troy Dawson - 4.3-2.1 +- Bump release for June 2024 mass rebuild -* Thu Aug 25 2022 Xiao Ni - 4.2-5 -- Update mdadm to latest upstream -- Resolves rhbz#2092326 +* Wed May 15 2024 Xiao Ni 4.3-2 +- Update to latest upstream and add gating test +- Resolves RHEL-30530 -* Sun Aug 07 2022 Xiao Ni - 4.2-4 -- Add KillMode=none to mdmon systemd service again -- Resolves rhbz#2109397 +* Fri Mar 29 2024 Xiao Ni 4.3-1 +- Update to 4.3 and to latest upstream +- Resolves RHEL-30530 -* Mon May 30 2022 Xiao Ni - 4.2-3 -- Update mdadm to latest upstream -- Resolves rhbz#2052563, rhbz#1991596 +* Thu Jan 25 2024 Fedora Release Engineering - 4.2-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Thu Feb 24 2022 Xiao Ni - 4.2-2 -- mdadm re-add fault/removed disk failed -- Resolves rhbz#2046323 +* Sun Jan 21 2024 Fedora Release Engineering - 4.2-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Fri Feb 18 2022 Xiao Ni - 4.2 -- Update to 4.2 -- Resolves rhbz#2034809 +* Thu Jul 20 2023 Fedora Release Engineering - 4.2-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Mon Nov 08 2021 Xiao Ni - 4.2-rc3 -- Update to 4.2-rc3 -- Resolves rhbz#1983019, rhbz#1995582, rhbz#1972032, rhbz#1885665 +* Wed Apr 12 2023 Xiao Ni - 4.2-5 +- Update to latest upstream for rawhide(f39) and fix mdcheck service bug +- Resolves bz#2175540 -* Thu Aug 05 2021 Xiao Ni - 4.2-rc2 -- Update to 4.2-rc2 -- Resolves rhbz#1989844 +* Mon Jan 30 2023 Xiao Ni - 4.2-4 +- Update to latest upstream for f38 +- Resolves bz#2163711 -* Fri Jul 23 2021 Xiao Ni - 4.2-rc1-4 -- Fix gating test failure -- Resolves rhbz#1984335 +* Thu Jan 19 2023 Fedora Release Engineering - 4.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild -* Tue Jul 20 2021 Xiao Ni - 4.2-rc1-3 -- Fix super1.0 offset problem and super imsm bugs -- Resolves rhbz#1966712 and rhbz#1975449 +* Thu Jul 21 2022 Fedora Release Engineering - 4.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild -* Thu Jun 10 2021 Xiao Ni - 4.2-rc1-2 -- Fix udev rule syntax error -- Resolves rhbz#1945780 +* Mon Mar 21 2022 Xiao Ni - 4.2-1 +- Update to mdadm-4.2 +- Resolves bz#2066150 -* Fri May 07 2021 Xiao Ni - 4.2-rc1 -- Update to upstream 4.2-rc1 -- Resovles rhbz#1920384 +* Thu Jan 20 2022 Fedora Release Engineering - 4.2-rc2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild -* Mon Jan 11 2021 Xiao Ni - 4.1.15 -- Update to latest upstream -- Resolves rhbz#1838005 +* Mon Aug 09 2021 Xiao Ni - 4.2-rc2 +- Update to mdadm-4.2-rc2 +- Resolves bz#1988236 -* Fri Jun 05 2020 Xiao Ni - 4.1.14 -- Update to latest upstream -- Resolves rhbz#1780501 +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 4.1-8 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. -* Fri Feb 28 2020 Xiao Ni - 4.1.13 -- Remove the unnecessary whitespace in .service file -- Resolves rhbz#1803470 +* Tue Jan 26 2021 Fedora Release Engineering - 4.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild -* Tue Feb 11 2020 Xiao Ni - 4.1.12 -- Update mdadm to latest upstream && change tmpfiles directory && correct changelog date -- Resolves rhbz#1800521 and rhbz#1657265 +* Tue Jul 28 2020 Fedora Release Engineering - 4.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild -* Sun Feb 09 2020 Xiao Ni - 4.1.11 -- mdcheck start service can't start -- Resolves rhbz#1769823 +* Wed May 27 2020 Xiao Ni - 4.1-5 +- Don't enable raid-check.service to avoid raid check after every boot +- Resolves bz1838409 -* Fri Nov 15 2019 Xiao Ni - 4.1.10 -- Update mdadm to latest upstream -- Resolves rhbz#1721937 +* Sun Mar 08 2020 Peter Robinson - 4.1-4 +- Fix install location of udev rules (rhbz 1809117) -* Wed Jul 10 2019 Xiao Ni - 4.1.9 -- Add --incremental for ddf member disk in udev rule -- Resolves rhbz#1693583 +* Fri Feb 07 2020 Alejandro Domínguez Muñoz - 4.1-3 +- Replace raid-check cron job with systemd timer -* Thu Jun 13 2019 Xiao Ni - 4.1.8 -- Update to latest upstream -- Resolves rhbz#1661203 +* Wed Jan 29 2020 Fedora Release Engineering - 4.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild -* Wed Jun 12 2019 Xiao Ni - 4.1.7 -- Fix gating test error -- Resolves rhbz#1682396 +* Mon Jan 13 2020 Peter Robinson 4.1-1 +- Update to 4.1 GA +- Spec cleanups and updates +- Update mdadm.pid location (rhbz 1701114, rhbz 1557623, rhbz 1557623) -* Thu May 23 2019 Xiao Ni - 4.1.6 -- Enable raid5 journal -- Resolves rhbz#1691202 +* Sun Dec 15 2019 Julian Sikorski - 4.1-rc2.0.5.2 +- Fix invalid substitution type error +- Resolves bz1740662, bz1749859 -* Fri Apr 12 2019 Xiao Ni - 4.1.5 -- add gating tests -- Resolves rhbz#1682396 +* Thu Jul 25 2019 Fedora Release Engineering - 4.1-rc2.0.5.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild -* Fri Jan 11 2019 Xiao Ni - 4.1.4 -- Disable raid5 journal -- Resolves rhbz#1664961 +* Tue Jun 04 2019 Xiao Ni - 4.1-rc2.0.5 +- Update tmpfiles directory to non-legacy location +- Resolves bz1704517 -* Fri Dec 21 2018 Xiao Ni - 4.1.3 -- Recovery isn't noticed while raid10 double degradation -- Resolves rhbz#1654482 +* Wed Apr 17 2019 Xiao Ni - 4.1-rc2.0.4 +- Change tmpfiles directory to /run/mdadm +- Resovles bz1701821 -* Wed Dec 12 2018 Xiao Ni - 4.1.2 -- Add warning message for using raid1 cluster -- Resolves rhbz#1654482 +* Sat Mar 16 2019 Björn Esser - 4.1-rc2.0.3 +- Add patch to build without -Werror, fixes FTBFS (#1675363) -* Fri Oct 26 2018 Xiao Ni - 4.1.1 -- Update to upstream 4.1 -- Resolves rhbz#1642206 +* Fri Feb 01 2019 Fedora Release Engineering - 4.1-rc2.0.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild -* Wed Oct 24 2018 Xiao Ni - 4.1-rc1-3 -- Can't find md device when install rhel8 -- Resolves rhbz#1628774 +* Thu Sep 13 2018 Adam Williamson - 4.1-rc2.0.2 +- Fix multipath check in udev rule, broke array init in F29 +- Resolves bz1628192 -* Thu Aug 16 2018 Xiao Ni - 4.1-rc1-2 -- Fix two IMSM bugs -- Resolves rhbz#1602420 and rhbz#1602422 +* Sun Aug 26 2018 Peter Robinson 4.1-rc2.0.1 +- Update to 4.1 rc2 -* Fri Jun 22 2018 Xiao Ni - 4.1-rc1-1 -- Upgrade to upstream mdadm-4.1-rc1 -- Resolves rhbz#1493605 and rhbz#1494477 and rhbz#1502118 +* Fri Jul 20 2018 Xiao Ni - 4.1-rc1_1.2 +- Add gcc into BuildRequires +- Resolves bz1604811 + +* Fri Jul 13 2018 Fedora Release Engineering - 4.1-rc1_1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jul 09 2018 Xiao Ni 4.1-rc1-1 +- Update to latest upstream version 4.1-rc1 +- Resolves bz1556591 + +* Wed Jul 4 2018 Peter Robinson 4.0-7 +- Cleanup spec, use %%licenece, drop old sys-v migration bits + +* Thu Feb 08 2018 Fedora Release Engineering - 4.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild * Thu Aug 03 2017 Fedora Release Engineering - 4.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild diff --git a/SOURCES/mdadm_event.conf b/mdadm_event.conf similarity index 100% rename from SOURCES/mdadm_event.conf rename to mdadm_event.conf diff --git a/SOURCES/mdcheck b/mdcheck old mode 100644 new mode 100755 similarity index 93% rename from SOURCES/mdcheck rename to mdcheck index aedfffa..700c3e2 --- a/SOURCES/mdcheck +++ b/mdcheck @@ -125,11 +125,13 @@ do do eval fl=\$MD_${i}_fl eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev if [ -z "$fl" ]; then continue; fi if [ "`cat $sys/md/sync_action`" != 'check' ] then + logger -p daemon.info mdcheck finished checking $dev eval MD_${i}_fl= rm -f $fl continue; @@ -138,13 +140,7 @@ do echo $a > $fl any=yes done - if [ -z "$any" ]; then - #mdcheck_continue.timer is started by mdcheck_start.timer. - #When he check action can be finished in mdcheck_start.service, - #it doesn't need mdcheck_continue anymore. - systemctl stop mdcheck_continue.timer - exit 0; - fi + if [ -z "$any" ]; then exit 0; fi sleep 120 done diff --git a/SOURCES/mdmonitor.service b/mdmonitor.service similarity index 63% rename from SOURCES/mdmonitor.service rename to mdmonitor.service index 123ae8a..a2f53d9 100644 --- a/SOURCES/mdmonitor.service +++ b/mdmonitor.service @@ -4,9 +4,9 @@ ConditionPathExists=/etc/mdadm.conf [Service] Type=forking -PIDFile=/var/run/mdadm/mdadm.pid +PIDFile=/run/mdadm/mdadm.pid EnvironmentFile=-/etc/sysconfig/mdmonitor -ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid +ExecStart=/sbin/mdadm --monitor --scan --syslog -f --pid-file=/run/mdadm/mdadm.pid [Install] WantedBy=multi-user.target diff --git a/SOURCES/raid-check b/raid-check old mode 100644 new mode 100755 similarity index 100% rename from SOURCES/raid-check rename to raid-check diff --git a/raid-check.service b/raid-check.service new file mode 100644 index 0000000..f8ed5ac --- /dev/null +++ b/raid-check.service @@ -0,0 +1,6 @@ +[Unit] +Description=RAID setup health check + +[Service] +Type=oneshot +ExecStart=/usr/sbin/raid-check diff --git a/raid-check.timer b/raid-check.timer new file mode 100644 index 0000000..c33bc24 --- /dev/null +++ b/raid-check.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Weekly RAID setup health check + +[Timer] +OnCalendar=Sun *-*-* 01:00:00 +Persistent=true +AccuracySec=24h + +[Install] +WantedBy=timers.target diff --git a/sources b/sources new file mode 100644 index 0000000..4010aa3 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (mdadm-4.4.tar.gz) = 08682b27f41a230f188d3b61e22e95ff8808b36c8fc2cba1dff443d39a72b35ba2eaf29ed64c7e5583c177fe6b71df983ec9a80a4128d8f07d58b7435d4700f6