From b7f7313bc88e06b25bcc064ae7d8094006e8aa4d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 10 2018 05:47:50 +0000 Subject: import mdadm-4.0-13.el7 --- diff --git a/SOURCES/Add-force-flag1-to-hot_remove_disk.patch b/SOURCES/Add-force-flag1-to-hot_remove_disk.patch new file mode 100644 index 0000000..b351498 --- /dev/null +++ b/SOURCES/Add-force-flag1-to-hot_remove_disk.patch @@ -0,0 +1,136 @@ +From 1ab9ed2afb7ca50c4f922a0b85c4e6631becde02 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 27 Mar 2017 14:36:56 +1100 +Subject: [RHEL7.5 PATCH 023/169] Add 'force' flag to *hot_remove_disk(). + +In rare circumstances, the short period that *hot_remove_disk() +waits isn't long enough to IO to complete. This particularly happens +when a device is failing and many retries are still happening. + +We don't want to increase the normal wait time for "mdadm --remove" +as that might be use just to test if a device is active or not, and a +delay would be problematic. +So allow "--force" to mean that mdadm should try extra hard for a +--remove to complete, waiting up to 5 seconds. + +Note that this patch fixes a comment which claim the previous +wait time was half a second, where it was really 50msec. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 2 +- + Manage.c | 10 +++++----- + mdadm.h | 4 ++-- + util.c | 10 +++++----- + 4 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 218a706..e22661c 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -2749,7 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + continue; + ioctl(fd, SET_DISK_FAULTY, + makedev(disk.major, disk.minor)); +- hot_remove_disk(fd, makedev(disk.major, disk.minor)); ++ hot_remove_disk(fd, makedev(disk.major, disk.minor), 1); + } + } + c = map_num(pers, level); +diff --git a/Manage.c b/Manage.c +index edf5798..55218d9 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1110,7 +1110,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + } + + int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, +- int sysfd, unsigned long rdev, int verbose, char *devname) ++ int sysfd, unsigned long rdev, int force, int verbose, char *devname) + { + int lfd = -1; + int err; +@@ -1177,9 +1177,9 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + /* device has been removed and we don't know + * the major:minor number + */ +- err = sys_hot_remove_disk(sysfd); ++ err = sys_hot_remove_disk(sysfd, force); + } else { +- err = hot_remove_disk(fd, rdev); ++ err = hot_remove_disk(fd, rdev, force); + if (err && errno == ENODEV) { + /* Old kernels rejected this if no personality + * is registered */ +@@ -1603,7 +1603,7 @@ int Manage_subdevs(char *devname, int fd, + + if (dv->disposition == 'F') + /* Need to remove first */ +- hot_remove_disk(fd, rdev); ++ hot_remove_disk(fd, rdev, force); + /* Make sure it isn't in use (in 2.6 or later) */ + tfd = dev_open(dv->devname, O_RDONLY|O_EXCL); + if (tfd >= 0) { +@@ -1645,7 +1645,7 @@ int Manage_subdevs(char *devname, int fd, + rv = -1; + } else + rv = Manage_remove(tst, fd, dv, sysfd, +- rdev, verbose, ++ rdev, verbose, force, + devname); + if (sysfd >= 0) + close(sysfd); +diff --git a/mdadm.h b/mdadm.h +index b855d24..cebc0c0 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1476,8 +1476,8 @@ extern int add_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); + extern int remove_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); +-extern int hot_remove_disk(int mdfd, unsigned long dev); +-extern int sys_hot_remove_disk(int statefd); ++extern int hot_remove_disk(int mdfd, unsigned long dev, int force); ++extern int sys_hot_remove_disk(int statefd, int force); + extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info); + unsigned long long min_recovery_start(struct mdinfo *array); + +diff --git a/util.c b/util.c +index b718531..683c869 100644 +--- a/util.c ++++ b/util.c +@@ -1795,15 +1795,15 @@ int remove_disk(int mdfd, struct supertype *st, + return rv; + } + +-int hot_remove_disk(int mdfd, unsigned long dev) ++int hot_remove_disk(int mdfd, unsigned long dev, int force) + { +- int cnt = 5; ++ int cnt = force ? 500 : 5; + int ret; + + /* HOT_REMOVE_DISK can fail with EBUSY if there are + * outstanding IO requests to the device. + * In this case, it can be helpful to wait a little while, +- * up to half a second, for that IO to flush. ++ * up to 5 seconds if 'force' is set, or 50 msec if not. + */ + while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && + errno == EBUSY && +@@ -1813,9 +1813,9 @@ int hot_remove_disk(int mdfd, unsigned long dev) + return ret; + } + +-int sys_hot_remove_disk(int statefd) ++int sys_hot_remove_disk(int statefd, int force) + { +- int cnt = 5; ++ int cnt = force ? 500 : 5; + int ret; + + while ((ret = write(statefd, "remove", 6)) == -1 && +-- +2.7.4 + diff --git a/SOURCES/Allow-more-spare-selection-criteria.patch b/SOURCES/Allow-more-spare-selection-criteria.patch index eba8997..c6f1588 100644 --- a/SOURCES/Allow-more-spare-selection-criteria.patch +++ b/SOURCES/Allow-more-spare-selection-criteria.patch @@ -40,9 +40,9 @@ index 680d318..fe9d644 100644 } free(st3); @@ -947,7 +948,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, - : INVALID_SECTORS) - < sra->component_size) - || + sra->devs ? sra->devs->data_offset : + INVALID_SECTORS) < + sra->component_size) || - (sra->component_size == 0 && devsize < component_size)) { + (sra->component_size == 0 && devsize < sc.min_size)) { if (verbose > 1) diff --git a/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch b/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch new file mode 100644 index 0000000..1716d70 --- /dev/null +++ b/SOURCES/Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch @@ -0,0 +1,31 @@ +From b6e60be6281a2a4ec326a72de114867797a42d7f Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:47:37 -0400 +Subject: [RHEL7.5 PATCH 065/169] Assemble/Assemble: Get rid of last use of + md_get_version() + +At this point in the code, we know we have a valid array, and any +recent kernel will return 9003, so no point in querying the kernel for +this. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Assemble.c b/Assemble.c +index fa5fdbe..0db428f 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1901,7 +1901,7 @@ int assemble_container_content(struct supertype *st, int mdfd, + c->readonly && + content->text_version[0] == '/') + content->text_version[0] = '-'; +- if (sysfs_set_array(content, md_get_version(mdfd)) != 0) { ++ if (sysfs_set_array(content, 9003) != 0) { + sysfs_free(sra); + return 1; + } +-- +2.7.4 + diff --git a/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch b/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch new file mode 100644 index 0000000..b55e6f3 --- /dev/null +++ b/SOURCES/Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch @@ -0,0 +1,31 @@ +From 6142741d144824c31b733f9d6e6e240b159effc0 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:09:18 -0400 +Subject: [RHEL7.5 PATCH 054/169] Assemble/Assemble: Stop checking kernel + md driver version + +Any kernel released during the last decade will return 9003 from +md_get_version() so no point in checking that. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 672cd12..fa5fdbe 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1477,8 +1477,7 @@ try_again: + return 1; + } + mddev = chosen_name; +- if (get_linux_version() < 2004000 || +- md_get_version(mdfd) < 9000) { ++ if (get_linux_version() < 2004000) { + pr_err("Assemble requires Linux 2.4 or later, and\n" + " md driver version 0.90.0 or later.\n" + " Upgrade your kernel or try --build\n"); +-- +2.7.4 + diff --git a/SOURCES/Assemble-Clean1-up-start_array.patch b/SOURCES/Assemble-Clean1-up-start_array.patch new file mode 100644 index 0000000..88def93 --- /dev/null +++ b/SOURCES/Assemble-Clean1-up-start_array.patch @@ -0,0 +1,249 @@ +From 94b53b777e095e1bc253654acc2e459d368c5dd5 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 12 Apr 2017 14:23:45 -0400 +Subject: [RHEL7.5 PATCH 075/169] Assemble: Clean up start_array() + +This is purely cosmetic, no codeflow changes. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 97 +++++++++++++++++++++++++++++++++++++------------------------- + 1 file changed, 58 insertions(+), 39 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index b828523..22596b5 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -992,7 +992,7 @@ static int start_array(int mdfd, + } + + /* First, add the raid disks, but add the chosen one last */ +- for (i=0; i<= bestcnt; i++) { ++ for (i = 0; i <= bestcnt; i++) { + int j; + if (i < bestcnt) { + j = best[i]; +@@ -1002,8 +1002,9 @@ static int start_array(int mdfd, + j = chosen_drive; + + if (j >= 0 && !devices[j].included) { +- int dfd = dev_open(devices[j].devname, +- O_RDWR|O_EXCL); ++ int dfd; ++ ++ dfd = dev_open(devices[j].devname, O_RDWR|O_EXCL); + if (dfd >= 0) { + remove_partitions(dfd); + close(dfd); +@@ -1012,28 +1013,30 @@ static int start_array(int mdfd, + + if (rv) { + pr_err("failed to add %s to %s: %s\n", +- devices[j].devname, +- mddev, ++ devices[j].devname, mddev, + strerror(errno)); +- if (i < content->array.raid_disks * 2 +- || i == bestcnt) ++ if (i < content->array.raid_disks * 2 || ++ i == bestcnt) + okcnt--; + else + sparecnt--; +- } else if (c->verbose > 0) ++ } else if (c->verbose > 0) { + pr_err("added %s to %s as %d%s%s\n", + devices[j].devname, mddev, + devices[j].i.disk.raid_disk, + devices[j].uptodate?"": + " (possibly out of date)", +- (devices[j].i.disk.state & (1<= 0) { + if (c->verbose > 0) + pr_err("%s is already in %s as %d\n", + devices[j].devname, mddev, + devices[j].i.disk.raid_disk); +- } else if (c->verbose > 0 && i < content->array.raid_disks*2 +- && (i&1) == 0) ++ } else if (c->verbose > 0 && ++ i < content->array.raid_disks * 2 && (i & 1) == 0) + pr_err("no uptodate device for slot %d of %s\n", + i/2, mddev); + } +@@ -1041,8 +1044,8 @@ static int start_array(int mdfd, + if (content->array.level == LEVEL_CONTAINER) { + if (c->verbose >= 0) { + pr_err("Container %s has been assembled with %d drive%s", +- mddev, okcnt+sparecnt+journalcnt, +- okcnt+sparecnt+journalcnt==1?"":"s"); ++ mddev, okcnt + sparecnt + journalcnt, ++ okcnt + sparecnt + journalcnt == 1 ? "" : "s"); + if (okcnt < (unsigned)content->array.raid_disks) + fprintf(stderr, " (out of %d)", + content->array.raid_disks); +@@ -1051,10 +1054,13 @@ static int start_array(int mdfd, + + if (st->ss->validate_container) { + struct mdinfo *devices_list; +- struct mdinfo *info_devices = xmalloc(sizeof(struct mdinfo)*(okcnt+sparecnt)); ++ struct mdinfo *info_devices; + unsigned int count; ++ + devices_list = NULL; +- for (count = 0; count < okcnt+sparecnt; count++) { ++ info_devices = xmalloc(sizeof(struct mdinfo) * ++ (okcnt + sparecnt)); ++ for (count = 0; count < okcnt + sparecnt; count++) { + info_devices[count] = devices[count].i; + info_devices[count].next = devices_list; + devices_list = &info_devices[count]; +@@ -1080,16 +1086,16 @@ static int start_array(int mdfd, + + if (c->runstop == 1 || + (c->runstop <= 0 && +- ( enough(content->array.level, content->array.raid_disks, +- content->array.layout, clean, avail) && +- (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok) +- ))) { ++ (enough(content->array.level, content->array.raid_disks, ++ content->array.layout, clean, avail) && ++ (okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)))) { + /* This array is good-to-go. + * If a reshape is in progress then we might need to + * continue monitoring it. In that case we start + * it read-only and let the grow code make it writable. + */ + int rv; ++ + if (content->reshape_active && + !(content->reshape_active & RESHAPE_NO_BACKUP) && + content->delta_disks <= 0) { +@@ -1109,8 +1115,8 @@ static int start_array(int mdfd, + c->backup_file, 0, + c->freeze_reshape); + } else if (c->readonly && +- sysfs_attribute_available( +- content, NULL, "array_state")) { ++ sysfs_attribute_available(content, NULL, ++ "array_state")) { + rv = sysfs_set_str(content, NULL, + "array_state", "readonly"); + } else +@@ -1121,13 +1127,19 @@ static int start_array(int mdfd, + pr_err("%s has been started with %d drive%s", + mddev, okcnt, okcnt==1?"":"s"); + if (okcnt < (unsigned)content->array.raid_disks) +- fprintf(stderr, " (out of %d)", content->array.raid_disks); ++ fprintf(stderr, " (out of %d)", ++ content->array.raid_disks); + if (rebuilding_cnt) +- fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt); ++ fprintf(stderr, "%s %d rebuilding", ++ sparecnt?",":" and", ++ rebuilding_cnt); + if (sparecnt) +- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); ++ fprintf(stderr, " and %d spare%s", ++ sparecnt, ++ sparecnt == 1 ? "" : "s"); + if (content->journal_clean) +- fprintf(stderr, " and %d journal", journalcnt); ++ fprintf(stderr, " and %d journal", ++ journalcnt); + fprintf(stderr, ".\n"); + } + if (content->reshape_active && +@@ -1137,11 +1149,14 @@ static int start_array(int mdfd, + * of the stripe cache - default is 256 + */ + int chunk_size = content->array.chunk_size; ++ + if (content->reshape_active && + content->new_chunk > chunk_size) + chunk_size = content->new_chunk; + if (256 < 4 * ((chunk_size+4065)/4096)) { +- struct mdinfo *sra = sysfs_read(mdfd, NULL, 0); ++ struct mdinfo *sra; ++ ++ sra = sysfs_read(mdfd, NULL, 0); + if (sra) + sysfs_set_num(sra, NULL, + "stripe_cache_size", +@@ -1174,7 +1189,9 @@ static int start_array(int mdfd, + if (content->array.level == 6 && + okcnt + 1 == (unsigned)content->array.raid_disks && + was_forced) { +- struct mdinfo *sra = sysfs_read(mdfd, NULL, 0); ++ struct mdinfo *sra; ++ ++ sra = sysfs_read(mdfd, NULL, 0); + if (sra) + sysfs_set_str(sra, NULL, + "sync_action", "repair"); +@@ -1182,45 +1199,47 @@ static int start_array(int mdfd, + } + return 0; + } +- pr_err("failed to RUN_ARRAY %s: %s\n", +- mddev, strerror(errno)); ++ pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno)); + + if (!enough(content->array.level, content->array.raid_disks, + content->array.layout, 1, avail)) + pr_err("Not enough devices to start the array.\n"); + else if (!enough(content->array.level, + content->array.raid_disks, +- content->array.layout, clean, +- avail)) ++ content->array.layout, clean, avail)) + pr_err("Not enough devices to start the array while not clean - consider --force.\n"); + + return 1; + } + if (c->runstop == -1) { + pr_err("%s assembled from %d drive%s", +- mddev, okcnt, okcnt==1?"":"s"); ++ mddev, okcnt, okcnt == 1 ? "" : "s"); + if (okcnt != (unsigned)content->array.raid_disks) +- fprintf(stderr, " (out of %d)", content->array.raid_disks); ++ fprintf(stderr, " (out of %d)", ++ content->array.raid_disks); + fprintf(stderr, ", but not started.\n"); + return 2; + } + if (c->verbose >= -1) { +- pr_err("%s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s"); ++ pr_err("%s assembled from %d drive%s", ++ mddev, okcnt, okcnt == 1 ? "" : "s"); + if (rebuilding_cnt) +- fprintf(stderr, "%s %d rebuilding", sparecnt?",":" and", rebuilding_cnt); ++ fprintf(stderr, "%s %d rebuilding", ++ sparecnt ? "," : " and", rebuilding_cnt); + if (sparecnt) +- fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); ++ fprintf(stderr, " and %d spare%s", sparecnt, ++ sparecnt == 1 ? "" : "s"); + if (!enough(content->array.level, content->array.raid_disks, + content->array.layout, 1, avail)) + fprintf(stderr, " - not enough to start the array.\n"); + else if (!enough(content->array.level, + content->array.raid_disks, +- content->array.layout, clean, +- avail)) ++ content->array.layout, clean, avail)) + fprintf(stderr, " - not enough to start the array while not clean - consider --force.\n"); + else { + if (req_cnt == (unsigned)content->array.raid_disks) +- fprintf(stderr, " - need all %d to start it", req_cnt); ++ fprintf(stderr, " - need all %d to start it", ++ req_cnt); + else + fprintf(stderr, " - need %d to start", req_cnt); + fprintf(stderr, " (use --run to insist).\n"); +-- +2.7.4 + diff --git a/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch b/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch new file mode 100644 index 0000000..c810636 --- /dev/null +++ b/SOURCES/Assemble-Remove-obsolete-test-for-kernels1-older-than.patch @@ -0,0 +1,34 @@ +From 0ef1043ce8dd3f36c7227aa4a260819c4c17c78d Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 12 Apr 2017 14:50:02 -0400 +Subject: [RHEL7.5 PATCH 077/169] Assemble: Remove obsolete test for + kernels older than 2.4 + +We only support 2.6.15+ at this point + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 22596b5..d6beb23 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1487,13 +1487,6 @@ try_again: + return 1; + } + mddev = chosen_name; +- if (get_linux_version() < 2004000) { +- pr_err("Assemble requires Linux 2.4 or later, and\n" +- " md driver version 0.90.0 or later.\n" +- " Upgrade your kernel or try --build\n"); +- close(mdfd); +- return 1; +- } + if (pre_exist == NULL) { + if (mddev_busy(fd2devnm(mdfd))) { + pr_err("%s already active, cannot restart it!\n", +-- +2.7.4 + diff --git a/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch b/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch new file mode 100644 index 0000000..130b4b9 --- /dev/null +++ b/SOURCES/Avoid-to-take-spare-without-defined-domain-by-imsm.patch @@ -0,0 +1,38 @@ +commit 3bf9495270d7cd00da942e183dc5f7c7eb68ff69 +Author: Mariusz Tkaczyk +Date: Thu Jan 11 12:39:49 2018 +0100 + + policy.c: Avoid to take spare without defined domain by imsm + + Only Imsm get_disk_controller_domain returns disk controller domain for + each disk. It causes that mdadm automatically creates disk controller + domain policy for imsm metadata, and imsm containers in the same disk + controller domain can take spare for recovery. + + Ignore spares if only one imsm domain is matched. + + Signed-off-by: Mariusz Tkaczyk + Signed-off-by: Jes Sorensen + +diff --git a/policy.c b/policy.c +index b17585a..c0d18a7 100644 +--- a/policy.c ++++ b/policy.c +@@ -661,6 +661,7 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + * 1: has domains, all match + */ + int found_any = -1; ++ int has_one_domain = 1; + struct dev_policy *p; + + pol = pol_find(pol, pol_domain); +@@ -670,6 +671,9 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol, + dom = dom->next; + if (!dom || strcmp(dom->dom, p->value) != 0) + return 0; ++ if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0) ++ found_any = -1; ++ has_one_domain = 0; + } + return found_any; + } diff --git a/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch b/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch new file mode 100644 index 0000000..ff7ca90 --- /dev/null +++ b/SOURCES/Build2-Stop-bothering-about-supporting-md-driver-olde.patch @@ -0,0 +1,266 @@ +From e6e5f8f1267de4f310415231b3434fce2d25f02a Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:20:52 -0400 +Subject: [RHEL7.5 PATCH 055/169] Build: Stop bothering about supporting md + driver older than 0.90.00 + +The kernel has been stuck at md driver version 0.90.03 for at least a +decade. No point in continuing to support the older API. + +Signed-off-by: Jes Sorensen +--- + Build.c | 187 ++++++++++++++++++++++++---------------------------------------- + 1 file changed, 69 insertions(+), 118 deletions(-) + +diff --git a/Build.c b/Build.c +index 691dd6f..11ba12f 100644 +--- a/Build.c ++++ b/Build.c +@@ -39,13 +39,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + * geometry is 0xpp00cc + * where pp is personality: 1==linear, 2=raid0 + * cc = chunk size factor: 0==4k, 1==8k etc. +- * +- * For md_version >= 0.90.0 we call +- * SET_ARRAY_INFO, ADD_NEW_DISK, RUN_ARRAY +- * + */ + int i; +- int vers; + struct stat stb; + int subdevs = 0, missing_disks = 0; + struct mddev_dev *dv; +@@ -55,6 +50,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + char chosen_name[1024]; + int uuid[4] = {0,0,0,0}; + struct map_ent *map = NULL; ++ mdu_array_info_t array; ++ mdu_param_t param; /* not used by syscall */ + + if (s->level == UnSet) { + pr_err("a RAID level is needed to Build an array.\n"); +@@ -122,39 +119,30 @@ int Build(char *mddev, struct mddev_dev *devlist, + map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name); + map_unlock(&map); + +- vers = md_get_version(mdfd); +- +- /* looks Ok, go for it */ +- if (vers >= 9000) { +- mdu_array_info_t array; +- array.level = s->level; +- if (s->size == MAX_SIZE) +- s->size = 0; +- array.size = s->size; +- array.nr_disks = s->raiddisks; +- array.raid_disks = s->raiddisks; +- array.md_minor = 0; +- if (fstat(mdfd, &stb)==0) +- array.md_minor = minor(stb.st_rdev); +- array.not_persistent = 1; +- array.state = 0; /* not clean, but no errors */ +- if (s->assume_clean) +- array.state |= 1; +- array.active_disks = s->raiddisks - missing_disks; +- array.working_disks = s->raiddisks - missing_disks; +- array.spare_disks = 0; +- array.failed_disks = missing_disks; +- if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR)) +- s->chunk = 64; +- 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)); +- goto abort; +- } +- } else if (s->bitmap_file) { +- pr_err("bitmaps not supported with this kernel\n"); ++ array.level = s->level; ++ if (s->size == MAX_SIZE) ++ s->size = 0; ++ array.size = s->size; ++ array.nr_disks = s->raiddisks; ++ array.raid_disks = s->raiddisks; ++ array.md_minor = 0; ++ if (fstat(mdfd, &stb) == 0) ++ array.md_minor = minor(stb.st_rdev); ++ array.not_persistent = 1; ++ array.state = 0; /* not clean, but no errors */ ++ if (s->assume_clean) ++ array.state |= 1; ++ array.active_disks = s->raiddisks - missing_disks; ++ array.working_disks = s->raiddisks - missing_disks; ++ array.spare_disks = 0; ++ array.failed_disks = missing_disks; ++ if (s->chunk == 0 && (s->level==0 || s->level==LEVEL_LINEAR)) ++ s->chunk = 64; ++ 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)); + goto abort; + } + +@@ -167,8 +155,10 @@ int Build(char *mddev, struct mddev_dev *devlist, + } + /* now add the devices */ + for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) { ++ mdu_disk_info_t disk; + unsigned long long dsize; + int fd; ++ + if (strcmp("missing", dv->devname) == 0) + continue; + if (stat(dv->devname, &stb)) { +@@ -191,94 +181,58 @@ int Build(char *mddev, struct mddev_dev *devlist, + (s->size == 0 || s->size == MAX_SIZE || dsize < s->size)) + s->size = dsize; + close(fd); +- if (vers >= 9000) { +- mdu_disk_info_t disk; +- disk.number = i; +- disk.raid_disk = i; +- disk.state = (1<writemostly == FlagSet) +- disk.state |= 1<devname, strerror(errno)); +- goto abort; +- } +- } else { +- if (ioctl(mdfd, REGISTER_DEV, &stb.st_rdev)) { +- pr_err("REGISTER_DEV failed for %s: %s.\n", +- dv->devname, strerror(errno)); +- goto abort; +- } ++ disk.number = i; ++ disk.raid_disk = i; ++ disk.state = (1<writemostly == FlagSet) ++ disk.state |= 1<devname, strerror(errno)); ++ goto abort; + } + } + /* now to start it */ +- if (vers >= 9000) { +- mdu_param_t param; /* not used by syscall */ +- if (s->bitmap_file) { +- bitmap_fd = open(s->bitmap_file, O_RDWR); +- if (bitmap_fd < 0) { +- int major = BITMAP_MAJOR_HI; ++ if (s->bitmap_file) { ++ bitmap_fd = open(s->bitmap_file, O_RDWR); ++ if (bitmap_fd < 0) { ++ int major = BITMAP_MAJOR_HI; + #if 0 +- if (s->bitmap_chunk == UnSet) { +- pr_err("%s cannot be openned.", +- s->bitmap_file); +- goto abort; +- } +-#endif +- if (vers < 9003) { +- major = BITMAP_MAJOR_HOSTENDIAN; +-#ifdef __BIG_ENDIAN +- pr_err("Warning - bitmaps created on this kernel are not portable\n" +- " between different architectures. Consider upgrading the Linux kernel.\n"); ++ if (s->bitmap_chunk == UnSet) { ++ pr_err("%s cannot be openned.", s->bitmap_file); ++ goto abort; ++ } + #endif +- } +- bitmapsize = s->size>>9; /* FIXME wrong for RAID10 */ +- if (CreateBitmap(s->bitmap_file, 1, NULL, s->bitmap_chunk, +- c->delay, s->write_behind, bitmapsize, major)) { +- goto abort; +- } +- bitmap_fd = open(s->bitmap_file, O_RDWR); +- if (bitmap_fd < 0) { +- pr_err("%s cannot be openned.", +- s->bitmap_file); +- goto abort; +- } ++ bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */ ++ if (CreateBitmap(s->bitmap_file, 1, NULL, ++ s->bitmap_chunk, c->delay, ++ s->write_behind, bitmapsize, major)) { ++ goto abort; + } +- 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)); +- goto abort; +- } ++ bitmap_fd = open(s->bitmap_file, O_RDWR); ++ if (bitmap_fd < 0) { ++ pr_err("%s cannot be openned.", s->bitmap_file); ++ goto abort; + } + } +- if (ioctl(mdfd, RUN_ARRAY, ¶m)) { +- pr_err("RUN_ARRAY failed: %s\n", +- strerror(errno)); +- if (s->chunk & (s->chunk-1)) { +- cont_err("Problem may be that chunk size is not a power of 2\n"); ++ 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)); ++ goto abort; + } +- goto abort; +- } +- } else { +- unsigned long arg; +- arg=0; +- while (s->chunk > 4096) { +- arg++; +- s->chunk >>= 1; + } +- if (s->level == 0) +- arg |= 0x20000; +- else +- arg |= 0x10000; +- if (ioctl(mdfd, START_MD, arg)) { +- pr_err("START_MD failed: %s\n", +- strerror(errno)); +- goto abort; ++ } ++ if (ioctl(mdfd, RUN_ARRAY, ¶m)) { ++ pr_err("RUN_ARRAY failed: %s\n", strerror(errno)); ++ if (s->chunk & (s->chunk - 1)) { ++ cont_err("Problem may be that chunk size is not a power of 2\n"); + } ++ goto abort; + } ++ + if (c->verbose >= 0) + pr_err("array %s built and started.\n", + mddev); +@@ -287,10 +241,7 @@ int Build(char *mddev, struct mddev_dev *devlist, + return 0; + + abort: +- if (vers >= 9000) +- ioctl(mdfd, STOP_ARRAY, 0); +- else +- ioctl(mdfd, STOP_MD, 0); ++ ioctl(mdfd, STOP_ARRAY, 0); + close(mdfd); + return 1; + } +-- +2.7.4 + diff --git a/SOURCES/Correct-examine-output-for-4k-disks.patch b/SOURCES/Correct-examine-output-for-4k-disks.patch deleted file mode 100644 index b82b2f3..0000000 --- a/SOURCES/Correct-examine-output-for-4k-disks.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit 84918897ee8bb450ea09f7c95b9da44df8e925e4 -Author: Maksymilian Kunt -Date: Tue May 9 14:03:27 2017 +0200 - - IMSM: Correct --examine output for 4k disks - - "Array Size" and "Per Dev Size" are incorrect for disks with sector size - different than 512B. - - Calculate "Array Size" and "Per Dev Size" based on sector size. Additionally - print "Sector Size". - - Signed-off-by: Maksymilian Kunt - Signed-off-by: Mariusz Dabrowski - Signed-off-by: Jes Sorensen - -diff --git a/super-intel.c b/super-intel.c -index ba6f810..8ca80d3 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -1482,13 +1482,16 @@ static void print_imsm_dev(struct intel_super *super, - ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : ""); - } else - printf(" This Slot : ?\n"); -+ printf(" Sector Size : %u\n", super->sector_size); - sz = __le32_to_cpu(dev->size_high); - sz <<= 32; - sz += __le32_to_cpu(dev->size_low); -- printf(" Array Size : %llu%s\n", (unsigned long long)sz, -+ printf(" Array Size : %llu%s\n", -+ (unsigned long long)sz * 512 / super->sector_size, - human_size(sz * 512)); - sz = blocks_per_member(map); -- printf(" Per Dev Size : %llu%s\n", (unsigned long long)sz, -+ printf(" Per Dev Size : %llu%s\n", -+ (unsigned long long)sz * 512 / super->sector_size, - human_size(sz * 512)); - printf(" Sector Offset : %llu\n", - pba_of_lba0(map)); diff --git a/SOURCES/Correct-examine-output-for-4kdisks.patch b/SOURCES/Correct-examine-output-for-4kdisks.patch new file mode 100644 index 0000000..b82b2f3 --- /dev/null +++ b/SOURCES/Correct-examine-output-for-4kdisks.patch @@ -0,0 +1,39 @@ +commit 84918897ee8bb450ea09f7c95b9da44df8e925e4 +Author: Maksymilian Kunt +Date: Tue May 9 14:03:27 2017 +0200 + + IMSM: Correct --examine output for 4k disks + + "Array Size" and "Per Dev Size" are incorrect for disks with sector size + different than 512B. + + Calculate "Array Size" and "Per Dev Size" based on sector size. Additionally + print "Sector Size". + + Signed-off-by: Maksymilian Kunt + Signed-off-by: Mariusz Dabrowski + Signed-off-by: Jes Sorensen + +diff --git a/super-intel.c b/super-intel.c +index ba6f810..8ca80d3 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1482,13 +1482,16 @@ static void print_imsm_dev(struct intel_super *super, + ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : ""); + } else + printf(" This Slot : ?\n"); ++ printf(" Sector Size : %u\n", super->sector_size); + sz = __le32_to_cpu(dev->size_high); + sz <<= 32; + sz += __le32_to_cpu(dev->size_low); +- printf(" Array Size : %llu%s\n", (unsigned long long)sz, ++ printf(" Array Size : %llu%s\n", ++ (unsigned long long)sz * 512 / super->sector_size, + human_size(sz * 512)); + sz = blocks_per_member(map); +- printf(" Per Dev Size : %llu%s\n", (unsigned long long)sz, ++ printf(" Per Dev Size : %llu%s\n", ++ (unsigned long long)sz * 512 / super->sector_size, + human_size(sz * 512)); + printf(" Sector Offset : %llu\n", + pba_of_lba0(map)); diff --git a/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch b/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch new file mode 100644 index 0000000..6c8e565 --- /dev/null +++ b/SOURCES/Create-Fixup-bad-placement-of-logical-in-multi-line-.patch @@ -0,0 +1,76 @@ +From cf622ec1d81a5bb3f882922667bac494b3a16581 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 11:53:12 -0400 +Subject: [RHEL7.5 PATCH 050/169] Create: Fixup bad placement of logical || + && in multi-line if statements + +These always go at the end of the line, never at the front + +Signed-off-by: Jes Sorensen +--- + Create.c | 28 +++++++++++----------------- + 1 file changed, 11 insertions(+), 17 deletions(-) + +diff --git a/Create.c b/Create.c +index ba24606..17333ce 100644 +--- a/Create.c ++++ b/Create.c +@@ -457,8 +457,8 @@ 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 +- || (s->level == 0 && s->raiddisks == 1)) ++ else if (s->level == 1 || s->level == LEVEL_CONTAINER || ++ (s->level == 0 && s->raiddisks == 1)) + /* partitions could be meaningful */ + warn |= check_partitions(fd, dname, freesize*2, s->size*2); + else +@@ -495,9 +495,8 @@ int Create(struct supertype *st, char *mddev, + pr_err("no size and no drives given - aborting create.\n"); + return 1; + } +- if (s->level > 0 || s->level == LEVEL_MULTIPATH +- || s->level == LEVEL_FAULTY +- || st->ss->external ) { ++ if (s->level > 0 || s->level == LEVEL_MULTIPATH || ++ s->level == LEVEL_FAULTY || st->ss->external ) { + /* size is meaningful */ + if (!st->ss->validate_geometry(st, s->level, s->layout, + s->raiddisks, +@@ -616,8 +615,8 @@ 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) { ++ 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); + close(mdfd); +@@ -653,16 +652,11 @@ int Create(struct supertype *st, char *mddev, + info.array.md_minor = minor(stb.st_rdev); + info.array.not_persistent = 0; + +- if ( ( (s->level == 4 || s->level == 5) && +- (insert_point < s->raiddisks || first_missing < s->raiddisks) ) +- || +- ( s->level == 6 && (insert_point < s->raiddisks +- || second_missing < s->raiddisks)) +- || +- ( s->level <= 0 ) +- || +- s->assume_clean +- ) { ++ if (((s->level == 4 || s->level == 5) && ++ (insert_point < s->raiddisks || first_missing < s->raiddisks)) || ++ (s->level == 6 && (insert_point < s->raiddisks || ++ second_missing < s->raiddisks)) || ++ (s->level <= 0) || s->assume_clean) { + info.array.state = 1; /* clean, but one+ drive will be missing*/ + info.resync_start = MaxSector; + } else { +-- +2.7.4 + diff --git a/SOURCES/Create-Fixup-various-whitespace-issues1.patch b/SOURCES/Create-Fixup-various-whitespace-issues1.patch new file mode 100644 index 0000000..dc65118 --- /dev/null +++ b/SOURCES/Create-Fixup-various-whitespace-issues1.patch @@ -0,0 +1,167 @@ +From 98dbf73cba81cd846f9c706f37edc22e21038cf4 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 11:57:30 -0400 +Subject: [RHEL7.5 PATCH 051/169] Create: Fixup various whitespace issues + +Signed-off-by: Jes Sorensen +--- + Create.c | 50 ++++++++++++++++++++++++-------------------------- + 1 file changed, 24 insertions(+), 26 deletions(-) + +diff --git a/Create.c b/Create.c +index 17333ce..4f98c58 100644 +--- a/Create.c ++++ b/Create.c +@@ -84,12 +84,12 @@ int Create(struct supertype *st, char *mddev, + * RUN_ARRAY + */ + int mdfd; +- unsigned long long minsize=0, maxsize=0; ++ unsigned long long minsize = 0, maxsize = 0; + char *mindisc = NULL; + char *maxdisc = NULL; + int dnum, raid_disk_num; + struct mddev_dev *dv; +- int fail=0, warn=0; ++ int fail = 0, warn = 0; + struct stat stb; + int first_missing = subdevs * 2; + int second_missing = subdevs * 2; +@@ -259,7 +259,7 @@ int Create(struct supertype *st, char *mddev, + &s->chunk, s->size*2, + data_offset, NULL, + &newsize, s->consistency_policy, +- c->verbose>=0)) ++ c->verbose >= 0)) + return 1; + + if (s->chunk && s->chunk != UnSet) { +@@ -290,7 +290,7 @@ int Create(struct supertype *st, char *mddev, + info.array.active_disks = 0; + info.array.working_disks = 0; + dnum = 0; +- for (dv = devlist; dv ; dv = dv->next) ++ for (dv = devlist; dv; dv = dv->next) + if (data_offset == VARIABLE_OFFSET) + dv->data_offset = INVALID_SECTORS; + else +@@ -302,7 +302,7 @@ int Create(struct supertype *st, char *mddev, + int dfd; + char *doff; + +- if (strcasecmp(dname, "missing")==0) { ++ if (strcasecmp(dname, "missing") == 0) { + if (first_missing > dnum) + first_missing = dnum; + if (second_missing > dnum && dnum > first_missing) +@@ -348,7 +348,7 @@ int Create(struct supertype *st, char *mddev, + */ + int i; + char *name = "default"; +- for(i=0; !st && superlist[i]; i++) { ++ for(i = 0; !st && superlist[i]; i++) { + st = superlist[i]->match_metadata_desc(name); + if (!st) + continue; +@@ -444,10 +444,10 @@ int Create(struct supertype *st, char *mddev, + skip_size_check: + if (c->runstop != 1 || c->verbose >= 0) { + int fd = open(dname, O_RDONLY); +- if (fd <0 ) { ++ if (fd < 0) { + pr_err("Cannot open %s: %s\n", + dname, strerror(errno)); +- fail=1; ++ fail = 1; + continue; + } + warn |= check_ext2(fd, dname); +@@ -496,7 +496,7 @@ int Create(struct supertype *st, char *mddev, + return 1; + } + if (s->level > 0 || s->level == LEVEL_MULTIPATH || +- s->level == LEVEL_FAULTY || st->ss->external ) { ++ s->level == LEVEL_FAULTY || st->ss->external) { + /* size is meaningful */ + if (!st->ss->validate_geometry(st, s->level, s->layout, + s->raiddisks, +@@ -571,9 +571,9 @@ int Create(struct supertype *st, char *mddev, + * as missing, so that a reconstruct happens (faster than re-parity) + * FIX: Can we do this for raid6 as well? + */ +- if (st->ss->external == 0 && +- s->assume_clean==0 && c->force == 0 && first_missing >= s->raiddisks) { +- switch ( s->level ) { ++ if (st->ss->external == 0 && s->assume_clean == 0 && ++ c->force == 0 && first_missing >= s->raiddisks) { ++ switch (s->level) { + case 4: + case 5: + insert_point = s->raiddisks-1; +@@ -648,7 +648,7 @@ int Create(struct supertype *st, char *mddev, + * with, but it chooses to trust me instead. Sigh + */ + info.array.md_minor = 0; +- if (fstat(mdfd, &stb)==0) ++ if (fstat(mdfd, &stb) == 0) + info.array.md_minor = minor(stb.st_rdev); + info.array.not_persistent = 0; + +@@ -714,13 +714,11 @@ int Create(struct supertype *st, char *mddev, + name = strrchr(mddev, '/'); + if (name) { + name++; +- if (strncmp(name, "md_", 3)==0 && +- strlen(name) > 3 && +- (name-mddev) == 5 /* /dev/ */) ++ if (strncmp(name, "md_", 3) == 0 && ++ strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */) + name += 3; +- else if (strncmp(name, "md", 2)==0 && +- strlen(name) > 2 && +- isdigit(name[2]) && ++ else if (strncmp(name, "md", 2) == 0 && ++ strlen(name) > 2 && isdigit(name[2]) && + (name-mddev) == 5 /* /dev/ */) + name += 2; + } +@@ -771,9 +769,9 @@ int Create(struct supertype *st, char *mddev, + #endif + } + +- if (s->bitmap_file && (strcmp(s->bitmap_file, "internal")==0 || +- strcmp(s->bitmap_file, "clustered")==0)) { +- if ((vers%100) < 2) { ++ if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 || ++ strcmp(s->bitmap_file, "clustered") == 0)) { ++ if ((vers % 100) < 2) { + pr_err("internal bitmaps not supported by this kernel.\n"); + goto abort_locked; + } +@@ -856,11 +854,11 @@ int Create(struct supertype *st, char *mddev, + + infos = xmalloc(sizeof(*infos) * total_slots); + enable_fds(total_slots); +- for (pass=1; pass <=2 ; pass++) { ++ 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++) { ++ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; ++ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { + int fd; + struct stat stb2; + struct mdinfo *inf = &infos[dnum]; +@@ -872,7 +870,7 @@ int Create(struct supertype *st, char *mddev, + moved_disk = dv; + continue; + } +- if (strcasecmp(dv->devname, "missing")==0) { ++ if (strcasecmp(dv->devname, "missing") == 0) { + raid_disk_num += 1; + continue; + } +-- +2.7.4 + diff --git a/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch b/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch new file mode 100644 index 0000000..9686a9f --- /dev/null +++ b/SOURCES/Create-Remove-all-attemps-to-handle-md-driver-older-.patch @@ -0,0 +1,88 @@ +From 5f4cc2392689528a9234fae1935cd442f7917738 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:32:40 -0400 +Subject: [RHEL7.5 PATCH 058/169] Create: Remove all attemps to handle md + driver older than 0.90.03 + +More legacy code moved to the bit-bucket. + +Signed-off-by: Jes Sorensen +--- + Create.c | 30 +++++------------------------- + 1 file changed, 5 insertions(+), 25 deletions(-) + +diff --git a/Create.c b/Create.c +index 4f98c58..6ca0924 100644 +--- a/Create.c ++++ b/Create.c +@@ -97,7 +97,6 @@ int Create(struct supertype *st, char *mddev, + int insert_point = subdevs * 2; /* where to insert a missing drive */ + int total_slots; + int pass; +- int vers; + int rv; + int bitmap_fd; + int have_container = 0; +@@ -112,6 +111,7 @@ int Create(struct supertype *st, char *mddev, + char chosen_name[1024]; + struct map_ent *map = NULL; + unsigned long long newsize; ++ mdu_array_info_t inf; + + int major_num = BITMAP_MAJOR_HI; + if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0) { +@@ -150,7 +150,6 @@ int Create(struct supertype *st, char *mddev, + /* If given a single device, it might be a container, and we can + * extract a device list from there + */ +- mdu_array_info_t inf; + int fd; + + memset(&inf, 0, sizeof(inf)); +@@ -625,18 +624,11 @@ int Create(struct supertype *st, char *mddev, + } + mddev = chosen_name; + +- vers = md_get_version(mdfd); +- if (vers < 9000) { +- pr_err("Create requires md driver version 0.90.0 or later\n"); ++ memset(&inf, 0, sizeof(inf)); ++ md_get_array_info(mdfd, &inf); ++ if (inf.working_disks != 0) { ++ pr_err("another array by this name is already running.\n"); + goto abort_locked; +- } else { +- mdu_array_info_t inf; +- memset(&inf, 0, sizeof(inf)); +- md_get_array_info(mdfd, &inf); +- if (inf.working_disks != 0) { +- pr_err("another array by this name is already running.\n"); +- goto abort_locked; +- } + } + + /* Ok, lets try some ioctls */ +@@ -761,20 +753,8 @@ int Create(struct supertype *st, char *mddev, + * to stop another mdadm from finding and using those devices. + */ + +- if (s->bitmap_file && vers < 9003) { +- major_num = BITMAP_MAJOR_HOSTENDIAN; +-#ifdef __BIG_ENDIAN +- pr_err("Warning - bitmaps created on this kernel are not portable\n" +- " between different architectured. Consider upgrading the Linux kernel.\n"); +-#endif +- } +- + if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 || + strcmp(s->bitmap_file, "clustered") == 0)) { +- if ((vers % 100) < 2) { +- pr_err("internal bitmaps not supported by this kernel.\n"); +- goto abort_locked; +- } + if (!st->ss->add_internal_bitmap) { + pr_err("internal bitmaps not supported with %s metadata\n", + st->ss->name); +-- +2.7.4 + diff --git a/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch b/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch new file mode 100644 index 0000000..c886229 --- /dev/null +++ b/SOURCES/Create-tell-udev-md-device-is-not-ready-when-first-c.patch @@ -0,0 +1,311 @@ +From cd6cbb08c458cee07acb1d854e04532b29ec87bf Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 28 Apr 2017 15:05:50 +1000 +Subject: [RHEL7.5 PATCH 100/169] Create: tell udev md device is not ready + when first created. + +When an array is created the content is not initialized, +so it could have remnants of an old filesystem or md array +etc on it. +udev will see this and might try to activate it, which is almost +certainly not what is wanted. + +So create a mechanism for mdadm to communicate with udev to tell +it that the device isn't ready. This mechanism is the existance +of a file /run/mdadm/created-mdXXX where mdXXX is the md device name. + +When creating an array, mdadm will create the file. +A new udev rule file, 01-md-raid-creating.rules, will detect the +precense of thst file and set ENV{SYSTEMD_READY}="0". +This is fairly uniformly used to suppress actions based on the +contents of the device. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Assemble.c | 2 +- + Build.c | 2 +- + Create.c | 9 +++++++- + Incremental.c | 4 ++-- + Makefile | 4 ++-- + lib.c | 29 +++++++++++++++++++++++++ + mdadm.h | 4 +++- + mdopen.c | 52 ++++++++++++++++++++++++++++----------------- + udev-md-raid-creating.rules | 7 ++++++ + 9 files changed, 86 insertions(+), 27 deletions(-) + create mode 100644 udev-md-raid-creating.rules + +diff --git a/Assemble.c b/Assemble.c +index d6beb23..a9442c8 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1478,7 +1478,7 @@ try_again: + name = strchr(name, ':')+1; + + mdfd = create_mddev(mddev, name, ident->autof, trustworthy, +- chosen_name); ++ chosen_name, 0); + } + if (mdfd < 0) { + st->ss->free_super(st); +diff --git a/Build.c b/Build.c +index 11ba12f..665d906 100644 +--- a/Build.c ++++ b/Build.c +@@ -109,7 +109,7 @@ 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, +- chosen_name); ++ chosen_name, 0); + if (mdfd < 0) { + map_unlock(&map); + return 1; +diff --git a/Create.c b/Create.c +index 6ca0924..df1bc20 100644 +--- a/Create.c ++++ b/Create.c +@@ -605,7 +605,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); ++ mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1); + if (mdfd < 0) { + map_unlock(&map); + return 1; +@@ -620,6 +620,7 @@ int Create(struct supertype *st, char *mddev, + chosen_name); + close(mdfd); + map_unlock(&map); ++ udev_unblock(); + return 1; + } + mddev = chosen_name; +@@ -1053,9 +1054,15 @@ int Create(struct supertype *st, char *mddev, + pr_err("not starting array - not enough devices.\n"); + } + close(mdfd); ++ /* Give udev a moment to process the Change event caused ++ * by the close. ++ */ ++ usleep(100*1000); ++ udev_unblock(); + return 0; + + abort: ++ udev_unblock(); + map_lock(&map); + abort_locked: + map_remove(&map, fd2devnm(mdfd)); +diff --git a/Incremental.c b/Incremental.c +index 66c5b03..4789e36 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -320,7 +320,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); ++ name_to_use, c->autof, trustworthy, chosen_name, 0); + + if (mdfd < 0) + goto out_unlock; +@@ -1596,7 +1596,7 @@ static int Incremental_container(struct supertype *st, char *devname, + ra->name, + c->autof, + trustworthy, +- chosen_name); ++ chosen_name, 0); + } + if (only && (!mp || strcmp(mp->devnm, only) != 0)) + continue; +diff --git a/Makefile b/Makefile +index 6850696..021d3ad 100644 +--- a/Makefile ++++ b/Makefile +@@ -256,8 +256,8 @@ install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 + $(INSTALL) -D -m 644 md.4 $(DESTDIR)$(MAN4DIR)/md.4 + $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 + +-install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules +- @for file in 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \ ++install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid-creating.rules ++ @for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \ + do sed -e 's,BINDIR,$(BINDIR),g' udev-$${file#??-} > .install.tmp.1 && \ + $(ECHO) $(INSTALL) -D -m 644 udev-$${file#??-} $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \ + $(INSTALL) -D -m 644 .install.tmp.1 $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \ +diff --git a/lib.c b/lib.c +index b640634..7e44b1f 100644 +--- a/lib.c ++++ b/lib.c +@@ -163,6 +163,35 @@ 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-FOO 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 1bbacfe..6a382a7 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1533,7 +1533,7 @@ extern char *get_md_name(char *devnm); + extern char DefaultConfFile[]; + + extern int create_mddev(char *dev, char *name, int autof, int trustworthy, +- char *chosen); ++ char *chosen, int block_udev); + /* values for 'trustworthy' */ + #define LOCAL 1 + #define LOCAL_ANY 10 +@@ -1567,6 +1567,8 @@ extern char *stat2kname(struct stat *st); + extern char *fd2kname(int fd); + extern char *stat2devnm(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 82b97fc..099efa0 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -135,7 +135,7 @@ void make_parts(char *dev, int cnt) + */ + + int create_mddev(char *dev, char *name, int autof, int trustworthy, +- char *chosen) ++ char *chosen, int block_udev) + { + int mdfd; + struct stat stb; +@@ -147,6 +147,10 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + char devname[37]; + char devnm[32]; + char cbuf[400]; ++ ++ if (!use_udev()) ++ block_udev = 0; ++ + if (chosen == NULL) + chosen = cbuf; + +@@ -305,43 +309,53 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + int fd; + int n = -1; + sprintf(devnm, "md_%s", cname); ++ if (block_udev) ++ udev_block(devnm); + fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY); + if (fd >= 0) { + n = write(fd, devnm, strlen(devnm)); + close(fd); + } +- if (n < 0) ++ if (n < 0) { + devnm[0] = 0; ++ udev_unblock(); ++ } + } + if (num >= 0) { + int fd; + int n = -1; + sprintf(devnm, "md%d", num); ++ if (block_udev) ++ udev_block(devnm); + fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY); + if (fd >= 0) { + n = write(fd, devnm, strlen(devnm)); + close(fd); + } +- if (n < 0) ++ if (n < 0) { + devnm[0] = 0; +- } +- if (devnm[0]) +- ; +- else if (num < 0) { +- /* need to choose a free number. */ +- char *_devnm = find_free_devnm(use_mdp); +- if (_devnm == NULL) { +- pr_err("No avail md devices - aborting\n"); +- return -1; ++ udev_unblock(); + } +- strcpy(devnm, _devnm); +- } else { +- sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num); +- if (mddev_busy(devnm)) { +- pr_err("%s is already in use.\n", +- dev); +- return -1; ++ } ++ if (devnm[0] == 0) { ++ if (num < 0) { ++ /* need to choose a free number. */ ++ char *_devnm = find_free_devnm(use_mdp); ++ if (_devnm == NULL) { ++ pr_err("No avail md devices - aborting\n"); ++ return -1; ++ } ++ strcpy(devnm, _devnm); ++ } else { ++ sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num); ++ if (mddev_busy(devnm)) { ++ pr_err("%s is already in use.\n", ++ dev); ++ return -1; ++ } + } ++ if (block_udev) ++ udev_block(devnm); + } + + sprintf(devname, "/dev/%s", devnm); +diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules +new file mode 100644 +index 0000000..2be466b +--- /dev/null ++++ b/udev-md-raid-creating.rules +@@ -0,0 +1,7 @@ ++# do not edit this file, it will be overwritten on update ++# While mdadm is creating an array, it creates a file ++# /run/mdadm/creating-mdXXX. If that file exists, then ++# the array is not "ready" and we should make sure the ++# content is ignored. ++ ++KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0" +-- +2.7.4 + diff --git a/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch b/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch new file mode 100644 index 0000000..843b6a4 --- /dev/null +++ b/SOURCES/Detail-Fixup-ugly-if-foo-abuse.patch @@ -0,0 +1,38 @@ +From 776b199e41d10e344efc47008366ca46715c5acc Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 12 Apr 2017 17:05:55 -0400 +Subject: [RHEL7.5 PATCH 078/169] Detail: Fixup ugly if () foo() abuse + +Cosmetic change only + +Signed-off-by: Jes Sorensen +--- + Detail.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 8f74832..e40cd8f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -141,13 +141,15 @@ int Detail(char *dev, struct context *c) + } + + /* try to load a superblock. Try sra->devs first, then try ioctl */ +- if (st && !info) for (d = 0, subdev = sra ? sra->devs : NULL; +- d < max_disks || subdev; +- subdev ? (void)(subdev = subdev->next) : (void)(d++)){ ++ if (st && !info) ++ for (d = 0, subdev = sra ? sra->devs : NULL; ++ d < max_disks || subdev; ++ subdev ? (void)(subdev = subdev->next) : (void)(d++)){ + mdu_disk_info_t disk; + char *dv; + int fd2; + int err; ++ + if (subdev) + disk = subdev->disk; + else { +-- +2.7.4 + diff --git a/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch b/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch new file mode 100644 index 0000000..0bc947a --- /dev/null +++ b/SOURCES/Detail-Reinstate-support-for-not-having-sysfs.patch @@ -0,0 +1,37 @@ +From 0885b942b3575c7f2a8290087751d83902587371 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 25 Apr 2017 14:34:31 -0400 +Subject: [RHEL7.5 PATCH 097/169] Detail: Reinstate support for not having + sysfs + +While sysfs support will hopefully go away eventually, lets not break +it unnecessarily for now. + +Fixes: 901d5ee ("Detail: Stop bothering about md drivers older than 0.90.00") +Signed-off-by: Jes Sorensen +--- + Detail.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Detail.c b/Detail.c +index ceb21b1..ef2370c 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -88,9 +88,11 @@ int Detail(char *dev, struct context *c) + } + sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE); + if (!sra) { +- pr_err("%s does not appear to be an md device\n", dev); +- close(fd); +- return rv; ++ if (md_get_array_info(fd, &array)) { ++ pr_err("%s does not appear to be an md device\n", dev); ++ close(fd); ++ return rv; ++ } + } + external = (sra != NULL && sra->array.major_version == -1 && + sra->array.minor_version == -2); +-- +2.7.4 + diff --git a/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch b/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch new file mode 100644 index 0000000..52ffc3f --- /dev/null +++ b/SOURCES/Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch @@ -0,0 +1,61 @@ +From 5e13ef714df4734c455b5e4389352c8ab7902038 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 12 Apr 2017 14:48:10 -0400 +Subject: [RHEL7.5 PATCH 076/169] Detail: Remove pre-2.6 code for printing + info on rebuilding + +Since we no longer support anything pre-2.6.15, there is no point in +keeping this around. + +Signed-off-by: Jes Sorensen +--- + Detail.c | 19 +++---------------- + 1 file changed, 3 insertions(+), 16 deletions(-) + +diff --git a/Detail.c b/Detail.c +index d4e6204..8f74832 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -64,8 +64,6 @@ int Detail(char *dev, struct context *c) + int max_devices = 0, n_devices = 0; + int spares = 0; + struct stat stb; +- int is_26 = get_linux_version() >= 2006000; +- int is_rebuilding = 0; + int failed = 0; + struct supertype *st; + char *subarray = NULL; +@@ -527,7 +525,6 @@ int Detail(char *dev, struct context *c) + "Reshape", "Check"}; + printf(" %7s Status : %d%% complete\n", + sync_action[e->resync], e->percent); +- is_rebuilding = 1; + } + free_mdstat(ms); + +@@ -676,19 +673,9 @@ This is pretty boring + |(1<= 0) +- printf(" rebuilding"); +- } else if (is_rebuilding && failed) { +- /* Taking a bit of a risk here, we remove the +- * device from the array, and then put it back. +- * If this fails, we are rebuilding +- */ +- int err = ioctl(fd, HOT_REMOVE_DISK, makedev(disk.major, disk.minor)); +- if (err == 0) ioctl(fd, HOT_ADD_DISK, makedev(disk.major, disk.minor)); +- if (err && errno == EBUSY) +- printf(" rebuilding"); +- } ++ if (disk.raid_disk < array.raid_disks && ++ disk.raid_disk >= 0) ++ printf(" rebuilding"); + } + } + if (disk.state == 0) spares++; +-- +2.7.4 + diff --git a/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch b/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch new file mode 100644 index 0000000..571e366 --- /dev/null +++ b/SOURCES/Detail-Respect-code-lines-are-80-character-wide.patch @@ -0,0 +1,521 @@ +From 5737086ed7a39e4d940ed1459d1afad359c3182c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 25 Apr 2017 12:21:39 -0400 +Subject: [RHEL7.5 PATCH 096/169] Detail: Respect code lines are 80 + character wide + +In addition apply spaces and don'f do 'if () action()' on the same line. + +Signed-off-by: Jes Sorensen +--- + Detail.c | 239 ++++++++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 138 insertions(+), 101 deletions(-) + +diff --git a/Detail.c b/Detail.c +index eb69276..ceb21b1 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -157,8 +157,7 @@ int Detail(char *dev, struct context *c) + if (md_get_disk_info(fd, &disk) < 0) + continue; + if (d >= array.raid_disks && +- disk.major == 0 && +- disk.minor == 0) ++ disk.major == 0 && disk.minor == 0) + continue; + } + +@@ -236,7 +235,8 @@ int Detail(char *dev, struct context *c) + printf("MD_METADATA=%s\n", sra->text_version); + else + printf("MD_METADATA=%d.%d\n", +- array.major_version, array.minor_version); ++ array.major_version, ++ array.minor_version); + } + + if (st && st->sb && info) { +@@ -244,12 +244,12 @@ int Detail(char *dev, struct context *c) + struct map_ent *mp, *map = NULL; + + fname_from_uuid(st, info, nbuf, ':'); +- printf("MD_UUID=%s\n", nbuf+5); ++ 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) { + printf("MD_DEVNAME="); +- print_escape(mp->path+8); ++ print_escape(mp->path + 8); + putchar('\n'); + } + +@@ -273,11 +273,12 @@ int Detail(char *dev, struct context *c) + if (sra) { + struct mdinfo *mdi; + for (mdi = sra->devs; mdi; mdi = mdi->next) { +- char *path = +- map_dev(mdi->disk.major, +- mdi->disk.minor, 0); ++ char *path; + char *sysdev = xstrdup(mdi->sys_name + 1); + char *cp; ++ ++ path = map_dev(mdi->disk.major, ++ mdi->disk.minor, 0); + for (cp = sysdev; *cp; cp++) + if (!isalnum(*cp)) + *cp = '_'; +@@ -299,19 +300,19 @@ int Detail(char *dev, struct context *c) + + disks = xmalloc(max_disks * 2 * sizeof(mdu_disk_info_t)); + for (d = 0; d < max_disks * 2; d++) { +- disks[d].state = (1<devs; mdi; mdi = mdi->next) { + disks[next++] = mdi->disk; +- disks[next-1].number = -1; ++ disks[next - 1].number = -1; + } + } else for (d = 0; d < max_disks; d++) { + mdu_disk_info_t disk; +@@ -324,21 +325,23 @@ int Detail(char *dev, struct context *c) + } + if (disk.major == 0 && disk.minor == 0) + continue; +- if (disk.raid_disk >= 0 && disk.raid_disk < array.raid_disks +- && disks[disk.raid_disk*2].state == (1<= 0 && disk.raid_disk < array.raid_disks +- && disks[disk.raid_disk*2+1].state == (1<= 0 && disk.raid_disk < array.raid_disks && ++ disks[disk.raid_disk * 2].state == (1 << MD_DISK_REMOVED) && ++ ((disk.state & (1 << MD_DISK_JOURNAL)) == 0)) ++ disks[disk.raid_disk * 2] = disk; ++ else if (disk.raid_disk >= 0 && ++ disk.raid_disk < array.raid_disks && ++ disks[disk.raid_disk * 2 + 1].state == ++ (1 << MD_DISK_REMOVED) && ++ !(disk.state & (1 << MD_DISK_JOURNAL))) ++ disks[disk.raid_disk * 2 + 1] = disk; ++ else if (next < max_disks * 2) + disks[next++] = disk; + } + + avail = xcalloc(array.raid_disks, 1); + +- for (d= 0; d < array.raid_disks; d++) { ++ for (d = 0; d < array.raid_disks; d++) { + + if ((disks[d*2].state & (1<verbose > 0) { + if (array.raid_disks) + printf(" level=%s num-devices=%d", +- str?str:"-unknown-", +- array.raid_disks ); ++ str ? str : "-unknown-", ++ array.raid_disks); + else if (!inactive) + printf(" level=container num-devices=%d", + array.nr_disks); +@@ -369,8 +372,8 @@ int Detail(char *dev, struct context *c) + if (sra && sra->array.major_version < 0) + printf(" metadata=%s", sra->text_version); + else +- printf(" metadata=%d.%d", +- array.major_version, array.minor_version); ++ printf(" metadata=%d.%d", array.major_version, ++ array.minor_version); + } + + /* Only try GET_BITMAP_FILE for 0.90.01 and later */ +@@ -385,7 +388,7 @@ int Detail(char *dev, struct context *c) + char *devnm; + + devnm = stat2devnm(&stb); +- for (e=ms; e; e=e->next) ++ for (e = ms; e; e = e->next) + if (strcmp(e->devnm, devnm) == 0) + break; + if (!get_dev_size(fd, NULL, &larray_size)) +@@ -394,14 +397,16 @@ int Detail(char *dev, struct context *c) + printf("%s:\n", dev); + + if (container) +- printf(" Container : %s, member %s\n", container, +- member); ++ printf(" Container : %s, member %s\n", ++ container, member); + else { +- if (sra && sra->array.major_version < 0) +- printf(" Version : %s\n", sra->text_version); +- else +- printf(" Version : %d.%d\n", +- array.major_version, array.minor_version); ++ if (sra && sra->array.major_version < 0) ++ printf(" Version : %s\n", ++ sra->text_version); ++ else ++ printf(" Version : %d.%d\n", ++ array.major_version, ++ array.minor_version); + } + + atime = array.ctime; +@@ -412,14 +417,17 @@ int Detail(char *dev, struct context *c) + if (str) + printf(" Raid Level : %s\n", str); + if (larray_size) +- printf(" Array Size : %llu%s\n", (larray_size>>10), ++ printf(" Array Size : %llu%s\n", ++ (larray_size >> 10), + human_size(larray_size)); + if (array.level >= 1) { + if (sra) + array.major_version = sra->array.major_version; + if (array.major_version != 0 && + (larray_size >= 0xFFFFFFFFULL|| array.size == 0)) { +- unsigned long long dsize = get_component_size(fd); ++ unsigned long long dsize; ++ ++ dsize = get_component_size(fd); + if (dsize > 0) + printf(" Used Dev Size : %llu%s\n", + dsize/2, +@@ -429,7 +437,8 @@ int Detail(char *dev, struct context *c) + } else + printf(" Used Dev Size : %lu%s\n", + (unsigned long)array.size, +- human_size((unsigned long long)array.size<<10)); ++ human_size((unsigned long long) ++ array.size << 10)); + } + if (array.raid_disks) + printf(" Raid Devices : %d\n", array.raid_disks); +@@ -440,7 +449,7 @@ int Detail(char *dev, struct context *c) + printf(" Preferred Minor : %d\n", array.md_minor); + if (sra == NULL || sra->array.major_version >= 0) + printf(" Persistence : Superblock is %spersistent\n", +- array.not_persistent?"not ":""); ++ array.not_persistent ? "not " : ""); + printf("\n"); + /* Only try GET_BITMAP_FILE for 0.90.01 and later */ + if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { +@@ -465,19 +474,25 @@ int Detail(char *dev, struct context *c) + st = ", degraded"; + + printf(" State : %s%s%s%s%s%s \n", +- (array.state&(1<percent < 0 && e->percent != RESYNC_PENDING && +- e->percent != RESYNC_DELAYED)) ? "" : sync_action[e->resync], ++ (array.state & (1 << MD_SB_CLEAN)) ? ++ "clean" : "active", st, ++ (!e || (e->percent < 0 && ++ e->percent != RESYNC_PENDING && ++ e->percent != RESYNC_DELAYED)) ? ++ "" : sync_action[e->resync], + larray_size ? "": ", Not Started", +- (e && e->percent == RESYNC_DELAYED) ? " (DELAYED)": "", +- (e && e->percent == RESYNC_PENDING) ? " (PENDING)": ""); ++ (e && e->percent == RESYNC_DELAYED) ? ++ " (DELAYED)": "", ++ (e && e->percent == RESYNC_PENDING) ? ++ " (PENDING)": ""); + } else if (inactive) { + printf(" State : inactive\n"); + } + if (array.raid_disks) + printf(" Active Devices : %d\n", array.active_disks); + if (array.working_disks > 0) +- printf(" Working Devices : %d\n", array.working_disks); ++ printf(" Working Devices : %d\n", ++ array.working_disks); + if (array.raid_disks) { + printf(" Failed Devices : %d\n", array.failed_disks); + printf(" Spare Devices : %d\n", array.spare_disks); +@@ -485,11 +500,13 @@ int Detail(char *dev, struct context *c) + printf("\n"); + if (array.level == 5) { + str = map_num(r5layout, array.layout); +- printf(" Layout : %s\n", str?str:"-unknown-"); ++ printf(" Layout : %s\n", ++ str ? str : "-unknown-"); + } + if (array.level == 6) { + str = map_num(r6layout, array.layout); +- printf(" Layout : %s\n", str?str:"-unknown-"); ++ printf(" Layout : %s\n", ++ str ? str : "-unknown-"); + } + if (array.level == 10) { + printf(" Layout :"); +@@ -510,12 +527,14 @@ int Detail(char *dev, struct context *c) + printf(" Rounding : %dK\n\n", + array.chunk_size/1024); + break; +- default: break; ++ default: ++ break; + } + + if (array.raid_disks) { +- struct mdinfo *mdi = sysfs_read(fd, NULL, +- GET_CONSISTENCY_POLICY); ++ struct mdinfo *mdi; ++ ++ mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY); + if (mdi) { + char *policy = map_num(consistency_policies, + mdi->consistency_policy); +@@ -528,8 +547,7 @@ int Detail(char *dev, struct context *c) + + if (e && e->percent >= 0) { + static char *sync_action[] = { +- "Rebuild", "Resync", +- "Reshape", "Check"}; ++ "Rebuild", "Resync", "Reshape", "Check"}; + printf(" %7s Status : %d%% complete\n", + sync_action[e->resync], e->percent); + } +@@ -539,8 +557,9 @@ int Detail(char *dev, struct context *c) + #if 0 + This is pretty boring + printf(" Reshape pos'n : %llu%s\n", +- (unsigned long long) info->reshape_progress<<9, +- human_size((unsigned long long)info->reshape_progress<<9)); ++ (unsigned long long) info->reshape_progress << 9, ++ human_size((unsigned long long) ++ info->reshape_progress << 9)); + #endif + if (info->delta_disks != 0) + printf(" Delta Devices : %d, (%d->%d)\n", +@@ -549,25 +568,29 @@ This is pretty boring + array.raid_disks); + if (info->new_level != array.level) { + str = map_num(pers, info->new_level); +- printf(" New Level : %s\n", str?str:"-unknown-"); ++ printf(" New Level : %s\n", ++ str ? str : "-unknown-"); + } + if (info->new_level != array.level || + info->new_layout != array.layout) { + if (info->new_level == 5) { +- str = map_num(r5layout, info->new_layout); ++ str = map_num(r5layout, ++ info->new_layout); + printf(" New Layout : %s\n", +- str?str:"-unknown-"); ++ str ? str : "-unknown-"); + } + if (info->new_level == 6) { +- str = map_num(r6layout, info->new_layout); ++ str = map_num(r6layout, ++ info->new_layout); + printf(" New Layout : %s\n", +- str?str:"-unknown-"); ++ str ? str : "-unknown-"); + } + if (info->new_level == 10) { + printf(" New Layout : near=%d, %s=%d\n", +- info->new_layout&255, +- (info->new_layout&0x10000)?"offset":"far", +- (info->new_layout>>8)&255); ++ info->new_layout & 255, ++ (info->new_layout & 0x10000) ? ++ "offset" : "far", ++ (info->new_layout >> 8) & 255); + } + } + if (info->new_chunk != array.chunk_size) +@@ -579,8 +602,10 @@ This is pretty boring + if (st && st->sb) + st->ss->detail_super(st, c->homehost); + +- if (array.raid_disks == 0 && sra && sra->array.major_version == -1 +- && sra->array.minor_version == -2 && sra->text_version[0] != '/') { ++ if (array.raid_disks == 0 && sra && ++ sra->array.major_version == -1 && ++ sra->array.minor_version == -2 && ++ sra->text_version[0] != '/') { + /* This looks like a container. Find any active arrays + * That claim to be a member. + */ +@@ -596,19 +621,21 @@ This is pretty boring + dev_t devid; + if (de->d_name[0] == '.') + continue; +- sprintf(path, "/sys/block/%s/md/metadata_version", ++ sprintf(path, ++ "/sys/block/%s/md/metadata_version", + de->d_name); + if (load_sys(path, vbuf, sizeof(vbuf)) < 0) + continue; +- if (strncmp(vbuf, "external:", 9) != 0 || +- !is_subarray(vbuf+9) || +- strncmp(vbuf+10, sra->sys_name, nlen) != 0 || +- vbuf[10+nlen] != '/') ++ if (strncmp(vbuf, "external:", 9) || ++ !is_subarray(vbuf + 9) || ++ strncmp(vbuf + 10, sra->sys_name, nlen) || ++ vbuf[10 + nlen] != '/') + continue; + devid = devnm2devid(de->d_name); +- printf(" %s", map_dev_preferred( +- major(devid), +- minor(devid), 1, c->prefer)); ++ printf(" %s", ++ map_dev_preferred(major(devid), ++ minor(devid), 1, ++ c->prefer)); + } + if (dir) + closedir(dir); +@@ -622,24 +649,23 @@ This is pretty boring + } + free(info); + +- for (d= 0; d < max_disks * 2; d++) { ++ for (d = 0; d < max_disks * 2; d++) { + char *dv; + mdu_disk_info_t disk = disks[d]; + +- if (d >= array.raid_disks*2 && +- disk.major == 0 && +- disk.minor == 0) ++ if (d >= array.raid_disks * 2 && ++ disk.major == 0 && disk.minor == 0) + continue; +- if ((d & 1) && +- disk.major == 0 && +- disk.minor == 0) ++ if ((d & 1) && disk.major == 0 && disk.minor == 0) + continue; + if (!c->brief) { +- if (d == array.raid_disks*2) printf("\n"); ++ if (d == array.raid_disks*2) ++ printf("\n"); + if (disk.number < 0 && disk.raid_disk < 0) + printf(" - %5d %5d - ", + disk.major, disk.minor); +- else if (disk.raid_disk < 0 || disk.state & (1<brief && array.raid_disks) { +- +- if (disk.state & (1<= 0) + failed++; + } +- if (disk.state & (1<> 8) & 0xff; + int copies = nc*fc; +- if (fc == 1 && array.raid_disks % copies == 0 && copies <= 26) { +- /* We can divide the devices into 'sets' */ +- int set = disk.raid_disk % copies; ++ if (fc == 1 && ++ array.raid_disks % copies == 0 && ++ copies <= 26) { ++ /* We can divide the devices ++ into 'sets' */ ++ int set; ++ set = disk.raid_disk % copies; + printf(" set-%c", set + 'A'); + } + } + } +- if (disk.state & (1<prefer); ++ if (disk.state == 0) ++ spares++; ++ dv = map_dev_preferred(disk.major, disk.minor, 0, c->prefer); + if (dv != NULL) { + if (c->brief) + n_devices = add_device(dv, &devices, +- &max_devices, +- n_devices); ++ &max_devices, n_devices); + else + printf(" %s", dv); + } +- if (!c->brief) printf("\n"); ++ if (!c->brief) ++ printf("\n"); + } +- if (spares && c->brief && array.raid_disks) printf(" spares=%d", spares); ++ if (spares && c->brief && array.raid_disks) ++ printf(" spares=%d", spares); + if (c->brief && st && st->sb) + st->ss->brief_detail_super(st); + if (st) +@@ -712,8 +750,7 @@ This is pretty boring + if (c->brief) + printf("\n"); + if (c->test && +- !enough(array.level, array.raid_disks, array.layout, +- 1, avail)) ++ !enough(array.level, array.raid_disks, array.layout, 1, avail)) + rv = 2; + + free(disks); +-- +2.7.4 + diff --git a/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch b/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch new file mode 100644 index 0000000..7e8ae29 --- /dev/null +++ b/SOURCES/Detail-Stop-bothering1-about-md-drivers-older-than-0..patch @@ -0,0 +1,78 @@ +From 901d5ee6da145033ac30fee68f4fec0e8af9eddc Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:26:53 -0400 +Subject: [RHEL7.5 PATCH 057/169] Detail: Stop bothering about md drivers + older than 0.90.00 + +Remove further handling of md driver version older than 0.90.00 + +Signed-off-by: Jes Sorensen +--- + Detail.c | 27 +++++++-------------------- + 1 file changed, 7 insertions(+), 20 deletions(-) + +diff --git a/Detail.c b/Detail.c +index fa6d4c7..d4e6204 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -54,7 +54,6 @@ int Detail(char *dev, struct context *c) + * Print out details for an md array + */ + int fd = open(dev, O_RDONLY); +- int vers; + mdu_array_info_t array; + mdu_disk_info_t *disks; + int next; +@@ -88,22 +87,14 @@ int Detail(char *dev, struct context *c) + dev, strerror(errno)); + return rv; + } +- vers = md_get_version(fd); +- if (vers < 0) { +- pr_err("%s does not appear to be an md device\n", +- dev); +- close(fd); +- return rv; +- } +- if (vers < 9000) { +- pr_err("cannot get detail for md device %s: driver version too old.\n", +- dev); ++ sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS); ++ if (!sra) { ++ pr_err("%s does not appear to be an md device\n", dev); + close(fd); + return rv; + } +- sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS); +- external = (sra != NULL && sra->array.major_version == -1 +- && sra->array.minor_version == -2); ++ external = (sra != NULL && sra->array.major_version == -1 && ++ sra->array.minor_version == -2); + st = super_by_fd(fd, &subarray); + if (md_get_array_info(fd, &array) == 0) { + inactive = 0; +@@ -378,9 +369,7 @@ int Detail(char *dev, struct context *c) + } + + /* Only try GET_BITMAP_FILE for 0.90.01 and later */ +- if (vers >= 9001 && +- ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && +- bmf.pathname[0]) { ++ if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { + printf(" bitmap=%s", bmf.pathname); + } + } else { +@@ -449,9 +438,7 @@ int Detail(char *dev, struct context *c) + array.not_persistent?"not ":""); + printf("\n"); + /* Only try GET_BITMAP_FILE for 0.90.01 and later */ +- if (vers >= 9001 && +- ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && +- bmf.pathname[0]) { ++ if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) { + printf(" Intent Bitmap : %s\n", bmf.pathname); + printf("\n"); + } else if (array.state & (1< +Date: Thu, 10 Aug 2017 11:43:48 +0200 +Subject: [RHEL7.5 PATCH 162/169] Detail: correct output for active arrays + +The check for inactive array is incorrect as it compares it against +active array. Introduce a new function md_is_array_active so the check +is consistent across the code. + +As the output contains list of disks in the array include this +information in sysfs read. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Detail.c | 15 +++++++-------- + mdadm.h | 1 + + util.c | 15 +++++++++------ + 3 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 2332b85..2c9fb24 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -86,7 +86,8 @@ int Detail(char *dev, struct context *c) + dev, strerror(errno)); + return rv; + } +- sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE); ++ sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | ++ GET_ARRAY_STATE | GET_STATE); + if (!sra) { + if (md_get_array_info(fd, &array)) { + pr_err("%s does not appear to be an md device\n", dev); +@@ -96,8 +97,7 @@ int Detail(char *dev, struct context *c) + } + external = (sra != NULL && sra->array.major_version == -1 && + sra->array.minor_version == -2); +- inactive = (sra->array_state == ARRAY_ACTIVE || +- sra->array_state == ARRAY_CLEAR); ++ inactive = (sra != NULL && !md_array_is_active(sra)); + st = super_by_fd(fd, &subarray); + if (md_get_array_info(fd, &array)) { + if (errno == ENODEV) { +@@ -314,11 +314,10 @@ int Detail(char *dev, struct context *c) + next = array.raid_disks * 2; + if (inactive) { + struct mdinfo *mdi; +- if (sra != NULL) +- for (mdi = sra->devs; mdi; mdi = mdi->next) { +- disks[next++] = mdi->disk; +- disks[next - 1].number = -1; +- } ++ for (mdi = sra->devs; mdi; mdi = mdi->next) { ++ disks[next++] = mdi->disk; ++ disks[next - 1].number = -1; ++ } + } else for (d = 0; d < max_disks; d++) { + mdu_disk_info_t disk; + disk.number = d; +diff --git a/mdadm.h b/mdadm.h +index ee9b837..191ae8f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1425,6 +1425,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c, + + int md_array_valid(int fd); + int md_array_active(int fd); ++int md_array_is_active(struct mdinfo *info); + int md_get_array_info(int fd, struct mdu_array_info_s *array); + int md_set_array_info(int fd, struct mdu_array_info_s *array); + int md_get_disk_info(int fd, struct mdu_disk_info_s *disk); +diff --git a/util.c b/util.c +index 8eeb509..c1c8509 100644 +--- a/util.c ++++ b/util.c +@@ -228,15 +228,11 @@ int md_array_active(int fd) + { + struct mdinfo *sra; + struct mdu_array_info_s array; +- int ret; ++ int ret = 0; + + sra = sysfs_read(fd, NULL, GET_ARRAY_STATE); + if (sra) { +- if (sra->array_state != ARRAY_CLEAR && +- sra->array_state != ARRAY_INACTIVE && +- sra->array_state != ARRAY_UNKNOWN_STATE) +- ret = 0; +- else ++ if (!md_array_is_active(sra)) + ret = -ENODEV; + + free(sra); +@@ -251,6 +247,13 @@ int md_array_active(int fd) + return !ret; + } + ++int md_array_is_active(struct mdinfo *info) ++{ ++ return (info->array_state != ARRAY_CLEAR && ++ info->array_state != ARRAY_INACTIVE && ++ info->array_state != ARRAY_UNKNOWN_STATE); ++} ++ + /* + * Get array info from the kernel. Longer term we want to deprecate the + * ioctl and get it from sysfs. +-- +2.7.4 + diff --git a/SOURCES/Detail-determine2-array-state-from-sysfs.patch b/SOURCES/Detail-determine2-array-state-from-sysfs.patch new file mode 100644 index 0000000..8d054f1 --- /dev/null +++ b/SOURCES/Detail-determine2-array-state-from-sysfs.patch @@ -0,0 +1,54 @@ +From a4dcdb23ea639d14e92d1c86336de7ad505b2f7d Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 25 Apr 2017 11:40:27 -0400 +Subject: [RHEL7.5 PATCH 095/169] Detail: determine array state from sysfs + +This is easily obtained from sysfs as part of the existing call to +sysfs_read() and it simplifies the code a little too. + +Another small step in the process of getting rid of the GET_ARRAY_STATE +ioctl. + +Signed-off-by: Jes Sorensen +--- + Detail.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 91c5a98..eb69276 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -86,7 +86,7 @@ int Detail(char *dev, struct context *c) + dev, strerror(errno)); + return rv; + } +- sra = sysfs_read(fd, NULL, GET_VERSION|GET_DEVS); ++ sra = sysfs_read(fd, NULL, GET_VERSION | GET_DEVS | GET_ARRAY_STATE); + if (!sra) { + pr_err("%s does not appear to be an md device\n", dev); + close(fd); +@@ -94,10 +94,10 @@ int Detail(char *dev, struct context *c) + } + external = (sra != NULL && sra->array.major_version == -1 && + sra->array.minor_version == -2); ++ inactive = (sra->array_state == ARRAY_ACTIVE || ++ sra->array_state == ARRAY_CLEAR); + st = super_by_fd(fd, &subarray); +- if (md_get_array_info(fd, &array) == 0) { +- inactive = 0; +- } else if (errno == ENODEV && sra) { ++ if (md_get_array_info(fd, &array) && errno == ENODEV) { + if (sra->array.major_version == -1 && + sra->array.minor_version == -1 && + sra->devs == NULL) { +@@ -107,7 +107,6 @@ int Detail(char *dev, struct context *c) + return rv; + } + array = sra->array; +- inactive = 1; + } else { + pr_err("cannot get array detail for %s: %s\n", + dev, strerror(errno)); +-- +2.7.4 + diff --git a/SOURCES/Detail-differentiate-between-container-and-inactive-.patch b/SOURCES/Detail-differentiate-between-container-and-inactive-.patch new file mode 100644 index 0000000..b4a0d73 --- /dev/null +++ b/SOURCES/Detail-differentiate-between-container-and-inactive-.patch @@ -0,0 +1,89 @@ +From bb8354598676428af01f23bfb1876c7356d61147 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 18 Aug 2017 12:00:23 +0200 +Subject: [RHEL7.5 PATCH 01/13] Detail: differentiate between container and + inactive arrays + +Containers used to be handled as active arrays because GET_ARRAY_INFO +ioctl returns valid structure for them. As containers appear as inactive +in sysfs, the output for detail command has changed. + +Stop relying on inactive state for containers. Make the output look the +same as in mdadm 4.0. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Detail.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 2c9fb24..4dcf81d 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -80,6 +80,7 @@ int Detail(char *dev, struct context *c) + char *avail = NULL; + int external; + int inactive; ++ int is_container = 0; + + if (fd < 0) { + pr_err("cannot open %s: %s\n", +@@ -119,6 +120,8 @@ int Detail(char *dev, struct context *c) + } + } + ++ if (array.raid_disks == 0 && external) ++ is_container = 1; + if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode)) + stb.st_rdev = 0; + rv = 0; +@@ -228,7 +231,7 @@ int Detail(char *dev, struct context *c) + printf("MD_LEVEL=%s\n", str); + printf("MD_DEVICES=%d\n", array.raid_disks); + } else { +- if (!inactive) ++ if (is_container) + printf("MD_LEVEL=container\n"); + printf("MD_DEVICES=%d\n", array.nr_disks); + } +@@ -357,13 +360,16 @@ int Detail(char *dev, struct context *c) + + if (c->brief) { + mdu_bitmap_file_t bmf; +- printf("%sARRAY %s", inactive ? "INACTIVE-":"", dev); ++ if (inactive && !is_container) ++ printf("INACTIVE-ARRAY %s", dev); ++ else ++ printf("ARRAY %s", dev); + if (c->verbose > 0) { + if (array.raid_disks) + printf(" level=%s num-devices=%d", + str ? str : "-unknown-", + array.raid_disks); +- else if (!inactive) ++ else if (is_container) + printf(" level=container num-devices=%d", + array.nr_disks); + else +@@ -416,7 +422,7 @@ int Detail(char *dev, struct context *c) + atime = array.ctime; + if (atime) + printf(" Creation Time : %.24s\n", ctime(&atime)); +- if (array.raid_disks == 0 && external) ++ if (is_container) + str = "container"; + if (str) + printf(" Raid Level : %s\n", str); +@@ -489,7 +495,7 @@ int Detail(char *dev, struct context *c) + " (DELAYED)": "", + (e && e->percent == RESYNC_PENDING) ? + " (PENDING)": ""); +- } else if (inactive) { ++ } else if (inactive && !is_container) { + printf(" State : inactive\n"); + } + if (array.raid_disks) +-- +2.7.4 + diff --git a/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch b/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch new file mode 100644 index 0000000..288f9ce --- /dev/null +++ b/SOURCES/Detail-don-t-exit-if-ioctl-has-been-successful.patch @@ -0,0 +1,76 @@ +From 9b8fea914f82281c440cdce9dee6a3775265861c Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Wed, 24 May 2017 11:34:22 +0200 +Subject: [RHEL7.5 PATCH 147/169] Detail: don't exit if ioctl has been + successful + +When GET_ARRAY_INFO ioctl is successful, mdadm exits with an error. +It breaks udev and no links in /dev/md are created. + +Also change debug print to error print in the message indicating lack +of the link to facilitate debugging similar issues in the future. + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + Detail.c | 27 +++++++++++++++------------ + util.c | 2 +- + 2 files changed, 16 insertions(+), 13 deletions(-) + +diff --git a/Detail.c b/Detail.c +index bf881ff..2332b85 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -99,21 +99,24 @@ int Detail(char *dev, struct context *c) + inactive = (sra->array_state == ARRAY_ACTIVE || + sra->array_state == ARRAY_CLEAR); + st = super_by_fd(fd, &subarray); +- if (md_get_array_info(fd, &array) && errno == ENODEV) { +- if (sra->array.major_version == -1 && +- sra->array.minor_version == -1 && +- sra->devs == NULL) { +- pr_err("Array associated with md device %s does not exist.\n", dev); ++ if (md_get_array_info(fd, &array)) { ++ if (errno == ENODEV) { ++ if (sra->array.major_version == -1 && ++ sra->array.minor_version == -1 && ++ sra->devs == NULL) { ++ pr_err("Array associated with md device %s does not exist.\n", ++ dev); ++ close(fd); ++ sysfs_free(sra); ++ return rv; ++ } ++ array = sra->array; ++ } else { ++ pr_err("cannot get array detail for %s: %s\n", ++ dev, strerror(errno)); + close(fd); +- sysfs_free(sra); + return rv; + } +- array = sra->array; +- } else { +- pr_err("cannot get array detail for %s: %s\n", +- dev, strerror(errno)); +- close(fd); +- return rv; + } + + if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode)) +diff --git a/util.c b/util.c +index d89438c..8eeb509 100644 +--- a/util.c ++++ b/util.c +@@ -1169,7 +1169,7 @@ void wait_for(char *dev, int fd) + delay *= 2; + } + if (i == 25) +- dprintf("timeout waiting for %s\n", dev); ++ pr_err("timeout waiting for %s\n", dev); + } + + struct superswitch *superlist[] = +-- +2.7.4 + diff --git a/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch b/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch new file mode 100644 index 0000000..7f2f073 --- /dev/null +++ b/SOURCES/Detail-ensure-export-names-are-acceptable-as-shell-v.patch @@ -0,0 +1,69 @@ +From b9c9bd9bacaab701d5b3cb3e4b6cb02ea8d36e47 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 20 Apr 2017 12:40:06 +1000 +Subject: [RHEL7.5 PATCH 089/169] Detail: ensure --export names are + acceptable as shell variables. + +If an array contains a device which has a name that +contains something other than alphnumerics and underscores, +then some values reported by "mdadm --detail --export" will +not be valid as variable assignment of the shell. +This particularly affects dm devices. +e.g. + MD_DEVICE_dm-4_ROLE=1 + MD_DEVICE_dm-4_DEV=/dev/dm-4 + +As it is particularly useful to be able to work with these +in a shell script, and as the precise name is not important, +change all non-alphanumerics to '_'. + + MD_DEVICE_dm_4_ROLE=1 + MD_DEVICE_dm_4_DEV=/dev/dm-4 + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Detail.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/Detail.c b/Detail.c +index e40cd8f..91c5a98 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -25,6 +25,7 @@ + #include "mdadm.h" + #include "md_p.h" + #include "md_u.h" ++#include + #include + + static int cmpstringp(const void *p1, const void *p2) +@@ -276,17 +277,22 @@ int Detail(char *dev, struct context *c) + char *path = + map_dev(mdi->disk.major, + mdi->disk.minor, 0); ++ char *sysdev = xstrdup(mdi->sys_name + 1); ++ char *cp; ++ for (cp = sysdev; *cp; cp++) ++ if (!isalnum(*cp)) ++ *cp = '_'; + + if (mdi->disk.raid_disk >= 0) + printf("MD_DEVICE_%s_ROLE=%d\n", +- mdi->sys_name+4, ++ sysdev, + mdi->disk.raid_disk); + else + printf("MD_DEVICE_%s_ROLE=spare\n", +- mdi->sys_name+4); ++ sysdev); + if (path) + printf("MD_DEVICE_%s_DEV=%s\n", +- mdi->sys_name+4, path); ++ sysdev, path); + } + } + goto out; +-- +2.7.4 + diff --git a/SOURCES/Detail-handle-non-existent-arrays-better.patch b/SOURCES/Detail-handle-non-existent-arrays-better.patch new file mode 100644 index 0000000..d5be68d --- /dev/null +++ b/SOURCES/Detail-handle-non-existent-arrays-better.patch @@ -0,0 +1,45 @@ +From b4decd517d90098bc2d17d3eddfe858d8b903920 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 27 Mar 2017 14:36:56 +1100 +Subject: [RHEL7.5 PATCH 024/169] Detail: handle non-existent arrays + better. + +If you call "mdadm --detail" with a device file for an array which +doesn't exist, such as by + mknod /dev/md57 b 9 57 + mdadm --detail /dev/md57 + +you get an unhelpful message about and inactive RAID0, and return +status is '0'. This is confusing. + +So catch this possibility and print a more useful message, and +return a non-zero status. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Detail.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/Detail.c b/Detail.c +index cb33794..3d92855 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -110,6 +110,14 @@ int Detail(char *dev, struct context *c) + if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) { + inactive = 0; + } else if (errno == ENODEV && sra) { ++ if (sra->array.major_version == -1 && ++ sra->array.minor_version == -1 && ++ sra->devs == NULL) { ++ pr_err("Array associated with md device %s does not exist.\n", dev); ++ close(fd); ++ sysfs_free(sra); ++ return rv; ++ } + array = sra->array; + inactive = 1; + } else { +-- +2.7.4 + diff --git a/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch b/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch new file mode 100644 index 0000000..c1a3530 --- /dev/null +++ b/SOURCES/Don-t-abort-starting-the-array-if-kernel-does-not-su.patch @@ -0,0 +1,106 @@ +From 2c8890e926a4c7f9169b5054e3dbf84426fe1025 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Thu, 28 Sep 2017 14:41:07 +0200 +Subject: [PATCH 01/12] Don't abort starting the array if kernel does + not support ppl + +Change the behavior of assemble and create for consistency-policy=ppl +for external metadata arrays. If the kernel does not support ppl, don't +abort but print a warning and start the array without ppl +(consistency-policy=resync). No change for native md arrays because the +kernel will not allow starting the array if it finds an unsupported +feature bit in the superblock. + +In sysfs_add_disk() check consistency_policy in the mdinfo structure +that represents the array, not the disk and read the current consistency +policy from sysfs in mdmon's manage_member(). This is necessary to make +sysfs_add_disk() honor the actual consistency policy and not what is in +the metadata. Also remove all the places where consistency_policy is set +for a disk's mdinfo - it is a property of the array, not the disk. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + managemon.c | 11 ++++++++--- + super-intel.c | 4 +--- + sysfs.c | 6 +++--- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/managemon.c b/managemon.c +index 68f0c2d..cc3c6f1 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -477,7 +477,7 @@ static void manage_member(struct mdstat_ent *mdstat, + char buf[64]; + int frozen; + struct supertype *container = a->container; +- unsigned long long int component_size = 0; ++ struct mdinfo *mdi; + + if (container == NULL) + /* Raced with something */ +@@ -489,8 +489,13 @@ static void manage_member(struct mdstat_ent *mdstat, + // MORE + } + +- if (sysfs_get_ll(&a->info, NULL, "component_size", &component_size) >= 0) +- a->info.component_size = component_size << 1; ++ mdi = sysfs_read(-1, mdstat->devnm, ++ GET_COMPONENT|GET_CONSISTENCY_POLICY); ++ if (mdi) { ++ a->info.component_size = mdi->component_size; ++ a->info.consistency_policy = mdi->consistency_policy; ++ sysfs_free(mdi); ++ } + + /* honor 'frozen' */ + if (sysfs_get_str(&a->info, NULL, "metadata_version", buf, sizeof(buf)) > 0) +diff --git a/super-intel.c b/super-intel.c +index bbe7bc7..e3dcd3d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7669,7 +7669,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + } else { + info_d->component_size = blocks_per_member(map); + } +- info_d->consistency_policy = this->consistency_policy; + + info_d->bb.supported = 1; + get_volume_badblocks(super->bbm_log, ord_to_idx(ord), +@@ -8758,8 +8757,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a, + di->component_size = a->info.component_size; + di->container_member = inst; + di->bb.supported = 1; +- if (dev->rwh_policy == RWH_DISTRIBUTED) { +- di->consistency_policy = CONSISTENCY_POLICY_PPL; ++ if (a->info.consistency_policy == CONSISTENCY_POLICY_PPL) { + di->ppl_sector = get_ppl_sector(super, inst); + di->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9; + } +diff --git a/sysfs.c b/sysfs.c +index 68ddd5f..bf5c8c5 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -709,8 +709,8 @@ int sysfs_set_array(struct mdinfo *info, int vers) + if (sysfs_set_str(info, NULL, "consistency_policy", + map_num(consistency_policies, + info->consistency_policy))) { +- pr_err("This kernel does not support PPL\n"); +- return 1; ++ pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n"); ++ info->consistency_policy = CONSISTENCY_POLICY_RESYNC; + } + } + +@@ -745,7 +745,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 (sd->consistency_policy == CONSISTENCY_POLICY_PPL) { ++ 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.7.4 + diff --git a/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch b/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch new file mode 100644 index 0000000..aa02c1f --- /dev/null +++ b/SOURCES/Don-t-use-UnSet-with-consistency_policy.patch @@ -0,0 +1,122 @@ +From b75805662e7208799207a8e5f8a61f69a44888f0 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Mon, 24 Apr 2017 16:03:26 +0200 +Subject: [RHEL7.5 PATCH 094/169] Don't use UnSet with consistency_policy + +Use CONSISTENCY_POLICY_UNKNOWN instead. Simplify some checks because +since 5e8e35fb7e17 ("maps: Use keyvalue for null terminator to indicate +'unset' value") map_name() can return this default directly. + +Suggested-by: Jes Sorensen +Signed-off-by: Artur Paszkiewicz +--- + maps.c | 2 +- + mdadm.c | 12 ++++++------ + super-intel.c | 4 +--- + sysfs.c | 10 ++++------ + 4 files changed, 12 insertions(+), 16 deletions(-) + +diff --git a/maps.c b/maps.c +index bb28ba6..02a0474 100644 +--- a/maps.c ++++ b/maps.c +@@ -137,7 +137,7 @@ mapping_t consistency_policies[] = { + { "bitmap", CONSISTENCY_POLICY_BITMAP}, + { "journal", CONSISTENCY_POLICY_JOURNAL}, + { "ppl", CONSISTENCY_POLICY_PPL}, +- { NULL, UnSet } ++ { NULL, CONSISTENCY_POLICY_UNKNOWN } + }; + + mapping_t sysfs_array_states[] = { +diff --git a/mdadm.c b/mdadm.c +index 41dae1d..b689e32 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -78,7 +78,7 @@ int main(int argc, char *argv[]) + .level = UnSet, + .layout = UnSet, + .bitmap_chunk = UnSet, +- .consistency_policy = UnSet, ++ .consistency_policy = CONSISTENCY_POLICY_UNKNOWN, + }; + + char sys_hostname[256]; +@@ -1228,8 +1228,7 @@ int main(int argc, char *argv[]) + case O(GROW, 'k'): + s.consistency_policy = map_name(consistency_policies, + optarg); +- if (s.consistency_policy == UnSet || +- s.consistency_policy < CONSISTENCY_POLICY_RESYNC) { ++ if (s.consistency_policy < CONSISTENCY_POLICY_RESYNC) { + pr_err("Invalid consistency policy: %s\n", + optarg); + exit(2); +@@ -1267,7 +1266,7 @@ int main(int argc, char *argv[]) + pr_err("--write-journal is only supported for RAID level 4/5/6.\n"); + exit(2); + } +- if (s.consistency_policy != UnSet && ++ 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)); +@@ -1275,7 +1274,8 @@ int main(int argc, char *argv[]) + } + } + +- if (mode == CREATE && s.consistency_policy != UnSet) { ++ if (mode == CREATE && ++ 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)); +@@ -1687,7 +1687,7 @@ int main(int argc, char *argv[]) + rv = Grow_reshape(devlist->devname, mdfd, + devlist->next, + data_offset, &c, &s); +- } else if (s.consistency_policy != UnSet) { ++ } else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) { + rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s); + } else if (array_size == 0) + pr_err("no changes to --grow\n"); +diff --git a/super-intel.c b/super-intel.c +index 0aed57c..fbff215 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5369,9 +5369,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + } + mpb->num_raid_devs++; + +- if (s->consistency_policy == UnSet || +- s->consistency_policy == CONSISTENCY_POLICY_RESYNC || +- s->consistency_policy == CONSISTENCY_POLICY_NONE) { ++ if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) { + dev->rwh_policy = RWH_OFF; + } else if (s->consistency_policy == CONSISTENCY_POLICY_PPL) { + dev->rwh_policy = RWH_DISTRIBUTED; +diff --git a/sysfs.c b/sysfs.c +index 712f8b3..aa30de5 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -254,13 +254,11 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + + if (options & GET_CONSISTENCY_POLICY) { + strcpy(base, "consistency_policy"); +- if (load_sys(fname, buf, sizeof(buf))) { ++ if (load_sys(fname, buf, sizeof(buf))) + sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN; +- } else { +- sra->consistency_policy = map_name(consistency_policies, buf); +- if (sra->consistency_policy == UnSet) +- sra->consistency_policy = CONSISTENCY_POLICY_UNKNOWN; +- } ++ else ++ sra->consistency_policy = map_name(consistency_policies, ++ buf); + } + + if (! (options & GET_DEVS)) +-- +2.7.4 + diff --git a/SOURCES/Don-t-use-exit-ERANGE.patch b/SOURCES/Don-t-use-exit-ERANGE.patch new file mode 100644 index 0000000..12314cd --- /dev/null +++ b/SOURCES/Don-t-use-exit-ERANGE.patch @@ -0,0 +1,31 @@ +From dcd24efcfab50c3c298d9b1c941edb6954c2677e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 4 Aug 2017 15:30:02 +1000 +Subject: [RHEL7.5 PATCH 167/169] Don't use exit(ERANGE) + +mdadm uses smaller exit codes like 0,1,2,3,4. +Using ERANGE is inconsistent and not helpful. +So change it to a more consistent number. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdadm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.c b/mdadm.c +index 70b16f2..d80aab3 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -619,7 +619,7 @@ int main(int argc, char *argv[]) + c.homecluster = optarg; + if (strlen(c.homecluster) > 64) { + pr_err("Cluster name too big.\n"); +- exit(ERANGE); ++ exit(2); + } + continue; + case O(CREATE,'x'): /* number of spare (eXtra) disks */ +-- +2.7.4 + diff --git a/SOURCES/Error-messages-should-end-with-a-newline-character.patch b/SOURCES/Error-messages-should-end-with-a-newline-character.patch new file mode 100644 index 0000000..5729ef8 --- /dev/null +++ b/SOURCES/Error-messages-should-end-with-a-newline-character.patch @@ -0,0 +1,91 @@ +From 8e5b52cdda95965787e2a289c855a4ab7099f00d Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 4 Aug 2017 15:30:02 +1000 +Subject: [RHEL7.5 PATCH 164/169] Error messages should end with a newline + character. + +Add "\n" to the end of error messages which don't already +have one. Also spell "opened" correctly. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Build.c | 4 ++-- + Grow.c | 4 ++-- + Manage.c | 2 +- + mdopen.c | 2 +- + 4 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Build.c b/Build.c +index 70ba068..962c2e3 100644 +--- a/Build.c ++++ b/Build.c +@@ -181,7 +181,7 @@ int Build(char *mddev, struct mddev_dev *devlist, + int major = BITMAP_MAJOR_HI; + #if 0 + if (s->bitmap_chunk == UnSet) { +- pr_err("%s cannot be openned.", s->bitmap_file); ++ pr_err("%s cannot be opened.\n", s->bitmap_file); + goto abort; + } + #endif +@@ -193,7 +193,7 @@ int Build(char *mddev, struct mddev_dev *devlist, + } + bitmap_fd = open(s->bitmap_file, O_RDWR); + if (bitmap_fd < 0) { +- pr_err("%s cannot be openned.", s->bitmap_file); ++ pr_err("%s cannot be opened.\n", s->bitmap_file); + goto abort; + } + } +diff --git a/Grow.c b/Grow.c +index b1cb306..534ba80 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3202,7 +3202,7 @@ static int reshape_array(char *container, int fd, char *devname, + + if (info2) { + if (sysfs_init(info2, fd, st->devnm)) { +- pr_err("unable to initialize sysfs for %s", ++ pr_err("unable to initialize sysfs for %s\n", + st->devnm); + free(info2); + goto release; +@@ -5146,7 +5146,7 @@ int Grow_continue_command(char *devname, int fd, + } + + if (sysfs_init(content, fd2, mdstat->devnm)) { +- pr_err("Unable to initialize sysfs for %s, Grow cannot continue", ++ pr_err("Unable to initialize sysfs for %s, Grow cannot continue.\n", + mdstat->devnm); + ret_val = 1; + close(fd2); +diff --git a/Manage.c b/Manage.c +index b82a729..871d342 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1417,7 +1417,7 @@ int Manage_subdevs(char *devname, int fd, + } + add_devlist = conf_get_devs(); + if (add_devlist == NULL) { +- pr_err("no devices to scan for missing members."); ++ pr_err("no devices to scan for missing members.\n"); + continue; + } + for (dp = &add_devlist; *dp; dp = & (*dp)->next) +diff --git a/mdopen.c b/mdopen.c +index c4f1c12..3c0052f 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -198,7 +198,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + return -1; + } + if (cname[0] == 0) { +- pr_err("%s is an invalid name for an md device (empty!).", dev); ++ pr_err("%s is an invalid name for an md device (empty!).\n", dev); + return -1; + } + if (num < 0) { +-- +2.7.4 + diff --git a/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch b/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch new file mode 100644 index 0000000..8f3f175 --- /dev/null +++ b/SOURCES/Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch @@ -0,0 +1,44 @@ +From bb6f40bf9c458a13b1a780006733c034105e6d36 Mon Sep 17 00:00:00 2001 +From: Wol +Date: Tue, 17 Jan 2017 17:47:05 +0000 +Subject: [RHEL7.5 PATCH 003/169] Fix oddity where mdadm did not recognise + a relative path + +mdadm assumed that a pathname started with a "/", while an array +name didn't. This alters the logic so that if the first character +is not a "/" it tries to open an array, and if that fails it drops +through to the pathname code rather than terminating immediately +with an error. + +Signed-off-by: Wol +Signed-off-by: Jes Sorensen +--- + mdadm.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index c3a265b..b5d89e4 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1899,12 +1899,12 @@ static int misc_list(struct mddev_dev *devlist, + rv |= SetAction(dv->devname, c->action); + continue; + } +- if (dv->devname[0] == '/') +- mdfd = open_mddev(dv->devname, 1); +- else { +- mdfd = open_dev(dv->devname); +- if (mdfd < 0) +- pr_err("Cannot open %s\n", dv->devname); ++ switch(dv->devname[0] == '/') { ++ case 0: ++ mdfd = open_dev(dv->devname); ++ if (mdfd >= 0) break; ++ case 1: ++ mdfd = open_mddev(dv->devname, 1); + } + if (mdfd>=0) { + switch(dv->disposition) { +-- +2.7.4 + diff --git a/SOURCES/Fix-typo2-in-new-udev-rule.patch b/SOURCES/Fix-typo2-in-new-udev-rule.patch new file mode 100644 index 0000000..61198ba --- /dev/null +++ b/SOURCES/Fix-typo2-in-new-udev-rule.patch @@ -0,0 +1,45 @@ +From dd180cb136d6b2193a58ea0de23b8a7942ca6f36 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 5 May 2017 15:16:15 +1000 +Subject: [RHEL7.5 PATCH 111/169] Fix typo in new udev rule. + +As pointed out by Peter Rajnoha, the correct usage in udev is +TEST=="file", not TEST="file". + +Also improve a related comment which was a bit informal. + +Reported-by: Peter Rajnoha +Fixes: cd6cbb08c458 ("Create: tell udev md device is not ready when first created.") +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + lib.c | 2 +- + udev-md-raid-creating.rules | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib.c b/lib.c +index 7e44b1f..be093e8 100644 +--- a/lib.c ++++ b/lib.c +@@ -165,7 +165,7 @@ char *fd2devnm(int fd) + + /* 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-FOO and expect that a udev ++ * 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"; +diff --git a/udev-md-raid-creating.rules b/udev-md-raid-creating.rules +index 2be466b..9bef8d1 100644 +--- a/udev-md-raid-creating.rules ++++ b/udev-md-raid-creating.rules +@@ -4,4 +4,4 @@ + # the array is not "ready" and we should make sure the + # content is ignored. + +-KERNEL=="md*", TEST="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0" ++KERNEL=="md*", TEST=="/run/mdadm/creating-$kernel", ENV{SYSTEMD_READY}="0" +-- +2.7.4 + diff --git a/SOURCES/Get-failed-disk-count-fromarray-state.patch b/SOURCES/Get-failed-disk-count-fromarray-state.patch new file mode 100644 index 0000000..54fb057 --- /dev/null +++ b/SOURCES/Get-failed-disk-count-fromarray-state.patch @@ -0,0 +1,163 @@ +From b13b52c80f3d9e3184ea1d6d39aa7053ef7bae49 Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Wed, 31 May 2017 12:46:57 +0200 +Subject: [RHEL7.5 PATCH 151/169] Get failed disk count from array state + +Recent commit has changed the way failed disks are counted. It breaks +recovery for external metadata arrays as failed disks are not part of +the array and have no corresponding entries is sysfs (they are only +reported for containers) so degraded arrays show no failed disks. + +Recent commit overwrites GET_DEGRADED result prior to GET_STATE and it +is not set again if GET_STATE has not been requested. As GET_STATE +provides the same information as GET_DEGRADED, the latter is not needed +anymore. Remove GET_DEGRADED option and replace it with GET_STATE +option. + +Don't count number of failed disks looking at sysfs entries but +calculate it at the end. Do it only for arrays as containers report +no disks, just spares. + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + Incremental.c | 14 ++++---------- + Monitor.c | 4 ++-- + managemon.c | 4 ++-- + mdadm.h | 1 - + raid6check.c | 2 +- + sysfs.c | 18 ++++++++---------- + 6 files changed, 17 insertions(+), 26 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 30dc7a2..6cf2174 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -886,16 +886,10 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + } + sra = sysfs_read(-1, mp->devnm, + GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE| +- GET_DEGRADED|GET_COMPONENT|GET_VERSION); +- if (!sra) { +- /* Probably a container - no degraded info */ +- sra = sysfs_read(-1, mp->devnm, +- GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE| +- GET_COMPONENT|GET_VERSION); +- if (sra) +- sra->array.failed_disks = -1; +- } +- if (!sra) ++ GET_COMPONENT|GET_VERSION); ++ if (sra) ++ sra->array.failed_disks = -1; ++ else + continue; + if (st == NULL) { + int i; +diff --git a/Monitor.c b/Monitor.c +index 725f47d..bef2f1b 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -485,8 +485,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->devnm[0] == 0) + strcpy(st->devnm, fd2devnm(fd)); + +- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED | +- GET_MISMATCH | GET_DEVS | GET_STATE); ++ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH | ++ GET_DEVS | GET_STATE); + if (!sra) + goto disappeared; + +diff --git a/managemon.c b/managemon.c +index a8df666..68f0c2d 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -685,8 +685,8 @@ static void manage_new(struct mdstat_ent *mdstat, + + mdi = sysfs_read(-1, mdstat->devnm, + GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT| +- GET_DEGRADED|GET_SAFEMODE| +- GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|GET_LAYOUT); ++ GET_SAFEMODE|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE| ++ GET_LAYOUT); + + if (!mdi) + return; +diff --git a/mdadm.h b/mdadm.h +index ec0a39e..ee9b837 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -637,7 +637,6 @@ enum sysfs_read_flags { + GET_MISMATCH = (1 << 5), + GET_VERSION = (1 << 6), + GET_DISKS = (1 << 7), +- GET_DEGRADED = (1 << 8), + GET_SAFEMODE = (1 << 9), + GET_BITMAP_LOCATION = (1 << 10), + +diff --git a/raid6check.c b/raid6check.c +index 551f835..a8e6005 100644 +--- a/raid6check.c ++++ b/raid6check.c +@@ -562,7 +562,7 @@ int main(int argc, char *argv[]) + GET_LEVEL| + GET_LAYOUT| + GET_DISKS| +- GET_DEGRADED | ++ GET_STATE | + GET_COMPONENT| + GET_CHUNK| + GET_DEVS| +diff --git a/sysfs.c b/sysfs.c +index e47f5e4..78d2b52 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -162,18 +162,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + goto abort; + sra->array.layout = strtoul(buf, NULL, 0); + } +- if (options & GET_DISKS) { ++ if (options & (GET_DISKS|GET_STATE)) { + strcpy(base, "raid_disks"); + if (load_sys(fname, buf, sizeof(buf))) + goto abort; + sra->array.raid_disks = strtoul(buf, NULL, 0); + } +- if (options & GET_DEGRADED) { +- strcpy(base, "degraded"); +- if (load_sys(fname, buf, sizeof(buf))) +- goto abort; +- sra->array.failed_disks = strtoul(buf, NULL, 0); +- } + if (options & GET_COMPONENT) { + strcpy(base, "component_size"); + if (load_sys(fname, buf, sizeof(buf))) +@@ -359,10 +353,9 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + strcpy(dbase, "state"); + if (load_sys(fname, buf, sizeof(buf))) + goto abort; +- if (strstr(buf, "faulty")) { ++ if (strstr(buf, "faulty")) + dev->disk.state |= (1<array.failed_disks++; +- } else { ++ else { + sra->array.working_disks++; + if (strstr(buf, "in_sync")) { + dev->disk.state |= (1<errors = strtoul(buf, NULL, 0); + } + } ++ ++ if ((options & GET_STATE) && sra->array.raid_disks) ++ sra->array.failed_disks = sra->array.raid_disks - ++ sra->array.active_disks - sra->array.spare_disks; ++ + closedir(dir); + return sra; + +-- +2.7.4 + diff --git a/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch b/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch new file mode 100644 index 0000000..70c76f9 --- /dev/null +++ b/SOURCES/Grow-Do-not-shadow-an-existing-variable.patch @@ -0,0 +1,41 @@ +From 49948a3561dcd48a94b1c5e98a6d23c9263d1ca3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 30 Mar 2017 10:46:01 -0400 +Subject: [RHEL7.5 PATCH 043/169] Grow: Do not shadow an existing variable + +Declaring 'int rv' twice within the same function is asking for +trouble. + +Signed-off-by: Jes Sorensen +--- + Grow.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 0d551ce..0c16d5b 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -1834,7 +1834,7 @@ int Grow_reshape(char *devname, int fd, + * pre-requisite spare devices (mdmon owns final validation) + */ + if (st->ss->external) { +- int rv; ++ int retval; + + if (subarray) { + container = st->container_devnm; +@@ -1852,9 +1852,9 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- rv = st->ss->load_container(st, cfd, NULL); ++ retval = st->ss->load_container(st, cfd, NULL); + +- if (rv) { ++ if (retval) { + pr_err("Cannot read superblock for %s\n", + devname); + free(subarray); +-- +2.7.4 + diff --git a/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch b/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch new file mode 100644 index 0000000..87008f6 --- /dev/null +++ b/SOURCES/Grow-Fixup-a-pile-of-cosmetic-issues.patch @@ -0,0 +1,176 @@ +From 6ebf34e6bdd9e952d00ad3c2f12a130bfb68965e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 12:15:20 -0400 +Subject: [RHEL7.5 PATCH 036/169] Grow: Fixup a pile of cosmetic issues + +No code change, simply cleanup ugliness. + +Signed-off-by: Jes Sorensen +--- + Grow.c | 60 ++++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 32 insertions(+), 28 deletions(-) + +diff --git a/Grow.c b/Grow.c +index b86b53e..6405f0e 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -1269,8 +1269,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + * raid5 with 2 disks, or + * raid0 with 1 disk + */ +- if (info->new_level > 1 && +- (info->component_size & 7)) ++ if (info->new_level > 1 && (info->component_size & 7)) + return "Cannot convert RAID1 of this size - reduce size to multiple of 4K first."; + if (info->new_level == 0) { + if (info->delta_disks != UnSet && +@@ -1288,12 +1287,9 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + re->level = 1; + return NULL; + } +- if (info->array.raid_disks != 2 && +- info->new_level == 5) ++ if (info->array.raid_disks != 2 && info->new_level == 5) + return "Can only convert a 2-device array to RAID5"; +- if (info->array.raid_disks == 2 && +- info->new_level == 5) { +- ++ if (info->array.raid_disks == 2 && info->new_level == 5) { + re->level = 5; + re->before.data_disks = 1; + if (info->delta_disks != UnSet && +@@ -1404,7 +1400,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + case 0: + /* RAID0 can be converted to RAID10, or to RAID456 */ + if (info->new_level == 10) { +- if (info->new_layout == UnSet && info->delta_disks == UnSet) { ++ if (info->new_layout == UnSet && ++ info->delta_disks == UnSet) { + /* Assume near=2 layout */ + info->new_layout = 0x102; + info->delta_disks = info->array.raid_disks; +@@ -1643,16 +1640,19 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + if (info->delta_disks == UnSet) + info->delta_disks = delta_parity; + +- re->after.data_disks = (re->before.data_disks +- + info->delta_disks +- - delta_parity); ++ re->after.data_disks = ++ (re->before.data_disks + info->delta_disks - delta_parity); ++ + switch (re->level) { +- case 6: re->parity = 2; ++ case 6: ++ re->parity = 2; + break; + case 4: +- case 5: re->parity = 1; ++ case 5: ++ re->parity = 1; + break; +- default: re->parity = 0; ++ default: ++ re->parity = 0; + break; + } + /* So we have a restripe operation, we need to calculate the number +@@ -1706,7 +1706,7 @@ static int set_array_size(struct supertype *st, struct mdinfo *sra, + + if (text_version == NULL) + text_version = sra->text_version; +- subarray = strchr(text_version+1, '/')+1; ++ subarray = strchr(text_version + 1, '/')+1; + info = st->ss->container_content(st, subarray); + if (info) { + unsigned long long current_size = 0; +@@ -1789,8 +1789,8 @@ int Grow_reshape(char *devname, int fd, + devname); + return 1; + } +- if (data_offset != INVALID_SECTORS && array.level != 10 +- && (array.level < 4 || array.level > 6)) { ++ if (data_offset != INVALID_SECTORS && array.level != 10 && ++ (array.level < 4 || array.level > 6)) { + pr_err("--grow --data-offset not yet supported\n"); + return 1; + } +@@ -1802,8 +1802,8 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- if (s->raiddisks && s->raiddisks < array.raid_disks && array.level > 1 && +- get_linux_version() < 2006032 && ++ 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"); +@@ -1873,10 +1873,11 @@ int Grow_reshape(char *devname, int fd, + /* check if reshape is allowed based on metadata + * indications stored in content.array.status + */ +- if (content->array.state & (1<array.state & ++ (1 << MD_SB_BLOCK_VOLUME)) + allow_reshape = 0; +- if (content->array.state +- & (1<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", +@@ -1896,7 +1897,7 @@ int Grow_reshape(char *devname, int fd, + for (dv = devlist; dv; dv = dv->next) + added_disks++; + if (s->raiddisks > array.raid_disks && +- array.spare_disks +added_disks < (s->raiddisks - array.raid_disks) && ++ array.spare_disks + added_disks < (s->raiddisks - array.raid_disks) && + !c->force) { + pr_err("Need %d spare%s to avoid degraded array, and only have %d.\n" + " Use --force to over-ride this check.\n", +@@ -1906,8 +1907,8 @@ int Grow_reshape(char *devname, int fd, + return 1; + } + +- sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS +- | GET_STATE | GET_VERSION); ++ sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS | ++ GET_STATE | GET_VERSION); + if (sra) { + if (st->ss->external && subarray == NULL) { + array.level = LEVEL_CONTAINER; +@@ -1930,7 +1931,8 @@ int Grow_reshape(char *devname, int fd, + } + + /* ========= set size =============== */ +- if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { ++ if (s->size > 0 && ++ (s->size == MAX_SIZE || s->size != (unsigned)array.size)) { + unsigned long long orig_size = get_component_size(fd)/2; + unsigned long long min_csize; + struct mdinfo *mdi; +@@ -1946,7 +1948,8 @@ int Grow_reshape(char *devname, int fd, + } + + if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL, +- devname, APPLY_METADATA_CHANGES, c->verbose > 0)) { ++ devname, APPLY_METADATA_CHANGES, ++ c->verbose > 0)) { + rv = 1; + goto release; + } +@@ -1965,7 +1968,8 @@ int Grow_reshape(char *devname, int fd, + sizeinfo->array.layout, + sizeinfo->array.raid_disks); + new_size /= data_disks; +- dprintf("Metadata size correction from %llu to %llu (%llu)\n", orig_size, new_size, ++ dprintf("Metadata size correction from %llu to %llu (%llu)\n", ++ orig_size, new_size, + new_size * data_disks); + s->size = new_size; + sysfs_free(sizeinfo); +-- +2.7.4 + diff --git a/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch b/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch new file mode 100644 index 0000000..44c25bb --- /dev/null +++ b/SOURCES/Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch @@ -0,0 +1,41 @@ +From 9e4524df1c6c85c362278a08fd4425888d27581f Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 2 May 2017 11:46:49 -0400 +Subject: [RHEL7.5 PATCH 104/169] Grow: Grow_continue_command: Avoid + aliasing array variable + +While this would cause a warning since the two are different types, +lets avoid aliasing an existing variable. + +Signed-off-by: Jes Sorensen +--- + Grow.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Grow.c b/Grow.c +index c6967ed..f4bd301 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -5075,7 +5075,7 @@ int Grow_continue_command(char *devname, int fd, + + cc = st->ss->container_content(st, subarray); + for (content = cc; content ; content = content->next) { +- char *array; ++ char *array_name; + int allow_reshape = 1; + + if (content->reshape_active == 0) +@@ -5100,8 +5100,8 @@ int Grow_continue_command(char *devname, int fd, + goto Grow_continue_command_exit; + } + +- array = strchr(content->text_version+1, '/')+1; +- mdstat = mdstat_by_subdev(array, container); ++ array_name = strchr(content->text_version+1, '/')+1; ++ mdstat = mdstat_by_subdev(array_name, container); + if (!mdstat) + continue; + if (mdstat->active == 0) { +-- +2.7.4 + diff --git a/SOURCES/Grow-Remove-unnecessary-optimization.patch b/SOURCES/Grow-Remove-unnecessary-optimization.patch new file mode 100644 index 0000000..ad0b3cc --- /dev/null +++ b/SOURCES/Grow-Remove-unnecessary-optimization.patch @@ -0,0 +1,51 @@ +From 758b327cf5a7aab50ae5c70ecbc371dc4f715bb6 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 30 Mar 2017 10:39:29 -0400 +Subject: [RHEL7.5 PATCH 042/169] Grow: Remove unnecessary optimization + +Per explanation by Neil, this optimization of writing "size" to the +attribute of each device, however when reducing the size of devices, +the size change isn't permitted until the array has been shrunk, so +this will fail anyway. + +This effectively reverts 65a9798b58b4e4de0157043e2b30a738c27eff43 + +Signed-off-by: Jes Sorensen +--- + Grow.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/Grow.c b/Grow.c +index af8d520..0d551ce 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -1982,15 +1982,7 @@ int Grow_reshape(char *devname, int fd, + * understands '0' to mean 'max'. + */ + min_csize = 0; +- rv = 0; + for (mdi = sra->devs; mdi; mdi = mdi->next) { +- if (sysfs_set_num(sra, mdi, "size", +- s->size == MAX_SIZE ? 0 : s->size) < 0) { +- /* Probably kernel refusing to let us +- * reduce the size - not an error. +- */ +- break; +- } + if (array.not_persistent == 0 && + array.major_version == 0 && + get_linux_version() < 3001000) { +@@ -2005,10 +1997,6 @@ int Grow_reshape(char *devname, int fd, + } + } + } +- if (rv) { +- pr_err("Cannot set size on array members.\n"); +- goto size_change_error; +- } + if (min_csize && s->size > min_csize) { + pr_err("Cannot safely make this array use more than 2TB per device on this kernel.\n"); + rv = 1; +-- +2.7.4 + diff --git a/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch b/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch new file mode 100644 index 0000000..dc90a94 --- /dev/null +++ b/SOURCES/Grow-Stop-bothering-about-md-driver-versions-older-t.patch @@ -0,0 +1,35 @@ +From 6ae8b2b3140475b1a70485052454210aba4065a6 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:22:36 -0400 +Subject: [RHEL7.5 PATCH 056/169] Grow: Stop bothering about md driver + versions older than 0.90.00 + +Signed-off-by: Jes Sorensen +--- + Grow.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 78a3474..15f4ed1 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -288,16 +288,9 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + struct supertype *st; + char *subarray = NULL; + int major = BITMAP_MAJOR_HI; +- int vers = md_get_version(fd); + unsigned long long bitmapsize, array_size; + struct mdinfo *mdi; + +- if (vers < 9003) { +- major = BITMAP_MAJOR_HOSTENDIAN; +- pr_err("Warning - bitmaps created on this kernel are not portable\n" +- " between different architectures. Consider upgrading the Linux kernel.\n"); +- } +- + /* + * We only ever get called if s->bitmap_file is != NULL, so this check + * is just here to quiet down static code checkers. +-- +2.7.4 + diff --git a/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch b/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch new file mode 100644 index 0000000..4249916 --- /dev/null +++ b/SOURCES/Grow-fix-switching-on-PPL-during-recovery.patch @@ -0,0 +1,34 @@ +From 41b25549f080ebac1269689f942f722368ed28b1 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:13 +0200 +Subject: [PATCH 07/12] Grow: fix switching on PPL during recovery + +If raid memeber is not in sync - it is skipped during +enablement of PPL. This is not correct, since the drive that +we are currently recovering to does not have ppl_size and ppl_sector +properly set in sysfs. +Remove this skipping, so all drives are updated during turning on the PPL. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + Grow.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/Grow.c b/Grow.c +index bab1eec..1149753 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -637,9 +637,6 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha + int dfd; + char *devpath; + +- if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0) +- continue; +- + devpath = map_dev(sd->disk.major, sd->disk.minor, 0); + dfd = dev_open(devpath, O_RDWR); + if (dfd < 0) { +-- +2.7.4 + diff --git a/SOURCES/Grow-set-component-size-prior-to-array-size.patch b/SOURCES/Grow-set-component-size-prior-to-array-size.patch new file mode 100644 index 0000000..ce27272 --- /dev/null +++ b/SOURCES/Grow-set-component-size-prior-to-array-size.patch @@ -0,0 +1,34 @@ +From 07c45a1871df0a70beb8da80d11601d33c7a5de2 Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Mon, 5 Jun 2017 16:09:44 +0200 +Subject: [RHEL7.5 PATCH 150/169] Grow: set component size prior to array + size + +It is a partial revert of commit 758b327cf5a7 ("Grow: Remove unnecessary +optimization"). For native metadata component size is set in kernel for +entire disk space. As external metadata supports multiple arrays within +one disk, the component size is set to array size. If component size is +not updated prior to array size update, the grow operation fails. + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + Grow.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Grow.c b/Grow.c +index ecf5ca0..4ecb1d8 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1977,6 +1977,8 @@ int Grow_reshape(char *devname, int fd, + */ + min_csize = 0; + for (mdi = sra->devs; mdi; mdi = mdi->next) { ++ sysfs_set_num(sra, mdi, "size", s->size == MAX_SIZE ? 0 ++ : s->size); + if (array.not_persistent == 0 && + array.major_version == 0 && + get_linux_version() < 3001000) { +-- +2.7.4 + diff --git a/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch b/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch new file mode 100644 index 0000000..f103451 --- /dev/null +++ b/SOURCES/Grow_continue_command-ensure-content-is-properly-ini.patch @@ -0,0 +1,36 @@ +From a250ce240f245df594570a5e25398680d403af67 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 20 Apr 2017 12:40:05 +1000 +Subject: [RHEL7.5 PATCH 087/169] Grow_continue_command: ensure 'content' + is properly initialised. + +Grow_continue_command() call verify_reshape_position(), which assumes +that info->sys_name is initialised. +'info' in verify_reshape_position() is 'content' in Grow_continue_command(). + +In the st->ss->external != 0 branch of that function, sysfs_init() is called +to initialize content->sys_name. +In the st->ss->external == 0 branch, ->sys_name is not initialized so +verify_reshape_position() will not do the right thing. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Grow.c b/Grow.c +index 15f4ed1..c6967ed 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -5002,6 +5002,7 @@ int Grow_continue_command(char *devname, int fd, + goto Grow_continue_command_exit; + } + content = &array; ++ sysfs_init(content, fd, NULL); + /* Need to load a superblock. + * FIXME we should really get what we need from + * sysfs +-- +2.7.4 + diff --git a/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch b/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch new file mode 100644 index 0000000..f2ba47d --- /dev/null +++ b/SOURCES/IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch @@ -0,0 +1,47 @@ +From 2a24dc1b0988a7d924de6339754d4160762a61f7 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Wed, 26 Apr 2017 11:08:07 +0200 +Subject: [RHEL7.5 PATCH 103/169] IMSM: Initialize my_vol_raid_dev_num + during vol creation + +This field was not initialized so far. This ID needs to be unique +for every newly created array in container. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index fbff215..36f77d3 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -232,8 +232,13 @@ struct imsm_super { + __u32 orig_family_num; /* 0x40 - 0x43 original family num */ + __u32 pwr_cycle_count; /* 0x44 - 0x47 simulated power cycle count for array */ + __u32 bbm_log_size; /* 0x48 - 0x4B - size of bad Block Mgmt Log in bytes */ +-#define IMSM_FILLERS 35 +- __u32 filler[IMSM_FILLERS]; /* 0x4C - 0xD7 RAID_MPB_FILLERS */ ++ __u16 num_raid_devs_created; /* 0x4C - 0x4D Used for generating unique ++ * volume IDs for raid_dev created in this array ++ * (starts at 1) ++ */ ++ __u16 filler1; /* 0x4E - 0x4F */ ++#define IMSM_FILLERS 34 ++ __u32 filler[IMSM_FILLERS]; /* 0x50 - 0xD7 RAID_MPB_FILLERS */ + struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */ + /* here comes imsm_dev[num_raid_devs] */ + /* here comes BBM logs */ +@@ -5368,6 +5373,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD); + } + mpb->num_raid_devs++; ++ mpb->num_raid_devs_created++; ++ dev->my_vol_raid_dev_num = mpb->num_raid_devs_created; + + if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) { + dev->rwh_policy = RWH_OFF; +-- +2.7.4 + diff --git a/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch b/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch new file mode 100644 index 0000000..931e32e --- /dev/null +++ b/SOURCES/Incremental-Cleanup-some-if-statement-spaghetti.patch @@ -0,0 +1,152 @@ +From f8c432bfc9929dbbcb659b2d11552dc9fc76ad24 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 25 Apr 2017 15:01:43 -0400 +Subject: [RHEL7.5 PATCH 099/169] Incremental: Cleanup some if() statement + spaghetti + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 50 +++++++++++++++++++++----------------------------- + 1 file changed, 21 insertions(+), 29 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index a351151..66c5b03 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -225,8 +225,8 @@ 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 && ++ strcasecmp(match->devname, "") == 0) { + if (c->verbose >= 0) + pr_err("array containing %s is explicitly ignored by mdadm.conf\n", + devname); +@@ -267,8 +267,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 && info.array.level == LEVEL_CONTAINER) { + name_to_use = info.text_version; + trustworthy = METADATA; + } +@@ -398,11 +397,10 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + * flag has a different meaning. The test has to happen + * at the device level there + */ +- if (!st->ss->external +- && (info.disk.state & (1<ss->name, +- act_re_add) +- && c->runstop < 1) { ++ if (!st->ss->external && ++ (info.disk.state & (1 << MD_DISK_SYNC)) != 0 && ++ !policy_action_allows(policy, st->ss->name, act_re_add) && ++ c->runstop < 1) { + if (md_array_active(mdfd)) { + pr_err("not adding %s to active array (without --run) %s\n", + devname, chosen_name); +@@ -537,8 +535,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + info.array.state |= 1; + + if (enough(info.array.level, info.array.raid_disks, +- info.array.layout, info.array.state & 1, +- avail) == 0) { ++ info.array.layout, info.array.state & 1, avail) == 0) { + if (c->export) { + printf("MD_STARTED=no\n"); + } else if (c->verbose >= 0) +@@ -599,8 +596,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + if (d->disk.state & (1<= info.array.working_disks) +- && trustworthy != FOREIGN) ++ if ((sra == NULL || active_disks >= info.array.working_disks) && ++ trustworthy != FOREIGN) + rv = ioctl(mdfd, RUN_ARRAY, NULL); + else + rv = sysfs_set_str(sra, NULL, +@@ -624,7 +621,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + * those devices we should re-add them now. + */ + for (dsk = sra->devs; dsk ; dsk = dsk->next) { +- if (disk_action_allows(dsk, st->ss->name, act_re_add) && ++ if (disk_action_allows(dsk, st->ss->name, ++ act_re_add) && + add_disk(mdfd, st, sra, dsk) == 0) + pr_err("%s re-added to %s\n", + dsk->sys_name, chosen_name); +@@ -688,8 +686,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra, + st->ss->free_super(st); + close(dfd); + +- if (info.disk.number != number || +- info.events >= events) ++ if (info.disk.number != number || info.events >= events) + continue; + + if (d->disk.raid_disk > -1) +@@ -970,11 +967,9 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + } + if ((sra->component_size > 0 && + st2->ss->avail_size(st2, devsize, +- sra->devs +- ? sra->devs->data_offset +- : INVALID_SECTORS) +- < sra->component_size) +- || ++ sra->devs ? sra->devs->data_offset : ++ INVALID_SECTORS) < ++ sra->component_size) || + (sra->component_size == 0 && devsize < component_size)) { + if (verbose > 1) + pr_err("not adding %s to %s as it is too small\n", +@@ -1107,8 +1102,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + char *devname = NULL; + unsigned long long devsectors; + +- if (de->d_ino == 0 || +- de->d_name[0] == '.' || ++ if (de->d_ino == 0 || de->d_name[0] == '.' || + (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN)) + goto next; + +@@ -1146,8 +1140,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + st2 = dup_super(st); + else + st2 = guess_super_type(fd, guess_partitions); +- if (st2 == NULL || +- st2->ss->load_super(st2, fd, NULL) < 0) ++ if (st2 == NULL || st2->ss->load_super(st2, fd, NULL) < 0) + goto next; + st2->ignore_hw_compat = 0; + +@@ -1175,8 +1168,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + * metadata which makes better use of the device can + * be found. + */ +- if (chosen == NULL || +- chosen_size < info.component_size) { ++ if (chosen == NULL || chosen_size < info.component_size) { + chosen_size = info.component_size; + free(chosen); + chosen = devname; +@@ -1399,8 +1391,8 @@ restart: + } + /* Ok, we can try this one. Maybe it needs a bitmap */ + for (mddev = devs ; mddev ; mddev = mddev->next) +- if (mddev->devname && me->path +- && devname_matches(mddev->devname, me->path)) ++ if (mddev->devname && me->path && ++ devname_matches(mddev->devname, me->path)) + break; + if (mddev && mddev->bitmap_file) { + /* +-- +2.7.4 + diff --git a/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch b/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch new file mode 100644 index 0000000..8de191e --- /dev/null +++ b/SOURCES/Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch @@ -0,0 +1,54 @@ +From 5b13d2e1fb8abecddd4e28e67facac5d7ef2cef3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 14:40:36 -0400 +Subject: [RHEL7.5 PATCH 038/169] Incremental: Remove redundant call for + GET_ARRAY_INFO + +The code above just called md_get_array_info() and only reached this +point if it returned an error that isn't ENODEV, so it's pointless to +check this again here. + +In addition it was incorrectly retrieving ioctl data into a +mdu_bitmap_file_t instead of mdu_array_info_t. + +Fixes: ("8382f19 Add new mode: --incremental") +Signed-off-by: Jes Sorensen +--- + Incremental.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 1f12c77..802e525 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1345,7 +1345,6 @@ int IncrementalScan(struct context *c, char *devnm) + restart: + for (me = mapl ; me ; me = me->next) { + mdu_array_info_t array; +- mdu_bitmap_file_t bmf; + struct mdinfo *sra; + int mdfd; + +@@ -1405,13 +1404,12 @@ restart: + * is a hint only + */ + int added = -1; +- if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) { +- int bmfd = open(mddev->bitmap_file, O_RDWR); +- if (bmfd >= 0) { +- added = ioctl(mdfd, SET_BITMAP_FILE, +- bmfd); +- close(bmfd); +- } ++ int bmfd; ++ ++ bmfd = open(mddev->bitmap_file, O_RDWR); ++ if (bmfd >= 0) { ++ added = ioctl(mdfd, SET_BITMAP_FILE, bmfd); ++ close(bmfd); + } + if (c->verbose >= 0) { + if (added == 0) +-- +2.7.4 + diff --git a/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch b/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch new file mode 100644 index 0000000..e23e883 --- /dev/null +++ b/SOURCES/Incremental-Use-md_array_active-to-determine3-state-o.patch @@ -0,0 +1,37 @@ +From 6921010d95dbc32c812aa8ffdbfa28e78b54b342 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 2 May 2017 10:36:51 -0400 +Subject: [RHEL7.5 PATCH 101/169] Incremental: Use md_array_active() to + determine state of array + +One less call to md_get_array_info() + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 4789e36..8909f2f 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -99,7 +99,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + int active_disks; + int trustworthy; + char *name_to_use; +- mdu_array_info_t ainf; + struct dev_policy *policy = NULL; + struct map_ent target_array; + int have_target; +@@ -551,7 +550,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + /* + add any bitmap file */ + /* + start the array (auto-readonly). */ + +- if (md_get_array_info(mdfd, &ainf) == 0) { ++ if (md_array_active(mdfd)) { + if (c->export) { + printf("MD_STARTED=already\n"); + } else if (c->verbose >= 0) +-- +2.7.4 + diff --git a/SOURCES/Incremental-Use-md_array_active-where-applicable.patch b/SOURCES/Incremental-Use-md_array_active-where-applicable.patch new file mode 100644 index 0000000..96e43ae --- /dev/null +++ b/SOURCES/Incremental-Use-md_array_active-where-applicable.patch @@ -0,0 +1,41 @@ +From ff4ad24b1c261ab4d286cbe54157d7c588191692 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 25 Apr 2017 14:57:46 -0400 +Subject: [RHEL7.5 PATCH 098/169] Incremental: Use md_array_active() where + applicable + +md_get_array_info() == 0 implies an array is active, however this is more +correct. + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 28f1f77..a351151 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -403,7 +403,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + && ! policy_action_allows(policy, st->ss->name, + act_re_add) + && c->runstop < 1) { +- if (md_get_array_info(mdfd, &ainf) == 0) { ++ if (md_array_active(mdfd)) { + pr_err("not adding %s to active array (without --run) %s\n", + devname, chosen_name); + rv = 2; +@@ -667,9 +667,8 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra, + * and events less than the passed events, and remove the device. + */ + struct mdinfo *d; +- mdu_array_info_t ra; + +- if (md_get_array_info(mdfd, &ra) == 0) ++ if (md_array_active(mdfd)) + return; /* not safe to remove from active arrays + * without thinking more */ + +-- +2.7.4 + diff --git a/SOURCES/Incremental-returnis-not-a-function.patch b/SOURCES/Incremental-returnis-not-a-function.patch new file mode 100644 index 0000000..310431e --- /dev/null +++ b/SOURCES/Incremental-returnis-not-a-function.patch @@ -0,0 +1,26 @@ +From c2d1a6ec6b94385e64e721b733bd44d1d704b530 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 5 May 2017 11:39:58 -0400 +Subject: [RHEL7.5 PATCH 112/169] Incremental: return is not a function + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Incremental.c b/Incremental.c +index 97b2e99..c00a43d 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -823,7 +823,7 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent + } + close(afd); + } +- return (max_degraded); ++ return max_degraded; + } + + static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, +-- +2.7.4 + diff --git a/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch b/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch new file mode 100644 index 0000000..652baeb --- /dev/null +++ b/SOURCES/IncrementalScan-Use-md_array_active-instead-of-mdge.patch @@ -0,0 +1,38 @@ +From 00e56fd9537e1f69583d8b0f60faf02026f24d1b Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 5 May 2017 12:18:29 -0400 +Subject: [RHEL7.5 PATCH 115/169] IncrementalScan: Use md_array_active() + instead of md_get_array_info() + +This eliminates yet another case where GET_ARRAY_INFO was used to +indicate whether the array was active. + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index b73eabd..680d318 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1317,7 +1317,6 @@ int IncrementalScan(struct context *c, char *devnm) + + restart: + for (me = mapl ; me ; me = me->next) { +- mdu_array_info_t array; + struct mdinfo *sra; + int mdfd; + +@@ -1362,7 +1361,7 @@ restart: + rv = 1; + continue; + } +- if (md_get_array_info(mdfd, &array) == 0 || errno != ENODEV) { ++ if (md_array_active(mdfd)) { + close(mdfd); + continue; + } +-- +2.7.4 + diff --git a/SOURCES/Introduce1-sys_hot_remove_disk.patch b/SOURCES/Introduce1-sys_hot_remove_disk.patch new file mode 100644 index 0000000..8c10682 --- /dev/null +++ b/SOURCES/Introduce1-sys_hot_remove_disk.patch @@ -0,0 +1,74 @@ +From fdd015696c2e2a6b234a92af564aea44b62e6a0d Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 27 Mar 2017 14:36:56 +1100 +Subject: [RHEL7.5 PATCH 022/169] Introduce sys_hot_remove_disk() + +The new hot_remove_disk() will retry HOT_REMOVE_DISK +several times in the face of EBUSY. +However we sometimes remove a device by writing "remove" to the +"state" attributed. This should be retried as well. +So introduce sys_hot_remove_disk() to repeat this action a few times. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Manage.c | 6 +----- + mdadm.h | 1 + + util.c | 12 ++++++++++++ + 3 files changed, 14 insertions(+), 5 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 9139f96..edf5798 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1177,11 +1177,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + /* device has been removed and we don't know + * the major:minor number + */ +- int n = write(sysfd, "remove", 6); +- if (n != 6) +- err = -1; +- else +- err = 0; ++ err = sys_hot_remove_disk(sysfd); + } else { + err = hot_remove_disk(fd, rdev); + if (err && errno == ENODEV) { +diff --git a/mdadm.h b/mdadm.h +index 5bcfb86..b855d24 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1477,6 +1477,7 @@ extern int add_disk(int mdfd, struct supertype *st, + extern int remove_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); + extern int hot_remove_disk(int mdfd, unsigned long dev); ++extern int sys_hot_remove_disk(int statefd); + extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info); + unsigned long long min_recovery_start(struct mdinfo *array); + +diff --git a/util.c b/util.c +index d09a7e2..b718531 100644 +--- a/util.c ++++ b/util.c +@@ -1813,6 +1813,18 @@ int hot_remove_disk(int mdfd, unsigned long dev) + return ret; + } + ++int sys_hot_remove_disk(int statefd) ++{ ++ int cnt = 5; ++ int ret; ++ ++ while ((ret = write(statefd, "remove", 6)) == -1 && ++ errno == EBUSY && ++ cnt-- > 0) ++ usleep(10000); ++ return ret == 6 ? 0 : -1; ++} ++ + int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + { + /* Initialise kernel's knowledge of array. +-- +2.7.4 + diff --git a/SOURCES/Makefile-Default-to-O2-optimization1.patch b/SOURCES/Makefile-Default-to-O2-optimization1.patch new file mode 100644 index 0000000..a476f9b --- /dev/null +++ b/SOURCES/Makefile-Default-to-O2-optimization1.patch @@ -0,0 +1,25 @@ +From 17d80e6eb64230593ee8d599b94005d303eb58ae Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 21 Apr 2017 12:06:35 -0400 +Subject: [RHEL7.5 PATCH 091/169] Makefile: Default to -O2 optimization + +Signed-off-by: Jes Sorensen +--- + Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile b/Makefile +index 5655812..6850696 100644 +--- a/Makefile ++++ b/Makefile +@@ -30,6 +30,7 @@ + + # define "CXFLAGS" to give extra flags to CC. + # e.g. make CXFLAGS=-O to optimise ++CXFLAGS ?=-O2 + 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 +-- +2.7.4 + diff --git a/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch b/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch new file mode 100644 index 0000000..5834242 --- /dev/null +++ b/SOURCES/Makefile-Fix-date-to-be-output-in-ISO-format.patch @@ -0,0 +1,31 @@ +From 53835cf50023aaad6887b647a3aaab524bd9b39e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 10 Jan 2017 18:51:40 -0500 +Subject: [RHEL7.5 PATCH 001/169] Makefile: Fix date to be output in ISO + format + +Updated the static version in the release, but forgot to fix the +Makefile generated version when extracting from git + +Reported-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 5fd7f16..a6f464c 100644 +--- a/Makefile ++++ b/Makefile +@@ -89,7 +89,7 @@ DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\" + CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS) $(COROSYNC) $(DLM) + + VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//') +-VERS_DATE = $(shell [ -d .git ] && date --date="`git log -n1 --format=format:%cd --date=short`" '+%0dth %B %Y' | sed -e 's/1th/1st/' -e 's/2th/2nd/' -e 's/11st/11th/' -e 's/12nd/12th/') ++VERS_DATE = $(shell [ -d .git ] && date --iso-8601 --date="`git log -n1 --format=format:%cd --date=iso --date=short`") + DVERS = $(if $(VERSION),-DVERSION=\"$(VERSION)\",) + DDATE = $(if $(VERS_DATE),-DVERS_DATE="\"$(VERS_DATE)\"",) + CFLAGS += $(DVERS) $(DDATE) +-- +2.7.4 + diff --git a/SOURCES/Manage-Manage-ro-Use-md_array_active.patch b/SOURCES/Manage-Manage-ro-Use-md_array_active.patch new file mode 100644 index 0000000..77156dc --- /dev/null +++ b/SOURCES/Manage-Manage-ro-Use-md_array_active.patch @@ -0,0 +1,41 @@ +From 80223cb4db3358a24c41a76414a3804c26d5ea3a Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 2 May 2017 10:40:07 -0400 +Subject: [RHEL7.5 PATCH 102/169] Manage: Manage_ro(): Use + md_array_active() + +One call less to md_get_array_info() for determining whether an array +is active or not. + +Signed-off-by: Jes Sorensen +--- + Manage.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 8966e33..230309b 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -40,7 +40,6 @@ int Manage_ro(char *devname, int fd, int readonly) + * use RESTART_ARRAY_RW or STOP_ARRAY_RO + * + */ +- mdu_array_info_t array; + struct mdinfo *mdi; + int rv = 0; + +@@ -88,9 +87,8 @@ int Manage_ro(char *devname, int fd, int readonly) + goto out; + } + +- if (md_get_array_info(fd, &array)) { +- pr_err("%s does not appear to be active.\n", +- devname); ++ if (!md_array_active(fd)) { ++ pr_err("%s does not appear to be active.\n", devname); + rv = 1; + goto out; + } +-- +2.7.4 + diff --git a/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch b/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch new file mode 100644 index 0000000..7d1e964 --- /dev/null +++ b/SOURCES/Manage-Remove-all-references1-to-md_get_version.patch @@ -0,0 +1,69 @@ +From 091e8e6e061a5739be68d214bbd4a25e38bec65c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:34:44 -0400 +Subject: [RHEL7.5 PATCH 059/169] Manage: Remove all references to + md_get_version() + +At this point, support for md driver prior to 0.90.03 is going to +disappear. + +Signed-off-by: Jes Sorensen +--- + Manage.c | 20 +------------------- + 1 file changed, 1 insertion(+), 19 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 618c98b..9e69132 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -46,10 +46,6 @@ int Manage_ro(char *devname, int fd, int readonly) + #endif + int rv = 0; + +- if (md_get_version(fd) < 9000) { +- pr_err("need md driver version 0.90.0 or later\n"); +- return 1; +- } + #ifndef MDASSEMBLE + /* If this is an externally-managed array, we need to modify the + * metadata_version so that mdmon doesn't undo our change. +@@ -176,10 +172,6 @@ int Manage_run(char *devname, int fd, struct context *c) + */ + char nm[32], *nmp; + +- if (md_get_version(fd) < 9000) { +- pr_err("need md driver version 0.90.0 or later\n"); +- return 1; +- } + nmp = fd2devnm(fd); + if (!nmp) { + pr_err("Cannot find %s in sysfs!!\n", devname); +@@ -207,14 +199,6 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + if (will_retry && verbose == 0) + verbose = -1; + +- if (md_get_version(fd) < 9000) { +- if (ioctl(fd, STOP_MD, 0) == 0) +- return 0; +- pr_err("stopping device %s failed: %s\n", +- devname, strerror(errno)); +- return 1; +- } +- + strcpy(devnm, fd2devnm(fd)); + /* Get EXCL access first. If this fails, then attempting + * to stop is probably a bad idea. +@@ -773,9 +757,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + " Adding anyway as --force was given.\n", + dv->devname, devname); + } +- if (!tst->ss->external && +- array->major_version == 0 && +- md_get_version(fd)%100 < 2) { ++ if (!tst->ss->external && array->major_version == 0) { + if (ioctl(fd, HOT_ADD_DISK, rdev)==0) { + if (verbose >= 0) + pr_err("hot added %s\n", +-- +2.7.4 + diff --git a/SOURCES/Manage-subdevs-Use-a-dev_t.patch b/SOURCES/Manage-subdevs-Use-a-dev_t.patch new file mode 100644 index 0000000..3e2607c --- /dev/null +++ b/SOURCES/Manage-subdevs-Use-a-dev_t.patch @@ -0,0 +1,28 @@ +From ffaf1a7eefc6167d7457d649e628c04ccee9a4dd Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 29 Sep 2017 18:08:01 -0400 +Subject: [RHEL7.5 PATCH 12/13] Manage_subdevs(): Use a dev_t + +Use the correct type for rdev + +Signed-off-by: Jes Sorensen +--- + Manage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Manage.c b/Manage.c +index 871d342..21536f5 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1367,7 +1367,7 @@ int Manage_subdevs(char *devname, int fd, + } + + for (dv = devlist; dv; dv = dv->next) { +- unsigned long rdev = 0; /* device to add/remove etc */ ++ dev_t rdev = 0; /* device to add/remove etc */ + int rv; + int mj,mn; + +-- +2.7.4 + diff --git a/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch b/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch new file mode 100644 index 0000000..0d7a8b9 --- /dev/null +++ b/SOURCES/Mention-endian-in-documentation-for-update-byte-orde.patch @@ -0,0 +1,32 @@ +From 4224685fe9baf1df4c42bcb950c9a593efa0585f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 8 May 2017 09:40:09 +1000 +Subject: [RHEL7.5 PATCH 116/169] Mention "endian" in documentation for + --update=byte-order + +This makes it easier to find as "endian" is a commonly used term. + +Reported-by: Trevor Cordes +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index fb99a5c..388e0ed 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -1264,7 +1264,8 @@ is correct. + The + .B byteorder + option allows arrays to be moved between machines with different +-byte-order. ++byte-order, such as from a big-endian machine like a Sparc or some ++MIPS machines, to a little-endian x86_64 machine. + When assembling such an array for the first time after a move, giving + .B "\-\-update=byteorder" + will cause +-- +2.7.4 + diff --git a/SOURCES/Monitor-Code-is-80-characters-per-line.patch b/SOURCES/Monitor-Code-is-80-characters-per-line.patch new file mode 100644 index 0000000..9c5ee14 --- /dev/null +++ b/SOURCES/Monitor-Code-is-80-characters-per-line.patch @@ -0,0 +1,151 @@ +From f27904a53b586e5507b442d7f321177e3dfb5a1a Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Mon, 8 May 2017 17:52:10 -0400 +Subject: [RHEL7.5 PATCH 118/169] Monitor: Code is 80 characters per line + +Fix up some lines that are too long for no reason, and some that have +silly line breaks. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 61 +++++++++++++++++++++++++++---------------------------------- + 1 file changed, 27 insertions(+), 34 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index b5231d2..ec643d4 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -527,13 +527,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + alert("NewArray", st->devname, NULL, ainfo); + } + +- if (st->utime == array.utime && +- st->failed == array.failed_disks && ++ if (st->utime == array.utime && st->failed == array.failed_disks && + st->working == array.working_disks && + st->spare == array.spare_disks && +- (mse == NULL || ( +- mse->percent == st->percent +- ))) { ++ (mse == NULL || (mse->percent == st->percent))) { + close(fd); + if ((st->active < st->raid) && st->spare == 0) + return 1; +@@ -541,32 +538,33 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + return 0; + } + if (st->utime == 0 && /* new array */ +- mse->pattern && strchr(mse->pattern, '_') /* degraded */ +- ) ++ mse->pattern && strchr(mse->pattern, '_') /* degraded */) + alert("DegradedArray", dev, NULL, ainfo); + + if (st->utime == 0 && /* new array */ +- st->expected_spares > 0 && +- array.spare_disks < st->expected_spares) ++ st->expected_spares > 0 && array.spare_disks < st->expected_spares) + alert("SparesMissing", dev, NULL, ainfo); + if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && + mse->percent >= 0) + alert("RebuildStarted", dev, NULL, ainfo); +- if (st->percent >= 0 && +- mse->percent >= 0 && ++ if (st->percent >= 0 && mse->percent >= 0 && + (mse->percent / increments) > (st->percent / increments)) { +- char percentalert[15]; // "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) ++ char percentalert[15]; ++ /* ++ * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars) ++ */ + + if((mse->percent / increments) == 0) +- snprintf(percentalert, sizeof(percentalert), "RebuildStarted"); ++ snprintf(percentalert, sizeof(percentalert), ++ "RebuildStarted"); + else +- snprintf(percentalert, sizeof(percentalert), "Rebuild%02d", mse->percent); ++ snprintf(percentalert, sizeof(percentalert), ++ "Rebuild%02d", mse->percent); + + alert(percentalert, dev, NULL, ainfo); + } + +- if (mse->percent == RESYNC_NONE && +- st->percent >= 0) { ++ if (mse->percent == RESYNC_NONE && st->percent >= 0) { + /* Rebuild/sync/whatever just finished. + * If there is a number in /mismatch_cnt, + * we should report that. +@@ -587,8 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->percent = mse->percent; + + remaining_disks = array.nr_disks; +- for (i=0; i 0; +- i++) { ++ for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) { + mdu_disk_info_t disc; + disc.number = i; + if (md_get_disk_info(fd, &disc) >= 0) { +@@ -606,15 +603,13 @@ 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); ++ strcpy(st->parent_devnm, mse->metadata_version+10); + sl = strchr(st->parent_devnm, '/'); + if (sl) + *sl = 0; + } else + st->parent_devnm[0] = 0; +- if (st->metadata == NULL && +- st->parent_devnm[0] == 0) ++ if (st->metadata == NULL && st->parent_devnm[0] == 0) + st->metadata = super_by_fd(fd, NULL); + + close(fd); +@@ -625,12 +620,10 @@ 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)) { ++ 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, +- prefer); ++ dv = map_dev_preferred(info[i].major, info[i].minor, 1, ++ prefer); + disc.state = newstate; + disc.major = info[i].major; + disc.minor = info[i].minor; +@@ -638,18 +631,18 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + newstate = (1 << MD_DISK_REMOVED); + + if (dv == NULL && st->devid[i]) +- dv = map_dev_preferred( +- major(st->devid[i]), +- minor(st->devid[i]), 1, prefer); ++ dv = map_dev_preferred(major(st->devid[i]), ++ minor(st->devid[i]), 1, prefer); + change = newstate ^ st->devstate[i]; + if (st->utime && change && !st->err && !new_array) { +- if ((st->devstate[i]&change)&(1<devstate[i]&change) & (1 << MD_DISK_SYNC)) + alert("Fail", dev, dv, ainfo); +- else if ((newstate & (1<devid[i] == makedev(disc.major, disc.minor)) ++ st->devid[i] == makedev(disc.major, ++ disc.minor)) + alert("FailSpare", dev, dv, ainfo); +- else if ((newstate&change)&(1<devstate[i] = newstate; +-- +2.7.4 + diff --git a/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch b/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch new file mode 100644 index 0000000..cf86704 --- /dev/null +++ b/SOURCES/Monitor-Fixup-apile-of-whitespace-issues.patch @@ -0,0 +1,329 @@ +From f566ef45d356f6dcd4ec54d294be8664770d8b84 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 11 May 2017 16:56:55 -0400 +Subject: [RHEL7.5 PATCH 139/169] Monitor: Fixup a pile of whitespace + issues + +No code was hurt in this event + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 110 +++++++++++++++++++++++++++++++------------------------------- + 1 file changed, 55 insertions(+), 55 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 83a6d10..0198a34 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -139,7 +139,7 @@ int Monitor(struct mddev_dev *devlist, + + if (!alert_cmd) { + alert_cmd = conf_get_program(); +- if (alert_cmd && ! c->scan) ++ if (alert_cmd && !c->scan) + pr_err("Monitor using program \"%s\" from config file\n", + alert_cmd); + } +@@ -164,8 +164,9 @@ int Monitor(struct mddev_dev *devlist, + + if (devlist == NULL) { + mdlist = conf_get_ident(NULL); +- for (; mdlist; mdlist=mdlist->next) { ++ for (; mdlist; mdlist = mdlist->next) { + struct state *st; ++ + if (mdlist->devname == NULL) + continue; + if (strcasecmp(mdlist->devname, "") == 0) +@@ -189,7 +190,8 @@ int Monitor(struct mddev_dev *devlist, + } + } else { + struct mddev_dev *dv; +- for (dv=devlist ; dv; dv=dv->next) { ++ ++ for (dv = devlist; dv; dv = dv->next) { + struct state *st = xcalloc(1, sizeof *st); + mdlist = conf_get_ident(dv->devname); + st->devname = xstrdup(dv->devname); +@@ -206,18 +208,18 @@ int Monitor(struct mddev_dev *devlist, + } + } + +- while (! finished) { ++ while (!finished) { + int new_found = 0; + struct state *st, **stp; + int anydegraded = 0; + + if (mdstat) + free_mdstat(mdstat); +- mdstat = mdstat_read(oneshot?0:1, 0); ++ mdstat = mdstat_read(oneshot ? 0 : 1, 0); + if (!mdstat) + mdstat_close(); + +- for (st=statelist; st; st=st->next) ++ for (st = statelist; st; st = st->next) + if (check_array(st, mdstat, c->test, &info, + increments, c->prefer)) + anydegraded = 1; +@@ -291,8 +293,8 @@ static int make_daemon(char *pidfile) + } + close(0); + open("/dev/null", O_RDWR); +- dup2(0,1); +- dup2(0,2); ++ dup2(0, 1); ++ dup2(0, 2); + setsid(); + return -1; + } +@@ -323,8 +325,7 @@ static int check_one_sharer(int scan) + fclose(fp); + } + if (scan) { +- if (mkdir(MDMON_DIR, S_IRWXU) < 0 && +- errno != EEXIST) { ++ if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) { + pr_err("Can't create autorebuild.pid file\n"); + } else { + fp = fopen(path, "w"); +@@ -347,7 +348,8 @@ static void alert(char *event, char *dev, 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"); ++ printf("%1.15s: %s on %s %s\n", ctime(&now) + 4, ++ event, dev, disc?disc:"unknown device"); + } + if (info->alert_cmd) { + int pid = fork(); +@@ -363,11 +365,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) + exit(2); + } + } +- if (info->mailaddr && +- (strncmp(event, "Fail", 4)==0 || +- strncmp(event, "Test", 4)==0 || +- strncmp(event, "Spares", 6)==0 || +- strncmp(event, "Degrade", 7)==0)) { ++ 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; +@@ -377,7 +378,8 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) + if (info->mailfrom) + fprintf(mp, "From: %s\n", info->mailfrom); + else +- fprintf(mp, "From: %s monitoring \n", Name); ++ 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); +@@ -403,8 +405,9 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) + 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); ++ while ((n = fread(buf, 1, sizeof(buf), ++ mdstat)) > 0) ++ n = fwrite(buf, 1, n, mp); + fclose(mdstat); + } + pclose(mp); +@@ -416,13 +419,13 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) + /* 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 (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 || ++ else if (strncmp(event, "Rebuild", 7) == 0 || ++ strncmp(event, "MoveSpare", 9) == 0 || + strncmp(event, "Spares", 6) != 0) + priority = LOG_WARNING; + /* Everything else: */ +@@ -497,7 +500,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + goto out; + } + +- for (mse2 = mdstat ; mse2 ; mse2=mse2->next) ++ for (mse2 = mdstat; mse2; mse2 = mse2->next) + if (strcmp(mse2->devnm, st->devnm) == 0) { + mse2->devnm[0] = 0; /* flag it as "used" */ + mse = mse2; +@@ -568,7 +571,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + char cnt[80]; + snprintf(cnt, sizeof(cnt), + " mismatches found: %d (on raid level %d)", +- sra->mismatch_cnt, sra->array.level); ++ sra->mismatch_cnt, sra->array.level); + alert("RebuildFinished", dev, cnt, ainfo); + } else + alert("RebuildFinished", dev, NULL, ainfo); +@@ -594,7 +597,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); ++ strcpy(st->parent_devnm, mse->metadata_version + 10); + sl = strchr(st->parent_devnm, '/'); + if (sl) + *sl = 0; +@@ -603,9 +606,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->metadata == NULL && st->parent_devnm[0] == 0) + st->metadata = super_by_fd(fd, NULL); + +- for (i=0; inext) +- if (mse->devnm[0] && +- (!mse->level || /* retrieve containers */ +- (strcmp(mse->level, "raid0") != 0 && +- strcmp(mse->level, "linear") != 0)) +- ) { ++ for (mse = mdstat; mse; mse = mse->next) ++ if (mse->devnm[0] && (!mse->level || /* retrieve containers */ ++ (strcmp(mse->level, "raid0") != 0 && ++ strcmp(mse->level, "linear") != 0))) { + struct state *st = xcalloc(1, sizeof *st); + mdu_array_info_t array; + int fd; +@@ -707,7 +708,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + st->percent = RESYNC_UNKNOWN; + st->expected_spares = -1; + if (mse->metadata_version && +- strncmp(mse->metadata_version, "external:", 9) == 0 && ++ strncmp(mse->metadata_version, ++ "external:", 9) == 0 && + is_subarray(mse->metadata_version+9)) { + char *sl; + strcpy(st->parent_devnm, +@@ -729,8 +731,7 @@ static int get_required_spare_criteria(struct state *st, + { + int fd; + +- if (!st->metadata || +- !st->metadata->ss->get_spare_criteria) { ++ if (!st->metadata || !st->metadata->ss->get_spare_criteria) { + sc->min_size = 0; + sc->sector_size = 0; + return 0; +@@ -779,14 +780,13 @@ static int check_donor(struct state *from, struct state *to) + } + + static dev_t choose_spare(struct state *from, struct state *to, +- struct domainlist *domlist, struct spare_criteria *sc) ++ struct domainlist *domlist, struct spare_criteria *sc) + { + int d; + dev_t dev = 0; + + for (d = from->raid; !dev && d < MAX_DISKS; d++) { +- if (from->devid[d] > 0 && +- from->devstate[d] == 0) { ++ if (from->devid[d] > 0 && from->devstate[d] == 0) { + struct dev_policy *pol; + unsigned long long dev_size; + unsigned int dev_sector_size; +@@ -810,7 +810,8 @@ static dev_t choose_spare(struct state *from, struct state *to, + if (from->spare_group) + pol_add(&pol, pol_domain, + from->spare_group, NULL); +- if (domain_test(domlist, pol, to->metadata->ss->name) == 1) ++ if (domain_test(domlist, pol, ++ to->metadata->ss->name) == 1) + dev = from->devid[d]; + dev_policy_free(pol); + } +@@ -857,8 +858,8 @@ static dev_t container_choose_spare(struct state *from, struct state *to, + } + dp = list->devs; + while (dp) { +- if (dp->disk.state & (1<disk.state & (1<disk.state & (1 << MD_DISK_SYNC) && ++ !(dp->disk.state & (1 << MD_DISK_FAULTY))) + active_cnt++; + dp = dp->next; + } +@@ -891,8 +892,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info + + link_containers_with_subarrays(statelist); + for (st = statelist; st; st = st->next) +- if (st->active < st->raid && +- st->spare == 0 && !st->err) { ++ if (st->active < st->raid && st->spare == 0 && !st->err) { + struct domainlist *domlist = NULL; + int d; + struct state *to = st; +@@ -940,9 +940,11 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info + else + devid = choose_spare(from, to, domlist, + &sc); +- if (devid > 0 +- && move_spare(from->devname, to->devname, devid)) { +- alert("MoveSpare", to->devname, from->devname, info); ++ if (devid > 0 && ++ move_spare(from->devname, to->devname, ++ devid)) { ++ alert("MoveSpare", to->devname, ++ from->devname, info); + break; + } + } +@@ -967,8 +969,7 @@ static void link_containers_with_subarrays(struct state *list) + for (st = list; st; st = st->next) + if (st->parent_devnm[0]) + for (cont = list; cont; cont = cont->next) +- if (!cont->err && +- cont->parent_devnm[0] == 0 && ++ if (!cont->err && cont->parent_devnm[0] == 0 && + strcmp(cont->devnm, st->parent_devnm) == 0) { + st->parent = cont; + st->subarray = cont->subarray; +@@ -992,7 +993,7 @@ int Wait(char *dev) + struct mdstat_ent *ms = mdstat_read(1, 0); + struct mdstat_ent *e; + +- for (e=ms ; e; e=e->next) ++ for (e = ms; e; e = e->next) + if (strcmp(e->devnm, devnm) == 0) + break; + +@@ -1115,8 +1116,7 @@ int WaitClean(char *dev, int sock, int verbose) + } else + rv = 1; + if (rv && verbose) +- pr_err("Error waiting for %s to be clean\n", +- dev); ++ pr_err("Error waiting for %s to be clean\n", dev); + + /* restore the original safe_mode_delay */ + sysfs_set_safemode(mdi, mdi->safe_mode_delay); +-- +2.7.4 + diff --git a/SOURCES/Monitor-Include-containers-in-spare-migration2.patch b/SOURCES/Monitor-Include-containers-in-spare-migration2.patch new file mode 100644 index 0000000..f2e9ea2 --- /dev/null +++ b/SOURCES/Monitor-Include-containers-in-spare-migration2.patch @@ -0,0 +1,36 @@ +From 2dab69c9e3acace828bbb6a00514fa820f8ca64f Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 16 Aug 2017 14:59:46 +0200 +Subject: [RHEL7.5 PATCH 169/169] Monitor: Include containers in spare + migration + +Spare migration doesn't work for external metadata. mdadm skips +a container with spare device because it is inactive. It used to work +because GET_ARRAY_INFO ioctl returned valid structure for a container +and mdadm treated such response as active container. Current +implementation checks it in sysfs where container is shown as inactive. + +Adapt sysfs implementation to work the same way as ioctl. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Monitor.c b/Monitor.c +index f70e5b5..497e364 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -497,7 +497,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (mse->level == NULL) + is_container = 1; + +- if (!md_array_active(fd)) ++ if (!is_container && !md_array_active(fd)) + goto disappeared; + + fcntl(fd, F_SETFD, FD_CLOEXEC); +-- +2.7.4 + diff --git a/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch b/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch new file mode 100644 index 0000000..b08a04b --- /dev/null +++ b/SOURCES/Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch @@ -0,0 +1,45 @@ +From 9f3dd4549b2b904d343b79a8a7ba40c547e71d5d Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 11 May 2017 16:40:16 -0400 +Subject: [RHEL7.5 PATCH 137/169] Monitor: Not much point declaring mdlist + in both forks of the if() statement + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 5b95847..a4afe75 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -127,6 +127,7 @@ int Monitor(struct mddev_dev *devlist, + struct mdstat_ent *mdstat = NULL; + char *mailfrom = NULL; + struct alert_info info; ++ struct mddev_ident *mdlist; + + if (!mailaddr) { + mailaddr = conf_get_mailaddr(); +@@ -162,7 +163,7 @@ int Monitor(struct mddev_dev *devlist, + return 1; + + if (devlist == NULL) { +- struct mddev_ident *mdlist = conf_get_ident(NULL); ++ mdlist = conf_get_ident(NULL); + for (; mdlist; mdlist=mdlist->next) { + struct state *st; + if (mdlist->devname == NULL) +@@ -189,8 +190,8 @@ int Monitor(struct mddev_dev *devlist, + } else { + struct mddev_dev *dv; + for (dv=devlist ; dv; dv=dv->next) { +- struct mddev_ident *mdlist = conf_get_ident(dv->devname); + struct state *st = xcalloc(1, sizeof *st); ++ mdlist = conf_get_ident(dv->devname); + st->devname = xstrdup(dv->devname); + st->next = statelist; + st->devnm[0] = 0; +-- +2.7.4 + diff --git a/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch b/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch new file mode 100644 index 0000000..68870c0 --- /dev/null +++ b/SOURCES/Monitor-Use-md_array_active-instead-of-manually-fidd.patch @@ -0,0 +1,81 @@ +From b9a0309c7fc3e6c1607d51ab3c3f8486478a65ef Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Mon, 8 May 2017 17:34:08 -0400 +Subject: [RHEL7.5 PATCH 117/169] Monitor: Use md_array_active() instead of + manually fiddling in sysfs + +This removes a pile of clutter that can easily behandled with a simple +check of array_state. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 39 +++++++++++---------------------------- + 1 file changed, 11 insertions(+), 28 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index e2b36ff..b5231d2 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -454,7 +454,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + mdu_array_info_t array; + struct mdstat_ent *mse = NULL, *mse2; + char *dev = st->devname; +- int fd = -1; ++ int fd; + int i; + int remaining_disks; + int last_disk; +@@ -462,33 +462,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + + if (test) + alert("TestMessage", dev, NULL, ainfo); +- if (st->devnm[0]) +- fd = open("/sys/block", O_RDONLY|O_DIRECTORY); +- if (fd >= 0) { +- /* Don't open the device unless it is present and +- * active in sysfs. +- */ +- char buf[10]; +- close(fd); +- fd = sysfs_open(st->devnm, NULL, "array_state"); +- if (fd < 0 || +- read(fd, buf, 10) < 5 || +- strncmp(buf,"clear",5) == 0 || +- strncmp(buf,"inact",5) == 0) { +- if (fd >= 0) +- close(fd); +- fd = sysfs_open(st->devnm, NULL, "level"); +- if (fd < 0 || read(fd, buf, 10) != 0) { +- if (fd >= 0) +- close(fd); +- if (!st->err) +- alert("DeviceDisappeared", dev, NULL, ainfo); +- st->err++; +- return 0; +- } +- } +- close(fd); +- } ++ + fd = open(dev, O_RDONLY); + if (fd < 0) { + if (!st->err) +@@ -496,6 +470,15 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->err++; + return 0; + } ++ ++ if (!md_array_active(fd)) { ++ close(fd); ++ if (!st->err) ++ alert("DeviceDisappeared", dev, NULL, ainfo); ++ st->err++; ++ return 0; ++ } ++ + fcntl(fd, F_SETFD, FD_CLOEXEC); + if (md_get_array_info(fd, &array) < 0) { + if (!st->err) +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Centralize-exit-path.patch b/SOURCES/Monitor-check_array-Centralize-exit-path.patch new file mode 100644 index 0000000..a02e634 --- /dev/null +++ b/SOURCES/Monitor-check_array-Centralize-exit-path.patch @@ -0,0 +1,102 @@ +From 1830e74b4cbde28279f341bc80b68e9d82df32c6 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:25:23 -0400 +Subject: [RHEL7.5 PATCH 125/169] Monitor/check_array: Centralize exit path + +Improve exit handling to make it easier to share error handling and free +sysfs entries later. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index c96f8e8..f404009 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -459,16 +459,19 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + int remaining_disks; + int last_disk; + int new_array = 0; ++ int retval; + + if (test) + alert("TestMessage", dev, NULL, ainfo); + ++ retval = 0; ++ + fd = open(dev, O_RDONLY); + if (fd < 0) { + if (!st->err) + alert("DeviceDisappeared", dev, NULL, ainfo); + st->err++; +- return 0; ++ goto out; + } + + if (!md_array_active(fd)) { +@@ -476,7 +479,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (!st->err) + alert("DeviceDisappeared", dev, NULL, ainfo); + st->err++; +- return 0; ++ goto out; + } + + fcntl(fd, F_SETFD, FD_CLOEXEC); +@@ -485,7 +488,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + alert("DeviceDisappeared", dev, NULL, ainfo); + st->err++; + close(fd); +- return 0; ++ goto out; + } + /* It's much easier to list what array levels can't + * have a device disappear than all of them that can +@@ -495,7 +498,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); + st->err++; + close(fd); +- return 0; ++ goto out; + } + if (st->devnm[0] == 0) + strcpy(st->devnm, fd2devnm(fd)); +@@ -511,7 +514,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + * or re-created after reading mdstat*/ + st->err++; + close(fd); +- return 0; ++ goto out; + } + /* this array is in /proc/mdstat */ + if (array.utime == 0) +@@ -533,9 +536,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + (mse == NULL || (mse->percent == st->percent))) { + close(fd); + if ((st->active < st->raid) && st->spare == 0) +- return 1; +- else +- return 0; ++ retval = 1; ++ goto out; + } + if (st->utime == 0 && /* new array */ + mse->pattern && strchr(mse->pattern, '_') /* degraded */) +@@ -656,8 +658,10 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->raid = array.raid_disks; + st->err = 0; + if ((st->active < st->raid) && st->spare == 0) +- return 1; +- return 0; ++ retval = 1; ++ ++ out: ++ return retval; + } + + static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch b/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch new file mode 100644 index 0000000..45e25b2 --- /dev/null +++ b/SOURCES/Monitor-check_array-Get-arraydisks-from-sysfs.patch @@ -0,0 +1,36 @@ +From 12a9d21f4e9fd4d3a14129407f1e8da6d6444cd6 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:58:55 -0400 +Subject: [RHEL7.5 PATCH 131/169] Monitor/check_array: Get array_disks from + sysfs + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 9456efd..fe6f2b4 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -481,7 +481,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->devnm[0] == 0) + strcpy(st->devnm, fd2devnm(fd)); + +- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED | ++ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED | + GET_MISMATCH); + if (!sra) + goto disappeared; +@@ -641,7 +641,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->spare = array.spare_disks; + st->failed = sra->array.failed_disks; + st->utime = array.utime; +- st->raid = array.raid_disks; ++ st->raid = sra->array.raid_disks; + st->err = 0; + if ((st->active < st->raid) && st->spare == 0) + retval = 1; +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch b/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch new file mode 100644 index 0000000..9b21ec6 --- /dev/null +++ b/SOURCES/Monitor-check_array-Get-faileddisks-from-sysfs.patch @@ -0,0 +1,46 @@ +From b8e5713c74901862b96bf599ab6fd227addc1498 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:54:19 -0400 +Subject: [RHEL7.5 PATCH 130/169] Monitor/check_array: Get 'failed_disks' + from sysfs + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index b94fd7c..9456efd 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -481,7 +481,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->devnm[0] == 0) + strcpy(st->devnm, fd2devnm(fd)); + +- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH); ++ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DEGRADED | ++ GET_MISMATCH); + if (!sra) + goto disappeared; + +@@ -522,7 +523,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + alert("NewArray", st->devname, NULL, ainfo); + } + +- if (st->utime == array.utime && st->failed == array.failed_disks && ++ if (st->utime == array.utime && st->failed == sra->array.failed_disks && + st->working == array.working_disks && + st->spare == array.spare_disks && + (mse == NULL || (mse->percent == st->percent))) { +@@ -638,7 +639,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->active = array.active_disks; + st->working = array.working_disks; + st->spare = array.spare_disks; +- st->failed = array.failed_disks; ++ st->failed = sra->array.failed_disks; + st->utime = array.utime; + st->raid = array.raid_disks; + st->err = 0; +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch b/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch new file mode 100644 index 0000000..092c0ff --- /dev/null +++ b/SOURCES/Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch @@ -0,0 +1,71 @@ +From b98943a4f889b466a3d07264068042b18c620d33 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 17:03:03 -0400 +Subject: [RHEL7.5 PATCH 132/169] Monitor/check_array: Get nr_disks, + active_disks and spare_disks from sysfs + +This leaves working_disks and utime missing before we can eliminate +check_array()'s call to md_get_array_info() + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index fe6f2b4..2204528 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -482,7 +482,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + strcpy(st->devnm, fd2devnm(fd)); + + sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED | +- GET_MISMATCH); ++ GET_MISMATCH | GET_DEVS | GET_STATE); + if (!sra) + goto disappeared; + +@@ -525,7 +525,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + + if (st->utime == array.utime && st->failed == sra->array.failed_disks && + st->working == array.working_disks && +- st->spare == array.spare_disks && ++ st->spare == sra->array.spare_disks && + (mse == NULL || (mse->percent == st->percent))) { + if ((st->active < st->raid) && st->spare == 0) + retval = 1; +@@ -535,8 +535,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + mse->pattern && strchr(mse->pattern, '_') /* degraded */) + alert("DegradedArray", dev, NULL, ainfo); + +- if (st->utime == 0 && /* new array */ +- st->expected_spares > 0 && array.spare_disks < st->expected_spares) ++ if (st->utime == 0 && /* new array */ st->expected_spares > 0 && ++ sra->array.spare_disks < st->expected_spares) + alert("SparesMissing", dev, NULL, ainfo); + if (st->percent < 0 && st->percent != RESYNC_UNKNOWN && + mse->percent >= 0) +@@ -574,7 +574,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + st->percent = mse->percent; + +- remaining_disks = array.nr_disks; ++ remaining_disks = sra->array.nr_disks; + for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) { + mdu_disk_info_t disc; + disc.number = i; +@@ -636,9 +636,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->devstate[i] = newstate; + st->devid[i] = makedev(disc.major, disc.minor); + } +- st->active = array.active_disks; ++ st->active = sra->array.active_disks; + st->working = array.working_disks; +- st->spare = array.spare_disks; ++ st->spare = sra->array.spare_disks; + st->failed = sra->array.failed_disks; + st->utime = array.utime; + st->raid = sra->array.raid_disks; +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch b/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch new file mode 100644 index 0000000..01b4eae --- /dev/null +++ b/SOURCES/Monitor-check_array-Obtain-RAID-level-fromsyfs.patch @@ -0,0 +1,44 @@ +From 48bc2ade86db576036375184774a3ebadf6a22e3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:52:44 -0400 +Subject: [RHEL7.5 PATCH 129/169] Monitor/check_array: Obtain RAID level + from syfs + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 75aea91..b94fd7c 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -481,14 +481,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->devnm[0] == 0) + strcpy(st->devnm, fd2devnm(fd)); + +- sra = sysfs_read(-1, st->devnm, GET_MISMATCH); ++ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_MISMATCH); + if (!sra) + goto disappeared; + + /* It's much easier to list what array levels can't + * have a device disappear than all of them that can + */ +- if (array.level == 0 || array.level == -1) { ++ if (sra->array.level == 0 || sra->array.level == -1) { + if (!st->err && !st->from_config) + alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); + st->err++; +@@ -566,7 +566,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + char cnt[80]; + snprintf(cnt, sizeof(cnt), + " mismatches found: %d (on raid level %d)", +- sra->mismatch_cnt, array.level); ++ sra->mismatch_cnt, sra->array.level); + alert("RebuildFinished", dev, cnt, ainfo); + } else + alert("RebuildFinished", dev, NULL, ainfo); +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch b/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch new file mode 100644 index 0000000..6542556 --- /dev/null +++ b/SOURCES/Monitor-check_array-Read-sysfs-entry-earlier.patch @@ -0,0 +1,79 @@ +From aed5f5c34c2b248876b874898d0b3bf65b6cca53 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:49:33 -0400 +Subject: [RHEL7.5 PATCH 128/169] Monitor/check_array: Read sysfs entry + earlier + +This will allow us to pull additional info from sysfs, such as level +and device info. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index bb3a2c4..75aea91 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -451,7 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + * '1' if the array is degraded, or '0' if it is optimal (or dead). + */ + struct { int state, major, minor; } info[MAX_DISKS]; +- struct mdinfo *sra; ++ struct mdinfo *sra = NULL; + mdu_array_info_t array; + struct mdstat_ent *mse = NULL, *mse2; + char *dev = st->devname; +@@ -478,6 +478,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (md_get_array_info(fd, &array) < 0) + goto disappeared; + ++ if (st->devnm[0] == 0) ++ strcpy(st->devnm, fd2devnm(fd)); ++ ++ sra = sysfs_read(-1, st->devnm, GET_MISMATCH); ++ if (!sra) ++ goto disappeared; ++ + /* It's much easier to list what array levels can't + * have a device disappear than all of them that can + */ +@@ -487,8 +494,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->err++; + goto out; + } +- if (st->devnm[0] == 0) +- strcpy(st->devnm, fd2devnm(fd)); + + for (mse2 = mdstat ; mse2 ; mse2=mse2->next) + if (strcmp(mse2->devnm, st->devnm) == 0) { +@@ -557,7 +562,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + * If there is a number in /mismatch_cnt, + * we should report that. + */ +- sra = sysfs_read(-1, st->devnm, GET_MISMATCH); + if (sra && sra->mismatch_cnt > 0) { + char cnt[80]; + snprintf(cnt, sizeof(cnt), +@@ -566,8 +570,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + alert("RebuildFinished", dev, cnt, ainfo); + } else + alert("RebuildFinished", dev, NULL, ainfo); +- if (sra) +- sysfs_free(sra); + } + st->percent = mse->percent; + +@@ -644,6 +646,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + retval = 1; + + out: ++ if (sra) ++ sysfs_free(sra); + if (fd > 0) + close(fd); + return retval; +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch b/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch new file mode 100644 index 0000000..54bafc1 --- /dev/null +++ b/SOURCES/Monitor-check_array-declate-mdinfo-instance-globally.patch @@ -0,0 +1,38 @@ +From 826522f0dc86d31cc7207b01957b5c4243f49dc8 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:41:06 -0400 +Subject: [RHEL7.5 PATCH 127/169] Monitor/check_array: Declate mdinfo + instance globally + +We can pull in more information from sysfs earlier, so move sra to the top. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index c519877..bb3a2c4 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -451,6 +451,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + * '1' if the array is degraded, or '0' if it is optimal (or dead). + */ + struct { int state, major, minor; } info[MAX_DISKS]; ++ struct mdinfo *sra; + mdu_array_info_t array; + struct mdstat_ent *mse = NULL, *mse2; + char *dev = st->devname; +@@ -556,8 +557,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + * If there is a number in /mismatch_cnt, + * we should report that. + */ +- struct mdinfo *sra = +- sysfs_read(-1, st->devnm, GET_MISMATCH); ++ sra = sysfs_read(-1, st->devnm, GET_MISMATCH); + if (sra && sra->mismatch_cnt > 0) { + char cnt[80]; + snprintf(cnt, sizeof(cnt), +-- +2.7.4 + diff --git a/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch b/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch new file mode 100644 index 0000000..08078f1 --- /dev/null +++ b/SOURCES/Monitor-check_array-reduce-duplicated-error-handling.patch @@ -0,0 +1,99 @@ +From 13e5d8455c22d4db420ead9fde3ee0c1536b73a3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 16:38:06 -0400 +Subject: [RHEL7.5 PATCH 126/169] Monitor/check_array: Reduce duplicated + error handling + +Avoid closing fd in multiple places, and duplicating the error message +for when a device disappeared. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 39 +++++++++++++++------------------------ + 1 file changed, 15 insertions(+), 24 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index f404009..c519877 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -467,29 +467,16 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + retval = 0; + + fd = open(dev, O_RDONLY); +- if (fd < 0) { +- if (!st->err) +- alert("DeviceDisappeared", dev, NULL, ainfo); +- st->err++; +- goto out; +- } ++ if (fd < 0) ++ goto disappeared; + +- if (!md_array_active(fd)) { +- close(fd); +- if (!st->err) +- alert("DeviceDisappeared", dev, NULL, ainfo); +- st->err++; +- goto out; +- } ++ if (!md_array_active(fd)) ++ goto disappeared; + + fcntl(fd, F_SETFD, FD_CLOEXEC); +- if (md_get_array_info(fd, &array) < 0) { +- if (!st->err) +- alert("DeviceDisappeared", dev, NULL, ainfo); +- st->err++; +- close(fd); +- goto out; +- } ++ if (md_get_array_info(fd, &array) < 0) ++ goto disappeared; ++ + /* It's much easier to list what array levels can't + * have a device disappear than all of them that can + */ +@@ -497,7 +484,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (!st->err && !st->from_config) + alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); + st->err++; +- close(fd); + goto out; + } + if (st->devnm[0] == 0) +@@ -534,7 +520,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->working == array.working_disks && + st->spare == array.spare_disks && + (mse == NULL || (mse->percent == st->percent))) { +- close(fd); + if ((st->active < st->raid) && st->spare == 0) + retval = 1; + goto out; +@@ -614,8 +599,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->metadata == NULL && st->parent_devnm[0] == 0) + st->metadata = super_by_fd(fd, NULL); + +- close(fd); +- + for (i=0; i 0) ++ close(fd); + return retval; ++ ++ disappeared: ++ if (!st->err) ++ alert("DeviceDisappeared", dev, NULL, ainfo); ++ st->err++; ++ goto out; + } + + static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, +-- +2.7.4 + diff --git a/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch b/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch new file mode 100644 index 0000000..e0c7736 --- /dev/null +++ b/SOURCES/Monitor-checkarray-Use-working_disks-from-sysfs.patch @@ -0,0 +1,38 @@ +From e5eb6857cde0a6a44684dcc7ea0fb196546cf56c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 17:15:14 -0400 +Subject: [RHEL7.5 PATCH 134/169] Monitor/check_array: Use working_disks + from sysfs + +sysfs now provides working_disks information, so lets use it too. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 2204528..5b95847 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -524,7 +524,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + } + + if (st->utime == array.utime && st->failed == sra->array.failed_disks && +- st->working == array.working_disks && ++ st->working == sra->array.working_disks && + st->spare == sra->array.spare_disks && + (mse == NULL || (mse->percent == st->percent))) { + if ((st->active < st->raid) && st->spare == 0) +@@ -637,7 +637,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + st->devid[i] = makedev(disc.major, disc.minor); + } + st->active = sra->array.active_disks; +- st->working = array.working_disks; ++ st->working = sra->array.working_disks; + st->spare = sra->array.spare_disks; + st->failed = sra->array.failed_disks; + st->utime = array.utime; +-- +2.7.4 + diff --git a/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch b/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch new file mode 100644 index 0000000..79acd00 --- /dev/null +++ b/SOURCES/Monitor-containers-don-t-have-the-same-sysfs-propert.patch @@ -0,0 +1,105 @@ +From 802961a2396d342b7bb3d548d412be26acbd7fa8 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 16 Aug 2017 14:22:32 +0200 +Subject: [RHEL7.5 PATCH 168/169] Monitor: containers don't have the same + sysfs properties as arrays + +GET_MISMATCH option doesn't exist for containers so sysfs_read fails if +this information is requested. Set options according to the device using +information from /proc/mdstat. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Monitor.c | 46 ++++++++++++++++++++++++++++------------------ + 1 file changed, 28 insertions(+), 18 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index 48c451c..f70e5b5 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -465,6 +465,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + int last_disk; + int new_array = 0; + int retval; ++ int is_container = 0; ++ unsigned long array_only_flags = 0; + + if (test) + alert("TestMessage", dev, NULL, ainfo); +@@ -475,6 +477,26 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (fd < 0) + goto disappeared; + ++ if (st->devnm[0] == 0) ++ strcpy(st->devnm, fd2devnm(fd)); ++ ++ for (mse2 = mdstat; mse2; mse2 = mse2->next) ++ if (strcmp(mse2->devnm, st->devnm) == 0) { ++ mse2->devnm[0] = 0; /* flag it as "used" */ ++ mse = mse2; ++ } ++ ++ if (!mse) { ++ /* duplicated array in statelist ++ * or re-created after reading mdstat ++ */ ++ st->err++; ++ goto out; ++ } ++ ++ if (mse->level == NULL) ++ is_container = 1; ++ + if (!md_array_active(fd)) + goto disappeared; + +@@ -482,11 +504,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (md_get_array_info(fd, &array) < 0) + goto disappeared; + +- if (st->devnm[0] == 0) +- strcpy(st->devnm, fd2devnm(fd)); ++ if (!is_container) ++ array_only_flags |= GET_MISMATCH; ++ ++ sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEVS | ++ GET_STATE | array_only_flags); + +- sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_MISMATCH | +- GET_DEVS | GET_STATE); + if (!sra) + goto disappeared; + +@@ -500,19 +523,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + goto out; + } + +- for (mse2 = mdstat; mse2; mse2 = mse2->next) +- if (strcmp(mse2->devnm, st->devnm) == 0) { +- mse2->devnm[0] = 0; /* flag it as "used" */ +- mse = mse2; +- } +- +- if (!mse) { +- /* duplicated array in statelist +- * or re-created after reading mdstat*/ +- st->err++; +- close(fd); +- goto out; +- } + /* this array is in /proc/mdstat */ + if (array.utime == 0) + /* external arrays don't update utime, so +@@ -653,7 +663,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + out: + if (sra) + sysfs_free(sra); +- if (fd > 0) ++ if (fd >= 0) + close(fd); + return retval; + +-- +2.7.4 + diff --git a/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch b/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch new file mode 100644 index 0000000..8539856 --- /dev/null +++ b/SOURCES/Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch @@ -0,0 +1,49 @@ +From cb91230c87e02bf885759e9218abea629ab9f4b9 Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Mon, 19 Jun 2017 11:19:53 +0200 +Subject: [RHEL7.5 PATCH 158/169] Monitor: don't assume mdadm parameter is + a block device + +If symlink (e.g. /dev/md/raid) is passed as a parameter to mdadm --wait, +it fails as it's not able to find a corresponding entry in /proc/mdstat +output. Get parameter file major:minor and look for block device name in +sysfs. This commit is partial revert of commit 9e04ac1c43e6 +("mdadm/util: unify stat checking blkdev into function"). + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + Monitor.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/Monitor.c b/Monitor.c +index bef2f1b..48c451c 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -982,12 +982,21 @@ static void link_containers_with_subarrays(struct state *list) + int Wait(char *dev) + { + char devnm[32]; ++ dev_t rdev; ++ char *tmp; + int rv = 1; + int frozen_remaining = 3; + +- if (!stat_is_blkdev(dev, NULL)) ++ if (!stat_is_blkdev(dev, &rdev)) ++ return 2; ++ ++ tmp = devid2devnm(rdev); ++ if (!tmp) { ++ pr_err("Cannot get md device name.\n"); + return 2; +- strcpy(devnm, dev); ++ } ++ ++ strcpy(devnm, tmp); + + while(1) { + struct mdstat_ent *ms = mdstat_read(1, 0); +-- +2.7.4 + diff --git a/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch b/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch new file mode 100644 index 0000000..95092b9 --- /dev/null +++ b/SOURCES/Monitor-mailfrom-is-initialized-correctly.patch @@ -0,0 +1,29 @@ +From 72362f18aee5adedb405fe61c324604184d74555 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 11 May 2017 16:44:19 -0400 +Subject: [RHEL7.5 PATCH 138/169] Monitor: mailfrom is initialized + correctly + +Remove gratituous variable initialization. + +Signed-off-by: Jes Sorensen +--- + Monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Monitor.c b/Monitor.c +index a4afe75..83a6d10 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -125,7 +125,7 @@ int Monitor(struct mddev_dev *devlist, + struct state *st2; + int finished = 0; + struct mdstat_ent *mdstat = NULL; +- char *mailfrom = NULL; ++ char *mailfrom; + struct alert_info info; + struct mddev_ident *mdlist; + +-- +2.7.4 + diff --git a/SOURCES/Query-Handle-error-returned-by-fstat.patch b/SOURCES/Query-Handle-error-returned-by-fstat.patch new file mode 100644 index 0000000..9b887da --- /dev/null +++ b/SOURCES/Query-Handle-error-returned-by-fstat.patch @@ -0,0 +1,72 @@ +From 8d0cd09d73a9a9d57ee73b7a79114e881dad1507 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 13 Apr 2017 11:53:21 -0400 +Subject: [RHEL7.5 PATCH 079/169] Query: Handle error returned by fstat() + +We shouldn't ignore any error returned by fstat() even if open() didn't +fail. + +Signed-off-by: Jes Sorensen +--- + Query.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/Query.c b/Query.c +index bea273f..0d18da4 100644 +--- a/Query.c ++++ b/Query.c +@@ -32,22 +32,21 @@ int Query(char *dev) + * whether it is an md device and whether it has + * a superblock + */ +- int fd = open(dev, O_RDONLY); +- int ioctlerr; ++ int fd; ++ int ioctlerr, staterr; + int superror; + struct mdinfo info; + mdu_array_info_t array; + struct supertype *st = NULL; +- + unsigned long long larray_size; + struct stat stb; + char *mddev; + mdu_disk_info_t disc; + char *activity; + ++ fd = open(dev, O_RDONLY); + if (fd < 0){ +- pr_err("cannot open %s: %s\n", +- dev, strerror(errno)); ++ pr_err("cannot open %s: %s\n", dev, strerror(errno)); + return 1; + } + +@@ -56,9 +55,12 @@ int Query(char *dev) + else + ioctlerr = 0; + +- fstat(fd, &stb); ++ if (fstat(fd, &stb) < 0) ++ staterr = errno; ++ else ++ staterr = 0; + +- if (!ioctlerr) { ++ if (!ioctlerr && !staterr) { + if (!get_dev_size(fd, NULL, &larray_size)) + larray_size = 0; + } +@@ -68,6 +70,9 @@ int Query(char *dev) + else if (ioctlerr) + printf("%s: is an md device, but gives \"%s\" when queried\n", + dev, strerror(ioctlerr)); ++ else if (staterr) ++ printf("%s: is not a valid md device, returning %s\n", ++ dev, strerror(ioctlerr)); + else { + printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n", + dev, +-- +2.7.4 + diff --git a/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch b/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch new file mode 100644 index 0000000..db4cfbb --- /dev/null +++ b/SOURCES/Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch @@ -0,0 +1,28 @@ +From 0dfff0f24355ad4b5c1776f7f19a404ffae25415 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 21 Apr 2017 12:04:05 -0400 +Subject: [RHEL7.5 PATCH 090/169] Query: Quiet gcc since it cannot know + errno != 0 in this case + +Signed-off-by: Jes Sorensen +--- + Query.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Query.c b/Query.c +index 4dec9f5..2bd0e2a 100644 +--- a/Query.c ++++ b/Query.c +@@ -68,6 +68,9 @@ int Query(char *dev) + + if (md_get_array_info(fd, &array) < 0) { + ioctlerr = errno; ++ level = -1; ++ raid_disks = -1; ++ spare_disks = -1; + } else { + level = array.level; + raid_disks = array.raid_disks; +-- +2.7.4 + diff --git a/SOURCES/Query-Remove-all-references-to-md_get_version.patch b/SOURCES/Query-Remove-all-references-to-md_get_version.patch new file mode 100644 index 0000000..58a65a2 --- /dev/null +++ b/SOURCES/Query-Remove-all-references-to-md_get_version.patch @@ -0,0 +1,65 @@ +From 5cb859962febacba3bb9257fc6ed9553ecc16752 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:37:38 -0400 +Subject: [RHEL7.5 PATCH 060/169] Query: Remove all references to + md_get_version() + +More legacy code removed + +Signed-off-by: Jes Sorensen +--- + Query.c | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +diff --git a/Query.c b/Query.c +index a2c839c..bea273f 100644 +--- a/Query.c ++++ b/Query.c +@@ -33,7 +33,6 @@ int Query(char *dev) + * a superblock + */ + int fd = open(dev, O_RDONLY); +- int vers; + int ioctlerr; + int superror; + struct mdinfo info; +@@ -52,7 +51,6 @@ int Query(char *dev) + return 1; + } + +- vers = md_get_version(fd); + if (md_get_array_info(fd, &array) < 0) + ioctlerr = errno; + else +@@ -60,16 +58,12 @@ int Query(char *dev) + + fstat(fd, &stb); + +- if (vers>=9000 && !ioctlerr) { ++ if (!ioctlerr) { + if (!get_dev_size(fd, NULL, &larray_size)) + larray_size = 0; + } + +- if (vers < 0) +- printf("%s: is not an md array\n", dev); +- else if (vers < 9000) +- printf("%s: is an md device, but kernel cannot provide details\n", dev); +- else if (ioctlerr == ENODEV) ++ if (ioctlerr == ENODEV) + printf("%s: is an md device which is not active\n", dev); + else if (ioctlerr) + printf("%s: is an md device, but gives \"%s\" when queried\n", +@@ -100,8 +94,7 @@ int Query(char *dev) + disc.number = info.disk.number; + activity = "undetected"; + if (mddev && (fd = open(mddev, O_RDONLY))>=0) { +- if (md_get_version(fd) >= 9000 && +- md_get_array_info(fd, &array) >= 0) { ++ if (md_get_array_info(fd, &array) >= 0) { + if (md_get_disk_info(fd, &disc) >= 0 && + makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev) + activity = "active"; +-- +2.7.4 + diff --git a/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch b/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch new file mode 100644 index 0000000..f3b783a --- /dev/null +++ b/SOURCES/Query-Use-sysfs-to-obtain-data-if-possible.patch @@ -0,0 +1,80 @@ +From f22d6cde7c7e4be38230ac4c51c3af850ed1614e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 13 Apr 2017 12:20:46 -0400 +Subject: [RHEL7.5 PATCH 080/169] Query: Use sysfs to obtain data if + possible + +Use sysfs to obtain leve, raid_disks, and spare_disks. If sysfs fails, +fall back to calling the ioctl via md_get_array_info(). + +Signed-off-by: Jes Sorensen +--- + Query.c | 32 ++++++++++++++++++++++---------- + 1 file changed, 22 insertions(+), 10 deletions(-) + +diff --git a/Query.c b/Query.c +index 0d18da4..b761c47 100644 +--- a/Query.c ++++ b/Query.c +@@ -35,7 +35,9 @@ int Query(char *dev) + int fd; + int ioctlerr, staterr; + int superror; ++ int level, raid_disks, spare_disks; + struct mdinfo info; ++ struct mdinfo *sra; + mdu_array_info_t array; + struct supertype *st = NULL; + unsigned long long larray_size; +@@ -50,16 +52,28 @@ int Query(char *dev) + return 1; + } + +- if (md_get_array_info(fd, &array) < 0) +- ioctlerr = errno; +- else +- ioctlerr = 0; +- + if (fstat(fd, &stb) < 0) + staterr = errno; + else + staterr = 0; + ++ ioctlerr = 0; ++ ++ sra = sysfs_read(fd, dev, GET_DISKS | GET_LEVEL | GET_DEVS | GET_STATE); ++ if (sra) { ++ level = sra->array.level; ++ raid_disks = sra->array.raid_disks; ++ spare_disks = sra->array.spare_disks; ++ } else { ++ if (md_get_array_info(fd, &array) < 0) { ++ ioctlerr = errno; ++ } else { ++ level = array.level; ++ raid_disks = array.raid_disks; ++ spare_disks = array.spare_disks; ++ } ++ } ++ + if (!ioctlerr && !staterr) { + if (!get_dev_size(fd, NULL, &larray_size)) + larray_size = 0; +@@ -75,11 +89,9 @@ int Query(char *dev) + dev, strerror(ioctlerr)); + 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, array.level), +- array.raid_disks, +- array.spare_disks, array.spare_disks==1?"":"s"); ++ dev, human_size_brief(larray_size,IEC), ++ map_num(pers, level), raid_disks, ++ spare_disks, spare_disks == 1 ? "" : "s"); + } + st = guess_super(fd); + if (st && st->ss->compare_super != NULL) +-- +2.7.4 + diff --git a/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch b/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch new file mode 100644 index 0000000..5a63e20 --- /dev/null +++ b/SOURCES/Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch @@ -0,0 +1,58 @@ +From 618f4e6d63c8c09d8d4002770e44617f3477f137 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Sat, 18 Mar 2017 10:33:44 +0800 +Subject: [RHEL7.5 PATCH 015/169] Replace snprintf with strncpy at some + places to avoid truncation + +In gcc7 there are some building errors like: +directive output may be truncated writing up to 31 bytes into a region of size 24 +snprintf(str, MPB_SIG_LEN, %s, mpb->sig); + +It just need to copy one string to target. So use strncpy to replace it. + +For this line code: snprintf(str, MPB_SIG_LEN, %s, mpb->sig); +Because mpb->sig has the content of version after magic, so +it's better to use strncpy to replace snprintf too. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + super-intel.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index d5e9517..343f20d 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1811,7 +1811,8 @@ static void examine_super_imsm(struct supertype *st, char *homehost) + __u32 reserved = imsm_reserved_sectors(super, super->disks); + struct dl *dl; + +- snprintf(str, MPB_SIG_LEN, "%s", mpb->sig); ++ strncpy(str, (char *)mpb->sig, MPB_SIG_LEN); ++ str[MPB_SIG_LEN-1] = '\0'; + printf(" Magic : %s\n", str); + snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb)); + printf(" Version : %s\n", get_imsm_version(mpb)); +@@ -7142,14 +7143,16 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + + u->type = update_rename_array; + u->dev_idx = vol; +- snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name); ++ strncpy((char *) u->name, name, MAX_RAID_SERIAL_LEN); ++ u->name[MAX_RAID_SERIAL_LEN-1] = '\0'; + append_metadata_update(st, u, sizeof(*u)); + } else { + struct imsm_dev *dev; + int i; + + dev = get_imsm_dev(super, vol); +- snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name); ++ strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN); ++ dev->volume[MAX_RAID_SERIAL_LEN-1] = '\0'; + for (i = 0; i < mpb->num_raid_devs; i++) { + dev = get_imsm_dev(super, i); + handle_missing(super, dev); +-- +2.7.4 + diff --git a/SOURCES/Retire-mdassemble.patch b/SOURCES/Retire-mdassemble.patch new file mode 100644 index 0000000..9669b3d --- /dev/null +++ b/SOURCES/Retire-mdassemble.patch @@ -0,0 +1,1396 @@ +From 32141c1765967e37d6f1accdf124c166bc103c3b Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 11 Apr 2017 12:54:26 -0400 +Subject: [RHEL7.5 PATCH 070/169] Retire mdassemble + +mdassemble doesn't handle container based arrays, no support for sysfs, +etc. It has not been actively maintained for years, so time to send it +off to retirement. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 21 +++------------- + Makefile | 37 ---------------------------- + Manage.c | 10 +------- + Monitor.c | 3 --- + mdassemble.c | 79 ----------------------------------------------------------- + super-ddf.c | 30 ----------------------- + super-gpt.c | 6 ----- + super-intel.c | 52 +-------------------------------------- + super-mbr.c | 8 ------ + super0.c | 11 --------- + super1.c | 21 +++------------- + util.c | 37 +++------------------------- + 12 files changed, 12 insertions(+), 303 deletions(-) + delete mode 100644 mdassemble.c + +diff --git a/Assemble.c b/Assemble.c +index 0db428f..b828523 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -222,13 +222,11 @@ static int select_devices(struct mddev_dev *devlist, + pr_err("%s is a container, but we are looking for components\n", + devname); + tmpdev->used = 2; +-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) + } if (!tst && (tst = super_by_fd(dfd, NULL)) == NULL) { + if (report_mismatch) + pr_err("not a recognisable container: %s\n", + devname); + tmpdev->used = 2; +-#endif + } else if (!tst->ss->load_container + || tst->ss->load_container(tst, dfd, NULL)) { + if (report_mismatch) +@@ -574,9 +572,7 @@ static int load_devices(struct devs *devices, char *devmap, + struct mddev_dev *tmpdev; + int devcnt = 0; + int nextspare = 0; +-#ifndef MDASSEMBLE + int bitmap_done = 0; +-#endif + int most_recent = -1; + int bestcnt = 0; + int *best = *bestp; +@@ -592,7 +588,6 @@ static int load_devices(struct devs *devices, char *devmap, + if (tmpdev->used != 1) + continue; + /* looks like a good enough match to update the super block if needed */ +-#ifndef MDASSEMBLE + if (c->update) { + /* prepare useful information in info structures */ + struct stat stb2; +@@ -683,9 +678,7 @@ static int load_devices(struct devs *devices, char *devmap, + else + bitmap_done = 1; + } +- } else +-#endif +- { ++ } else { + dfd = dev_open(devname, + tmpdev->disposition == 'I' + ? O_RDWR : (O_RDWR|O_EXCL)); +@@ -1097,7 +1090,6 @@ static int start_array(int mdfd, + * it read-only and let the grow code make it writable. + */ + int rv; +-#ifndef MDASSEMBLE + if (content->reshape_active && + !(content->reshape_active & RESHAPE_NO_BACKUP) && + content->delta_disks <= 0) { +@@ -1122,7 +1114,6 @@ static int start_array(int mdfd, + rv = sysfs_set_str(content, NULL, + "array_state", "readonly"); + } else +-#endif + rv = ioctl(mdfd, RUN_ARRAY, NULL); + reopen_mddev(mdfd); /* drop O_EXCL */ + if (rv == 0) { +@@ -1506,7 +1497,6 @@ try_again: + ioctl(mdfd, STOP_ARRAY, NULL); + } + +-#ifndef MDASSEMBLE + if (content != &info) { + /* This is a member of a container. Try starting the array. */ + int err; +@@ -1515,7 +1505,7 @@ try_again: + close(mdfd); + return err; + } +-#endif ++ + /* Ok, no bad inconsistancy, we can try updating etc */ + devices = xcalloc(num_devs, sizeof(*devices)); + devmap = xcalloc(num_devs, content->array.raid_disks); +@@ -1668,14 +1658,13 @@ try_again: + return 1; + } + st->ss->getinfo_super(st, content, NULL); +-#ifndef MDASSEMBLE + if (sysfs_init(content, mdfd, NULL)) { + pr_err("Unable to initialize sysfs\n"); + close(mdfd); + free(devices); + return 1; + } +-#endif ++ + /* after reload context, store journal_clean in context */ + content->journal_clean = journal_clean; + for (i=0; ireshape_active && + !(content->reshape_active & RESHAPE_NO_BACKUP)) { + int err = 0; +@@ -1813,7 +1801,6 @@ try_again: + return err; + } + } +-#endif + + /* Almost ready to actually *do* something */ + /* First, fill in the map, so that udev can find our name +@@ -1876,7 +1863,6 @@ try_again: + return rv == 2 ? 0 : rv; + } + +-#ifndef MDASSEMBLE + int assemble_container_content(struct supertype *st, int mdfd, + struct mdinfo *content, struct context *c, + char *chosen_name, int *result) +@@ -2119,4 +2105,3 @@ int assemble_container_content(struct supertype *st, int mdfd, + return err; + /* FIXME should have an O_EXCL and wait for read-auto */ + } +-#endif +diff --git a/Makefile b/Makefile +index 5ff6cc0..a5d2a0a 100644 +--- a/Makefile ++++ b/Makefile +@@ -158,18 +158,6 @@ MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS)) + STATICSRC = pwgr.c + STATICOBJS = pwgr.o + +-ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c policy.c dlink.c util.c \ +- maps.c lib.c xmalloc.c \ +- super0.c super1.c super-ddf.c super-intel.c sha1.c crc32.c sg_io.c mdstat.c \ +- platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c mapfile.c \ +- crc32c.c +-ASSEMBLE_AUTO_SRCS := mdopen.c +-ASSEMBLE_FLAGS:= $(CFLAGS) -DMDASSEMBLE +-ifdef MDASSEMBLE_AUTO +-ASSEMBLE_SRCS += $(ASSEMBLE_AUTO_SRCS) +-ASSEMBLE_FLAGS += -DMDASSEMBLE_AUTO +-endif +- + all : mdadm mdmon + man : mdadm.man md.man mdadm.conf.man mdmon.man raid6check.man + +@@ -222,31 +210,6 @@ test_stripe : restripe.c xmalloc.o mdadm.h + raid6check : raid6check.o mdadm.h $(CHECK_OBJS) + $(CC) $(CXFLAGS) $(LDFLAGS) -o raid6check raid6check.o $(CHECK_OBJS) + +-mdassemble : $(ASSEMBLE_SRCS) $(INCL) +- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS) $(STATICSRC) +- +-mdassemble.diet : $(ASSEMBLE_SRCS) $(INCL) +- rm -f $(OBJS) +- $(DIET_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS) $(STATICSRC) +- +-mdassemble.static : $(ASSEMBLE_SRCS) $(INCL) +- rm -f $(OBJS) +- $(CC) $(LDFLAGS) $(CPPFLAGS) $(ASSEMBLE_FLAGS) -static -DHAVE_STDINT_H -o mdassemble.static $(ASSEMBLE_SRCS) $(STATICSRC) +- +-mdassemble.auto : $(ASSEMBLE_SRCS) $(INCL) $(ASSEMBLE_AUTO_SRCS) +- rm -f mdassemble.static +- $(MAKE) MDASSEMBLE_AUTO=1 mdassemble.static +- mv mdassemble.static mdassemble.auto +- +-mdassemble.uclibc : $(ASSEMBLE_SRCS) $(INCL) +- rm -f $(OJS) +- $(UCLIBC_GCC) $(ASSEMBLE_FLAGS) -DUCLIBC -DHAVE_STDINT_H -static -o mdassemble.uclibc $(ASSEMBLE_SRCS) $(STATICSRC) +- +-# This doesn't work +-mdassemble.klibc : $(ASSEMBLE_SRCS) $(INCL) +- rm -f $(OBJS) +- $(KLIBC_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS) +- + 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 +diff --git a/Manage.c b/Manage.c +index 9e69132..bb84d28 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -41,12 +41,9 @@ int Manage_ro(char *devname, int fd, int readonly) + * + */ + mdu_array_info_t array; +-#ifndef MDASSEMBLE + struct mdinfo *mdi; +-#endif + int rv = 0; + +-#ifndef MDASSEMBLE + /* If this is an externally-managed array, we need to modify the + * metadata_version so that mdmon doesn't undo our change. + */ +@@ -90,7 +87,7 @@ int Manage_ro(char *devname, int fd, int readonly) + } + goto out; + } +-#endif ++ + if (md_get_array_info(fd, &array)) { + pr_err("%s does not appear to be active.\n", + devname); +@@ -114,14 +111,10 @@ int Manage_ro(char *devname, int fd, int readonly) + } + } + out: +-#ifndef MDASSEMBLE + sysfs_free(mdi); +-#endif + return rv; + } + +-#ifndef MDASSEMBLE +- + static void remove_devices(char *devnm, char *path) + { + /* +@@ -1802,4 +1795,3 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + close(fd2); + return 0; + } +-#endif +diff --git a/Monitor.c b/Monitor.c +index 036a561..1f15377 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1058,8 +1058,6 @@ int Wait(char *dev) + } + } + +-#ifndef MDASSEMBLE +- + static char *clean_states[] = { + "clear", "inactive", "readonly", "read-auto", "clean", NULL }; + +@@ -1151,4 +1149,3 @@ int WaitClean(char *dev, int sock, int verbose) + + return rv; + } +-#endif /* MDASSEMBLE */ +diff --git a/mdassemble.c b/mdassemble.c +deleted file mode 100644 +index f0833bc..0000000 +--- a/mdassemble.c ++++ /dev/null +@@ -1,79 +0,0 @@ +-/* +- * mdassemble - assemble Linux "md" devices aka RAID arrays. +- * +- * Copyright (C) 2001-2009 Neil Brown +- * Copyright (C) 2003 Luca Berra +- * +- * +- * 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 +- * +- * Author: Neil Brown +- * Email: +- */ +- +-#include "mdadm.h" +-#include "md_p.h" +- +-char const Name[] = "mdassemble"; +- +-#ifndef MDASSEMBLE_AUTO +-/* from mdopen.c */ +-int open_mddev(char *dev, int report_errors/*unused*/) +-{ +- struct mdu_array_info_s array; +- int mdfd = open(dev, O_RDONLY); +- if (mdfd < 0) +- pr_err("error opening %s: %s\n", dev, strerror(errno)); +- else if (md_get_array_info(mdfd, &array) != 0) { +- pr_err("%s does not appear to be an md device\n", dev); +- close(mdfd); +- mdfd = -1; +- } +- return mdfd; +-} +-int create_mddev(char *dev, char *name, int autof/*unused*/, int trustworthy, +- char *chosen) +-{ +- return open_mddev(dev, 0); +-} +-#endif +- +-int rv; +-int mdfd = -1; +- +-int main(int argc, char *argv[]) +-{ +- struct mddev_ident *array_list = conf_get_ident(NULL); +- struct context c = { .freeze_reshape = 1 }; +- if (!array_list) { +- pr_err("No arrays found in config file\n"); +- rv = 1; +- } else +- for (; array_list; array_list = array_list->next) { +- mdu_array_info_t array; +- if (strcasecmp(array_list->devname, "") == 0) +- continue; +- mdfd = open_mddev(array_list->devname, 0); +- if (mdfd >= 0 && md_get_array_info(mdfd, &array) == 0) { +- rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */ +- continue; +- } +- if (mdfd >= 0) +- close(mdfd); +- rv |= Assemble(array_list->st, array_list->devname, +- array_list, NULL, &c); +- } +- return rv; +-} +diff --git a/super-ddf.c b/super-ddf.c +index c6037c1..796eaa5 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -500,7 +500,6 @@ struct ddf_super { + } *dlist, *add_list; + }; + +-#ifndef MDASSEMBLE + 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 *); +@@ -518,7 +517,6 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + unsigned long long data_offset, + char *dev, unsigned long long *freesize, + int verbose); +-#endif + + static void free_super_ddf(struct supertype *st); + static int all_ff(const char *guid); +@@ -1305,8 +1303,6 @@ static struct supertype *match_metadata_desc_ddf(char *arg) + return st; + } + +-#ifndef MDASSEMBLE +- + static mapping_t ddf_state[] = { + { "Optimal", 0}, + { "Degraded", 1}, +@@ -1355,7 +1351,6 @@ static mapping_t ddf_sec_level[] = { + { "Spanned", DDF_2SPANNED}, + { NULL, 0} + }; +-#endif + + static int all_ff(const char *guid) + { +@@ -1382,7 +1377,6 @@ static const char *guid_str(const char *guid) + return (const char *) buf; + } + +-#ifndef MDASSEMBLE + static void print_guid(char *guid, int tstamp) + { + /* A GUIDs are part (or all) ASCII and part binary. +@@ -1748,7 +1742,6 @@ static void detail_super_ddf(struct supertype *st, char *homehost) + printf(" Virtual Disks : %d\n", cnt); + printf("\n"); + } +-#endif + + static const char *vendors_with_variable_volume_UUID[] = { + "LSI ", +@@ -1795,7 +1788,6 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf, + memcpy(uuid, sha, 4*4); + } + +-#ifndef MDASSEMBLE + static void brief_detail_super_ddf(struct supertype *st) + { + struct mdinfo info; +@@ -1811,7 +1803,6 @@ static void brief_detail_super_ddf(struct supertype *st) + fname_from_uuid(st, &info, nbuf,':'); + printf(" UUID=%s", nbuf + 5); + } +-#endif + + static int match_home_ddf(struct supertype *st, char *homehost) + { +@@ -1833,7 +1824,6 @@ static int match_home_ddf(struct supertype *st, char *homehost) + ddf->controller.vendor_data[len] == 0); + } + +-#ifndef MDASSEMBLE + static int find_index_in_bvd(const struct ddf_super *ddf, + const struct vd_config *conf, unsigned int n, + unsigned int *n_bvd) +@@ -1914,7 +1904,6 @@ bad: + pr_err("Could't find disk %d in array %u\n", n, inst); + return NULL; + } +-#endif + + static int find_phys(const struct ddf_super *ddf, be32 phys_refnum) + { +@@ -2274,7 +2263,6 @@ static unsigned int find_vde_by_name(const struct ddf_super *ddf, + return DDF_NOTFOUND; + } + +-#ifndef MDASSEMBLE + static unsigned int find_vde_by_guid(const struct ddf_super *ddf, + const char *guid) + { +@@ -2286,7 +2274,6 @@ static unsigned int find_vde_by_guid(const struct ddf_super *ddf, + return i; + return DDF_NOTFOUND; + } +-#endif + + static int init_super_ddf(struct supertype *st, + mdu_array_info_t *info, +@@ -2507,7 +2494,6 @@ static int chunk_to_shift(int chunksize) + return ffs(chunksize/512)-1; + } + +-#ifndef MDASSEMBLE + struct extent { + unsigned long long start, size; + }; +@@ -2608,7 +2594,6 @@ static unsigned long long find_space( + free(e); + return INVALID_SECTORS; + } +-#endif + + static int init_super_ddf_bvd(struct supertype *st, + mdu_array_info_t *info, +@@ -2727,7 +2712,6 @@ static int init_super_ddf_bvd(struct supertype *st, + return 1; + } + +-#ifndef MDASSEMBLE + static void add_to_super_ddf_bvd(struct supertype *st, + mdu_disk_info_t *dk, int fd, char *devname, + unsigned long long data_offset) +@@ -3015,7 +2999,6 @@ static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk) + } + return 0; + } +-#endif + + /* + * This is the write_init_super method for a ddf container. It is +@@ -3176,7 +3159,6 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d) + return 1; + } + +-#ifndef MDASSEMBLE + static int __write_init_super_ddf(struct supertype *st) + { + struct ddf_super *ddf = st->sb; +@@ -3259,8 +3241,6 @@ static int write_init_super_ddf(struct supertype *st) + } + } + +-#endif +- + static __u64 avail_size_ddf(struct supertype *st, __u64 devsize, + unsigned long long data_offset) + { +@@ -3270,8 +3250,6 @@ static __u64 avail_size_ddf(struct supertype *st, __u64 devsize, + return devsize - 32*1024*2; + } + +-#ifndef MDASSEMBLE +- + static int reserve_space(struct supertype *st, int raiddisks, + unsigned long long size, int chunk, + unsigned long long data_offset, +@@ -3653,8 +3631,6 @@ static int load_container_ddf(struct supertype *st, int fd, + return load_super_ddf_all(st, fd, &st->sb, devname); + } + +-#endif /* MDASSEMBLE */ +- + static int check_secondary(const struct vcl *vc) + { + const struct vd_config *conf = &vc->conf; +@@ -4075,7 +4051,6 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) + return 0; + } + +-#ifndef MDASSEMBLE + /* + * A new array 'a' has been started which claims to be instance 'inst' + * within container 'c'. +@@ -5196,7 +5171,6 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + *updates = mu; + return rv; + } +-#endif /* MDASSEMBLE */ + + static int ddf_level_to_layout(int level) + { +@@ -5225,7 +5199,6 @@ static void default_geometry_ddf(struct supertype *st, int *level, int *layout, + } + + struct superswitch super_ddf = { +-#ifndef MDASSEMBLE + .examine_super = examine_super_ddf, + .brief_examine_super = brief_examine_super_ddf, + .brief_examine_subarrays = brief_examine_subarrays_ddf, +@@ -5239,7 +5212,6 @@ struct superswitch super_ddf = { + .load_container = load_container_ddf, + .copy_metadata = copy_metadata_ddf, + .kill_subarray = kill_subarray_ddf, +-#endif + .match_home = match_home_ddf, + .uuid_from_super= uuid_from_super_ddf, + .getinfo_super = getinfo_super_ddf, +@@ -5259,7 +5231,6 @@ struct superswitch super_ddf = { + + .external = 1, + +-#ifndef MDASSEMBLE + /* for mdmon */ + .open_new = ddf_open_new, + .set_array_state= ddf_set_array_state, +@@ -5268,6 +5239,5 @@ struct superswitch super_ddf = { + .process_update = ddf_process_update, + .prepare_update = ddf_prepare_update, + .activate_spare = ddf_activate_spare, +-#endif + .name = "ddf", + }; +diff --git a/super-gpt.c b/super-gpt.c +index bb38a97..a1e9aa9 100644 +--- a/super-gpt.c ++++ b/super-gpt.c +@@ -47,7 +47,6 @@ static void free_gpt(struct supertype *st) + st->sb = NULL; + } + +-#ifndef MDASSEMBLE + static void examine_gpt(struct supertype *st, char *homehost) + { + struct GPT *gpt = st->sb + 512; +@@ -66,7 +65,6 @@ static void examine_gpt(struct supertype *st, char *homehost) + ); + } + } +-#endif /* MDASSEMBLE */ + + static int load_gpt(struct supertype *st, int fd, char *devname) + { +@@ -199,7 +197,6 @@ static struct supertype *match_metadata_desc(char *arg) + return st; + } + +-#ifndef MDASSEMBLE + static int validate_geometry(struct supertype *st, int level, + int layout, int raiddisks, + int *chunk, unsigned long long size, +@@ -210,13 +207,10 @@ static int validate_geometry(struct supertype *st, int level, + pr_err("gpt metadata cannot be used this way\n"); + return 0; + } +-#endif + + struct superswitch gpt = { +-#ifndef MDASSEMBLE + .examine_super = examine_gpt, + .validate_geometry = validate_geometry, +-#endif + .match_metadata_desc = match_metadata_desc, + .load_super = load_gpt, + .store_super = store_gpt, +diff --git a/super-intel.c b/super-intel.c +index 84dfe2b..0aed57c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -260,9 +260,7 @@ struct bbm_log { + struct bbm_log_entry marked_block_entries[BBM_LOG_MAX_ENTRIES]; + } __attribute__ ((__packed__)); + +-#ifndef MDASSEMBLE + static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" }; +-#endif + + #define BLOCKS_PER_KB (1024/512) + +@@ -672,12 +670,10 @@ static struct supertype *match_metadata_desc_imsm(char *arg) + return st; + } + +-#ifndef MDASSEMBLE + static __u8 *get_imsm_version(struct imsm_super *mpb) + { + return &mpb->sig[MPB_SIG_LEN]; + } +-#endif + + /* retrieve a disk directly from the anchor when the anchor is known to be + * up-to-date, currently only at load time +@@ -784,7 +780,6 @@ static size_t sizeof_imsm_dev(struct imsm_dev *dev, int migr_state) + return size; + } + +-#ifndef MDASSEMBLE + /* retrieve disk serial number list from a metadata update */ + static struct disk_info *get_disk_info(struct imsm_update_create_array *update) + { +@@ -796,7 +791,6 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update) + + return inf; + } +-#endif + + static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index) + { +@@ -847,7 +841,6 @@ static inline struct bbm_log_block_addr __cpu_to_le48(unsigned long long sec) + return addr; + } + +-#ifndef MDASSEMBLE + /* get size of the bbm log */ + static __u32 get_imsm_bbm_log_size(struct bbm_log *log) + { +@@ -978,7 +971,6 @@ static int clear_badblock(struct bbm_log *log, const __u8 idx, const unsigned + + return 1; + } +-#endif /* MDASSEMBLE */ + + /* allocate and load BBM log from metadata */ + static int load_bbm_log(struct intel_super *super) +@@ -1423,7 +1415,6 @@ static int is_gen_migration(struct imsm_dev *dev); + + #define IMSM_4K_DIV 8 + +-#ifndef MDASSEMBLE + static __u64 blocks_per_migr_unit(struct intel_super *super, + struct imsm_dev *dev); + +@@ -1698,7 +1689,6 @@ void examine_migr_rec_imsm(struct intel_super *super) + break; + } + } +-#endif /* MDASSEMBLE */ + + void convert_from_4k_imsm_migr_rec(struct intel_super *super) + { +@@ -1858,7 +1848,6 @@ static int imsm_check_attributes(__u32 attributes) + return ret_val; + } + +-#ifndef MDASSEMBLE + static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map); + + static void examine_super_imsm(struct supertype *st, char *homehost) +@@ -2572,8 +2561,6 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) + return result; + } + +-#endif +- + static int match_home_imsm(struct supertype *st, char *homehost) + { + /* the imsm metadata format does not specify any host +@@ -2984,7 +2971,6 @@ out: + return retval; + } + +-#ifndef MDASSEMBLE + /******************************************************************************* + * function: imsm_create_metadata_checkpoint_update + * Description: It creates update for checkpoint change. +@@ -3125,7 +3111,6 @@ static int write_imsm_migr_rec(struct supertype *st) + close(fd); + return retval; + } +-#endif /* MDASSEMBLE */ + + /* spare/missing disks activations are not allowe when + * array/container performs reshape operation, because +@@ -3396,7 +3381,6 @@ static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, + static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev, + int look_in_map); + +-#ifndef MDASSEMBLE + static void manage_second_map(struct intel_super *super, struct imsm_dev *dev) + { + if (is_gen_migration(dev)) { +@@ -3412,7 +3396,6 @@ static void manage_second_map(struct intel_super *super, struct imsm_dev *dev) + } + } + } +-#endif + + static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index) + { +@@ -3994,7 +3977,6 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd) + return 0; + } + +-#ifndef MDASSEMBLE + /* When migrating map0 contains the 'destination' state while map1 + * contains the current state. When not migrating map0 contains the + * current state. This routine assumes that map[0].map_state is set to +@@ -4082,7 +4064,6 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super, + dev->vol.curr_migr_unit = 0; + map->map_state = map_state; + } +-#endif + + static int parse_raid_devices(struct intel_super *super) + { +@@ -4528,7 +4509,6 @@ static int find_missing(struct intel_super *super) + return 0; + } + +-#ifndef MDASSEMBLE + static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list) + { + struct intel_disk *idisk = disk_list; +@@ -5066,7 +5046,6 @@ static int load_container_imsm(struct supertype *st, int fd, char *devname) + { + return load_super_imsm_all(st, fd, &st->sb, devname, NULL, 1); + } +-#endif + + static int load_super_imsm(struct supertype *st, int fd, char *devname) + { +@@ -5483,7 +5462,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + return 1; + } + +-#ifndef MDASSEMBLE + static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + int fd, char *devname) + { +@@ -6028,7 +6006,6 @@ static int mgmt_disk(struct supertype *st) + + return 0; + } +-#endif + + __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len); + +@@ -6136,8 +6113,6 @@ out: + return ret; + } + +-#ifndef MDASSEMBLE +- + static int write_init_ppl_imsm_all(struct supertype *st, struct mdinfo *info) + { + struct intel_super *super = st->sb; +@@ -6199,7 +6174,6 @@ static int write_init_super_imsm(struct supertype *st) + + return rv; + } +-#endif + + static int store_super_imsm(struct supertype *st, int fd) + { +@@ -6209,16 +6183,11 @@ static int store_super_imsm(struct supertype *st, int fd) + if (!mpb) + return 1; + +-#ifndef MDASSEMBLE + if (super->sector_size == 4096) + convert_to_4k(super); + return store_imsm_mpb(fd, mpb); +-#else +- return 1; +-#endif + } + +-#ifndef MDASSEMBLE + static int validate_geometry_imsm_container(struct supertype *st, int level, + int layout, int raiddisks, int chunk, + unsigned long long size, +@@ -7433,7 +7402,6 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + + return 0; + } +-#endif /* MDASSEMBLE */ + + static int is_gen_migration(struct imsm_dev *dev) + { +@@ -7467,7 +7435,6 @@ static int is_rebuilding(struct imsm_dev *dev) + return 0; + } + +-#ifndef MDASSEMBLE + static int is_initializing(struct imsm_dev *dev) + { + struct imsm_map *migr_map; +@@ -7485,7 +7452,6 @@ static int is_initializing(struct imsm_dev *dev) + + return 0; + } +-#endif + + static void update_recovery_start(struct intel_super *super, + struct imsm_dev *dev, +@@ -7519,9 +7485,7 @@ static void update_recovery_start(struct intel_super *super, + rebuild->recovery_start = units * blocks_per_migr_unit(super, dev); + } + +-#ifndef MDASSEMBLE + static int recover_backup_imsm(struct supertype *st, struct mdinfo *info); +-#endif + + static struct mdinfo *container_content_imsm(struct supertype *st, char *subarray) + { +@@ -7560,9 +7524,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + struct imsm_map *map2; + struct mdinfo *this; + int slot; +-#ifndef MDASSEMBLE + int chunk; +-#endif + char *ep; + + if (subarray && +@@ -7591,7 +7553,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + super->current_vol = i; + getinfo_super_imsm_volume(st, this, NULL); + this->next = rest; +-#ifndef MDASSEMBLE + chunk = __le16_to_cpu(map->blocks_per_strip) >> 1; + /* mdadm does not support all metadata features- set the bit in all arrays state */ + if (!validate_geometry_imsm_orom(super, +@@ -7606,7 +7567,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + (1<array.spare_disks += spare_disks; + +-#ifndef MDASSEMBLE + /* check for reshape */ + if (this->reshape_active == 1) + recover_backup_imsm(st, this); +-#endif + rest = this; + } + +@@ -7831,7 +7789,6 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev, + return failed; + } + +-#ifndef MDASSEMBLE + static int imsm_open_new(struct supertype *c, struct active_array *a, + char *inst) + { +@@ -10003,7 +9960,6 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind + __free_imsm_disk(dl); + } + } +-#endif /* MDASSEMBLE */ + + static void close_targets(int *targets, int new_disks) + { +@@ -10206,7 +10162,7 @@ int validate_container_imsm(struct mdinfo *info) + + return 0; + } +-#ifndef MDASSEMBLE ++ + /******************************************************************************* + * Function: imsm_record_badblock + * Description: This routine stores new bad block record in BBM log +@@ -11852,10 +11808,7 @@ abort: + return ret_val; + } + +-#endif /* MDASSEMBLE */ +- + struct superswitch super_imsm = { +-#ifndef MDASSEMBLE + .examine_super = examine_super_imsm, + .brief_examine_super = brief_examine_super_imsm, + .brief_examine_subarrays = brief_examine_subarrays_imsm, +@@ -11878,7 +11831,6 @@ struct superswitch super_imsm = { + .recover_backup = recover_backup_imsm, + .copy_metadata = copy_metadata_imsm, + .examine_badblocks = examine_badblocks_imsm, +-#endif + .match_home = match_home_imsm, + .uuid_from_super= uuid_from_super_imsm, + .getinfo_super = getinfo_super_imsm, +@@ -11904,7 +11856,6 @@ struct superswitch super_imsm = { + .external = 1, + .name = "imsm", + +-#ifndef MDASSEMBLE + /* for mdmon */ + .open_new = imsm_open_new, + .set_array_state= imsm_set_array_state, +@@ -11916,5 +11867,4 @@ struct superswitch super_imsm = { + .record_bad_block = imsm_record_badblock, + .clear_bad_block = imsm_clear_badblock, + .get_bad_blocks = imsm_get_badblocks, +-#endif /* MDASSEMBLE */ + }; +diff --git a/super-mbr.c b/super-mbr.c +index 1bbe57a..839f000 100644 +--- a/super-mbr.c ++++ b/super-mbr.c +@@ -48,8 +48,6 @@ static void free_mbr(struct supertype *st) + st->sb = NULL; + } + +-#ifndef MDASSEMBLE +- + static void examine_mbr(struct supertype *st, char *homehost) + { + struct MBR *sb = st->sb; +@@ -71,8 +69,6 @@ static void examine_mbr(struct supertype *st, char *homehost) + + } + +-#endif /*MDASSEMBLE */ +- + static int load_super_mbr(struct supertype *st, int fd, char *devname) + { + /* try to read an mbr +@@ -187,7 +183,6 @@ static struct supertype *match_metadata_desc(char *arg) + return st; + } + +-#ifndef MDASSEMBLE + static int validate_geometry(struct supertype *st, int level, + int layout, int raiddisks, + int *chunk, unsigned long long size, +@@ -198,13 +193,10 @@ static int validate_geometry(struct supertype *st, int level, + pr_err("mbr metadata cannot be used this way\n"); + return 0; + } +-#endif + + struct superswitch mbr = { +-#ifndef MDASSEMBLE + .examine_super = examine_mbr, + .validate_geometry = validate_geometry, +-#endif + .match_metadata_desc = match_metadata_desc, + .load_super = load_super_mbr, + .store_super = store_mbr, +diff --git a/super0.c b/super0.c +index 10d9c40..dc13efb 100644 +--- a/super0.c ++++ b/super0.c +@@ -76,8 +76,6 @@ static void super0_swap_endian(struct mdp_superblock_s *sb) + + } + +-#ifndef MDASSEMBLE +- + static void examine_super0(struct supertype *st, char *homehost) + { + mdp_super_t *sb = st->sb; +@@ -380,7 +378,6 @@ static void brief_detail_super0(struct supertype *st) + else + printf("%08x", sb->set_uuid0); + } +-#endif + + static int match_home0(struct supertype *st, char *homehost) + { +@@ -814,7 +811,6 @@ struct devinfo { + struct devinfo *next; + }; + +-#ifndef MDASSEMBLE + /* Add a device to the superblock being created */ + static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo, + int fd, char *devname, unsigned long long data_offset) +@@ -845,7 +841,6 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo, + + return 0; + } +-#endif + + static int store_super0(struct supertype *st, int fd) + { +@@ -899,7 +894,6 @@ static int store_super0(struct supertype *st, int fd) + return 0; + } + +-#ifndef MDASSEMBLE + static int write_init_super0(struct supertype *st) + { + mdp_super_t *sb = st->sb; +@@ -930,7 +924,6 @@ static int write_init_super0(struct supertype *st) + } + return rv; + } +-#endif + + static int compare_super0(struct supertype *st, struct supertype *tst) + { +@@ -1261,7 +1254,6 @@ static void free_super0(struct supertype *st) + st->sb = NULL; + } + +-#ifndef MDASSEMBLE + static int validate_geometry0(struct supertype *st, int level, + int layout, int raiddisks, + int *chunk, unsigned long long size, +@@ -1320,10 +1312,8 @@ static int validate_geometry0(struct supertype *st, int level, + *freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9); + return 1; + } +-#endif /* MDASSEMBLE */ + + struct superswitch super0 = { +-#ifndef MDASSEMBLE + .examine_super = examine_super0, + .brief_examine_super = brief_examine_super0, + .export_examine_super = export_examine_super0, +@@ -1333,7 +1323,6 @@ struct superswitch super0 = { + .validate_geometry = validate_geometry0, + .add_to_super = add_to_super0, + .copy_metadata = copy_metadata0, +-#endif + .match_home = match_home0, + .uuid_from_super = uuid_from_super0, + .getinfo_super = getinfo_super0, +diff --git a/super1.c b/super1.c +index 6f91611..4db4dff 100644 +--- a/super1.c ++++ b/super1.c +@@ -152,7 +152,6 @@ struct misc_dev_info { + |MD_FEATURE_PPL \ + ) + +-#ifndef MDASSEMBLE + static int role_from_sb(struct mdp_superblock_1 *sb) + { + unsigned int d; +@@ -165,7 +164,6 @@ static int role_from_sb(struct mdp_superblock_1 *sb) + role = MD_DISK_ROLE_SPARE; + return role; + } +-#endif + + /* return how many bytes are needed for bitmap, for cluster-md each node + * should have it's own bitmap */ +@@ -304,7 +302,6 @@ static inline unsigned int choose_ppl_space(int chunk) + return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2); + } + +-#ifndef MDASSEMBLE + static void examine_super1(struct supertype *st, char *homehost) + { + struct mdp_superblock_1 *sb = st->sb; +@@ -903,8 +900,6 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + return 0; + } + +-#endif +- + static int match_home1(struct supertype *st, char *homehost) + { + struct mdp_superblock_1 *sb = st->sb; +@@ -1276,7 +1271,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + long bm_sectors = 0; + long space; + +-#ifndef MDASSEMBLE + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset); + bm_sectors = calc_bitmap_size(bms, 4096) >> 9; +@@ -1284,7 +1278,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset); + bm_sectors = (long)__le16_to_cpu(sb->ppl.size); + } +-#endif ++ + if (sb_offset < data_offset) { + /* 1.1 or 1.2. Put bbl after bitmap leaving at least 32K + */ +@@ -1578,7 +1572,7 @@ struct devinfo { + mdu_disk_info_t disk; + struct devinfo *next; + }; +-#ifndef MDASSEMBLE ++ + /* Add a device to the superblock being created */ + static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + int fd, char *devname, unsigned long long data_offset) +@@ -1634,7 +1628,6 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + + return 0; + } +-#endif + + static int locate_bitmap1(struct supertype *st, int fd, int node_num); + +@@ -1742,8 +1735,6 @@ static unsigned long choose_bm_space(unsigned long devsize) + + static void free_super1(struct supertype *st); + +-#ifndef MDASSEMBLE +- + __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len); + + static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd) +@@ -2028,7 +2019,6 @@ error_out: + out: + return rv; + } +-#endif + + static int compare_super1(struct supertype *st, struct supertype *tst) + { +@@ -2282,7 +2272,6 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, + if (devsize < 24) + return 0; + +-#ifndef MDASSEMBLE + if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) { + /* hot-add. allow for actual size of bitmap */ + struct bitmap_super_s *bsb; +@@ -2291,7 +2280,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, + } else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) { + bmspace = __le16_to_cpu(super->ppl.size); + } +-#endif ++ + /* Allow space for bad block log */ + if (super->bblog_size) + bbspace = __le16_to_cpu(super->bblog_size); +@@ -2644,7 +2633,6 @@ static void free_super1(struct supertype *st) + st->sb = NULL; + } + +-#ifndef MDASSEMBLE + static int validate_geometry1(struct supertype *st, int level, + int layout, int raiddisks, + int *chunk, unsigned long long size, +@@ -2740,7 +2728,6 @@ static int validate_geometry1(struct supertype *st, int level, + *freesize = devsize; + return 1; + } +-#endif /* MDASSEMBLE */ + + void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0) + { +@@ -2793,7 +2780,6 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 + } + + struct superswitch super1 = { +-#ifndef MDASSEMBLE + .examine_super = examine_super1, + .brief_examine_super = brief_examine_super1, + .export_examine_super = export_examine_super1, +@@ -2806,7 +2792,6 @@ struct superswitch super1 = { + .examine_badblocks = examine_badblocks_super1, + .copy_metadata = copy_metadata1, + .write_init_ppl = write_init_ppl1, +-#endif + .match_home = match_home1, + .uuid_from_super = uuid_from_super1, + .getinfo_super = getinfo_super1, +diff --git a/util.c b/util.c +index a536f81..a695c45 100644 +--- a/util.c ++++ b/util.c +@@ -89,7 +89,6 @@ int dlm_funs_ready(void) + return is_dlm_hooks_ready ? 1 : 0; + } + +-#ifndef MDASSEMBLE + static struct dlm_hooks *dlm_hooks = NULL; + struct dlm_lock_resource *dlm_lock_res = NULL; + static int ast_called = 0; +@@ -200,16 +199,6 @@ int cluster_release_dlmlock(int lockid) + out: + return ret; + } +-#else +-int cluster_get_dlmlock(int *lockid) +-{ +- return -1; +-} +-int cluster_release_dlmlock(int lockid) +-{ +- return -1; +-} +-#endif + + /* + * Get array info from the kernel. Longer term we want to deprecate the +@@ -291,7 +280,6 @@ int get_linux_version() + return (a*1000000)+(b*1000)+c; + } + +-#ifndef MDASSEMBLE + int mdadm_version(char *version) + { + int a, b, c; +@@ -397,7 +385,6 @@ long parse_num(char *num) + else + return rv; + } +-#endif + + int parse_cluster_confirm_arg(char *input, char **devname, int *slot) + { +@@ -639,7 +626,6 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char + return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : st->ss->swapuuid, buf, sep); + } + +-#ifndef MDASSEMBLE + int check_ext2(int fd, char *name) + { + /* +@@ -743,7 +729,6 @@ int ask(char *mesg) + pr_err("assuming 'no'\n"); + return 0; + } +-#endif /* MDASSEMBLE */ + + int is_standard(char *dev, int *nump) + { +@@ -803,7 +788,6 @@ unsigned long calc_csum(void *super, int bytes) + return csum; + } + +-#ifndef MDASSEMBLE + char *human_size(long long bytes) + { + static char buf[47]; +@@ -895,7 +879,6 @@ void print_r10_layout(int layout) + if (near*far == 1) + printf("NO REDUNDANCY"); + } +-#endif + + unsigned long long calc_array_size(int level, int raid_disks, int layout, + int chunksize, unsigned long long devsize) +@@ -962,7 +945,6 @@ dev_t devnm2devid(char *devnm) + return 0; + } + +-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) + char *get_md_name(char *devnm) + { + /* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */ +@@ -1016,7 +998,6 @@ void put_md_name(char *name) + if (strncmp(name, "/dev/.tmp.md", 12) == 0) + unlink(name); + } +-#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */ + + int get_maj_min(char *dev, int *major, int *minor) + { +@@ -1146,9 +1127,8 @@ struct superswitch *superlist[] = + &super0, &super1, + &super_ddf, &super_imsm, + &mbr, &gpt, +- NULL }; +- +-#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) ++ NULL ++}; + + struct supertype *super_by_fd(int fd, char **subarrayp) + { +@@ -1213,7 +1193,6 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + + return st; + } +-#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */ + + int dev_size_from_id(dev_t id, unsigned long long *size) + { +@@ -1753,7 +1732,7 @@ int add_disk(int mdfd, struct supertype *st, + { + /* Add a device to an array, in one of 2 ways. */ + int rv; +-#ifndef MDASSEMBLE ++ + if (st->ss->external) { + if (info->disk.state & (1<recovery_start = MaxSector; +@@ -1773,7 +1752,6 @@ int add_disk(int mdfd, struct supertype *st, + } + } + } else +-#endif + rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk); + return rv; + } +@@ -1782,12 +1760,11 @@ int remove_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info) + { + int rv; ++ + /* Remove the disk given by 'info' from the array */ +-#ifndef MDASSEMBLE + if (st->ss->external) + rv = sysfs_set_str(sra, info, "slot", "none"); + else +-#endif + rv = ioctl(mdfd, HOT_REMOVE_DISK, makedev(info->disk.major, + info->disk.minor)); + return rv; +@@ -1832,10 +1809,8 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + mdu_array_info_t inf; + int rv; + +-#ifndef MDASSEMBLE + if (st->ss->external) + return sysfs_set_array(info, 9003); +-#endif + + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; +@@ -2015,7 +1990,6 @@ use_random: + memcpy(buf, r, 16); + } + +-#ifndef MDASSEMBLE + int flush_metadata_updates(struct supertype *st) + { + int sfd; +@@ -2057,7 +2031,6 @@ void append_metadata_update(struct supertype *st, void *buf, int len) + *st->update_tail = mu; + st->update_tail = &mu->next; + } +-#endif /* MDASSEMBLE */ + + #ifdef __TINYC__ + /* tinyc doesn't optimize this check in ioctl.h out ... */ +@@ -2197,7 +2170,6 @@ void reopen_mddev(int mdfd) + dup2(fd, mdfd); + } + +-#ifndef MDASSEMBLE + static struct cmap_hooks *cmap_hooks = NULL; + static int is_cmap_hooks_ready = 0; + +@@ -2272,4 +2244,3 @@ void set_hooks(void) + set_dlm_hooks(); + set_cmap_hooks(); + } +-#endif +-- +2.7.4 + diff --git a/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch b/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch new file mode 100644 index 0000000..271fc4c --- /dev/null +++ b/SOURCES/Retry-HOT_REMOVE_DISK-a-few-times.patch @@ -0,0 +1,117 @@ +From 2dd271fe7041c2f7036939cf6917c0578b92fefe Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 27 Mar 2017 12:50:16 +1100 +Subject: [RHEL7.5 PATCH 020/169] Retry HOT_REMOVE_DISK a few times. + +HOT_REMOVE_DISK can fail with EBUSY if there are outstanding +IO request that have not completed yet. It can sometimes +be helpful to wait a little while for these to complete. + +We already do this in impose_level() when reshaping a device, +but not in Manage.c in response to an explicit --remove request. + +So create hot_remove_disk() to central this code, and call it +where-ever it makes sense to wait for a HOT_REMOVE_DISK to succeed. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 9 +-------- + Manage.c | 4 ++-- + mdadm.h | 1 + + util.c | 18 ++++++++++++++++++ + 4 files changed, 22 insertions(+), 10 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 455c5f9..218a706 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -2736,7 +2736,6 @@ static int impose_level(int fd, int level, char *devname, int verbose) + for (d = 0, found = 0; + d < MAX_DISKS && found < array.nr_disks; + d++) { +- int cnt; + mdu_disk_info_t disk; + disk.number = d; + if (ioctl(fd, GET_DISK_INFO, &disk) < 0) +@@ -2750,13 +2749,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + continue; + ioctl(fd, SET_DISK_FAULTY, + makedev(disk.major, disk.minor)); +- cnt = 5; +- while (ioctl(fd, HOT_REMOVE_DISK, +- makedev(disk.major, disk.minor)) < 0 +- && errno == EBUSY +- && cnt--) { +- usleep(10000); +- } ++ hot_remove_disk(fd, makedev(disk.major, disk.minor)); + } + } + c = map_num(pers, level); +diff --git a/Manage.c b/Manage.c +index 5c3d2b9..9139f96 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1183,7 +1183,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, + else + err = 0; + } else { +- err = ioctl(fd, HOT_REMOVE_DISK, rdev); ++ err = hot_remove_disk(fd, rdev); + if (err && errno == ENODEV) { + /* Old kernels rejected this if no personality + * is registered */ +@@ -1607,7 +1607,7 @@ int Manage_subdevs(char *devname, int fd, + + if (dv->disposition == 'F') + /* Need to remove first */ +- ioctl(fd, HOT_REMOVE_DISK, rdev); ++ hot_remove_disk(fd, rdev); + /* Make sure it isn't in use (in 2.6 or later) */ + tfd = dev_open(dv->devname, O_RDONLY|O_EXCL); + if (tfd >= 0) { +diff --git a/mdadm.h b/mdadm.h +index 91fd9eb..5bcfb86 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1476,6 +1476,7 @@ extern int add_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); + extern int remove_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); ++extern int hot_remove_disk(int mdfd, unsigned long dev); + extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info); + unsigned long long min_recovery_start(struct mdinfo *array); + +diff --git a/util.c b/util.c +index 32bd909..d09a7e2 100644 +--- a/util.c ++++ b/util.c +@@ -1795,6 +1795,24 @@ int remove_disk(int mdfd, struct supertype *st, + return rv; + } + ++int hot_remove_disk(int mdfd, unsigned long dev) ++{ ++ int cnt = 5; ++ int ret; ++ ++ /* HOT_REMOVE_DISK can fail with EBUSY if there are ++ * outstanding IO requests to the device. ++ * In this case, it can be helpful to wait a little while, ++ * up to half a second, for that IO to flush. ++ */ ++ while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 && ++ errno == EBUSY && ++ cnt-- > 0) ++ usleep(10000); ++ ++ return ret; ++} ++ + int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + { + /* Initialise kernel's knowledge of array. +-- +2.7.4 + diff --git a/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch b/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch new file mode 100644 index 0000000..2b0e01e --- /dev/null +++ b/SOURCES/Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch @@ -0,0 +1,32 @@ +From 2cfe6f7c646ebc25043f7607f5756edad0bc3071 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 11 Apr 2017 11:30:23 -0400 +Subject: [RHEL7.5 PATCH 069/169] Revert "mdadm/grow: reshape would be + stuck from raid1 to raid5" + +This reverts commit 5b2846684ef5172eccc432e3520b79efbc2abba5. + +This was a red herring and shouldn't have been applied in the first +place. + +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 882bc0b..5c667d2 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -10,7 +10,7 @@ Description=Manage MD Reshape on /dev/%I + DefaultDependencies=no + + [Service] +-ExecStart=BINDIR/mdadm --grow --continue /dev/%i ++ExecStart=BINDIR/mdadm --grow --continue /dev/%I + StandardInput=null + StandardOutput=null + StandardError=null +-- +2.7.4 + diff --git a/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch b/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch new file mode 100644 index 0000000..a80d6f1 --- /dev/null +++ b/SOURCES/Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch @@ -0,0 +1,49 @@ +From ceb5f8ef92c97d1f44c75a3b74f64aa12a3303ef Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 4 Aug 2017 15:30:02 +1000 +Subject: [RHEL7.5 PATCH 165/169] Use correct syntax for passing DEVLINKS + to mdadm from udev + + ${DEVLINKS} +is not valid udev syntax, and is passed through uninterpreted. + $env{DEVLINKS} +or + %e{DEVLINKS} +is correct. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 2 +- + udev-md-raid-assembly.rules | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 461c5de..e0747fb 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -2947,7 +2947,7 @@ This is the only context where the aliases are used. They are + usually provided by a + .I udev + rules mentioning +-.BR ${DEVLINKS} . ++.BR $env{DEVLINKS} . + + .IP + + Does the device have a valid md superblock? If a specific metadata +diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules +index 8ca232a..9f055ed 100644 +--- a/udev-md-raid-assembly.rules ++++ b/udev-md-raid-assembly.rules +@@ -30,7 +30,7 @@ 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 ${DEVLINKS}" ++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", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" + ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" +-- +2.7.4 + diff --git a/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch b/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch new file mode 100644 index 0000000..4b284ec --- /dev/null +++ b/SOURCES/Zeroout-whole-ppl-space-during-creation-force-assemb.patch @@ -0,0 +1,134 @@ +From b251424242b46d62f666829c0e7a7550768fc8de Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:11 +0200 +Subject: [PATCH 05/12] Zeroout whole ppl space during creation/force + assemble + +PPL area should be cleared before creation/force assemble. +If the drive was used in other RAID array, it might contains PPL from it. +There is a risk that mdadm recognizes those PPLs and +refuses to assemble the RAID due to PPL conflict with created +array. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + mdadm.h | 1 + + super-intel.c | 7 ++++++- + super1.c | 5 +++++ + util.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 61 insertions(+), 1 deletion(-) + +diff --git a/mdadm.h b/mdadm.h +index 3fc8a4f..85947bf 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -687,6 +687,7 @@ extern int sysfs_unique_holder(char *devnm, long rdev); + extern int sysfs_freeze_array(struct mdinfo *sra); + extern int sysfs_wait(int fd, int *msec); + extern int load_sys(char *path, char *buf, int len); ++extern int zero_disk_range(int fd, unsigned long long sector, size_t count); + extern int reshape_prepare_fdlist(char *devname, + struct mdinfo *sra, + int raid_disks, +diff --git a/super-intel.c b/super-intel.c +index 56dec36..65cdc92 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6065,7 +6065,12 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd + struct ppl_header *ppl_hdr; + int ret; + +- ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE); ++ /* first clear entire ppl space */ ++ ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size); ++ if (ret) ++ return ret; ++ ++ ret = posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE); + if (ret) { + pr_err("Failed to allocate PPL header buffer\n"); + return ret; +diff --git a/super1.c b/super1.c +index f80e38a..7ae6dc3 100644 +--- a/super1.c ++++ b/super1.c +@@ -1823,6 +1823,11 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd) + struct ppl_header *ppl_hdr; + int ret; + ++ /* first clear entire ppl space */ ++ ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size); ++ if (ret) ++ return ret; ++ + ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE); + if (ret) { + pr_err("Failed to allocate PPL header buffer\n"); +diff --git a/util.c b/util.c +index 68af381..c11729e 100644 +--- a/util.c ++++ b/util.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2334,3 +2335,51 @@ void set_hooks(void) + set_dlm_hooks(); + set_cmap_hooks(); + } ++ ++int zero_disk_range(int fd, unsigned long long sector, size_t count) ++{ ++ int ret = 0; ++ int fd_zero; ++ void *addr = NULL; ++ size_t written = 0; ++ size_t len = count * 512; ++ ssize_t n; ++ ++ fd_zero = open("/dev/zero", O_RDONLY); ++ if (fd_zero < 0) { ++ pr_err("Cannot open /dev/zero\n"); ++ return -1; ++ } ++ ++ if (lseek64(fd, sector * 512, SEEK_SET) < 0) { ++ ret = -errno; ++ pr_err("Failed to seek offset for zeroing\n"); ++ goto out; ++ } ++ ++ addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd_zero, 0); ++ ++ if (addr == MAP_FAILED) { ++ ret = -errno; ++ pr_err("Mapping /dev/zero failed\n"); ++ goto out; ++ } ++ ++ do { ++ n = write(fd, addr + written, len - written); ++ if (n < 0) { ++ if (errno == EINTR) ++ continue; ++ ret = -errno; ++ pr_err("Zeroing disk range failed\n"); ++ break; ++ } ++ written += n; ++ } while (written != len); ++ ++ munmap(addr, len); ++ ++out: ++ close(fd_zero); ++ return ret; ++} +-- +2.7.4 + diff --git a/SOURCES/bitmap-Remove-use-of-md-get-version1.patch b/SOURCES/bitmap-Remove-use-of-md-get-version1.patch new file mode 100644 index 0000000..e0a754d --- /dev/null +++ b/SOURCES/bitmap-Remove-use-of-md-get-version1.patch @@ -0,0 +1,26 @@ +From 5d89b18da805cb9ce2b0f726cd534bcbf4dce8c6 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:38:48 -0400 +Subject: [RHEL7.5 PATCH 061/169] bitmap: Remove use of md_get_version() + +Signed-off-by: Jes Sorensen +--- + bitmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/bitmap.c b/bitmap.c +index ccedfd3..16a6b73 100644 +--- a/bitmap.c ++++ b/bitmap.c +@@ -260,7 +260,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + if (!info) + return rv; + sb = &info->sb; +- if (sb->magic != BITMAP_MAGIC && md_get_version(fd) > 0) { ++ if (sb->magic != BITMAP_MAGIC) { + pr_err("This is an md array. To view a bitmap you need to examine\n"); + pr_err("a member device, not the array.\n"); + pr_err("Reporting bitmap that would be used if this array were used\n"); +-- +2.7.4 + diff --git a/SOURCES/change-back-0644-permission-for-Grow.c.patch b/SOURCES/change-back-0644-permission-for-Grow.c.patch new file mode 100644 index 0000000..472482a --- /dev/null +++ b/SOURCES/change-back-0644-permission-for-Grow.c.patch @@ -0,0 +1,21 @@ +From 99148c19bd9149bb938309ffb6b4dcde20b67934 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Tue, 2 May 2017 17:27:13 +0800 +Subject: [RHEL7.5 PATCH 105/169] change back 0644 permission for Grow.c + +Fixes commit: +26714713cd2b ("mdadm: Change timestamps to unsigned data type.") + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Grow.c | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + mode change 100755 => 100644 Grow.c + +diff --git a/Grow.c b/Grow.c +old mode 100755 +new mode 100644 +-- +2.7.4 + diff --git a/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch b/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch new file mode 100644 index 0000000..26ad79a --- /dev/null +++ b/SOURCES/container_members_max-degradation-Switch-to-using-sy.patch @@ -0,0 +1,65 @@ +From 74d293a2535ef8726a9d43577dad4a908f471a0e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 5 May 2017 12:06:57 -0400 +Subject: [RHEL7.5 PATCH 114/169] container_members_max_degradation: Switch + to using syfs for disk info + +With sysfs now providing the necessary active_disks info, switch to +sysfs and eliminate one more use of md_get_array_info(). We can do +this unconditionally since we wouldn't get here witout sysfs being +available. + +Signed-off-by: Jes Sorensen +--- + Incremental.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index c00a43d..b73eabd 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -802,27 +802,27 @@ static int count_active(struct supertype *st, struct mdinfo *sra, + } + + /* test if container has degraded member(s) */ +-static int container_members_max_degradation(struct map_ent *map, struct map_ent *me) ++static int ++container_members_max_degradation(struct map_ent *map, struct map_ent *me) + { +- mdu_array_info_t array; +- int afd; +- int max_degraded = 0; ++ struct mdinfo *sra; ++ int degraded, max_degraded = 0; + + for(; map; map = map->next) { + if (!metadata_container_matches(map->metadata, me->devnm)) + continue; +- afd = open_dev(map->devnm); +- if (afd < 0) +- continue; + /* most accurate information regarding array degradation */ +- if (md_get_array_info(afd, &array) >= 0) { +- int degraded = array.raid_disks - array.active_disks - +- array.spare_disks; +- if (degraded > max_degraded) +- max_degraded = degraded; +- } +- close(afd); ++ sra = sysfs_read(-1, map->devnm, ++ GET_DISKS | GET_DEVS | GET_STATE); ++ if (!sra) ++ continue; ++ degraded = sra->array.raid_disks - sra->array.active_disks - ++ sra->array.spare_disks; ++ if (degraded > max_degraded) ++ max_degraded = degraded; ++ sysfs_free(sra); + } ++ + return max_degraded; + } + +-- +2.7.4 + diff --git a/SOURCES/disable-journal.patch b/SOURCES/disable-journal.patch index 7631164..1bd67c3 100644 --- a/SOURCES/disable-journal.patch +++ b/SOURCES/disable-journal.patch @@ -1,32 +1,30 @@ -diff --git a/ReadMe.c b/ReadMe.c -index eb8fb4b..2de30e1 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -147,7 +147,9 @@ struct option long_options[] = { +--- a/ReadMe.c~ 2017-12-11 11:15:10.314176222 +0800 ++++ b/ReadMe.c 2017-12-11 11:16:42.451297334 +0800 +@@ -147,7 +147,9 @@ {"data-offset",1, 0, DataOffset}, {"nodes",1, 0, Nodes}, /* also for --assemble */ {"home-cluster",1, 0, ClusterName}, -+#if 0 /* Disable for RHEL */ ++#if 0 /*Disable for rhel7.5*/ {"write-journal",1, 0, WriteJournal}, +#endif {"consistency-policy", 1, 0, 'k'}, /* For assemble */ -@@ -163,7 +165,9 @@ struct option long_options[] = { +@@ -163,7 +165,9 @@ /* Management */ {"add", 0, 0, Add}, {"add-spare", 0, 0, AddSpare}, -+#if 0 /* Disable for RHEL */ ++#if 0 /*Disable for rhel7.5*/ {"add-journal", 0, 0, AddJournal}, +#endif {"remove", 0, 0, Remove}, {"fail", 0, 0, Fail}, {"set-faulty",0, 0, Fail}, -@@ -383,7 +387,9 @@ char Help_create[] = +@@ -383,7 +387,9 @@ " --name= -N : Textual name for array - max 32 characters\n" " --bitmap-chunk= : bitmap chunksize in Kilobytes.\n" " --delay= -d : bitmap update delay in seconds.\n" -+#if 0 /* Disable for RHEL */ ++#if 0 /*Disable for rhel7.5*/ " --write-journal= : Specify journal device for RAID-4/5/6 array\n" +#endif " --consistency-policy= : Specify the policy that determines how the array\n" diff --git a/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch b/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch deleted file mode 100644 index 6b2ec98..0000000 --- a/SOURCES/dont-allow-disks-with-different-sector-size-in-one.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit f2cc4f7d829e1b849e78bdf6c38b7bd6e234c600 -Author: Alexey Obitotskiy -Date: Tue May 9 12:25:45 2017 +0200 - - imsm: don't allow disks with different sector size in one array - - As there is no support in IMSM for arrays including disks with different - sector sizes, don't allow to create such configuration. Also skip the - disk with unsuitable sector size when looking for spares in the same - container. - - Signed-off-by: Alexey Obitotskiy - Signed-off-by: Tomasz Majchrzak - Signed-off-by: Jes Sorensen - -diff --git a/super-intel.c b/super-intel.c -index cfb10d5..e88fe82 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -5483,6 +5483,22 @@ - return 1; - } - -+static int drive_validate_sector_size(struct intel_super *super, struct dl *dl) -+{ -+ unsigned int member_sector_size; -+ -+ if (dl->fd < 0) { -+ pr_err("Invalid file descriptor for %s\n", dl->devname); -+ return 0; -+ } -+ -+ if (!get_dev_sector_size(dl->fd, dl->devname, &member_sector_size)) -+ return 0; -+ if (member_sector_size != super->sector_size) -+ return 0; -+ return 1; -+} -+ - #ifndef MDASSEMBLE - static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, - int fd, char *devname) -@@ -5523,6 +5539,11 @@ - return 1; - } - -+ if (!drive_validate_sector_size(super, dl)) { -+ pr_err("Combining drives of different sector size in one volume is not allowed\n"); -+ return 1; -+ } -+ - /* add a pristine spare to the metadata */ - if (dl->index < 0) { - dl->index = super->anchor->num_disks; -@@ -8484,6 +8505,9 @@ - if (dl->index == -1 && !activate_new) - continue; - -+ if (!drive_validate_sector_size(super, dl)) -+ continue; -+ - /* Does this unused device have the requisite free space? - * It needs to be able to cover all member volumes - */ diff --git a/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch b/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch new file mode 100644 index 0000000..02f1b02 --- /dev/null +++ b/SOURCES/dont-allow-disks-with-different-sector-sizein-one.patch @@ -0,0 +1,64 @@ +commit f2cc4f7d829e1b849e78bdf6c38b7bd6e234c600 +Author: Alexey Obitotskiy +Date: Tue May 9 12:25:45 2017 +0200 + + imsm: don't allow disks with different sector size in one array + + As there is no support in IMSM for arrays including disks with different + sector sizes, don't allow to create such configuration. Also skip the + disk with unsuitable sector size when looking for spares in the same + container. + + Signed-off-by: Alexey Obitotskiy + Signed-off-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/super-intel.c b/super-intel.c +index cfb10d5..e88fe82 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5468,6 +5468,22 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, + return 1; + } + ++static int drive_validate_sector_size(struct intel_super *super, struct dl *dl) ++{ ++ unsigned int member_sector_size; ++ ++ if (dl->fd < 0) { ++ pr_err("Invalid file descriptor for %s\n", dl->devname); ++ return 0; ++ } ++ ++ if (!get_dev_sector_size(dl->fd, dl->devname, &member_sector_size)) ++ return 0; ++ if (member_sector_size != super->sector_size) ++ return 0; ++ return 1; ++} ++ + static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + int fd, char *devname) + { +@@ -5507,6 +5523,11 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, + return 1; + } + ++ if (!drive_validate_sector_size(super, dl)) { ++ pr_err("Combining drives of different sector size in one volume is not allowed\n"); ++ return 1; ++ } ++ + /* add a pristine spare to the metadata */ + if (dl->index < 0) { + dl->index = super->anchor->num_disks; +@@ -8440,6 +8461,9 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot, + if (dl->index == -1 && !activate_new) + continue; + ++ if (!drive_validate_sector_size(super, dl)) ++ continue; ++ + /* Does this unused device have the requisite free space? + * It needs to be able to cover all member volumes + */ diff --git a/SOURCES/examine-tidy-up-some-code.patch b/SOURCES/examine-tidy-up-some-code.patch new file mode 100644 index 0000000..d157195 --- /dev/null +++ b/SOURCES/examine-tidy-up-some-code.patch @@ -0,0 +1,146 @@ +From 36352fc95778677f0319f677ea079c49f7bbe9d0 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 3 Mar 2017 10:57:00 +1100 +Subject: [RHEL7.5 PATCH 006/169] examine: tidy up some code. + +Michael Shigorin reports that the 'lcc' compiler isn't able +to deduce that 'st' must be initialized in + + if (c->SparcAdjust) + st->ss->update_super(st, NULL, "sparc2.2", + +just because the only times it isn't initialised, 'err' is set non-zero. + +This results in a 'possibly uninitialised' warning. +While there is no bug in the code, this does suggest that maybe +the code could be made more obviously correct. + +So this patch: + 1/ moves the "err" variable inside the for loop, so an error in + one device doesn't stop the other devices from being processed + 2/ calls 'continue' early if the device cannot be opened, so that + a level of indent can be removed, and so that it is clear that + 'st' is always initialised before being used + 3/ frees 'st' if an error occured in load_super or load_container. + +Reported-by: Michael Shigorin +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Examine.c | 75 +++++++++++++++++++++++++++++++++------------------------------ + 1 file changed, 39 insertions(+), 36 deletions(-) + +diff --git a/Examine.c b/Examine.c +index 953b8ee..7013480 100644 +--- a/Examine.c ++++ b/Examine.c +@@ -53,7 +53,6 @@ int Examine(struct mddev_dev *devlist, + */ + int fd; + int rv = 0; +- int err = 0; + + struct array { + struct supertype *st; +@@ -66,6 +65,8 @@ int Examine(struct mddev_dev *devlist, + for (; devlist ; devlist = devlist->next) { + struct supertype *st; + int have_container = 0; ++ int err = 0; ++ int container = 0; + + fd = dev_open(devlist->devname, O_RDONLY); + if (fd < 0) { +@@ -74,44 +75,46 @@ int Examine(struct mddev_dev *devlist, + devlist->devname, strerror(errno)); + rv = 1; + } +- err = 1; ++ continue; + } +- else { +- int container = 0; +- if (forcest) +- st = dup_super(forcest); +- else if (must_be_container(fd)) { +- /* might be a container */ +- st = super_by_fd(fd, NULL); +- container = 1; +- } else +- st = guess_super(fd); +- if (st) { +- err = 1; +- st->ignore_hw_compat = 1; +- if (!container) +- err = st->ss->load_super(st, fd, +- (c->brief||c->scan) ? NULL +- :devlist->devname); +- if (err && st->ss->load_container) { +- err = st->ss->load_container(st, fd, +- (c->brief||c->scan) ? NULL +- :devlist->devname); +- if (!err) +- have_container = 1; +- } +- st->ignore_hw_compat = 0; +- } else { +- if (!c->brief) { +- pr_err("No md superblock detected on %s.\n", devlist->devname); +- rv = 1; +- } +- err = 1; ++ ++ if (forcest) ++ st = dup_super(forcest); ++ else if (must_be_container(fd)) { ++ /* might be a container */ ++ st = super_by_fd(fd, NULL); ++ container = 1; ++ } else ++ st = guess_super(fd); ++ if (st) { ++ err = 1; ++ st->ignore_hw_compat = 1; ++ if (!container) ++ err = st->ss->load_super(st, fd, ++ (c->brief||c->scan) ? NULL ++ :devlist->devname); ++ if (err && st->ss->load_container) { ++ err = st->ss->load_container(st, fd, ++ (c->brief||c->scan) ? NULL ++ :devlist->devname); ++ if (!err) ++ have_container = 1; + } +- close(fd); ++ st->ignore_hw_compat = 0; ++ } else { ++ if (!c->brief) { ++ pr_err("No md superblock detected on %s.\n", devlist->devname); ++ rv = 1; ++ } ++ err = 1; + } +- if (err) ++ close(fd); ++ ++ if (err) { ++ if (st) ++ st->ss->free_super(st); + continue; ++ } + + if (c->SparcAdjust) + st->ss->update_super(st, NULL, "sparc2.2", +@@ -121,7 +124,7 @@ int Examine(struct mddev_dev *devlist, + if (c->brief && st->ss->brief_examine_super == NULL) { + if (!c->scan) + pr_err("No brief listing for %s on %s\n", +- st->ss->name, devlist->devname); ++ st->ss->name, devlist->devname); + } else if (c->brief) { + struct array *ap; + char *d; +-- +2.7.4 + diff --git a/SOURCES/imsm-Set-disk-slot-number.patch b/SOURCES/imsm-Set-disk-slot-number.patch new file mode 100644 index 0000000..a382c59 --- /dev/null +++ b/SOURCES/imsm-Set-disk-slot-number.patch @@ -0,0 +1,32 @@ +commit 20dc76d15b40c17b4ccdc3d6283af8ecb513707f +Author: Mariusz Tkaczyk +Date: Tue Oct 3 14:49:49 2017 +0200 + + imsm: Set disk slot number + + If first disk of IMSM RAID1 is failed but still present in the system, + the array is not auto-assembled. Auto-assemble uses raid disk slot from + metadata to index disks. As it's not set, the valid disk is seen as a + replacement disk and its metadata is ignored. The problem is not + observed for other RAID levels as they have more than 2 disks - + replacement disks are only stored under uneven indexes so third disk + metadata is used in such scenario. + + Signed-off-by: Mariusz Tkaczyk + Reviewed-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/super-intel.c b/super-intel.c +index 536cb61..b561fe2 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -3502,6 +3502,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * + __u32 ord = get_imsm_ord_tbl_ent(dev, j, MAP_0); + __u32 idx = ord_to_idx(ord); + ++ if (super->disks && super->disks->index == (int)idx) ++ info->disk.raid_disk = j; ++ + if (!(ord & IMSM_ORD_REBUILD) && + get_imsm_missing(super, idx)) { + missing = 1; diff --git a/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch b/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch new file mode 100644 index 0000000..84d2ef0 --- /dev/null +++ b/SOURCES/imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch @@ -0,0 +1,38 @@ +From 50b9c10da0e7c153744b548680147dc8cc7c4c72 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:15 +0200 +Subject: [PATCH 09/12] imsm: Write empty PPL header if assembling + regular clean array. + +If array was initially assembled with kernel without PPL support - +initial header was never written to the drive. +If initial resync was completed and system is rebooted to kernel with +PPL support - mdadm prevents from assembling normal clean array +due to lack of valid PPL. +Write empty header when assemble normal clean array, so the +its assamble is no longer blocked. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index 7b2327b..501d0c3 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6225,7 +6225,9 @@ out: + } + + if (ret == 1) { +- if (map->map_state == IMSM_T_STATE_UNINITIALIZED) ++ if (map->map_state == IMSM_T_STATE_UNINITIALIZED || ++ (map->map_state == IMSM_T_STATE_NORMAL && ++ !(dev->vol.dirty & RAIDVOL_DIRTY))) + ret = st->ss->write_init_ppl(st, info, d->fd); + else + info->mismatch_cnt++; +-- +2.7.4 + diff --git a/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch b/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch new file mode 100644 index 0000000..afbf310 --- /dev/null +++ b/SOURCES/imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch @@ -0,0 +1,32 @@ +From 98e96bdbefaf0bf1c3d4161862af1ab6d03da1db Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Thu, 28 Sep 2017 14:41:16 +0200 +Subject: [PATCH 10/12] imsm: always do ppl recovery when starting a + rebuilding array + +Set resync_start to 0 when starting a rebuilding array to make the +kernel perform ppl recovery before the rebuild. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index 501d0c3..996d133 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7756,6 +7756,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + map->blocks_per_strip; + info_d->ppl_sector = this->ppl_sector; + info_d->ppl_size = this->ppl_size; ++ if (this->consistency_policy == CONSISTENCY_POLICY_PPL && ++ recovery_start == 0) ++ this->resync_start = 0; + } else { + info_d->component_size = blocks_per_member(map); + } +-- +2.7.4 + diff --git a/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch b/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch new file mode 100644 index 0000000..33a218c --- /dev/null +++ b/SOURCES/imsm-continue-resync-on-3disk-RAID10.patch @@ -0,0 +1,113 @@ +commit 8b9cd157dc030924afaeb1dd1a4d3306f5bda118 +Author: Maksymilian Kunt +Date: Mon Nov 13 12:30:49 2017 +0100 + + imsm: continue resync on 3-disk RAID10 + + If RAID10 gets degraded during resync and is stopped, it doesn't continue + resync after automatic assemble and it is reported to be in sync. Resync + is blocked because the disk is missing. It should not happen for RAID10 as + it can still continue with 3 disks. + + Count missing disks. Block resync only if number of missing disks exceeds + limit for given RAID level (only different for RAID10). Check if the + disk under recovery is present. If not, resync should be allowed to run. + + Signed-off-by: Maksymilian Kunt + Signed-off-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/super-intel.c b/super-intel.c +index 2f912f2..c55802f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1342,6 +1342,20 @@ static unsigned long long round_size_to_mb(unsigned long long size, unsigned int + return size; + } + ++static int able_to_resync(int raid_level, int missing_disks) ++{ ++ int max_missing_disks = 0; ++ ++ switch (raid_level) { ++ case 10: ++ max_missing_disks = 1; ++ break; ++ default: ++ max_missing_disks = 0; ++ } ++ return missing_disks <= max_missing_disks; ++} ++ + /* try to determine how much space is reserved for metadata from + * the last get_extents() entry on the smallest active disk, + * otherwise fallback to the default +@@ -7645,6 +7659,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + int slot; + int chunk; + char *ep; ++ int level; + + if (subarray && + (i != strtoul(subarray, &ep, 10) || *ep != '\0')) +@@ -7653,6 +7668,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + dev = get_imsm_dev(super, i); + map = get_imsm_map(dev, MAP_0); + map2 = get_imsm_map(dev, MAP_1); ++ level = get_imsm_raid_level(map); + + /* do not publish arrays that are in the middle of an + * unsupported migration +@@ -7675,8 +7691,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + chunk = __le16_to_cpu(map->blocks_per_strip) >> 1; + /* mdadm does not support all metadata features- set the bit in all arrays state */ + if (!validate_geometry_imsm_orom(super, +- get_imsm_raid_level(map), /* RAID level */ +- imsm_level_to_layout(get_imsm_raid_level(map)), ++ level, /* RAID level */ ++ imsm_level_to_layout(level), + map->num_members, /* raid disks */ + &chunk, join_u32(dev->size_low, dev->size_high), + 1 /* verbose */)) { +@@ -7700,6 +7716,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + int idx; + int skip; + __u32 ord; ++ int missing = 0; + + skip = 0; + idx = get_imsm_disk_idx(dev, slot, MAP_0); +@@ -7713,19 +7730,27 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + skip = 1; + if (d && is_failed(&d->disk)) + skip = 1; +- if (ord & IMSM_ORD_REBUILD) ++ if (!skip && (ord & IMSM_ORD_REBUILD)) + recovery_start = 0; + + /* + * if we skip some disks the array will be assmebled degraded; + * reset resync start to avoid a dirty-degraded + * situation when performing the intial sync +- * +- * FIXME handle dirty degraded + */ +- if ((skip || recovery_start == 0) && +- !(dev->vol.dirty & RAIDVOL_DIRTY)) +- this->resync_start = MaxSector; ++ if (skip) ++ missing++; ++ ++ if (!(dev->vol.dirty & RAIDVOL_DIRTY)) { ++ if ((!able_to_resync(level, missing) || ++ recovery_start == 0)) ++ this->resync_start = MaxSector; ++ } else { ++ /* ++ * FIXME handle dirty degraded ++ */ ++ } ++ + if (skip) + continue; + diff --git a/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch b/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch new file mode 100644 index 0000000..a2e8196 --- /dev/null +++ b/SOURCES/imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch @@ -0,0 +1,61 @@ +From b23d07503d5940086ea0884d09a737ccb0a9e435 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Thu, 28 Sep 2017 14:41:14 +0200 +Subject: [PATCH 08/12] imsm: don't skip resync when an invalid ppl + header is found + +If validate_ppl_imsm() detects an invalid ppl header it will be +overwritten with a valid, empty ppl header. But if we are assembling an +array after unclean shutdown this will cause the kernel to skip resync +after ppl recovery. We don't want that because if there was an invalid +ppl it's best to assume that the ppl recovery is not enough to make the +array consistent and a full resync should be performed. So when +overwriting the invalid ppl add one ppl_header_entry with a wrong +checksum. This will prevent the kernel from skipping resync after ppl +recovery. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 630fb6e..7b2327b 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6080,6 +6080,16 @@ static int write_init_ppl_imsm(struct supertype *st, struct mdinfo *info, int fd + ppl_hdr = buf; + memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED); + ppl_hdr->signature = __cpu_to_le32(super->anchor->orig_family_num); ++ ++ if (info->mismatch_cnt) { ++ /* ++ * We are overwriting an invalid ppl. Make one entry with wrong ++ * checksum to prevent the kernel from skipping resync. ++ */ ++ ppl_hdr->entries_count = __cpu_to_le32(1); ++ ppl_hdr->entries[0].checksum = ~0; ++ } ++ + ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE)); + + if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) { +@@ -6214,8 +6224,12 @@ out: + } + } + +- if (ret == 1 && map->map_state == IMSM_T_STATE_UNINITIALIZED) +- return st->ss->write_init_ppl(st, info, d->fd); ++ if (ret == 1) { ++ if (map->map_state == IMSM_T_STATE_UNINITIALIZED) ++ ret = st->ss->write_init_ppl(st, info, d->fd); ++ else ++ info->mismatch_cnt++; ++ } + + return ret; + } +-- +2.7.4 + diff --git a/SOURCES/imsm-fix-missing-error-message-during-migration1.patch b/SOURCES/imsm-fix-missing-error-message-during-migration1.patch new file mode 100644 index 0000000..70810d2 --- /dev/null +++ b/SOURCES/imsm-fix-missing-error-message-during-migration1.patch @@ -0,0 +1,35 @@ +From 565cc99e341b3021ad26ff6da19a67d4e4abffde Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Tue, 24 Jan 2017 14:29:33 +0100 +Subject: [RHEL7.5 PATCH 002/169] imsm: fix missing error message during + migration + +If user tries to migrate from raid0 to raid5 and there is no spare +drive to perform it - mdadm will exit with errorcode, but +no error message is printed. + +Print error instead of debug message when this condition occurs, +so user is informed why requested migration is not started. + +Signed-off-by: Pawel Baldysiak +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 433bb6d..d5e9517 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -10718,7 +10718,7 @@ static int imsm_create_metadata_update_for_migration( + free(u); + sysfs_free(spares); + update_memory_size = 0; +- dprintf("error: cannot get spare device for requested migration"); ++ pr_err("cannot get spare device for requested migration\n"); + return 0; + } + sysfs_free(spares); +-- +2.7.4 + diff --git a/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch b/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch new file mode 100644 index 0000000..fe941c8 --- /dev/null +++ b/SOURCES/imsm-rebuild-from-2-disk-RAID10.patch @@ -0,0 +1,181 @@ +From fb12a7454000c56aa0439c5bc07fb29de2f3f2a1 Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Thu, 10 Aug 2017 15:47:22 +0200 +Subject: [RHEL7.5 PATCH 163/169] imsm: rebuild from 2-disk RAID10 + +When RAID10 loses 2 disks and it is still operational, it cannot be +rebuilt. The rebuild process starts for the first disk and completes, +however completion is not recorded in metadata. There is an assumption +that rebuild completion corresponds to transition from degraded to +normal state. It's not the case for 2-disk RAID10 as it's still degraded +after rebuild to first disk completes. + +Check if disk rebuild flag is set in the second map and clear it. So far it +has been checked only in the first map (where it was not set). The flag in +the second map has not been cleared but rebuild completion dropped second +map so the problem was not visible. + +If rebuild completion is notified and array still has failed disks and is in +degraded state, check first if rebuild position is really unset (the same +check as for array in normal state). If so, mark migration as done but don't +change array state (it should remain degraded). Update failed disk number. + +On rebuild start don't clear the rebuild flag in the destination map for all +the drives because failed state is lost for one of them. Just do a copy of +a map and clear the flag in the destination map for the disk that goes into +rebuild. Similarily preserve the rebuild flag in the map during disk removal. + +If the disk is missing on array start and migration has been in progress, +don't just cancel it. Check first if maybe one of the disks was not under +rebuild (rebuild flag present both in source and destination map). If so, +rebuild was running despite of failed disk so there is no need to cancel +migration. + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 67 insertions(+), 10 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 51b7cc3..125c3a9 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4023,7 +4023,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super, + + /* duplicate and then set the target end state in map[0] */ + memcpy(dest, src, sizeof_imsm_map(src)); +- if (migr_type == MIGR_REBUILD || migr_type == MIGR_GEN_MIGR) { ++ if (migr_type == MIGR_GEN_MIGR) { + __u32 ord; + int i; + +@@ -7936,14 +7936,35 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev) + /* end process for initialization and rebuild only + */ + if (is_gen_migration(dev) == 0) { +- __u8 map_state; +- int failed; ++ int failed = imsm_count_failed(super, dev, MAP_0); + +- failed = imsm_count_failed(super, dev, MAP_0); +- map_state = imsm_check_degraded(super, dev, failed, MAP_0); ++ if (failed) { ++ __u8 map_state; ++ struct imsm_map *map = get_imsm_map(dev, MAP_0); ++ struct imsm_map *map1; ++ int i, ord, ord_map1; ++ int rebuilt = 1; + +- if (failed) +- end_migration(dev, super, map_state); ++ for (i = 0; i < map->num_members; i++) { ++ ord = get_imsm_ord_tbl_ent(dev, i, MAP_0); ++ if (!(ord & IMSM_ORD_REBUILD)) ++ continue; ++ ++ map1 = get_imsm_map(dev, MAP_1); ++ if (!map1) ++ continue; ++ ++ ord_map1 = __le32_to_cpu(map1->disk_ord_tbl[i]); ++ if (ord_map1 & IMSM_ORD_REBUILD) ++ rebuilt = 0; ++ } ++ ++ if (rebuilt) { ++ map_state = imsm_check_degraded(super, dev, ++ failed, MAP_0); ++ end_migration(dev, super, map_state); ++ } ++ } + } + for (dl = super->missing; dl; dl = dl->next) + mark_missing(super, dev, &dl->disk, dl->index); +@@ -8225,8 +8246,10 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + int failed; + int ord; + __u8 map_state; ++ int rebuild_done = 0; ++ int i; + +- ord = imsm_disk_slot_to_ord(a, n); ++ ord = get_imsm_ord_tbl_ent(dev, n, MAP_X); + if (ord < 0) + return; + +@@ -8244,6 +8267,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + struct imsm_map *migr_map = get_imsm_map(dev, MAP_1); + + set_imsm_ord_tbl_ent(migr_map, n, ord_to_idx(ord)); ++ rebuild_done = 1; + super->updates_pending++; + } + +@@ -8306,7 +8330,39 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + dprintf_cont(" Map state change"); + end_migration(dev, super, map_state); + super->updates_pending++; ++ } else if (!rebuild_done) { ++ break; ++ } ++ ++ /* check if recovery is really finished */ ++ for (mdi = a->info.devs; mdi ; mdi = mdi->next) ++ if (mdi->recovery_start != MaxSector) { ++ recovery_not_finished = 1; ++ break; ++ } ++ if (recovery_not_finished) { ++ dprintf_cont("\n"); ++ dprintf("Rebuild has not finished yet, state not changed"); ++ if (a->last_checkpoint < mdi->recovery_start) { ++ a->last_checkpoint = ++ mdi->recovery_start; ++ super->updates_pending++; ++ } ++ break; + } ++ ++ dprintf_cont(" Rebuild done, still degraded"); ++ dev->vol.migr_state = 0; ++ set_migr_type(dev, 0); ++ dev->vol.curr_migr_unit = 0; ++ ++ for (i = 0; i < map->num_members; i++) { ++ int idx = get_imsm_ord_tbl_ent(dev, i, MAP_0); ++ ++ if (idx & IMSM_ORD_REBUILD) ++ map->failed_disk_num = i; ++ } ++ super->updates_pending++; + break; + } + if (is_gen_migration(dev)) { +@@ -9936,7 +9992,7 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind + struct imsm_dev *dev; + struct imsm_map *map; + unsigned int i, j, num_members; +- __u32 ord; ++ __u32 ord, ord_map0; + struct bbm_log *log = super->bbm_log; + + dprintf("deleting device[%d] from imsm_super\n", index); +@@ -9958,12 +10014,13 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind + * ord-flags to the first map + */ + ord = get_imsm_ord_tbl_ent(dev, j, MAP_X); ++ ord_map0 = get_imsm_ord_tbl_ent(dev, j, MAP_0); + + if (ord_to_idx(ord) <= index) + continue; + + map = get_imsm_map(dev, MAP_0); +- set_imsm_ord_tbl_ent(map, j, ord_to_idx(ord - 1)); ++ set_imsm_ord_tbl_ent(map, j, ord_map0 - 1); + map = get_imsm_map(dev, MAP_1); + if (map) + set_imsm_ord_tbl_ent(map, j, ord - 1); +-- +2.7.4 + diff --git a/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch b/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch new file mode 100644 index 0000000..3aae7b5 --- /dev/null +++ b/SOURCES/imsm-switch-to-multiple-ppls-automatically-during-as.patch @@ -0,0 +1,60 @@ +From 54148aba7c1a02bf018ae777bebc7f16e6cd3195 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:12 +0200 +Subject: [PATCH 06/12] imsm: switch to multiple ppls automatically + during assemble + +If user has array with single ppl - +update the metadata to use multiple ppls. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index 65cdc92..630fb6e 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6184,6 +6184,36 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + out: + free(buf); + ++ /* ++ * Update metadata to use mutliple PPLs area (1MB). ++ * This is done once for all RAID members ++ */ ++ if (info->consistency_policy == CONSISTENCY_POLICY_PPL && ++ info->ppl_size != (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9)) { ++ char subarray[20]; ++ struct mdinfo *member_dev; ++ ++ sprintf(subarray, "%d", info->container_member); ++ ++ if (mdmon_running(st->container_devnm)) ++ st->update_tail = &st->updates; ++ ++ if (st->ss->update_subarray(st, subarray, "ppl", NULL)) { ++ pr_err("Failed to update subarray %s\n", ++ subarray); ++ } else { ++ if (st->update_tail) ++ flush_metadata_updates(st); ++ else ++ st->ss->sync_metadata(st); ++ info->ppl_size = (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9); ++ for (member_dev = info->devs; member_dev; ++ member_dev = member_dev->next) ++ member_dev->ppl_size = ++ (MULTIPLE_PPL_AREA_SIZE_IMSM >> 9); ++ } ++ } ++ + if (ret == 1 && map->map_state == IMSM_T_STATE_UNINITIALIZED) + return st->ss->write_init_ppl(st, info, d->fd); + +-- +2.7.4 + diff --git a/SOURCES/imsm-use-correct-map-when-validating-ppl.patch b/SOURCES/imsm-use-correct-map-when-validating-ppl.patch new file mode 100644 index 0000000..c0c40e6 --- /dev/null +++ b/SOURCES/imsm-use-correct-map-when-validating-ppl.patch @@ -0,0 +1,48 @@ +From 2fc0fc63a9dbf31a3e333492bc1df80c21fdb10c Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Thu, 28 Sep 2017 14:41:17 +0200 +Subject: [PATCH 11/12] imsm: use correct map when validating ppl + +Use the first map to get the correct disk when rebuilding and not the +failed disk from the second map. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 996d133..cf5d822 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6119,7 +6119,6 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + struct ppl_header *ppl_hdr; + __u32 crc; + struct imsm_dev *dev; +- struct imsm_map *map; + __u32 idx; + unsigned int i; + unsigned long long ppl_offset = 0; +@@ -6134,8 +6133,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + } + + dev = get_imsm_dev(super, info->container_member); +- map = get_imsm_map(dev, MAP_X); +- idx = get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_X); ++ idx = get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_0); + d = get_imsm_dl_disk(super, idx); + + if (!d || d->index < 0 || is_failed(&d->disk)) +@@ -6225,6 +6223,8 @@ out: + } + + if (ret == 1) { ++ struct imsm_map *map = get_imsm_map(dev, MAP_X); ++ + if (map->map_state == IMSM_T_STATE_UNINITIALIZED || + (map->map_state == IMSM_T_STATE_NORMAL && + !(dev->vol.dirty & RAIDVOL_DIRTY))) +-- +2.7.4 + diff --git a/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch b/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch new file mode 100644 index 0000000..55f04de --- /dev/null +++ b/SOURCES/imsm-validate-multiple-ppls-during-assemble.patch @@ -0,0 +1,124 @@ +From 44b6b87610281a4add36a1addd7630095dc8a545 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:10 +0200 +Subject: [PATCH 04/12] imsm: validate multiple ppls during assemble + +Change validation algorithm to check validity of multiple ppls that +are stored in PPL area. + +If read error occurs during - treat the all PPLs as invalid - +there is no guarantee that this one was not latest. If the header CRC is +incorrect - assume that there are no further PPLs in PPL area. + +If whole PPL area was written at least once - there is a possibility that +old PPL (with lower generation number) will follow the recent one +(with higest generation number). Compare those generation numbers to check +which PPL is latest. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 71 +++++++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 47 insertions(+), 24 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 347838e..56dec36 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6106,11 +6106,14 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + struct imsm_dev *dev; + struct imsm_map *map; + __u32 idx; ++ unsigned int i; ++ unsigned long long ppl_offset = 0; ++ unsigned long long prev_gen_num = 0; + + if (disk->disk.raid_disk < 0) + return 0; + +- if (posix_memalign(&buf, 4096, PPL_HEADER_SIZE)) { ++ if (posix_memalign(&buf, MAX_SECTOR_SIZE, PPL_HEADER_SIZE)) { + pr_err("Failed to allocate PPL header buffer\n"); + return -1; + } +@@ -6123,34 +6126,54 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info, + if (!d || d->index < 0 || is_failed(&d->disk)) + goto out; + +- if (lseek64(d->fd, info->ppl_sector * 512, SEEK_SET) < 0) { +- perror("Failed to seek to PPL header location"); +- ret = -1; +- goto out; +- } ++ ret = 1; ++ while (ppl_offset < MULTIPLE_PPL_AREA_SIZE_IMSM) { ++ dprintf("Checking potential PPL at offset: %llu\n", ppl_offset); + +- if (read(d->fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) { +- perror("Read PPL header failed"); +- ret = -1; +- goto out; +- } ++ if (lseek64(d->fd, info->ppl_sector * 512 + ppl_offset, ++ SEEK_SET) < 0) { ++ perror("Failed to seek to PPL header location"); ++ ret = -1; ++ goto out; ++ } + +- ppl_hdr = buf; ++ if (read(d->fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) { ++ perror("Read PPL header failed"); ++ ret = -1; ++ goto out; ++ } + +- crc = __le32_to_cpu(ppl_hdr->checksum); +- ppl_hdr->checksum = 0; ++ ppl_hdr = buf; + +- if (crc != ~crc32c_le(~0, buf, PPL_HEADER_SIZE)) { +- dprintf("Wrong PPL header checksum on %s\n", +- d->devname); +- ret = 1; +- } ++ crc = __le32_to_cpu(ppl_hdr->checksum); ++ ppl_hdr->checksum = 0; ++ ++ if (crc != ~crc32c_le(~0, buf, PPL_HEADER_SIZE)) { ++ dprintf("Wrong PPL header checksum on %s\n", ++ d->devname); ++ goto out; ++ } ++ ++ if (prev_gen_num > __le64_to_cpu(ppl_hdr->generation)) { ++ /* previous was newest, it was already checked */ ++ goto out; ++ } ++ ++ if ((__le32_to_cpu(ppl_hdr->signature) != ++ super->anchor->orig_family_num)) { ++ dprintf("Wrong PPL header signature on %s\n", ++ d->devname); ++ ret = 1; ++ goto out; ++ } ++ ++ ret = 0; ++ prev_gen_num = __le64_to_cpu(ppl_hdr->generation); + +- if (!ret && (__le32_to_cpu(ppl_hdr->signature) != +- super->anchor->orig_family_num)) { +- dprintf("Wrong PPL header signature on %s\n", +- d->devname); +- ret = 1; ++ ppl_offset += PPL_HEADER_SIZE; ++ for (i = 0; i < __le32_to_cpu(ppl_hdr->entries_count); i++) ++ ppl_offset += ++ __le32_to_cpu(ppl_hdr->entries[i].pp_size); + } + + out: +-- +2.7.4 + diff --git a/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch b/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch new file mode 100644 index 0000000..47d2093 --- /dev/null +++ b/SOURCES/imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch @@ -0,0 +1,35 @@ +From 2ec9d182ea5821ec2f7234ff3c0cf07ae9f43cb4 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Thu, 28 Sep 2017 14:41:18 +0200 +Subject: [PATCH 12/12] imsm: write initial ppl on a disk added for + rebuild + +When rebuild is initiated by the UEFI driver it is possible that the new +disk will not contain a valid ppl header. Just write the initial ppl +and don't abort assembly. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/super-intel.c b/super-intel.c +index cf5d822..536cb61 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6227,7 +6227,10 @@ out: + + if (map->map_state == IMSM_T_STATE_UNINITIALIZED || + (map->map_state == IMSM_T_STATE_NORMAL && +- !(dev->vol.dirty & RAIDVOL_DIRTY))) ++ !(dev->vol.dirty & RAIDVOL_DIRTY)) || ++ (dev->vol.migr_state == MIGR_REBUILD && ++ dev->vol.curr_migr_unit == 0 && ++ get_imsm_disk_idx(dev, disk->disk.raid_disk, MAP_1) != idx)) + ret = st->ss->write_init_ppl(st, info, d->fd); + else + info->mismatch_cnt++; +-- +2.7.4 + diff --git a/SOURCES/imsmadd-support-for-multiple-ppls.patch b/SOURCES/imsmadd-support-for-multiple-ppls.patch new file mode 100644 index 0000000..aafe19c --- /dev/null +++ b/SOURCES/imsmadd-support-for-multiple-ppls.patch @@ -0,0 +1,132 @@ +From c24620685185eb7a159a8563b60a5e062b03b12e Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:09 +0200 +Subject: [PATCH 03/12] imsm: Add support for multiple ppls + +Add interpreting new rwh_policy bits. Set PPL size as 1MB. +If new array with ppl is created - use new implementation of ppl by +default. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 37 +++++++++++++++++++++++++++---------- + 1 file changed, 27 insertions(+), 10 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index e3dcd3d..347838e 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -92,6 +92,9 @@ + #define NUM_BLOCKS_DIRTY_STRIPE_REGION 2056 + #define SECT_PER_MB_SHIFT 11 + #define MAX_SECTOR_SIZE 4096 ++#define MULTIPLE_PPL_AREA_SIZE_IMSM (1024 * 1024) /* Size of the whole ++ * mutliple PPL area ++ */ + + /* Disk configuration info. */ + #define IMSM_MAX_DEVICES 255 +@@ -207,6 +210,9 @@ struct imsm_dev { + #define RWH_OFF 0 + #define RWH_DISTRIBUTED 1 + #define RWH_JOURNALING_DRIVE 2 ++#define RWH_MULTIPLE_DISTRIBUTED 3 ++#define RWH_MULTIPLE_PPLS_JOURNALING_DRIVE 4 ++#define RWH_MULTIPLE_OFF 5 + __u8 rwh_policy; /* Raid Write Hole Policy */ + __u8 jd_serial[MAX_RAID_SERIAL_LEN]; /* Journal Drive serial number */ + __u8 filler1; +@@ -284,7 +290,7 @@ static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" + * already been migrated and must + * be recovered from checkpoint area */ + +-#define PPL_ENTRY_SPACE (128 * 1024) /* Size of the PPL, without the header */ ++#define PPL_ENTRY_SPACE (128 * 1024) /* Size of single PPL, without the header */ + + struct migr_record { + __u32 rec_status; /* Status used to determine how to restart +@@ -1539,12 +1545,16 @@ static void print_imsm_dev(struct intel_super *super, + printf(" Dirty State : %s\n", (dev->vol.dirty & RAIDVOL_DIRTY) ? + "dirty" : "clean"); + printf(" RWH Policy : "); +- if (dev->rwh_policy == RWH_OFF) ++ if (dev->rwh_policy == RWH_OFF || dev->rwh_policy == RWH_MULTIPLE_OFF) + printf("off\n"); + else if (dev->rwh_policy == RWH_DISTRIBUTED) + printf("PPL distributed\n"); + else if (dev->rwh_policy == RWH_JOURNALING_DRIVE) + printf("PPL journaling drive\n"); ++ else if (dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED) ++ printf("Multiple distributed PPLs\n"); ++ else if (dev->rwh_policy == RWH_MULTIPLE_PPLS_JOURNALING_DRIVE) ++ printf("Multiple PPLs on journaling drive\n"); + else + printf("\n", dev->rwh_policy); + } +@@ -3294,10 +3304,16 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, + memset(info->uuid, 0, sizeof(info->uuid)); + info->recovery_start = MaxSector; + +- if (info->array.level == 5 && dev->rwh_policy == RWH_DISTRIBUTED) { ++ if (info->array.level == 5 && ++ (dev->rwh_policy == RWH_DISTRIBUTED || ++ dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED)) { + info->consistency_policy = CONSISTENCY_POLICY_PPL; + info->ppl_sector = get_ppl_sector(super, super->current_vol); +- info->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9; ++ if (dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED) ++ info->ppl_size = MULTIPLE_PPL_AREA_SIZE_IMSM >> 9; ++ else ++ info->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) ++ >> 9; + } else if (info->array.level <= 0) { + info->consistency_policy = CONSISTENCY_POLICY_NONE; + } else { +@@ -5390,9 +5406,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + dev->my_vol_raid_dev_num = mpb->num_raid_devs_created; + + if (s->consistency_policy <= CONSISTENCY_POLICY_RESYNC) { +- dev->rwh_policy = RWH_OFF; ++ dev->rwh_policy = RWH_MULTIPLE_OFF; + } else if (s->consistency_policy == CONSISTENCY_POLICY_PPL) { +- dev->rwh_policy = RWH_DISTRIBUTED; ++ dev->rwh_policy = RWH_MULTIPLE_DISTRIBUTED; + } else { + free(dev); + free(dv); +@@ -7403,9 +7419,9 @@ static int update_subarray_imsm(struct supertype *st, char *subarray, + return 2; + + if (strcmp(update, "ppl") == 0) +- new_policy = RWH_DISTRIBUTED; ++ new_policy = RWH_MULTIPLE_DISTRIBUTED; + else +- new_policy = RWH_OFF; ++ new_policy = RWH_MULTIPLE_OFF; + + if (st->update_tail) { + struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u)); +@@ -8205,7 +8221,8 @@ skip_mark_checkpoint: + dev->vol.dirty = RAIDVOL_CLEAN; + } else { + dev->vol.dirty = RAIDVOL_DIRTY; +- if (dev->rwh_policy == RWH_DISTRIBUTED) ++ if (dev->rwh_policy == RWH_DISTRIBUTED || ++ dev->rwh_policy == RWH_MULTIPLE_DISTRIBUTED) + dev->vol.dirty |= RAIDVOL_DSRECORD_VALID; + } + super->updates_pending++; +@@ -8759,7 +8776,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a, + di->bb.supported = 1; + if (a->info.consistency_policy == CONSISTENCY_POLICY_PPL) { + di->ppl_sector = get_ppl_sector(super, inst); +- di->ppl_size = (PPL_HEADER_SIZE + PPL_ENTRY_SPACE) >> 9; ++ di->ppl_size = MULTIPLE_PPL_AREA_SIZE_IMSM >> 9; + } + super->random = random32(); + di->next = rv; +-- +2.7.4 + diff --git a/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch b/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch new file mode 100644 index 0000000..7db2c88 --- /dev/null +++ b/SOURCES/kernel-patch-Remove-obsolete-kernel-patches-against-.patch @@ -0,0 +1,395 @@ +From 2b7bddf06c30da08f8d6270b40f0d382c1c5fc6e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 4 May 2017 11:39:05 -0400 +Subject: [RHEL7.5 PATCH 107/169] kernel-patch: Remove obsolete kernel + patches against 2.6 + +While we still support some of these kernels, I do not think it makes +sense to carry this patches around at this point. + +Signed-off-by: Jes Sorensen +--- + kernel-patch-2.6.18 | 35 --------- + kernel-patch-2.6.18.6 | 35 --------- + kernel-patch-2.6.19 | 34 --------- + kernel-patch-2.6.25 | 199 -------------------------------------------------- + kernel-patch-2.6.27 | 36 --------- + 5 files changed, 339 deletions(-) + delete mode 100644 kernel-patch-2.6.18 + delete mode 100644 kernel-patch-2.6.18.6 + delete mode 100644 kernel-patch-2.6.19 + delete mode 100644 kernel-patch-2.6.25 + delete mode 100644 kernel-patch-2.6.27 + +diff --git a/kernel-patch-2.6.18 b/kernel-patch-2.6.18 +deleted file mode 100644 +index 87496ea..0000000 +--- a/kernel-patch-2.6.18 ++++ /dev/null +@@ -1,35 +0,0 @@ +- +-### Diffstat output +- ./drivers/md/md.c | 6 +++++- +- 1 file changed, 5 insertions(+), 1 deletion(-) +- +-diff .prev/drivers/md/md.c ./drivers/md/md.c +---- .prev/drivers/md/md.c 2006-10-23 10:26:37.000000000 +1000 +-+++ ./drivers/md/md.c 2006-12-21 16:28:29.000000000 +1100 +-@@ -1783,7 +1783,8 @@ state_store(mdk_rdev_t *rdev, const char +- else { +- mddev_t *mddev = rdev->mddev; +- kick_rdev_from_array(rdev); +-- md_update_sb(mddev); +-+ if (mddev->pers) +-+ md_update_sb(mddev); +- md_new_event(mddev); +- err = 0; +- } +-@@ -1994,6 +1995,8 @@ static mdk_rdev_t *md_import_device(dev_ +- kobject_init(&rdev->kobj); +- +- rdev->desc_nr = -1; +-+ rdev->saved_raid_disk = -1; +-+ rdev->raid_disk = -1; +- rdev->flags = 0; +- rdev->data_offset = 0; +- rdev->sb_events = 0; +-@@ -3991,6 +3994,7 @@ static int set_array_info(mddev_t * mdde +- mddev->major_version = info->major_version; +- mddev->minor_version = info->minor_version; +- mddev->patch_version = info->patch_version; +-+ mddev->persistent = ! info->not_persistent; +- return 0; +- } +- mddev->major_version = MD_MAJOR_VERSION; +diff --git a/kernel-patch-2.6.18.6 b/kernel-patch-2.6.18.6 +deleted file mode 100644 +index e702e14..0000000 +--- a/kernel-patch-2.6.18.6 ++++ /dev/null +@@ -1,35 +0,0 @@ +-Signed-off-by: Neil Brown +- +-### Diffstat output +- ./drivers/md/md.c | 5 ++++- +- 1 file changed, 4 insertions(+), 1 deletion(-) +- +-diff .prev/drivers/md/md.c ./drivers/md/md.c +---- .prev/drivers/md/md.c 2006-12-21 17:08:23.000000000 +1100 +-+++ ./drivers/md/md.c 2006-12-21 17:08:26.000000000 +1100 +-@@ -1783,7 +1783,8 @@ state_store(mdk_rdev_t *rdev, const char +- else { +- mddev_t *mddev = rdev->mddev; +- kick_rdev_from_array(rdev); +-- md_update_sb(mddev); +-+ if (mddev->pers) +-+ md_update_sb(mddev); +- md_new_event(mddev); +- err = 0; +- } +-@@ -1995,6 +1996,7 @@ static mdk_rdev_t *md_import_device(dev_ +- +- rdev->desc_nr = -1; +- rdev->saved_raid_disk = -1; +-+ rdev->raid_disk = -1; +- rdev->flags = 0; +- rdev->data_offset = 0; +- rdev->sb_events = 0; +-@@ -3993,6 +3995,7 @@ static int set_array_info(mddev_t * mdde +- mddev->major_version = info->major_version; +- mddev->minor_version = info->minor_version; +- mddev->patch_version = info->patch_version; +-+ mddev->persistent = ! info->not_persistent; +- return 0; +- } +- mddev->major_version = MD_MAJOR_VERSION; +diff --git a/kernel-patch-2.6.19 b/kernel-patch-2.6.19 +deleted file mode 100644 +index 22a67a3..0000000 +--- a/kernel-patch-2.6.19 ++++ /dev/null +@@ -1,34 +0,0 @@ +- +-### Diffstat output +- ./drivers/md/md.c | 5 ++++- +- 1 file changed, 4 insertions(+), 1 deletion(-) +- +-diff .prev/drivers/md/md.c ./drivers/md/md.c +---- .prev/drivers/md/md.c 2006-12-21 15:55:01.000000000 +1100 +-+++ ./drivers/md/md.c 2006-12-21 16:28:09.000000000 +1100 +-@@ -1792,7 +1792,8 @@ state_store(mdk_rdev_t *rdev, const char +- else { +- mddev_t *mddev = rdev->mddev; +- kick_rdev_from_array(rdev); +-- md_update_sb(mddev, 1); +-+ if (mddev->pers) +-+ md_update_sb(mddev, 1); +- md_new_event(mddev); +- err = 0; +- } +-@@ -2004,6 +2005,7 @@ static mdk_rdev_t *md_import_device(dev_ +- +- rdev->desc_nr = -1; +- rdev->saved_raid_disk = -1; +-+ rdev->raid_disk = -1; +- rdev->flags = 0; +- rdev->data_offset = 0; +- rdev->sb_events = 0; +-@@ -3977,6 +3979,7 @@ static int set_array_info(mddev_t * mdde +- mddev->major_version = info->major_version; +- mddev->minor_version = info->minor_version; +- mddev->patch_version = info->patch_version; +-+ mddev->persistent = ! info->not_persistent; +- return 0; +- } +- mddev->major_version = MD_MAJOR_VERSION; +diff --git a/kernel-patch-2.6.25 b/kernel-patch-2.6.25 +deleted file mode 100644 +index 2329007..0000000 +--- a/kernel-patch-2.6.25 ++++ /dev/null +@@ -1,199 +0,0 @@ +-Status: ok +- +-Support adding a spare to a live md array with external metadata. +- +-i.e. extend the 'md/dev-XXX/slot' attribute so that you can +-tell a device to fill an vacant slot in an and md array. +- +- +-Signed-off-by: Neil Brown +- +-### Diffstat output +- ./drivers/md/md.c | 44 ++++++++++++++++++++++++++++++++++++++++---- +- ./drivers/md/multipath.c | 7 ++++++- +- ./drivers/md/raid1.c | 7 ++++++- +- ./drivers/md/raid10.c | 10 ++++++++-- +- ./drivers/md/raid5.c | 10 ++++++++-- +- 5 files changed, 68 insertions(+), 10 deletions(-) +- +-diff .prev/drivers/md/md.c ./drivers/md/md.c +---- .prev/drivers/md/md.c 2008-06-05 09:19:56.000000000 +1000 +-+++ ./drivers/md/md.c 2008-06-10 10:41:21.000000000 +1000 +-@@ -1932,7 +1932,7 @@ slot_store(mdk_rdev_t *rdev, const char +- slot = -1; +- else if (e==buf || (*e && *e!= '\n')) +- return -EINVAL; +-- if (rdev->mddev->pers) { +-+ if (rdev->mddev->pers && slot == -1) { +- /* Setting 'slot' on an active array requires also +- * updating the 'rd%d' link, and communicating +- * with the personality with ->hot_*_disk. +-@@ -1940,8 +1940,6 @@ slot_store(mdk_rdev_t *rdev, const char +- * failed/spare devices. This normally happens automatically, +- * but not when the metadata is externally managed. +- */ +-- if (slot != -1) +-- return -EBUSY; +- if (rdev->raid_disk == -1) +- return -EEXIST; +- /* personality does all needed checks */ +-@@ -1955,6 +1953,44 @@ slot_store(mdk_rdev_t *rdev, const char +- sysfs_remove_link(&rdev->mddev->kobj, nm); +- set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); +- md_wakeup_thread(rdev->mddev->thread); +-+ } else if (rdev->mddev->pers) { +-+ mdk_rdev_t *rdev2; +-+ struct list_head *tmp; +-+ /* Activating a spare .. or possibly reactivating +-+ * if we every get bitmaps working here. +-+ */ +-+ +-+ if (rdev->raid_disk != -1) +-+ return -EBUSY; +-+ +-+ if (rdev->mddev->pers->hot_add_disk == NULL) +-+ return -EINVAL; +-+ +-+ rdev_for_each(rdev2, tmp, rdev->mddev) +-+ if (rdev2->raid_disk == slot) +-+ return -EEXIST; +-+ +-+ rdev->raid_disk = slot; +-+ if (test_bit(In_sync, &rdev->flags)) +-+ rdev->saved_raid_disk = slot; +-+ else +-+ rdev->saved_raid_disk = -1; +-+ err = rdev->mddev->pers-> +-+ hot_add_disk(rdev->mddev, rdev); +-+ if (err != 1) { +-+ rdev->raid_disk = -1; +-+ if (err == 0) +-+ return -EEXIST; +-+ return err; +-+ } +-+ sprintf(nm, "rd%d", rdev->raid_disk); +-+ if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) +-+ printk(KERN_WARNING +-+ "md: cannot register " +-+ "%s for %s\n", +-+ nm, mdname(rdev->mddev)); +-+ +-+ /* don't wakeup anyone, leave that to userspace. */ +- } else { +- if (slot >= rdev->mddev->raid_disks) +- return -ENOSPC; +-@@ -4205,7 +4241,7 @@ static int add_new_disk(mddev_t * mddev, +- super_types[mddev->major_version]. +- validate_super(mddev, rdev); +- err = mddev->pers->hot_add_disk(mddev, rdev); +-- if (err) +-+ if (err < 0) +- unbind_rdev_from_array(rdev); +- } +- if (err) +- +-diff .prev/drivers/md/multipath.c ./drivers/md/multipath.c +---- .prev/drivers/md/multipath.c 2008-05-30 14:49:31.000000000 +1000 +-+++ ./drivers/md/multipath.c 2008-06-10 10:35:03.000000000 +1000 +-@@ -284,10 +284,15 @@ static int multipath_add_disk(mddev_t *m +- int found = 0; +- int path; +- struct multipath_info *p; +-+ int first = 0; +-+ int last = mddev->raid_disks - 1; +-+ +-+ if (rdev->raid_disk >= 0) +-+ first = last = rdev->raid_disk; +- +- print_multipath_conf(conf); +- +-- for (path=0; pathraid_disks; path++) +-+ for (path = first; path <= last; path++) +- if ((p=conf->multipaths+path)->rdev == NULL) { +- q = rdev->bdev->bd_disk->queue; +- blk_queue_stack_limits(mddev->queue, q); +- +-diff .prev/drivers/md/raid10.c ./drivers/md/raid10.c +---- .prev/drivers/md/raid10.c 2008-05-30 14:49:31.000000000 +1000 +-+++ ./drivers/md/raid10.c 2008-06-10 10:28:53.000000000 +1000 +-@@ -1116,6 +1116,8 @@ static int raid10_add_disk(mddev_t *mdde +- int found = 0; +- int mirror; +- mirror_info_t *p; +-+ int first = 0; +-+ int last = mddev->raid_disks - 1; +- +- if (mddev->recovery_cp < MaxSector) +- /* only hot-add to in-sync arrays, as recovery is +-@@ -1125,12 +1127,16 @@ static int raid10_add_disk(mddev_t *mdde +- if (!enough(conf)) +- return 0; +- +-+ if (rdev->raid_disk) +-+ first = last = rdev->raid_disk; +-+ +- if (rdev->saved_raid_disk >= 0 && +-+ rdev->saved_raid_disk >= first && +- conf->mirrors[rdev->saved_raid_disk].rdev == NULL) +- mirror = rdev->saved_raid_disk; +- else +-- mirror = 0; +-- for ( ; mirror < mddev->raid_disks; mirror++) +-+ mirror = first; +-+ for ( ; mirror <= last ; mirror++) +- if ( !(p=conf->mirrors+mirror)->rdev) { +- +- blk_queue_stack_limits(mddev->queue, +- +-diff .prev/drivers/md/raid1.c ./drivers/md/raid1.c +---- .prev/drivers/md/raid1.c 2008-05-30 14:49:31.000000000 +1000 +-+++ ./drivers/md/raid1.c 2008-06-10 10:41:00.000000000 +1000 +-@@ -1103,8 +1103,13 @@ static int raid1_add_disk(mddev_t *mddev +- int found = 0; +- int mirror = 0; +- mirror_info_t *p; +-+ int first = 0; +-+ int last = mddev->raid_disks - 1; +- +-- for (mirror=0; mirror < mddev->raid_disks; mirror++) +-+ if (rdev->raid_disk >= 0) +-+ first = last = rdev->raid_disk; +-+ +-+ for (mirror = first; mirror <= last; mirror++) +- if ( !(p=conf->mirrors+mirror)->rdev) { +- +- blk_queue_stack_limits(mddev->queue, +- +-diff .prev/drivers/md/raid5.c ./drivers/md/raid5.c +---- .prev/drivers/md/raid5.c 2008-05-30 14:49:35.000000000 +1000 +-+++ ./drivers/md/raid5.c 2008-06-10 10:27:51.000000000 +1000 +-@@ -4399,21 +4399,27 @@ static int raid5_add_disk(mddev_t *mddev +- int found = 0; +- int disk; +- struct disk_info *p; +-+ int first = 0; +-+ int last = conf->raid_disks - 1; +- +- if (mddev->degraded > conf->max_degraded) +- /* no point adding a device */ +- return 0; +- +-+ if (rdev->raid_disk >= 0) +-+ first = last = rdev->raid_disk; +-+ +- /* +- * find the disk ... but prefer rdev->saved_raid_disk +- * if possible. +- */ +- if (rdev->saved_raid_disk >= 0 && +-+ rdev->saved_raid_disk >= first && +- conf->disks[rdev->saved_raid_disk].rdev == NULL) +- disk = rdev->saved_raid_disk; +- else +-- disk = 0; +-- for ( ; disk < conf->raid_disks; disk++) +-+ disk = first; +-+ for ( ; disk <= last ; disk++) +- if ((p=conf->disks + disk)->rdev == NULL) { +- clear_bit(In_sync, &rdev->flags); +- rdev->raid_disk = disk; +diff --git a/kernel-patch-2.6.27 b/kernel-patch-2.6.27 +deleted file mode 100644 +index 8d0785d..0000000 +--- a/kernel-patch-2.6.27 ++++ /dev/null +@@ -1,36 +0,0 @@ +-touch_mnt_namespace when the mount flags change +- +-From: Dan Williams +- +-Daemons that need to be launched while the rootfs is read-only can now +-poll /proc/mounts to be notified when their O_RDWR requests may no +-longer end in EROFS. +- +-Cc: Kay Sievers +-Cc: Neil Brown +-Signed-off-by: Dan Williams +---- +- +- fs/namespace.c | 7 ++++++- +- 1 files changed, 6 insertions(+), 1 deletions(-) +- +- +-diff --git a/fs/namespace.c b/fs/namespace.c +-index 6e283c9..1bd5ba2 100644 +---- a/fs/namespace.c +-+++ b/fs/namespace.c +-@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, +- if (!err) +- nd->path.mnt->mnt_flags = mnt_flags; +- up_write(&sb->s_umount); +-- if (!err) +-+ if (!err) { +- security_sb_post_remount(nd->path.mnt, flags, data); +-+ +-+ spin_lock(&vfsmount_lock); +-+ touch_mnt_namespace(nd->path.mnt->mnt_ns); +-+ spin_unlock(&vfsmount_lock); +-+ } +- return err; +- } +- +-- +2.7.4 + diff --git a/SOURCES/lib-devid2kname-should-take-a-dev_t.patch b/SOURCES/lib-devid2kname-should-take-a-dev_t.patch new file mode 100644 index 0000000..89c1617 --- /dev/null +++ b/SOURCES/lib-devid2kname-should-take-a-dev_t.patch @@ -0,0 +1,52 @@ +From d3c40faba807e3c7a63c5fe34de52bf753c88b2d Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 29 Sep 2017 17:54:12 -0400 +Subject: [RHEL7.5 PATCH 10/13] lib: devid2kname() should take a dev_t + +Make devid2kname() and devid2devnm() consistent in their APIs + +Signed-off-by: Jes Sorensen +--- + lib.c | 5 ++--- + mdadm.h | 2 +- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/lib.c b/lib.c +index be093e8..60890b9 100644 +--- a/lib.c ++++ b/lib.c +@@ -61,7 +61,7 @@ int get_mdp_major(void) + return mdp_major; + } + +-char *devid2kname(int devid) ++char *devid2kname(dev_t devid) + { + char path[30]; + char link[PATH_MAX]; +@@ -73,8 +73,7 @@ char *devid2kname(int devid) + * /sys/dev/block/%d:%d link which must look like + * and take the last component. + */ +- sprintf(path, "/sys/dev/block/%d:%d", major(devid), +- minor(devid)); ++ sprintf(path, "/sys/dev/block/%d:%d", major(devid), minor(devid)); + n = readlink(path, link, sizeof(link) - 1); + if (n > 0) { + link[n] = 0; +diff --git a/mdadm.h b/mdadm.h +index 191ae8f..db08188 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1537,7 +1537,7 @@ extern void print_r10_layout(int layout); + extern char *find_free_devnm(int use_partitions); + + extern void put_md_name(char *name); +-extern char *devid2kname(int devid); ++extern char *devid2kname(dev_t devid); + extern char *devid2devnm(dev_t devid); + extern dev_t devnm2devid(char *devnm); + extern char *get_md_name(char *devnm); +-- +2.7.4 + diff --git a/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch b/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch new file mode 100644 index 0000000..c2ed2bf --- /dev/null +++ b/SOURCES/managemon-Dont-add-disk-to-the-array-after-it.patch @@ -0,0 +1,61 @@ +commit a44c262abc49b3c69ee80c97813388e5d021d20b +Author: Tomasz Majchrzak +Date: Thu Dec 7 10:23:54 2017 +0100 + + managemon: Don't add disk to the array after it has started + + If disk has disappeared from the system and appears again, it is added to the + corresponding container as long the metadata matches and disk number is set. + This code had no effect on imsm until commit 20dc76d15b40 ("imsm: Set disk slot + number"). Now the disk is added to container but not to the array - it is + correct as the disk is out-of-sync. Rebuild should start for the disk but it + doesn't. There is the same behaviour for both imsm and ddf metadata. + + There is no point to handle out-of-sync disk as "good member of array" so + remove that part of code. There are no scenarios when monitor is already + running and disk can be safely added to the array. Just write initial metadata + to the disk so it's taken for rebuild. + + Signed-off-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/managemon.c b/managemon.c +index 4e85398..101231c 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -266,9 +266,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd) + { + int dfd; + char nm[20]; +- struct supertype *st2; + struct metadata_update *update = NULL; +- struct mdinfo info; + mdu_disk_info_t dk = { + .number = -1, + .major = sd->disk.major, +@@ -287,25 +285,6 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd) + if (dfd < 0) + return; + +- /* Check the metadata and see if it is already part of this +- * array +- */ +- st2 = dup_super(st); +- if (st2->ss->load_super(st2, dfd, NULL) == 0) { +- st2->ss->getinfo_super(st2, &info, NULL); +- if (st->ss->compare_super(st, st2) == 0 && +- info.disk.raid_disk >= 0) { +- /* Looks like a good member of array. +- * Just accept it. +- * mdadm will incorporate any parts into +- * active arrays. +- */ +- st2->ss->free_super(st2); +- return; +- } +- } +- st2->ss->free_super(st2); +- + st->update_tail = &update; + st->ss->add_to_super(st, &dk, dfd, NULL, INVALID_SECTORS); + st->ss->write_init_super(st); diff --git a/SOURCES/manpage-badblock-support-for-IMSM.patch b/SOURCES/manpage-badblock-support-for-IMSM.patch new file mode 100644 index 0000000..33b710b --- /dev/null +++ b/SOURCES/manpage-badblock-support-for-IMSM.patch @@ -0,0 +1,29 @@ +From 8fac4a54cbafdd8e0a6a0c0b3ce87f1bcdef3d9d Mon Sep 17 00:00:00 2001 +From: Tomasz Majchrzak +Date: Thu, 18 May 2017 15:14:49 +0200 +Subject: [RHEL7.5 PATCH 146/169] manpage: bad block support for IMSM + +Signed-off-by: Tomasz Majchrzak +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 388e0ed..ecfe9da 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -2211,8 +2211,8 @@ option. In any case 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 metadata), space +-will be allocated to store a bad block list. This allows a modest ++If the metadata type supports it (currently only 1.x and IMSM metadata), ++space will be allocated to store a bad block list. This allows a modest + number of bad blocks to be recorded, allowing the drive to remain in + service while only partially functional. + +-- +2.7.4 + diff --git a/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch b/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch new file mode 100644 index 0000000..1de54bd --- /dev/null +++ b/SOURCES/maps-Remove-incorrect-comment-about-strcmp.patch @@ -0,0 +1,29 @@ +From 966188e959ec198889bec6d2f9dac34bff97478f Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 21 Apr 2017 12:09:12 -0400 +Subject: [RHEL7.5 PATCH 092/169] maps: Remove incorrect comment about + strcmp() + +Signed-off-by: Jes Sorensen +--- + maps.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/maps.c b/maps.c +index 11dd3d2..81f29c4 100644 +--- a/maps.c ++++ b/maps.c +@@ -141,10 +141,6 @@ mapping_t consistency_policies[] = { + }; + + mapping_t sysfs_array_states[] = { +- /* +- * Beware map_name() uses strcmp() so active-idle must come before +- * active, to be detected correctly. +- */ + { "active-idle", ARRAY_ACTIVE_IDLE }, + { "active", ARRAY_ACTIVE }, + { "clear", ARRAY_CLEAR }, +-- +2.7.4 + diff --git a/SOURCES/maps-Simplify-implementation-of-map_name.patch b/SOURCES/maps-Simplify-implementation-of-map_name.patch new file mode 100644 index 0000000..6c458e4 --- /dev/null +++ b/SOURCES/maps-Simplify-implementation-of-map_name.patch @@ -0,0 +1,32 @@ +From 4a4379b054a72b3c4abd93dd6e1283d6aa992ee2 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 21 Apr 2017 12:11:21 -0400 +Subject: [RHEL7.5 PATCH 093/169] maps: Simplify implementation of + map_name() + +Reported-By: NeilBrown +Signed-off-by: Jes Sorensen +--- + maps.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/maps.c b/maps.c +index 81f29c4..bb28ba6 100644 +--- a/maps.c ++++ b/maps.c +@@ -165,11 +165,8 @@ char *map_num(mapping_t *map, int num) + + int map_name(mapping_t *map, char *name) + { +- while (map->name) { +- if (strcmp(map->name, name)==0) +- return map->num; ++ while (map->name && strcmp(map->name, name) != 0) + map++; +- } + + return map->num; + } +-- +2.7.4 + diff --git a/SOURCES/maps-Terminate-modes-map-correctly.patch b/SOURCES/maps-Terminate-modes-map-correctly.patch new file mode 100644 index 0000000..8be6f4b --- /dev/null +++ b/SOURCES/maps-Terminate-modes-map-correctly.patch @@ -0,0 +1,28 @@ +From e47781fcea24778a16e4be53e5b84eab8db9413c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 20 Apr 2017 00:13:31 -0400 +Subject: [RHEL7.5 PATCH 083/169] maps: Terminate 'modes' map correctly. + +While we are unlikely to fail here, terminate the modes map correctly +to ensure we don't start running over undefined data. + +Signed-off-by: Jes Sorensen +--- + maps.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/maps.c b/maps.c +index a8a4639..a2d293b 100644 +--- a/maps.c ++++ b/maps.c +@@ -106,6 +106,7 @@ mapping_t modes[] = { + { "grow", GROW}, + { "incremental", INCREMENTAL}, + { "auto-detect", AUTODETECT}, ++ { NULL, 0 } + }; + + mapping_t faultylayout[] = { +-- +2.7.4 + diff --git a/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch b/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch new file mode 100644 index 0000000..2b8d89a --- /dev/null +++ b/SOURCES/maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch @@ -0,0 +1,106 @@ +From 5e8e35fb7e17495032e144f319517dcae38d1b56 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 20 Apr 2017 00:19:44 -0400 +Subject: [RHEL7.5 PATCH 084/169] maps: Use keyvalue for null terminator to + indicate 'unset' value + +This simplifies the code calling map_name() so it no longer has to +manually check for UnSet and convert the value manually. + +Signed-off-by: Jes Sorensen +--- + maps.c | 17 +++++++++-------- + sysfs.c | 2 -- + 2 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/maps.c b/maps.c +index a2d293b..11dd3d2 100644 +--- a/maps.c ++++ b/maps.c +@@ -44,7 +44,7 @@ mapping_t r5layout[] = { + { "ddf-N-restart", ALGORITHM_LEFT_ASYMMETRIC}, + { "ddf-N-continue", ALGORITHM_LEFT_SYMMETRIC}, + +- { NULL, 0} ++ { NULL, UnSet } + }; + mapping_t r6layout[] = { + { "left-asymmetric", ALGORITHM_LEFT_ASYMMETRIC}, +@@ -70,7 +70,7 @@ mapping_t r6layout[] = { + { "right-symmetric-6", ALGORITHM_RIGHT_SYMMETRIC_6}, + { "parity-first-6", ALGORITHM_PARITY_0_6}, + +- { NULL, 0} ++ { NULL, UnSet } + }; + + mapping_t pers[] = { +@@ -93,7 +93,7 @@ mapping_t pers[] = { + { "10", 10}, + { "faulty", LEVEL_FAULTY}, + { "container", LEVEL_CONTAINER}, +- { NULL, 0} ++ { NULL, UnSet } + }; + + mapping_t modes[] = { +@@ -106,7 +106,7 @@ mapping_t modes[] = { + { "grow", GROW}, + { "incremental", INCREMENTAL}, + { "auto-detect", AUTODETECT}, +- { NULL, 0 } ++ { NULL, UnSet } + }; + + mapping_t faultylayout[] = { +@@ -127,7 +127,7 @@ mapping_t faultylayout[] = { + { "flush", ClearFaults}, + { "none", ClearErrors}, + { "default", ClearErrors}, +- { NULL, 0} ++ { NULL, UnSet } + }; + + mapping_t consistency_policies[] = { +@@ -137,7 +137,7 @@ mapping_t consistency_policies[] = { + { "bitmap", CONSISTENCY_POLICY_BITMAP}, + { "journal", CONSISTENCY_POLICY_JOURNAL}, + { "ppl", CONSISTENCY_POLICY_PPL}, +- { NULL, 0} ++ { NULL, UnSet } + }; + + mapping_t sysfs_array_states[] = { +@@ -154,7 +154,7 @@ mapping_t sysfs_array_states[] = { + { "read-auto", ARRAY_READ_AUTO }, + { "clean", ARRAY_CLEAN }, + { "write-pending", ARRAY_WRITE_PENDING }, +- { NULL, 0 } ++ { NULL, ARRAY_UNKNOWN_STATE } + }; + + char *map_num(mapping_t *map, int num) +@@ -174,5 +174,6 @@ int map_name(mapping_t *map, char *name) + return map->num; + map++; + } +- return UnSet; ++ ++ return map->num; + } +diff --git a/sysfs.c b/sysfs.c +index c6df9b0..712f8b3 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -250,8 +250,6 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + if (load_sys(fname, buf, sizeof(buf))) + goto abort; + sra->array_state = map_name(sysfs_array_states, buf); +- if (sra->array_state == UnSet) +- sra->array_state = ARRAY_UNKNOWN_STATE; + } + + if (options & GET_CONSISTENCY_POLICY) { +-- +2.7.4 + diff --git a/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch b/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch new file mode 100644 index 0000000..2c580c6 --- /dev/null +++ b/SOURCES/md_u-Remove-some-unused-ioctl-declarations.patch @@ -0,0 +1,40 @@ +From b0ba6a1dee995b3cd7331b4df92d115e51d8ac0c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 15:48:24 -0400 +Subject: [RHEL7.5 PATCH 041/169] md_u: Remove some unused ioctl + declarations + +These were no longer used in the code, so get rid of them. + +Signed-off-by: Jes Sorensen +--- + md_u.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/md_u.h b/md_u.h +index f570a34..d59aa2d 100644 +--- a/md_u.h ++++ b/md_u.h +@@ -21,19 +21,13 @@ + #define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t) + #define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t) + #define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t) +-#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13) + #define RAID_AUTORUN _IO (MD_MAJOR, 0x14) + #define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t) + + /* configuration */ +-#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20) + #define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t) + #define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22) + #define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t) +-#define SET_DISK_INFO _IO (MD_MAJOR, 0x24) +-#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25) +-#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26) +-#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27) + #define HOT_ADD_DISK _IO (MD_MAJOR, 0x28) + #define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29) + #define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int) +-- +2.7.4 + diff --git a/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch b/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch new file mode 100644 index 0000000..4e17568 --- /dev/null +++ b/SOURCES/md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch @@ -0,0 +1,31 @@ +From ea1c4a8722605da9c2ce5dd1a8324b4f23a34b7a Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 31 May 2017 19:38:36 +0800 +Subject: [RHEL7.5 PATCH 149/169] md_u: Remove unused ioctl declaration of + START_ARRAY + +START_ARRAY is no longer used in the code, so get rid of it. +MD commit: fbedac04fa11 ("[PATCH] md: the scheduled removal +of the START_ARRAY ioctl for md") merged in the year 2006. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + md_u.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/md_u.h b/md_u.h +index d59aa2d..2d66d52 100644 +--- a/md_u.h ++++ b/md_u.h +@@ -34,7 +34,6 @@ + + /* usage */ + #define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t) +-#define START_ARRAY _IO (MD_MAJOR, 0x31) + #define STOP_ARRAY _IO (MD_MAJOR, 0x32) + #define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33) + #define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34) +-- +2.7.4 + diff --git a/SOURCES/mdadm-3.3-udev.patch b/SOURCES/mdadm-3.3-udev.patch index 1dfac7b..8483d5c 100644 --- a/SOURCES/mdadm-3.3-udev.patch +++ b/SOURCES/mdadm-3.3-udev.patch @@ -1,5 +1,5 @@ ---- mdadm-3.3.1/udev-md-raid-assembly.rules~ 2014-06-10 13:29:41.192829830 +0200 -+++ mdadm-3.3.1/udev-md-raid-assembly.rules 2014-06-10 13:30:20.838613208 +0200 +--- mdadm/udev-md-raid-assembly.rules~ 2017-09-19 11:22:49.912766829 +0800 ++++ mdadm/udev-md-raid-assembly.rules 2017-09-19 11:23:23.951809560 +0800 @@ -5,6 +5,10 @@ ENV{ANACONDA}=="?*", GOTO="md_inc_end" # assemble md arrays @@ -10,4 +10,4 @@ + SUBSYSTEM!="block", GOTO="md_inc_end" - # handle potential components of arrays (the ones supported by md) + # skip non-initialized devices diff --git a/SOURCES/mdadm-3.3.2-skip-rules.patch b/SOURCES/mdadm-3.3.2-skip-rules.patch index ee43d23..da7794a 100644 --- a/SOURCES/mdadm-3.3.2-skip-rules.patch +++ b/SOURCES/mdadm-3.3.2-skip-rules.patch @@ -1,11 +1,11 @@ ---- mdadm-3.4/Makefile~ 2016-02-01 22:59:47.327994011 +0800 -+++ mdadm-3.4/Makefile 2016-02-02 10:18:51.165377518 +0800 -@@ -292,7 +292,7 @@ +--- mdadm/Makefile~ 2017-09-19 11:09:05.788484060 +0800 ++++ mdadm/Makefile 2017-09-19 11:09:26.956482310 +0800 +@@ -257,7 +257,7 @@ $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 - install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules -- @for file in 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \ -+ @for file in 63-md-raid-arrays.rules ; \ + install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid-creating.rules +- @for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules ; \ ++ @for file in 01-md-raid-creating.rules 63-md-raid-arrays.rules ; \ do sed -e 's,BINDIR,$(BINDIR),g' udev-$${file#??-} > .install.tmp.1 && \ $(ECHO) $(INSTALL) -D -m 644 udev-$${file#??-} $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \ $(INSTALL) -D -m 644 .install.tmp.1 $(DESTDIR)$(UDEVDIR)/rules.d/$$file ; \ diff --git a/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch b/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch new file mode 100644 index 0000000..4615fab --- /dev/null +++ b/SOURCES/mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch @@ -0,0 +1,37 @@ +From 8268821b434d1308d083454fb681d80176cf352b Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 17 Mar 2017 19:55:42 +0800 +Subject: [RHEL7.5 PATCH 009/169] mdadm: Add Wimplicit-fallthrough=0 in + Makefile + +There are many errors like 'error: this statement may fall through'. +But the logic is right. So add the flag Wimplicit-fallthrough=0 +to disable the error messages. The method I use is from +https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html +#index-Wimplicit-fallthrough-375 + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + Makefile | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Makefile b/Makefile +index a6f464c..d1a6ac4 100644 +--- a/Makefile ++++ b/Makefile +@@ -48,6 +48,11 @@ ifdef WARN_UNUSED + CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 + endif + ++FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l) ++ifneq "$(FALLTHROUGH)" "0" ++CWFLAGS += -Wimplicit-fallthrough=0 ++endif ++ + ifdef DEBIAN + CPPFLAGS += -DDEBIAN + endif +-- +2.7.4 + diff --git a/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch b/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch new file mode 100644 index 0000000..b2ea514 --- /dev/null +++ b/SOURCES/mdadm-Build1-check-the-level-parameter-when-build-new.patch @@ -0,0 +1,34 @@ +From 1b4944f3a1e135871437cc33c26539028e6da5d6 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Tue, 28 Mar 2017 21:52:27 +0800 +Subject: [RHEL7.5 PATCH 021/169] mdadm/Build:check the level parameter + when build new array + +check if user forgets to specify the --level +when build a new array. such as: +./mdadm -B /dev/md0 -n2 /dev/loop[0-1] + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Build.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Build.c b/Build.c +index 74a440e..a5fcc06 100644 +--- a/Build.c ++++ b/Build.c +@@ -56,6 +56,10 @@ int Build(char *mddev, struct mddev_dev *devlist, + int uuid[4] = {0,0,0,0}; + struct map_ent *map = NULL; + ++ if (s->level == UnSet) { ++ pr_err("a RAID level is needed to Build an array.\n"); ++ return 1; ++ } + /* scan all devices, make sure they really are block devices */ + for (dv = devlist; dv; dv=dv->next) { + subdevs++; +-- +2.7.4 + diff --git a/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch b/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch new file mode 100644 index 0000000..d09f733 --- /dev/null +++ b/SOURCES/mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch @@ -0,0 +1,80 @@ +From ed1809969802ba03be0a33b7cd9f0ea85c7a42aa Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 11:55:19 -0400 +Subject: [RHEL7.5 PATCH 033/169] mdadm: Clean up some ugly multiple + actions on single line + +'foo(); continue;' on the same line within a switch statement is +always wrong. Get rid of some of it. + +Signed-off-by: Jes Sorensen +--- + mdadm.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index 5ebf117..502e721 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1928,16 +1928,21 @@ static int misc_list(struct mddev_dev *devlist, + } + continue; + case 'Q': +- rv |= Query(dv->devname); continue; ++ rv |= Query(dv->devname); ++ continue; + case 'X': +- rv |= ExamineBitmap(dv->devname, c->brief, ss); continue; ++ rv |= ExamineBitmap(dv->devname, c->brief, ss); ++ continue; + case ExamineBB: +- rv |= ExamineBadblocks(dv->devname, c->brief, ss); continue; ++ rv |= ExamineBadblocks(dv->devname, c->brief, ss); ++ continue; + case 'W': + case WaitOpt: +- rv |= Wait(dv->devname); continue; ++ rv |= Wait(dv->devname); ++ continue; + case Waitclean: +- rv |= WaitClean(dv->devname, -1, c->verbose); continue; ++ rv |= WaitClean(dv->devname, -1, c->verbose); ++ continue; + case KillSubarray: + rv |= Kill_subarray(dv->devname, c->subarray, c->verbose); + continue; +@@ -1964,7 +1969,8 @@ static int misc_list(struct mddev_dev *devlist, + switch(dv->devname[0] == '/') { + case 0: + mdfd = open_dev(dv->devname); +- if (mdfd >= 0) break; ++ if (mdfd >= 0) ++ break; + case 1: + mdfd = open_mddev(dv->devname, 1); + } +@@ -1972,13 +1978,17 @@ static int misc_list(struct mddev_dev *devlist, + switch(dv->disposition) { + case 'R': + c->runstop = 1; +- rv |= Manage_run(dv->devname, mdfd, c); break; ++ rv |= Manage_run(dv->devname, mdfd, c); ++ break; + case 'S': +- rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break; ++ rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); ++ break; + case 'o': +- rv |= Manage_ro(dv->devname, mdfd, 1); break; ++ rv |= Manage_ro(dv->devname, mdfd, 1); ++ break; + case 'w': +- rv |= Manage_ro(dv->devname, mdfd, -1); break; ++ rv |= Manage_ro(dv->devname, mdfd, -1); ++ break; + } + close(mdfd); + } else +-- +2.7.4 + diff --git a/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch b/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch new file mode 100644 index 0000000..2c8349c --- /dev/null +++ b/SOURCES/mdadm-Create-declaring1-an-existing-struct-within-sam.patch @@ -0,0 +1,56 @@ +From 230a0dde0926125b8895e02a669b4701f79c0f07 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Sat, 1 Apr 2017 20:51:44 +0800 +Subject: [RHEL7.5 PATCH 049/169] mdadm/Create: declaring an existing + struct within same function + +Create:declaring 'struct stat stb' twice within the same +function, rename stb as stb2 when declares 'struct stat' +at the second time. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Create.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Create.c b/Create.c +index 32987af..ba24606 100644 +--- a/Create.c ++++ b/Create.c +@@ -868,7 +868,7 @@ int Create(struct supertype *st, char *mddev, + for (dnum=0, raid_disk_num=0, dv = devlist ; dv ; + dv=(dv->next)?(dv->next):moved_disk, dnum++) { + int fd; +- struct stat stb; ++ struct stat stb2; + struct mdinfo *inf = &infos[dnum]; + + if (dnum >= total_slots) +@@ -924,9 +924,9 @@ int Create(struct supertype *st, char *mddev, + dv->devname); + goto abort_locked; + } +- fstat(fd, &stb); +- inf->disk.major = major(stb.st_rdev); +- inf->disk.minor = minor(stb.st_rdev); ++ fstat(fd, &stb2); ++ inf->disk.major = major(stb2.st_rdev); ++ inf->disk.minor = minor(stb2.st_rdev); + } + if (fd >= 0) + remove_partitions(fd); +@@ -947,8 +947,8 @@ int Create(struct supertype *st, char *mddev, + + if (!have_container) { + /* getinfo_super might have lost these ... */ +- inf->disk.major = major(stb.st_rdev); +- inf->disk.minor = minor(stb.st_rdev); ++ inf->disk.major = major(stb2.st_rdev); ++ inf->disk.minor = minor(stb2.st_rdev); + } + break; + case 2: +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch b/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch new file mode 100644 index 0000000..fefb45c --- /dev/null +++ b/SOURCES/mdadm-Fail-for-kernels-older-than-2.6.15.patch @@ -0,0 +1,32 @@ +From dcf3d4de95d1a4cbc65b24a844173ba1c1300b55 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 6 Apr 2017 15:46:31 -0400 +Subject: [RHEL7.5 PATCH 067/169] mdadm: Fail for kernels older than 2.6.15 + +With the removal of old kernel API support, mdadm will no longer run +on kernels older than 2.6.15. + +Signed-off-by: Jes Sorensen +--- + mdadm.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/mdadm.c b/mdadm.c +index 3fe17fc..001ff68 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -120,6 +120,11 @@ int main(int argc, char *argv[]) + 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); ++ } ++ + while ((option_index = -1), + (opt = getopt_long(argc, argv, shortopt, long_options, + &option_index)) != -1) { +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fix-broken-formatting1.patch b/SOURCES/mdadm-Fix-broken-formatting1.patch new file mode 100644 index 0000000..2d3a7a9 --- /dev/null +++ b/SOURCES/mdadm-Fix-broken-formatting1.patch @@ -0,0 +1,121 @@ +From b831b299e864224b389743d8a435d6629ee674e3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 16 May 2017 14:04:22 -0400 +Subject: [RHEL7.5 PATCH 144/169] mdadm: Fix '==' broken formatting + +Signed-off-by: Jes Sorensen +--- + Detail.c | 6 +++--- + config.c | 4 ++-- + managemon.c | 4 ++-- + super-ddf.c | 16 ++++++++-------- + super-intel.c | 2 +- + 5 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/Detail.c b/Detail.c +index ef2370c..bf881ff 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -714,9 +714,9 @@ This is pretty boring + if (disk.state & (1 << MD_DISK_JOURNAL)) + printf(" journal"); + if ((disk.state & +- ((1<= 0) +diff --git a/config.c b/config.c +index 9b008e3..48e0278 100644 +--- a/config.c ++++ b/config.c +@@ -1118,8 +1118,8 @@ struct mddev_ident *conf_match(struct supertype *st, + match = NULL; + for (; array_list; array_list = array_list->next) { + if (array_list->uuid_set && +- same_uuid(array_list->uuid, info->uuid, st->ss->swapuuid) +- == 0) { ++ same_uuid(array_list->uuid, info->uuid, ++ st->ss->swapuuid) == 0) { + if (verbose >= 2 && array_list->devname) + pr_err("UUID differs from %s.\n", + array_list->devname); +diff --git a/managemon.c b/managemon.c +index 0a33fc9..a8df666 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -580,8 +580,8 @@ static void manage_member(struct mdstat_ent *mdstat, + usleep(15*1000); + } + replace_array(container, a, newa); +- if (sysfs_set_str(&a->info, NULL, "sync_action", "recover") +- == 0) ++ if (sysfs_set_str(&a->info, NULL, ++ "sync_action", "recover") == 0) + newa->prev_action = recover; + dprintf("recovery started on %s\n", a->info.sys_name); + out: +diff --git a/super-ddf.c b/super-ddf.c +index 4da7c09..c233601 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1883,8 +1883,8 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst, + nsec = n / be16_to_cpu(conf->prim_elmnt_count); + if (conf->sec_elmnt_seq != nsec) { + for (ibvd = 1; ibvd < conf->sec_elmnt_count; ibvd++) { +- if (v->other_bvds[ibvd-1]->sec_elmnt_seq +- == nsec) ++ if (v->other_bvds[ibvd-1]->sec_elmnt_seq == ++ nsec) + break; + } + if (ibvd == conf->sec_elmnt_count) +@@ -3814,13 +3814,13 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray + unsigned int iphys; + int stt; + +- if (be32_to_cpu(ddf->phys->entries[pd].refnum) +- == 0xFFFFFFFF) ++ if (be32_to_cpu(ddf->phys->entries[pd].refnum) == ++ 0xffffffff) + continue; + + stt = be16_to_cpu(ddf->phys->entries[pd].state); +- if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding)) +- != DDF_Online) ++ if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding)) != ++ DDF_Online) + continue; + + i = get_pd_index_from_refnum( +@@ -4205,8 +4205,8 @@ static int get_bvd_state(const struct ddf_super *ddf, + if (pd < 0) + continue; + st = be16_to_cpu(ddf->phys->entries[pd].state); +- if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding)) +- == DDF_Online) { ++ if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding)) == ++ DDF_Online) { + working++; + avail[i] = 1; + } +diff --git a/super-intel.c b/super-intel.c +index 3d0a37c..51b7cc3 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4023,7 +4023,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super, + + /* duplicate and then set the target end state in map[0] */ + memcpy(dest, src, sizeof_imsm_map(src)); +- if (migr_type == MIGR_REBUILD || migr_type == MIGR_GEN_MIGR) { ++ if (migr_type == MIGR_REBUILD || migr_type == MIGR_GEN_MIGR) { + __u32 ord; + int i; + +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch b/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch new file mode 100644 index 0000000..5386482 --- /dev/null +++ b/SOURCES/mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch @@ -0,0 +1,453 @@ +From fc54fe7a7e77fdb6316d332d4d41d0ed2293d6be Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 16 May 2017 13:52:15 -0400 +Subject: [RHEL7.5 PATCH 142/169] mdadm: Fixup a large number of bad + formatting of logical operators + +Logical oprators never belong at the beginning of a line. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 23 ++++++++++------------- + Grow.c | 34 ++++++++++++++++------------------ + Manage.c | 29 +++++++++++++---------------- + managemon.c | 10 +++++----- + mdadm.c | 3 +-- + monitor.c | 4 ++-- + super-ddf.c | 33 ++++++++++++++++----------------- + super-intel.c | 10 +++++----- + util.c | 20 ++++++++------------ + 9 files changed, 76 insertions(+), 90 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 30d5838..1b1905c 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -753,12 +753,12 @@ static int load_devices(struct devs *devices, char *devmap, + bestcnt = newbestcnt; + } + if (best[i] >=0 && +- devices[best[i]].i.events +- == devices[devcnt].i.events +- && (devices[best[i]].i.disk.minor +- != devices[devcnt].i.disk.minor) +- && st->ss == &super0 +- && content->array.level != LEVEL_MULTIPATH) { ++ devices[best[i]].i.events == ++ devices[devcnt].i.events && ++ (devices[best[i]].i.disk.minor ++ != devices[devcnt].i.disk.minor) && ++ st->ss == &super0 && ++ content->array.level != LEVEL_MULTIPATH) { + /* two different devices with identical superblock. + * Could be a mis-detection caused by overlapping + * partitions. fail-safe. +@@ -801,14 +801,11 @@ static int force_array(struct mdinfo *content, + int okcnt = 0; + while (!enough(content->array.level, content->array.raid_disks, + content->array.layout, 1, +- avail) +- || ++ avail) || + (content->reshape_active && content->delta_disks > 0 && + !enough(content->array.level, (content->array.raid_disks + - content->delta_disks), +- content->new_layout, 1, +- avail) +- )) { ++ content->new_layout, 1, avail))) { + /* Choose the newest best drive which is + * not up-to-date, update the superblock + * and add it. +@@ -1303,8 +1300,8 @@ int Assemble(struct supertype *st, char *mddev, + int mdfd; + int clean; + int auto_assem = (mddev == NULL && !ident->uuid_set && +- ident->super_minor == UnSet && ident->name[0] == 0 +- && (ident->container == NULL || ident->member == NULL)); ++ ident->super_minor == UnSet && ident->name[0] == 0 && ++ (ident->container == NULL || ident->member == NULL)); + struct devs *devices; + char *devmap; + int *best = NULL; /* indexed by raid_disk */ +diff --git a/Grow.c b/Grow.c +index a527436..39110b8 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -813,8 +813,8 @@ static void unfreeze(struct supertype *st) + char buf[20]; + + if (sra && +- sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0 +- && strcmp(buf, "frozen\n") == 0) ++ sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0 && ++ strcmp(buf, "frozen\n") == 0) + sysfs_set_str(sra, NULL, "sync_action", "idle"); + sysfs_free(sra); + } +@@ -2902,8 +2902,8 @@ static int impose_level(int fd, int level, char *devname, int verbose) + if (disk.major == 0 && disk.minor == 0) + continue; + found++; +- if ((disk.state & (1 << MD_DISK_ACTIVE)) +- && disk.raid_disk < data_disks) ++ if ((disk.state & (1 << MD_DISK_ACTIVE)) && ++ disk.raid_disk < data_disks) + /* keep this */ + continue; + ioctl(fd, HOT_REMOVE_DISK, +@@ -2921,8 +2921,8 @@ static int impose_level(int fd, int level, char *devname, int verbose) + if (disk.major == 0 && disk.minor == 0) + continue; + found++; +- if ((disk.state & (1 << MD_DISK_ACTIVE)) +- && disk.raid_disk < data_disks) ++ if ((disk.state & (1 << MD_DISK_ACTIVE)) && ++ disk.raid_disk < data_disks) + /* keep this */ + continue; + ioctl(fd, SET_DISK_FAULTY, +@@ -3597,9 +3597,8 @@ started: + } + + if (!st->ss->external && +- !(reshape.before.data_disks != reshape.after.data_disks +- && info->custom_array_size) && +- info->new_level == reshape.level && ++ !(reshape.before.data_disks != reshape.after.data_disks && ++ info->custom_array_size) && info->new_level == reshape.level && + !forked) { + /* no need to wait for the reshape to finish as + * there is nothing more to do. +@@ -4092,14 +4091,14 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, + * before setting 'sync_action' to 'idle'. + * So we need these extra tests. + */ +- if (completed == 0 && advancing +- && strncmp(action, "idle", 4) == 0 +- && info->reshape_progress > 0) ++ if (completed == 0 && advancing && ++ strncmp(action, "idle", 4) == 0 && ++ info->reshape_progress > 0) + break; +- if (completed == 0 && !advancing +- && strncmp(action, "idle", 4) == 0 +- && info->reshape_progress < (info->component_size +- * reshape->after.data_disks)) ++ if (completed == 0 && !advancing && ++ strncmp(action, "idle", 4) == 0 && ++ info->reshape_progress < (info->component_size ++ * reshape->after.data_disks)) + break; + sysfs_wait(fd, NULL); + if (sysfs_fd_get_ll(fd, &completed) < 0) +@@ -4787,8 +4786,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt + /* reshape_progress is increasing */ + if ((__le64_to_cpu(bsb.arraystart) + + __le64_to_cpu(bsb.length) +- < info->reshape_progress) +- && ++ < info->reshape_progress) && + (__le64_to_cpu(bsb.arraystart2) + + __le64_to_cpu(bsb.length2) + < info->reshape_progress)) +diff --git a/Manage.c b/Manage.c +index 467efb7..cee5dad 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -204,11 +204,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + count = 5; + while (((fd = ((devname[0] == '/') + ?open(devname, O_RDONLY|O_EXCL) +- :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 +- || strcmp(fd2devnm(fd), devnm) != 0) +- && container[0] +- && mdmon_running(container) +- && count) { ++ :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 || ++ strcmp(fd2devnm(fd), devnm) != 0) && container[0] && ++ mdmon_running(container) && count) { + /* Can't open, so something might be wrong. However it + * is a container, so we might be racing with mdmon, so + * retry for a bit. +@@ -244,8 +242,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) + while (count && + (err = sysfs_set_str(mdi, NULL, + "array_state", +- "inactive")) < 0 +- && errno == EBUSY) { ++ "inactive")) < 0 && ++ errno == EBUSY) { + usleep(200000); + count--; + } +@@ -447,9 +445,8 @@ done: + * so it is reasonable to retry for a while - 5 seconds. + */ + count = 25; err = 0; +- while (count && fd >= 0 +- && (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 +- && errno == EBUSY) { ++ while (count && fd >= 0 && ++ (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { + usleep(200000); + count --; + } +@@ -795,8 +792,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + break; + } + /* FIXME this is a bad test to be using */ +- if (!tst->sb && (dv->disposition != 'a' +- && dv->disposition != 'S')) { ++ if (!tst->sb && (dv->disposition != 'a' && ++ dv->disposition != 'S')) { + /* we are re-adding a device to a + * completely dead array - have to depend + * on kernel to check +@@ -1393,8 +1390,7 @@ int Manage_subdevs(char *devname, int fd, + + if (strcmp(dv->devname, "failed") == 0 || + strcmp(dv->devname, "faulty") == 0) { +- if (dv->disposition != 'A' +- && dv->disposition != 'r') { ++ if (dv->disposition != 'A' && dv->disposition != 'r') { + pr_err("%s only meaningful with -r or --re-add, not -%c\n", + dv->devname, dv->disposition); + goto abort; +@@ -1499,8 +1495,9 @@ int Manage_subdevs(char *devname, int fd, + goto abort; + } + } +- } else if ((dv->disposition == 'r' || dv->disposition == 'f') +- && get_maj_min(dv->devname, &mj, &mn)) { ++ } else if ((dv->disposition == 'r' || ++ dv->disposition == 'f') && ++ get_maj_min(dv->devname, &mj, &mn)) { + /* for 'fail' and 'remove', the device might + * not exist. + */ +diff --git a/managemon.c b/managemon.c +index 3c1d4cb..0a33fc9 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -499,9 +499,9 @@ static void manage_member(struct mdstat_ent *mdstat, + frozen = 1; /* can't read metadata_version assume the worst */ + + /* If sync_action is not 'idle' then don't try recovery now */ +- if (!frozen +- && sysfs_get_str(&a->info, NULL, "sync_action", buf, sizeof(buf)) > 0 +- && strncmp(buf, "idle", 4) != 0) ++ if (!frozen && ++ sysfs_get_str(&a->info, NULL, "sync_action", ++ buf, sizeof(buf)) > 0 && strncmp(buf, "idle", 4) != 0) + frozen = 1; + + if (mdstat->level) { +@@ -626,8 +626,8 @@ static void manage_member(struct mdstat_ent *mdstat, + newd = xmalloc(sizeof(*newd)); + disk_init_and_add(newd, d, newa); + } +- if (sysfs_get_ll(info, NULL, "array_size", &array_size) == 0 +- && a->info.custom_array_size > array_size*2) { ++ if (sysfs_get_ll(info, NULL, "array_size", &array_size) == 0 && ++ a->info.custom_array_size > array_size*2) { + sysfs_set_num(info, NULL, "array_size", + a->info.custom_array_size/2); + } +diff --git a/mdadm.c b/mdadm.c +index b689e32..70b16f2 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1843,8 +1843,7 @@ static int misc_scan(char devmode, struct context *c) + if (members != member) + continue; + me = map_by_devnm(&map, e->devnm); +- if (me && me->path +- && strcmp(me->path, "/unknown") != 0) ++ if (me && me->path && strcmp(me->path, "/unknown") != 0) + name = me->path; + if (name == NULL || stat(name, &stb) != 0) + name = get_md_name(e->devnm); +diff --git a/monitor.c b/monitor.c +index 00b7c68..81537ed 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -576,8 +576,8 @@ static int read_and_act(struct active_array *a, fd_set *fds) + a->last_checkpoint = sync_completed; + a->container->ss->set_array_state(a, a->curr_state <= clean); + } else if ((a->curr_action == idle && a->prev_action == reshape) || +- (a->curr_action == reshape +- && sync_completed > a->last_checkpoint) ) { ++ (a->curr_action == reshape && ++ sync_completed > a->last_checkpoint)) { + /* Reshape has progressed or completed so we need to + * update the array state - and possibly the array size + */ +diff --git a/super-ddf.c b/super-ddf.c +index 50197a8..769eded 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -670,8 +670,8 @@ static int layout_md2ddf(const mdu_array_info_t *array, + sec_elmnt_count = array->raid_disks / 2; + srl = DDF_2SPANNED; + prl = DDF_RAID1; +- } else if (array->raid_disks % 3 == 0 +- && array->layout == 0x103) { ++ } else if (array->raid_disks % 3 == 0 && ++ array->layout == 0x103) { + rlq = DDF_RAID1_MULTI; + prim_elmnt_count = cpu_to_be16(3); + sec_elmnt_count = array->raid_disks / 3; +@@ -853,8 +853,8 @@ static void *load_section(int fd, struct ddf_super *super, void *buf, + int dofree = (buf == NULL); + + if (check) +- if (len != 2 && len != 8 && len != 32 +- && len != 128 && len != 512) ++ if (len != 2 && len != 8 && len != 32 && ++ len != 128 && len != 512) + return NULL; + + if (len > 1024) +@@ -2028,8 +2028,8 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m + be32_to_cpu(ddf->phys->entries[e].refnum) == 0xffffffff) + e++; + if (i < info->array.raid_disks && e < max && +- !(be16_to_cpu(ddf->phys->entries[e].state) +- & DDF_Failed)) ++ !(be16_to_cpu(ddf->phys->entries[e].state) & ++ DDF_Failed)) + map[i] = 1; + else + map[i] = 0; +@@ -2114,11 +2114,10 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha + info->resync_start = 0; + info->reshape_active = 0; + info->recovery_blocked = 0; +- if (!(ddf->virt->entries[info->container_member].state +- & DDF_state_inconsistent) && +- (ddf->virt->entries[info->container_member].init_state +- & DDF_initstate_mask) +- == DDF_init_full) ++ if (!(ddf->virt->entries[info->container_member].state & ++ DDF_state_inconsistent) && ++ (ddf->virt->entries[info->container_member].init_state & ++ DDF_initstate_mask) == DDF_init_full) + info->resync_start = MaxSector; + + uuid_from_super_ddf(st, info->uuid); +@@ -2135,7 +2134,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha + if (map) + for (j = 0; j < map_disks; j++) { + map[j] = 0; +- if (j < info->array.raid_disks) { ++ if (j < info->array.raid_disks) { + int i = find_phys(ddf, vc->conf.phys_refnum[j]); + if (i >= 0 && + (be16_to_cpu(ddf->phys->entries[i].state) +@@ -4618,9 +4617,9 @@ static void ddf_remove_failed(struct ddf_super *ddf) + 0xFFFFFFFF) + continue; + if (be16_and(ddf->phys->entries[pdnum].state, +- cpu_to_be16(DDF_Failed)) +- && be16_and(ddf->phys->entries[pdnum].state, +- cpu_to_be16(DDF_Transition))) { ++ cpu_to_be16(DDF_Failed)) && ++ be16_and(ddf->phys->entries[pdnum].state, ++ cpu_to_be16(DDF_Transition))) { + /* skip this one unless in dlist*/ + for (dl = ddf->dlist; dl; dl = dl->next) + if (dl->pdnum == (int)pdnum) +@@ -5151,8 +5150,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, + vc = (struct vd_config *)(mu->buf + + i_sec * ddf->conf_rec_len * 512); + for (dl = ddf->dlist; dl; dl = dl->next) +- if (dl->major == di->disk.major +- && dl->minor == di->disk.minor) ++ if (dl->major == di->disk.major && ++ dl->minor == di->disk.minor) + break; + if (!dl || dl->pdnum < 0) { + pr_err("BUG: can't find disk %d (%d/%d)\n", +diff --git a/super-intel.c b/super-intel.c +index 8ca80d3..c84e755 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -4165,8 +4165,8 @@ int check_mpb_migr_compatibility(struct intel_super *super) + if (pba_of_lba0(map0) != pba_of_lba0(map1)) + /* migration optimization area was used */ + return -1; +- if (migr_rec->ascending_migr == 0 +- && migr_rec->dest_depth_per_unit > 0) ++ if (migr_rec->ascending_migr == 0 && ++ migr_rec->dest_depth_per_unit > 0) + /* descending reshape not supported yet */ + return -1; + } +@@ -6442,7 +6442,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, + + for (memb = mdstat ; memb ; memb = memb->next) { + if (memb->metadata_version && +- (strncmp(memb->metadata_version, "external:", 9) == 0) && ++ (strncmp(memb->metadata_version, "external:", 9) == 0) && + (strcmp(&memb->metadata_version[9], name) == 0) && + !is_subarray(memb->metadata_version+9) && + memb->members) { +@@ -11640,8 +11640,8 @@ static int imsm_manage_reshape( + + /* Find volume during the reshape */ + for (dv = super->devlist; dv; dv = dv->next) { +- if (dv->dev->vol.migr_type == MIGR_GEN_MIGR +- && dv->dev->vol.migr_state == 1) { ++ if (dv->dev->vol.migr_type == MIGR_GEN_MIGR && ++ dv->dev->vol.migr_state == 1) { + dev = dv->dev; + migr_vol_qan++; + } +diff --git a/util.c b/util.c +index fc9cd3f..0564c0b 100644 +--- a/util.c ++++ b/util.c +@@ -1014,21 +1014,18 @@ char *get_md_name(char *devnm) + 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)) ++ 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)) ++ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && ++ (stb.st_rdev == rdev)) + return devname; + + 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 (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && ++ (stb.st_rdev == rdev)) + return devname; + + dn = map_dev(major(rdev), minor(rdev), 0); +@@ -1039,9 +1036,8 @@ char *get_md_name(char *devnm) + if (errno != EEXIST) + return NULL; + +- if (stat(devname, &stb) == 0 +- && (S_IFMT&stb.st_mode) == S_IFBLK +- && (stb.st_rdev == rdev)) ++ if (stat(devname, &stb) == 0 && (S_IFMT&stb.st_mode) == S_IFBLK && ++ (stb.st_rdev == rdev)) + return devname; + unlink(devname); + return NULL; +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch b/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch new file mode 100644 index 0000000..009229c --- /dev/null +++ b/SOURCES/mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch @@ -0,0 +1,197 @@ +From 8ea982179af73f5b1d3fc937676ec7c969a190ac Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 12:02:14 -0400 +Subject: [RHEL7.5 PATCH 034/169] mdadm: Fixup a number of whitespace + inconsistency cases + +Lots of code lacked whitespaces in assignments, and in other places +had them in the wrong place. + +Signed-off-by: Jes Sorensen +--- + mdadm.c | 51 +++++++++++++++++++++++++-------------------------- + 1 file changed, 25 insertions(+), 26 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index 502e721..0f32773 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -106,11 +106,11 @@ int main(int argc, char *argv[]) + + srandom(time(0) ^ getpid()); + +- ident.uuid_set=0; ++ ident.uuid_set = 0; + ident.level = UnSet; + ident.raid_disks = UnSet; +- ident.super_minor= UnSet; +- ident.devices=0; ++ ident.super_minor = UnSet; ++ ident.devices = 0; + ident.spare_group = NULL; + ident.autof = 0; + ident.st = NULL; +@@ -120,10 +120,9 @@ int main(int argc, char *argv[]) + ident.container = NULL; + ident.member = NULL; + +- while ((option_index = -1) , +- (opt=getopt_long(argc, argv, +- shortopt, long_options, +- &option_index)) != -1) { ++ while ((option_index = -1), ++ (opt = getopt_long(argc, argv, shortopt, long_options, ++ &option_index)) != -1) { + int newmode = mode; + /* firstly, some mode-independent options */ + switch(opt) { +@@ -397,7 +396,7 @@ int main(int argc, char *argv[]) + pr_err("metadata information already given\n"); + exit(2); + } +- for(i=0; !ss && superlist[i]; i++) ++ for(i = 0; !ss && superlist[i]; i++) + ss = superlist[i]->match_metadata_desc(optarg); + + if (!ss) { +@@ -542,7 +541,7 @@ int main(int argc, char *argv[]) + + case 5: + s.layout = map_name(r5layout, optarg); +- if (s.layout==UnSet) { ++ if (s.layout == UnSet) { + pr_err("layout %s not understood for raid5.\n", + optarg); + exit(2); +@@ -550,7 +549,7 @@ int main(int argc, char *argv[]) + break; + case 6: + s.layout = map_name(r6layout, optarg); +- if (s.layout==UnSet) { ++ if (s.layout == UnSet) { + pr_err("layout %s not understood for raid6.\n", + optarg); + exit(2); +@@ -665,7 +664,7 @@ int main(int argc, char *argv[]) + case O(MISC,'f'): /* force zero */ + case O(MISC,Force): /* force zero */ + case O(MANAGE,Force): /* add device which is too large */ +- c.force=1; ++ c.force = 1; + continue; + /* now for the Assemble options */ + case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during +@@ -777,12 +776,12 @@ int main(int argc, char *argv[]) + continue; + if (strcmp(c.update, "revert-reshape") == 0) + continue; +- if (strcmp(c.update, "byteorder")==0) { ++ if (strcmp(c.update, "byteorder") == 0) { + if (ss) { + pr_err("must not set metadata type with --update=byteorder.\n"); + exit(2); + } +- for(i=0; !ss && superlist[i]; i++) ++ for(i = 0; !ss && superlist[i]; i++) + ss = superlist[i]->match_metadata_desc( + "0.swap"); + if (!ss) { +@@ -1476,7 +1475,7 @@ int main(int argc, char *argv[]) + pr_err("can only assemble a single array when providing a backup file.\n"); + exit(1); + } +- for (dv = devlist ; dv ; dv=dv->next) { ++ for (dv = devlist; dv; dv = dv->next) { + struct mddev_ident *array_ident = conf_get_ident(dv->devname); + if (array_ident == NULL) { + pr_err("%s not identified in config file.\n", +@@ -1611,10 +1610,10 @@ int main(int argc, char *argv[]) + else + c.delay = 60; + } +- rv= Monitor(devlist, mailaddr, program, +- &c, daemonise, oneshot, +- dosyslog, pidfile, increments, +- spare_sharing); ++ rv = Monitor(devlist, mailaddr, program, ++ &c, daemonise, oneshot, ++ dosyslog, pidfile, increments, ++ spare_sharing); + break; + + case GROW: +@@ -1654,7 +1653,7 @@ int main(int argc, char *argv[]) + rv = 1; + break; + } +- for (dv=devlist->next; dv ; dv=dv->next) { ++ for (dv = devlist->next; dv; dv = dv->next) { + rv = Grow_Add_device(devlist->devname, mdfd, + dv->devname); + if (rv) +@@ -1749,7 +1748,7 @@ static int scan_assemble(struct supertype *ss, + pr_err("No devices listed in conf file were found.\n"); + return 1; + } +- for (a = array_list; a ; a = a->next) { ++ for (a = array_list; a; a = a->next) { + a->assembled = 0; + if (a->autof == 0) + a->autof = c->autof; +@@ -1760,7 +1759,7 @@ static int scan_assemble(struct supertype *ss, + failures = 0; + successes = 0; + rv = 0; +- for (a = array_list; a ; a = a->next) { ++ for (a = array_list; a; a = a->next) { + int r; + if (a->assembled) + continue; +@@ -1826,7 +1825,7 @@ static int misc_scan(char devmode, struct context *c) + int rv = 0; + + for (members = 0; members <= 1; members++) { +- for (e=ms ; e ; e=e->next) { ++ for (e = ms; e; e = e->next) { + char *name = NULL; + struct map_ent *me; + struct stat stb; +@@ -1864,7 +1863,7 @@ static int stop_scan(int verbose) + /* Due to possible stacking of devices, repeat until + * nothing more can be stopped + */ +- int progress=1, err; ++ int progress = 1, err; + int last = 0; + int rv = 0; + do { +@@ -1873,7 +1872,7 @@ static int stop_scan(int verbose) + + if (!progress) last = 1; + progress = 0; err = 0; +- for (e=ms ; e ; e=e->next) { ++ for (e = ms; e; e = e->next) { + char *name = get_md_name(e->devnm); + int mdfd; + +@@ -1908,7 +1907,7 @@ static int misc_list(struct mddev_dev *devlist, + struct mddev_dev *dv; + int rv = 0; + +- for (dv=devlist ; dv; dv=(rv & 16) ? NULL : dv->next) { ++ for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) { + int mdfd; + + switch(dv->disposition) { +@@ -1974,7 +1973,7 @@ static int misc_list(struct mddev_dev *devlist, + case 1: + mdfd = open_mddev(dv->devname, 1); + } +- if (mdfd>=0) { ++ if (mdfd >= 0) { + switch(dv->disposition) { + case 'R': + c->runstop = 1; +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fixup-broken-formatting2.patch b/SOURCES/mdadm-Fixup-broken-formatting2.patch new file mode 100644 index 0000000..e2197a2 --- /dev/null +++ b/SOURCES/mdadm-Fixup-broken-formatting2.patch @@ -0,0 +1,163 @@ +From d16a749444251c12689fa93d398149025a9c2398 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 16 May 2017 14:09:57 -0400 +Subject: [RHEL7.5 PATCH 145/169] mdadm: Fixup != broken formatting + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 4 ++-- + Grow.c | 13 +++++++------ + policy.c | 5 ++--- + restripe.c | 8 +++++--- + super-ddf.c | 8 ++++---- + super0.c | 8 ++++---- + 6 files changed, 24 insertions(+), 22 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index afc6d9c..3c10b6c 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -755,8 +755,8 @@ static int load_devices(struct devs *devices, char *devmap, + if (best[i] >=0 && + devices[best[i]].i.events == + devices[devcnt].i.events && +- (devices[best[i]].i.disk.minor +- != devices[devcnt].i.disk.minor) && ++ (devices[best[i]].i.disk.minor != ++ devices[devcnt].i.disk.minor) && + st->ss == &super0 && + content->array.level != LEVEL_MULTIPATH) { + /* two different devices with identical superblock. +diff --git a/Grow.c b/Grow.c +index db3f18b..ecf5ca0 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1403,8 +1403,8 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) + if (info->new_layout == UnSet) { + int copies = 1 + (info->delta_disks + / info->array.raid_disks); +- if (info->array.raid_disks * (copies-1) +- != info->delta_disks) ++ if (info->array.raid_disks * (copies-1) != ++ info->delta_disks) + return "Impossible number of devices for RAID0->RAID10"; + info->new_layout = 0x100 + copies; + } +@@ -3067,8 +3067,8 @@ static int reshape_array(char *container, int fd, char *devname, + if (restart && + (reshape.level != info->array.level || + reshape.before.layout != info->array.layout || +- reshape.before.data_disks + reshape.parity +- != info->array.raid_disks - max(0, info->delta_disks))) { ++ reshape.before.data_disks + reshape.parity != ++ info->array.raid_disks - max(0, info->delta_disks))) { + pr_err("reshape info is not in native format - cannot continue.\n"); + goto release; + } +@@ -4281,8 +4281,9 @@ static int grow_backup(struct mdinfo *sra, + ((char*)&bsb.sb_csum2)-((char*)&bsb)); + + rv = -1; +- if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0) +- != destoffsets[i] - 4096) ++ if ((unsigned long long)lseek64(destfd[i], ++ destoffsets[i] - 4096, 0) != ++ destoffsets[i] - 4096) + break; + if (write(destfd[i], &bsb, 512) != 512) + break; +diff --git a/policy.c b/policy.c +index 064d349..b17585a 100644 +--- a/policy.c ++++ b/policy.c +@@ -887,9 +887,8 @@ int Write_rules(char *rule_name) + fd = 1; + + /* write static invocation */ +- if (write(fd, udev_template_start, +- sizeof(udev_template_start) - 1) +- != (int)sizeof(udev_template_start)-1) ++ if (write(fd, udev_template_start, sizeof(udev_template_start) - 1) != ++ (int)sizeof(udev_template_start) - 1) + goto abort; + + /* iterate, if none created or error occurred, remove file */ +diff --git a/restripe.c b/restripe.c +index 6b31695..31b07e8 100644 +--- a/restripe.c ++++ b/restripe.c +@@ -581,14 +581,16 @@ int save_stripes(int *source, unsigned long long *offsets, + raid_disks, level, layout); + if (dnum < 0) abort(); + if (source[dnum] < 0 || +- lseek64(source[dnum], offsets[dnum]+offset, 0) < 0 || +- read(source[dnum], buf+disk * chunk_size, chunk_size) +- != chunk_size) ++ lseek64(source[dnum], ++ offsets[dnum] + offset, 0) < 0 || ++ read(source[dnum], buf+disk * chunk_size, ++ chunk_size) != chunk_size) { + if (failed <= 2) { + fdisk[failed] = dnum; + fblock[failed] = disk; + failed++; + } ++ } + } + if (failed == 0 || fblock[0] >= data_disks) + /* all data disks are good */ +diff --git a/super-ddf.c b/super-ddf.c +index c233601..d02a19a 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3511,8 +3511,8 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + if (minsize == 0) + minsize = 8; + for (dl = ddf->dlist; dl ; dl = dl->next) { +- if (find_space(ddf, dl, data_offset, &minsize) +- != INVALID_SECTORS) ++ if (find_space(ddf, dl, data_offset, &minsize) != ++ INVALID_SECTORS) + dcnt++; + } + if (dcnt < raiddisks) { +@@ -4004,8 +4004,8 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) + continue; + + if (posix_memalign((void **)&dl1, 512, +- sizeof(*dl1) + (first->max_part) * sizeof(dl1->vlist[0])) +- != 0) { ++ sizeof(*dl1) + (first->max_part) * ++ sizeof(dl1->vlist[0])) != 0) { + pr_err("could not allocate disk info buffer\n"); + return 3; + } +diff --git a/super0.c b/super0.c +index dc13efb..756cab5 100644 +--- a/super0.c ++++ b/super0.c +@@ -589,8 +589,8 @@ static int update_super0(struct supertype *st, struct mdinfo *info, + * being marked 'sync' + */ + add = (1<disks[d].state & ~mask) | add) +- != (unsigned)info->disk.state) { ++ if (((sb->disks[d].state & ~mask) | add) != ++ (unsigned)info->disk.state) { + sb->disks[d].state = info->disk.state | wonly |failfast; + rv = 1; + } +@@ -1058,8 +1058,8 @@ static int load_super0(struct supertype *st, int fd, char *devname) + * valid. If it doesn't clear the bit. An --assemble --force + * should get that written out. + */ +- if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096)) +- != ROUND_UP(sizeof(struct bitmap_super_s),4096)) ++ if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096)) != ++ ROUND_UP(sizeof(struct bitmap_super_s), 4096)) + goto no_bitmap; + + uuid_from_super0(st, uuid); +-- +2.7.4 + diff --git a/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch b/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch new file mode 100644 index 0000000..e7f66a3 --- /dev/null +++ b/SOURCES/mdadm-Fixup-morebroken-logical-operator-formatting.patch @@ -0,0 +1,256 @@ +From d7be7d87366a7f9b190bc4e41ea06f7c9984028e Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 16 May 2017 13:59:43 -0400 +Subject: [RHEL7.5 PATCH 143/169] mdadm: Fixup more broken logical operator + formatting + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 9 ++++----- + Grow.c | 16 +++++++++------- + Manage.c | 4 ++-- + Monitor.c | 4 ++-- + mapfile.c | 4 ++-- + mdstat.c | 10 ++++++---- + platform-intel.c | 4 ++-- + restripe.c | 4 ++-- + super-ddf.c | 15 +++++++-------- + super-intel.c | 3 +-- + util.c | 3 +-- + 11 files changed, 38 insertions(+), 38 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 1b1905c..afc6d9c 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -220,8 +220,8 @@ static int select_devices(struct mddev_dev *devlist, + pr_err("not a recognisable container: %s\n", + devname); + tmpdev->used = 2; +- } else if (!tst->ss->load_container +- || tst->ss->load_container(tst, dfd, NULL)) { ++ } else if (!tst->ss->load_container || ++ tst->ss->load_container(tst, dfd, NULL)) { + if (report_mismatch) + pr_err("no correct container type: %s\n", + devname); +@@ -776,9 +776,8 @@ static int load_devices(struct devs *devices, char *devmap, + *stp = st; + return -1; + } +- if (best[i] == -1 +- || (devices[best[i]].i.events +- < devices[devcnt].i.events)) ++ if (best[i] == -1 || (devices[best[i]].i.events ++ < devices[devcnt].i.events)) + best[i] = devcnt; + } + devcnt++; +diff --git a/Grow.c b/Grow.c +index 39110b8..db3f18b 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3995,8 +3995,8 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, + * a backup. + */ + if (advancing) { +- if ((need_backup > info->reshape_progress +- || info->array.major_version < 0) && ++ if ((need_backup > info->reshape_progress || ++ info->array.major_version < 0) && + *suspend_point < info->reshape_progress + target) { + if (need_backup < *suspend_point + 2 * target) + *suspend_point = need_backup; +@@ -4149,8 +4149,9 @@ check_progress: + * it was just a device failure that leaves us degraded but + * functioning. + */ +- if (sysfs_get_str(info, NULL, "reshape_position", buf, sizeof(buf)) < 0 +- || strncmp(buf, "none", 4) != 0) { ++ if (sysfs_get_str(info, NULL, "reshape_position", buf, ++ sizeof(buf)) < 0 || ++ strncmp(buf, "none", 4) != 0) { + /* The abort might only be temporary. Wait up to 10 + * seconds for fd to contain a valid number again. + */ +@@ -4182,9 +4183,10 @@ check_progress: + /* Maybe racing with array shutdown - check state */ + if (fd >= 0) + close(fd); +- if (sysfs_get_str(info, NULL, "array_state", buf, sizeof(buf)) < 0 +- || strncmp(buf, "inactive", 8) == 0 +- || strncmp(buf, "clear",5) == 0) ++ if (sysfs_get_str(info, NULL, "array_state", buf, ++ sizeof(buf)) < 0 || ++ strncmp(buf, "inactive", 8) == 0 || ++ strncmp(buf, "clear",5) == 0) + return -2; /* abort */ + return -1; /* complete */ + } +diff --git a/Manage.c b/Manage.c +index cee5dad..04b9398 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -655,8 +655,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + if (dv->failfast == FlagClear) + disc.state &= ~(1 << MD_DISK_FAILFAST); + remove_partitions(tfd); +- if (update || dv->writemostly != FlagDefault +- || dv->failfast != FlagDefault) { ++ if (update || dv->writemostly != FlagDefault || ++ dv->failfast != FlagDefault) { + int rv = -1; + tfd = dev_open(dv->devname, O_RDWR); + if (tfd < 0) { +diff --git a/Monitor.c b/Monitor.c +index 0198a34..725f47d 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -530,7 +530,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + if (st->utime == array.utime && st->failed == sra->array.failed_disks && + st->working == sra->array.working_disks && + st->spare == sra->array.spare_disks && +- (mse == NULL || (mse->percent == st->percent))) { ++ (mse == NULL || (mse->percent == st->percent))) { + if ((st->active < st->raid) && st->spare == 0) + retval = 1; + goto out; +@@ -672,7 +672,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + char *name; + + for (mse = mdstat; mse; mse = mse->next) +- if (mse->devnm[0] && (!mse->level || /* retrieve containers */ ++ if (mse->devnm[0] && (!mse->level || /* retrieve containers */ + (strcmp(mse->level, "raid0") != 0 && + strcmp(mse->level, "linear") != 0))) { + struct state *st = xcalloc(1, sizeof *st); +diff --git a/mapfile.c b/mapfile.c +index c89d403..f3c8191 100644 +--- a/mapfile.c ++++ b/mapfile.c +@@ -439,8 +439,8 @@ void RebuildMap(void) + if ((homehost == NULL || + st->ss->match_home(st, homehost) != 1) && + st->ss->match_home(st, "any") != 1 && +- (require_homehost +- || ! conf_name_is_free(info->name))) ++ (require_homehost || ++ !conf_name_is_free(info->name))) + /* require a numeric suffix */ + unum = 0; + else +diff --git a/mdstat.c b/mdstat.c +index 3962896..0d44050 100644 +--- a/mdstat.c ++++ b/mdstat.c +@@ -166,8 +166,8 @@ struct mdstat_ent *mdstat_read(int hold, int start) + continue; + insert_here = NULL; + /* Better be an md line.. */ +- if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32 +- || (line[2] != '_' && !isdigit(line[2]))) ++ if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32 || ++ (line[2] != '_' && !isdigit(line[2]))) + continue; + strcpy(devnm, line); + +@@ -212,8 +212,10 @@ struct mdstat_ent *mdstat_read(int hold, int start) + struct mdstat_ent **ih; + ih = &all; + while (ih != insert_here && *ih && +- ((int)strlen((*ih)->devnm) != ep-w +- || strncmp((*ih)->devnm, w, ep-w) != 0)) ++ ((int)strlen((*ih)->devnm) != ++ ep-w || ++ strncmp((*ih)->devnm, w, ++ ep-w) != 0)) + ih = & (*ih)->next; + insert_here = ih; + } +diff --git a/platform-intel.c b/platform-intel.c +index 9867697..a11101d 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -548,8 +548,8 @@ static int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name + + errno = 0; + var_data_len = strtoul(buf, NULL, 16); +- if ((errno == ERANGE && (var_data_len == LONG_MAX)) +- || (errno != 0 && var_data_len == 0)) ++ if ((errno == ERANGE && (var_data_len == LONG_MAX)) || ++ (errno != 0 && var_data_len == 0)) + return 1; + + /* get data */ +diff --git a/restripe.c b/restripe.c +index de85ee4..6b31695 100644 +--- a/restripe.c ++++ b/restripe.c +@@ -731,8 +731,8 @@ int restore_stripes(int *dest, unsigned long long *offsets, + zero_size = chunk_size; + } + +- if (stripe_buf == NULL || stripes == NULL || blocks == NULL +- || zero == NULL) { ++ if (stripe_buf == NULL || stripes == NULL || blocks == NULL || ++ zero == NULL) { + rv = -2; + goto abort; + } +diff --git a/super-ddf.c b/super-ddf.c +index 769eded..4da7c09 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -932,14 +932,13 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) + if (load_ddf_header(fd, be64_to_cpu(super->anchor.secondary_lba), + dsize >> 9, 2, + &super->secondary, &super->anchor)) { +- if (super->active == NULL +- || (be32_to_cpu(super->primary.seq) +- < be32_to_cpu(super->secondary.seq) && +- !super->secondary.openflag) +- || (be32_to_cpu(super->primary.seq) +- == be32_to_cpu(super->secondary.seq) && +- super->primary.openflag && !super->secondary.openflag) +- ) ++ if (super->active == NULL || ++ (be32_to_cpu(super->primary.seq) ++ < be32_to_cpu(super->secondary.seq) && ++ !super->secondary.openflag) || ++ (be32_to_cpu(super->primary.seq) == ++ be32_to_cpu(super->secondary.seq) && ++ super->primary.openflag && !super->secondary.openflag)) + super->active = &super->secondary; + } else if (devname && + be64_to_cpu(super->anchor.secondary_lba) != ~(__u64)0) +diff --git a/super-intel.c b/super-intel.c +index c84e755..3d0a37c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -10874,8 +10874,7 @@ static int imsm_create_metadata_update_for_reshape( + */ + spares = get_spares_for_grow(st); + +- if (spares == NULL +- || delta_disks > spares->array.spare_disks) { ++ if (spares == NULL || delta_disks > spares->array.spare_disks) { + pr_err("imsm: ERROR: Cannot get spare devices for %s.\n", geo->dev_name); + i = -1; + goto abort; +diff --git a/util.c b/util.c +index 0564c0b..d89438c 100644 +--- a/util.c ++++ b/util.c +@@ -2213,8 +2213,7 @@ void enable_fds(int devices) + { + unsigned int fds = 20 + devices; + struct rlimit lim; +- if (getrlimit(RLIMIT_NOFILE, &lim) != 0 +- || lim.rlim_cur >= fds) ++ if (getrlimit(RLIMIT_NOFILE, &lim) != 0 || lim.rlim_cur >= fds) + return; + if (lim.rlim_max < fds) + lim.rlim_max = fds; +-- +2.7.4 + diff --git a/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch b/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch new file mode 100644 index 0000000..f2f6712 --- /dev/null +++ b/SOURCES/mdadm-Forced-type-conversion-to-avoid-truncation.patch @@ -0,0 +1,33 @@ +From 5b97512954e9710fd45ab5778bf679205c35892d Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Sat, 18 Mar 2017 10:33:45 +0800 +Subject: [RHEL7.5 PATCH 016/169] mdadm: Forced type conversion to avoid + truncation + +Gcc reports it needs 19 bytes to right to disk->serial. Because the +type of argument i is int. But the meaning of i is failed disk +number. So it doesn't need to use 19 bytes. Just add a type +conversion to avoid this building error + +Signed-off-by: Xiao Ni +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 343f20d..e1618f1 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -5228,7 +5228,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, + disk->status = CONFIGURED_DISK | FAILED_DISK; + disk->scsi_id = __cpu_to_le32(~(__u32)0); + snprintf((char *) disk->serial, MAX_RAID_SERIAL_LEN, +- "missing:%d", i); ++ "missing:%d", (__u8)i); + } + find_missing(super); + } else { +-- +2.7.4 + diff --git a/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch b/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch new file mode 100644 index 0000000..376d374 --- /dev/null +++ b/SOURCES/mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch @@ -0,0 +1,47 @@ +From 75dd32a185871fead13cd3586e00980b35410ff0 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 20 Mar 2017 13:21:41 +0800 +Subject: [RHEL7.5 PATCH 014/169] mdadm/Monitor: Fix NULL pointer + dereference when stat2devnm return NULL + +Wait(): stat2devnm() returns NULL for non block devices. Check the +pointer is valid derefencing it. This can happen when using --wait, +such as the 'f' and 'd' file type, causing a core dump. +such as: ./mdadm --wait /dev/md/ + +Reviewed-by: NeilBrown +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Monitor.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/Monitor.c b/Monitor.c +index 802a9d9..bdd3e63 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -994,6 +994,7 @@ int Wait(char *dev) + { + struct stat stb; + char devnm[32]; ++ char *tmp; + int rv = 1; + int frozen_remaining = 3; + +@@ -1002,7 +1003,12 @@ int Wait(char *dev) + strerror(errno)); + return 2; + } +- strcpy(devnm, stat2devnm(&stb)); ++ tmp = stat2devnm(&stb); ++ if (!tmp) { ++ pr_err("%s is not a block device.\n", dev); ++ return 2; ++ } ++ strcpy(devnm, tmp); + + while(1) { + struct mdstat_ent *ms = mdstat_read(1, 0); +-- +2.7.4 + diff --git a/SOURCES/mdadm-Uninitialized-variable-rdev.patch b/SOURCES/mdadm-Uninitialized-variable-rdev.patch new file mode 100644 index 0000000..c4b7977 --- /dev/null +++ b/SOURCES/mdadm-Uninitialized-variable-rdev.patch @@ -0,0 +1,29 @@ +From a3476c9223e55ebb6063e7c5ee057647c70da0d2 Mon Sep 17 00:00:00 2001 +From: James Puthukattukaran +Date: Tue, 16 May 2017 11:57:00 -0400 +Subject: [RHEL7.5 PATCH 140/169] mdadm: Uninitialized variable rdev + +rdev is not initialized properly causing compiler complaint. + +Signed-off-by: James Puthukattukaran +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-ddf.c b/super-ddf.c +index 9c82f4f..ac14017 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3526,7 +3526,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + return 1; + } + /* This device must be a member of the set */ +- if (!stat_is_blkdev(dev, NULL)) ++ if (!stat_is_blkdev(dev, &rdev)) + return 0; + for (dl = ddf->dlist ; dl ; dl = dl->next) { + if (dl->major == (int)major(rdev) && +-- +2.7.4 + diff --git a/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch b/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch new file mode 100644 index 0000000..4ecaa95 --- /dev/null +++ b/SOURCES/mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch @@ -0,0 +1,36 @@ +From 72b616aff26e64079727ea908073027c08f99c07 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Tue, 7 Mar 2017 11:13:03 +0800 +Subject: [RHEL7.5 PATCH 008/169] mdadm:add checking clustered bitmap in + assemble mode + +mdadm:Both clustered and internal array don't need +to specify --bitmap when assembling array. + +Signed-off-by: Zhilong Liu +Acked-by: Coly Li +Signed-off-by: Jes Sorensen +--- + mdadm.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index b5ac061..d6ad8dc 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1095,8 +1095,10 @@ int main(int argc, char *argv[]) + pr_err("bitmap file needed with -b in --assemble mode\n"); + exit(2); + } +- if (strcmp(optarg, "internal") == 0) { +- pr_err("there is no need to specify --bitmap when assembling arrays with internal bitmaps\n"); ++ if (strcmp(optarg, "internal") == 0 || ++ strcmp(optarg, "clustered") == 0) { ++ pr_err("no need to specify --bitmap when assembling" ++ " arrays with internal or clustered bitmap\n"); + continue; + } + bitmap_fd = open(optarg, O_RDWR); +-- +2.7.4 + diff --git a/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch b/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch new file mode 100644 index 0000000..d40197a --- /dev/null +++ b/SOURCES/mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch @@ -0,0 +1,60 @@ +From 8cc56e8b3269305ec5483527d853464eac3bf690 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 28 Aug 2017 17:24:27 +0800 +Subject: [RHEL7.5 PATCH 04/13] mdadm/bitmap: examine-bitmap failed when bitmap + is external mode + +--examine-bitmap: the bitmap_file_open() shouldn't omit the +regular file descriptor when the bitmap is external mode. +Such as: ./mdadm -X /mnt/3 + +This commit is partial revert of commit 0a6bff09d416 +(mdadm/util: unify fstat checking blkdev into function) + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + bitmap.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/bitmap.c b/bitmap.c +index 3653660..e38cb96 100644 +--- a/bitmap.c ++++ b/bitmap.c +@@ -183,6 +183,7 @@ static int + bitmap_file_open(char *filename, struct supertype **stp, int node_num) + { + int fd; ++ struct stat stb; + struct supertype *st = *stp; + + fd = open(filename, O_RDONLY|O_DIRECT); +@@ -192,7 +193,12 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num) + return -1; + } + +- if (fstat_is_blkdev(fd, filename, NULL)) { ++ if (fstat(fd, &stb) < 0) { ++ pr_err("fstat failed for %s: %s\n", filename, strerror(errno)); ++ close(fd); ++ return -1; ++ } ++ if ((stb.st_mode & S_IFMT) == S_IFBLK) { + /* block device, so we are probably after an internal bitmap */ + if (!st) + st = guess_super(fd); +@@ -211,11 +217,7 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num) + fd = -1; + } + } +- + *stp = st; +- } else { +- close(fd); +- return -1; + } + + return fd; +-- +2.7.4 + diff --git a/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch b/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch new file mode 100644 index 0000000..bbc62fc --- /dev/null +++ b/SOURCES/mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch @@ -0,0 +1,39 @@ +From 4c829c2252d2a6fb4871ec0cdad58b6c3a0218fd Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 20 Mar 2017 18:46:39 +0800 +Subject: [RHEL7.5 PATCH 018/169] mdadm/bitmap:fixed typos in comments of + bitmap.h + +bitmap.h: fixed trivial typos in comments + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + bitmap.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/bitmap.h b/bitmap.h +index b8fb071..7b1f80f 100644 +--- a/bitmap.h ++++ b/bitmap.h +@@ -46,7 +46,7 @@ + * + * 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 aswell, thus setting the counter to 0. ++ * 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. + * +@@ -185,7 +185,7 @@ struct bitmap_page { + */ + char *map; + /* +- * in emergencies (when map cannot be alloced), hijack the map ++ * in emergencies (when map cannot be allocated), hijack the map + * pointer and use it as two counters itself + */ + unsigned int hijacked; +-- +2.7.4 + diff --git a/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch b/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch new file mode 100644 index 0000000..9c679e6 --- /dev/null +++ b/SOURCES/mdadm-check-the-nodes-when-operate-clustered1-array.patch @@ -0,0 +1,55 @@ +From 9d67f6496c71efbc68b33aea663dbcc1597a0828 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 1 Mar 2017 18:42:33 +0800 +Subject: [RHEL7.5 PATCH 005/169] mdadm:check the nodes when operate + clustered array + +It doesn't make sense to write_bitmap with less than 2 nodes, +in order to avoid 'write_bitmap' received invalid nodes number, +it would be better to do checking nodes in getopt operations. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.c | 4 ++-- + super1.c | 9 +-------- + 2 files changed, 3 insertions(+), 10 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index 16fd49a..b5ac061 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -603,8 +603,8 @@ int main(int argc, char *argv[]) + case O(GROW, Nodes): + case O(CREATE, Nodes): + c.nodes = parse_num(optarg); +- if (c.nodes <= 0) { +- pr_err("invalid number for the number of cluster nodes: %s\n", ++ if (c.nodes < 2) { ++ pr_err("clustered array needs two nodes at least: %s\n", + optarg); + exit(2); + } +diff --git a/super1.c b/super1.c +index 87a74cb..882cd61 100644 +--- a/super1.c ++++ b/super1.c +@@ -2380,14 +2380,7 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update + } + + if (bms->version == BITMAP_MAJOR_CLUSTERED) { +- 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) +- /* --nodes is not specified */ +- break; +- else if (__cpu_to_le32(st->nodes) < bms->nodes) { ++ if (__cpu_to_le32(st->nodes) < bms->nodes) { + /* Since the nodes num is not increased, no need to check the space + * is enough or not, just update bms->nodes */ + bms->nodes = __cpu_to_le32(st->nodes); +-- +2.7.4 + diff --git a/SOURCES/mdadm-fix-typo1-in-comment.patch b/SOURCES/mdadm-fix-typo1-in-comment.patch new file mode 100644 index 0000000..b3a9c2f --- /dev/null +++ b/SOURCES/mdadm-fix-typo1-in-comment.patch @@ -0,0 +1,27 @@ +From e93bb91b12b5c8a799a04e314d376da38d007e9d Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 1 Mar 2017 16:44:33 +0800 +Subject: [RHEL7.5 PATCH 004/169] mdadm:fix typo in comment + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.c b/mdadm.c +index b5d89e4..16fd49a 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1268,7 +1268,7 @@ int main(int argc, char *argv[]) + * hopefully it's mostly right but there might be some stuff + * missing + * +- * That is mosty checked in the per-mode stuff but... ++ * That is mostly checked in the per-mode stuff but... + * + * For @,B,C and A without -s, the first device listed must be + * an md device. We check that here and open it. +-- +2.7.4 + diff --git a/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch b/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch new file mode 100644 index 0000000..f3af424 --- /dev/null +++ b/SOURCES/mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch @@ -0,0 +1,39 @@ +From 7054da69c778a69ea5e83965bb15620ad5e9e053 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 20 Mar 2017 13:20:06 +0800 +Subject: [RHEL7.5 PATCH 011/169] mdadm:fixed some trivial typos in + comments of mdadm.h + +mdadm.h: fixed some trivial typos in comments + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 71b8afb..91fd9eb 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -552,7 +552,7 @@ struct mdstat_ent { + char devnm[32]; + int active; + char *level; +- char *pattern; /* U or up, _ for down */ ++ char *pattern; /* U for up, _ for down */ + int percent; /* -1 if no resync */ + int resync; /* 3 if check, 2 if reshape, 1 if resync, 0 if recovery */ + int devcnt; +@@ -742,7 +742,7 @@ struct reshape { + unsigned long long new_size; /* New size of array in sectors */ + }; + +-/* A superswitch provides entry point the a metadata handler. ++/* A superswitch provides entry point to a metadata handler. + * + * The superswitch primarily operates on some "metadata" that + * is accessed via the 'supertype'. +-- +2.7.4 + diff --git a/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch b/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch new file mode 100644 index 0000000..0492bf1 --- /dev/null +++ b/SOURCES/mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch @@ -0,0 +1,38 @@ +From 5b2846684ef5172eccc432e3520b79efbc2abba5 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Thu, 30 Mar 2017 15:38:08 +0800 +Subject: [RHEL7.5 PATCH 044/169] mdadm/grow: reshape would be stuck from + raid1 to raid5 + +systemctl doesn't interpret mdadm-grow-continue@.service +correctly due to the wrong argument provided in [service], +it should be corrected %I as %i. Otherwise, if the service +cannot start by systemctl and the reshap progress would be +stuck all time when grows array from raid1 to raid5. + +reproduce steps: +./mdadm -CR /dev/md0 -l1 -b internal -n2 /dev/loop[0-1] +./mdadm --grow /dev/md0 -l5 -n3 -a /dev/loop2 + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-grow-continue@.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service +index 5c667d2..882bc0b 100644 +--- a/systemd/mdadm-grow-continue@.service ++++ b/systemd/mdadm-grow-continue@.service +@@ -10,7 +10,7 @@ Description=Manage MD Reshape on /dev/%I + DefaultDependencies=no + + [Service] +-ExecStart=BINDIR/mdadm --grow --continue /dev/%I ++ExecStart=BINDIR/mdadm --grow --continue /dev/%i + StandardInput=null + StandardOutput=null + StandardError=null +-- +2.7.4 + diff --git a/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch b/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch new file mode 100644 index 0000000..935537c --- /dev/null +++ b/SOURCES/mdadm-install-twomore-udev-rules-in-mdadm.spec.patch @@ -0,0 +1,32 @@ +From 52f6a11ec800114164a5b6866548109e0cbf8578 Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Mon, 28 Aug 2017 15:20:35 -0700 +Subject: [RHEL7.5 PATCH 02/13] mdadm: install two more udev rules in + mdadm.spec + +To avoid rpmbuild error. + +Signed-off-by: Song Liu +Signed-off-by: Jes Sorensen +--- + mdadm.spec | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/mdadm.spec b/mdadm.spec +index 4e97efb..4e6f870 100644 +--- a/mdadm.spec ++++ b/mdadm.spec +@@ -37,8 +37,10 @@ rm -rf $RPM_BUILD_ROOT + %doc TODO ChangeLog mdadm.conf-example COPYING + %{_sbindir}/mdadm + %{_sbindir}/mdmon ++/usr/lib/udev/rules.d/01-md-raid-creating.rules + /usr/lib/udev/rules.d/63-md-raid-arrays.rules + /usr/lib/udev/rules.d/64-md-raid-assembly.rules ++/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules + %config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf + %{_mandir}/man*/md* + +-- +2.7.4 + diff --git a/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch b/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch new file mode 100644 index 0000000..88f2178 --- /dev/null +++ b/SOURCES/mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch @@ -0,0 +1,32 @@ +From 27c48b375d8fb6b4835fd9b11593c75d247ea1c1 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 20 Mar 2017 13:21:03 +0800 +Subject: [RHEL7.5 PATCH 012/169] mdadm:it doesn't make sense to set + --bitmap twice + +mdadm.c: it doesn't make sense to set --bitmap twice. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/mdadm.c b/mdadm.c +index d6ad8dc..08ddcab 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1139,6 +1139,10 @@ int main(int argc, char *argv[]) + case O(CREATE,Bitmap): /* here we create the bitmap */ + case O(GROW,'b'): + case O(GROW,Bitmap): ++ if (s.bitmap_file) { ++ pr_err("bitmap cannot be set twice. Second value: %s.\n", optarg); ++ exit(2); ++ } + if (strcmp(optarg, "internal") == 0 || + strcmp(optarg, "none") == 0 || + strchr(optarg, '/') != NULL) { +-- +2.7.4 + diff --git a/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch b/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch new file mode 100644 index 0000000..08bba0b --- /dev/null +++ b/SOURCES/mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch @@ -0,0 +1,31 @@ +From e39c76b9b72db00d32780e9f30dfba25f58922d2 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 12 Apr 2017 16:37:27 +0800 +Subject: [RHEL7.5 PATCH 074/169] mdadm/manpage:clustered arrays don't + support array-size yet + +Update manpage for array-size section: +Clustered arrays don't support the --array-size yet. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/mdadm.8.in b/mdadm.8.in +index f10a8b8..fb99a5c 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -541,6 +541,8 @@ A value of + restores the apparent size of the array to be whatever the real + amount of available space is. + ++Clustered arrays do not support this parameter yet. ++ + .TP + .BR \-c ", " \-\-chunk= + Specify chunk size of kilobytes. The default when creating an +-- +2.7.4 + diff --git a/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch b/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch new file mode 100644 index 0000000..7c248b3 --- /dev/null +++ b/SOURCES/mdadm-manpage-update-manpage-for-readonly-parameter.patch @@ -0,0 +1,44 @@ +From 8a70632fc2f9026e0f4895f5348cc7cd20d9fbb3 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 12 Apr 2017 16:36:38 +0800 +Subject: [RHEL7.5 PATCH 073/169] mdadm/manpage:update manpage for readonly + parameter + +update readonly in manpage: +Currently both the readwrite and readonly are worked well, +update the readonly section. +One commit in linux/driver/md. Cleared "MD_CLOSING bit" to +Fixes: af8d8e6f0315 ("md: changes for MD_STILL_CLOSED flag") + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 744c12b..f10a8b8 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -925,7 +925,8 @@ will not try to be so clever. + Start the array + .B read only + rather than read-write as normal. No writes will be allowed to the +-array, and no resync, recovery, or reshape will be started. ++array, and no resync, recovery, or reshape will be started. It works with ++Create, Assemble, Manage and Misc mode. + + .TP + .BR \-a ", " "\-\-auto{=yes,md,mdp,part,p}{NN}" +@@ -2232,7 +2233,7 @@ be in use. + + .TP + .B \-\-readonly +-start the array readonly \(em not supported yet. ++start the array in readonly mode. + + .SH MANAGE MODE + .HP 12 +-- +2.7.4 + diff --git a/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch b/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch new file mode 100644 index 0000000..0b1b9e4 --- /dev/null +++ b/SOURCES/mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch @@ -0,0 +1,36 @@ +From 17645275ca30a8ca8024f03672aae45d455bbc4b Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Tue, 9 May 2017 14:25:17 +0800 +Subject: [RHEL7.5 PATCH 119/169] mdadm/md.4: set page-length as 1000 to + avoid warnings from grotty + +"nroff" ("man") or ("tbl") needs a long page to avoid warnings +from "grotty", set 'pl' as 1000 to fix the following issue. + +This command invokes by Makefile rule. +linux-tjrh:~/mdadm # man -l md.4 > test +grotty: ():5967: +character above first line discarded +... ... + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + md.4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/md.4 b/md.4 +index 5bdf7a7..3a1d677 100644 +--- a/md.4 ++++ b/md.4 +@@ -4,6 +4,7 @@ + .\" the Free Software Foundation; either version 2 of the License, or + .\" (at your option) any later version. + .\" See file COPYING in distribution for details. ++.if n .pl 1000v + .TH MD 4 + .SH NAME + md \- Multiple Device driver aka Linux Software RAID +-- +2.7.4 + diff --git a/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch b/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch new file mode 100644 index 0000000..34aae18 --- /dev/null +++ b/SOURCES/mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch @@ -0,0 +1,34 @@ +From e81070a69bf0c6e20f95806b6c60f6ec5c952a20 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 20 Mar 2017 13:21:24 +0800 +Subject: [RHEL7.5 PATCH 013/169] mdadm/mdmon:deleted the abort_reshape + never invoked + +mdmon.c: abort_reshape() has implemented in Grow.c, +this function doesn't make a lot of sense here. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdmon.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index e4b73d9..95e9bba 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -580,11 +580,6 @@ int restore_stripes(int *dest, unsigned long long *offsets, + return 1; + } + +-void abort_reshape(struct mdinfo *sra) +-{ +- return; +-} +- + int save_stripes(int *source, unsigned long long *offsets, + int raid_disks, int chunk_size, int level, int layout, + int nwrites, int *dest, +-- +2.7.4 + diff --git a/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch b/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch new file mode 100644 index 0000000..1889f38 --- /dev/null +++ b/SOURCES/mdadm-r5cache-allow-adding-journal-to-array-without-.patch @@ -0,0 +1,63 @@ +From 3373d49f32b2bd8149f633727eba453708a9bf9c Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Tue, 28 Mar 2017 11:04:44 -0700 +Subject: [RHEL7.5 PATCH 160/169] mdadm/r5cache: allow adding journal to + array without journal + +Currently, --add-journal can be only used to recreate broken journal +for arrays with journal since creation. As the kernel code getting +more mature, this constraint is no longer necessary. + +This patch allows --add-journal to add journal to array without +journal. + +Signed-off-by: Song Liu +Signed-off-by: Jes Sorensen +--- + Manage.c | 6 ------ + mdadm.8.in | 5 ++--- + 2 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 04b9398..b82a729 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -911,7 +911,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + + /* only add journal to array that supports journaling */ + if (dv->disposition == 'j') { +- struct mdinfo mdi; + struct mdinfo *mdp; + + mdp = sysfs_read(fd, NULL, GET_ARRAY_STATE); +@@ -928,11 +927,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + + sysfs_free(mdp); + +- tst->ss->getinfo_super(tst, &mdi, NULL); +- if (mdi.journal_device_required == 0) { +- pr_err("%s does not support journal device.\n", devname); +- return -1; +- } + disc.raid_disk = 0; + } + +diff --git a/mdadm.8.in b/mdadm.8.in +index ecfe9da..461c5de 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -1526,9 +1526,8 @@ the device is found or :missing in case the device is not found. + + .TP + .BR \-\-add-journal +-Recreate journal for RAID-4/5/6 array that lost a journal device. In the +-current implementation, this command cannot add a journal to an array +-that had a failed journal. To avoid interrupting on-going write opertions, ++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, + .B \-\-add-journal + only works for array in Read-Only state. + +-- +2.7.4 + diff --git a/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch b/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch new file mode 100644 index 0000000..e394a22 --- /dev/null +++ b/SOURCES/mdadm-retire-mdassemble-in-make-everything.patch @@ -0,0 +1,58 @@ +From b63804583e25fbc00b96c7f37f97d568b5b1ba9c Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Sun, 16 Apr 2017 15:01:29 +0800 +Subject: [RHEL7.5 PATCH 086/169] mdadm: retire mdassemble in make + everything + +make everything reports no rule to make mdassemble, because mdassemble +is removed from mdadm. This patch removes mdassemble from "everything" +in Makefile, now there is no failure when compiling a static mdadm binary. + +Signed-off-by: Coly Li +Signed-off-by: Jes Sorensen +--- + Makefile | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/Makefile b/Makefile +index a5d2a0a..5655812 100644 +--- a/Makefile ++++ b/Makefile +@@ -169,12 +169,10 @@ check_rundir: + fi + + everything: all mdadm.static swap_super test_stripe raid6check \ +- mdassemble mdassemble.auto mdassemble.static mdassemble.man \ + mdadm.Os mdadm.O2 man + everything-test: all mdadm.static swap_super test_stripe \ +- mdassemble.auto mdassemble.static mdassemble.man \ + mdadm.Os mdadm.O2 man +-# mdadm.uclibc and mdassemble.uclibc don't work on x86-64 ++# mdadm.uclibc doesn't work on x86-64 + # mdadm.tcc doesn't work.. + + mdadm : $(OBJS) | check_rundir +@@ -226,9 +224,6 @@ md.man : md.4 + mdadm.conf.man : mdadm.conf.5 + man -l mdadm.conf.5 > mdadm.conf.man + +-mdassemble.man : mdassemble.8 +- man -l mdassemble.8 > mdassemble.man +- + raid6check.man : raid6check.8 + man -l raid6check.8 > raid6check.man + +@@ -293,9 +288,7 @@ 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 \ +- mdassemble mdassemble.static mdassemble.auto mdassemble.uclibc \ +- mdassemble.klibc swap_super \ ++ mdadm.Os mdadm.O2 mdmon.O2 swap_super \ + init.cpio.gz mdadm.uclibc.static test_stripe raid6check raid6check.o mdmon \ + mdadm.8 + +-- +2.7.4 + diff --git a/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch b/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch new file mode 100644 index 0000000..24cadfe --- /dev/null +++ b/SOURCES/mdadm-set-journal_clean-after-scanning-all-disks.patch @@ -0,0 +1,60 @@ +From 3b8c7127558bad386c8350e039061107c9cf6cde Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Tue, 29 Aug 2017 09:53:02 -0700 +Subject: [RHEL7.5 PATCH 03/13] mdadm: set journal_clean after scanning all + disks + +Summary: +In Incremental.c:count_active(), max_events is tracked to show to +which devices are up to date. If a device has events==max_events+1, +getinfo_super() is called to reload the superblock from this +device. getinfo_super1() blindly set journal_clean to 0, which is +wrong. + +This patch fixes this by tracking max_journal_events for all the +disks. After scanning all disks, journal_clean is set if +max_journal_events >= max_events-1. + +Signed-off-by: Song Liu +Reviewed-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Incremental.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index 6cf2174..91301eb 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -684,6 +684,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra, + int cnt = 0; + int replcnt = 0; + __u64 max_events = 0; ++ __u64 max_journal_events = 0; + char *avail = NULL; + int *best = NULL; + char *devmap = NULL; +@@ -714,8 +715,9 @@ static int count_active(struct supertype *st, struct mdinfo *sra, + + info.array.raid_disks = raid_disks; + st->ss->getinfo_super(st, &info, devmap + raid_disks * devnum); +- if (info.disk.raid_disk == MD_DISK_ROLE_JOURNAL) +- bestinfo->journal_clean = 1; ++ if (info.disk.raid_disk == MD_DISK_ROLE_JOURNAL && ++ info.events > max_journal_events) ++ max_journal_events = info.events; + if (!avail) { + raid_disks = info.array.raid_disks; + avail = xcalloc(raid_disks, 1); +@@ -765,6 +767,8 @@ static int count_active(struct supertype *st, struct mdinfo *sra, + replcnt++; + st->ss->free_super(st); + } ++ if (max_journal_events >= max_events - 1) ++ bestinfo->journal_clean = 1; + + if (!avail) + return 0; +-- +2.7.4 + diff --git a/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch b/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch new file mode 100644 index 0000000..3617c77 --- /dev/null +++ b/SOURCES/mdadm-test-Add-disks-to-support-testing-phsical-devi.patch @@ -0,0 +1,139 @@ +From 25357919d227fd907e4da167d0e07f33f9c94bca Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 14 Jun 2017 21:02:53 +0800 +Subject: [RHEL7.5 PATCH 157/169] mdadm/test: Add '--disks=' to support + testing phsical devices + +If test mode has set as '--dev=disk', then users can specify +the argument of "--disks" to test a bunch of physical devices. +For example: ./test --dev=disk --disks=/dev/sda{2..15} +could execute all test cases on physical devices. + +Currently, the --dev=disk mode would confilct with testdev() +in current test cases, thus ignore testing testdev() if has +set --dev=disk mode. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + test | 37 ++++++++++++++++++++++++++++++++----- + 1 file changed, 32 insertions(+), 5 deletions(-) + +diff --git a/test b/test +index df2eeab..87e2df2 100755 +--- a/test ++++ b/test +@@ -73,11 +73,11 @@ save_log() { + then + # not supported lvm type yet + echo +- elif [ $DEVTYPE == 'loop' ] ++ elif [ "$DEVTYPE" == 'loop' -o "$DEVTYPE" == 'disk' ] + then + if [ ! -z ${array[@]} -a ${#array[@]} -ge 1 ] + then +- md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/$DEVTYPE" | cut -d'=' -f2)) ++ md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/" | cut -d'=' -f2)) + cat /proc/mdstat | grep -q "bitmap" + if [ $? -eq 0 ] + then +@@ -114,6 +114,9 @@ cleanup() { + eval "lvremove --quiet -f \$dev$d" + done + ;; ++ disk ) ++ $mdadm --zero ${disks[@]} &> /dev/null ++ ;; + esac + } + +@@ -128,6 +131,7 @@ do_setup() { + [ -d $logdir ] || mkdir -p $logdir + dmesg -c > /dev/null + ++ devlist= + if [ "$DEVTYPE" == "loop" ] + then + # make sure there are no loop devices remaining. +@@ -139,8 +143,22 @@ do_setup() { + losetup -d /dev/loop[0-9]* 2> /dev/null + sleep 0.2 + done ++ elif [ "$DEVTYPE" == "disk" ] ++ then ++ if [ ! -z "$disks" ] ++ then ++ for d in $(seq 0 ${#disks[@]}) ++ do ++ eval "dev$d=${disks[$d]}" ++ eval devlist=\"\$devlist \$dev$d\" ++ eval devlist$d=\"\$devlist\" ++ done ++ $mdadm --zero ${disks[@]} &> /dev/null ++ else ++ echo "Forget to provide physical devices for disk mode." ++ exit 1 ++ fi + fi +- devlist= + for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + do + sz=$size +@@ -320,6 +338,7 @@ no_errors() { + # basic device test + testdev() { + [ -b $1 ] || die "$1 isn't a block device." ++ [ "$DEVTYPE" == "disk" ] && return 0 + udevadm settle + dev=$1 + cnt=$2 +@@ -383,6 +402,7 @@ do_test() { + do_help() { + cat <<-EOF + Usage: $0 [options] ++ Example for disk mode: ./test --dev=disk --disks=/dev/sda{2..15} + Options: + --tests=test1,test2,... Comma separated list of tests to run + --raidtype= raid0|linear|raid1|raid456|raid10|ddf|imsm +@@ -391,7 +411,8 @@ 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 +- --dev=loop|lvm|ram Use loop devices (default), LVM, or RAM disk ++ --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 + setup Setup test environment and exit + cleanup Cleanup test environment +@@ -476,6 +497,9 @@ parse_args() { + ram ) + DEVTYPE=ram + ;; ++ disk ) ++ DEVTYPE=disk ++ ;; + * ) + echo "Unknown argument: $i" + do_help +@@ -483,6 +507,9 @@ parse_args() { + ;; + esac + ;; ++ --disks=* ) ++ disks=(${disks[*]} ${i##*=}) ++ ;; + --volgroup=* ) + LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'` + ;; +@@ -509,7 +536,7 @@ check_env() { + echo "test: please run 'make everything' before perform testing." + exit 1 + } +- cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck) ++ cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck seq) + for cmd in ${cmds[@]} + do + which $cmd > /dev/null || { +-- +2.7.4 + diff --git a/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch b/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch new file mode 100644 index 0000000..603f9e1 --- /dev/null +++ b/SOURCES/mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch @@ -0,0 +1,70 @@ +From 8403b202ca3cd390589a26a85a7ee9af1cc7c69b Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 14 Jun 2017 21:02:52 +0800 +Subject: [RHEL7.5 PATCH 156/169] mdadm/test: Add '--raidtype=' to run + different raidlevel cases + +It supports to specify the argument of "--raidtype" +to run the different raid level cases. Details refer +to the do_help() usage. +For example: ./test --raidtype=raid1 +could execute all the raid1 test cases under tests/. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + test | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/test b/test +index 7ee523b..df2eeab 100755 +--- a/test ++++ b/test +@@ -385,6 +385,7 @@ do_help() { + Usage: $0 [options] + Options: + --tests=test1,test2,... Comma separated list of tests to run ++ --raidtype= raid0|linear|raid1|raid456|raid10|ddf|imsm + --disable-multipath Disable any tests involving multipath + --disable-integrity Disable slow tests of RAID[56] consistency + --logdir=directory Directory to save all logfiles in +@@ -419,6 +420,36 @@ parse_args() { + --tests=* ) + TESTLIST=($(echo ${i##*=} | sed -e 's/,/ /g')) + ;; ++ --raidtype=* ) ++ case ${i##*=} in ++ raid0 ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]r0\|raid0")) ++ ;; ++ linear ) ++ TESTLIST=($(ls $testdir | grep "linear")) ++ ;; ++ raid1 ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]r1\|raid1" | grep -vi raid10)) ++ ;; ++ raid456 ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]r[4-6]\|raid[4-6]")) ++ ;; ++ raid10 ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]r10\|raid10")) ++ ;; ++ ddf ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]ddf")) ++ ;; ++ imsm ) ++ TESTLIST=($(ls $testdir | grep "[0-9][0-9]imsm")) ++ ;; ++ * ) ++ echo "Unknown argument: $i" ++ do_help ++ exit 1 ++ ;; ++ esac ++ ;; + --logdir=* ) + logdir="${i##*=}" + ;; +-- +2.7.4 + diff --git a/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch b/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch new file mode 100644 index 0000000..80a330d --- /dev/null +++ b/SOURCES/mdadm-test-Convert-code-formatto-use-Tab.patch @@ -0,0 +1,806 @@ +From 662c349a5a995c270c8f7bcf0a4b4a0408c813fd Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 7 Jun 2017 17:31:26 +0800 +Subject: [RHEL7.5 PATCH 154/169] mdadm/test: Convert code format to use + Tab + +In case to make codes neat, this commit didn't change +any codes, just tidy up and use Tab as code format. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + test | 702 ++++++++++++++++++++++++++++++++++++------------------------------- + 1 file changed, 378 insertions(+), 324 deletions(-) + +diff --git a/test b/test +index 13f1bda..7942d6e 100755 +--- a/test ++++ b/test +@@ -3,8 +3,9 @@ + # run test suite for mdadm + user=`id -un` + if [ " $user" != " root" ] +-then echo >&2 "test: testing can only be done as 'root'." +- exit 1; ++then ++ echo >&2 "test: testing can only be done as 'root'." ++ exit 1 + fi + + prefix='[0-9][0-9]' +@@ -13,7 +14,7 @@ dir=`pwd` + mdadm=$dir/mdadm + if [ \! -x $mdadm ] + then +- echo >&2 "test: $mdadm isn't usable." ++ echo >&2 "test: $mdadm isn't usable." + fi + + testdir="tests" +@@ -25,8 +26,9 @@ echo "Testing on linux-$(uname -r) kernel" + + # Check whether to run multipath tests + modprobe multipath 2> /dev/null +-if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat ; then +- MULTIPATH="yes" ++if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat ++then ++ MULTIPATH="yes" + fi + INTEGRITY=yes + DEVTYPE=loop +@@ -36,7 +38,9 @@ LVM_VOLGROUP=mdtest + export MDADM_NO_SYSTEMCTL=1 + + # assume md0, md1, md2 exist in /dev +-md0=/dev/md0 md1=/dev/md1 md2=/dev/md2 ++md0=/dev/md0 ++md1=/dev/md1 ++md2=/dev/md2 + mdp0=/dev/md_d0 + mdp1=/dev/md_d1 + +@@ -69,21 +73,21 @@ config=/tmp/mdadm.conf + cleanup() { + udevadm settle + $mdadm -Ssq 2> /dev/null +- case $DEVTYPE in +- loop) +- for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 +- do +- losetup -d /dev/loop$d ; # rm -f $targetdir/mdtest$d +- rm -f /dev/disk/by-path/loop* +- done +- ;; +- lvm) +- for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 +- do +- eval "lvremove --quiet -f \$dev$d" +- done +- ;; +- esac ++ case $DEVTYPE in ++ loop) ++ for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ++ do ++ losetup -d /dev/loop$d # rm -f $targetdir/mdtest$d ++ rm -f /dev/disk/by-path/loop* ++ done ++ ;; ++ lvm) ++ for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ++ do ++ eval "lvremove --quiet -f \$dev$d" ++ done ++ ;; ++ esac + } + + ctrl_c() { +@@ -91,329 +95,377 @@ ctrl_c() { + } + + do_setup() { +- trap cleanup 0 1 3 15 +- trap ctrl_c 2 ++ trap cleanup 0 1 3 15 ++ trap ctrl_c 2 + +- # make sure there are no loop devices remaining. +- # udev started things can sometimes prevent them being stopped +- # immediately +- while grep loop /proc/partitions > /dev/null 2>&1 +- do +- mdadm -Ss +- losetup -d /dev/loop[0-9]* 2> /dev/null +- sleep 1 +- done +- devlist= +- for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 +- do +- sz=$size +- if [ $d -gt 7 ]; then sz=$ddfsize ; fi +- case $DEVTYPE in +- loop) +- [ -f $targetdir/mdtest$d ] || 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 +- else +- losetup /dev/loop$d $targetdir/mdtest$d +- fi +- eval dev$d=/dev/loop$d +- eval file$d=$targetdir/mdtest$d +- ;; +- lvm) +- unset MULTIPATH +- eval dev$d=/dev/mapper/${LVM_VOLGROUP}-mdtest$d +- if ! lvcreate --quiet -L ${sz}K -n mdtest$d $LVM_VOLGROUP; then +- trap '' 0 # make sure lvremove is not called +- eval echo error creating \$dev$d +- exit 129 +- fi +- ;; +- ram) +- unset MULTIPATH +- eval dev$d=/dev/ram$d +- ;; +- esac +- eval devlist=\"\$devlist \$dev$d\" +- eval devlist$d=\"\$devlist\" +- #" <-- add this quote to un-confuse vim syntax highlighting +- done +- path0=$dev6 +- path1=$dev7 +- +- ulimit -c unlimited +- [ -f /proc/mdstat ] || modprobe md_mod +- echo 2000 > /proc/sys/dev/raid/speed_limit_max +- echo 0 > /sys/module/md_mod/parameters/start_ro ++ # make sure there are no loop devices remaining. ++ # udev started things can sometimes prevent them being stopped ++ # immediately ++ while grep loop /proc/partitions > /dev/null 2>&1 ++ do ++ mdadm -Ss ++ losetup -d /dev/loop[0-9]* 2> /dev/null ++ sleep 1 ++ done ++ devlist= ++ for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ++ do ++ sz=$size ++ if [ $d -gt 7 ] ++ then ++ sz=$ddfsize ++ fi ++ case $DEVTYPE in ++ loop) ++ [ -f $targetdir/mdtest$d ] || ++ 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 ++ else ++ losetup /dev/loop$d $targetdir/mdtest$d ++ fi ++ eval dev$d=/dev/loop$d ++ eval file$d=$targetdir/mdtest$d ++ ;; ++ lvm) ++ unset MULTIPATH ++ eval dev$d=/dev/mapper/${LVM_VOLGROUP}-mdtest$d ++ if ! lvcreate --quiet -L ${sz}K -n mdtest$d $LVM_VOLGROUP ++ then ++ trap '' 0 # make sure lvremove is not called ++ eval echo error creating \$dev$d ++ exit 129 ++ fi ++ ;; ++ ram) ++ unset MULTIPATH ++ eval dev$d=/dev/ram$d ++ ;; ++ esac ++ eval devlist=\"\$devlist \$dev$d\" ++ eval devlist$d=\"\$devlist\" ++ #" <-- add this quote to un-confuse vim syntax highlighting ++ done ++ path0=$dev6 ++ path1=$dev7 ++ ulimit -c unlimited ++ [ -f /proc/mdstat ] || modprobe md_mod ++ echo 2000 > /proc/sys/dev/raid/speed_limit_max ++ echo 0 > /sys/module/md_mod/parameters/start_ro + } + + # mdadm always adds --quiet, and we want to see any unexpected messages + mdadm() { +- rm -f $targetdir/stderr +- case $* in +- *-S* ) udevadm settle +- p=`cat /proc/sys/dev/raid/speed_limit_max` +- echo 20000 > /proc/sys/dev/raid/speed_limit_max +- esac +- case $* in +- *-C* ) $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes;; +- * ) $mdadm 2> $targetdir/stderr --quiet "$@" +- esac +- rv=$? +- case $* in +- *-S* ) udevadm settle +- echo $p > /proc/sys/dev/raid/speed_limit_max +- esac +- cat >&2 $targetdir/stderr +- return $rv ++ rm -f $targetdir/stderr ++ case $* in ++ *-S* ) ++ udevadm settle ++ p=`cat /proc/sys/dev/raid/speed_limit_max` ++ echo 20000 > /proc/sys/dev/raid/speed_limit_max ++ ;; ++ esac ++ case $* in ++ *-C* ) ++ $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes ++ ;; ++ * ) ++ $mdadm 2> $targetdir/stderr --quiet "$@" ++ ;; ++ esac ++ rv=$? ++ case $* in ++ *-S* ) ++ udevadm settle ++ echo $p > /proc/sys/dev/raid/speed_limit_max ++ ;; ++ esac ++ cat >&2 $targetdir/stderr ++ return $rv + } + + # check various things + check() { +- case $1 in +- spares ) +- spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0` +- if [ $spares -ne $2 ] +- then +- echo >&2 "ERROR expected $2 spares, found $spares"; exit 1; +- fi +- ;; +- raid* | linear ) +- grep -s "active $1 " /proc/mdstat > /dev/null || { +- echo >&2 "ERROR active $1 not found" ; cat /proc/mdstat ; exit 1;} +- ;; +- algorithm ) +- grep -s " algorithm $2 " /proc/mdstat > /dev/null || { +- echo >&2 "ERROR algorithm $2 not found"; cat /proc/mdstat; exit 1;} +- ;; +- resync | recovery | reshape) +- cnt=5 +- while ! grep -s $1 /proc/mdstat > /dev/null +- do +- if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null +- then # Something isn't idle - wait a bit ++ case $1 in ++ spares ) ++ spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0` ++ if [ $spares -ne $2 ] ++ then ++ echo >&2 "ERROR expected $2 spares, found $spares" ++ exit 1 ++ fi ++ ;; ++ raid* | linear ) ++ grep -s "active $1 " /proc/mdstat > /dev/null || { ++ echo >&2 "ERROR active $1 not found" ++ cat /proc/mdstat ++ exit 1 ++ } ++ ;; ++ algorithm ) ++ grep -s " algorithm $2 " /proc/mdstat > /dev/null || { ++ echo >&2 "ERROR algorithm $2 not found" ++ cat /proc/mdstat ++ exit 1 ++ } ++ ;; ++ resync | recovery | reshape ) ++ cnt=5 ++ while ! grep -s $1 /proc/mdstat > /dev/null ++ do ++ if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null ++ then # Something isn't idle - wait a bit ++ sleep 0.5 ++ cnt=$[cnt-1] ++ else ++ echo >&2 ERROR no $1 happening ++ cat /proc/mdstat ++ exit 1 ++ fi ++ done ++ ;; ++ nosync ) + sleep 0.5 +- cnt=$[cnt-1] +- else +- echo >&2 ERROR no $1 happening; cat /proc/mdstat; exit 1 +- fi +- done +- ;; +- +- nosync ) +- sleep 0.5 +- # Since 4.2 we delay the close of recovery until there has been a chance for +- # spares to be activated. That means that a recovery that finds nothing +- # to do can still take a little longer than expected. +- # add an extra check: is sync_completed shows the end is reached, assume +- # there is no recovery. +- if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat ; then +- incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'` +- if [ -n "$incomplete" ]; then +- echo >&2 "ERROR resync or recovery is happening!"; cat /proc/mdstat ; exit 1; +- fi +- fi +- ;; +- +- wait ) +- p=`cat /proc/sys/dev/raid/speed_limit_max` +- echo 2000000 > /proc/sys/dev/raid/speed_limit_max +- sleep 0.1 +- while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat || +- grep -v idle > /dev/null /sys/block/md*/md/sync_action +- do sleep 0.5; +- done +- echo $p > /proc/sys/dev/raid/speed_limit_max +- ;; +- +- state ) +- grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || { +- echo >&2 "ERROR state $2 not found!"; cat /proc/mdstat ; exit 1; } +- sleep 0.5 +- ;; +- +- bitmap ) +- grep -s bitmap > /dev/null /proc/mdstat || { +- echo >&2 ERROR no bitmap ; cat /proc/mdstat ; exit 1; } +- ;; +- nobitmap ) +- if grep -s "bitmap" > /dev/null /proc/mdstat +- then +- echo >&2 ERROR bitmap present ; cat /proc/mdstat ; exit 1; +- fi +- ;; +- +- readonly ) +- grep -s "read-only" > /dev/null /proc/mdstat || { +- echo >&2 "ERROR array is not read-only!"; cat /proc/mdstat ; exit 1; } +- ;; +- +- inactive ) +- grep -s "inactive" > /dev/null /proc/mdstat || { +- echo >&2 "ERROR array is not inactive!"; cat /proc/mdstat ; exit 1; } +- ;; +- * ) echo >&2 ERROR unknown check $1 ; exit 1; +- esac ++ # Since 4.2 we delay the close of recovery until there has been a chance for ++ # spares to be activated. That means that a recovery that finds nothing ++ # to do can still take a little longer than expected. ++ # add an extra check: is sync_completed shows the end is reached, assume ++ # there is no recovery. ++ if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat ++ then ++ incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'` ++ if [ -n "$incomplete" ] ++ then ++ echo >&2 "ERROR resync or recovery is happening!" ++ cat /proc/mdstat ++ exit 1 ++ fi ++ fi ++ ;; ++ wait ) ++ p=`cat /proc/sys/dev/raid/speed_limit_max` ++ echo 2000000 > /proc/sys/dev/raid/speed_limit_max ++ sleep 0.1 ++ while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat || ++ grep -v idle > /dev/null /sys/block/md*/md/sync_action ++ do ++ sleep 0.5 ++ done ++ echo $p > /proc/sys/dev/raid/speed_limit_max ++ ;; ++ state ) ++ grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || { ++ echo >&2 "ERROR state $2 not found!" ++ cat /proc/mdstat ++ exit 1 ++ } ++ sleep 0.5 ++ ;; ++ bitmap ) ++ grep -s bitmap > /dev/null /proc/mdstat || { ++ echo >&2 ERROR no bitmap ++ cat /proc/mdstat ++ exit 1 ++ } ++ ;; ++ nobitmap ) ++ if grep -s "bitmap" > /dev/null /proc/mdstat ++ then ++ echo >&2 ERROR bitmap present ++ cat /proc/mdstat ++ exit 1 ++ fi ++ ;; ++ readonly ) ++ grep -s "read-only" > /dev/null /proc/mdstat || { ++ echo >&2 "ERROR array is not read-only!" ++ cat /proc/mdstat ++ exit 1 ++ } ++ ;; ++ inactive ) ++ grep -s "inactive" > /dev/null /proc/mdstat || { ++ echo >&2 "ERROR array is not inactive!" ++ cat /proc/mdstat ++ exit 1 ++ } ++ ;; ++ * ) ++ echo >&2 ERROR unknown check $1 ++ exit 1 ++ ;; ++ esac + } + + no_errors() { +- if [ -s $targetdir/stderr ] +- then echo Bad errors from mdadm: ; cat $targetdir/stderr; exit 2; +- fi ++ if [ -s $targetdir/stderr ] ++ then ++ echo Bad errors from mdadm: ++ cat $targetdir/stderr ++ exit 2 ++ fi + } +-# basic device test + ++# basic device test + testdev() { +- udevadm settle +- dev=$1 +- cnt=$2 +- dvsize=$3 +- chunk=$4 +- if [ -z "$5" ]; then +- mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2 +- fi +- dsize=$[dvsize/chunk] +- dsize=$[dsize*chunk] +- rasize=$[dsize*2*cnt] +- # rasize is in sectors +- if [ -n "$DEV_ROUND_K" ]; then +- rasize=$[rasize/DEV_ROUND_K/2] +- rasize=$[rasize*DEV_ROUND_K*2] +- fi +- if [ `/sbin/blockdev --getsize $dev` -eq 0 ]; then sleep 2 ; fi +- _sz=`/sbin/blockdev --getsize $dev` +- if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] +- then +- echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz" +- exit 1 +- fi ++ udevadm settle ++ dev=$1 ++ cnt=$2 ++ dvsize=$3 ++ chunk=$4 ++ if [ -z "$5" ] ++ then ++ mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2 ++ fi ++ dsize=$[dvsize/chunk] ++ dsize=$[dsize*chunk] ++ rasize=$[dsize*2*cnt] ++ # rasize is in sectors ++ if [ -n "$DEV_ROUND_K" ] ++ then ++ rasize=$[rasize/DEV_ROUND_K/2] ++ rasize=$[rasize*DEV_ROUND_K*2] ++ fi ++ if [ `/sbin/blockdev --getsize $dev` -eq 0 ] ++ then ++ sleep 2 ++ fi ++ _sz=`/sbin/blockdev --getsize $dev` ++ if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] ++ then ++ echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz" ++ exit 1 ++ fi + } + + fast_sync() { +- echo 200000 > /proc/sys/dev/raid/speed_limit_max ++ echo 200000 > /proc/sys/dev/raid/speed_limit_max + } + + rotest() { +- dev=$1 +- fsck -fn $dev >&2 ++ dev=$1 ++ fsck -fn $dev >&2 + } + + do_test() { +- _script=$1 +- _basename=`basename $_script` +- if [ -f "$_script" ] +- then +- rm -f $targetdir/stderr +- # stop all arrays, just incase some script left an array active. +- $mdadm -Ssq 2> /dev/null +- mdadm --zero $devlist 2> /dev/null +- mdadm --zero $devlist 2> /dev/null +- # this might have been reset: restore the default. +- echo 2000 > /proc/sys/dev/raid/speed_limit_max +- # source script in a subshell, so it has access to our +- # namespace, but cannot change it. +- echo -ne "$_script... " +- if ( set -ex ; . $_script ) &> $targetdir/log +- then +- echo "succeeded" +- _fail=0 +- else +- log=log +- cat $targetdir/stderr >> $targetdir/log +- echo "=======================dmesg=================" >> $targetdir/log +- dmesg | tail -n 200 >> $targetdir/log +- if [ $exitonerror == 0 ]; then +- log=log-`basename $_script` +- mv $targetdir/log $logdir/$log +- fi +- echo "FAILED - see $logdir/$log for details" +- _fail=1 +- fi +- if [ "$savelogs" == "1" ]; then +- cp $targetdir/log $logdir/$_basename.log +- fi +- if [ "$_fail" == "1" -a "$exitonerror" == "1" ]; then +- exit 1 +- fi +- fi ++ _script=$1 ++ _basename=`basename $_script` ++ if [ -f "$_script" ] ++ then ++ rm -f $targetdir/stderr ++ # stop all arrays, just incase some script left an array active. ++ $mdadm -Ssq 2> /dev/null ++ mdadm --zero $devlist 2> /dev/null ++ mdadm --zero $devlist 2> /dev/null ++ # this might have been reset: restore the default. ++ echo 2000 > /proc/sys/dev/raid/speed_limit_max ++ # source script in a subshell, so it has access to our ++ # namespace, but cannot change it. ++ echo -ne "$_script... " ++ if ( set -ex ; . $_script ) &> $targetdir/log ++ then ++ echo "succeeded" ++ _fail=0 ++ else ++ log=log ++ cat $targetdir/stderr >> $targetdir/log ++ echo "=======================dmesg=================" >> $targetdir/log ++ dmesg | tail -n 200 >> $targetdir/log ++ if [ $exitonerror == 0 ]; then ++ log=log-`basename $_script` ++ mv $targetdir/log $logdir/$log ++ fi ++ echo "FAILED - see $logdir/$log for details" ++ _fail=1 ++ fi ++ if [ "$savelogs" == "1" ] ++ then ++ cp $targetdir/log $logdir/$_basename.log ++ fi ++ if [ "$_fail" == "1" -a "$exitonerror" == "1" ] ++ then ++ exit 1 ++ fi ++ fi + } + + do_help() { +- echo "Usage: $0 [options]" +- echo " Options:" +- echo " --tests= Comma separated list of tests to run" +- echo " --disable-multipath Disable any tests involving multipath" +- echo " --disable-integrity Disable slow tests of RAID[56] consistency" +- echo " --logdir= Directory to save logfiles in" +- echo " --save-logs Save all logs in " +- echo " --keep-going Don't stop on error, ie. run all tests" +- echo " --dev=[loop|lvm|ram] Use loop devices (default), LVM, or RAM disk" +- echo " --volgroup= LVM volume group for LVM test" +- echo " setup Setup test environment and exit" +- echo " cleanup Cleanup test environment" +- echo " Run tests with " ++ echo "Usage: $0 [options]" ++ echo " Options:" ++ echo " --tests= Comma separated list of tests to run" ++ echo " --disable-multipath Disable any tests involving multipath" ++ echo " --disable-integrity Disable slow tests of RAID[56] consistency" ++ echo " --logdir= Directory to save logfiles in" ++ echo " --save-logs Save all logs in " ++ echo " --keep-going Don't stop on error, ie. run all tests" ++ echo " --dev=[loop|lvm|ram] Use loop devices (default), LVM, or RAM disk" ++ echo " --volgroup= LVM volume group for LVM test" ++ echo " setup Setup test environment and exit" ++ echo " cleanup Cleanup test environment" ++ echo " Run tests with " + } + + parse_args() { +- for i in $* +- do +- case $i in +- [0-9]*) +- prefix=$i +- ;; +- setup) +- echo "mdadm test environment setup" +- do_setup +- trap 0; exit 0 +- ;; +- cleanup) +- cleanup +- exit 0 +- ;; +- --tests=*) +- TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'` +- ;; +- --logdir=*) +- logdir=`expr "x$i" : 'x[^=]*=\(.*\)'` +- ;; +- --save-logs) +- savelogs=1 +- ;; +- --keep-going | --no-error) +- exitonerror=0 +- ;; +- --disable-multipath) +- unset MULTIPATH +- ;; +- --disable-integrity) +- unset INTEGRITY +- ;; +- --dev=loop) +- DEVTYPE=loop +- ;; +- --dev=lvm) +- DEVTYPE=lvm +- ;; +- --dev=ram) +- DEVTYPE=ram +- ;; +- --volgroup=*) +- LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'` +- ;; +- --help) +- do_help +- exit 0; +- ;; +- -*) +- echo " $0: Unknown argument: $i" +- do_help +- exit 0; +- ;; +- esac +-done ++ for i in $* ++ do ++ case $i in ++ [0-9]* ) ++ prefix=$i ++ ;; ++ setup ) ++ echo "mdadm test environment setup" ++ do_setup ++ trap 0 ++ exit 0 ++ ;; ++ cleanup ) ++ cleanup ++ exit 0 ++ ;; ++ --tests=* ) ++ TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'` ++ ;; ++ --logdir=* ) ++ logdir=`expr "x$i" : 'x[^=]*=\(.*\)'` ++ ;; ++ --save-logs ) ++ savelogs=1 ++ ;; ++ --keep-going | --no-error ) ++ exitonerror=0 ++ ;; ++ --disable-multipath ) ++ unset MULTIPATH ++ ;; ++ --disable-integrity ) ++ unset INTEGRITY ++ ;; ++ --dev=loop ) ++ DEVTYPE=loop ++ ;; ++ --dev=lvm ) ++ DEVTYPE=lvm ++ ;; ++ --dev=ram ) ++ DEVTYPE=ram ++ ;; ++ --volgroup=* ) ++ LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'` ++ ;; ++ --help ) ++ do_help ++ exit 0 ++ ;; ++ -* ) ++ echo " $0: Unknown argument: $i" ++ do_help ++ exit 0 ++ ;; ++ esac ++ done + } + + logdir=$targetdir +@@ -422,19 +474,21 @@ parse_args $@ + do_setup + mkdir -p $logdir + +-if [ "$savelogs" == "1" ]; then +- echo "Saving logs to $logdir" ++if [ "$savelogs" == "1" ] ++then ++ echo "Saving logs to $logdir" + fi + +-if [ "x$TESTLIST" != "x" ]; then +- for script in $TESTLIST +- do +- do_test $testdir/$script +- done ++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 ++ for script in $testdir/$prefix $testdir/$prefix*[^~] ++ do ++ do_test $script ++ done + fi + exit 0 +-- +2.7.4 + diff --git a/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch b/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch new file mode 100644 index 0000000..c5cc6ff --- /dev/null +++ b/SOURCES/mdadm-test-Refactor-and-revamp-test-script.patch @@ -0,0 +1,643 @@ +From 20d10b4be873baf6044304702808bd66ce84299c Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Wed, 14 Jun 2017 21:02:51 +0800 +Subject: [RHEL7.5 PATCH 155/169] mdadm/test: Refactor and revamp 'test' + script + +Adding functions: +die() + uniform the abnormal situations that have to abort. +check_env() + do various basic checking before running test suite. +save_log() + collect array infos, include of dmesg, superblock, + bitmap and /proc/mdstat. +main() + the core function of this script. + +Improve functions: +cleanup() + clear dmesg and remove the /var/tmp/mdtest* files. +mdadm() + clear superblock once creating or building arrays + every time, because it's always creating arrays + many times in a test case. +check() + just tidy up with die(), didn't change code meanings. +testdev() + add checking $1 must be a block device, add 'return 0' + in final because this function exists in last line of + test case, such as tests/05r6tor0. +do_test() + add checking abnormal dmesg and changing log management. +do_help() + just recommend a better way to print Usage. +parse_args() + revamp and improve. + +Delete function: +fast_sync() + It's no longer used, so get rid of it. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + test | 408 +++++++++++++++++++++++++++++++++++++------------------------------ + 1 file changed, 228 insertions(+), 180 deletions(-) + +diff --git a/test b/test +index 7942d6e..7ee523b 100755 +--- a/test ++++ b/test +@@ -1,37 +1,20 @@ + #!/bin/bash + # + # run test suite for mdadm +-user=`id -un` +-if [ " $user" != " root" ] +-then +- echo >&2 "test: testing can only be done as 'root'." +- exit 1 +-fi +- +-prefix='[0-9][0-9]' +- +-dir=`pwd` ++dir=$(pwd) + mdadm=$dir/mdadm +-if [ \! -x $mdadm ] +-then +- echo >&2 "test: $mdadm isn't usable." +-fi +- + testdir="tests" +-logdir="$testdir/logs" +-logsave=0 +-exitonerror=1 ++targetdir="/var/tmp" ++logdir="$targetdir" ++config=/tmp/mdadm.conf + +-echo "Testing on linux-$(uname -r) kernel" ++savelogs=0 ++exitonerror=1 ++prefix='[0-9][0-9]' + +-# Check whether to run multipath tests +-modprobe multipath 2> /dev/null +-if grep -s 'Personalities : .*multipath' > /dev/null /proc/mdstat +-then +- MULTIPATH="yes" +-fi +-INTEGRITY=yes ++# use loop devices by default if doesn't specify --dev + DEVTYPE=loop ++INTEGRITY=yes + LVM_VOLGROUP=mdtest + + # make sure to test local mdmon, not system one +@@ -46,7 +29,6 @@ mdp1=/dev/md_d1 + + # We test mdadm on loop-back block devices. + # dir for storing files should be settable by command line maybe +-targetdir=/var/tmp + size=20000 + # super0, round down to multiple of 64 and substract 64 + mdsize0=19904 +@@ -68,20 +50,65 @@ mdsize12=19988 + # ddf needs bigger devices as 32Meg is reserved! + ddfsize=65536 + +-config=/tmp/mdadm.conf ++# $1 is optional parameter, it shows why to save log ++save_log() { ++ status=$1 ++ logfile="$status""$_basename".log ++ ++ cat $targetdir/stderr >> $targetdir/log ++ cp $targetdir/log $logdir/$_basename.log ++ echo "## $HOSTNAME: saving dmesg." >> $logdir/$logfile ++ dmesg -c >> $logdir/$logfile ++ $mdadm -As 2> /dev/null ++ echo "## $HOSTNAME: saving proc mdstat." >> $logdir/$logfile ++ cat /proc/mdstat >> $logdir/$logfile ++ array=($(mdadm -Ds | cut -d' ' -f2)) ++ echo "## $HOSTNAME: mdadm -D ${array[@]}" >> $logdir/$logfile ++ $mdadm -D ${array[@]} >> $logdir/$logfile ++ [ "$1" == "fail" ] && ++ echo "FAILED - see $logdir/$_basename.log and $logdir/$logfile for details" ++ # ignore saving external(external file, imsm...) bitmap ++ cat /proc/mdstat | grep -q "linear\|external" && return 0 ++ if [ $DEVTYPE == 'lvm' ] ++ then ++ # not supported lvm type yet ++ echo ++ elif [ $DEVTYPE == 'loop' ] ++ then ++ if [ ! -z ${array[@]} -a ${#array[@]} -ge 1 ] ++ then ++ md_disks=($($mdadm -D -Y ${array[@]} | grep "/dev/$DEVTYPE" | cut -d'=' -f2)) ++ cat /proc/mdstat | grep -q "bitmap" ++ if [ $? -eq 0 ] ++ then ++ echo "## $HOSTNAME: mdadm -X ${md_disks[@]}" >> $logdir/$logfile ++ $mdadm -X ${md_disks[@]} >> $logdir/$logfile ++ fi ++ else ++ echo "## $HOSTNAME: no array assembled!" >> $logdir/$logfile ++ fi ++ fi ++} ++ ++die() { ++ echo -e "\n\tERROR: $* \n" ++ save_log fail ++ exit 2 ++} + + cleanup() { + udevadm settle + $mdadm -Ssq 2> /dev/null + case $DEVTYPE in +- loop) ++ loop ) + for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + do +- losetup -d /dev/loop$d # rm -f $targetdir/mdtest$d ++ losetup -d /dev/loop$d + rm -f /dev/disk/by-path/loop* ++ rm -f /var/tmp/mdtest$d + done + ;; +- lvm) ++ lvm ) + for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + do + eval "lvremove --quiet -f \$dev$d" +@@ -98,23 +125,26 @@ do_setup() { + trap cleanup 0 1 3 15 + trap ctrl_c 2 + +- # make sure there are no loop devices remaining. +- # udev started things can sometimes prevent them being stopped +- # immediately +- while grep loop /proc/partitions > /dev/null 2>&1 +- do +- mdadm -Ss +- losetup -d /dev/loop[0-9]* 2> /dev/null +- sleep 1 +- done ++ [ -d $logdir ] || mkdir -p $logdir ++ dmesg -c > /dev/null ++ ++ if [ "$DEVTYPE" == "loop" ] ++ then ++ # make sure there are no loop devices remaining. ++ # udev started things can sometimes prevent them being stopped ++ # immediately ++ while grep loop /proc/partitions > /dev/null 2>&1 ++ do ++ $mdadm -Ssq ++ losetup -d /dev/loop[0-9]* 2> /dev/null ++ sleep 0.2 ++ done ++ fi + devlist= + for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + do + sz=$size +- if [ $d -gt 7 ] +- then +- sz=$ddfsize +- fi ++ [ $d -gt 7 ] && sz=$ddfsize + case $DEVTYPE in + loop) + [ -f $targetdir/mdtest$d ] || +@@ -169,7 +199,17 @@ mdadm() { + ;; + esac + case $* in +- *-C* ) ++ *-C* | *--create* | *-B* | *--build* ) ++ # clear superblock every time once creating or ++ # building arrays, because it's always creating ++ # and building array many times in a test case. ++ for args in $* ++ do ++ [[ $args =~ "/dev/" ]] && { ++ [[ $args =~ "md" ]] || ++ $mdadm --zero $args > /dev/null ++ } ++ done + $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes + ;; + * ) +@@ -191,39 +231,28 @@ mdadm() { + check() { + case $1 in + spares ) +- spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0` +- if [ $spares -ne $2 ] +- then +- echo >&2 "ERROR expected $2 spares, found $spares" +- exit 1 +- fi ++ spares=$(tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0) ++ [ $spares -ne $2 ] && ++ die "expected $2 spares, found $spares" + ;; + raid* | linear ) +- grep -s "active $1 " /proc/mdstat > /dev/null || { +- echo >&2 "ERROR active $1 not found" +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq "active $1 " /proc/mdstat || ++ die "active $1 not found" + ;; + algorithm ) +- grep -s " algorithm $2 " /proc/mdstat > /dev/null || { +- echo >&2 "ERROR algorithm $2 not found" +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq " algorithm $2 " /proc/mdstat || ++ die "algorithm $2 not found" + ;; + resync | recovery | reshape ) + cnt=5 +- while ! grep -s $1 /proc/mdstat > /dev/null ++ while ! grep -sq $1 /proc/mdstat + do + if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null + then # Something isn't idle - wait a bit + sleep 0.5 + cnt=$[cnt-1] + else +- echo >&2 ERROR no $1 happening +- cat /proc/mdstat +- exit 1 ++ die "no $1 happening" + fi + done + ;; +@@ -234,22 +263,18 @@ check() { + # to do can still take a little longer than expected. + # add an extra check: is sync_completed shows the end is reached, assume + # there is no recovery. +- if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat ++ if grep -sq -E '(resync|recovery|reshape) *=' /proc/mdstat + then + incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'` +- if [ -n "$incomplete" ] +- then +- echo >&2 "ERROR resync or recovery is happening!" +- cat /proc/mdstat +- exit 1 +- fi ++ [ -n "$incomplete" ] && ++ die "resync or recovery is happening!" + fi + ;; + wait ) + p=`cat /proc/sys/dev/raid/speed_limit_max` + echo 2000000 > /proc/sys/dev/raid/speed_limit_max + sleep 0.1 +- while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat || ++ while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat || + grep -v idle > /dev/null /sys/block/md*/md/sync_action + do + sleep 0.5 +@@ -257,45 +282,28 @@ check() { + echo $p > /proc/sys/dev/raid/speed_limit_max + ;; + state ) +- grep -s "blocks.*\[$2\]\$" /proc/mdstat > /dev/null || { +- echo >&2 "ERROR state $2 not found!" +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq "blocks.*\[$2\]\$" /proc/mdstat || ++ die "state $2 not found!" + sleep 0.5 + ;; + bitmap ) +- grep -s bitmap > /dev/null /proc/mdstat || { +- echo >&2 ERROR no bitmap +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq bitmap /proc/mdstat || ++ die "no bitmap" + ;; + nobitmap ) +- if grep -s "bitmap" > /dev/null /proc/mdstat +- then +- echo >&2 ERROR bitmap present +- cat /proc/mdstat +- exit 1 +- fi ++ grep -sq "bitmap" /proc/mdstat && ++ die "bitmap present" + ;; + readonly ) +- grep -s "read-only" > /dev/null /proc/mdstat || { +- echo >&2 "ERROR array is not read-only!" +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq "read-only" /proc/mdstat || ++ die "array is not read-only!" + ;; + inactive ) +- grep -s "inactive" > /dev/null /proc/mdstat || { +- echo >&2 "ERROR array is not inactive!" +- cat /proc/mdstat +- exit 1 +- } ++ grep -sq "inactive" /proc/mdstat || ++ die "array is not inactive!" + ;; + * ) +- echo >&2 ERROR unknown check $1 +- exit 1 ++ die "unknown check $1" + ;; + esac + } +@@ -311,6 +319,7 @@ no_errors() { + + # basic device test + testdev() { ++ [ -b $1 ] || die "$1 isn't a block device." + udevadm settle + dev=$1 + cnt=$2 +@@ -329,20 +338,11 @@ testdev() { + rasize=$[rasize/DEV_ROUND_K/2] + rasize=$[rasize*DEV_ROUND_K*2] + fi +- if [ `/sbin/blockdev --getsize $dev` -eq 0 ] +- then +- sleep 2 +- fi ++ [ `/sbin/blockdev --getsize $dev` -eq 0 ] && sleep 2 + _sz=`/sbin/blockdev --getsize $dev` +- if [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] +- then +- echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz" +- exit 1 +- fi +-} +- +-fast_sync() { +- echo 200000 > /proc/sys/dev/raid/speed_limit_max ++ [ $rasize -lt $_sz -o $[rasize*4/5] -gt $_sz ] && ++ die "size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not $_sz" ++ return 0 + } + + rotest() { +@@ -359,7 +359,6 @@ do_test() { + # stop all arrays, just incase some script left an array active. + $mdadm -Ssq 2> /dev/null + mdadm --zero $devlist 2> /dev/null +- mdadm --zero $devlist 2> /dev/null + # this might have been reset: restore the default. + echo 2000 > /proc/sys/dev/raid/speed_limit_max + # source script in a subshell, so it has access to our +@@ -367,52 +366,44 @@ 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!" + echo "succeeded" + _fail=0 + else +- log=log +- cat $targetdir/stderr >> $targetdir/log +- echo "=======================dmesg=================" >> $targetdir/log +- dmesg | tail -n 200 >> $targetdir/log +- if [ $exitonerror == 0 ]; then +- log=log-`basename $_script` +- mv $targetdir/log $logdir/$log +- fi +- echo "FAILED - see $logdir/$log for details" ++ save_log fail + _fail=1 + fi +- if [ "$savelogs" == "1" ] +- then +- cp $targetdir/log $logdir/$_basename.log +- fi +- if [ "$_fail" == "1" -a "$exitonerror" == "1" ] +- then +- exit 1 +- fi ++ [ "$savelogs" == "1" ] && ++ mv -f $targetdir/log $logdir/$_basename.log ++ [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1 + fi + } + + do_help() { +- echo "Usage: $0 [options]" +- echo " Options:" +- echo " --tests= Comma separated list of tests to run" +- echo " --disable-multipath Disable any tests involving multipath" +- echo " --disable-integrity Disable slow tests of RAID[56] consistency" +- echo " --logdir= Directory to save logfiles in" +- echo " --save-logs Save all logs in " +- echo " --keep-going Don't stop on error, ie. run all tests" +- echo " --dev=[loop|lvm|ram] Use loop devices (default), LVM, or RAM disk" +- echo " --volgroup= LVM volume group for LVM test" +- echo " setup Setup test environment and exit" +- echo " cleanup Cleanup test environment" +- echo " Run tests with " ++ cat <<-EOF ++ Usage: $0 [options] ++ Options: ++ --tests=test1,test2,... Comma separated list of tests to run ++ --disable-multipath Disable any tests involving multipath ++ --disable-integrity Disable slow tests of RAID[56] consistency ++ --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 ++ --dev=loop|lvm|ram Use loop devices (default), LVM, or RAM disk ++ --volgroup=name LVM volume group for LVM test ++ setup Setup test environment and exit ++ cleanup Cleanup test environment ++ prefix Run tests with ++ --help | -h Print this usage ++ EOF + } + + parse_args() { + for i in $* + do + case $i in +- [0-9]* ) ++ [0-9][0-9] ) + prefix=$i + ;; + setup ) +@@ -426,10 +417,10 @@ parse_args() { + exit 0 + ;; + --tests=* ) +- TESTLIST=`expr "x$i" : 'x[^=]*=\(.*\)' | sed -e 's/,/ /g'` ++ TESTLIST=($(echo ${i##*=} | sed -e 's/,/ /g')) + ;; + --logdir=* ) +- logdir=`expr "x$i" : 'x[^=]*=\(.*\)'` ++ logdir="${i##*=}" + ;; + --save-logs ) + savelogs=1 +@@ -443,52 +434,109 @@ parse_args() { + --disable-integrity ) + unset INTEGRITY + ;; +- --dev=loop ) +- DEVTYPE=loop +- ;; +- --dev=lvm ) +- DEVTYPE=lvm +- ;; +- --dev=ram ) +- DEVTYPE=ram ++ --dev=* ) ++ case ${i##*=} in ++ loop ) ++ DEVTYPE=loop ++ ;; ++ lvm ) ++ DEVTYPE=lvm ++ ;; ++ ram ) ++ DEVTYPE=ram ++ ;; ++ * ) ++ echo "Unknown argument: $i" ++ do_help ++ exit 1 ++ ;; ++ esac + ;; + --volgroup=* ) + LVM_VOLGROUP=`expr "x$i" : 'x[^=]*=\(.*\)'` + ;; +- --help ) ++ --help | -h ) + do_help + exit 0 + ;; +- -* ) ++ * ) + echo " $0: Unknown argument: $i" + do_help +- exit 0 ++ exit 1 + ;; + esac + done + } + +-logdir=$targetdir +-parse_args $@ ++check_env() { ++ user=$(id -un) ++ [ "X$user" != "Xroot" ] && { ++ echo "test: testing can only be done as 'root'." ++ exit 1 ++ } ++ [ -x "raid6check" -a -x $mdadm ] || { ++ echo "test: please run 'make everything' before perform testing." ++ exit 1 ++ } ++ cmds=(mdadm lsblk df udevadm losetup mkfs.ext3 fsck) ++ for cmd in ${cmds[@]} ++ do ++ which $cmd > /dev/null || { ++ echo "$cmd command not found!" ++ exit 1 ++ } ++ done ++ mdadm_src_ver="$($mdadm -V 2>&1)" ++ mdadm_sbin_ver="$($(which mdadm) -V 2>&1)" ++ if [ "$mdadm_src_ver" != "$mdadm_sbin_ver" ] ++ then ++ # it's nessesary to 'make install' mdadm to /SBIN/DIR, ++ # such as systemd/mdadm-grow-continue@.service, would ++ # run as an instance by systemd when reshape happens, ++ # thus ensure that the correct mdadm is in testing. ++ echo "test: please run 'make install' before testing." ++ exit 1 ++ fi ++ if ! $(df -T . | grep -iq ext) ++ then ++ # 'external file' bitmap only supports with ext[2-4] file system ++ echo "test: please run test suite with ext[2-4] file system." ++ exit 1 ++ fi ++ if $(lsblk -a | grep -iq raid) ++ then ++ # donot run mdadm -Ss directly if there are RAIDs working. ++ echo "test: please run test suite without running RAIDs environment." ++ exit 1 ++ fi ++ # Check whether to run multipath tests ++ modprobe multipath 2> /dev/null ++ grep -sq 'Personalities : .*multipath' /proc/mdstat && ++ MULTIPATH="yes" ++} + +-do_setup +-mkdir -p $logdir ++main() { ++ check_env ++ do_setup + +-if [ "$savelogs" == "1" ] +-then +- echo "Saving logs to $logdir" +-fi ++ 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 + +-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 +-exit 0 ++ exit 0 ++} ++ ++parse_args $@ ++main +-- +2.7.4 + diff --git a/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch b/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch new file mode 100644 index 0000000..cd66d54 --- /dev/null +++ b/SOURCES/mdadm-util-unify-fstat-checking-blkdev1-into-function.patch @@ -0,0 +1,439 @@ +From 0a6bff09d41650f27136d56a0604c9af46b6f583 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Thu, 4 May 2017 20:16:21 +0800 +Subject: [RHEL7.5 PATCH 109/169] mdadm/util: unify fstat checking blkdev + into function + +declare function fstat_is_blkdev() to integrate repeated fstat +checking block device operations, it returns true/1 when it is +a block device, and returns false/0 when it isn't. +The fd and devname are necessary parameters, *rdev is optional, +parse the pointer of dev_t *rdev, if valid, assigned the device +number to dev_t *rdev, if NULL, ignores. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Assemble.c | 19 +++++++------------ + Build.c | 5 +++-- + Create.c | 23 ++++++++++------------- + Grow.c | 10 ++++------ + Incremental.c | 33 ++++++++++++--------------------- + Manage.c | 2 +- + bitmap.c | 13 ++++--------- + mdadm.h | 1 + + super-intel.c | 13 +++---------- + util.c | 17 +++++++++++++++++ + 10 files changed, 62 insertions(+), 74 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index a9442c8..9d0a89f 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -149,6 +149,7 @@ static int select_devices(struct mddev_dev *devlist, + struct mdinfo *content = NULL; + int report_mismatch = ((inargv && c->verbose >= 0) || c->verbose > 0); + struct domainlist *domains = NULL; ++ dev_t rdev; + + tmpdev = devlist; num_devs = 0; + while (tmpdev) { +@@ -169,7 +170,6 @@ static int select_devices(struct mddev_dev *devlist, + tmpdev = tmpdev ? tmpdev->next : NULL) { + char *devname = tmpdev->devname; + int dfd; +- struct stat stb; + struct supertype *tst; + struct dev_policy *pol = NULL; + int found_container = 0; +@@ -204,14 +204,7 @@ static int select_devices(struct mddev_dev *devlist, + pr_err("cannot open device %s: %s\n", + devname, strerror(errno)); + tmpdev->used = 2; +- } else if (fstat(dfd, &stb)< 0) { +- /* Impossible! */ +- pr_err("fstat failed for %s: %s\n", +- devname, strerror(errno)); +- tmpdev->used = 2; +- } else if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- pr_err("%s is not a block device.\n", +- devname); ++ } else if (!fstat_is_blkdev(dfd, devname, &rdev)) { + tmpdev->used = 2; + } else if (must_be_container(dfd)) { + if (st) { +@@ -234,7 +227,8 @@ static int select_devices(struct mddev_dev *devlist, + devname); + tmpdev->used = 2; + } else if (auto_assem && +- !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)), ++ !conf_test_metadata(tst->ss->name, ++ (pol = devid_policy(rdev)), + tst->ss->match_home(tst, c->homehost) == 1)) { + if (report_mismatch) + pr_err("%s has metadata type %s for which auto-assembly is disabled\n", +@@ -261,7 +255,8 @@ static int select_devices(struct mddev_dev *devlist, + tst->ss->name, devname); + tmpdev->used = 2; + } else if (auto_assem && st == NULL && +- !conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)), ++ !conf_test_metadata(tst->ss->name, ++ (pol = devid_policy(rdev)), + tst->ss->match_home(tst, c->homehost) == 1)) { + if (report_mismatch) + pr_err("%s has metadata type %s for which auto-assembly is disabled\n", +@@ -484,7 +479,7 @@ static int select_devices(struct mddev_dev *devlist, + /* Collect domain information from members only */ + if (tmpdev && tmpdev->used == 1) { + if (!pol) +- pol = devid_policy(stb.st_rdev); ++ pol = devid_policy(rdev); + domain_merge(&domains, pol, tst?tst->ss->name:NULL); + } + dev_policy_free(pol); +diff --git a/Build.c b/Build.c +index 665d906..2d84b96 100644 +--- a/Build.c ++++ b/Build.c +@@ -42,6 +42,7 @@ int Build(char *mddev, struct mddev_dev *devlist, + */ + int i; + struct stat stb; ++ dev_t rdev; + int subdevs = 0, missing_disks = 0; + struct mddev_dev *dv; + int bitmap_fd; +@@ -126,8 +127,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + array.nr_disks = s->raiddisks; + array.raid_disks = s->raiddisks; + array.md_minor = 0; +- if (fstat(mdfd, &stb) == 0) +- array.md_minor = minor(stb.st_rdev); ++ if (fstat_is_blkdev(mdfd, mddev, &rdev)) ++ array.md_minor = minor(rdev); + array.not_persistent = 1; + array.state = 0; /* not clean, but no errors */ + if (s->assume_clean) +diff --git a/Create.c b/Create.c +index df1bc20..239545f 100644 +--- a/Create.c ++++ b/Create.c +@@ -89,8 +89,8 @@ int Create(struct supertype *st, char *mddev, + char *maxdisc = NULL; + int dnum, raid_disk_num; + struct mddev_dev *dv; ++ dev_t rdev; + int fail = 0, warn = 0; +- struct stat stb; + int first_missing = subdevs * 2; + int second_missing = subdevs * 2; + int missing_disks = 0; +@@ -325,11 +325,8 @@ int Create(struct supertype *st, char *mddev, + dname, strerror(errno)); + exit(2); + } +- if (fstat(dfd, &stb) != 0 || +- (stb.st_mode & S_IFMT) != S_IFBLK) { ++ if (!fstat_is_blkdev(dfd, dname, NULL)) { + close(dfd); +- pr_err("%s is not a block device\n", +- dname); + exit(2); + } + close(dfd); +@@ -641,8 +638,8 @@ int Create(struct supertype *st, char *mddev, + * with, but it chooses to trust me instead. Sigh + */ + info.array.md_minor = 0; +- if (fstat(mdfd, &stb) == 0) +- info.array.md_minor = minor(stb.st_rdev); ++ if (fstat_is_blkdev(mdfd, mddev, &rdev)) ++ info.array.md_minor = minor(rdev); + info.array.not_persistent = 0; + + if (((s->level == 4 || s->level == 5) && +@@ -841,7 +838,6 @@ int Create(struct supertype *st, char *mddev, + for (dnum = 0, raid_disk_num = 0, dv = devlist; dv; + dv = (dv->next) ? (dv->next) : moved_disk, dnum++) { + int fd; +- struct stat stb2; + struct mdinfo *inf = &infos[dnum]; + + if (dnum >= total_slots) +@@ -897,9 +893,10 @@ int Create(struct supertype *st, char *mddev, + dv->devname); + goto abort_locked; + } +- fstat(fd, &stb2); +- inf->disk.major = major(stb2.st_rdev); +- inf->disk.minor = minor(stb2.st_rdev); ++ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) ++ return 1; ++ inf->disk.major = major(rdev); ++ inf->disk.minor = minor(rdev); + } + if (fd >= 0) + remove_partitions(fd); +@@ -920,8 +917,8 @@ int Create(struct supertype *st, char *mddev, + + if (!have_container) { + /* getinfo_super might have lost these ... */ +- inf->disk.major = major(stb2.st_rdev); +- inf->disk.minor = minor(stb2.st_rdev); ++ inf->disk.major = major(rdev); ++ inf->disk.minor = minor(rdev); + } + break; + case 2: +diff --git a/Grow.c b/Grow.c +index f4bd301..a527436 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -109,7 +109,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + */ + struct mdinfo info; + +- struct stat stb; ++ dev_t rdev; + int nfd, fd2; + int d, nd; + struct supertype *st = NULL; +@@ -145,9 +145,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + free(st); + return 1; + } +- fstat(nfd, &stb); +- if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- pr_err("%s is not a block device!\n", newdev); ++ if (!fstat_is_blkdev(nfd, newdev, &rdev)) { + close(nfd); + free(st); + return 1; +@@ -198,8 +196,8 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + */ + + info.disk.number = d; +- info.disk.major = major(stb.st_rdev); +- info.disk.minor = minor(stb.st_rdev); ++ info.disk.major = major(rdev); ++ info.disk.minor = minor(rdev); + info.disk.raid_disk = d; + info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); + st->ss->update_super(st, &info, "linear-grow-new", newdev, +diff --git a/Incremental.c b/Incremental.c +index 8909f2f..11a34e7 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -87,6 +87,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + * start the array (auto-readonly). + */ + struct stat stb; ++ dev_t rdev; + struct mdinfo info, dinfo; + struct mdinfo *sra = NULL, *d; + struct mddev_ident *match; +@@ -174,21 +175,11 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + /* 2/ Find metadata, reject if none appropriate (check + * version/name from args) */ + +- if (fstat(dfd, &stb) < 0) { +- if (c->verbose >= 0) +- pr_err("fstat failed for %s: %s.\n", +- devname, strerror(errno)); +- goto out; +- } +- if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- if (c->verbose >= 0) +- pr_err("%s is not a block device.\n", +- devname); ++ if (!fstat_is_blkdev(dfd, devname, &rdev)) + goto out; +- } + +- dinfo.disk.major = major(stb.st_rdev); +- dinfo.disk.minor = minor(stb.st_rdev); ++ dinfo.disk.major = major(rdev); ++ dinfo.disk.minor = minor(rdev); + + policy = disk_policy(&dinfo); + have_target = policy_check_path(&dinfo, &target_array); +@@ -339,8 +330,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + } + + dinfo = info; +- dinfo.disk.major = major(stb.st_rdev); +- dinfo.disk.minor = minor(stb.st_rdev); ++ dinfo.disk.major = major(rdev); ++ dinfo.disk.minor = minor(rdev); + if (add_disk(mdfd, st, &info, &dinfo) != 0) { + pr_err("failed to add %s to new array %s: %s.\n", + devname, chosen_name, strerror(errno)); +@@ -441,8 +432,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + goto out_unlock; + } + } +- info.disk.major = major(stb.st_rdev); +- info.disk.minor = minor(stb.st_rdev); ++ info.disk.major = major(rdev); ++ info.disk.minor = minor(rdev); + /* add disk needs to know about containers */ + if (st->ss->external) + sra->array.level = LEVEL_CONTAINER; +@@ -863,12 +854,12 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + * Return 0 on success, or some exit code on failure, probably 1. + */ + int rv = 1; +- struct stat stb; ++ dev_t rdev; + struct map_ent *mp, *map = NULL; + struct mdinfo *chosen = NULL; + int dfd = *dfdp; + +- if (fstat(dfd, &stb) != 0) ++ if (!fstat_is_blkdev(dfd, devname, &rdev)) + return 1; + + /* +@@ -1038,8 +1029,8 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + devlist.writemostly = FlagDefault; + devlist.failfast = FlagDefault; + devlist.devname = chosen_devname; +- sprintf(chosen_devname, "%d:%d", major(stb.st_rdev), +- minor(stb.st_rdev)); ++ sprintf(chosen_devname, "%d:%d", major(rdev), ++ minor(rdev)); + devlist.disposition = 'a'; + close(dfd); + *dfdp = -1; +diff --git a/Manage.c b/Manage.c +index 230309b..af55266 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1513,7 +1513,7 @@ int Manage_subdevs(char *devname, int fd, + struct stat stb; + tfd = dev_open(dv->devname, O_RDONLY); + if (tfd >= 0) { +- fstat(tfd, &stb); ++ fstat_is_blkdev(tfd, dv->devname, &rdev); + close(tfd); + } else { + int open_err = errno; +diff --git a/bitmap.c b/bitmap.c +index 16a6b73..3653660 100644 +--- a/bitmap.c ++++ b/bitmap.c +@@ -183,7 +183,6 @@ static int + bitmap_file_open(char *filename, struct supertype **stp, int node_num) + { + int fd; +- struct stat stb; + struct supertype *st = *stp; + + fd = open(filename, O_RDONLY|O_DIRECT); +@@ -193,14 +192,7 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num) + return -1; + } + +- if (fstat(fd, &stb) < 0) { +- pr_err("failed to determine bitmap file/device type: %s\n", +- strerror(errno)); +- close(fd); +- return -1; +- } +- +- if ((stb.st_mode & S_IFMT) == S_IFBLK) { ++ if (fstat_is_blkdev(fd, filename, NULL)) { + /* block device, so we are probably after an internal bitmap */ + if (!st) + st = guess_super(fd); +@@ -221,6 +213,9 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num) + } + + *stp = st; ++ } else { ++ close(fd); ++ return -1; + } + + return fd; +diff --git a/mdadm.h b/mdadm.h +index 07ee963..4adb840 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1434,6 +1434,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 int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); + + extern int get_mdp_major(void); + extern int get_maj_min(char *dev, int *major, int *minor); +diff --git a/super-intel.c b/super-intel.c +index 36f77d3..c4196ea 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6562,7 +6562,7 @@ count_volumes_list(struct md_list *devlist, char *homehost, + + for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) { + char *devname = tmpdev->devname; +- struct stat stb; ++ dev_t rdev; + struct supertype *tst; + int dfd; + if (tmpdev->used > 1) +@@ -6578,14 +6578,7 @@ count_volumes_list(struct md_list *devlist, char *homehost, + dprintf("cannot open device %s: %s\n", + devname, strerror(errno)); + tmpdev->used = 2; +- } else if (fstat(dfd, &stb)< 0) { +- /* Impossible! */ +- dprintf("fstat failed for %s: %s\n", +- devname, strerror(errno)); +- tmpdev->used = 2; +- } else if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- dprintf("%s is not a block device.\n", +- devname); ++ } else if (!fstat_is_blkdev(dfd, devname, &rdev)) { + tmpdev->used = 2; + } else if (must_be_container(dfd)) { + struct supertype *cst; +@@ -6607,7 +6600,7 @@ count_volumes_list(struct md_list *devlist, char *homehost, + if (cst) + cst->ss->free_super(cst); + } else { +- tmpdev->st_rdev = stb.st_rdev; ++ tmpdev->st_rdev = rdev; + if (tst->ss->load_super(tst,dfd, NULL)) { + dprintf("no RAID superblock on %s\n", + devname); +diff --git a/util.c b/util.c +index c7585ac..a92faf8 100644 +--- a/util.c ++++ b/util.c +@@ -730,6 +730,23 @@ int check_raid(int fd, char *name) + return 1; + } + ++int fstat_is_blkdev(int fd, char *devname, dev_t *rdev) ++{ ++ struct stat stb; ++ ++ if (fstat(fd, &stb) != 0) { ++ pr_err("fstat failed for %s: %s\n", devname, strerror(errno)); ++ return 0; ++ } ++ if ((S_IFMT & stb.st_mode) != S_IFBLK) { ++ pr_err("%s is not a block device.\n", devname); ++ return 0; ++ } ++ if (rdev) ++ *rdev = stb.st_rdev; ++ return 1; ++} ++ + int ask(char *mesg) + { + char *add = ""; +-- +2.7.4 + diff --git a/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch b/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch new file mode 100644 index 0000000..b671e28 --- /dev/null +++ b/SOURCES/mdadm-util-unify-stat-checking-blkdev-into-function.patch @@ -0,0 +1,335 @@ +From 9e04ac1c43e63eccb68eb196174069e5c23d0270 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Fri, 5 May 2017 11:09:41 +0800 +Subject: [RHEL7.5 PATCH 110/169] mdadm/util: unify stat checking blkdev + into function + +declare function stat_is_blkdev() to integrate repeated stat +checking blkdev operations, it returns 'true/1' when it is a +block device, and returns 'false/0' when it isn't. +The devname is necessary parameter, *rdev is optional, parse +the pointer of dev_t *rdev, if valid, assigned device number +to dev_t *rdev, if NULL, ignores. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Assemble.c | 7 ++----- + Build.c | 25 ++++--------------------- + Incremental.c | 21 ++++----------------- + Manage.c | 11 +---------- + Monitor.c | 16 ++++------------ + mdadm.h | 1 + + super-ddf.c | 10 ++++------ + super-intel.c | 10 ++++------ + util.c | 17 +++++++++++++++++ + 9 files changed, 41 insertions(+), 77 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9d0a89f..30d5838 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -512,15 +512,12 @@ static int select_devices(struct mddev_dev *devlist, + + /* Now reject spares that don't match domains of identified members */ + for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) { +- struct stat stb; + if (tmpdev->used != 3) + continue; +- if (stat(tmpdev->devname, &stb)< 0) { +- pr_err("fstat failed for %s: %s\n", +- tmpdev->devname, strerror(errno)); ++ if (!stat_is_blkdev(tmpdev->devname, &rdev)) { + tmpdev->used = 2; + } else { +- struct dev_policy *pol = devid_policy(stb.st_rdev); ++ struct dev_policy *pol = devid_policy(rdev); + int dt = domain_test(domains, pol, NULL); + if (inargv && dt != 0) + /* take this spare as domains match +diff --git a/Build.c b/Build.c +index 2d84b96..ad59867 100644 +--- a/Build.c ++++ b/Build.c +@@ -41,7 +41,6 @@ int Build(char *mddev, struct mddev_dev *devlist, + * cc = chunk size factor: 0==4k, 1==8k etc. + */ + int i; +- struct stat stb; + dev_t rdev; + int subdevs = 0, missing_disks = 0; + struct mddev_dev *dv; +@@ -65,16 +64,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + missing_disks++; + continue; + } +- if (stat(dv->devname, &stb)) { +- pr_err("Cannot find %s: %s\n", +- dv->devname, strerror(errno)); +- return 1; +- } +- if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- pr_err("%s is not a block device.\n", +- dv->devname); ++ if (!stat_is_blkdev(dv->devname, NULL)) + return 1; +- } + } + + if (s->raiddisks != subdevs) { +@@ -162,16 +153,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + + if (strcmp("missing", dv->devname) == 0) + continue; +- if (stat(dv->devname, &stb)) { +- pr_err("Weird: %s has disappeared.\n", +- dv->devname); ++ if (!stat_is_blkdev(dv->devname, &rdev)) + goto abort; +- } +- if ((stb.st_mode & S_IFMT)!= S_IFBLK) { +- pr_err("Weird: %s is no longer a block device.\n", +- dv->devname); +- goto abort; +- } + fd = open(dv->devname, O_RDONLY|O_EXCL); + if (fd < 0) { + pr_err("Cannot open %s: %s\n", +@@ -187,8 +170,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + disk.state = (1<writemostly == FlagSet) + disk.state |= 1<devname, strerror(errno)); +diff --git a/Incremental.c b/Incremental.c +index 11a34e7..97b2e99 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -86,8 +86,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + * - if number of OK devices match expected, or -R and there are enough, + * start the array (auto-readonly). + */ +- struct stat stb; +- dev_t rdev; ++ dev_t rdev, rdev2; + struct mdinfo info, dinfo; + struct mdinfo *sra = NULL, *d; + struct mddev_ident *match; +@@ -108,18 +107,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + + struct createinfo *ci = conf_get_create_info(); + +- if (stat(devname, &stb) < 0) { +- if (c->verbose >= 0) +- pr_err("stat failed for %s: %s.\n", +- devname, strerror(errno)); +- return rv; +- } +- if ((stb.st_mode & S_IFMT) != S_IFBLK) { +- if (c->verbose >= 0) +- pr_err("%s is not a block device.\n", +- devname); ++ if (!stat_is_blkdev(devname, &rdev)) + return rv; +- } + dfd = dev_open(devname, O_RDONLY); + if (dfd < 0) { + if (c->verbose >= 0) +@@ -158,10 +147,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + if (!devlist) { + devlist = conf_get_devs(); + for (;devlist; devlist = devlist->next) { +- struct stat st2; +- if (stat(devlist->devname, &st2) == 0 && +- (st2.st_mode & S_IFMT) == S_IFBLK && +- st2.st_rdev == stb.st_rdev) ++ if (stat_is_blkdev(devlist->devname, &rdev2) && ++ rdev2 == rdev) + break; + } + } +diff --git a/Manage.c b/Manage.c +index af55266..14276b7 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1510,24 +1510,16 @@ int Manage_subdevs(char *devname, int fd, + */ + rdev = makedev(mj, mn); + } else { +- struct stat stb; + tfd = dev_open(dv->devname, O_RDONLY); + if (tfd >= 0) { + fstat_is_blkdev(tfd, dv->devname, &rdev); + close(tfd); + } else { + int open_err = errno; +- if (stat(dv->devname, &stb) != 0) { +- pr_err("Cannot find %s: %s\n", +- dv->devname, strerror(errno)); +- goto abort; +- } +- if ((stb.st_mode & S_IFMT) != S_IFBLK) { ++ if (!stat_is_blkdev(dv->devname, &rdev)) { + if (dv->disposition == 'M') + /* non-fatal. Also improbable */ + continue; +- pr_err("%s is not a block device.\n", +- dv->devname); + goto abort; + } + if (dv->disposition == 'r') +@@ -1544,7 +1536,6 @@ int Manage_subdevs(char *devname, int fd, + goto abort; + } + } +- rdev = stb.st_rdev; + } + switch(dv->disposition){ + default: +diff --git a/Monitor.c b/Monitor.c +index 1f15377..e2b36ff 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -993,23 +993,13 @@ static void link_containers_with_subarrays(struct state *list) + /* Not really Monitor but ... */ + int Wait(char *dev) + { +- struct stat stb; + char devnm[32]; +- char *tmp; + int rv = 1; + int frozen_remaining = 3; + +- if (stat(dev, &stb) != 0) { +- pr_err("Cannot find %s: %s\n", dev, +- strerror(errno)); ++ if (!stat_is_blkdev(dev, NULL)) + return 2; +- } +- tmp = stat2devnm(&stb); +- if (!tmp) { +- pr_err("%s is not a block device.\n", dev); +- return 2; +- } +- strcpy(devnm, tmp); ++ strcpy(devnm, dev); + + while(1) { + struct mdstat_ent *ms = mdstat_read(1, 0); +@@ -1068,6 +1058,8 @@ int WaitClean(char *dev, int sock, int verbose) + int rv = 1; + char devnm[32]; + ++ if (!stat_is_blkdev(dev, NULL)) ++ return 2; + fd = open(dev, O_RDONLY); + if (fd < 0) { + if (verbose) +diff --git a/mdadm.h b/mdadm.h +index 4adb840..a92feb2 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1435,6 +1435,7 @@ extern int check_partitions(int fd, char *dname, + unsigned long long freesize, + unsigned long long size); + extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev); ++extern int stat_is_blkdev(char *devname, dev_t *rdev); + + extern int get_mdp_major(void); + extern int get_maj_min(char *dev, int *major, int *minor); +diff --git a/super-ddf.c b/super-ddf.c +index 796eaa5..9c82f4f 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3490,7 +3490,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + char *dev, unsigned long long *freesize, + int verbose) + { +- struct stat stb; ++ dev_t rdev; + struct ddf_super *ddf = st->sb; + struct dl *dl; + unsigned long long maxsize; +@@ -3526,13 +3526,11 @@ static int validate_geometry_ddf_bvd(struct supertype *st, + return 1; + } + /* This device must be a member of the set */ +- if (stat(dev, &stb) < 0) +- return 0; +- if ((S_IFMT & stb.st_mode) != S_IFBLK) ++ if (!stat_is_blkdev(dev, NULL)) + return 0; + for (dl = ddf->dlist ; dl ; dl = dl->next) { +- if (dl->major == (int)major(stb.st_rdev) && +- dl->minor == (int)minor(stb.st_rdev)) ++ if (dl->major == (int)major(rdev) && ++ dl->minor == (int)minor(rdev)) + break; + } + if (!dl) { +diff --git a/super-intel.c b/super-intel.c +index c4196ea..e13c940 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -6855,7 +6855,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + unsigned long long *freesize, + int verbose) + { +- struct stat stb; ++ dev_t rdev; + struct intel_super *super = st->sb; + struct imsm_super *mpb; + struct dl *dl; +@@ -6920,13 +6920,11 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + } + + /* This device must be a member of the set */ +- if (stat(dev, &stb) < 0) +- return 0; +- if ((S_IFMT & stb.st_mode) != S_IFBLK) ++ if (!stat_is_blkdev(dev, &rdev)) + return 0; + for (dl = super->disks ; dl ; dl = dl->next) { +- if (dl->major == (int)major(stb.st_rdev) && +- dl->minor == (int)minor(stb.st_rdev)) ++ if (dl->major == (int)major(rdev) && ++ dl->minor == (int)minor(rdev)) + break; + } + if (!dl) { +diff --git a/util.c b/util.c +index a92faf8..11ff2cc 100644 +--- a/util.c ++++ b/util.c +@@ -747,6 +747,23 @@ int fstat_is_blkdev(int fd, char *devname, dev_t *rdev) + return 1; + } + ++int stat_is_blkdev(char *devname, dev_t *rdev) ++{ ++ struct stat stb; ++ ++ if (stat(devname, &stb) != 0) { ++ pr_err("stat failed for %s: %s\n", devname, strerror(errno)); ++ return 0; ++ } ++ if ((S_IFMT & stb.st_mode) != S_IFBLK) { ++ pr_err("%s is not a block device.\n", devname); ++ return 0; ++ } ++ if (rdev) ++ *rdev = stb.st_rdev; ++ return 1; ++} ++ + int ask(char *mesg) + { + char *add = ""; +-- +2.7.4 + diff --git a/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch b/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch new file mode 100644 index 0000000..4ee6d76 --- /dev/null +++ b/SOURCES/mdadm.c-fix-compile-error-switch-condition-has-boole.patch @@ -0,0 +1,44 @@ +From 13428e2e76e8149336282d514908ced424f878a2 Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Thu, 30 Mar 2017 18:58:13 +0200 +Subject: [RHEL7.5 PATCH 046/169] mdadm.c: fix compile error "switch + condition has boolean value" + +Remove a boolean expression in switch condition +to prevent compile error of some compilers, +for example, gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2). + +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + mdadm.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index 0f32773..d6b5437 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1965,14 +1965,12 @@ static int misc_list(struct mddev_dev *devlist, + rv |= SetAction(dv->devname, c->action); + continue; + } +- switch(dv->devname[0] == '/') { +- case 0: +- mdfd = open_dev(dv->devname); +- if (mdfd >= 0) +- break; +- case 1: +- mdfd = open_mddev(dv->devname, 1); +- } ++ ++ if (dv->devname[0] != '/') ++ mdfd = open_dev(dv->devname); ++ if (dv->devname[0] == '/' || mdfd < 0) ++ mdfd = open_mddev(dv->devname, 1); ++ + if (mdfd >= 0) { + switch(dv->disposition) { + case 'R': +-- +2.7.4 + diff --git a/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch b/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch new file mode 100644 index 0000000..4c73450 --- /dev/null +++ b/SOURCES/mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch @@ -0,0 +1,32 @@ +From 5fbc1f1527ec86ae904739a27c0af4e3bc89084e Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Mon, 10 Apr 2017 12:49:52 +0800 +Subject: [RHEL7.5 PATCH 068/169] mdadm.c:fix compile warning "mdfd is + uninitialized" + +Initialized the mdfd as -1 to prevent compile error +of some compilers. +For example, gcc version 4.8.5(SUSE Linux). + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + mdadm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.c b/mdadm.c +index 001ff68..41dae1d 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1916,7 +1916,7 @@ static int misc_list(struct mddev_dev *devlist, + int rv = 0; + + for (dv = devlist; dv; dv = (rv & 16) ? NULL : dv->next) { +- int mdfd; ++ int mdfd = -1; + + switch(dv->disposition) { + case 'D': +-- +2.7.4 + diff --git a/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch b/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch new file mode 100644 index 0000000..44d8ab2 --- /dev/null +++ b/SOURCES/mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch @@ -0,0 +1,31 @@ +From a86b1c8d15dc0aca2eda5276bae088b5f55030a2 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 11:37:27 -0400 +Subject: [RHEL7.5 PATCH 031/169] mdadm.h: struct mdinfo: reorganize ppl + elements for better struct packing + +Minor optimization putting ints next to ints for better data +alignment. + +Signed-off-by: Jes Sorensen +--- + mdadm.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mdadm.h b/mdadm.h +index 4891acf..dbf1f92 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -301,8 +301,8 @@ struct mdinfo { + }; + long bitmap_offset; /* 0 == none, 1 == a file */ + unsigned int ppl_size; +- unsigned long long ppl_sector; + int ppl_offset; ++ unsigned long long ppl_sector; + unsigned long safe_mode_delay; /* ms delay to mark clean */ + int new_level, delta_disks, new_layout, new_chunk; + int errors; +-- +2.7.4 + diff --git a/SOURCES/mdassemble-Kill-off-the-last-remains.patch b/SOURCES/mdassemble-Kill-off-the-last-remains.patch new file mode 100644 index 0000000..2abe1c3 --- /dev/null +++ b/SOURCES/mdassemble-Kill-off-the-last-remains.patch @@ -0,0 +1,108 @@ +From 935795398d52a589598fa13e6cb6272619c5d134 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 4 May 2017 11:57:41 -0400 +Subject: [RHEL7.5 PATCH 108/169] mdassemble: Kill off the last remains + +Having gotten rid of mdassemble, lets get rid of the man page too + +Signed-off-by: Jes Sorensen +--- + README.initramfs | 9 ++++---- + mdassemble.8 | 65 -------------------------------------------------------- + 2 files changed, 4 insertions(+), 70 deletions(-) + delete mode 100644 mdassemble.8 + +diff --git a/README.initramfs b/README.initramfs +index 8f9b8dd..c5fa668 100644 +--- a/README.initramfs ++++ b/README.initramfs +@@ -16,11 +16,10 @@ devices. + + These mechanisms, while useful, do not provide complete functionality + and are unlikely to be extended. The preferred way to assemble md +-arrays at boot time is using 'mdadm' or 'mdassemble' (which is a +-trimmed-down mdadm). To assemble an array which contains the root +-filesystem, mdadm needs to be run before that filesystem is mounted, +-and so needs to be run from an initial-ram-fs. It is how this can +-work that is the primary focus of this document. ++arrays at boot time is using 'mdadm'. To assemble an array which ++contains the root filesystem, mdadm needs to be run before that ++filesystem is mounted, and so needs to be run from an initial-ram-fs. ++It is how this can work that is the primary focus of this document. + + It should be noted up front that only the array containing the root + filesystem should be assembled from the initramfs. Any other arrays +diff --git a/mdassemble.8 b/mdassemble.8 +deleted file mode 100644 +index 33aa977..0000000 +--- a/mdassemble.8 ++++ /dev/null +@@ -1,65 +0,0 @@ +-.\" -*- nroff -*- +-.TH MDASSEMBLE 8 "" v4.0 +-.SH NAME +-mdassemble \- assemble MD devices +-.I aka +-Linux Software RAID +- +-.SH SYNOPSIS +- +-.BI mdassemble +- +-.SH DESCRIPTION +-.B mdassemble +-is a tiny program that can be used to assemble MD devices inside an +-initial ramdisk (initrd) or initramfs; it is meant to replace the in-kernel +-automatic RAID detection and activation. +-It can be built statically and linked against lightweight libc alternatives, like +-.B dietlibc, +-.B klibc +-or +-.B uClibc. +- +-.SH USAGE +-Invoking +-.B mdassemble +-has the same effect as invoking +-.B mdadm \-\-assemble \-\-scan. +-.PP +-Invoking +-.B mdassemble +-a second time will make all defined arrays readwrite, this is useful if +-using the +-.B start_ro +-module parameter. +- +-.SH OPTIONS +- +-There are no options to +-.B mdassemble. +- +-.SH FILES +- +-.SS /etc/mdadm.conf +- +-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 +-.BR mdadm.conf (5) +-for more details. +- +-.B mdassemble +-supports all configuration parameters defined in +-.B mdadm.conf +-with the exception of +-.B auto= +-which is supported only if mdadm was built with the +-.B \-DMDASSEMBLE_AUTO +-define. +- +-.SH SEE ALSO +-.PP +-.BR mdadm (8), +-.BR mdadm.conf (5), +-.BR md (4), +-.BR diet (1). +-- +2.7.4 + diff --git a/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch b/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch new file mode 100644 index 0000000..899ad8a --- /dev/null +++ b/SOURCES/mdassemble-Use-md_get_array_info-to-check-for-valid-.patch @@ -0,0 +1,38 @@ +From 1c9591115d577841522acd245cd2445cb77ee204 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:46:35 -0400 +Subject: [RHEL7.5 PATCH 064/169] mdassemble: Use md_get_array_info() to + check for valid array + +Get rid of another use of md_get_version() + +Signed-off-by: Jes Sorensen +--- + mdassemble.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/mdassemble.c b/mdassemble.c +index a24b324..f0833bc 100644 +--- a/mdassemble.c ++++ b/mdassemble.c +@@ -32,13 +32,12 @@ char const Name[] = "mdassemble"; + /* from mdopen.c */ + int open_mddev(char *dev, int report_errors/*unused*/) + { ++ struct mdu_array_info_s array; + int mdfd = open(dev, O_RDONLY); + if (mdfd < 0) +- pr_err("error opening %s: %s\n", +- dev, strerror(errno)); +- else if (md_get_version(mdfd) <= 0) { +- pr_err("%s does not appear to be an md device\n", +- dev); ++ pr_err("error opening %s: %s\n", dev, strerror(errno)); ++ else if (md_get_array_info(mdfd, &array) != 0) { ++ pr_err("%s does not appear to be an md device\n", dev); + close(mdfd); + mdfd = -1; + } +-- +2.7.4 + diff --git a/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch b/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch new file mode 100644 index 0000000..4679992 --- /dev/null +++ b/SOURCES/mdmon-Stop-bothering-about-md-get-version2.patch @@ -0,0 +1,32 @@ +From 15d924d363a2bc02aa4a489241333be3d7820978 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:39:51 -0400 +Subject: [RHEL7.5 PATCH 062/169] mdmon: Stop bothering about + md_get_version() + +If anyone has a kernel with md driver older than 0.90.03 they will +also know where to find older versions of mdadm. + +Signed-off-by: Jes Sorensen +--- + mdmon.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 95e9bba..0955fcc 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -408,10 +408,6 @@ static int mdmon(char *devnm, int must_fork, int takeover) + pr_err("%s: %s\n", devnm, strerror(errno)); + return 1; + } +- if (md_get_version(mdfd) < 0) { +- pr_err("%s: Not an md device\n", devnm); +- return 1; +- } + + /* Fork, and have the child tell us when they are ready */ + if (must_fork) { +-- +2.7.4 + diff --git a/SOURCES/mdmon-get-safe-mode-delay-file.patch b/SOURCES/mdmon-get-safe-mode-delay-file.patch new file mode 100644 index 0000000..9332ec8 --- /dev/null +++ b/SOURCES/mdmon-get-safe-mode-delay-file.patch @@ -0,0 +1,74 @@ +commit c76242c56efb4d799bb15af1035a5f503cb4b8f3 +Author: Tomasz Majchrzak +Date: Wed Oct 4 10:18:21 2017 +0200 + + mdmon: get safe mode delay file descriptor early + + After switch root new mdmon is started. It sends initrd mdmon a signal + to terminate. initrd mdmon receives it and switches the safe mode delay + to 1 ms in order to get array to clean state and flush last version of + metadata. The problem is sysfs filesystem is not available to initrd mdmon + after switch root so the original safe mode delay is unchanged. The delay + is set to few seconds - if there is a lot of traffic on the filesystem, + initrd mdmon doesn't terminate for a long time (no clean state). There + are 2 instances of mdmon. initrd mdmon flushes metadata when array goes + to clean state but this metadata might be already outdated. + + Use file descriptor obtained on mdmon start to change safe mode delay. + + Signed-off-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/managemon.c b/managemon.c +index cc3c6f1..4e85398 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -129,6 +129,8 @@ static void close_aa(struct active_array *aa) + close(aa->metadata_fd); + if (aa->sync_completed_fd >= 0) + close(aa->sync_completed_fd); ++ if (aa->safe_mode_delay_fd >= 0) ++ close(aa->safe_mode_delay_fd); + } + + static void free_aa(struct active_array *aa) +@@ -532,9 +534,15 @@ static void manage_member(struct mdstat_ent *mdstat, + if (a->container == NULL) + return; + +- if (sigterm && a->info.safe_mode_delay != 1) { +- sysfs_set_safemode(&a->info, 1); +- a->info.safe_mode_delay = 1; ++ if (sigterm && a->info.safe_mode_delay != 1 && ++ a->safe_mode_delay_fd >= 0) { ++ long int new_delay = 1; ++ char delay[10]; ++ ssize_t len; ++ ++ len = snprintf(delay, sizeof(delay), "0.%03ld\n", new_delay); ++ if (write(a->safe_mode_delay_fd, delay, len) == len) ++ a->info.safe_mode_delay = new_delay; + } + + /* We don't check the array while any update is pending, as it +@@ -734,6 +742,8 @@ static void manage_new(struct mdstat_ent *mdstat, + new->resync_start_fd = sysfs_open2(new->info.sys_name, NULL, "resync_start"); + new->metadata_fd = sysfs_open2(new->info.sys_name, NULL, "metadata_version"); + new->sync_completed_fd = sysfs_open2(new->info.sys_name, NULL, "sync_completed"); ++ new->safe_mode_delay_fd = sysfs_open2(new->info.sys_name, NULL, ++ "safe_mode_delay"); + + dprintf("inst: %s action: %d state: %d\n", inst, + new->action_fd, new->info.state_fd); +diff --git a/mdmon.h b/mdmon.h +index 0b08c3d..818367c 100644 +--- a/mdmon.h ++++ b/mdmon.h +@@ -35,6 +35,7 @@ struct active_array { + int resync_start_fd; + int metadata_fd; /* for monitoring rw/ro status */ + int sync_completed_fd; /* for checkpoint notification events */ ++ int safe_mode_delay_fd; + unsigned long long last_checkpoint; /* sync_completed fires for many + * reasons this field makes sure the + * kernel has made progress before diff --git a/SOURCES/mdmonitor.service b/SOURCES/mdmonitor.service index 8c92f82..08cae12 100644 --- a/SOURCES/mdmonitor.service +++ b/SOURCES/mdmonitor.service @@ -6,8 +6,9 @@ ConditionPathExists=/etc/mdadm.conf [Service] Type=forking PIDFile=/var/run/mdadm/mdadm.pid +Environment= MDADM_MONITOR_ARGS=--scan EnvironmentFile=-/etc/sysconfig/mdmonitor -ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid +ExecStart=/sbin/mdadm --monitor $MDADM_MONITOR_ARGS -f --pid-file=/var/run/mdadm/mdadm.pid [Install] WantedBy=multi-user.target diff --git a/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch b/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch new file mode 100644 index 0000000..2c29e51 --- /dev/null +++ b/SOURCES/mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch @@ -0,0 +1,46 @@ +From 40b054e1dc9e334621fd2081bf6fc46b01dd7ef4 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:44:20 -0400 +Subject: [RHEL7.5 PATCH 063/169] mdopen/open_mddev: Use + md_get_array_info() to determine valid array + +md_get_array_info() can be used instead of md_get_version() to +determine this is in fact a valid array. + +Signed-off-by: Jes Sorensen +--- + mdopen.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/mdopen.c b/mdopen.c +index 685ca32..fe240e5 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -416,19 +416,23 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + */ + int open_mddev(char *dev, int report_errors) + { ++ struct mdu_array_info_s array; + int mdfd = open(dev, O_RDONLY); ++ + if (mdfd < 0) { + if (report_errors) + pr_err("error opening %s: %s\n", + dev, strerror(errno)); + return -1; + } +- if (md_get_version(mdfd) <= 0) { ++ ++ if (md_get_array_info(mdfd, &array) != 0) { + close(mdfd); + if (report_errors) + pr_err("%s does not appear to be an md device\n", dev); + return -2; + } ++ + return mdfd; + } + +-- +2.7.4 + diff --git a/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch b/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch new file mode 100644 index 0000000..18ea5e5 --- /dev/null +++ b/SOURCES/mdopen-use-parameters-new_array-to-create-arrays-whe.patch @@ -0,0 +1,54 @@ +From 039df36231335fabe4da1a22fa3accb160d8bc1b Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 12 Apr 2017 16:29:04 +1000 +Subject: [RHEL7.5 PATCH 072/169] mdopen: use parameters/new_array to + create arrays whenever possible. + +In a sufficiently recent kernel, an md%d array can be +created by writing to .../parameters/new_array. +If mdadm does this consistently, then another new +feature, disabling create_on_open, can be enabled. +This avoids races on shutdown. + +An added benefit of using new_array (where available) +is that it allows md arrays with numbers larger than 511 +(e.g. md999) to be created. The old create_on_open +mechanism doesn't support such devices since +Commit: af5628f05db6 ("md: disable probing for md devices 512 and over.") +in Linux 3.17. + +After a few more mdadm releases it would be good to +have mdadm disable create_on_open automatically. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdopen.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/mdopen.c b/mdopen.c +index fe240e5..82b97fc 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -313,6 +313,18 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + if (n < 0) + devnm[0] = 0; + } ++ if (num >= 0) { ++ int fd; ++ int n = -1; ++ sprintf(devnm, "md%d", num); ++ fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY); ++ if (fd >= 0) { ++ n = write(fd, devnm, strlen(devnm)); ++ close(fd); ++ } ++ if (n < 0) ++ devnm[0] = 0; ++ } + if (devnm[0]) + ; + else if (num < 0) { +-- +2.7.4 + diff --git a/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch b/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch new file mode 100644 index 0000000..c257d16 --- /dev/null +++ b/SOURCES/retire-the-APIs-that-driver-nolonger-supports.patch @@ -0,0 +1,51 @@ +From e644902ddbc66d58a3fd4353c9539276ee1fabd7 Mon Sep 17 00:00:00 2001 +From: Zhilong Liu +Date: Thu, 11 May 2017 16:52:41 +0800 +Subject: [RHEL7.5 PATCH 136/169] retire the APIs that driver no longer + supports + +refer to commit: e6e5f8f1267d ("Build: Stop +bothering about supporting md driver ...") +continue to retire the APIs that md driver +wasn't supported for very long period of time. + +Signed-off-by: Zhilong Liu +Signed-off-by: Jes Sorensen +--- + Build.c | 4 ---- + Manage.c | 4 ---- + 2 files changed, 8 deletions(-) + +diff --git a/Build.c b/Build.c +index ad59867..70ba068 100644 +--- a/Build.c ++++ b/Build.c +@@ -24,10 +24,6 @@ + + #include "mdadm.h" + +-#define REGISTER_DEV _IO (MD_MAJOR, 1) +-#define START_MD _IO (MD_MAJOR, 2) +-#define STOP_MD _IO (MD_MAJOR, 3) +- + int Build(char *mddev, struct mddev_dev *devlist, + struct shape *s, struct context *c) + { +diff --git a/Manage.c b/Manage.c +index 14276b7..467efb7 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -27,10 +27,6 @@ + #include "md_p.h" + #include + +-#define REGISTER_DEV _IO (MD_MAJOR, 1) +-#define START_MD _IO (MD_MAJOR, 2) +-#define STOP_MD _IO (MD_MAJOR, 3) +- + int Manage_ro(char *devname, int fd, int readonly) + { + /* switch to readonly or rw +-- +2.7.4 + diff --git a/SOURCES/stop-previous-reshape-process-first.patch b/SOURCES/stop-previous-reshape-process-first.patch new file mode 100644 index 0000000..9314a20 --- /dev/null +++ b/SOURCES/stop-previous-reshape-process-first.patch @@ -0,0 +1,35 @@ +commit e1b942b9afa9f3310ea19c57caea896af97b557e +Author: Tomasz Majchrzak +Date: Thu Sep 7 13:01:16 2017 +0200 + + Grow: stop previous reshape process first + + If array is stopped during reshape and assembled again straight away, + reshape process in a background might still be running. systemd doesn't + start a new service if one already exists. If there is a race, previous + process might terminate and new one is not created. Reshape doesn't + continue after assemble. + + Tell systemd to restart the service rather than just start it. It will + assure previous service is stopped first. If it's not running, stopping + has no effect and only new process is started. + + Signed-off-by: Tomasz Majchrzak + Signed-off-by: Jes Sorensen + +diff --git a/Grow.c b/Grow.c +index 534ba80..267b06f 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3003,9 +3003,9 @@ static int continue_via_systemd(char *devnm) + snprintf(pathbuf, sizeof(pathbuf), "mdadm-grow-continue@%s.service", + devnm); + status = execl("/usr/bin/systemctl", "systemctl", +- "start", ++ "restart", + pathbuf, NULL); +- status = execl("/bin/systemctl", "systemctl", "start", ++ status = execl("/bin/systemctl", "systemctl", "restart", + pathbuf, NULL); + exit(1); + case -1: /* Just do it ourselves. */ diff --git a/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch b/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch new file mode 100644 index 0000000..680f406 --- /dev/null +++ b/SOURCES/super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch @@ -0,0 +1,27 @@ +From a0628abf2bf87c69bec3384f90aae2398a8e64aa Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 16 May 2017 13:29:46 -0400 +Subject: [RHEL7.5 PATCH 141/169] super-ddf: sysfs_read() takes a pointer + as device name argument + +Signed-off-by: Jes Sorensen +--- + super-ddf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/super-ddf.c b/super-ddf.c +index ac14017..50197a8 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -3557,7 +3557,7 @@ static int load_super_ddf_all(struct supertype *st, int fd, + char nm[20]; + int dfd; + +- sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE); ++ sra = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE); + if (!sra) + return 1; + if (sra->array.major_version != -1 || +-- +2.7.4 + diff --git a/SOURCES/super1-Always-round-data-offset-to-1M.patch b/SOURCES/super1-Always-round-data-offset-to-1M.patch new file mode 100644 index 0000000..548e775 --- /dev/null +++ b/SOURCES/super1-Always-round-data-offset-to-1M.patch @@ -0,0 +1,33 @@ +From 795bd44ed11aafbed2628ba21216c667371e79a5 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Wed, 26 Jul 2017 16:41:54 +0200 +Subject: [RHEL7.5 PATCH 159/169] super1: Always round data offset to 1M + +Currently if metadata requires more then 1M, +data offset will be rounded down to closest MB. +This is not correct, since less then required space is reserved. +Always round data offset up to multiple of 1M. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super1.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/super1.c b/super1.c +index 86ec850..b15a1c7 100644 +--- a/super1.c ++++ b/super1.c +@@ -2796,8 +2796,7 @@ static int validate_geometry1(struct supertype *st, int level, + headroom >>= 1; + data_offset = 12*2 + bmspace + headroom; + #define ONE_MEG (2*1024) +- if (data_offset > ONE_MEG) +- data_offset = (data_offset / ONE_MEG) * ONE_MEG; ++ data_offset = ROUND_UP(data_offset, ONE_MEG); + break; + } + if (st->data_offset == INVALID_SECTORS) +-- +2.7.4 + diff --git a/SOURCES/super1-Clean-up-various-style-abuses.patch b/SOURCES/super1-Clean-up-various-style-abuses.patch new file mode 100644 index 0000000..e7bec44 --- /dev/null +++ b/SOURCES/super1-Clean-up-various-style-abuses.patch @@ -0,0 +1,909 @@ +From 46a533a90c01b0492577c61d4e65de2ac4bf220c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 11 Apr 2017 14:25:24 -0400 +Subject: [RHEL7.5 PATCH 071/169] super1: Clean up various style abuses + +Code is 80 characters wide, so lets try to respect that. In addition, we +should never have one-line 'if () action()' statements. Fixup various +whitespace abuse. + +Signed-off-by: Jes Sorensen +--- + super1.c | 363 +++++++++++++++++++++++++++++++++++++++------------------------ + 1 file changed, 223 insertions(+), 140 deletions(-) + +diff --git a/super1.c b/super1.c +index 4db4dff..2fcb814 100644 +--- a/super1.c ++++ b/super1.c +@@ -227,6 +227,7 @@ static void init_afd(struct align_fd *afd, int fd) + } + + static char abuf[4096+4096]; ++ + static int aread(struct align_fd *afd, void *buf, int len) + { + /* aligned read. +@@ -339,7 +340,8 @@ static void examine_super1(struct supertype *st, char *homehost) + strncmp(sb->set_name, homehost, l) == 0) + printf(" (local to host %s)", homehost); + printf("\n"); +- if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) ++ if (bms->nodes > 0 && ++ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) + printf(" Cluster Name : %-64s\n", bms->cluster_name); + atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL; + printf(" Creation Time : %.24s\n", ctime(&atime)); +@@ -385,7 +387,8 @@ static void examine_super1(struct supertype *st, char *homehost) + printf(" Super Offset : %llu sectors\n", + (unsigned long long)__le64_to_cpu(sb->super_offset)); + if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_RECOVERY_OFFSET) +- printf("Recovery Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->recovery_offset)); ++ printf("Recovery Offset : %llu sectors\n", ++ (unsigned long long)__le64_to_cpu(sb->recovery_offset)); + + st->ss->getinfo_super(st, &info, NULL); + if (info.space_after != 1 && +@@ -393,10 +396,12 @@ static void examine_super1(struct supertype *st, char *homehost) + 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"); ++ printf(" State : %s\n", ++ (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean"); + printf(" Device UUID : "); + for (i=0; i<16; i++) { +- if ((i&3)==0 && i != 0) printf(":"); ++ if ((i&3)==0 && i != 0) ++ printf(":"); + printf("%02x", sb->device_uuid[i]); + } + printf("\n"); +@@ -410,12 +415,15 @@ static void examine_super1(struct supertype *st, char *homehost) + __le16_to_cpu(sb->ppl.offset)); + } + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) { +- printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2, ++ printf(" Reshape pos'n : %llu%s\n", (unsigned long long) ++ __le64_to_cpu(sb->reshape_position)/2, + human_size(__le64_to_cpu(sb->reshape_position)<<9)); + if (__le32_to_cpu(sb->delta_disks)) { +- printf(" Delta Devices : %d", __le32_to_cpu(sb->delta_disks)); ++ printf(" Delta Devices : %d", ++ __le32_to_cpu(sb->delta_disks)); + printf(" (%d->%d)\n", +- __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks), ++ __le32_to_cpu(sb->raid_disks) - ++ __le32_to_cpu(sb->delta_disks), + __le32_to_cpu(sb->raid_disks)); + if ((int)__le32_to_cpu(sb->delta_disks) < 0) + delta_extra = -__le32_to_cpu(sb->delta_disks); +@@ -424,13 +432,16 @@ static void examine_super1(struct supertype *st, char *homehost) + c = map_num(pers, __le32_to_cpu(sb->new_level)); + printf(" New Level : %s\n", c?c:"-unknown-"); + } +- if (__le32_to_cpu(sb->new_layout) != __le32_to_cpu(sb->layout)) { ++ if (__le32_to_cpu(sb->new_layout) != ++ __le32_to_cpu(sb->layout)) { + if (__le32_to_cpu(sb->level) == 5) { +- c = map_num(r5layout, __le32_to_cpu(sb->new_layout)); ++ c = map_num(r5layout, ++ __le32_to_cpu(sb->new_layout)); + printf(" New Layout : %s\n", c?c:"-unknown-"); + } + if (__le32_to_cpu(sb->level) == 6) { +- c = map_num(r6layout, __le32_to_cpu(sb->new_layout)); ++ c = map_num(r6layout, ++ __le32_to_cpu(sb->new_layout)); + printf(" New Layout : %s\n", c?c:"-unknown-"); + } + if (__le32_to_cpu(sb->level) == 10) { +@@ -439,8 +450,10 @@ static void examine_super1(struct supertype *st, char *homehost) + printf("\n"); + } + } +- if (__le32_to_cpu(sb->new_chunk) != __le32_to_cpu(sb->chunksize)) +- printf(" New Chunksize : %dK\n", __le32_to_cpu(sb->new_chunk)/2); ++ if (__le32_to_cpu(sb->new_chunk) != ++ __le32_to_cpu(sb->chunksize)) ++ printf(" New Chunksize : %dK\n", ++ __le32_to_cpu(sb->new_chunk)/2); + printf("\n"); + } + if (sb->devflags) { +@@ -459,18 +472,20 @@ static void examine_super1(struct supertype *st, char *homehost) + printf(" Bad Block Log : %d entries available at offset %ld sectors", + __le16_to_cpu(sb->bblog_size)*512/8, + (long)(int32_t)__le32_to_cpu(sb->bblog_offset)); +- if (sb->feature_map & +- __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) ++ if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) + printf(" - bad blocks present."); + printf("\n"); + } + + if (calc_sb_1_csum(sb) == sb->sb_csum) +- printf(" Checksum : %x - correct\n", __le32_to_cpu(sb->sb_csum)); ++ printf(" Checksum : %x - correct\n", ++ __le32_to_cpu(sb->sb_csum)); + else +- printf(" Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum), ++ printf(" Checksum : %x - expected %x\n", ++ __le32_to_cpu(sb->sb_csum), + __le32_to_cpu(calc_sb_1_csum(sb))); +- printf(" Events : %llu\n", (unsigned long long)__le64_to_cpu(sb->events)); ++ printf(" Events : %llu\n", ++ (unsigned long long)__le64_to_cpu(sb->events)); + printf("\n"); + if (__le32_to_cpu(sb->level) == 5) { + c = map_num(r5layout, __le32_to_cpu(sb->layout)); +@@ -492,26 +507,34 @@ static void examine_super1(struct supertype *st, char *homehost) + case 5: + case 6: + case 10: +- printf(" Chunk Size : %dK\n", __le32_to_cpu(sb->chunksize)/2); ++ printf(" Chunk Size : %dK\n", ++ __le32_to_cpu(sb->chunksize)/2); + break; + case -1: +- printf(" Rounding : %dK\n", __le32_to_cpu(sb->chunksize)/2); ++ printf(" Rounding : %dK\n", ++ __le32_to_cpu(sb->chunksize)/2); ++ break; ++ default: + break; +- default: break; + } + printf("\n"); + #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++) { ++ for (d = 0; d < i; d++) { + int role = __le16_to_cpu(sb->dev_roles[d]); +- if (d) printf(", "); +- if (role == MD_DISK_ROLE_SPARE) printf("empty"); +- else if(role == MD_DISK_ROLE_FAULTY) printf("failed"); +- else printf("%d", role); ++ if (d) ++ printf(", "); ++ if (role == MD_DISK_ROLE_SPARE) ++ printf("empty"); ++ else ++ if(role == MD_DISK_ROLE_FAULTY) ++ printf("failed"); ++ else ++ printf("%d", role); + } + printf(")\n"); + #endif +@@ -527,10 +550,10 @@ static void examine_super1(struct supertype *st, char *homehost) + printf("Active device %d\n", role); + + printf(" Array State : "); +- for (d=0; d<__le32_to_cpu(sb->raid_disks) + delta_extra; d++) { ++ for (d = 0; d < __le32_to_cpu(sb->raid_disks) + delta_extra; d++) { + int cnt = 0; + unsigned int i; +- for (i=0; i< __le32_to_cpu(sb->max_dev); i++) { ++ for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { + unsigned int role = __le16_to_cpu(sb->dev_roles[i]); + if (role == d) + cnt++; +@@ -547,12 +570,13 @@ 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++; + } +- if (faulty) printf(" %d failed", faulty); ++ if (faulty) ++ printf(" %d failed", faulty); + #endif + printf(" ('A' == active, '.' == missing, 'R' == replacing)"); + printf("\n"); +@@ -564,7 +588,7 @@ static void brief_examine_super1(struct supertype *st, int verbose) + int i; + unsigned long long sb_offset; + char *nm; +- char *c=map_num(pers, __le32_to_cpu(sb->level)); ++ char *c = map_num(pers, __le32_to_cpu(sb->level)); + + nm = strchr(sb->set_name, ':'); + if (nm) +@@ -592,8 +616,9 @@ static void brief_examine_super1(struct supertype *st, int verbose) + if (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) printf(":"); ++ for (i = 0; i < 16; i++) { ++ if ((i&3)==0 && i != 0) ++ printf(":"); + printf("%02x", sb->set_uuid[i]); + } + if (sb->set_name[0]) { +@@ -612,9 +637,8 @@ static void export_examine_super1(struct supertype *st) + + printf("MD_LEVEL=%s\n", map_num(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') { ++ for (i = 0; i < 32; i++) ++ if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { + len = i; + break; + } +@@ -623,10 +647,16 @@ static void export_examine_super1(struct supertype *st) + if (__le32_to_cpu(sb->level) > 0) { + int ddsks = 0, ddsks_denom = 1; + switch(__le32_to_cpu(sb->level)) { +- case 1: ddsks=1;break; ++ case 1: ++ ddsks = 1; ++ break; + case 4: +- case 5: ddsks = __le32_to_cpu(sb->raid_disks)-1; break; +- case 6: ddsks = __le32_to_cpu(sb->raid_disks)-2; break; ++ case 5: ++ ddsks = __le32_to_cpu(sb->raid_disks)-1; ++ break; ++ case 6: ++ ddsks = __le32_to_cpu(sb->raid_disks)-2; ++ break; + case 10: + layout = __le32_to_cpu(sb->layout); + ddsks = __le32_to_cpu(sb->raid_disks); +@@ -635,20 +665,23 @@ static void export_examine_super1(struct supertype *st) + if (ddsks) { + long long asize = __le64_to_cpu(sb->size); + asize = (asize << 9) * ddsks / ddsks_denom; +- printf("MD_ARRAY_SIZE=%s\n",human_size_brief(asize,JEDEC)); ++ printf("MD_ARRAY_SIZE=%s\n", ++ human_size_brief(asize, JEDEC)); + } + } + printf("MD_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"); + printf("MD_UPDATE_TIME=%llu\n", + __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL); + printf("MD_DEV_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->device_uuid[i]); + } + printf("\n"); +@@ -797,15 +830,16 @@ static void detail_super1(struct supertype *st, char *homehost) + int l = homehost ? strlen(homehost) : 0; + + printf(" Name : %.32s", sb->set_name); +- if (l > 0 && l < 32 && +- sb->set_name[l] == ':' && ++ if (l > 0 && l < 32 && sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0) + printf(" (local to host %s)", homehost); +- if (bms->nodes > 0 && (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) +- printf("\n Cluster Name : %-64s", bms->cluster_name); ++ if (bms->nodes > 0 && ++ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) ++ printf("\n Cluster Name : %-64s", bms->cluster_name); + printf("\n 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 Events : %llu\n\n", +@@ -822,8 +856,9 @@ static void brief_detail_super1(struct supertype *st) + print_quoted(sb->set_name); + } + printf(" 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]); + } + } +@@ -834,9 +869,8 @@ static void export_detail_super1(struct supertype *st) + int i; + int len = 32; + +- for (i=0; i<32; i++) +- if (sb->set_name[i] == '\n' || +- sb->set_name[i] == '\0') { ++ for (i = 0; i < 32; i++) ++ if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') { + len = i; + break; + } +@@ -852,13 +886,12 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) + __u64 *bbl, *bbp; + int i; + +- if (!sb->bblog_size || __le16_to_cpu(sb->bblog_size) > 100 +- || !sb->bblog_offset){ ++ if (!sb->bblog_size || __le16_to_cpu(sb->bblog_size) > 100 || ++ !sb->bblog_offset){ + printf("No bad-blocks list configured on %s\n", devname); + return 0; + } +- if ((sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) +- == 0) { ++ if ((sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) == 0) { + printf("Bad-blocks list is empty in %s\n", devname); + return 0; + } +@@ -905,8 +938,7 @@ static int match_home1(struct supertype *st, char *homehost) + struct mdp_superblock_1 *sb = st->sb; + int l = homehost ? strlen(homehost) : 0; + +- return (l > 0 && l < 32 && +- sb->set_name[l] == ':' && ++ return (l > 0 && l < 32 && sb->set_name[l] == ':' && + strncmp(sb->set_name, homehost, l) == 0); + } + +@@ -915,7 +947,7 @@ static void uuid_from_super1(struct supertype *st, int uuid[4]) + struct mdp_superblock_1 *super = st->sb; + char *cuuid = (char*)uuid; + int i; +- for (i=0; i<16; i++) ++ for (i = 0; i < 16; i++) + cuuid[i] = super->set_uuid[i]; + } + +@@ -923,7 +955,8 @@ 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 misc_dev_info *misc = (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); ++ struct misc_dev_info *misc = ++ (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE); + int working = 0; + unsigned int i; + unsigned int role; +@@ -943,8 +976,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->array.utime = __le64_to_cpu(sb->utime); + info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512; + info->array.state = +- (__le64_to_cpu(sb->resync_offset) == MaxSector) +- ? 1 : 0; ++ (__le64_to_cpu(sb->resync_offset) == MaxSector) ? 1 : 0; + if (__le32_to_cpu(bsb->nodes) > 1) + info->array.state |= (1 << MD_SB_CLUSTERED); + +@@ -985,7 +1017,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + } + + if (super_offset + info->bitmap_offset + info->ppl_offset < end) +- end = super_offset + info->bitmap_offset + info->ppl_offset; ++ end = super_offset + info->bitmap_offset + ++ info->ppl_offset; + + if (info->data_offset + data_size < end) + info->space_after = end - data_size - info->data_offset; +@@ -1002,8 +1035,9 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + if (bmend > earliest) + earliest = bmend; + } else if (info->ppl_offset > 0) { +- unsigned long long pplend = info->ppl_offset + +- info->ppl_size; ++ unsigned long long pplend; ++ ++ pplend = info->ppl_offset + info->ppl_size; + if (pplend > earliest) + earliest = pplend; + } +@@ -1018,7 +1052,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->space_before = info->data_offset - earliest; + else + info->space_before = 0; +- info->space_after = misc->device_size - data_size - info->data_offset; ++ info->space_after = misc->device_size - data_size - ++ info->data_offset; + } + if (info->space_before == 0 && info->space_after == 0) { + /* It will look like we don't support data_offset changes, +@@ -1032,7 +1067,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->disk.raid_disk = -1; + switch(role) { + case MD_DISK_ROLE_SPARE: +- info->disk.state = 0; /* spare: not active, not sync, not faulty */ ++ /* spare: not active, not sync, not faulty */ ++ info->disk.state = 0; + break; + case MD_DISK_ROLE_FAULTY: + info->disk.state = (1 << MD_DISK_FAULTY); /* faulty */ +@@ -1040,7 +1076,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + case MD_DISK_ROLE_JOURNAL: + info->disk.state = (1 << MD_DISK_JOURNAL); + info->disk.raid_disk = role; +- info->space_after = (misc->device_size - info->data_offset) % 8; /* journal uses all 4kB blocks*/ ++ /* journal uses all 4kB blocks*/ ++ info->space_after = (misc->device_size - info->data_offset) % 8; + break; + default: + info->disk.state = 6; /* active and in sync */ +@@ -1129,8 +1166,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, ++ char *update, char *devname, int verbose, + int uuid_set, char *homehost) + { + /* NOTE: for 'assemble' and 'force' we need to return non-zero +@@ -1145,7 +1181,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { + rv = cluster_get_dlmlock(&lockid); + if (rv) { +- pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv); ++ pr_err("Cannot get dlmlock in %s return %d\n", ++ __func__, rv); + cluster_release_dlmlock(lockid); + return rv; + } +@@ -1178,7 +1215,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + * maybe need to mark it 'clean'. + */ + switch(__le32_to_cpu(sb->level)) { +- case 5: case 4: case 6: ++ case 4: ++ case 5: ++ case 6: + /* need to force clean */ + if (sb->resync_offset != MaxSector) + rv = 1; +@@ -1198,17 +1237,23 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + rv = 1; + } + if (info->reshape_active && +- sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && ++ sb->feature_map & ++ __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && + info->delta_disks >= 0 && +- info->reshape_progress < __le64_to_cpu(sb->reshape_position)) { +- sb->reshape_position = __cpu_to_le64(info->reshape_progress); ++ info->reshape_progress < ++ __le64_to_cpu(sb->reshape_position)) { ++ sb->reshape_position = ++ __cpu_to_le64(info->reshape_progress); + rv = 1; + } + if (info->reshape_active && +- sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && ++ sb->feature_map & ++ __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && + info->delta_disks < 0 && +- info->reshape_progress > __le64_to_cpu(sb->reshape_position)) { +- sb->reshape_position = __cpu_to_le64(info->reshape_progress); ++ info->reshape_progress > ++ __le64_to_cpu(sb->reshape_position)) { ++ sb->reshape_position = ++ __cpu_to_le64(info->reshape_progress); + rv = 1; + } + } else if (strcmp(update, "linear-grow-new") == 0) { +@@ -1216,8 +1261,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + int fd; + unsigned int max = __le32_to_cpu(sb->max_dev); + +- for (i=0 ; i < max ; i++) +- if (__le16_to_cpu(sb->dev_roles[i]) >= MD_DISK_ROLE_FAULTY) ++ for (i = 0; i < max; i++) ++ if (__le16_to_cpu(sb->dev_roles[i]) >= ++ MD_DISK_ROLE_FAULTY) + break; + sb->dev_number = __cpu_to_le32(i); + info->disk.number = i; +@@ -1226,8 +1272,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + + random_uuid(sb->device_uuid); + +- sb->dev_roles[i] = +- __cpu_to_le16(info->disk.raid_disk); ++ sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk); + + fd = open(devname, O_RDONLY); + if (fd >= 0) { +@@ -1280,14 +1325,16 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + } + + if (sb_offset < data_offset) { +- /* 1.1 or 1.2. Put bbl after bitmap leaving at least 32K ++ /* ++ * 1.1 or 1.2. Put bbl after bitmap leaving ++ * at least 32K + */ + long bb_offset; + bb_offset = sb_offset + 8; + if (bm_sectors && bitmap_offset > 0) + bb_offset = bitmap_offset + bm_sectors; +- while (bb_offset < (long)sb_offset + 8 + 32*2 +- && bb_offset + 8+8 <= (long)data_offset) ++ 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) { +@@ -1381,8 +1428,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + } else + strncpy(sb->set_name, info->name, sizeof(sb->set_name)); + } else if (strcmp(update, "devicesize") == 0 && +- __le64_to_cpu(sb->super_offset) < +- __le64_to_cpu(sb->data_offset)) { ++ __le64_to_cpu(sb->super_offset) < ++ __le64_to_cpu(sb->data_offset)) { + /* 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); +@@ -1390,7 +1437,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + misc->device_size - __le64_to_cpu(sb->data_offset)); + } else if (strncmp(update, "revert-reshape", 14) == 0) { + rv = -2; +- if (!(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) ++ if (!(sb->feature_map & ++ __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) + pr_err("No active reshape to revert on %s\n", + devname); + else { +@@ -1431,9 +1479,11 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + */ + if (__le32_to_cpu(sb->level) >= 4 && + __le32_to_cpu(sb->level) <= 6) { +- reshape_sectors = __le64_to_cpu(sb->reshape_position); ++ reshape_sectors = ++ __le64_to_cpu(sb->reshape_position); + reshape_chunk = __le32_to_cpu(sb->new_chunk); +- reshape_chunk *= __le32_to_cpu(sb->raid_disks) - __le32_to_cpu(sb->delta_disks) - ++ reshape_chunk *= __le32_to_cpu(sb->raid_disks) - ++ __le32_to_cpu(sb->delta_disks) - + (__le32_to_cpu(sb->level)==6 ? 2 : 1); + if (reshape_sectors % reshape_chunk) { + pr_err("Reshape position is not suitably aligned.\n"); +@@ -1441,8 +1491,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + return -2; + } + } +- sb->raid_disks = __cpu_to_le32(__le32_to_cpu(sb->raid_disks) - +- __le32_to_cpu(sb->delta_disks)); ++ sb->raid_disks = ++ __cpu_to_le32(__le32_to_cpu(sb->raid_disks) - ++ __le32_to_cpu(sb->delta_disks)); + if (sb->delta_disks == 0) + sb->feature_map ^= __cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS); + else +@@ -1456,19 +1507,21 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->new_chunk = sb->chunksize; + sb->chunksize = temp; + +- if (sb->feature_map & __cpu_to_le32(MD_FEATURE_NEW_OFFSET)) { +- long offset_delta = (int32_t)__le32_to_cpu(sb->new_offset); ++ if (sb->feature_map & ++ __cpu_to_le32(MD_FEATURE_NEW_OFFSET)) { ++ long offset_delta = ++ (int32_t)__le32_to_cpu(sb->new_offset); + sb->data_offset = __cpu_to_le64(__le64_to_cpu(sb->data_offset) + offset_delta); + sb->new_offset = __cpu_to_le32(-offset_delta); + sb->data_size = __cpu_to_le64(__le64_to_cpu(sb->data_size) - offset_delta); + } + done:; + } +- } else if (strcmp(update, "_reshape_progress")==0) ++ } else if (strcmp(update, "_reshape_progress") == 0) + sb->reshape_position = __cpu_to_le64(info->reshape_progress); +- else if (strcmp(update, "writemostly")==0) ++ else if (strcmp(update, "writemostly") == 0) + sb->devflags |= WriteMostly1; +- else if (strcmp(update, "readwrite")==0) ++ else if (strcmp(update, "readwrite") == 0) + sb->devflags &= ~WriteMostly1; + else if (strcmp(update, "failfast") == 0) + sb->devflags |= FailFast1; +@@ -1553,11 +1606,14 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, + sb->resync_offset = MaxSector; + else + sb->resync_offset = 0; +- sbsize = sizeof(struct mdp_superblock_1) + 2 * (info->raid_disks + spares); ++ sbsize = sizeof(struct mdp_superblock_1) + ++ 2 * (info->raid_disks + spares); + sbsize = ROUND_UP(sbsize, 512); +- sb->max_dev = __cpu_to_le32((sbsize - sizeof(struct mdp_superblock_1)) / 2); ++ sb->max_dev = ++ __cpu_to_le32((sbsize - sizeof(struct mdp_superblock_1)) / 2); + +- memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1)); ++ memset(sb->dev_roles, 0xff, ++ MAX_SB_SIZE - sizeof(struct mdp_superblock_1)); + + if (s->consistency_policy == CONSISTENCY_POLICY_PPL) + sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); +@@ -1587,7 +1643,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { + rv = cluster_get_dlmlock(&lockid); + if (rv) { +- pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv); ++ pr_err("Cannot get dlmlock in %s return %d\n", ++ __func__, rv); + cluster_release_dlmlock(lockid); + return rv; + } +@@ -1599,7 +1656,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + *rp = __cpu_to_le16(dk->raid_disk); + else if (dk_state & (1< spare */ ++ else if ((dk_state & ~(1< spare */ + *rp = MD_DISK_ROLE_SPARE; + else + *rp = MD_DISK_ROLE_FAULTY; +@@ -1644,7 +1702,8 @@ static int store_super1(struct supertype *st, int fd) + if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { + rv = cluster_get_dlmlock(&lockid); + if (rv) { +- pr_err("Cannot get dlmlock in %s return %d\n", __func__, rv); ++ pr_err("Cannot get dlmlock in %s return %d\n", ++ __func__, rv); + cluster_release_dlmlock(lockid); + return rv; + } +@@ -1911,7 +1970,8 @@ static int write_init_super1(struct supertype *st) + bm_space = calc_bitmap_size(bms, 4096) >> 9; + bm_offset = (long)__le32_to_cpu(sb->bitmap_offset); + } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { +- bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize)); ++ bm_space = ++ choose_ppl_space(__le32_to_cpu(sb->chunksize)); + if (bm_space > UINT16_MAX) + bm_space = UINT16_MAX; + if (st->minor_version == 0) { +@@ -1981,7 +2041,10 @@ static int write_init_super1(struct supertype *st) + rv = -EINVAL; + goto out; + } +- /* Disable badblock log on clusters, or when explicitly requested */ ++ /* ++ * Disable badblock log on clusters, or when ++ * explicitly requested ++ */ + if (st->nodes > 0 || conf_get_create_info()->bblist == 0) { + sb->bblog_size = 0; + sb->bblog_offset = 0; +@@ -1997,7 +2060,8 @@ static int write_init_super1(struct supertype *st) + } + + if (rv == 0 && +- (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) { ++ (__le32_to_cpu(sb->feature_map) & ++ MD_FEATURE_BITMAP_OFFSET)) { + rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate); + } else if (rv == 0 && + (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) { +@@ -2014,8 +2078,7 @@ static int write_init_super1(struct supertype *st) + } + error_out: + if (rv) +- pr_err("Failed to write metadata to %s\n", +- di->devname); ++ pr_err("Failed to write metadata to %s\n", di->devname); + out: + return rv; + } +@@ -2080,7 +2143,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) + /* guess... choose latest ctime */ + memset(&tst, 0, sizeof(tst)); + tst.ss = &super1; +- for (tst.minor_version = 0; tst.minor_version <= 2 ; tst.minor_version++) { ++ for (tst.minor_version = 0; tst.minor_version <= 2; ++ tst.minor_version++) { + switch(load_super1(&tst, fd, devname)) { + case 0: super = tst.sb; + if (bestvers == -1 || +@@ -2167,7 +2231,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) + if (__le32_to_cpu(super->magic) != MD_SB_MAGIC) { + if (devname) + pr_err("No super block found on %s (Expected magic %08x, got %08x)\n", +- devname, MD_SB_MAGIC, __le32_to_cpu(super->magic)); ++ devname, MD_SB_MAGIC, ++ __le32_to_cpu(super->magic)); + free(super); + return 2; + } +@@ -2190,7 +2255,8 @@ static int load_super1(struct supertype *st, int fd, char *devname) + + bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); + +- misc = (struct misc_dev_info*) (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE); ++ misc = (struct misc_dev_info*) ++ (((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); +@@ -2230,13 +2296,11 @@ static struct supertype *match_metadata_desc1(char *arg) + /* leading zeros can be safely ignored. --detail generates them. */ + while (*arg == '0') + arg++; +- if (strcmp(arg, "1.0") == 0 || +- strcmp(arg, "1.00") == 0) { ++ if (strcmp(arg, "1.0") == 0 || strcmp(arg, "1.00") == 0) { + st->minor_version = 0; + return st; + } +- if (strcmp(arg, "1.1") == 0 || +- strcmp(arg, "1.01") == 0 ++ if (strcmp(arg, "1.1") == 0 || strcmp(arg, "1.01") == 0 + ) { + st->minor_version = 1; + return st; +@@ -2249,8 +2313,7 @@ static struct supertype *match_metadata_desc1(char *arg) + st->minor_version = 2; + return st; + } +- if (strcmp(arg, "1") == 0 || +- strcmp(arg, "default") == 0) { ++ if (strcmp(arg, "1") == 0 || strcmp(arg, "default") == 0) { + st->minor_version = -1; + return st; + } +@@ -2348,20 +2411,26 @@ add_internal_bitmap1(struct supertype *st, + int uuid[4]; + + if (__le64_to_cpu(sb->data_size) == 0) +- /* Must be creating the array, else data_size would be non-zero */ ++ /* ++ * Must be creating the array, else data_size ++ * would be non-zero ++ */ + creating = 1; + switch(st->minor_version) { + case 0: +- /* either 3K after the superblock (when hot-add), ++ /* ++ * either 3K after the superblock (when hot-add), + * or some amount of space before. + */ + if (creating) { +- /* We are creating array, so we *know* how much room has ++ /* ++ * We are creating array, so we *know* how much room has + * been left. + */ + offset = 0; + bbl_size = 8; +- room = choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size; ++ room = ++ choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size; + } else { + room = __le64_to_cpu(sb->super_offset) + - __le64_to_cpu(sb->data_offset) +@@ -2373,8 +2442,8 @@ add_internal_bitmap1(struct supertype *st, + if (bbl_size < -bbl_offset) + bbl_size = -bbl_offset; + +- if (!may_change || (room < 3*2 && +- __le32_to_cpu(sb->max_dev) <= 384)) { ++ if (!may_change || ++ (room < 3*2 && __le32_to_cpu(sb->max_dev) <= 384)) { + room = 3*2; + offset = 1*2; + bbl_size = 0; +@@ -2388,13 +2457,15 @@ add_internal_bitmap1(struct supertype *st, + if (creating) { + offset = 4*2; + bbl_size = 8; +- room = choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size; ++ room = ++ choose_bm_space(__le64_to_cpu(sb->size)) + bbl_size; + } else { + room = __le64_to_cpu(sb->data_offset) + - __le64_to_cpu(sb->super_offset); + bbl_size = __le16_to_cpu(sb->bblog_size); + if (bbl_size) +- room = __le32_to_cpu(sb->bblog_offset) + bbl_size; ++ room = ++ __le32_to_cpu(sb->bblog_offset) + bbl_size; + else + bbl_size = 8; + +@@ -2453,8 +2524,8 @@ add_internal_bitmap1(struct supertype *st, + + sb->bitmap_offset = (int32_t)__cpu_to_le32(offset); + +- sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) +- | MD_FEATURE_BITMAP_OFFSET); ++ sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | ++ MD_FEATURE_BITMAP_OFFSET); + memset(bms, 0, sizeof(*bms)); + bms->magic = __cpu_to_le32(BITMAP_MAGIC); + bms->version = __cpu_to_le32(major); +@@ -2466,8 +2537,8 @@ add_internal_bitmap1(struct supertype *st, + bms->write_behind = __cpu_to_le32(write_behind); + 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); ++ sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) | ++ MD_FEATURE_BITMAP_VERSIONED); + if (st->cluster_name) { + len = sizeof(bms->cluster_name); + strncpy((char *)bms->cluster_name, st->cluster_name, len); +@@ -2528,31 +2599,43 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update + break; + case NodeNumUpdate: + /* cluster md only supports superblock 1.2 now */ +- if (st->minor_version != 2 && bms->version == BITMAP_MAJOR_CLUSTERED) { ++ if (st->minor_version != 2 && ++ bms->version == BITMAP_MAJOR_CLUSTERED) { + pr_err("Warning: cluster md only works with superblock 1.2\n"); + return -EINVAL; + } + + if (bms->version == BITMAP_MAJOR_CLUSTERED) { + if (__cpu_to_le32(st->nodes) < bms->nodes) { +- /* Since the nodes num is not increased, no need to check the space +- * is enough or not, just update bms->nodes */ ++ /* ++ * Since the nodes num is not increased, no ++ * need to check the space enough or not, ++ * just update bms->nodes ++ */ + bms->nodes = __cpu_to_le32(st->nodes); + break; + } + } else { +- /* no need to change bms->nodes for other bitmap types */ ++ /* ++ * no need to change bms->nodes for other ++ * bitmap types ++ */ + if (st->nodes) + pr_err("Warning: --nodes option is only suitable for clustered bitmap\n"); + break; + } + +- /* Each node has an independent bitmap, it is necessary to calculate the +- * space is enough or not, first get how many bytes for the total bitmap */ ++ /* ++ * Each node has an independent bitmap, it is necessary to ++ * calculate the space is enough or not, first get how many ++ * bytes for the total bitmap ++ */ + bm_space_per_node = calc_bitmap_size(bms, 4096); + +- total_bm_space = 512 * (__le64_to_cpu(sb->data_offset) - __le64_to_cpu(sb->super_offset)); +- total_bm_space = total_bm_space - 4096; /* leave another 4k for superblock */ ++ total_bm_space = 512 * (__le64_to_cpu(sb->data_offset) - ++ __le64_to_cpu(sb->super_offset)); ++ /* leave another 4k for superblock */ ++ total_bm_space = total_bm_space - 4096; + + if (bm_space_per_node * st->nodes > total_bm_space) { + pr_err("Warning: The max num of nodes can't exceed %llu\n", +-- +2.7.4 + diff --git a/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch b/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch new file mode 100644 index 0000000..0b38da0 --- /dev/null +++ b/SOURCES/super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch @@ -0,0 +1,56 @@ +From 68fee4af1703dc0bc0d1c9c99fd750e8dca3a131 Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +Date: Thu, 25 May 2017 17:28:11 +0800 +Subject: [RHEL7.5 PATCH 148/169] super1: fix sb->max_dev when adding a new + disk in linear array + +The value of sb->max_dev will always be increased by 1 when adding +a new disk in linear array. It causes an inconsistence between each +disk in the array and the "Array State" value of "mdadm --examine DISK" +is wrong. For example, when adding the first new disk into linear array +it will be: + +Array State : RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +('A' == active, '.' == missing, 'R' == replacing) + +Adding the second disk into linear array it will be + +Array State : .AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +('A' == active, '.' == missing, 'R' == replacing) + +Signed-off-by: Lidong Zhong +Signed-off-by: Jes Sorensen +--- + super1.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/super1.c b/super1.c +index 2fcb814..86ec850 100644 +--- a/super1.c ++++ b/super1.c +@@ -1267,8 +1267,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + break; + sb->dev_number = __cpu_to_le32(i); + info->disk.number = i; +- if (max >= __le32_to_cpu(sb->max_dev)) ++ if (i >= max) { + sb->max_dev = __cpu_to_le32(max+1); ++ } + + random_uuid(sb->device_uuid); + +@@ -1293,7 +1294,11 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + } + } + } else if (strcmp(update, "linear-grow-update") == 0) { ++ int max = __le32_to_cpu(sb->max_dev); + sb->raid_disks = __cpu_to_le32(info->array.raid_disks); ++ if (info->array.raid_disks > max) { ++ sb->max_dev = __cpu_to_le32(max+1); ++ } + sb->dev_roles[info->disk.number] = + __cpu_to_le16(info->disk.raid_disk); + } else if (strcmp(update, "resync") == 0) { +-- +2.7.4 + diff --git a/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch b/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch new file mode 100644 index 0000000..f73b1b0 --- /dev/null +++ b/SOURCES/super1-ignore-failfast-flag-for-setting-device-role.patch @@ -0,0 +1,48 @@ +From e23c2663da73f905aa5fa9800feda3d08a8026ee Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Mon, 20 Mar 2017 10:51:56 +0100 +Subject: [RHEL7.5 PATCH 017/169] super1: ignore failfast flag for setting + device role + +There is corner case for setting device role, +if new device has failfast flag. +The failfast flag should be ignored. + +Signed-off-by: Gioh Kim +Signed-off-by: Jack Wang +Signed-off-by: Jes Sorensen +--- + super1.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/super1.c b/super1.c +index 882cd61..f3520ac 100644 +--- a/super1.c ++++ b/super1.c +@@ -1491,6 +1491,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + struct devinfo *di, **dip; + bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); + int rv, lockid; ++ int dk_state; + + if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { + rv = cluster_get_dlmlock(&lockid); +@@ -1501,11 +1502,12 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + } + } + +- if ((dk->state & 6) == 6) /* active, sync */ ++ dk_state = dk->state & ~(1<raid_disk); +- else if (dk->state & (1<state & ~2) == 0) /* active or idle -> spare */ ++ else if ((dk_state & ~2) == 0) /* active or idle -> spare */ + *rp = MD_DISK_ROLE_SPARE; + else + *rp = MD_DISK_ROLE_FAULTY; +-- +2.7.4 + diff --git a/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch b/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch new file mode 100644 index 0000000..59ccca1 --- /dev/null +++ b/SOURCES/super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch @@ -0,0 +1,43 @@ +From 6438c249c4fed92cf6e5fb492d19f4c4f516ff6f Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 4 Aug 2017 15:30:02 +1000 +Subject: [RHEL7.5 PATCH 166/169] super1: only set clustered flag when + bitmap is present + +If no bitmap is present, then the test + + if (__le32_to_cpu(bsb->nodes) > 1) + +accesses uninitialised memory. So move that test inside +a test for a bitmap being present. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + super1.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/super1.c b/super1.c +index b15a1c7..f6a1045 100644 +--- a/super1.c ++++ b/super1.c +@@ -977,14 +977,14 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512; + info->array.state = + (__le64_to_cpu(sb->resync_offset) == MaxSector) ? 1 : 0; +- if (__le32_to_cpu(bsb->nodes) > 1) +- info->array.state |= (1 << MD_SB_CLUSTERED); + + super_offset = __le64_to_cpu(sb->super_offset); + info->data_offset = __le64_to_cpu(sb->data_offset); + info->component_size = __le64_to_cpu(sb->size); + if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { + info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset); ++ if (__le32_to_cpu(bsb->nodes) > 1) ++ info->array.state |= (1 << MD_SB_CLUSTERED); + } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { + info->ppl_offset = __le16_to_cpu(sb->ppl.offset); + info->ppl_size = __le16_to_cpu(sb->ppl.size); +-- +2.7.4 + diff --git a/SOURCES/super1-ppl-support.patch b/SOURCES/super1-ppl-support.patch deleted file mode 100644 index 665387d..0000000 --- a/SOURCES/super1-ppl-support.patch +++ /dev/null @@ -1,430 +0,0 @@ -commit e97a7cd011345e5dead736de51b33968da49d876 -Author: Artur Paszkiewicz -Date: Wed Mar 29 11:54:18 2017 +0200 - - super1: PPL support - - Enable creating and assembling raid5 arrays with PPL for 1.x metadata. - - When creating, reserve enough space for PPL and store its size and - location in the superblock and set MD_FEATURE_PPL bit. Write an initial - empty header in the PPL area on each device. PPL is stored in the - metadata region reserved for internal write-intent bitmap, so don't - allow using bitmap and PPL together. - - While at it, fix two endianness issues in write_empty_r5l_meta_block() - and write_init_super1(). - - Signed-off-by: Artur Paszkiewicz - Signed-off-by: Jes Sorensen - -diff --git a/Assemble.c b/Assemble.c -index 8e55b49..c098420 100644 ---- a/Assemble.c -+++ b/Assemble.c -@@ -962,6 +962,9 @@ static int start_array(int mdfd, - c->readonly = 1; - } - -+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) -+ clean = 1; -+ - rv = set_array_info(mdfd, st, content); - if (rv && !err_ok) { - pr_err("failed to set array info for %s: %s\n", -diff --git a/Create.c b/Create.c -index 4080bf6..10e7d10 100644 ---- a/Create.c -+++ b/Create.c -@@ -524,6 +524,8 @@ int Create(struct supertype *st, char *mddev, - if (!s->bitmap_file && - s->level >= 1 && - st->ss->add_internal_bitmap && -+ (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && -+ s->consistency_policy != CONSISTENCY_POLICY_PPL) && - (s->write_behind || s->size > 100*1024*1024ULL)) { - if (c->verbose > 0) - pr_err("automatically enabling write-intent bitmap on large array\n"); -diff --git a/Grow.c b/Grow.c -index e22661c..a849012 100755 ---- a/Grow.c -+++ b/Grow.c -@@ -290,6 +290,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - int major = BITMAP_MAJOR_HI; - int vers = md_get_version(fd); - unsigned long long bitmapsize, array_size; -+ struct mdinfo *mdi; - - if (vers < 9003) { - major = BITMAP_MAJOR_HOSTENDIAN; -@@ -389,12 +390,23 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - free(st); - return 1; - } -+ -+ mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY); -+ if (mdi) { -+ if (mdi->consistency_policy == CONSISTENCY_POLICY_PPL) { -+ pr_err("Cannot add bitmap to array with PPL\n"); -+ free(mdi); -+ free(st); -+ return 1; -+ } -+ free(mdi); -+ } -+ - if (strcmp(s->bitmap_file, "internal") == 0 || - strcmp(s->bitmap_file, "clustered") == 0) { - int rv; - int d; - int offset_setable = 0; -- struct mdinfo *mdi; - if (st->ss->add_internal_bitmap == NULL) { - pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name); - return 1; -@@ -446,6 +458,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - sysfs_init(mdi, fd, NULL); - rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", - mdi->bitmap_offset); -+ free(mdi); - } else { - if (strcmp(s->bitmap_file, "clustered") == 0) - array.state |= (1 << MD_SB_CLUSTERED); -diff --git a/Incremental.c b/Incremental.c -index 0f507bb..81afc7e 100644 ---- a/Incremental.c -+++ b/Incremental.c -@@ -528,6 +528,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, - - journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); - -+ if (info.consistency_policy == CONSISTENCY_POLICY_PPL) -+ info.array.state |= 1; -+ - if (enough(info.array.level, info.array.raid_disks, - info.array.layout, info.array.state & 1, - avail) == 0) { -diff --git a/mdadm.h b/mdadm.h -index d222cc3..2c7066d 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -302,6 +302,7 @@ struct mdinfo { - long bitmap_offset; /* 0 == none, 1 == a file */ - unsigned int ppl_size; - unsigned long long ppl_sector; -+ int ppl_offset; - unsigned long safe_mode_delay; /* ms delay to mark clean */ - int new_level, delta_disks, new_layout, new_chunk; - int errors; -diff --git a/super1.c b/super1.c -index 8df17a1..409b6c3 100644 ---- a/super1.c -+++ b/super1.c -@@ -48,10 +48,18 @@ struct mdp_superblock_1 { - - __u32 chunksize; /* in 512byte sectors */ - __u32 raid_disks; -- __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. -- */ -+ 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 */ -@@ -131,6 +139,7 @@ struct misc_dev_info { - #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_ALL (MD_FEATURE_BITMAP_OFFSET \ - |MD_FEATURE_RECOVERY_OFFSET \ - |MD_FEATURE_RESHAPE_ACTIVE \ -@@ -140,6 +149,7 @@ struct misc_dev_info { - |MD_FEATURE_NEW_OFFSET \ - |MD_FEATURE_BITMAP_VERSIONED \ - |MD_FEATURE_JOURNAL \ -+ |MD_FEATURE_PPL \ - ) - - #ifndef MDASSEMBLE -@@ -289,6 +299,11 @@ static int awrite(struct align_fd *afd, void *buf, int len) - return len; - } - -+static inline unsigned int choose_ppl_space(int chunk) -+{ -+ return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2); -+} -+ - #ifndef MDASSEMBLE - static void examine_super1(struct supertype *st, char *homehost) - { -@@ -392,6 +407,10 @@ static void examine_super1(struct supertype *st, char *homehost) - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { - printf("Internal Bitmap : %ld sectors from superblock\n", - (long)(int32_t)__le32_to_cpu(sb->bitmap_offset)); -+ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { -+ printf(" PPL : %u sectors at offset %d sectors from superblock\n", -+ __le16_to_cpu(sb->ppl.size), -+ __le16_to_cpu(sb->ppl.offset)); - } - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) { - printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2, -@@ -934,10 +953,16 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - if (__le32_to_cpu(bsb->nodes) > 1) - info->array.state |= (1 << MD_SB_CLUSTERED); - -+ super_offset = __le64_to_cpu(sb->super_offset); - info->data_offset = __le64_to_cpu(sb->data_offset); - info->component_size = __le64_to_cpu(sb->size); -- if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) -+ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { - info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset); -+ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { -+ info->ppl_offset = __le16_to_cpu(sb->ppl.offset); -+ info->ppl_size = __le16_to_cpu(sb->ppl.size); -+ info->ppl_sector = super_offset + info->ppl_offset; -+ } - - info->disk.major = 0; - info->disk.minor = 0; -@@ -948,7 +973,6 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - else - role = __le16_to_cpu(sb->dev_roles[__le32_to_cpu(sb->dev_number)]); - -- super_offset = __le64_to_cpu(sb->super_offset); - if (info->array.level <= 0) - data_size = __le64_to_cpu(sb->data_size); - else -@@ -965,8 +989,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - end = bboffset; - } - -- if (super_offset + info->bitmap_offset < end) -- end = super_offset + info->bitmap_offset; -+ if (super_offset + info->bitmap_offset + info->ppl_offset < end) -+ end = super_offset + info->bitmap_offset + info->ppl_offset; - - if (info->data_offset + data_size < end) - info->space_after = end - data_size - info->data_offset; -@@ -982,6 +1006,11 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - bmend += size; - if (bmend > earliest) - earliest = bmend; -+ } else if (info->ppl_offset > 0) { -+ unsigned long long pplend = info->ppl_offset + -+ info->ppl_size; -+ if (pplend > earliest) -+ earliest = pplend; - } - if (sb->bblog_offset && sb->bblog_size) { - unsigned long long bbend = super_offset; -@@ -1075,8 +1104,20 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) - } - - info->array.working_disks = working; -- if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) -+ -+ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) { - info->journal_device_required = 1; -+ info->consistency_policy = CONSISTENCY_POLICY_JOURNAL; -+ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { -+ info->consistency_policy = CONSISTENCY_POLICY_PPL; -+ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { -+ info->consistency_policy = CONSISTENCY_POLICY_BITMAP; -+ } else if (info->array.level <= 0) { -+ info->consistency_policy = CONSISTENCY_POLICY_NONE; -+ } else { -+ info->consistency_policy = CONSISTENCY_POLICY_RESYNC; -+ } -+ - info->journal_clean = 0; - } - -@@ -1239,6 +1280,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, - if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { - bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset); - bm_sectors = calc_bitmap_size(bms, 4096) >> 9; -+ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { -+ bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset); -+ bm_sectors = (long)__le16_to_cpu(sb->ppl.size); - } - #endif - if (sb_offset < data_offset) { -@@ -1472,6 +1516,9 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, - - memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1)); - -+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) -+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); -+ - return 1; - } - -@@ -1645,10 +1692,49 @@ static unsigned long choose_bm_space(unsigned long devsize) - - static void free_super1(struct supertype *st); - --#define META_BLOCK_SIZE 4096 -+#ifndef MDASSEMBLE -+ - __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len); - --#ifndef MDASSEMBLE -+static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd) -+{ -+ struct mdp_superblock_1 *sb = st->sb; -+ void *buf; -+ struct ppl_header *ppl_hdr; -+ int ret; -+ -+ ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE); -+ if (ret) { -+ pr_err("Failed to allocate PPL header buffer\n"); -+ return ret; -+ } -+ -+ memset(buf, 0, PPL_HEADER_SIZE); -+ ppl_hdr = buf; -+ memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED); -+ ppl_hdr->signature = __cpu_to_le32(~crc32c_le(~0, sb->set_uuid, -+ sizeof(sb->set_uuid))); -+ ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE)); -+ -+ if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) { -+ ret = errno; -+ perror("Failed to seek to PPL header location"); -+ } -+ -+ if (!ret && write(fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) { -+ ret = errno; -+ perror("Write PPL header failed"); -+ } -+ -+ if (!ret) -+ fsync(fd); -+ -+ free(buf); -+ return ret; -+} -+ -+#define META_BLOCK_SIZE 4096 -+ - static int write_empty_r5l_meta_block(struct supertype *st, int fd) - { - struct r5l_meta_block *mb; -@@ -1675,7 +1761,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) - crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE); - mb->checksum = crc; - -- if (lseek64(fd, (sb->data_offset) * 512, 0) < 0LL) { -+ if (lseek64(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) { - pr_err("cannot seek to offset of the meta block\n"); - goto fail_to_write; - } -@@ -1708,7 +1794,7 @@ static int write_init_super1(struct supertype *st) - - for (di = st->info; di; di = di->next) { - if (di->disk.state & (1 << MD_DISK_JOURNAL)) -- sb->feature_map |= MD_FEATURE_JOURNAL; -+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); - } - - for (di = st->info; di; di = di->next) { -@@ -1783,6 +1869,21 @@ static int write_init_super1(struct supertype *st) - (((char *)sb) + MAX_SB_SIZE); - bm_space = calc_bitmap_size(bms, 4096) >> 9; - bm_offset = (long)__le32_to_cpu(sb->bitmap_offset); -+ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { -+ bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize)); -+ if (bm_space > UINT16_MAX) -+ bm_space = UINT16_MAX; -+ if (st->minor_version == 0) { -+ bm_offset = -bm_space - 8; -+ if (bm_offset < INT16_MIN) { -+ bm_offset = INT16_MIN; -+ bm_space = -bm_offset - 8; -+ } -+ } else { -+ bm_offset = 8; -+ } -+ sb->ppl.offset = __cpu_to_le16(bm_offset); -+ sb->ppl.size = __cpu_to_le16(bm_space); - } else { - bm_space = choose_bm_space(array_size); - bm_offset = 8; -@@ -1854,8 +1955,17 @@ static int write_init_super1(struct supertype *st) - goto error_out; - } - -- if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1)) -+ if (rv == 0 && -+ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) { - rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate); -+ } else if (rv == 0 && -+ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) { -+ struct mdinfo info; -+ -+ st->ss->getinfo_super(st, &info, NULL); -+ rv = st->ss->write_init_ppl(st, &info, di->fd); -+ } -+ - close(di->fd); - di->fd = -1; - if (rv) -@@ -2123,11 +2233,13 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, - return 0; - - #ifndef MDASSEMBLE -- if (__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) { -+ 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); - bmspace = calc_bitmap_size(bsb, 4096) >> 9; -+ } else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) { -+ bmspace = __le16_to_cpu(super->ppl.size); - } - #endif - /* Allow space for bad block log */ -@@ -2530,8 +2642,9 @@ static int validate_geometry1(struct supertype *st, int level, - return 0; - } - -- /* creating: allow suitable space for bitmap */ -- bmspace = choose_bm_space(devsize); -+ /* creating: allow suitable space for bitmap or PPL */ -+ bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ? -+ choose_ppl_space((*chunk)*2) : choose_bm_space(devsize); - - if (data_offset == INVALID_SECTORS) - data_offset = st->data_offset; -@@ -2566,7 +2679,7 @@ static int validate_geometry1(struct supertype *st, int level, - switch(st->minor_version) { - case 0: /* metadata at end. Round down and subtract space to reserve */ - devsize = (devsize & ~(4ULL*2-1)); -- /* space for metadata, bblog, bitmap */ -+ /* space for metadata, bblog, bitmap/ppl */ - devsize -= 8*2 + 8 + bmspace; - break; - case 1: -@@ -2642,6 +2755,7 @@ struct superswitch super1 = { - .add_to_super = add_to_super1, - .examine_badblocks = examine_badblocks_super1, - .copy_metadata = copy_metadata1, -+ .write_init_ppl = write_init_ppl1, - #endif - .match_home = match_home1, - .uuid_from_super = uuid_from_super1, diff --git a/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch b/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch new file mode 100644 index 0000000..2816e3a --- /dev/null +++ b/SOURCES/super1-replace-hard-coded-values-with-bit-definition.patch @@ -0,0 +1,46 @@ +From aa3131183661955de112fa7d9824207de63d9fa5 Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Wed, 29 Mar 2017 11:40:33 +0200 +Subject: [RHEL7.5 PATCH 032/169] super1: replace hard-coded values with + bit definitions + +Some hard-coded values for disk status are replaced +with bit definitions. + +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + super1.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/super1.c b/super1.c +index e76f777..6f91611 100644 +--- a/super1.c ++++ b/super1.c +@@ -1040,7 +1040,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->disk.state = 0; /* spare: not active, not sync, not faulty */ + break; + case MD_DISK_ROLE_FAULTY: +- info->disk.state = 1; /* faulty */ ++ info->disk.state = (1 << MD_DISK_FAULTY); /* faulty */ + break; + case MD_DISK_ROLE_JOURNAL: + info->disk.state = (1 << MD_DISK_JOURNAL); +@@ -1600,11 +1600,12 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + } + + dk_state = dk->state & ~(1<raid_disk); + else if (dk_state & (1< spare */ ++ else if ((dk_state & ~(1< spare */ + *rp = MD_DISK_ROLE_SPARE; + else + *rp = MD_DISK_ROLE_FAULTY; +-- +2.7.4 + diff --git a/SOURCES/super1add-support-for-multiple-ppls.patch b/SOURCES/super1add-support-for-multiple-ppls.patch new file mode 100644 index 0000000..ccf70e7 --- /dev/null +++ b/SOURCES/super1add-support-for-multiple-ppls.patch @@ -0,0 +1,194 @@ +From fa601c2e897adfb3d2316377354269ffdeb824c3 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Thu, 28 Sep 2017 14:41:08 +0200 +Subject: [PATCH 02/12] super1: Add support for multiple-ppls + +Add support for super1 with multiple ppls. Extend ppl area size to 1MB. +Use 1MB as default during creation. Always start array as single ppl - +if kernel is capable of multiple ppls and there is enough space reserved - +it will switch the policy during first metadata update. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super1.c | 65 ++++++++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 37 insertions(+), 28 deletions(-) + +diff --git a/super1.c b/super1.c +index 3cfbbc0..f80e38a 100644 +--- a/super1.c ++++ b/super1.c +@@ -121,6 +121,9 @@ struct misc_dev_info { + __u64 device_size; + }; + ++#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 +@@ -140,6 +143,7 @@ struct misc_dev_info { + #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_ALL (MD_FEATURE_BITMAP_OFFSET \ + |MD_FEATURE_RECOVERY_OFFSET \ + |MD_FEATURE_RESHAPE_ACTIVE \ +@@ -150,6 +154,7 @@ struct misc_dev_info { + |MD_FEATURE_BITMAP_VERSIONED \ + |MD_FEATURE_JOURNAL \ + |MD_FEATURE_PPL \ ++ |MD_FEATURE_MULTIPLE_PPLS \ + ) + + static int role_from_sb(struct mdp_superblock_1 *sb) +@@ -298,6 +303,12 @@ static int awrite(struct align_fd *afd, void *buf, int len) + return 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))); ++} ++ + static inline unsigned int choose_ppl_space(int chunk) + { + return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2); +@@ -409,7 +420,7 @@ static void examine_super1(struct supertype *st, char *homehost) + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + printf("Internal Bitmap : %ld sectors from superblock\n", + (long)(int32_t)__le32_to_cpu(sb->bitmap_offset)); +- } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { ++ } else if (md_feature_any_ppl_on(sb->feature_map)) { + printf(" PPL : %u sectors at offset %d sectors from superblock\n", + __le16_to_cpu(sb->ppl.size), + __le16_to_cpu(sb->ppl.offset)); +@@ -985,7 +996,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset); + if (__le32_to_cpu(bsb->nodes) > 1) + info->array.state |= (1 << MD_SB_CLUSTERED); +- } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { ++ } else if (md_feature_any_ppl_on(sb->feature_map)) { + info->ppl_offset = __le16_to_cpu(sb->ppl.offset); + info->ppl_size = __le16_to_cpu(sb->ppl.size); + info->ppl_sector = super_offset + info->ppl_offset; +@@ -1140,7 +1151,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) { + info->journal_device_required = 1; + info->consistency_policy = CONSISTENCY_POLICY_JOURNAL; +- } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { ++ } else if (md_feature_any_ppl_on(sb->feature_map)) { + info->consistency_policy = CONSISTENCY_POLICY_PPL; + } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { + info->consistency_policy = CONSISTENCY_POLICY_BITMAP; +@@ -1324,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset); + bm_sectors = calc_bitmap_size(bms, 4096) >> 9; +- } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { ++ } else if (md_feature_any_ppl_on(sb->feature_map)) { + bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset); + bm_sectors = (long)__le16_to_cpu(sb->ppl.size); + } +@@ -1377,7 +1388,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + unsigned long long data_size = __le64_to_cpu(sb->data_size); + long bb_offset = __le32_to_cpu(sb->bblog_offset); + int space; +- int optimal_space; + int offset; + + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { +@@ -1408,18 +1418,23 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + return -2; + } + +- optimal_space = choose_ppl_space(__le32_to_cpu(sb->chunksize)); +- +- if (space > optimal_space) +- space = optimal_space; +- if (space > UINT16_MAX) +- space = UINT16_MAX; ++ if (space >= (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9)) { ++ space = (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9); ++ } else { ++ int optimal_space = choose_ppl_space( ++ __le32_to_cpu(sb->chunksize)); ++ if (space > optimal_space) ++ space = optimal_space; ++ if (space > UINT16_MAX) ++ space = UINT16_MAX; ++ } + + 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) { +- sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_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); +@@ -1974,20 +1989,12 @@ static int write_init_super1(struct supertype *st) + (((char *)sb) + MAX_SB_SIZE); + bm_space = calc_bitmap_size(bms, 4096) >> 9; + bm_offset = (long)__le32_to_cpu(sb->bitmap_offset); +- } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { +- bm_space = +- choose_ppl_space(__le32_to_cpu(sb->chunksize)); +- if (bm_space > UINT16_MAX) +- bm_space = UINT16_MAX; +- if (st->minor_version == 0) { ++ } else if (md_feature_any_ppl_on(sb->feature_map)) { ++ bm_space = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; ++ if (st->minor_version == 0) + bm_offset = -bm_space - 8; +- if (bm_offset < INT16_MIN) { +- bm_offset = INT16_MIN; +- bm_space = -bm_offset - 8; +- } +- } else { ++ else + bm_offset = 8; +- } + sb->ppl.offset = __cpu_to_le16(bm_offset); + sb->ppl.size = __cpu_to_le16(bm_space); + } else { +@@ -2069,7 +2076,7 @@ static int write_init_super1(struct supertype *st) + MD_FEATURE_BITMAP_OFFSET)) { + rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate); + } else if (rv == 0 && +- (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) { ++ md_feature_any_ppl_on(sb->feature_map)) { + struct mdinfo info; + + st->ss->getinfo_super(st, &info, NULL); +@@ -2345,7 +2352,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, + struct bitmap_super_s *bsb; + bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); + bmspace = calc_bitmap_size(bsb, 4096) >> 9; +- } else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) { ++ } else if (md_feature_any_ppl_on(super->feature_map)) { + bmspace = __le16_to_cpu(super->ppl.size); + } + +@@ -2769,8 +2776,10 @@ static int validate_geometry1(struct supertype *st, int level, + } + + /* creating: allow suitable space for bitmap or PPL */ +- bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ? +- choose_ppl_space((*chunk)*2) : choose_bm_space(devsize); ++ if (consistency_policy == CONSISTENCY_POLICY_PPL) ++ bmspace = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; ++ else ++ bmspace = choose_bm_space(devsize); + + if (data_offset == INVALID_SECTORS) + data_offset = st->data_offset; +-- +2.7.4 + diff --git a/SOURCES/super1ppl-support.patch b/SOURCES/super1ppl-support.patch new file mode 100644 index 0000000..665387d --- /dev/null +++ b/SOURCES/super1ppl-support.patch @@ -0,0 +1,430 @@ +commit e97a7cd011345e5dead736de51b33968da49d876 +Author: Artur Paszkiewicz +Date: Wed Mar 29 11:54:18 2017 +0200 + + super1: PPL support + + Enable creating and assembling raid5 arrays with PPL for 1.x metadata. + + When creating, reserve enough space for PPL and store its size and + location in the superblock and set MD_FEATURE_PPL bit. Write an initial + empty header in the PPL area on each device. PPL is stored in the + metadata region reserved for internal write-intent bitmap, so don't + allow using bitmap and PPL together. + + While at it, fix two endianness issues in write_empty_r5l_meta_block() + and write_init_super1(). + + Signed-off-by: Artur Paszkiewicz + Signed-off-by: Jes Sorensen + +diff --git a/Assemble.c b/Assemble.c +index 8e55b49..c098420 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -962,6 +962,9 @@ static int start_array(int mdfd, + c->readonly = 1; + } + ++ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) ++ clean = 1; ++ + rv = set_array_info(mdfd, st, content); + if (rv && !err_ok) { + pr_err("failed to set array info for %s: %s\n", +diff --git a/Create.c b/Create.c +index 4080bf6..10e7d10 100644 +--- a/Create.c ++++ b/Create.c +@@ -524,6 +524,8 @@ int Create(struct supertype *st, char *mddev, + if (!s->bitmap_file && + s->level >= 1 && + st->ss->add_internal_bitmap && ++ (s->consistency_policy != CONSISTENCY_POLICY_RESYNC && ++ s->consistency_policy != CONSISTENCY_POLICY_PPL) && + (s->write_behind || s->size > 100*1024*1024ULL)) { + if (c->verbose > 0) + pr_err("automatically enabling write-intent bitmap on large array\n"); +diff --git a/Grow.c b/Grow.c +index e22661c..a849012 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -290,6 +290,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + int major = BITMAP_MAJOR_HI; + int vers = md_get_version(fd); + unsigned long long bitmapsize, array_size; ++ struct mdinfo *mdi; + + if (vers < 9003) { + major = BITMAP_MAJOR_HOSTENDIAN; +@@ -389,12 +390,23 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + free(st); + return 1; + } ++ ++ mdi = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY); ++ if (mdi) { ++ if (mdi->consistency_policy == CONSISTENCY_POLICY_PPL) { ++ pr_err("Cannot add bitmap to array with PPL\n"); ++ free(mdi); ++ free(st); ++ return 1; ++ } ++ free(mdi); ++ } ++ + if (strcmp(s->bitmap_file, "internal") == 0 || + strcmp(s->bitmap_file, "clustered") == 0) { + int rv; + int d; + int offset_setable = 0; +- struct mdinfo *mdi; + if (st->ss->add_internal_bitmap == NULL) { + pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name); + return 1; +@@ -446,6 +458,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + sysfs_init(mdi, fd, NULL); + rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", + mdi->bitmap_offset); ++ free(mdi); + } else { + if (strcmp(s->bitmap_file, "clustered") == 0) + array.state |= (1 << MD_SB_CLUSTERED); +diff --git a/Incremental.c b/Incremental.c +index 0f507bb..81afc7e 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -528,6 +528,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + + journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0); + ++ if (info.consistency_policy == CONSISTENCY_POLICY_PPL) ++ info.array.state |= 1; ++ + if (enough(info.array.level, info.array.raid_disks, + info.array.layout, info.array.state & 1, + avail) == 0) { +diff --git a/mdadm.h b/mdadm.h +index d222cc3..2c7066d 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -302,6 +302,7 @@ struct mdinfo { + long bitmap_offset; /* 0 == none, 1 == a file */ + unsigned int ppl_size; + unsigned long long ppl_sector; ++ int ppl_offset; + unsigned long safe_mode_delay; /* ms delay to mark clean */ + int new_level, delta_disks, new_layout, new_chunk; + int errors; +diff --git a/super1.c b/super1.c +index 8df17a1..409b6c3 100644 +--- a/super1.c ++++ b/super1.c +@@ -48,10 +48,18 @@ struct mdp_superblock_1 { + + __u32 chunksize; /* in 512byte sectors */ + __u32 raid_disks; +- __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. +- */ ++ 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 */ +@@ -131,6 +139,7 @@ struct misc_dev_info { + #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_ALL (MD_FEATURE_BITMAP_OFFSET \ + |MD_FEATURE_RECOVERY_OFFSET \ + |MD_FEATURE_RESHAPE_ACTIVE \ +@@ -140,6 +149,7 @@ struct misc_dev_info { + |MD_FEATURE_NEW_OFFSET \ + |MD_FEATURE_BITMAP_VERSIONED \ + |MD_FEATURE_JOURNAL \ ++ |MD_FEATURE_PPL \ + ) + + #ifndef MDASSEMBLE +@@ -289,6 +299,11 @@ static int awrite(struct align_fd *afd, void *buf, int len) + return len; + } + ++static inline unsigned int choose_ppl_space(int chunk) ++{ ++ return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2); ++} ++ + #ifndef MDASSEMBLE + static void examine_super1(struct supertype *st, char *homehost) + { +@@ -392,6 +407,10 @@ static void examine_super1(struct supertype *st, char *homehost) + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + printf("Internal Bitmap : %ld sectors from superblock\n", + (long)(int32_t)__le32_to_cpu(sb->bitmap_offset)); ++ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { ++ printf(" PPL : %u sectors at offset %d sectors from superblock\n", ++ __le16_to_cpu(sb->ppl.size), ++ __le16_to_cpu(sb->ppl.offset)); + } + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) { + printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2, +@@ -934,10 +953,16 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + if (__le32_to_cpu(bsb->nodes) > 1) + info->array.state |= (1 << MD_SB_CLUSTERED); + ++ super_offset = __le64_to_cpu(sb->super_offset); + info->data_offset = __le64_to_cpu(sb->data_offset); + info->component_size = __le64_to_cpu(sb->size); +- if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) ++ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { + info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset); ++ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { ++ info->ppl_offset = __le16_to_cpu(sb->ppl.offset); ++ info->ppl_size = __le16_to_cpu(sb->ppl.size); ++ info->ppl_sector = super_offset + info->ppl_offset; ++ } + + info->disk.major = 0; + info->disk.minor = 0; +@@ -948,7 +973,6 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + else + role = __le16_to_cpu(sb->dev_roles[__le32_to_cpu(sb->dev_number)]); + +- super_offset = __le64_to_cpu(sb->super_offset); + if (info->array.level <= 0) + data_size = __le64_to_cpu(sb->data_size); + else +@@ -965,8 +989,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + end = bboffset; + } + +- if (super_offset + info->bitmap_offset < end) +- end = super_offset + info->bitmap_offset; ++ if (super_offset + info->bitmap_offset + info->ppl_offset < end) ++ end = super_offset + info->bitmap_offset + info->ppl_offset; + + if (info->data_offset + data_size < end) + info->space_after = end - data_size - info->data_offset; +@@ -982,6 +1006,11 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + bmend += size; + if (bmend > earliest) + earliest = bmend; ++ } else if (info->ppl_offset > 0) { ++ unsigned long long pplend = info->ppl_offset + ++ info->ppl_size; ++ if (pplend > earliest) ++ earliest = pplend; + } + if (sb->bblog_offset && sb->bblog_size) { + unsigned long long bbend = super_offset; +@@ -1075,8 +1104,20 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) + } + + info->array.working_disks = working; +- if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) ++ ++ if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) { + info->journal_device_required = 1; ++ info->consistency_policy = CONSISTENCY_POLICY_JOURNAL; ++ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { ++ info->consistency_policy = CONSISTENCY_POLICY_PPL; ++ } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { ++ info->consistency_policy = CONSISTENCY_POLICY_BITMAP; ++ } else if (info->array.level <= 0) { ++ info->consistency_policy = CONSISTENCY_POLICY_NONE; ++ } else { ++ info->consistency_policy = CONSISTENCY_POLICY_RESYNC; ++ } ++ + info->journal_clean = 0; + } + +@@ -1239,6 +1280,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { + bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset); + bm_sectors = calc_bitmap_size(bms, 4096) >> 9; ++ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { ++ bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset); ++ bm_sectors = (long)__le16_to_cpu(sb->ppl.size); + } + #endif + if (sb_offset < data_offset) { +@@ -1472,6 +1516,9 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, + + memset(sb->dev_roles, 0xff, MAX_SB_SIZE - sizeof(struct mdp_superblock_1)); + ++ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) ++ sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); ++ + return 1; + } + +@@ -1645,10 +1692,49 @@ static unsigned long choose_bm_space(unsigned long devsize) + + static void free_super1(struct supertype *st); + +-#define META_BLOCK_SIZE 4096 ++#ifndef MDASSEMBLE ++ + __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len); + +-#ifndef MDASSEMBLE ++static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd) ++{ ++ struct mdp_superblock_1 *sb = st->sb; ++ void *buf; ++ struct ppl_header *ppl_hdr; ++ int ret; ++ ++ ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE); ++ if (ret) { ++ pr_err("Failed to allocate PPL header buffer\n"); ++ return ret; ++ } ++ ++ memset(buf, 0, PPL_HEADER_SIZE); ++ ppl_hdr = buf; ++ memset(ppl_hdr->reserved, 0xff, PPL_HDR_RESERVED); ++ ppl_hdr->signature = __cpu_to_le32(~crc32c_le(~0, sb->set_uuid, ++ sizeof(sb->set_uuid))); ++ ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE)); ++ ++ if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) { ++ ret = errno; ++ perror("Failed to seek to PPL header location"); ++ } ++ ++ if (!ret && write(fd, buf, PPL_HEADER_SIZE) != PPL_HEADER_SIZE) { ++ ret = errno; ++ perror("Write PPL header failed"); ++ } ++ ++ if (!ret) ++ fsync(fd); ++ ++ free(buf); ++ return ret; ++} ++ ++#define META_BLOCK_SIZE 4096 ++ + static int write_empty_r5l_meta_block(struct supertype *st, int fd) + { + struct r5l_meta_block *mb; +@@ -1675,7 +1761,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd) + crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE); + mb->checksum = crc; + +- if (lseek64(fd, (sb->data_offset) * 512, 0) < 0LL) { ++ if (lseek64(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) { + pr_err("cannot seek to offset of the meta block\n"); + goto fail_to_write; + } +@@ -1708,7 +1794,7 @@ static int write_init_super1(struct supertype *st) + + for (di = st->info; di; di = di->next) { + if (di->disk.state & (1 << MD_DISK_JOURNAL)) +- sb->feature_map |= MD_FEATURE_JOURNAL; ++ sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); + } + + for (di = st->info; di; di = di->next) { +@@ -1783,6 +1869,21 @@ static int write_init_super1(struct supertype *st) + (((char *)sb) + MAX_SB_SIZE); + bm_space = calc_bitmap_size(bms, 4096) >> 9; + bm_offset = (long)__le32_to_cpu(sb->bitmap_offset); ++ } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { ++ bm_space = choose_ppl_space(__le32_to_cpu(sb->chunksize)); ++ if (bm_space > UINT16_MAX) ++ bm_space = UINT16_MAX; ++ if (st->minor_version == 0) { ++ bm_offset = -bm_space - 8; ++ if (bm_offset < INT16_MIN) { ++ bm_offset = INT16_MIN; ++ bm_space = -bm_offset - 8; ++ } ++ } else { ++ bm_offset = 8; ++ } ++ sb->ppl.offset = __cpu_to_le16(bm_offset); ++ sb->ppl.size = __cpu_to_le16(bm_space); + } else { + bm_space = choose_bm_space(array_size); + bm_offset = 8; +@@ -1854,8 +1955,17 @@ static int write_init_super1(struct supertype *st) + goto error_out; + } + +- if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1)) ++ if (rv == 0 && ++ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) { + rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate); ++ } else if (rv == 0 && ++ (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) { ++ struct mdinfo info; ++ ++ st->ss->getinfo_super(st, &info, NULL); ++ rv = st->ss->write_init_ppl(st, &info, di->fd); ++ } ++ + close(di->fd); + di->fd = -1; + if (rv) +@@ -2123,11 +2233,13 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, + return 0; + + #ifndef MDASSEMBLE +- if (__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) { ++ 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); + bmspace = calc_bitmap_size(bsb, 4096) >> 9; ++ } else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) { ++ bmspace = __le16_to_cpu(super->ppl.size); + } + #endif + /* Allow space for bad block log */ +@@ -2530,8 +2642,9 @@ static int validate_geometry1(struct supertype *st, int level, + return 0; + } + +- /* creating: allow suitable space for bitmap */ +- bmspace = choose_bm_space(devsize); ++ /* creating: allow suitable space for bitmap or PPL */ ++ bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ? ++ choose_ppl_space((*chunk)*2) : choose_bm_space(devsize); + + if (data_offset == INVALID_SECTORS) + data_offset = st->data_offset; +@@ -2566,7 +2679,7 @@ static int validate_geometry1(struct supertype *st, int level, + switch(st->minor_version) { + case 0: /* metadata at end. Round down and subtract space to reserve */ + devsize = (devsize & ~(4ULL*2-1)); +- /* space for metadata, bblog, bitmap */ ++ /* space for metadata, bblog, bitmap/ppl */ + devsize -= 8*2 + 8 + bmspace; + break; + case 1: +@@ -2642,6 +2755,7 @@ struct superswitch super1 = { + .add_to_super = add_to_super1, + .examine_badblocks = examine_badblocks_super1, + .copy_metadata = copy_metadata1, ++ .write_init_ppl = write_init_ppl1, + #endif + .match_home = match_home1, + .uuid_from_super = uuid_from_super1, diff --git a/SOURCES/support-consistency-policy-change.patch b/SOURCES/support-consistency-policy-change.patch deleted file mode 100644 index 26861a7..0000000 --- a/SOURCES/support-consistency-policy-change.patch +++ /dev/null @@ -1,339 +0,0 @@ -commit 860f11ed4d6a7bac6f2d698a30a13371c0aa7924 -Author: Artur Paszkiewicz -Date: Wed Mar 29 11:54:20 2017 +0200 - - Grow: support consistency policy change - - Extend the --consistency-policy parameter to work also in Grow mode. - Using it changes the currently active consistency policy in the kernel - driver and updates the metadata to make this change permanent. Currently - this supports only changing between "ppl" and "resync" policies, that is - enabling or disabling PPL at runtime. - - Signed-off-by: Artur Paszkiewicz - Signed-off-by: Jes Sorensen - -diff --git a/Grow.c b/Grow.c -index a849012..b86b53e 100755 ---- a/Grow.c -+++ b/Grow.c -@@ -528,6 +528,178 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) - return 0; - } - -+int Grow_consistency_policy(char *devname, int fd, struct context *c, struct shape *s) -+{ -+ struct supertype *st; -+ struct mdinfo *sra; -+ struct mdinfo *sd; -+ char *subarray = NULL; -+ int ret = 0; -+ char container_dev[PATH_MAX]; -+ -+ 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)); -+ return 1; -+ } -+ -+ st = super_by_fd(fd, &subarray); -+ if (!st) -+ return 1; -+ -+ sra = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY|GET_LEVEL| -+ GET_DEVS|GET_STATE); -+ if (!sra) { -+ ret = 1; -+ goto free_st; -+ } -+ -+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL && -+ !st->ss->write_init_ppl) { -+ pr_err("%s metadata does not support PPL\n", st->ss->name); -+ ret = 1; -+ goto free_info; -+ } -+ -+ if (sra->array.level != 5) { -+ pr_err("Operation not supported for array level %d\n", -+ sra->array.level); -+ ret = 1; -+ goto free_info; -+ } -+ -+ if (sra->consistency_policy == (unsigned)s->consistency_policy) { -+ pr_err("Consistency policy is already %s\n", -+ map_num(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)); -+ ret = 1; -+ goto free_info; -+ } -+ -+ if (subarray) { -+ char *update; -+ -+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) -+ update = "ppl"; -+ else -+ update = "no-ppl"; -+ -+ sprintf(container_dev, "/dev/%s", st->container_devnm); -+ -+ ret = Update_subarray(container_dev, subarray, update, NULL, -+ c->verbose); -+ if (ret) -+ goto free_info; -+ } -+ -+ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) { -+ struct mdinfo info; -+ -+ if (subarray) { -+ struct mdinfo *mdi; -+ int cfd; -+ -+ cfd = open(container_dev, O_RDWR|O_EXCL); -+ if (cfd < 0) { -+ pr_err("Failed to open %s\n", container_dev); -+ ret = 1; -+ goto free_info; -+ } -+ -+ ret = st->ss->load_container(st, cfd, st->container_devnm); -+ close(cfd); -+ -+ if (ret) { -+ pr_err("Cannot read superblock for %s\n", -+ container_dev); -+ goto free_info; -+ } -+ -+ mdi = st->ss->container_content(st, subarray); -+ info = *mdi; -+ free(mdi); -+ } -+ -+ for (sd = sra->devs; sd; sd = sd->next) { -+ int dfd; -+ char *devpath; -+ -+ if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0) -+ continue; -+ -+ devpath = map_dev(sd->disk.major, sd->disk.minor, 0); -+ dfd = dev_open(devpath, O_RDWR); -+ if (dfd < 0) { -+ pr_err("Failed to open %s\n", devpath); -+ ret = 1; -+ goto free_info; -+ } -+ -+ if (!subarray) { -+ ret = st->ss->load_super(st, dfd, NULL); -+ if (ret) { -+ pr_err("Failed to load super-block.\n"); -+ close(dfd); -+ goto free_info; -+ } -+ -+ ret = st->ss->update_super(st, sra, "ppl", devname, -+ c->verbose, 0, NULL); -+ if (ret) { -+ close(dfd); -+ st->ss->free_super(st); -+ goto free_info; -+ } -+ st->ss->getinfo_super(st, &info, NULL); -+ } -+ -+ ret |= sysfs_set_num(sra, sd, "ppl_sector", info.ppl_sector); -+ ret |= sysfs_set_num(sra, sd, "ppl_size", info.ppl_size); -+ -+ if (ret) { -+ pr_err("Failed to set PPL attributes for %s\n", -+ sd->sys_name); -+ close(dfd); -+ st->ss->free_super(st); -+ goto free_info; -+ } -+ -+ ret = st->ss->write_init_ppl(st, &info, dfd); -+ if (ret) -+ pr_err("Failed to write PPL\n"); -+ -+ close(dfd); -+ -+ if (!subarray) -+ st->ss->free_super(st); -+ -+ if (ret) -+ goto free_info; -+ } -+ } -+ -+ ret = sysfs_set_str(sra, NULL, "consistency_policy", -+ map_num(consistency_policies, -+ s->consistency_policy)); -+ if (ret) -+ pr_err("Failed to change array consistency policy\n"); -+ -+free_info: -+ sysfs_free(sra); -+free_st: -+ free(st); -+ free(subarray); -+ -+ return ret; -+} -+ - /* - * When reshaping an array we might need to backup some data. - * This is written to all spares with a 'super_block' describing it. -diff --git a/ReadMe.c b/ReadMe.c -index fc04c2c..eb8fb4b 100644 ---- a/ReadMe.c -+++ b/ReadMe.c -@@ -559,28 +559,30 @@ char Help_grow[] = - "reconfiguration.\n" - "\n" - "Options that are valid with the grow (-G --grow) mode are:\n" --" --level= -l : Tell mdadm what level to convert the array to.\n" --" --layout= -p : For a FAULTY array, set/change the error mode.\n" --" : for other arrays, update the layout\n" --" --size= -z : Change the active size of devices in an array.\n" --" : This is useful if all devices have been replaced\n" --" : with larger devices. Value is in Kilobytes, or\n" --" : the special word 'max' meaning 'as large as possible'.\n" --" --assume-clean : When increasing the --size, this flag will avoid\n" --" : a resync of the new space\n" --" --chunk= -c : Change the chunksize of the array\n" --" --raid-devices= -n : Change the number of active devices in an array.\n" --" --add= -a : Add listed devices as part of reshape. This is\n" --" : needed for resizing a RAID0 which cannot have\n" --" : spares already present.\n" --" --bitmap= -b : Add or remove a write-intent bitmap.\n" --" --backup-file= file : A file on a different device to store data for a\n" --" : short time while increasing raid-devices on a\n" --" : RAID4/5/6 array. Also needed throughout a reshape\n" --" : when changing parameters other than raid-devices\n" --" --array-size= -Z : Change visible size of array. This does not change\n" --" : any data on the device, and is not stable across restarts.\n" --" --data-offset= : Location on device to move start of data to.\n" -+" --level= -l : Tell mdadm what level to convert the array to.\n" -+" --layout= -p : For a FAULTY array, set/change the error mode.\n" -+" : for other arrays, update the layout\n" -+" --size= -z : Change the active size of devices in an array.\n" -+" : This is useful if all devices have been replaced\n" -+" : with larger devices. Value is in Kilobytes, or\n" -+" : the special word 'max' meaning 'as large as possible'.\n" -+" --assume-clean : When increasing the --size, this flag will avoid\n" -+" : a resync of the new space\n" -+" --chunk= -c : Change the chunksize of the array\n" -+" --raid-devices= -n : Change the number of active devices in an array.\n" -+" --add= -a : Add listed devices as part of reshape. This is\n" -+" : needed for resizing a RAID0 which cannot have\n" -+" : spares already present.\n" -+" --bitmap= -b : Add or remove a write-intent bitmap.\n" -+" --backup-file= file : A file on a different device to store data for a\n" -+" : short time while increasing raid-devices on a\n" -+" : RAID4/5/6 array. Also needed throughout a reshape\n" -+" : when changing parameters other than raid-devices\n" -+" --array-size= -Z : Change visible size of array. This does not change any\n" -+" : data on the device, and is not stable across restarts.\n" -+" --data-offset= : Location on device to move start of data to.\n" -+" --consistency-policy= : Change the consistency policy of an active array.\n" -+" -k : Currently works only for PPL with RAID5.\n" - ; - - char Help_incr[] = -diff --git a/mdadm.8.in b/mdadm.8.in -index 1178ed9..744c12b 100644 ---- a/mdadm.8.in -+++ b/mdadm.8.in -@@ -126,7 +126,7 @@ of component devices and changing the number of active devices in - Linear and RAID levels 0/1/4/5/6, - changing the RAID level between 0, 1, 5, and 6, and between 0 and 10, - changing the chunk size and layout for RAID 0,4,5,6,10 as well as adding or --removing a write-intent bitmap. -+removing a write-intent bitmap and changing the array's consistency policy. - - .TP - .B "Incremental Assembly" -@@ -1050,6 +1050,10 @@ after unclean shutdown. Implicitly selected when using - For RAID5 only, Partial Parity Log is used to close the write hole and - eliminate resync. PPL is stored in the metadata region of RAID member drives, - no additional journal drive is needed. -+ -+.PP -+Can be used with \-\-grow to change the consistency policy of an active array -+in some cases. See CONSISTENCY POLICY CHANGES below. - .RE - - -@@ -2694,6 +2698,8 @@ RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode). - .IP \(bu 4 - add a write-intent bitmap to any array which supports these bitmaps, or - remove a write-intent bitmap from such an array. -+.IP \(bu 4 -+change the array's consistency policy. - .PP - - Using GROW on containers is currently supported only for Intel's IMSM -@@ -2850,6 +2856,16 @@ 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. - -+.SS CONSISTENCY POLICY CHANGES -+ -+The consistency policy of an active array can be changed by using the -+.B \-\-consistency\-policy -+option in Grow mode. Currently this works only for the -+.B ppl -+and -+.B resync -+policies and allows to enable or disable the RAID5 Partial Parity Log (PPL). -+ - .SH INCREMENTAL MODE - - .HP 12 -diff --git a/mdadm.c b/mdadm.c -index 6edf3ab..5ebf117 100644 ---- a/mdadm.c -+++ b/mdadm.c -@@ -1221,6 +1221,7 @@ int main(int argc, char *argv[]) - s.journaldisks = 1; - continue; - case O(CREATE, 'k'): -+ case O(GROW, 'k'): - s.consistency_policy = map_name(consistency_policies, - optarg); - if (s.consistency_policy == UnSet || -@@ -1679,6 +1680,8 @@ int main(int argc, char *argv[]) - rv = Grow_reshape(devlist->devname, mdfd, - devlist->next, - data_offset, &c, &s); -+ } else if (s.consistency_policy != UnSet) { -+ rv = Grow_consistency_policy(devlist->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 2c7066d..4891acf 100644 ---- a/mdadm.h -+++ b/mdadm.h -@@ -1331,6 +1331,8 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info, - extern int Grow_continue(int mdfd, struct supertype *st, - struct mdinfo *info, char *backup_file, - int forked, int freeze_reshape); -+extern int Grow_consistency_policy(char *devname, int fd, -+ struct context *c, struct shape *s); - - extern int restore_backup(struct supertype *st, - struct mdinfo *content, diff --git a/SOURCES/support-consistency-policy1-change.patch b/SOURCES/support-consistency-policy1-change.patch new file mode 100644 index 0000000..26861a7 --- /dev/null +++ b/SOURCES/support-consistency-policy1-change.patch @@ -0,0 +1,339 @@ +commit 860f11ed4d6a7bac6f2d698a30a13371c0aa7924 +Author: Artur Paszkiewicz +Date: Wed Mar 29 11:54:20 2017 +0200 + + Grow: support consistency policy change + + Extend the --consistency-policy parameter to work also in Grow mode. + Using it changes the currently active consistency policy in the kernel + driver and updates the metadata to make this change permanent. Currently + this supports only changing between "ppl" and "resync" policies, that is + enabling or disabling PPL at runtime. + + Signed-off-by: Artur Paszkiewicz + Signed-off-by: Jes Sorensen + +diff --git a/Grow.c b/Grow.c +index a849012..b86b53e 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -528,6 +528,178 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + return 0; + } + ++int Grow_consistency_policy(char *devname, int fd, struct context *c, struct shape *s) ++{ ++ struct supertype *st; ++ struct mdinfo *sra; ++ struct mdinfo *sd; ++ char *subarray = NULL; ++ int ret = 0; ++ char container_dev[PATH_MAX]; ++ ++ 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)); ++ return 1; ++ } ++ ++ st = super_by_fd(fd, &subarray); ++ if (!st) ++ return 1; ++ ++ sra = sysfs_read(fd, NULL, GET_CONSISTENCY_POLICY|GET_LEVEL| ++ GET_DEVS|GET_STATE); ++ if (!sra) { ++ ret = 1; ++ goto free_st; ++ } ++ ++ if (s->consistency_policy == CONSISTENCY_POLICY_PPL && ++ !st->ss->write_init_ppl) { ++ pr_err("%s metadata does not support PPL\n", st->ss->name); ++ ret = 1; ++ goto free_info; ++ } ++ ++ if (sra->array.level != 5) { ++ pr_err("Operation not supported for array level %d\n", ++ sra->array.level); ++ ret = 1; ++ goto free_info; ++ } ++ ++ if (sra->consistency_policy == (unsigned)s->consistency_policy) { ++ pr_err("Consistency policy is already %s\n", ++ map_num(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)); ++ ret = 1; ++ goto free_info; ++ } ++ ++ if (subarray) { ++ char *update; ++ ++ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) ++ update = "ppl"; ++ else ++ update = "no-ppl"; ++ ++ sprintf(container_dev, "/dev/%s", st->container_devnm); ++ ++ ret = Update_subarray(container_dev, subarray, update, NULL, ++ c->verbose); ++ if (ret) ++ goto free_info; ++ } ++ ++ if (s->consistency_policy == CONSISTENCY_POLICY_PPL) { ++ struct mdinfo info; ++ ++ if (subarray) { ++ struct mdinfo *mdi; ++ int cfd; ++ ++ cfd = open(container_dev, O_RDWR|O_EXCL); ++ if (cfd < 0) { ++ pr_err("Failed to open %s\n", container_dev); ++ ret = 1; ++ goto free_info; ++ } ++ ++ ret = st->ss->load_container(st, cfd, st->container_devnm); ++ close(cfd); ++ ++ if (ret) { ++ pr_err("Cannot read superblock for %s\n", ++ container_dev); ++ goto free_info; ++ } ++ ++ mdi = st->ss->container_content(st, subarray); ++ info = *mdi; ++ free(mdi); ++ } ++ ++ for (sd = sra->devs; sd; sd = sd->next) { ++ int dfd; ++ char *devpath; ++ ++ if ((sd->disk.state & (1 << MD_DISK_SYNC)) == 0) ++ continue; ++ ++ devpath = map_dev(sd->disk.major, sd->disk.minor, 0); ++ dfd = dev_open(devpath, O_RDWR); ++ if (dfd < 0) { ++ pr_err("Failed to open %s\n", devpath); ++ ret = 1; ++ goto free_info; ++ } ++ ++ if (!subarray) { ++ ret = st->ss->load_super(st, dfd, NULL); ++ if (ret) { ++ pr_err("Failed to load super-block.\n"); ++ close(dfd); ++ goto free_info; ++ } ++ ++ ret = st->ss->update_super(st, sra, "ppl", devname, ++ c->verbose, 0, NULL); ++ if (ret) { ++ close(dfd); ++ st->ss->free_super(st); ++ goto free_info; ++ } ++ st->ss->getinfo_super(st, &info, NULL); ++ } ++ ++ ret |= sysfs_set_num(sra, sd, "ppl_sector", info.ppl_sector); ++ ret |= sysfs_set_num(sra, sd, "ppl_size", info.ppl_size); ++ ++ if (ret) { ++ pr_err("Failed to set PPL attributes for %s\n", ++ sd->sys_name); ++ close(dfd); ++ st->ss->free_super(st); ++ goto free_info; ++ } ++ ++ ret = st->ss->write_init_ppl(st, &info, dfd); ++ if (ret) ++ pr_err("Failed to write PPL\n"); ++ ++ close(dfd); ++ ++ if (!subarray) ++ st->ss->free_super(st); ++ ++ if (ret) ++ goto free_info; ++ } ++ } ++ ++ ret = sysfs_set_str(sra, NULL, "consistency_policy", ++ map_num(consistency_policies, ++ s->consistency_policy)); ++ if (ret) ++ pr_err("Failed to change array consistency policy\n"); ++ ++free_info: ++ sysfs_free(sra); ++free_st: ++ free(st); ++ free(subarray); ++ ++ return ret; ++} ++ + /* + * When reshaping an array we might need to backup some data. + * This is written to all spares with a 'super_block' describing it. +diff --git a/ReadMe.c b/ReadMe.c +index fc04c2c..eb8fb4b 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -559,28 +559,30 @@ char Help_grow[] = + "reconfiguration.\n" + "\n" + "Options that are valid with the grow (-G --grow) mode are:\n" +-" --level= -l : Tell mdadm what level to convert the array to.\n" +-" --layout= -p : For a FAULTY array, set/change the error mode.\n" +-" : for other arrays, update the layout\n" +-" --size= -z : Change the active size of devices in an array.\n" +-" : This is useful if all devices have been replaced\n" +-" : with larger devices. Value is in Kilobytes, or\n" +-" : the special word 'max' meaning 'as large as possible'.\n" +-" --assume-clean : When increasing the --size, this flag will avoid\n" +-" : a resync of the new space\n" +-" --chunk= -c : Change the chunksize of the array\n" +-" --raid-devices= -n : Change the number of active devices in an array.\n" +-" --add= -a : Add listed devices as part of reshape. This is\n" +-" : needed for resizing a RAID0 which cannot have\n" +-" : spares already present.\n" +-" --bitmap= -b : Add or remove a write-intent bitmap.\n" +-" --backup-file= file : A file on a different device to store data for a\n" +-" : short time while increasing raid-devices on a\n" +-" : RAID4/5/6 array. Also needed throughout a reshape\n" +-" : when changing parameters other than raid-devices\n" +-" --array-size= -Z : Change visible size of array. This does not change\n" +-" : any data on the device, and is not stable across restarts.\n" +-" --data-offset= : Location on device to move start of data to.\n" ++" --level= -l : Tell mdadm what level to convert the array to.\n" ++" --layout= -p : For a FAULTY array, set/change the error mode.\n" ++" : for other arrays, update the layout\n" ++" --size= -z : Change the active size of devices in an array.\n" ++" : This is useful if all devices have been replaced\n" ++" : with larger devices. Value is in Kilobytes, or\n" ++" : the special word 'max' meaning 'as large as possible'.\n" ++" --assume-clean : When increasing the --size, this flag will avoid\n" ++" : a resync of the new space\n" ++" --chunk= -c : Change the chunksize of the array\n" ++" --raid-devices= -n : Change the number of active devices in an array.\n" ++" --add= -a : Add listed devices as part of reshape. This is\n" ++" : needed for resizing a RAID0 which cannot have\n" ++" : spares already present.\n" ++" --bitmap= -b : Add or remove a write-intent bitmap.\n" ++" --backup-file= file : A file on a different device to store data for a\n" ++" : short time while increasing raid-devices on a\n" ++" : RAID4/5/6 array. Also needed throughout a reshape\n" ++" : when changing parameters other than raid-devices\n" ++" --array-size= -Z : Change visible size of array. This does not change any\n" ++" : data on the device, and is not stable across restarts.\n" ++" --data-offset= : Location on device to move start of data to.\n" ++" --consistency-policy= : Change the consistency policy of an active array.\n" ++" -k : Currently works only for PPL with RAID5.\n" + ; + + char Help_incr[] = +diff --git a/mdadm.8.in b/mdadm.8.in +index 1178ed9..744c12b 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -126,7 +126,7 @@ of component devices and changing the number of active devices in + Linear and RAID levels 0/1/4/5/6, + changing the RAID level between 0, 1, 5, and 6, and between 0 and 10, + changing the chunk size and layout for RAID 0,4,5,6,10 as well as adding or +-removing a write-intent bitmap. ++removing a write-intent bitmap and changing the array's consistency policy. + + .TP + .B "Incremental Assembly" +@@ -1050,6 +1050,10 @@ after unclean shutdown. Implicitly selected when using + For RAID5 only, Partial Parity Log is used to close the write hole and + eliminate resync. PPL is stored in the metadata region of RAID member drives, + no additional journal drive is needed. ++ ++.PP ++Can be used with \-\-grow to change the consistency policy of an active array ++in some cases. See CONSISTENCY POLICY CHANGES below. + .RE + + +@@ -2694,6 +2698,8 @@ RAID0, RAID4, and RAID5, and between RAID0 and RAID10 (in the near-2 mode). + .IP \(bu 4 + add a write-intent bitmap to any array which supports these bitmaps, or + remove a write-intent bitmap from such an array. ++.IP \(bu 4 ++change the array's consistency policy. + .PP + + Using GROW on containers is currently supported only for Intel's IMSM +@@ -2850,6 +2856,16 @@ 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. + ++.SS CONSISTENCY POLICY CHANGES ++ ++The consistency policy of an active array can be changed by using the ++.B \-\-consistency\-policy ++option in Grow mode. Currently this works only for the ++.B ppl ++and ++.B resync ++policies and allows to enable or disable the RAID5 Partial Parity Log (PPL). ++ + .SH INCREMENTAL MODE + + .HP 12 +diff --git a/mdadm.c b/mdadm.c +index 6edf3ab..5ebf117 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1221,6 +1221,7 @@ int main(int argc, char *argv[]) + s.journaldisks = 1; + continue; + case O(CREATE, 'k'): ++ case O(GROW, 'k'): + s.consistency_policy = map_name(consistency_policies, + optarg); + if (s.consistency_policy == UnSet || +@@ -1679,6 +1680,8 @@ int main(int argc, char *argv[]) + rv = Grow_reshape(devlist->devname, mdfd, + devlist->next, + data_offset, &c, &s); ++ } else if (s.consistency_policy != UnSet) { ++ rv = Grow_consistency_policy(devlist->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 2c7066d..4891acf 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1331,6 +1331,8 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info, + extern int Grow_continue(int mdfd, struct supertype *st, + struct mdinfo *info, char *backup_file, + int forked, int freeze_reshape); ++extern int Grow_consistency_policy(char *devname, int fd, ++ struct context *c, struct shape *s); + + extern int restore_backup(struct supertype *st, + struct mdinfo *content, diff --git a/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch b/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch new file mode 100644 index 0000000..f9c94fd --- /dev/null +++ b/SOURCES/sysfs-Make-sysfs_init-return-an-error-code.patch @@ -0,0 +1,332 @@ +From dae131379f9fd82e2867aed25a3ff719f957e9a3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 30 Mar 2017 16:52:37 -0400 +Subject: [RHEL7.5 PATCH 048/169] sysfs: Make sysfs_init() return an error + code + +Rather than have the caller inspect the returned content, return an +error code from sysfs_init(). In addition make all callers actually +check it. + +Signed-off-by: Jes Sorensen +--- + Assemble.c | 12 ++++++++++-- + Create.c | 10 ++++++++-- + Grow.c | 39 +++++++++++++++++++++++++++++++++------ + Incremental.c | 12 ++++++++++-- + Manage.c | 7 +++++-- + Monitor.c | 4 +++- + mdadm.c | 11 ++++++++--- + mdadm.h | 2 +- + sysfs.c | 16 ++++++++++------ + 9 files changed, 88 insertions(+), 25 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 6a6a56b..672cd12 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1670,7 +1670,12 @@ try_again: + } + st->ss->getinfo_super(st, content, NULL); + #ifndef MDASSEMBLE +- sysfs_init(content, mdfd, NULL); ++ if (sysfs_init(content, mdfd, NULL)) { ++ pr_err("Unable to initialize sysfs\n"); ++ close(mdfd); ++ free(devices); ++ return 1; ++ } + #endif + /* after reload context, store journal_clean in context */ + content->journal_clean = journal_clean; +@@ -1885,7 +1890,10 @@ int assemble_container_content(struct supertype *st, int mdfd, + char *avail; + int err; + +- sysfs_init(content, mdfd, NULL); ++ if (sysfs_init(content, mdfd, NULL)) { ++ pr_err("Unable to initialize sysfs\n"); ++ return 1; ++ } + + sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS); + if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) { +diff --git a/Create.c b/Create.c +index 0e0778f..32987af 100644 +--- a/Create.c ++++ b/Create.c +@@ -737,7 +737,10 @@ int Create(struct supertype *st, char *mddev, + + total_slots = info.array.nr_disks; + st->ss->getinfo_super(st, &info, NULL); +- sysfs_init(&info, mdfd, NULL); ++ if (sysfs_init(&info, mdfd, NULL)) { ++ pr_err("unable to initialize sysfs\n"); ++ goto abort_locked; ++ } + + if (did_default && c->verbose >= 0) { + if (is_subarray(info.text_version)) { +@@ -794,7 +797,10 @@ int Create(struct supertype *st, char *mddev, + s->bitmap_file = NULL; + } + +- sysfs_init(&info, mdfd, NULL); ++ if (sysfs_init(&info, mdfd, NULL)) { ++ pr_err("unable to initialize sysfs\n"); ++ goto abort_locked; ++ } + + if (st->ss->external && st->container_devnm[0]) { + /* member */ +diff --git a/Grow.c b/Grow.c +index 0c16d5b..78a3474 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -455,7 +455,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + } + if (offset_setable) { + st->ss->getinfo_super(st, mdi, NULL); +- sysfs_init(mdi, fd, NULL); ++ if (sysfs_init(mdi, fd, NULL)) { ++ pr_err("failed to intialize sysfs.\n"); ++ free(mdi); ++ } + rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", + mdi->bitmap_offset); + free(mdi); +@@ -2149,7 +2152,11 @@ size_change_error: + + memset(&info, 0, sizeof(info)); + info.array = array; +- sysfs_init(&info, fd, NULL); ++ if (sysfs_init(&info, fd, NULL)) { ++ pr_err("failed to intialize sysfs.\n"); ++ rv = 1; ++ goto release; ++ } + strcpy(info.text_version, sra->text_version); + info.component_size = s->size*2; + info.new_level = s->level; +@@ -2870,7 +2877,11 @@ static int impose_level(int fd, int level, char *devname, int verbose) + char *c; + struct mdu_array_info_s array; + struct mdinfo info; +- sysfs_init(&info, fd, NULL); ++ ++ if (sysfs_init(&info, fd, NULL)) { ++ pr_err("failed to intialize sysfs.\n"); ++ return 1; ++ } + + md_get_array_info(fd, &array); + if (level == 0 && +@@ -3178,7 +3189,12 @@ static int reshape_array(char *container, int fd, char *devname, + struct mdinfo *d; + + if (info2) { +- sysfs_init(info2, fd, st->devnm); ++ if (sysfs_init(info2, fd, st->devnm)) { ++ pr_err("unable to initialize sysfs for %s", ++ st->devnm); ++ free(info2); ++ goto release; ++ } + /* When increasing number of devices, we need to set + * new raid_disks before adding these, or they might + * be rejected. +@@ -3777,7 +3793,12 @@ int reshape_container(char *container, char *devname, + } + strcpy(last_devnm, mdstat->devnm); + +- sysfs_init(content, fd, mdstat->devnm); ++ if (sysfs_init(content, fd, mdstat->devnm)) { ++ pr_err("Unable to initialize sysfs for %s\n", ++ mdstat->devnm); ++ rv = 1; ++ break; ++ } + + if (mdmon_running(container)) + flush_mdmon(container); +@@ -5110,7 +5131,13 @@ int Grow_continue_command(char *devname, int fd, + goto Grow_continue_command_exit; + } + +- sysfs_init(content, fd2, mdstat->devnm); ++ if (sysfs_init(content, fd2, mdstat->devnm)) { ++ pr_err("Unable to initialize sysfs for %s, Grow cannot continue", ++ mdstat->devnm); ++ ret_val = 1; ++ close(fd2); ++ goto Grow_continue_command_exit; ++ } + + close(fd2); + +diff --git a/Incremental.c b/Incremental.c +index 802e525..28f1f77 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -326,7 +326,12 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + if (mdfd < 0) + goto out_unlock; + +- sysfs_init(&info, mdfd, NULL); ++ if (sysfs_init(&info, mdfd, NULL)) { ++ pr_err("unable to initialize sysfs for %s\n", ++ chosen_name); ++ rv = 2; ++ goto out_unlock; ++ } + + if (set_array_info(mdfd, st, &info) != 0) { + pr_err("failed to set array info for %s: %s\n", +@@ -1734,7 +1739,10 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) + pr_err("%s does not appear to be a component of any array\n", devname); + return 1; + } +- sysfs_init(&mdi, -1, ent->devnm); ++ if (sysfs_init(&mdi, -1, ent->devnm)) { ++ pr_err("unable to initialize sysfs for: %s\n", devname); ++ return 1; ++ } + mdfd = open_dev_excl(ent->devnm); + if (mdfd > 0) { + close(mdfd); +diff --git a/Manage.c b/Manage.c +index 0ffb6c6..618c98b 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1382,12 +1382,15 @@ int Manage_subdevs(char *devname, int fd, + int busy = 0; + int raid_slot = -1; + ++ if (sysfs_init(&info, fd, NULL)) { ++ pr_err("sysfs not availabile for %s\n", devname); ++ goto abort; ++ } ++ + if (md_get_array_info(fd, &array)) { + pr_err("Cannot get array info for %s\n", devname); + goto abort; + } +- sysfs_init(&info, fd, NULL); +- + /* array.size is only 32 bits and may be truncated. + * So read from sysfs if possible, and record number of sectors + */ +diff --git a/Monitor.c b/Monitor.c +index 2c0f717..036a561 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1026,7 +1026,9 @@ int Wait(char *dev) + */ + struct mdinfo mdi; + char buf[21]; +- sysfs_init(&mdi, -1, devnm); ++ ++ if (sysfs_init(&mdi, -1, devnm)) ++ return 2; + if (sysfs_get_str(&mdi, NULL, "sync_action", + buf, 20) > 0 && + strcmp(buf,"idle\n") != 0) { +diff --git a/mdadm.c b/mdadm.c +index d6b5437..3fe17fc 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1631,7 +1631,10 @@ int main(int argc, char *argv[]) + rv = 1; + break; + } +- sysfs_init(&sra, mdfd, NULL); ++ if (sysfs_init(&sra, mdfd, NULL)) { ++ rv = 1; ++ break; ++ } + if (array_size == MAX_SIZE) + err = sysfs_set_str(&sra, NULL, "array_size", "default"); + else +@@ -1998,13 +2001,15 @@ int SetAction(char *dev, char *action) + { + int fd = open(dev, O_RDONLY); + struct mdinfo mdi; ++ int retval; ++ + if (fd < 0) { + pr_err("Couldn't open %s: %s\n", dev, strerror(errno)); + return 1; + } +- sysfs_init(&mdi, fd, NULL); ++ retval = sysfs_init(&mdi, fd, NULL); + close(fd); +- if (!mdi.sys_name[0]) { ++ if (retval) { + pr_err("%s is no an md array\n", dev); + return 1; + } +diff --git a/mdadm.h b/mdadm.h +index 084bc97..612bd86 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -639,7 +639,7 @@ enum sysfs_read_flags { + * else use devnm. + */ + extern int sysfs_open(char *devnm, char *devname, char *attr); +-extern void sysfs_init(struct mdinfo *mdi, int fd, char *devnm); ++extern int sysfs_init(struct mdinfo *mdi, int fd, char *devnm); + extern void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid); + extern void sysfs_free(struct mdinfo *sra); + extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options); +diff --git a/sysfs.c b/sysfs.c +index 93ec3de..51deb23 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -84,25 +84,30 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) + sizeof(mdi->sys_name), "dev-%s", devid2kname(devid)); + } + +-void sysfs_init(struct mdinfo *mdi, int fd, char *devnm) ++int sysfs_init(struct mdinfo *mdi, int fd, char *devnm) + { + struct stat stb; + char fname[MAX_SYSFS_PATH_LEN]; ++ int retval = -ENODEV; + + mdi->sys_name[0] = 0; + if (fd >= 0) + devnm = fd2devnm(fd); + + if (devnm == NULL) +- return; ++ goto out; + + snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm); + + if (stat(fname, &stb)) +- return; ++ goto out; + if (!S_ISDIR(stb.st_mode)) +- return; ++ goto out; + strcpy(mdi->sys_name, devnm); ++ ++ retval = 0; ++out: ++ return retval; + } + + struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) +@@ -117,8 +122,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + struct dirent *de; + + sra = xcalloc(1, sizeof(*sra)); +- sysfs_init(sra, fd, devnm); +- if (sra->sys_name[0] == 0) { ++ if (sysfs_init(sra, fd, devnm)) { + free(sra); + return NULL; + } +-- +2.7.4 + diff --git a/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch b/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch new file mode 100644 index 0000000..212b6d1 --- /dev/null +++ b/SOURCES/sysfs-Parse-array_state-in-sysfs_read.patch @@ -0,0 +1,116 @@ +From 5e4ca8bb82e98400c9258cb3d7e4d030576f21df Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 19 Apr 2017 23:27:58 -0400 +Subject: [RHEL7.5 PATCH 081/169] sysfs: Parse array_state in sysfs_read() + +Rather than copying in the array_state string, parse it and use an +enum to indicate the state. + +Signed-off-by: Jes Sorensen +--- + Manage.c | 2 +- + maps.c | 17 +++++++++++++++++ + mdadm.h | 17 ++++++++++++++--- + sysfs.c | 9 +++++---- + 4 files changed, 37 insertions(+), 8 deletions(-) + +diff --git a/Manage.c b/Manage.c +index bb84d28..8966e33 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -929,7 +929,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + return -1; + } + +- if (strncmp(mdp->sysfs_array_state, "readonly", 8) != 0) { ++ if (mdp->array_state != ARRAY_READONLY) { + sysfs_free(mdp); + pr_err("%s is not readonly, cannot add journal.\n", devname); + return -1; +diff --git a/maps.c b/maps.c +index d9ee7de..a8a4639 100644 +--- a/maps.c ++++ b/maps.c +@@ -139,6 +139,23 @@ mapping_t consistency_policies[] = { + { NULL, 0} + }; + ++mapping_t sysfs_array_states[] = { ++ /* ++ * Beware map_name() uses strcmp() so active-idle must come before ++ * active, to be detected correctly. ++ */ ++ { "active-idle", ARRAY_ACTIVE_IDLE }, ++ { "active", ARRAY_ACTIVE }, ++ { "clear", ARRAY_CLEAR }, ++ { "inactive", ARRAY_INACTIVE }, ++ { "suspended", ARRAY_SUSPENDED }, ++ { "readonly", ARRAY_READONLY }, ++ { "read-auto", ARRAY_READ_AUTO }, ++ { "clean", ARRAY_CLEAN }, ++ { "write-pending", ARRAY_WRITE_PENDING }, ++ { NULL, 0 } ++}; ++ + char *map_num(mapping_t *map, int num) + { + while (map->name) { +diff --git a/mdadm.h b/mdadm.h +index f1f643c..a379973 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -335,8 +335,18 @@ struct mdinfo { + int prev_state, curr_state, next_state; + + /* info read from sysfs */ +- char sysfs_array_state[20]; +- ++ enum { ++ ARRAY_CLEAR, ++ ARRAY_INACTIVE, ++ ARRAY_SUSPENDED, ++ ARRAY_READONLY, ++ ARRAY_READ_AUTO, ++ ARRAY_CLEAN, ++ ARRAY_ACTIVE, ++ ARRAY_WRITE_PENDING, ++ ARRAY_ACTIVE_IDLE, ++ ARRAY_UNKNOWN_STATE, ++ } array_state; + struct md_bb bb; + }; + +@@ -716,7 +726,8 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, + + extern char *map_num(mapping_t *map, int num); + extern int map_name(mapping_t *map, char *name); +-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[], consistency_policies[]; ++extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[]; ++extern mapping_t consistency_policies[], sysfs_array_states[]; + + extern char *map_dev_preferred(int major, int minor, int create, + char *prefer); +diff --git a/sysfs.c b/sysfs.c +index 51deb23..c6df9b0 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -247,11 +247,12 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + + if (options & GET_ARRAY_STATE) { + strcpy(base, "array_state"); +- if (load_sys(fname, sra->sysfs_array_state, +- sizeof(sra->sysfs_array_state))) ++ if (load_sys(fname, buf, sizeof(buf))) + goto abort; +- } else +- sra->sysfs_array_state[0] = 0; ++ sra->array_state = map_name(sysfs_array_states, buf); ++ if (sra->array_state == UnSet) ++ sra->array_state = ARRAY_UNKNOWN_STATE; ++ } + + if (options & GET_CONSISTENCY_POLICY) { + strcpy(base, "consistency_policy"); +-- +2.7.4 + diff --git a/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch b/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch new file mode 100644 index 0000000..a8c172b --- /dev/null +++ b/SOURCES/sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch @@ -0,0 +1,51 @@ +From 67a02d520085b01a1b9e6ea59fb30e79c5649c9c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 30 Mar 2017 16:02:36 -0400 +Subject: [RHEL7.5 PATCH 047/169] sysfs: Use the presence of + /sys/block//md as indicator of valid device + +Rather than calling ioctl(RAID_VERSION), use the presence of +/sys/block//md as indicator of the device being valid and sysfs +being active for it. The ioctl could return valid data, but sysfs +not mounted, which renders sysfs_init() useless anyway. + +Signed-off-by: Jes Sorensen +--- + sysfs.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/sysfs.c b/sysfs.c +index 2a91ba0..93ec3de 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -86,15 +86,22 @@ void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) + + void sysfs_init(struct mdinfo *mdi, int fd, char *devnm) + { ++ struct stat stb; ++ char fname[MAX_SYSFS_PATH_LEN]; ++ + mdi->sys_name[0] = 0; +- if (fd >= 0) { +- mdu_version_t vers; +- if (ioctl(fd, RAID_VERSION, &vers) != 0) +- return; ++ if (fd >= 0) + devnm = fd2devnm(fd); +- } ++ + if (devnm == NULL) + return; ++ ++ snprintf(fname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md", devnm); ++ ++ if (stat(fname, &stb)) ++ return; ++ if (!S_ISDIR(stb.st_mode)) ++ return; + strcpy(mdi->sys_name, devnm); + } + +-- +2.7.4 + diff --git a/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch b/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch new file mode 100644 index 0000000..acc5a0a --- /dev/null +++ b/SOURCES/sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch @@ -0,0 +1,47 @@ +From 64ec81da7a70adcdc0dbccaacc69aaf90edb4011 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 5 May 2017 11:51:43 -0400 +Subject: [RHEL7.5 PATCH 113/169] sysfs/sysfs_read: Count active_disks and + failed_disks + +Cound active_disks as drives mark 'in_sync' and failed_disks as +disks marked 'faulty', in the same way ioctl(GET_ARRAY_INFO) does. + +Signed-off-by: Jes Sorensen +--- + sysfs.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/sysfs.c b/sysfs.c +index aa30de5..f7967e8 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -270,6 +270,8 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + if (!dir) + goto abort; + sra->array.spare_disks = 0; ++ sra->array.active_disks = 0; ++ sra->array.failed_disks = 0; + + devp = &sra->devs; + sra->devs = NULL; +@@ -356,10 +358,14 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + strcpy(dbase, "state"); + if (load_sys(fname, buf, sizeof(buf))) + goto abort; +- if (strstr(buf, "in_sync")) ++ if (strstr(buf, "in_sync")) { + dev->disk.state |= (1<array.active_disks++; ++ } ++ if (strstr(buf, "faulty")) { + dev->disk.state |= (1<array.failed_disks++; ++ } + if (dev->disk.state == 0) + sra->array.spare_disks++; + } +-- +2.7.4 + diff --git a/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch b/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch new file mode 100644 index 0000000..2c75429 --- /dev/null +++ b/SOURCES/sysfs-sysfs_read-Count-workingdisks.patch @@ -0,0 +1,53 @@ +From 8b0ebd645202b627982eb3ed9fc72583c4f245d3 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 May 2017 17:09:40 -0400 +Subject: [RHEL7.5 PATCH 133/169] sysfs/sysfs_read: Count working_disks + +This counts working_disks the same way as get_array_info counts it in +the kernel. + +Signed-off-by: Jes Sorensen +--- + sysfs.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/sysfs.c b/sysfs.c +index f7967e8..e47f5e4 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -272,6 +272,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + sra->array.spare_disks = 0; + sra->array.active_disks = 0; + sra->array.failed_disks = 0; ++ sra->array.working_disks = 0; + + devp = &sra->devs; + sra->devs = NULL; +@@ -358,16 +359,18 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + strcpy(dbase, "state"); + if (load_sys(fname, buf, sizeof(buf))) + goto abort; +- if (strstr(buf, "in_sync")) { +- dev->disk.state |= (1<array.active_disks++; +- } + if (strstr(buf, "faulty")) { + dev->disk.state |= (1<array.failed_disks++; ++ } else { ++ sra->array.working_disks++; ++ if (strstr(buf, "in_sync")) { ++ dev->disk.state |= (1<array.active_disks++; ++ } ++ if (dev->disk.state == 0) ++ sra->array.spare_disks++; + } +- if (dev->disk.state == 0) +- sra->array.spare_disks++; + } + if (options & GET_ERROR) { + strcpy(buf, "errors"); +-- +2.7.4 + diff --git a/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch b/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch new file mode 100644 index 0000000..bd0db97 --- /dev/null +++ b/SOURCES/sysfs_init_dev-takea-dev_t-argument.patch @@ -0,0 +1,42 @@ +From a37563c91386a0c53d2d46aad00fe89ee28bd0da Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 29 Sep 2017 18:04:06 -0400 +Subject: [RHEL7.5 PATCH 11/13] sysfs_init_dev - take a dev_t argument + +Be consistent and use the correct type. + +Signed-off-by: Jes Sorensen +--- + mdadm.h | 2 +- + sysfs.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index db08188..3fc8a4f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -654,7 +654,7 @@ enum sysfs_read_flags { + */ + extern int sysfs_open(char *devnm, char *devname, char *attr); + extern int sysfs_init(struct mdinfo *mdi, int fd, char *devnm); +-extern void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid); ++extern void sysfs_init_dev(struct mdinfo *mdi, dev_t devid); + extern void sysfs_free(struct mdinfo *sra); + extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options); + extern int sysfs_attr_match(const char *attr, const char *str); +diff --git a/sysfs.c b/sysfs.c +index 78d2b52..68ddd5f 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -78,7 +78,7 @@ int sysfs_open(char *devnm, char *devname, char *attr) + return fd; + } + +-void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid) ++void sysfs_init_dev(struct mdinfo *mdi, dev_t devid) + { + snprintf(mdi->sys_name, + sizeof(mdi->sys_name), "dev-%s", devid2kname(devid)); +-- +2.7.4 + diff --git a/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch b/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch new file mode 100644 index 0000000..a61aea0 --- /dev/null +++ b/SOURCES/systemd-mdadm-last-resort-use-ConditionPathExists-in.patch @@ -0,0 +1,49 @@ +From 5c4b3b9aa9f576305b36d5ccbd4b929b51307ce9 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 20 Apr 2017 12:40:05 +1000 +Subject: [RHEL7.5 PATCH 088/169] systemd/mdadm-last-resort: use + ConditionPathExists instead of Conflicts + +Commit cec72c071bbe ("systemd/mdadm-last-resort: add Conflicts to .service file.") + +added a 'Conflicts' directive to the mdadm-last-resort@.service file in +the hope that this would make sure the service didn't run after the device +was active, even if the timer managed to get started, which is possible in +race conditions. + +This seemed to work is testing, but it isn't clear why, and it is known +to cause problems. +If systemd happens to know that the mentioned device is a dependency of a +mount point, the Conflicts can unmount that mountpoint, which is certainly +not wanted. + +So remove the "Conflicts" and instead use + ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action + +The "sync_action" file exists for any array which requires last-resort +handling, and only appears when the array is activated. So it is safe +to rely on it to determine if the last-resort is really needed. + +Fixes: cec72c071bbe ("systemd/mdadm-last-resort: add Conflicts to .service file.") +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/mdadm-last-resort@.service | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/systemd/mdadm-last-resort@.service b/systemd/mdadm-last-resort@.service +index e93d72b..f9d4d12 100644 +--- a/systemd/mdadm-last-resort@.service ++++ b/systemd/mdadm-last-resort@.service +@@ -1,7 +1,7 @@ + [Unit] + Description=Activate md array even though degraded + DefaultDependencies=no +-Conflicts=sys-devices-virtual-block-%i.device ++ConditionPathExists=!/sys/devices/virtual/block/%i/md/sync_action + + [Service] + Type=oneshot +-- +2.7.4 + diff --git a/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch b/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch new file mode 100644 index 0000000..8931cd5 --- /dev/null +++ b/SOURCES/udev-md-raid-assembly.rules-Skip-non-ready-devices.patch @@ -0,0 +1,39 @@ +From 3a77acd7170199adc690332ded37c41f067c720e Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +Date: Mon, 27 Mar 2017 11:15:44 +1100 +Subject: [RHEL7.5 PATCH 019/169] udev-md-raid-assembly.rules: Skip + non-ready devices + +If a device isn't fully initialized (e.g if it should be +handled by multipathing) it should not be considered for +md/RAID auto-assembly. Doing so can cause incorrect results +such as causing multipath to fail during startup. + +There is a convention that the udev environment variable +SYSTEMD_READY be set to zero for such devices. So change +the mdadm rules to ignore devices with SYSTEMD_READY==0. + +Signed-off-by: Hannes Reinecke +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + udev-md-raid-assembly.rules | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules +index d0d440a..8ca232a 100644 +--- a/udev-md-raid-assembly.rules ++++ b/udev-md-raid-assembly.rules +@@ -7,6 +7,9 @@ ENV{ANACONDA}=="?*", GOTO="md_inc_end" + + SUBSYSTEM!="block", GOTO="md_inc_end" + ++# skip non-initialized devices ++ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end" ++ + # handle potential components of arrays (the ones supported by md) + ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc" + +-- +2.7.4 + diff --git a/SOURCES/util-Code-is-80-characterswide.patch b/SOURCES/util-Code-is-80-characterswide.patch new file mode 100644 index 0000000..5e49255 --- /dev/null +++ b/SOURCES/util-Code-is-80-characterswide.patch @@ -0,0 +1,101 @@ +From b7a462e56135e38dfd9e53aeed6f425c28b1bbc7 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Fri, 29 Sep 2017 18:15:23 -0400 +Subject: [RHEL7.5 PATCH 13/13] util: Code is 80 characters wide + +Lets not make things uglier than they need to be. + +Signed-off-by: Jes Sorensen +--- + util.c | 33 +++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +diff --git a/util.c b/util.c +index c1c8509..68af381 100644 +--- a/util.c ++++ b/util.c +@@ -147,9 +147,9 @@ int cluster_get_dlmlock(int *lockid) + } + + snprintf(str, 64, "bitmap%s", cluster_name); +- ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE, &dlm_lock_res->lksb, +- flags, str, strlen(str), 0, dlm_ast, +- dlm_lock_res, NULL, NULL); ++ ret = dlm_hooks->ls_lock(dlm_lock_res->ls, LKM_PWMODE, ++ &dlm_lock_res->lksb, flags, str, strlen(str), ++ 0, dlm_ast, dlm_lock_res, NULL, NULL); + if (ret) { + pr_err("error %d when get PW mode on lock %s\n", errno, str); + dlm_hooks->release_lockspace(cluster_name, dlm_lock_res->ls, 1); +@@ -183,7 +183,8 @@ int cluster_release_dlmlock(int lockid) + + errno = dlm_lock_res->lksb.sb_status; + if (errno != EUNLOCK) { +- pr_err("error %d happened in ast when unlock lockspace\n", errno); ++ pr_err("error %d happened in ast when unlock lockspace\n", ++ errno); + /* XXX make sure the lockspace is unlocked eventually */ + goto out; + } +@@ -639,14 +640,16 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep) + + } + +-char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep) ++char *fname_from_uuid(struct supertype *st, struct mdinfo *info, ++ char *buf, char sep) + { + // dirty hack to work around an issue with super1 superblocks... + // super1 superblocks need swapuuid set in order for assembly to + // work, but can't have it set if we want this printout to match + // all the other uuid printouts in super1.c, so we force swapuuid + // to 1 to make our printout match the rest of super1 +- return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : st->ss->swapuuid, buf, sep); ++ return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : ++ st->ss->swapuuid, buf, sep); + } + + int check_ext2(int fd, char *name) +@@ -1084,9 +1087,11 @@ int dev_open(char *dev, int flags) + } + if (fd < 0) { + /* Try /tmp as /dev appear to be read-only */ +- snprintf(devname, sizeof(devname), "/tmp/.tmp.md.%d:%d:%d", ++ snprintf(devname, sizeof(devname), ++ "/tmp/.tmp.md.%d:%d:%d", + (int)getpid(), major, minor); +- if (mknod(devname, S_IFBLK|0600, makedev(major, minor)) == 0) { ++ if (mknod(devname, S_IFBLK|0600, ++ makedev(major, minor)) == 0) { + fd = open(devname, flags); + unlink(devname); + } +@@ -2261,8 +2266,10 @@ void set_cmap_hooks(void) + if (!cmap_hooks->cmap_handle) + return; + +- cmap_hooks->initialize = dlsym(cmap_hooks->cmap_handle, "cmap_initialize"); +- cmap_hooks->get_string = dlsym(cmap_hooks->cmap_handle, "cmap_get_string"); ++ cmap_hooks->initialize = ++ dlsym(cmap_hooks->cmap_handle, "cmap_initialize"); ++ cmap_hooks->get_string = ++ dlsym(cmap_hooks->cmap_handle, "cmap_get_string"); + cmap_hooks->finalize = dlsym(cmap_hooks->cmap_handle, "cmap_finalize"); + + if (!cmap_hooks->initialize || !cmap_hooks->get_string || +@@ -2305,8 +2312,10 @@ void set_dlm_hooks(void) + if (!dlm_hooks->dlm_handle) + return; + +- dlm_hooks->create_lockspace = dlsym(dlm_hooks->dlm_handle, "dlm_create_lockspace"); +- dlm_hooks->release_lockspace = dlsym(dlm_hooks->dlm_handle, "dlm_release_lockspace"); ++ dlm_hooks->create_lockspace = ++ dlsym(dlm_hooks->dlm_handle, "dlm_create_lockspace"); ++ dlm_hooks->release_lockspace = ++ dlsym(dlm_hooks->dlm_handle, "dlm_release_lockspace"); + dlm_hooks->ls_lock = dlsym(dlm_hooks->dlm_handle, "dlm_ls_lock"); + dlm_hooks->ls_unlock = dlsym(dlm_hooks->dlm_handle, "dlm_ls_unlock"); + dlm_hooks->ls_get_fd = dlsym(dlm_hooks->dlm_handle, "dlm_ls_get_fd"); +-- +2.7.4 + diff --git a/SOURCES/util-Cosmetic-changes.patch b/SOURCES/util-Cosmetic-changes.patch new file mode 100644 index 0000000..6053689 --- /dev/null +++ b/SOURCES/util-Cosmetic-changes.patch @@ -0,0 +1,99 @@ +From efa295309fd2d85133aaf3c224cd5834b689234c Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 12:05:12 -0400 +Subject: [RHEL7.5 PATCH 035/169] util: Cosmetic changes + +Fixup a number of indentation and whitespace issues + +Signed-off-by: Jes Sorensen +--- + util.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/util.c b/util.c +index 683c869..374015e 100644 +--- a/util.c ++++ b/util.c +@@ -828,14 +828,12 @@ char *human_size(long long bytes) + long cMiB = (bytes * 200LL / (1LL<<20) + 1) / 2; + long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; + snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)", +- cMiB/100 , cMiB % 100, +- cMB/100, cMB % 100); ++ cMiB/100, cMiB % 100, cMB/100, cMB % 100); + } else { + long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2; + long cGB = (bytes / (1000000000LL/200LL ) +1) /2; + snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)", +- cGiB/100 , cGiB % 100, +- cGB/100, cGB % 100); ++ cGiB/100, cGiB % 100, cGB/100, cGB % 100); + } + return buf; + } +@@ -862,22 +860,22 @@ char *human_size_brief(long long bytes, int prefix) + if (bytes < 2*1024LL*1024LL*1024LL) { + long cMiB = (bytes * 200LL / (1LL<<20) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldMiB", +- cMiB/100 , cMiB % 100); ++ cMiB/100, cMiB % 100); + } else { + long cGiB = (bytes * 200LL / (1LL<<30) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldGiB", +- cGiB/100 , cGiB % 100); ++ cGiB/100, cGiB % 100); + } + } + else if (prefix == JEDEC) { + if (bytes < 2*1024LL*1024LL*1024LL) { + long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldMB", +- cMB/100, cMB % 100); ++ cMB/100, cMB % 100); + } else { + long cGB = (bytes / (1000000000LL/200LL ) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldGB", +- cGB/100 , cGB % 100); ++ cGB/100, cGB % 100); + } + } + else +@@ -1093,7 +1091,7 @@ int open_dev_excl(char *devnm) + long delay = 1000; + + sprintf(buf, "%d:%d", major(devid), minor(devid)); +- for (i = 0 ; i < 25 ; i++) { ++ for (i = 0; i < 25; i++) { + int fd = dev_open(buf, flags|O_EXCL); + if (fd >= 0) + return fd; +@@ -1134,7 +1132,7 @@ void wait_for(char *dev, int fd) + (stb_want.st_mode & S_IFMT) != S_IFBLK) + return; + +- for (i = 0 ; i < 25 ; i++) { ++ for (i = 0; i < 25; i++) { + struct stat stb; + if (stat(dev, &stb) == 0 && + (stb.st_mode & S_IFMT) == S_IFBLK && +@@ -1205,7 +1203,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + verstr = "-no-metadata-"; + } + +- for (i = 0; st == NULL && superlist[i] ; i++) ++ for (i = 0; st == NULL && superlist[i]; i++) + st = superlist[i]->match_metadata_desc(verstr); + + sysfs_free(sra); +@@ -1270,7 +1268,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type) + st = xcalloc(1, sizeof(*st)); + st->container_devnm[0] = 0; + +- for (i = 0 ; superlist[i]; i++) { ++ for (i = 0; superlist[i]; i++) { + int rv; + ss = superlist[i]; + if (guess_type == guess_array && ss->add_to_super == NULL) +-- +2.7.4 + diff --git a/SOURCES/util-Finally-kill-off-md_get_version.patch b/SOURCES/util-Finally-kill-off-md_get_version.patch new file mode 100644 index 0000000..321810b --- /dev/null +++ b/SOURCES/util-Finally-kill-off-md_get_version.patch @@ -0,0 +1,66 @@ +From 303949f6f00b750a88bcdfc39ffdfe9f0463f6f2 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:49:18 -0400 +Subject: [RHEL7.5 PATCH 066/169] util: Finally kill off md_get_version() + +Signed-off-by: Jes Sorensen +--- + mdadm.h | 1 - + util.c | 29 ----------------------------- + 2 files changed, 30 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 612bd86..f1f643c 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1404,7 +1404,6 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c, + extern int Restore_metadata(char *dev, char *dir, struct context *c, + struct supertype *st, int only); + +-extern int md_get_version(int fd); + int md_get_array_info(int fd, struct mdu_array_info_s *array); + int md_set_array_info(int fd, struct mdu_array_info_s *array); + int md_get_disk_info(int fd, struct mdu_disk_info_s *disk); +diff --git a/util.c b/util.c +index afeb6a5..a536f81 100644 +--- a/util.c ++++ b/util.c +@@ -273,35 +273,6 @@ int parse_uuid(char *str, int uuid[4]) + return 0; + } + +-/* +- * Get the md version number. +- * We use the RAID_VERSION ioctl if it is supported +- * If not, but we have a block device with major '9', we assume +- * 0.36.0 +- * +- * Return version number as 24 but number - assume version parts +- * always < 255 +- */ +- +-int md_get_version(int fd) +-{ +- struct stat stb; +- mdu_version_t vers; +- +- if (fstat(fd, &stb)<0) +- return -1; +- if ((S_IFMT&stb.st_mode) != S_IFBLK) +- return -1; +- +- if (ioctl(fd, RAID_VERSION, &vers) == 0) +- return (vers.major*10000) + (vers.minor*100) + vers.patchlevel; +- if (errno == EACCES) +- return -1; +- if (major(stb.st_rdev) == MD_MAJOR) +- return (3600); +- return -1; +-} +- + int get_linux_version() + { + struct utsname name; +-- +2.7.4 + diff --git a/SOURCES/util-Get-rid-of-unused-enoughfd.patch b/SOURCES/util-Get-rid-of-unused-enoughfd.patch new file mode 100644 index 0000000..035064e --- /dev/null +++ b/SOURCES/util-Get-rid-of-unused-enoughfd.patch @@ -0,0 +1,70 @@ +From 44356754ec8d7c38720db6c9916fef8f24921831 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 20 Apr 2017 11:53:30 -0400 +Subject: [RHEL7.5 PATCH 085/169] util: Get rid of unused enough_fd() + +enough_fd() is no longer used, so lets get rid of it. + +Signed-off-by: Jes Sorensen +--- + mdadm.h | 1 - + util.c | 31 ------------------------------- + 2 files changed, 32 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index f6e97fd..1bbacfe 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1485,7 +1485,6 @@ extern char *fname_from_uuid(struct supertype *st, + extern unsigned long calc_csum(void *super, int bytes); + extern int enough(int level, int raid_disks, int layout, int clean, + char *avail); +-extern int enough_fd(int fd); + extern int ask(char *mesg); + extern unsigned long long get_component_size(int fd); + extern void remove_partitions(int fd); +diff --git a/util.c b/util.c +index 3adc675..21a63c9 100644 +--- a/util.c ++++ b/util.c +@@ -542,37 +542,6 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail) + } + } + +-int enough_fd(int fd) +-{ +- struct mdu_array_info_s array; +- struct mdu_disk_info_s disk; +- int i, rv; +- char *avail; +- +- if (md_get_array_info(fd, &array) != 0 || array.raid_disks <= 0) +- return 0; +- avail = xcalloc(array.raid_disks, 1); +- for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) { +- disk.number = i; +- if (md_get_disk_info(fd, &disk) != 0) +- continue; +- if (disk.major == 0 && disk.minor == 0) +- continue; +- array.nr_disks--; +- +- if (! (disk.state & (1<= array.raid_disks) +- continue; +- avail[disk.raid_disk] = 1; +- } +- /* This is used on an active array, so assume it is clean */ +- rv = enough(array.level, array.raid_disks, array.layout, +- 1, avail); +- free(avail); +- return rv; +-} +- + const int uuid_zero[4] = { 0, 0, 0, 0 }; + + int same_uuid(int a[4], int b[4], int swapuuid) +-- +2.7.4 + diff --git a/SOURCES/util-Introduce2-md_get_array_info.patch b/SOURCES/util-Introduce2-md_get_array_info.patch new file mode 100644 index 0000000..eeeb6e8 --- /dev/null +++ b/SOURCES/util-Introduce2-md_get_array_info.patch @@ -0,0 +1,416 @@ +From 9cd39f015558dba82c293a4433b481b921ceec87 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 14:35:41 -0400 +Subject: [RHEL7.5 PATCH 037/169] util: Introduce md_get_array_info() + +Remove most direct ioctl calls for GET_ARRAY_INFO, except for one, +which will be addressed in the next patch. + +This is the start of the effort to clean up the use of ioctl calls and +introduce a more structured API, which will use sysfs and fall back to +ioctl for backup. + +Signed-off-by: Jes Sorensen +--- + Create.c | 5 ++--- + Detail.c | 2 +- + Grow.c | 31 ++++++++++++++++--------------- + Incremental.c | 11 +++++------ + Manage.c | 13 ++++++------- + Monitor.c | 7 ++++--- + Query.c | 7 ++++--- + mdadm.h | 1 + + mdassemble.c | 2 +- + util.c | 14 +++++++++++--- + 10 files changed, 51 insertions(+), 42 deletions(-) + +diff --git a/Create.c b/Create.c +index 10e7d10..0e0778f 100644 +--- a/Create.c ++++ b/Create.c +@@ -156,8 +156,7 @@ int Create(struct supertype *st, char *mddev, + memset(&inf, 0, sizeof(inf)); + fd = open(devlist->devname, O_RDONLY); + if (fd >= 0 && +- ioctl(fd, GET_ARRAY_INFO, &inf) == 0 && +- inf.raid_disks == 0) { ++ md_get_array_info(fd, &inf) == 0 && inf.raid_disks == 0) { + /* yep, looks like a container */ + if (st) { + rv = st->ss->load_container(st, fd, +@@ -634,7 +633,7 @@ int Create(struct supertype *st, char *mddev, + } else { + mdu_array_info_t inf; + memset(&inf, 0, sizeof(inf)); +- ioctl(mdfd, GET_ARRAY_INFO, &inf); ++ md_get_array_info(mdfd, &inf); + if (inf.working_disks != 0) { + pr_err("another array by this name is already running.\n"); + goto abort_locked; +diff --git a/Detail.c b/Detail.c +index 136875b..d7e886a 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -107,7 +107,7 @@ int Detail(char *dev, struct context *c) + external = (sra != NULL && sra->array.major_version == -1 + && sra->array.minor_version == -2); + st = super_by_fd(fd, &subarray); +- if (ioctl(fd, GET_ARRAY_INFO, &array) == 0) { ++ if (md_get_array_info(fd, &array) == 0) { + inactive = 0; + } else if (errno == ENODEV && sra) { + if (sra->array.major_version == -1 && +diff --git a/Grow.c b/Grow.c +index 6405f0e..4eab5cc 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -115,7 +115,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + struct supertype *st = NULL; + char *subarray = NULL; + +- if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) { ++ if (md_get_array_info(fd, &info.array) < 0) { + pr_err("cannot get array info for %s\n", devname); + return 1; + } +@@ -221,7 +221,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + * Now go through and update all superblocks + */ + +- if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) { ++ if (md_get_array_info(fd, &info.array) < 0) { + pr_err("cannot get array info for %s\n", devname); + return 1; + } +@@ -328,7 +328,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + devname, bmf.pathname); + return 1; + } +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) { ++ if (md_get_array_info(fd, &array) != 0) { + pr_err("cannot get array status for %s\n", devname); + return 1; + } +@@ -1784,7 +1784,7 @@ int Grow_reshape(char *devname, int fd, + struct mdinfo info; + struct mdinfo *sra; + +- if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) { ++ if (md_get_array_info(fd, &array) < 0) { + pr_err("%s is not an active md array - aborting\n", + devname); + return 1; +@@ -2030,7 +2030,7 @@ int Grow_reshape(char *devname, int fd, + /* get array parameters after takeover + * to change one parameter at time only + */ +- rv = ioctl(fd, GET_ARRAY_INFO, &array); ++ rv = md_get_array_info(fd, &array); + } + } + /* make sure mdmon is +@@ -2072,7 +2072,7 @@ int Grow_reshape(char *devname, int fd, + /* go back to raid0, drop parity disk + */ + sysfs_set_str(sra, NULL, "level", "raid0"); +- ioctl(fd, GET_ARRAY_INFO, &array); ++ md_get_array_info(fd, &array); + } + + size_change_error: +@@ -2101,7 +2101,7 @@ size_change_error: + sysfs_set_str(sra, NULL, "resync_start", "none") < 0) + pr_err("--assume-clean not supported with --grow on this kernel\n"); + } +- ioctl(fd, GET_ARRAY_INFO, &array); ++ md_get_array_info(fd, &array); + s->size = get_component_size(fd)/2; + if (s->size == 0) + s->size = array.size; +@@ -2267,7 +2267,7 @@ size_change_error: + rv =1 ; + } + if (s->layout_str) { +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) { ++ if (md_get_array_info(fd, &array) != 0) { + dprintf("Cannot get array information.\n"); + goto release; + } +@@ -2830,7 +2830,7 @@ static int impose_reshape(struct mdinfo *sra, + * reshape->after.data_disks); + } + +- ioctl(fd, GET_ARRAY_INFO, &array); ++ md_get_array_info(fd, &array); + if (info->array.chunk_size == info->new_chunk && + reshape->before.layout == reshape->after.layout && + st->ss->external == 0) { +@@ -2885,7 +2885,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + struct mdinfo info; + sysfs_init(&info, fd, NULL); + +- ioctl(fd, GET_ARRAY_INFO, &array); ++ md_get_array_info(fd, &array); + if (level == 0 && + (array.level >= 4 && array.level <= 6)) { + /* To convert to RAID0 we need to fail and +@@ -2921,7 +2921,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + makedev(disk.major, disk.minor)); + } + /* Now fail anything left */ +- ioctl(fd, GET_ARRAY_INFO, &array); ++ md_get_array_info(fd, &array); + for (d = 0, found = 0; + d < MAX_DISKS && found < array.nr_disks; + d++) { +@@ -3042,7 +3042,7 @@ static int reshape_array(char *container, int fd, char *devname, + /* when reshaping a RAID0, the component_size might be zero. + * So try to fix that up. + */ +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) { ++ if (md_get_array_info(fd, &array) != 0) { + dprintf("Cannot get array information.\n"); + goto release; + } +@@ -3230,7 +3230,7 @@ static int reshape_array(char *container, int fd, char *devname, + * some more changes: layout, raid_disks, chunk_size + */ + /* read current array info */ +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) { ++ if (md_get_array_info(fd, &array) != 0) { + dprintf("Cannot get array information.\n"); + goto release; + } +@@ -4994,8 +4994,9 @@ int Grow_continue_command(char *devname, int fd, + int d; + int cnt = 5; + dprintf_cont("native array (%s)\n", devname); +- if (ioctl(fd, GET_ARRAY_INFO, &array.array) < 0) { +- pr_err("%s is not an active md array - aborting\n", devname); ++ if (md_get_array_info(fd, &array.array) < 0) { ++ pr_err("%s is not an active md array - aborting\n", ++ devname); + ret_val = 1; + goto Grow_continue_command_exit; + } +diff --git a/Incremental.c b/Incremental.c +index 81afc7e..1f12c77 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -398,7 +398,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + && ! policy_action_allows(policy, st->ss->name, + act_re_add) + && c->runstop < 1) { +- if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) { ++ if (md_get_array_info(mdfd, &ainf) == 0) { + pr_err("not adding %s to active array (without --run) %s\n", + devname, chosen_name); + rv = 2; +@@ -549,7 +549,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + /* + add any bitmap file */ + /* + start the array (auto-readonly). */ + +- if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) { ++ if (md_get_array_info(mdfd, &ainf) == 0) { + if (c->export) { + printf("MD_STARTED=already\n"); + } else if (c->verbose >= 0) +@@ -664,7 +664,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra, + struct mdinfo *d; + mdu_array_info_t ra; + +- if (ioctl(mdfd, GET_ARRAY_INFO, &ra) == 0) ++ if (md_get_array_info(mdfd, &ra) == 0) + return; /* not safe to remove from active arrays + * without thinking more */ + +@@ -837,7 +837,7 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent + if (afd < 0) + continue; + /* most accurate information regarding array degradation */ +- if (ioctl(afd, GET_ARRAY_INFO, &array) >= 0) { ++ if (md_get_array_info(afd, &array) >= 0) { + int degraded = array.raid_disks - array.active_disks - + array.spare_disks; + if (degraded > max_degraded) +@@ -1390,8 +1390,7 @@ restart: + rv = 1; + continue; + } +- if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 || +- errno != ENODEV) { ++ if (md_get_array_info(mdfd, &array) == 0 || errno != ENODEV) { + close(mdfd); + continue; + } +diff --git a/Manage.c b/Manage.c +index 55218d9..24ed370 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -95,7 +95,7 @@ int Manage_ro(char *devname, int fd, int readonly) + goto out; + } + #endif +- if (ioctl(fd, GET_ARRAY_INFO, &array)) { ++ if (md_get_array_info(fd, &array)) { + pr_err("%s does not appear to be active.\n", + devname); + rv = 1; +@@ -539,7 +539,7 @@ static void add_faulty(struct mddev_dev *dv, int fd, char disp) + int remaining_disks; + int i; + +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) ++ if (md_get_array_info(fd, &array) != 0) + return; + + remaining_disks = array.nr_disks; +@@ -565,7 +565,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp) + int remaining_disks; + int i; + +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) ++ if (md_get_array_info(fd, &array) != 0) + return; + + remaining_disks = array.nr_disks; +@@ -602,7 +602,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) + int copies, set; + int i; + +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) ++ if (md_get_array_info(fd, &array) != 0) + return; + if (array.level != 10) + return; +@@ -1383,9 +1383,8 @@ int Manage_subdevs(char *devname, int fd, + int busy = 0; + int raid_slot = -1; + +- if (ioctl(fd, GET_ARRAY_INFO, &array)) { +- pr_err("Cannot get array info for %s\n", +- devname); ++ if (md_get_array_info(fd, &array)) { ++ pr_err("Cannot get array info for %s\n", devname); + goto abort; + } + sysfs_init(&info, fd, NULL); +diff --git a/Monitor.c b/Monitor.c +index bdd3e63..0a0a1e2 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -497,7 +497,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + return 0; + } + fcntl(fd, F_SETFD, FD_CLOEXEC); +- if (ioctl(fd, GET_ARRAY_INFO, &array)<0) { ++ if (md_get_array_info(fd, &array) < 0) { + if (!st->err) + alert("DeviceDisappeared", dev, NULL, ainfo); + st->err++; +@@ -709,9 +709,10 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, + + st->devname = xstrdup(name); + if ((fd = open(st->devname, O_RDONLY)) < 0 || +- ioctl(fd, GET_ARRAY_INFO, &array)< 0) { ++ md_get_array_info(fd, &array) < 0) { + /* no such array */ +- if (fd >=0) close(fd); ++ if (fd >= 0) ++ close(fd); + put_md_name(st->devname); + free(st->devname); + if (st->metadata) { +diff --git a/Query.c b/Query.c +index fbc1d10..cae75d1 100644 +--- a/Query.c ++++ b/Query.c +@@ -53,9 +53,10 @@ int Query(char *dev) + } + + vers = md_get_version(fd); +- if (ioctl(fd, GET_ARRAY_INFO, &array)<0) ++ if (md_get_array_info(fd, &array) < 0) + ioctlerr = errno; +- else ioctlerr = 0; ++ else ++ ioctlerr = 0; + + fstat(fd, &stb); + +@@ -100,7 +101,7 @@ int Query(char *dev) + activity = "undetected"; + if (mddev && (fd = open(mddev, O_RDONLY))>=0) { + if (md_get_version(fd) >= 9000 && +- ioctl(fd, GET_ARRAY_INFO, &array)>= 0) { ++ md_get_array_info(fd, &array) >= 0) { + if (ioctl(fd, GET_DISK_INFO, &disc) >= 0 && + makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev) + activity = "active"; +diff --git a/mdadm.h b/mdadm.h +index dbf1f92..7770585 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1405,6 +1405,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c, + struct supertype *st, int only); + + extern int md_get_version(int fd); ++int md_get_array_info(int fd, struct mdu_array_info_s *array); + extern int get_linux_version(void); + extern int mdadm_version(char *version); + extern unsigned long long parse_size(char *size); +diff --git a/mdassemble.c b/mdassemble.c +index 471ffeb..a24b324 100644 +--- a/mdassemble.c ++++ b/mdassemble.c +@@ -67,7 +67,7 @@ int main(int argc, char *argv[]) + if (strcasecmp(array_list->devname, "") == 0) + continue; + mdfd = open_mddev(array_list->devname, 0); +- if (mdfd >= 0 && ioctl(mdfd, GET_ARRAY_INFO, &array) == 0) { ++ if (mdfd >= 0 && md_get_array_info(mdfd, &array) == 0) { + rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */ + continue; + } +diff --git a/util.c b/util.c +index 374015e..725877d 100644 +--- a/util.c ++++ b/util.c +@@ -212,6 +212,15 @@ int cluster_release_dlmlock(int lockid) + #endif + + /* ++ * Get array info from the kernel. Longer term we want to deprecate the ++ * ioctl and get it from sysfs. ++ */ ++int md_get_array_info(int fd, struct mdu_array_info_s *array) ++{ ++ return ioctl(fd, GET_ARRAY_INFO, array); ++} ++ ++/* + * Parse a 128 bit uuid in 4 integers + * format is 32 hexx nibbles with options :. separator + * If not exactly 32 hex digits are found, return 0 +@@ -539,8 +548,7 @@ int enough_fd(int fd) + int i, rv; + char *avail; + +- if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 || +- array.raid_disks <= 0) ++ if (md_get_array_info(fd, &array) != 0 || array.raid_disks <= 0) + return 0; + avail = xcalloc(array.raid_disks, 1); + for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) { +@@ -1175,7 +1183,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp) + minor = sra->array.minor_version; + verstr = sra->text_version; + } else { +- if (ioctl(fd, GET_ARRAY_INFO, &array)) ++ if (md_get_array_info(fd, &array)) + array.major_version = array.minor_version = 0; + vers = array.major_version; + minor = array.minor_version; +-- +2.7.4 + diff --git a/SOURCES/util-Introduce3-md_get_disk_info.patch b/SOURCES/util-Introduce3-md_get_disk_info.patch new file mode 100644 index 0000000..5d58b92 --- /dev/null +++ b/SOURCES/util-Introduce3-md_get_disk_info.patch @@ -0,0 +1,268 @@ +From d97572f5a59ca1ddde9971a79d47c9ea4db5891b Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 15:23:50 -0400 +Subject: [RHEL7.5 PATCH 039/169] util: Introduce md_get_disk_info() + +This removes all the inline ioctl calls for GET_DISK_INFO, allowing us +to switch to sysfs in one place, and improves type checking. + +Signed-off-by: Jes Sorensen +--- + Detail.c | 8 +++----- + Grow.c | 14 +++++++------- + Manage.c | 19 +++++++++---------- + Monitor.c | 2 +- + Query.c | 2 +- + mdadm.h | 1 + + util.c | 10 +++++++++- + 7 files changed, 31 insertions(+), 25 deletions(-) + +diff --git a/Detail.c b/Detail.c +index d7e886a..fa6d4c7 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -51,10 +51,8 @@ static int add_device(const char *dev, char ***p_devices, + int Detail(char *dev, struct context *c) + { + /* +- * Print out details for an md array by using +- * GET_ARRAY_INFO and GET_DISK_INFO ioctl calls ++ * Print out details for an md array + */ +- + int fd = open(dev, O_RDONLY); + int vers; + mdu_array_info_t array; +@@ -165,7 +163,7 @@ int Detail(char *dev, struct context *c) + disk = subdev->disk; + else { + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if (d >= array.raid_disks && + disk.major == 0 && +@@ -322,7 +320,7 @@ int Detail(char *dev, struct context *c) + } else for (d = 0; d < max_disks; d++) { + mdu_disk_info_t disk; + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { ++ if (md_get_disk_info(fd, &disk) < 0) { + if (d < array.raid_disks) + pr_err("cannot get device detail for device %d: %s\n", + d, strerror(errno)); +diff --git a/Grow.c b/Grow.c +index 4eab5cc..1c90902 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -161,7 +161,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + st->ss->free_super(st); + + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { ++ if (md_get_disk_info(fd, &disk) < 0) { + pr_err("cannot get device detail for device %d\n", + d); + close(nfd); +@@ -232,7 +232,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev) + char *dv; + + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { ++ if (md_get_disk_info(fd, &disk) < 0) { + pr_err("cannot get device detail for device %d\n", + d); + return 1; +@@ -422,7 +422,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + int fd2; + + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -483,7 +483,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + char *dv; + int fd2; + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if ((disk.major==0 && disk.minor == 0) || + (disk.state & (1 << MD_DISK_REMOVED))) +@@ -2908,7 +2908,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + d++) { + mdu_disk_info_t disk; + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -2927,7 +2927,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + d++) { + mdu_disk_info_t disk; + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -5011,7 +5011,7 @@ int Grow_continue_command(char *devname, int fd, + char *dv; + int err; + disk.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disk) < 0) ++ if (md_get_disk_info(fd, &disk) < 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +diff --git a/Manage.c b/Manage.c +index 24ed370..0ffb6c6 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -546,7 +546,7 @@ static void add_faulty(struct mddev_dev *dv, int fd, char disp) + for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) { + char buf[40]; + disk.number = i; +- if (ioctl(fd, GET_DISK_INFO, &disk) != 0) ++ if (md_get_disk_info(fd, &disk) != 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -573,7 +573,7 @@ static void add_detached(struct mddev_dev *dv, int fd, char disp) + char buf[40]; + int sfd; + disk.number = i; +- if (ioctl(fd, GET_DISK_INFO, &disk) != 0) ++ if (md_get_disk_info(fd, &disk) != 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -615,7 +615,7 @@ static void add_set(struct mddev_dev *dv, int fd, char set_char) + for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) { + char buf[40]; + disk.number = i; +- if (ioctl(fd, GET_DISK_INFO, &disk) != 0) ++ if (md_get_disk_info(fd, &disk) != 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +@@ -661,9 +661,8 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, + get_linux_version() <= 2006018) + goto skip_re_add; + disc.number = mdi.disk.number; +- if (ioctl(fd, GET_DISK_INFO, &disc) != 0 +- || disc.major != 0 || disc.minor != 0 +- ) ++ if (md_get_disk_info(fd, &disc) != 0 || ++ disc.major != 0 || disc.minor != 0) + goto skip_re_add; + disc.major = major(rdev); + disc.minor = minor(rdev); +@@ -805,7 +804,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + char *dev; + int dfd; + disc.number = j; +- if (ioctl(fd, GET_DISK_INFO, &disc)) ++ if (md_get_disk_info(fd, &disc)) + continue; + if (disc.major==0 && disc.minor==0) + continue; +@@ -888,7 +887,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + + for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) { + disc.number = d; +- if (ioctl(fd, GET_DISK_INFO, &disc)) ++ if (md_get_disk_info(fd, &disc)) + continue; + if (disc.major == 0 && disc.minor == 0) + continue; +@@ -929,7 +928,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + */ + for (j = array->raid_disks; j < tst->max_devs; j++) { + disc.number = j; +- if (ioctl(fd, GET_DISK_INFO, &disc)) ++ if (md_get_disk_info(fd, &disc)) + break; + if (disc.major==0 && disc.minor==0) + break; +@@ -994,7 +993,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, + for (j = 0; j < tst->max_devs; j++) { + mdu_disk_info_t disc2; + disc2.number = j; +- if (ioctl(fd, GET_DISK_INFO, &disc2)) ++ if (md_get_disk_info(fd, &disc2)) + continue; + if (disc2.major==0 && disc2.minor==0) + continue; +diff --git a/Monitor.c b/Monitor.c +index 0a0a1e2..2c0f717 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -608,7 +608,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, + i++) { + mdu_disk_info_t disc; + disc.number = i; +- if (ioctl(fd, GET_DISK_INFO, &disc) >= 0) { ++ if (md_get_disk_info(fd, &disc) >= 0) { + info[i].state = disc.state; + info[i].major = disc.major; + info[i].minor = disc.minor; +diff --git a/Query.c b/Query.c +index cae75d1..a2c839c 100644 +--- a/Query.c ++++ b/Query.c +@@ -102,7 +102,7 @@ int Query(char *dev) + if (mddev && (fd = open(mddev, O_RDONLY))>=0) { + if (md_get_version(fd) >= 9000 && + md_get_array_info(fd, &array) >= 0) { +- if (ioctl(fd, GET_DISK_INFO, &disc) >= 0 && ++ if (md_get_disk_info(fd, &disc) >= 0 && + makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev) + activity = "active"; + else +diff --git a/mdadm.h b/mdadm.h +index 7770585..3ab548f 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1406,6 +1406,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c, + + extern int md_get_version(int fd); + int md_get_array_info(int fd, struct mdu_array_info_s *array); ++int md_get_disk_info(int fd, struct mdu_disk_info_s *disk); + extern int get_linux_version(void); + extern int mdadm_version(char *version); + extern unsigned long long parse_size(char *size); +diff --git a/util.c b/util.c +index 725877d..aa27e59 100644 +--- a/util.c ++++ b/util.c +@@ -221,6 +221,14 @@ int md_get_array_info(int fd, struct mdu_array_info_s *array) + } + + /* ++ * Get disk info from the kernel. ++ */ ++int md_get_disk_info(int fd, struct mdu_disk_info_s *disk) ++{ ++ return ioctl(fd, GET_DISK_INFO, disk); ++} ++ ++/* + * Parse a 128 bit uuid in 4 integers + * format is 32 hexx nibbles with options :. separator + * If not exactly 32 hex digits are found, return 0 +@@ -553,7 +561,7 @@ int enough_fd(int fd) + avail = xcalloc(array.raid_disks, 1); + for (i = 0; i < MAX_DISKS && array.nr_disks > 0; i++) { + disk.number = i; +- if (ioctl(fd, GET_DISK_INFO, &disk) != 0) ++ if (md_get_disk_info(fd, &disk) != 0) + continue; + if (disk.major == 0 && disk.minor == 0) + continue; +-- +2.7.4 + diff --git a/SOURCES/util-Introduce4-md_set_array_info.patch b/SOURCES/util-Introduce4-md_set_array_info.patch new file mode 100644 index 0000000..fe57bae --- /dev/null +++ b/SOURCES/util-Introduce4-md_set_array_info.patch @@ -0,0 +1,153 @@ +From 018a488238e2ff55d7c2fd29333c1f7305354318 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 29 Mar 2017 15:43:53 -0400 +Subject: [RHEL7.5 PATCH 040/169] util: Introduce md_set_array_info() + +Switch from using ioctl(SET_ARRAY_INFO) to using md_set_array_info() + +Signed-off-by: Jes Sorensen +--- + Build.c | 4 ++-- + Grow.c | 17 ++++++++--------- + mdadm.h | 1 + + util.c | 12 ++++++++++-- + 4 files changed, 21 insertions(+), 13 deletions(-) + +diff --git a/Build.c b/Build.c +index a5fcc06..691dd6f 100644 +--- a/Build.c ++++ b/Build.c +@@ -148,8 +148,8 @@ int Build(char *mddev, struct mddev_dev *devlist, + s->chunk = 64; + array.chunk_size = s->chunk*1024; + array.layout = s->layout; +- if (ioctl(mdfd, SET_ARRAY_INFO, &array)) { +- pr_err("SET_ARRAY_INFO failed for %s: %s\n", ++ if (md_set_array_info(mdfd, &array)) { ++ pr_err("md_set_array_info() failed for %s: %s\n", + mddev, strerror(errno)); + goto abort; + } +diff --git a/Grow.c b/Grow.c +index 1c90902..af8d520 100755 +--- a/Grow.c ++++ b/Grow.c +@@ -335,7 +335,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + if (array.state & (1 << MD_SB_BITMAP_PRESENT)) { + if (strcmp(s->bitmap_file, "none")==0) { + array.state &= ~(1 << MD_SB_BITMAP_PRESENT); +- if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) { ++ if (md_set_array_info(fd, &array) != 0) { + if (array.state & (1 << MD_SB_CLUSTERED)) + pr_err("failed to remove clustered bitmap.\n"); + else +@@ -463,7 +463,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + if (strcmp(s->bitmap_file, "clustered") == 0) + array.state |= (1 << MD_SB_CLUSTERED); + array.state |= (1 << MD_SB_BITMAP_PRESENT); +- rv = ioctl(fd, SET_ARRAY_INFO, &array); ++ rv = md_set_array_info(fd, &array); + } + if (rv < 0) { + if (errno == EBUSY) +@@ -1823,7 +1823,7 @@ int Grow_reshape(char *devname, int fd, + (array.state & (1<verbose >= 0) +@@ -2836,8 +2836,7 @@ static int impose_reshape(struct mdinfo *sra, + st->ss->external == 0) { + /* use SET_ARRAY_INFO but only if reshape hasn't started */ + array.raid_disks = reshape->after.data_disks + reshape->parity; +- if (!restart && +- ioctl(fd, SET_ARRAY_INFO, &array) != 0) { ++ if (!restart && md_set_array_info(fd, &array) != 0) { + int err = errno; + + pr_err("Cannot set device shape for %s: %s\n", +@@ -3239,7 +3238,7 @@ static int reshape_array(char *container, int fd, char *devname, + if (info->new_layout != UnSet && + info->new_layout != array.layout) { + array.layout = info->new_layout; +- if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) { ++ if (md_set_array_info(fd, &array) != 0) { + pr_err("failed to set new layout\n"); + goto release; + } else if (verbose >= 0) +@@ -3250,7 +3249,7 @@ static int reshape_array(char *container, int fd, char *devname, + info->delta_disks != 0 && + array.raid_disks != (info->array.raid_disks + info->delta_disks)) { + array.raid_disks += info->delta_disks; +- if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) { ++ if (md_set_array_info(fd, &array) != 0) { + pr_err("failed to set raid disks\n"); + goto release; + } else if (verbose >= 0) { +diff --git a/mdadm.h b/mdadm.h +index 3ab548f..084bc97 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1406,6 +1406,7 @@ extern int Restore_metadata(char *dev, char *dir, struct context *c, + + extern int md_get_version(int fd); + int md_get_array_info(int fd, struct mdu_array_info_s *array); ++int md_set_array_info(int fd, struct mdu_array_info_s *array); + int md_get_disk_info(int fd, struct mdu_disk_info_s *disk); + extern int get_linux_version(void); + extern int mdadm_version(char *version); +diff --git a/util.c b/util.c +index aa27e59..9fc7ba0 100644 +--- a/util.c ++++ b/util.c +@@ -221,6 +221,14 @@ int md_get_array_info(int fd, struct mdu_array_info_s *array) + } + + /* ++ * Set array info ++ */ ++int md_set_array_info(int fd, struct mdu_array_info_s *array) ++{ ++ return ioctl(fd, SET_ARRAY_INFO, array); ++} ++ ++/* + * Get disk info from the kernel. + */ + int md_get_disk_info(int fd, struct mdu_disk_info_s *disk) +@@ -1858,9 +1866,9 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + memset(&inf, 0, sizeof(inf)); + inf.major_version = info->array.major_version; + inf.minor_version = info->array.minor_version; +- rv = ioctl(mdfd, SET_ARRAY_INFO, &inf); ++ rv = md_set_array_info(mdfd, &inf); + } else +- rv = ioctl(mdfd, SET_ARRAY_INFO, NULL); ++ rv = md_set_array_info(mdfd, NULL); + return rv; + } + +-- +2.7.4 + diff --git a/SOURCES/util-Introduce6-md_array_active-helper.patch b/SOURCES/util-Introduce6-md_array_active-helper.patch new file mode 100644 index 0000000..1837755 --- /dev/null +++ b/SOURCES/util-Introduce6-md_array_active-helper.patch @@ -0,0 +1,99 @@ +From 3ab8f4bf33d906cb1084f7b4036556bfb4bb73ec Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Thu, 13 Apr 2017 13:30:17 -0400 +Subject: [RHEL7.5 PATCH 082/169] util: Introduce md_array_active() helper + +Rather than querying md_get_array_info() to determine whether an array +is valid, do the work in md_array_active() using sysfs, and fall back +on md_get_array_info() if sysfs fails. + +Signed-off-by: Jes Sorensen +--- + Query.c | 5 +++-- + mdadm.h | 1 + + util.c | 27 +++++++++++++++++++++++++++ + 3 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/Query.c b/Query.c +index b761c47..4dec9f5 100644 +--- a/Query.c ++++ b/Query.c +@@ -38,7 +38,6 @@ int Query(char *dev) + int level, raid_disks, spare_disks; + struct mdinfo info; + struct mdinfo *sra; +- mdu_array_info_t array; + struct supertype *st = NULL; + unsigned long long larray_size; + struct stat stb; +@@ -65,6 +64,8 @@ int Query(char *dev) + raid_disks = sra->array.raid_disks; + spare_disks = sra->array.spare_disks; + } else { ++ mdu_array_info_t array; ++ + if (md_get_array_info(fd, &array) < 0) { + ioctlerr = errno; + } else { +@@ -111,7 +112,7 @@ int Query(char *dev) + disc.number = info.disk.number; + activity = "undetected"; + if (mddev && (fd = open(mddev, O_RDONLY))>=0) { +- if (md_get_array_info(fd, &array) >= 0) { ++ if (md_array_active(fd)) { + if (md_get_disk_info(fd, &disc) >= 0 && + makedev((unsigned)disc.major,(unsigned)disc.minor) == stb.st_rdev) + activity = "active"; +diff --git a/mdadm.h b/mdadm.h +index a379973..f6e97fd 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1415,6 +1415,7 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c, + extern int Restore_metadata(char *dev, char *dir, struct context *c, + struct supertype *st, int only); + ++int md_array_active(int fd); + int md_get_array_info(int fd, struct mdu_array_info_s *array); + int md_set_array_info(int fd, struct mdu_array_info_s *array); + int md_get_disk_info(int fd, struct mdu_disk_info_s *disk); +diff --git a/util.c b/util.c +index a695c45..3adc675 100644 +--- a/util.c ++++ b/util.c +@@ -200,6 +200,33 @@ out: + return ret; + } + ++int md_array_active(int fd) ++{ ++ struct mdinfo *sra; ++ struct mdu_array_info_s array; ++ int ret; ++ ++ sra = sysfs_read(fd, NULL, GET_ARRAY_STATE); ++ if (sra) { ++ if (sra->array_state != ARRAY_CLEAR && ++ sra->array_state != ARRAY_INACTIVE && ++ sra->array_state != ARRAY_UNKNOWN_STATE) ++ ret = 0; ++ else ++ ret = -ENODEV; ++ ++ free(sra); ++ } else { ++ /* ++ * 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); ++ } ++ ++ return !ret; ++} ++ + /* + * Get array info from the kernel. Longer term we want to deprecate the + * ioctl and get it from sysfs. +-- +2.7.4 + diff --git a/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch b/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch new file mode 100644 index 0000000..f8cf036 --- /dev/null +++ b/SOURCES/util-md_array_valid-Introduce5-md_array_valid-helper.patch @@ -0,0 +1,91 @@ +From 9db2ab4e9b1ad79b9364b6e03bdd675716a688a5 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 3 May 2017 14:25:57 -0400 +Subject: [RHEL7.5 PATCH 106/169] util: md_array_valid(): Introduce + md_array_valid() helper + +Using md_get_array_info() to determine if an array is valid is broken +during creation, since the ioctl() returns -ENODEV if the device is +valid but not active. + +Where did I leave my stash of brown paper bags? + +Fixes: ("40b054e mdopen/open_mddev: Use md_get_array_info() to determine valid array") +Signed-off-by: Jes Sorensen +--- + mdadm.h | 1 + + mdopen.c | 3 +-- + util.c | 24 ++++++++++++++++++++++++ + 3 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index 6a382a7..07ee963 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1415,6 +1415,7 @@ extern int Dump_metadata(char *dev, char *dir, struct context *c, + extern int Restore_metadata(char *dev, char *dir, struct context *c, + struct supertype *st, int only); + ++int md_array_valid(int fd); + int md_array_active(int fd); + int md_get_array_info(int fd, struct mdu_array_info_s *array); + int md_set_array_info(int fd, struct mdu_array_info_s *array); +diff --git a/mdopen.c b/mdopen.c +index 099efa0..c4f1c12 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -442,7 +442,6 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, + */ + int open_mddev(char *dev, int report_errors) + { +- struct mdu_array_info_s array; + int mdfd = open(dev, O_RDONLY); + + if (mdfd < 0) { +@@ -452,7 +451,7 @@ int open_mddev(char *dev, int report_errors) + return -1; + } + +- if (md_get_array_info(mdfd, &array) != 0) { ++ if (md_array_valid(mdfd) == 0) { + close(mdfd); + if (report_errors) + pr_err("%s does not appear to be an md device\n", dev); +diff --git a/util.c b/util.c +index 21a63c9..c7585ac 100644 +--- a/util.c ++++ b/util.c +@@ -200,6 +200,30 @@ out: + return ret; + } + ++int md_array_valid(int fd) ++{ ++ struct mdinfo *sra; ++ int ret; ++ ++ sra = sysfs_read(fd, NULL, GET_ARRAY_STATE); ++ if (sra) { ++ if (sra->array_state != ARRAY_UNKNOWN_STATE) ++ ret = 0; ++ else ++ ret = -ENODEV; ++ ++ free(sra); ++ } else { ++ /* ++ * 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, RAID_VERSION); ++ } ++ ++ return !ret; ++} ++ + int md_array_active(int fd) + { + struct mdinfo *sra; +-- +2.7.4 + diff --git a/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch b/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch new file mode 100644 index 0000000..5031a88 --- /dev/null +++ b/SOURCES/util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch @@ -0,0 +1,37 @@ +From f5c924f441cedce2a13c48b12be35250560ee575 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 14:01:30 -0400 +Subject: [RHEL7.5 PATCH 052/169] util/must_be_container: Use + sysfs_read(GET_VERSION) to determine valid array + +Use sysfs_read() instead of ioctl(RAID_VERSION) to determine this is +in fact a valid raid array fd. + +Signed-off-by: Jes Sorensen +--- + util.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/util.c b/util.c +index 9fc7ba0..56daee3 100644 +--- a/util.c ++++ b/util.c +@@ -1376,9 +1376,14 @@ int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep) + */ + int must_be_container(int fd) + { ++ struct mdinfo *mdi; + unsigned long long size; +- if (md_get_version(fd) < 0) ++ ++ mdi = sysfs_read(fd, NULL, GET_VERSION); ++ if (!mdi) + return 0; ++ sysfs_free(mdi); ++ + if (get_dev_size(fd, NULL, &size) == 0) + return 1; + if (size == 0) +-- +2.7.4 + diff --git a/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch b/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch new file mode 100644 index 0000000..d290939 --- /dev/null +++ b/SOURCES/util-set_array_info-Simplify-code-since-md_get-versi.patch @@ -0,0 +1,52 @@ +From 700483a22340f2f25a761acd08e6db87e92d90e9 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 5 Apr 2017 15:06:24 -0400 +Subject: [RHEL7.5 PATCH 053/169] util/set_array_info: Simplify code since + md_get_version returns a constant + +md_get_version() always returns (0 * 1000) + (90 * 100) + 3, so no +point in calling it. + +Signed-off-by: Jes Sorensen +--- + util.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/util.c b/util.c +index 56daee3..afeb6a5 100644 +--- a/util.c ++++ b/util.c +@@ -1858,22 +1858,19 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) + * This varies between externally managed arrays + * and older kernels + */ +- int vers = md_get_version(mdfd); ++ mdu_array_info_t inf; + int rv; + + #ifndef MDASSEMBLE + if (st->ss->external) +- rv = sysfs_set_array(info, vers); +- else ++ return sysfs_set_array(info, 9003); + #endif +- if ((vers % 100) >= 1) { /* can use different versions */ +- mdu_array_info_t inf; +- memset(&inf, 0, sizeof(inf)); +- inf.major_version = info->array.major_version; +- inf.minor_version = info->array.minor_version; +- rv = md_set_array_info(mdfd, &inf); +- } else +- rv = md_set_array_info(mdfd, NULL); ++ ++ memset(&inf, 0, sizeof(inf)); ++ inf.major_version = info->array.major_version; ++ inf.minor_version = info->array.minor_version; ++ rv = md_set_array_info(mdfd, &inf); ++ + return rv; + } + +-- +2.7.4 + diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec index a8f19b8..360a5c9 100644 --- a/SPECS/mdadm.spec +++ b/SPECS/mdadm.spec @@ -1,7 +1,7 @@ Summary: The mdadm program controls Linux md devices (software RAID arrays) Name: mdadm Version: 4.0 -Release: 5%{?dist} +Release: 13%{?dist} Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz Source1: mdmonitor.init Source2: raid-check @@ -12,30 +12,208 @@ Source6: mdmonitor.service Source7: mdadm.conf Source8: mdadm_event.conf -Patch1: add-man-page-for-symlinks.patch -Patch2: specify-enough-length-when-write-to-buffer.patch -Patch3: generic-support-for-consistency-policy-and-PPL.patch -Patch4: detail-show-consistency-policy.patch -Patch5: imsmppl-support.patch -Patch6: super1-ppl-support.patch -Patch7: add-ppl-and-no-ppl-options-for-update.patch -Patch8: support-consistency-policy-change.patch -Patch9: imsm-use-rounded-size-for-metadata-initialization.patch -Patch10: allow-drives-in-a-container-regardless-of-sector-size.patch -Patch11: allocate-buffer-to-support-maximum-sector-size.patch -Patch12: dont-allow-disks-with-different-sector-size-in-one.patch -Patch13: Allow-more-spare-selection-criteria.patch -Patch14: Add-sector-size-as-spare-selection-criterion.patch -Patch15: Correct-examine-output-for-4k-disks.patch -Patch16: dont-allow-array-geometry-change-with-ppl-enabled.patch -Patch17: dont-allow-to-enable-PPL-reshape-in-progress.patch +Patch1: Makefile-Fix-date-to-be-output-in-ISO-format.patch +Patch2: imsm-fix-missing-error-message-during-migration1.patch +Patch3: Fix-oddity-where-mdadm-did-not-recognise-a-relative-.patch +Patch4: mdadm-fix-typo1-in-comment.patch +Patch5: mdadm-check-the-nodes-when-operate-clustered1-array.patch +Patch6: examine-tidy-up-some-code.patch +Patch7: add-man-page-for-symlinks.patch +Patch8: mdadm-add-checking-clustered2-bitmap-in-assemble-mode.patch +Patch9: mdadm-Add-Wimplicit-fallthrough-0-in-Makefile.patch +Patch10: specify-enough-length-when-write-to-buffer.patch +Patch11: mdadm-fixed-some-trivial-typos-in-comments-of-mdadm.patch +Patch12: mdadm-it-doesn-t-make-sense-to-set-bitmap-twice.patch +Patch13: mdadm-mdmon-deleted-the-abort_reshape-never-invoked.patch +Patch14: mdadm-Monitor-Fix-NULL-pointer-dereference-when-stat.patch +Patch15: Replace-snprintf-with-strncpy-at-some-places-to-avoi.patch +Patch16: mdadm-Forced-type-conversion-to-avoid-truncation.patch +Patch17: super1-ignore-failfast-flag-for-setting-device-role.patch +Patch18: mdadm-bitmap-fixed-typos-in-comments1-of-bitmap.h.patch +Patch19: udev-md-raid-assembly.rules-Skip-non-ready-devices.patch +Patch20: Retry-HOT_REMOVE_DISK-a-few-times.patch +Patch21: mdadm-Build1-check-the-level-parameter-when-build-new.patch +Patch22: Introduce1-sys_hot_remove_disk.patch +Patch23: Add-force-flag1-to-hot_remove_disk.patch +Patch24: Detail-handle-non-existent-arrays-better.patch +Patch25: generic-support-for-consistency-policy-and-PPL.patch +Patch26: detail-show-consistency-policy.patch +Patch27: imsmppl-support.patch +Patch28: super1ppl-support.patch +Patch29: add-ppl-and-no-ppl-options-for-update.patch +Patch30: support-consistency-policy1-change.patch +Patch31: mdadm.h-struct-mdinfo-reorganize-ppl-elements-for-be.patch +Patch32: super1-replace-hard-coded-values-with-bit-definition.patch +Patch33: mdadm-Clean-up-some-ugly-multiple-actions-on-single-.patch +Patch34: mdadm-Fixup-a-number-of-whitespace-inconsistency-cas.patch +Patch35: util-Cosmetic-changes.patch +Patch36: Grow-Fixup-a-pile-of-cosmetic-issues.patch +Patch37: util-Introduce2-md_get_array_info.patch +Patch38: Incremental-Remove-redundant-call-for-GET_ARRAY_INFO.patch +Patch39: util-Introduce3-md_get_disk_info.patch +Patch40: util-Introduce4-md_set_array_info.patch +Patch41: md_u-Remove-some-unused-ioctl-declarations.patch +Patch42: Grow-Remove-unnecessary-optimization.patch +Patch43: Grow-Do-not-shadow-an-existing-variable.patch +Patch44: mdadm-grow-reshape-would1-be-stuck-from-raid1-to-raid.patch +Patch45: imsm-use-rounded-size-for-metadata-initialization.patch +Patch46: mdadm.c-fix-compile-error-switch-condition-has-boole.patch +Patch47: sysfs-Use-the-presence-of-sys-block-dev-md-as-indica.patch +Patch48: sysfs-Make-sysfs_init-return-an-error-code.patch +Patch49: mdadm-Create-declaring1-an-existing-struct-within-sam.patch +Patch50: Create-Fixup-bad-placement-of-logical-in-multi-line-.patch +Patch51: Create-Fixup-various-whitespace-issues1.patch +Patch52: util-must_be-container1-Use-sysfs_read-GET_VERSION-to.patch +Patch53: util-set_array_info-Simplify-code-since-md_get-versi.patch +Patch54: Assemble-Assemble-Stop-checking-kernel-md-driver-ver.patch +Patch55: Build2-Stop-bothering-about-supporting-md-driver-olde.patch +Patch56: Grow-Stop-bothering-about-md-driver-versions-older-t.patch +Patch57: Detail-Stop-bothering1-about-md-drivers-older-than-0..patch +Patch58: Create-Remove-all-attemps-to-handle-md-driver-older-.patch +Patch59: Manage-Remove-all-references1-to-md_get_version.patch +Patch60: Query-Remove-all-references-to-md_get_version.patch +Patch61: bitmap-Remove-use-of-md-get-version1.patch +Patch62: mdmon-Stop-bothering-about-md-get-version2.patch +Patch63: mdopen-open_mddev-Use-md_get_array_info-to-determine1.patch +Patch64: mdassemble-Use-md_get_array_info-to-check-for-valid-.patch +Patch65: Assemble-Assemble-Get-rid-of-last-use-of-md_get-vers.patch +Patch66: util-Finally-kill-off-md_get_version.patch +Patch67: mdadm-Fail-for-kernels-older-than-2.6.15.patch +Patch68: mdadm.c-fix-compile-warning-mdfd-is-uninitialized.patch +Patch69: Revert-mdadm-grow-reshape-would-be-stuck-from-raid1-.patch +Patch70: Retire-mdassemble.patch +Patch71: super1-Clean-up-various-style-abuses.patch +Patch72: mdopen-use-parameters-new_array-to-create-arrays-whe.patch +Patch73: mdadm-manpage-update-manpage-for-readonly-parameter.patch +Patch74: mdadm-manpage-clustered3-arrays-don-t-support-array-s.patch +Patch75: Assemble-Clean1-up-start_array.patch +Patch76: Detail-Remove-pre-2.6-code-for-printing-info-on-rebu.patch +Patch77: Assemble-Remove-obsolete-test-for-kernels1-older-than.patch +Patch78: Detail-Fixup-ugly-if-foo-abuse.patch +Patch79: Query-Handle-error-returned-by-fstat.patch +Patch80: Query-Use-sysfs-to-obtain-data-if-possible.patch +Patch81: sysfs-Parse-array_state-in-sysfs_read.patch +Patch82: util-Introduce6-md_array_active-helper.patch +Patch83: maps-Terminate-modes-map-correctly.patch +Patch84: maps-Use-keyvalue-for-null-terminator-to-indicate-un.patch +Patch85: util-Get-rid-of-unused-enoughfd.patch +Patch86: mdadm-retire-mdassemble-in-make-everything.patch +Patch87: Grow_continue_command-ensure-content-is-properly-ini.patch +Patch88: systemd-mdadm-last-resort-use-ConditionPathExists-in.patch +Patch89: Detail-ensure-export-names-are-acceptable-as-shell-v.patch +Patch90: Query-Quiet-gcc-since-it-cannot-know-errno-0-in-this.patch +Patch91: Makefile-Default-to-O2-optimization1.patch +Patch92: maps-Remove-incorrect-comment-about-strcmp.patch +Patch93: maps-Simplify-implementation-of-map_name.patch +Patch94: Don-t-use-UnSet-with-consistency_policy.patch +Patch95: Detail-determine2-array-state-from-sysfs.patch +Patch96: Detail-Respect-code-lines-are-80-character-wide.patch +Patch97: Detail-Reinstate-support-for-not-having-sysfs.patch +Patch98: Incremental-Use-md_array_active-where-applicable.patch +Patch99: Incremental-Cleanup-some-if-statement-spaghetti.patch +Patch100: Create-tell-udev-md-device-is-not-ready-when-first-c.patch +Patch101: Incremental-Use-md_array_active-to-determine3-state-o.patch +Patch102: Manage-Manage-ro-Use-md_array_active.patch +Patch103: IMSM-Initialize-my_vol_raid_dev_num-during-vol-creat.patch +Patch104: Grow-Grow_continue_command-Avoid-aliasing-array-vari.patch +Patch105: change-back-0644-permission-for-Grow.c.patch +Patch106: util-md_array_valid-Introduce5-md_array_valid-helper.patch +Patch107: kernel-patch-Remove-obsolete-kernel-patches-against-.patch +Patch108: mdassemble-Kill-off-the-last-remains.patch +Patch109: mdadm-util-unify-fstat-checking-blkdev1-into-function.patch +Patch110: mdadm-util-unify-stat-checking-blkdev-into-function.patch +Patch111: Fix-typo2-in-new-udev-rule.patch +Patch112: Incremental-returnis-not-a-function.patch +Patch113: sysfs-sysfs_read-Count-activedisks-and-failed_disks.patch +Patch114: container_members_max-degradation-Switch-to-using-sy.patch +Patch115: IncrementalScan-Use-md_array_active-instead-of-mdge.patch +Patch116: Mention-endian-in-documentation-for-update-byte-orde.patch +Patch117: Monitor-Use-md_array_active-instead-of-manually-fidd.patch +Patch118: Monitor-Code-is-80-characters-per-line.patch +Patch119: mdadm-md.4-set-page-length-as-1000-to-avoid-warnings.patch +Patch120: allow-drives-in-a-container-regardless-of-sector-size.patch +Patch121: allocate-buffer-to-support-maximum-sector-size.patch +Patch122: dont-allow-disks-with-different-sector-sizein-one.patch +Patch123: Allow-more-spare-selection-criteria.patch +Patch124: Add-sector-size-as-spare-selection-criterion.patch +Patch125: Monitor-check_array-Centralize-exit-path.patch +Patch126: Monitor-check_array-reduce-duplicated-error-handling.patch +Patch127: Monitor-check_array-declate-mdinfo-instance-globally.patch +Patch128: Monitor-check_array-Read-sysfs-entry-earlier.patch +Patch129: Monitor-check_array-Obtain-RAID-level-fromsyfs.patch +Patch130: Monitor-check_array-Get-faileddisks-from-sysfs.patch +Patch131: Monitor-check_array-Get-arraydisks-from-sysfs.patch +Patch132: Monitor-check_array-Get-nrdisks-active_disks-and-sp.patch +Patch133: sysfs-sysfs_read-Count-workingdisks.patch +Patch134: Monitor-checkarray-Use-working_disks-from-sysfs.patch +Patch135: Correct-examine-output-for-4kdisks.patch +Patch136: retire-the-APIs-that-driver-nolonger-supports.patch +Patch137: Monitor-Not-much-point-declaring-mdlist-in-both-fork.patch +Patch138: Monitor-mailfrom-is-initialized-correctly.patch +Patch139: Monitor-Fixup-apile-of-whitespace-issues.patch +Patch140: mdadm-Uninitialized-variable-rdev.patch +Patch141: super-ddf-sysfs_read-takes-a-pointer-as-devicename-.patch +Patch142: mdadm-Fixup-a-large-number-of-bad-formatting-of-logi.patch +Patch143: mdadm-Fixup-morebroken-logical-operator-formatting.patch +Patch144: mdadm-Fix-broken-formatting1.patch +Patch145: mdadm-Fixup-broken-formatting2.patch +Patch146: manpage-badblock-support-for-IMSM.patch +Patch147: Detail-don-t-exit-if-ioctl-has-been-successful.patch +Patch148: super1-fix-sb-max_dev-when-adding-a-new-disk-inline.patch +Patch149: md_u-Remove-unused-ioctl-declaration-of-START_ARRAY.patch +Patch150: Grow-set-component-size-prior-to-array-size.patch +Patch151: Get-failed-disk-count-fromarray-state.patch +Patch152: dont-allow-array-geometry-change-with-ppl-enabled.patch +Patch153: dont-allow-to-enable-PPL-reshape-in-progress.patch +Patch154: mdadm-test-Convert-code-formatto-use-Tab.patch +Patch155: mdadm-test-Refactor-and-revamp-test-script.patch +Patch156: mdadm-test-Add-raidtype-to-run-different-raidlevel-c.patch +Patch157: mdadm-test-Add-disks-to-support-testing-phsical-devi.patch +Patch158: Monitor-don-t-assume-mdadm-parameter-is-a-blockdevi.patch +Patch159: super1-Always-round-data-offset-to-1M.patch +Patch160: mdadm-r5cache-allow-adding-journal-to-array-without-.patch +Patch161: Detail-correct-outputfor-active-arrays.patch +Patch162: imsm-rebuild-from-2-disk-RAID10.patch +Patch163: Error-messages-should-end-with-a-newline-character.patch +Patch164: Use-correct-syntax-for-passing-DEVLINKS-to-mdadm-fro.patch +Patch165: super1-only-set-clustered4-flag2-when-bitmap-is-presen.patch +Patch166: Don-t-use-exit-ERANGE.patch +Patch167: Monitor-containers-don-t-have-the-same-sysfs-propert.patch +Patch168: Monitor-Include-containers-in-spare-migration2.patch +Patch169: Detail-differentiate-between-container-and-inactive-.patch +Patch170: mdadm-bitmap-examine-bitmap-failed1-when-bitmap-is-ex.patch +Patch171: mdadm-install-twomore-udev-rules-in-mdadm.spec.patch +Patch172: mdadm-set-journal_clean-after-scanning-all-disks.patch +Patch173: lib-devid2kname-should-take-a-dev_t.patch +Patch174: sysfs_init_dev-takea-dev_t-argument.patch +Patch175: Manage-subdevs-Use-a-dev_t.patch +Patch176: util-Code-is-80-characterswide.patch +#The above patches are backported from RHEL7.5 upstream rebase +Patch177: Don-t-abort-starting-the-array-if-kernel-does-not-su.patch +Patch178: super1add-support-for-multiple-ppls.patch +Patch179: imsmadd-support-for-multiple-ppls.patch +Patch180: imsm-validate-multiple-ppls-during-assemble.patch +Patch181: Zeroout-whole-ppl-space-during-creation-force-assemb.patch +Patch182: imsm-switch-to-multiple-ppls-automatically-during-as.patch +Patch183: Grow-fix-switching-on-PPL-during-recovery.patch +Patch184: imsm-don-t-skip-resync-when-an-invalid-ppl-header-is.patch +Patch185: imsm-Write-empty-PPL-header-if-assembling-regular-cl.patch +Patch186: imsm-always-do-ppl-recovery-when-starting-a-rebuildi.patch +Patch187: imsm-use-correct-map-when-validating-ppl.patch +Patch188: imsm-write-initial-ppl-on-a-disk-added-for-rebuild.patch +Patch189: mdmon-get-safe-mode-delay-file.patch +Patch190: imsm-continue-resync-on-3disk-RAID10.patch +Patch191: imsm-Set-disk-slot-number.patch +Patch192: managemon-Dont-add-disk-to-the-array-after-it.patch +Patch193: Avoid-to-take-spare-without-defined-domain-by-imsm.patch +Patch194: stop-previous-reshape-process-first.patch # RHEL customization patches -Patch95: mdadm-3.4-udev-race.patch -Patch96: mdadm-3.3.2-skip-rules.patch -Patch97: mdadm-3.3-udev.patch -Patch98: mdadm-2.5.2-static.patch -Patch99: disable-journal.patch +Patch195: mdadm-3.4-udev-race.patch +Patch196: mdadm-3.3.2-skip-rules.patch +Patch197: mdadm-3.3-udev.patch +Patch198: mdadm-2.5.2-static.patch +Patch199: disable-journal.patch URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ Group: System Environment/Base @@ -51,7 +229,7 @@ Requires: libreport-filesystem %define _hardened_build 1 -%description +%description The mdadm program is used to create, manage, and monitor Linux MD (software RAID) devices. As such, it provides similar functionality to the raidtools package. However, mdadm is a single program, and it can perform @@ -61,30 +239,207 @@ file can be used to help with some common tasks. %prep %setup -q -%patch1 -p1 -b .symlinks -%patch2 -p1 -b .specify -%patch3 -p1 -b .generic -%patch4 -p1 -b .detail -%patch5 -p1 -b .imsmppl -%patch6 -p1 -b .super1 -%patch7 -p1 -b .options -%patch8 -p1 -b .change -%patch9 -p1 -b .rounded -%patch10 -p1 -b .regardless -%patch11 -p1 -b .maximum -%patch12 -p1 -b .different -%patch13 -p1 -b .criteria -%patch14 -p1 -b .criterion -%patch15 -p1 -b .output -%patch16 -p1 -b .pplgeometry -%patch17 -p1 -b .pplreshape +%patch1 -p1 -b .ISO +%patch2 -p1 -b .migration1 +%patch3 -p1 -b .oddity +%patch4 -p1 -b .typo1 +%patch5 -p1 -b .clustered1 +%patch6 -p1 -b .tidy +%patch7 -p1 -b .symlinks +%patch8 -p1 -b .clustered2 +%patch9 -p1 -b .Wimplicit +%patch10 -p1 -b .specify +%patch11 -p1 -b .trivial +%patch12 -p1 -b .twice +%patch13 -p1 -b .invoked +%patch14 -p1 -b .dereference +%patch15 -p1 -b .Replace +%patch16 -p1 -b .Forced +%patch17 -p1 -b .ignore +%patch18 -p1 -b .comments1 +%patch19 -p1 -b .assembly +%patch20 -p1 -b .Retry +%patch21 -p1 -b .Build1 +%patch22 -p1 -b .Introduce1 +%patch23 -p1 -b .force +%patch24 -p1 -b .existent +%patch25 -p1 -b .generic +%patch26 -p1 -b .detail +%patch27 -p1 -b .imsmppl +%patch28 -p1 -b .super1ppl +%patch29 -p1 -b .options +%patch30 -p1 -b .policy1 +%patch31 -p1 -b .reorganize +%patch32 -p1 -b .hard +%patch33 -p1 -b .multiple +%patch34 -p1 -b .inconsistency +%patch35 -p1 -b .Cosmetic +%patch36 -p1 -b .cosmetic +%patch37 -p1 -b .Introduce2 +%patch38 -p1 -b .redundant +%patch39 -p1 -b .Introduce3 +%patch40 -p1 -b .Introduce4 +%patch41 -p1 -b .declarations +%patch42 -p1 -b .unnecessary +%patch43 -p1 -b .shadow +%patch44 -p1 -b .would1 +%patch45 -p1 -b .rounded +%patch46 -p1 -b .switch +%patch47 -p1 -b .presence +%patch48 -p1 -b .Make +%patch49 -p1 -b .declaring1 +%patch50 -p1 -b .multi +%patch51 -p1 -b .issues1 +%patch52 -p1 -b .container1 +%patch53 -p1 -b .versi +%patch54 -p1 -b .ver +%patch55 -p1 -b .Build2 +%patch56 -p1 -b .versions +%patch57 -p1 -b .bothering1 +%patch58 -p1 -b .attemps +%patch59 -p1 -b .references1 +%patch60 -p1 -b .references +%patch61 -p1 -b .version1 +%patch62 -p1 -b .version2 +%patch63 -p1 -b .determine1 +%patch64 -p1 -b .valid +%patch65 -p1 -b .vers +%patch66 -p1 -b .Finally +%patch67 -p1 -b .kernels +%patch68 -p1 -b .uninitialized +%patch69 -p1 -b .Revert +%patch70 -p1 -b .Retire +%patch71 -p1 -b .abuses +%patch72 -p1 -b .parameters +%patch73 -p1 -b .readonly +%patch74 -p1 -b .clustered3 +%patch75 -p1 -b .Clean1 +%patch76 -p1 -b .pre +%patch77 -p1 -b .kernels1 +%patch78 -p1 -b .abuse +%patch79 -p1 -b .Handle +%patch80 -p1 -b .obtain +%patch81 -p1 -b .Parse +%patch82 -p1 -b .Introduce6 +%patch83 -p1 -b .Terminate +%patch84 -p1 -b .keyvalue +%patch85 -p1 -b .enoughfd +%patch86 -p1 -b .everything +%patch87 -p1 -b .ini +%patch88 -p1 -b .ConditionPathExists +%patch89 -p1 -b .export +%patch90 -p1 -b .Quiet +%patch91 -p1 -b .optimization1 +%patch92 -p1 -b .incorrect +%patch93 -p1 -b .implementation +%patch94 -p1 -b .UnSet +%patch95 -p1 -b .determine2 +%patch96 -p1 -b .Respect +%patch97 -p1 -b .Reinstate +%patch98 -p1 -b .applicable +%patch99 -p1 -b .Cleanup +%patch100 -p1 -b .first +%patch101 -p1 -b .determine3 +%patch102 -p1 -b .ro +%patch103 -p1 -b .Initialize +%patch104 -p1 -b .vari +%patch105 -p1 -b .back +%patch106 -p1 -b .Introduce5 +%patch107 -p1 -b .against +%patch108 -p1 -b .remains +%patch109 -p1 -b .blkdev1 +%patch110 -p1 -b .blkdev +%patch111 -p1 -b .typo2 +%patch112 -p1 -b .returnis +%patch113 -p1 -b .activedisks +%patch114 -p1 -b .degradation +%patch115 -p1 -b .mdge +%patch116 -p1 -b .orde +%patch117 -p1 -b .fidd +%patch118 -p1 -b .characters +%patch119 -p1 -b .warnings +%patch120 -p1 -b .regardless +%patch121 -p1 -b .allocate +%patch122 -p1 -b .sizein +%patch123 -p1 -b .criteria +%patch124 -p1 -b .criterion +%patch125 -p1 -b .Centralize +%patch126 -p1 -b .reduce +%patch127 -p1 -b .declate +%patch128 -p1 -b .earlier +%patch129 -p1 -b .fromsyfs +%patch130 -p1 -b .faileddisks +%patch131 -p1 -b .arraydisks +%patch132 -p1 -b .nrdisks +%patch133 -p1 -b .workingdisks +%patch134 -p1 -b .checkarray +%patch135 -p1 -b .4kdisks +%patch136 -p1 -b .nolonger +%patch137 -p1 -b .fork +%patch138 -p1 -b .mailfrom +%patch139 -p1 -b .apile +%patch140 -p1 -b .rdev +%patch141 -p1 -b .devicename +%patch142 -p1 -b .logi +%patch143 -p1 -b .morebroken +%patch144 -p1 -b .formatting1 +%patch145 -p1 -b .formatting2 +%patch146 -p1 -b .badblock +%patch147 -p1 -b .successful +%patch148 -p1 -b .inline +%patch149 -p1 -b .declaration +%patch150 -p1 -b .prior +%patch151 -p1 -b .fromarray +%patch152 -p1 -b .pplgeometry +%patch153 -p1 -b .pplreshape +%patch154 -p1 -b .formatto +%patch155 -p1 -b .revamp +%patch156 -p1 -b .raidlevel +%patch157 -p1 -b .phsical +%patch158 -p1 -b .blockdevi +%patch159 -p1 -b .offset +%patch160 -p1 -b .without +%patch161 -p1 -b .outputfor +%patch162 -p1 -b .rebuild +%patch163 -p1 -b .newline +%patch164 -p1 -b .fro +%patch165 -p1 -b .flag2 +%patch166 -p1 -b .ERANGE +%patch167 -p1 -b .propert +%patch168 -p1 -b .migration2 +%patch169 -p1 -b .differentiate +%patch170 -p1 -b .failed1 +%patch171 -p1 -b .twomore +%patch172 -p1 -b .scanning +%patch173 -p1 -b .devid2kname +%patch174 -p1 -b .takea +%patch175 -p1 -b .subdevs +%patch176 -p1 -b .characterswide +%patch177 -p1 -b .abort +%patch178 -p1 -b .super1add +%patch179 -p1 -b .imsmadd +%patch180 -p1 -b .validate +%patch181 -p1 -b .Zeroout +%patch182 -p1 -b .automatically +%patch183 -p1 -b .switching +%patch184 -p1 -b .invalid +%patch185 -p1 -b .assembling +%patch186 -p1 -b .rebuildi +%patch187 -p1 -b .validating +%patch188 -p1 -b .initial +%patch189 -p1 -b .safe +%patch190 -p1 -b .3disk +%patch191 -p1 -b .slot +%patch192 -p1 -b .Dont +%patch193 -p1 -b .defined +%patch194 -p1 -b .previous # RHEL customization patches -%patch95 -p1 -b .race -%patch96 -p1 -b .rules -%patch97 -p1 -b .udev -%patch98 -p1 -b .static -%patch99 -p1 -b .journal +%patch195 -p1 -b .race +%patch196 -p1 -b .rules +%patch197 -p1 -b .udev +%patch198 -p1 -b .static +%patch199 -p1 -b .disable %build make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon @@ -146,13 +501,45 @@ rm -rf %{buildroot} /etc/libreport/events.d/* %changelog +* Wed Feb 07 2018 Xiao Ni - 4.0-13 +- stop previous reshape process first +- Resolves rhbz#1507415 + +* Wed Jan 31 2018 Xiao Ni - 4.0-12 +- Don't take spare without defined domain by imsm +- Resolves rhbz#1535436 + +* Fri Jan 12 2018 Xiao Ni - 4.0-11 +- Fix some IMSM bugs +- Resolves rhbz#1507439 rhbz#1516800 rhbz#1528267 + +* Mon Dec 11 2017 Xiao Ni - 4.0-10 +- Disable raid5 journal function +- Resolves rhbz#1518477 + +* Fri Nov 03 2017 Xiao Ni - 4.0-9 +- Enable raid5 journal function +- Resolves rhbz1505611 + +* Fri Nov 03 2017 Xiao Ni - 4.0-8 +- Support for multiple-ppl in mdadm +- Resolves rhbz#1500638 + +* Fri Nov 03 2017 Xiao Ni - 4.0-7 +- Support adding flags for mdmonitor.service +- Resolves rhbz#1320018 + +* Mon Sep 18 2017 Xiao Ni - 4.0-6 +- Update to the latest upstream +- Resolves rhbz#1455936 + * Mon Jun 12 2017 Nigel Croxon - 4.0-5 - RAID array grow not blocked when PPL is enabled - Resolves rhbz#1460141 * Wed May 31 2017 Xiao Ni - 4.0-4 -- Imsm should not allow combing 512 and 4096 sector size disks in - one volume and Wrong array size shown for array built on 4096 +- Imsm should not allow combing 512 and 4096 sector size disks in + one volume and Wrong array size shown for array built on 4096 sector size disks - Resolves rhbz#1454390 and rhbz#1454379 @@ -178,7 +565,7 @@ rm -rf %{buildroot} these can show up with a valid size of 0. Work around this to only exit for non container arrays. - Resolves rhbz#1379194 - + * Wed Sep 14 2016 Jes Sorensen - 3.4-13 - Make udev-md-array-arrays.rules more resilient to races if arrays are assembled and stopped and reassembled quick after each other. @@ -225,7 +612,7 @@ rm -rf %{buildroot} - Resolves rhbz#1324637 * Thu Apr 28 2016 Xiao Ni - 3.4-3 -- Fix Degraded Raid1 array becomes inactive after rebooting +- Fix Degraded Raid1 array becomes inactive after rebooting - Resolves rhbz#1290494 * Tue Mar 1 2016 Jes Sorensen - 3.4-2 @@ -312,7 +699,7 @@ rm -rf %{buildroot} * Thu Oct 10 2013 Jes Sorensen - 3.2.6-22 - Check for DM_UDEV_DISABLE_OTHER_RULES_FLAG instead of - DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules + DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules - Resolves bz1015515 * Thu Aug 29 2013 Jes Sorensen - 3.2.6-21 @@ -323,7 +710,7 @@ rm -rf %{buildroot} * Wed Apr 24 2013 Jes Sorensen - 3.2.6-19 - Fix problem where rebuild of IMSM RAID5 volume started in OROM, - does not proceed in OS + does not proceed in OS - Resolves bz956021 (f18), bz956026 (f17), bz956031 (f19) * Tue Apr 23 2013 Jes Sorensen - 3.2.6-18 @@ -436,7 +823,7 @@ rm -rf %{buildroot} * Wed Jul 18 2012 Karsten Hopp 3.2.5-5 - include in some to avoid type clashes. - same problem as rhbz #840902 + same problem as rhbz #840902 * Mon Jul 16 2012 Jes Sorensen - 3.2.5-4 - Move /etc/tmpfiles.d/mdadm.conf to /lib/tmpfiles.d/ to comply with @@ -511,7 +898,7 @@ rm -rf %{buildroot} * Thu Feb 16 2012 Jes Sorensen - 3.2.3-5 - Fix issue with devices failing to be added to a raid using bitmaps, due to trying to write the bitmap with mis-aligned buffers using - O_DIRECT + O_DIRECT - Resolves: bz789898 (f16) bz791189 (f15) * Mon Jan 30 2012 Jes Sorensen - 3.2.3-4 @@ -811,7 +1198,7 @@ rm -rf %{buildroot} - Modify mdadm to put its mapfile in /dev/md instead of /var/run/mdadm since at startup /var/run/mdadm is read-only by default and this breaks incremental assembly -- Change how mdadm decides to assemble incremental devices using their +- Change how mdadm decides to assemble incremental devices using their preferred name or a random name to avoid possible conflicts when plugging a foreign array into a host @@ -866,7 +1253,7 @@ rm -rf %{buildroot} * Thu Apr 17 2008 Bill Nottingham - 2.6.4-4 - make /dev/md if necessary in incremental mode (#429604) - open RAID devices with O_EXCL to avoid racing against other --incremental processes (#433932) - + * Fri Feb 1 2008 Bill Nottingham - 2.6.4-3 - add a udev rules file for device assembly (#429604)