diff --git a/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch b/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch new file mode 100644 index 0000000..17510de --- /dev/null +++ b/SOURCES/0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch @@ -0,0 +1,39 @@ +From 0833f9c3dbaaee202b92ea956f9e2decc7b9593a Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Tue, 6 Nov 2018 15:27:42 +0100 +Subject: [RHEL7.7 PATCH 01/24] Assemble: keep MD_DISK_FAILFAST and + MD_DISK_WRITEMOSTLY flag + +Before updating superblock of slave disks, desired_state value +is set for the target state of the slave disks. But it forgets +to check MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY flags. Then +start_arrays() calls ADD_NEW_DISK ioctl-call and pass the state +without MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY. + +Currenlty it does not generate any problem because kernel does not +care MD_DISK_FAILFAST or MD_DISK_WRITEMOSTLY flags. + +Reviewed-by: NeilBrown +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + Assemble.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/Assemble.c b/Assemble.c +index a79466c..f39c9e1 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1704,6 +1704,9 @@ try_again: + else + desired_state = (1< +Date: Fri, 9 Nov 2018 17:12:33 +1100 +Subject: [RHEL7.7 PATCH 02/24] Document PART-POLICY lines + +PART-POLICY has been accepted in mdadm.conf since the same +time that POLICY was accepted, but it was never documented. +So add the missing documentation. + +Also fix a bug which would have stopped it from working if +anyone had ever tried to use it. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + mdadm.conf.5 | 24 +++++++++++++++++++++++- + policy.c | 2 +- + 2 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/mdadm.conf.5 b/mdadm.conf.5 +index 18512cb..47c962a 100644 +--- a/mdadm.conf.5 ++++ b/mdadm.conf.5 +@@ -501,7 +501,7 @@ To update hot plug configuration it is necessary to execute + .B mdadm \-\-udev\-rules + command after changing the config file + +-Key words used in the ++Keywords used in the + .I POLICY + line and supported values are: + +@@ -565,6 +565,28 @@ be automatically added to that array (or it's container) + as above and the disk will become a spare in remaining cases + .RE + ++.TP ++.B PART-POLICY ++This is similar to ++.B POLICY ++and accepts the same keyword assignments. It allows a consistent set ++of policies to applied to each of the partitions of a device. ++ ++A ++.B PART-POLICY ++line should set ++.I type=disk ++and identify the path to one or more disk devices. Each partition on ++these disks will be treated according to the ++.I action= ++setting from this line. If a ++.I domain ++is set in the line, then the domain associated with each patition will ++be based on the domain, but with ++.RB \(dq -part N\(dq ++appended, when N is the partition number for the partition that was ++found. ++ + .SH EXAMPLE + DEVICE /dev/sd[bcdjkl]1 + .br +diff --git a/policy.c b/policy.c +index c0d18a7..258f393 100644 +--- a/policy.c ++++ b/policy.c +@@ -300,7 +300,7 @@ static int path_has_part(char *path, char **part) + l--; + if (l < 5 || strncmp(path+l-5, "-part", 5) != 0) + return 0; +- *part = path+l-4; ++ *part = path+l-5; + return 1; + } + +-- +2.7.5 + diff --git a/SOURCES/0003-policy-support-devices-with-multiple-paths.patch b/SOURCES/0003-policy-support-devices-with-multiple-paths.patch new file mode 100644 index 0000000..d4ffe1b --- /dev/null +++ b/SOURCES/0003-policy-support-devices-with-multiple-paths.patch @@ -0,0 +1,334 @@ +From cd72f9d114da206baa01fd56ff2d8ffcc08f3239 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 9 Nov 2018 17:12:33 +1100 +Subject: [RHEL7.7 PATCH 03/24] policy: support devices with multiple paths. + +As new releases of Linux some time change the name of +a path, some distros keep "legacy" names as well. This +is useful, but confuses mdadm which assumes each device has +precisely one path. + +So change this assumption: allow a disk to have several +paths, and allow any to match when looking for a policy +which matches a disk. + +Reported-and-tested-by: Mariusz Tkaczyk +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Incremental.c | 5 +- + mdadm.h | 2 +- + policy.c | 163 ++++++++++++++++++++++++++++++++-------------------------- + 3 files changed, 95 insertions(+), 75 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index a4ff7d4..d4d3c35 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1080,6 +1080,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + struct supertype *st2 = NULL; + char *devname = NULL; + unsigned long long devsectors; ++ char *pathlist[2]; + + if (de->d_ino == 0 || de->d_name[0] == '.' || + (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN)) +@@ -1094,7 +1095,9 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, + /* This is a partition - skip it */ + goto next; + +- pol2 = path_policy(de->d_name, type_disk); ++ pathlist[0] = de->d_name; ++ pathlist[1] = NULL; ++ pol2 = path_policy(pathlist, type_disk); + + domain_merge(&domlist, pol2, st ? st->ss->name : NULL); + if (domain_test(domlist, pol, st ? st->ss->name : NULL) != 1) +diff --git a/mdadm.h b/mdadm.h +index 387e681..705bd9b 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1247,7 +1247,7 @@ extern void policyline(char *line, char *type); + extern void policy_add(char *type, ...); + extern void policy_free(void); + +-extern struct dev_policy *path_policy(char *path, char *type); ++extern struct dev_policy *path_policy(char **paths, char *type); + extern struct dev_policy *disk_policy(struct mdinfo *disk); + extern struct dev_policy *devid_policy(int devid); + extern void dev_policy_free(struct dev_policy *p); +diff --git a/policy.c b/policy.c +index 258f393..fa67d55 100644 +--- a/policy.c ++++ b/policy.c +@@ -189,15 +189,17 @@ struct dev_policy *pol_find(struct dev_policy *pol, char *name) + return pol; + } + +-static char *disk_path(struct mdinfo *disk) ++static char **disk_paths(struct mdinfo *disk) + { + struct stat stb; + int prefix_len; + DIR *by_path; + char symlink[PATH_MAX] = "/dev/disk/by-path/"; +- char nm[PATH_MAX]; ++ char **paths; ++ int cnt = 0; + struct dirent *ent; +- int rv; ++ ++ paths = xmalloc(sizeof(*paths) * (cnt+1)); + + by_path = opendir(symlink); + if (by_path) { +@@ -214,22 +216,13 @@ static char *disk_path(struct mdinfo *disk) + continue; + if (stb.st_rdev != makedev(disk->disk.major, disk->disk.minor)) + continue; +- closedir(by_path); +- return xstrdup(ent->d_name); ++ paths[cnt++] = xstrdup(ent->d_name); ++ paths = xrealloc(paths, sizeof(*paths) * (cnt+1)); + } + closedir(by_path); + } +- /* A NULL path isn't really acceptable - use the devname.. */ +- sprintf(symlink, "/sys/dev/block/%d:%d", disk->disk.major, disk->disk.minor); +- rv = readlink(symlink, nm, sizeof(nm)-1); +- if (rv > 0) { +- char *dname; +- nm[rv] = 0; +- dname = strrchr(nm, '/'); +- if (dname) +- return xstrdup(dname + 1); +- } +- return xstrdup("unknown"); ++ paths[cnt] = NULL; ++ return paths; + } + + char type_part[] = "part"; +@@ -246,18 +239,53 @@ static char *disk_type(struct mdinfo *disk) + return type_disk; + } + +-static int pol_match(struct rule *rule, char *path, char *type) ++static int path_has_part(char *path, char **part) ++{ ++ /* check if path ends with "-partNN" and ++ * if it does, place a pointer to "-pathNN" ++ * in 'part'. ++ */ ++ int l; ++ if (!path) ++ return 0; ++ l = strlen(path); ++ while (l > 1 && isdigit(path[l-1])) ++ l--; ++ if (l < 5 || strncmp(path+l-5, "-part", 5) != 0) ++ return 0; ++ *part = path+l-5; ++ return 1; ++} ++ ++static int pol_match(struct rule *rule, char **paths, char *type, char **part) + { +- /* check if this rule matches on path and type */ ++ /* Check if this rule matches on any path and type. ++ * If 'part' is not NULL, then 'path' must end in -partN, which ++ * we ignore for matching, and return in *part on success. ++ */ + int pathok = 0; /* 0 == no path, 1 == match, -1 == no match yet */ + int typeok = 0; + +- while (rule) { ++ for (; rule; rule = rule->next) { + if (rule->name == rule_path) { ++ char *p; ++ int i; + if (pathok == 0) + pathok = -1; +- if (path && fnmatch(rule->value, path, 0) == 0) +- pathok = 1; ++ if (!paths) ++ continue; ++ for (i = 0; paths[i]; i++) { ++ if (part) { ++ if (!path_has_part(paths[i], &p)) ++ continue; ++ *p = '\0'; ++ *part = p+1; ++ } ++ if (fnmatch(rule->value, paths[i], 0) == 0) ++ pathok = 1; ++ if (part) ++ *p = '-'; ++ } + } + if (rule->name == rule_type) { + if (typeok == 0) +@@ -265,7 +293,6 @@ static int pol_match(struct rule *rule, char *path, char *type) + if (type && strcmp(rule->value, type) == 0) + typeok = 1; + } +- rule = rule->next; + } + return pathok >= 0 && typeok >= 0; + } +@@ -286,24 +313,6 @@ static void pol_merge(struct dev_policy **pol, struct rule *rule) + pol_new(pol, r->name, r->value, metadata); + } + +-static int path_has_part(char *path, char **part) +-{ +- /* check if path ends with "-partNN" and +- * if it does, place a pointer to "-pathNN" +- * in 'part'. +- */ +- int l; +- if (!path) +- return 0; +- l = strlen(path); +- while (l > 1 && isdigit(path[l-1])) +- l--; +- if (l < 5 || strncmp(path+l-5, "-part", 5) != 0) +- return 0; +- *part = path+l-5; +- return 1; +-} +- + static void pol_merge_part(struct dev_policy **pol, struct rule *rule, char *part) + { + /* copy any name assignments from rule into pol, appending +@@ -352,7 +361,7 @@ static int config_rules_has_path = 0; + * path_policy() gathers policy information for the + * disk described in the given a 'path' and a 'type'. + */ +-struct dev_policy *path_policy(char *path, char *type) ++struct dev_policy *path_policy(char **paths, char *type) + { + struct pol_rule *rules; + struct dev_policy *pol = NULL; +@@ -361,27 +370,24 @@ struct dev_policy *path_policy(char *path, char *type) + rules = config_rules; + + while (rules) { +- char *part; ++ char *part = NULL; + if (rules->type == rule_policy) +- if (pol_match(rules->rule, path, type)) ++ if (pol_match(rules->rule, paths, type, NULL)) + pol_merge(&pol, rules->rule); + if (rules->type == rule_part && strcmp(type, type_part) == 0) +- if (path_has_part(path, &part)) { +- *part = 0; +- if (pol_match(rules->rule, path, type_disk)) +- pol_merge_part(&pol, rules->rule, part+1); +- *part = '-'; +- } ++ if (pol_match(rules->rule, paths, type_disk, &part)) ++ pol_merge_part(&pol, rules->rule, part); + rules = rules->next; + } + + /* Now add any metadata-specific internal knowledge + * about this path + */ +- for (i=0; path && superlist[i]; i++) ++ for (i=0; paths[0] && superlist[i]; i++) + if (superlist[i]->get_disk_controller_domain) { + const char *d = +- superlist[i]->get_disk_controller_domain(path); ++ superlist[i]->get_disk_controller_domain( ++ paths[0]); + if (d) + pol_new(&pol, pol_domain, d, superlist[i]->name); + } +@@ -400,22 +406,34 @@ void pol_add(struct dev_policy **pol, + pol_dedup(*pol); + } + ++static void free_paths(char **paths) ++{ ++ int i; ++ ++ if (!paths) ++ return; ++ ++ for (i = 0; paths[i]; i++) ++ free(paths[i]); ++ free(paths); ++} ++ + /* + * disk_policy() gathers policy information for the + * disk described in the given mdinfo (disk.{major,minor}). + */ + struct dev_policy *disk_policy(struct mdinfo *disk) + { +- char *path = NULL; ++ char **paths = NULL; + char *type = disk_type(disk); + struct dev_policy *pol = NULL; + + if (config_rules_has_path) +- path = disk_path(disk); ++ paths = disk_paths(disk); + +- pol = path_policy(path, type); ++ pol = path_policy(paths, type); + +- free(path); ++ free_paths(paths); + return pol; + } + +@@ -756,27 +774,26 @@ int policy_check_path(struct mdinfo *disk, struct map_ent *array) + { + char path[PATH_MAX]; + FILE *f = NULL; +- char *id_path = disk_path(disk); +- int rv; ++ char **id_paths = disk_paths(disk); ++ int i; ++ int rv = 0; + +- if (!id_path) +- return 0; ++ for (i = 0; id_paths[i]; i++) { ++ snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_paths[i]); ++ f = fopen(path, "r"); ++ if (!f) ++ continue; + +- snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path); +- f = fopen(path, "r"); +- if (!f) { +- free(id_path); +- return 0; ++ rv = fscanf(f, " %s %x:%x:%x:%x\n", ++ array->metadata, ++ array->uuid, ++ array->uuid+1, ++ array->uuid+2, ++ array->uuid+3); ++ fclose(f); ++ break; + } +- +- rv = fscanf(f, " %s %x:%x:%x:%x\n", +- array->metadata, +- array->uuid, +- array->uuid+1, +- array->uuid+2, +- array->uuid+3); +- fclose(f); +- free(id_path); ++ free_paths(id_paths); + return rv == 5; + } + +-- +2.7.5 + diff --git a/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch b/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch new file mode 100644 index 0000000..97e1f6f --- /dev/null +++ b/SOURCES/0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch @@ -0,0 +1,137 @@ +From 4199d3c629c14866505923d19fa50017ee92d2e1 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 5 Dec 2018 16:35:00 +1100 +Subject: [RHEL7.7 PATCH 04/24] mdcheck: add systemd unit files to run mdcheck. + +Having the mdcheck script is not use if is never run. +This patch adds systemd unit files so that it can easily +be run on the first Sunday of each month for 6 hours, +then on every subsequent morning until the check is +finished. + +The units still need to be enabled with + systemctl enable mdcheck_start.timer + +The timer will only actually be started when an array +which might need it becomes active. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Makefile | 5 ++++- + systemd/mdcheck_continue.service | 18 ++++++++++++++++++ + systemd/mdcheck_continue.timer | 13 +++++++++++++ + systemd/mdcheck_start.service | 17 +++++++++++++++++ + systemd/mdcheck_start.timer | 15 +++++++++++++++ + 5 files changed, 67 insertions(+), 1 deletion(-) + create mode 100644 systemd/mdcheck_continue.service + create mode 100644 systemd/mdcheck_continue.timer + create mode 100644 systemd/mdcheck_start.service + create mode 100644 systemd/mdcheck_start.timer + +diff --git a/Makefile b/Makefile +index 2767ac6..afb62cc 100644 +--- a/Makefile ++++ b/Makefile +@@ -276,7 +276,10 @@ install-udev: udev-md-raid-arrays.rules udev-md-raid-assembly.rules udev-md-raid + + install-systemd: systemd/mdmon@.service + @for file in mdmon@.service mdmonitor.service mdadm-last-resort@.timer \ +- mdadm-last-resort@.service mdadm-grow-continue@.service; \ ++ mdadm-last-resort@.service mdadm-grow-continue@.service \ ++ mdcheck_start.timer mdcheck_start.service \ ++ mdcheck_continue.timer mdcheck_continue.service \ ++ ; \ + do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp.2 && \ + $(ECHO) $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \ + $(INSTALL) -D -m 644 .install.tmp.2 $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \ +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +new file mode 100644 +index 0000000..592c607 +--- /dev/null ++++ b/systemd/mdcheck_continue.service +@@ -0,0 +1,18 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=MD array scrubbing - continuation ++ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* ++ ++[Service] ++Type=oneshot ++Environment= MDADM_CHECK_DURATION='"6 hours"' ++EnvironmentFile=-/run/sysconfig/mdadm ++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStart=/usr/share/mdadm/mdcheck --continue --duration $MDADM_CHECK_DURATION ++ +diff --git a/systemd/mdcheck_continue.timer b/systemd/mdcheck_continue.timer +new file mode 100644 +index 0000000..3ccfd78 +--- /dev/null ++++ b/systemd/mdcheck_continue.timer +@@ -0,0 +1,13 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=MD array scrubbing - continuation ++ ++[Timer] ++OnCalendar= 1:05:00 ++ +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +new file mode 100644 +index 0000000..812141b +--- /dev/null ++++ b/systemd/mdcheck_start.service +@@ -0,0 +1,17 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=MD array scrubbing ++Wants=mdcheck_continue.timer ++ ++[Service] ++Type=oneshot ++Environment= MDADM_CHECK_DURATION='"6 hours"' ++EnvironmentFile=-/run/sysconfig/mdadm ++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStart=/usr/share/mdadm/mdcheck --duration $MDADM_CHECK_DURATION +diff --git a/systemd/mdcheck_start.timer b/systemd/mdcheck_start.timer +new file mode 100644 +index 0000000..6480736 +--- /dev/null ++++ b/systemd/mdcheck_start.timer +@@ -0,0 +1,15 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=MD array scrubbing ++ ++[Timer] ++OnCalendar=Sun *-*-1..7 1:00:00 ++ ++[Install] ++WantedBy= mdmonitor.service +-- +2.7.5 + diff --git a/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch b/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch new file mode 100644 index 0000000..1cbf255 --- /dev/null +++ b/SOURCES/0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch @@ -0,0 +1,83 @@ +From 7cd7e91ab3de5aa75dc963cb08b0618c1885cf0d Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 5 Dec 2018 16:35:00 +1100 +Subject: [RHEL7.7 PATCH 05/24] Monitor: add system timer to run --oneshot + periodically + +"mdadm --monitor --oneshot" can be used to get a warning +if there are any degraded arrays. It can be helpful to get +this warning periodically while the condition persists. + +This patch add a systemd service and timer which can +be enabled with + systemctl enable mdmonitor-oneshot.service + +and will then provide daily warnings. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Makefile | 1 + + systemd/mdmonitor-oneshot.service | 15 +++++++++++++++ + systemd/mdmonitor-oneshot.timer | 15 +++++++++++++++ + 3 files changed, 31 insertions(+) + create mode 100644 systemd/mdmonitor-oneshot.service + create mode 100644 systemd/mdmonitor-oneshot.timer + +diff --git a/Makefile b/Makefile +index afb62cc..dfe00b0 100644 +--- a/Makefile ++++ b/Makefile +@@ -279,6 +279,7 @@ install-systemd: systemd/mdmon@.service + mdadm-last-resort@.service mdadm-grow-continue@.service \ + mdcheck_start.timer mdcheck_start.service \ + mdcheck_continue.timer mdcheck_continue.service \ ++ mdmonitor-oneshot.timer mdmonitor-oneshot.service \ + ; \ + do sed -e 's,BINDIR,$(BINDIR),g' systemd/$$file > .install.tmp.2 && \ + $(ECHO) $(INSTALL) -D -m 644 systemd/$$file $(DESTDIR)$(SYSTEMD_DIR)/$$file ; \ +diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service +new file mode 100644 +index 0000000..fd469b1 +--- /dev/null ++++ b/systemd/mdmonitor-oneshot.service +@@ -0,0 +1,15 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=Reminder for degraded MD arrays ++ ++[Service] ++Environment= MDADM_MONITOR_ARGS=--scan ++EnvironmentFile=-/run/sysconfig/mdadm ++ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh ++ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS +diff --git a/systemd/mdmonitor-oneshot.timer b/systemd/mdmonitor-oneshot.timer +new file mode 100644 +index 0000000..cb54bda +--- /dev/null ++++ b/systemd/mdmonitor-oneshot.timer +@@ -0,0 +1,15 @@ ++# This file is part of mdadm. ++# ++# mdadm 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. ++ ++[Unit] ++Description=Reminder for degraded MD arrays ++ ++[Timer] ++OnCalendar= 2:00:00 ++ ++[Install] ++WantedBy= mdmonitor.service +-- +2.7.5 + diff --git a/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch b/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch new file mode 100644 index 0000000..567a277 --- /dev/null +++ b/SOURCES/0006-imsm-update-metadata-correctly-while-raid10-double-d.patch @@ -0,0 +1,83 @@ +From d7a1fda2769ba272d89de6caeab35d52b73a9c3c Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 17 Oct 2018 12:11:41 +0200 +Subject: [RHEL7.7 PATCH 06/24] imsm: update metadata correctly while raid10 + double degradation + +Mdmon calls end_migration() when map state changes from normal to +degraded. It is not valid because in raid 10 double degradation case +mdmon breaks checkpointing but array is still rebuilding. +In this case mdmon has to mark map as degraded and continues marking +recovery checkpoint in metadata. Migration can be finished only if newly +failed device is a rebuilding device. + +Add catching double degraded to degraded transition. Migration is +finished but map state doesn't change, array is still degraded. + +Update failed_disk_num correctly. If double degradation +happens rebuild will start on the lowest slot, but this variable points +to the first failed slot. If second fail happens while rebuild this +variable shouldn't be updated until rebuild is not finished. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + super-intel.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 6438987..d2035cc 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8136,7 +8136,8 @@ static int mark_failure(struct intel_super *super, + set_imsm_ord_tbl_ent(map2, slot2, + idx | IMSM_ORD_REBUILD); + } +- if (map->failed_disk_num == 0xff) ++ if (map->failed_disk_num == 0xff || ++ (!is_rebuilding(dev) && map->failed_disk_num > slot)) + map->failed_disk_num = slot; + + clear_disk_badblocks(super->bbm_log, ord_to_idx(ord)); +@@ -8558,13 +8559,25 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + break; + } + if (is_rebuilding(dev)) { +- dprintf_cont("while rebuilding."); ++ dprintf_cont("while rebuilding "); + if (map->map_state != map_state) { +- dprintf_cont(" Map state change"); +- end_migration(dev, super, map_state); ++ dprintf_cont("map state change "); ++ if (n == map->failed_disk_num) { ++ dprintf_cont("end migration"); ++ end_migration(dev, super, map_state); ++ } else { ++ dprintf_cont("raid10 double degradation, map state change"); ++ map->map_state = map_state; ++ } + super->updates_pending++; +- } else if (!rebuild_done) { ++ } else if (!rebuild_done) + break; ++ else if (n == map->failed_disk_num) { ++ /* r10 double degraded to degraded transition */ ++ dprintf_cont("raid10 double degradation end migration"); ++ end_migration(dev, super, map_state); ++ a->last_checkpoint = 0; ++ super->updates_pending++; + } + + /* check if recovery is really finished */ +@@ -8575,7 +8588,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + } + if (recovery_not_finished) { + dprintf_cont("\n"); +- dprintf("Rebuild has not finished yet, state not changed"); ++ dprintf_cont("Rebuild has not finished yet, map state changes only if raid10 double degradation happens"); + if (a->last_checkpoint < mdi->recovery_start) { + a->last_checkpoint = + mdi->recovery_start; +-- +2.7.5 + diff --git a/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch b/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch new file mode 100644 index 0000000..a9c41a5 --- /dev/null +++ b/SOURCES/0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch @@ -0,0 +1,43 @@ +From 563ac108659980b3d1e226fe416254a86656235f Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Tue, 6 Nov 2018 16:20:17 +0100 +Subject: [RHEL7.7 PATCH 07/24] Assemble: mask FAILFAST and WRITEMOSTLY flags + when finding the most recent device + +If devices[].i.disk.state has MD_DISK_FAILFAST or MD_DISK_WRITEMOSTLY +flag, it cannot be the most recent device. Both flags should be masked +before checking the state. + +Reviewed-by: NeilBrown +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + Assemble.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/Assemble.c b/Assemble.c +index f39c9e1..9f75c68 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -578,6 +578,7 @@ static int load_devices(struct devs *devices, char *devmap, + struct supertype *tst; + int i; + int dfd; ++ int disk_state; + + if (tmpdev->used != 1) + continue; +@@ -711,7 +712,9 @@ static int load_devices(struct devs *devices, char *devmap, + devices[devcnt].i.disk.major = major(stb.st_rdev); + devices[devcnt].i.disk.minor = minor(stb.st_rdev); + +- if (devices[devcnt].i.disk.state == 6) { ++ disk_state = devices[devcnt].i.disk.state & ~((1< devices[most_recent].i.events) { +-- +2.7.5 + diff --git a/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch b/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch new file mode 100644 index 0000000..5480125 --- /dev/null +++ b/SOURCES/0008-Grow-avoid-overflow-in-compute_backup_blocks.patch @@ -0,0 +1,34 @@ +From 085df42259cba7863cd6ebe5cd0d8492ac5b869e Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 6 Dec 2018 10:35:41 +1100 +Subject: [RHEL7.7 PATCH 08/24] Grow: avoid overflow in compute_backup_blocks() + +With a chunk size of 16Meg and data drive count of 8, +this calculate can easily overflow the 'int' type that +is used for the multiplications. +So force it to use "long" instead. + +Reported-and-tested-by: Ed Spiridonov +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 4436a4d..76f82c0 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -1196,7 +1196,8 @@ unsigned long compute_backup_blocks(int nchunk, int ochunk, + /* Find GCD */ + a = GCD(a, b); + /* LCM == product / GCD */ +- blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a; ++ blocks = (unsigned long)(ochunk/512) * (unsigned long)(nchunk/512) * ++ odata * ndata / a; + + return blocks; + } +-- +2.7.5 + diff --git a/SOURCES/0009-Grow-report-correct-new-chunk-size.patch b/SOURCES/0009-Grow-report-correct-new-chunk-size.patch new file mode 100644 index 0000000..3ae8fb9 --- /dev/null +++ b/SOURCES/0009-Grow-report-correct-new-chunk-size.patch @@ -0,0 +1,30 @@ +From 76d505dec6c9f92564553596fc8350324be82463 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 6 Dec 2018 10:36:28 +1100 +Subject: [RHEL7.7 PATCH 09/24] Grow: report correct new chunk size. + +When using "--grow --chunk=" to change chunk +size, the old chunksize is reported instead of the new. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Grow.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Grow.c b/Grow.c +index 76f82c0..363b209 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -3286,7 +3286,7 @@ static int reshape_array(char *container, int fd, char *devname, + goto release; + } else if (verbose >= 0) + printf("chunk size for %s set to %d\n", +- devname, array.chunk_size); ++ devname, info->new_chunk); + } + unfreeze(st); + return 0; +-- +2.7.5 + diff --git a/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch b/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch new file mode 100644 index 0000000..73eb5db --- /dev/null +++ b/SOURCES/0010-policy.c-prevent-NULL-pointer-referencing.patch @@ -0,0 +1,31 @@ +From 467e6a1b4ece8e552ee638dab7f44a4d235ece1a Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Fri, 7 Dec 2018 12:04:44 +0100 +Subject: [RHEL7.7 PATCH 10/24] policy.c: prevent NULL pointer referencing + +paths could be NULL and paths[0] should be followed by NULL pointer +checking. + +Reviewed-by: NeilBrown +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/policy.c b/policy.c +index fa67d55..e3a0671 100644 +--- a/policy.c ++++ b/policy.c +@@ -383,7 +383,7 @@ struct dev_policy *path_policy(char **paths, char *type) + /* Now add any metadata-specific internal knowledge + * about this path + */ +- for (i=0; paths[0] && superlist[i]; i++) ++ for (i=0; paths && paths[0] && superlist[i]; i++) + if (superlist[i]->get_disk_controller_domain) { + const char *d = + superlist[i]->get_disk_controller_domain( +-- +2.7.5 + diff --git a/SOURCES/0011-policy.c-Fix-for-compiler-error.patch b/SOURCES/0011-policy.c-Fix-for-compiler-error.patch new file mode 100644 index 0000000..14a3c7b --- /dev/null +++ b/SOURCES/0011-policy.c-Fix-for-compiler-error.patch @@ -0,0 +1,36 @@ +From 757e55435997e355ee9b03e5d913b5496a3c39a8 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 11 Dec 2018 15:04:07 +0100 +Subject: [RHEL7.7 PATCH 11/24] policy.c: Fix for compiler error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After cd72f9d(policy: support devices with multiple paths.) compilation +on old compilers fails because "ā€˜pā€™ may be used uninitialized +in this function". + +Initialize it with NULL to prevent this. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/policy.c b/policy.c +index e3a0671..3c53bd3 100644 +--- a/policy.c ++++ b/policy.c +@@ -268,7 +268,7 @@ static int pol_match(struct rule *rule, char **paths, char *type, char **part) + + for (; rule; rule = rule->next) { + if (rule->name == rule_path) { +- char *p; ++ char *p = NULL; + int i; + if (pathok == 0) + pathok = -1; +-- +2.7.5 + diff --git a/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch b/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch new file mode 100644 index 0000000..f146436 --- /dev/null +++ b/SOURCES/0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch @@ -0,0 +1,95 @@ +From a4e96fd8f3f0b5416783237c1cb6ee87e7eff23d Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 8 Feb 2019 11:07:10 +0100 +Subject: [RHEL7.7 PATCH 12/24] imsm: finish recovery when drive with rebuild + fails + +Commit d7a1fda2769b ("imsm: update metadata correctly while raid10 double +degradation") resolves main Imsm double degradation problems but it +omits one case. Now metadata hangs in the rebuilding state if the drive +under rebuild is removed during recovery from double degradation. + +The root cause of this problem is comparing new map_state with current +and if they both are degraded assuming that nothing new happens. + +Don't rely on map states, just check if device is failed. If the drive +under rebuild fails then finish migration, in other cases update map +state only (second fail means that destination map state can't be normal). + +To avoid problems with reassembling move end_migration (called after +double degradation successful recovery) after check if recovery really +finished, for details see (7ce057018 "imsm: fix: rebuild does not +continue after reboot"). +Remove redundant code responsible for finishing rebuild process. Function +end_migration do exactly the same. Set last_checkpoint to 0, to prepare +it for the next rebuild. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + super-intel.c | 26 +++++++++++--------------- + 1 file changed, 11 insertions(+), 15 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index d2035cc..38a1b6c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8560,26 +8560,22 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + } + if (is_rebuilding(dev)) { + dprintf_cont("while rebuilding "); +- if (map->map_state != map_state) { +- dprintf_cont("map state change "); ++ if (state & DS_FAULTY) { ++ dprintf_cont("removing failed drive "); + if (n == map->failed_disk_num) { + dprintf_cont("end migration"); + end_migration(dev, super, map_state); ++ a->last_checkpoint = 0; + } else { +- dprintf_cont("raid10 double degradation, map state change"); ++ dprintf_cont("fail detected during rebuild, changing map state"); + map->map_state = map_state; + } + super->updates_pending++; +- } else if (!rebuild_done) +- break; +- else if (n == map->failed_disk_num) { +- /* r10 double degraded to degraded transition */ +- dprintf_cont("raid10 double degradation end migration"); +- end_migration(dev, super, map_state); +- a->last_checkpoint = 0; +- super->updates_pending++; + } + ++ if (!rebuild_done) ++ break; ++ + /* check if recovery is really finished */ + for (mdi = a->info.devs; mdi ; mdi = mdi->next) + if (mdi->recovery_start != MaxSector) { +@@ -8588,7 +8584,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + } + if (recovery_not_finished) { + dprintf_cont("\n"); +- dprintf_cont("Rebuild has not finished yet, map state changes only if raid10 double degradation happens"); ++ dprintf_cont("Rebuild has not finished yet"); + if (a->last_checkpoint < mdi->recovery_start) { + a->last_checkpoint = + mdi->recovery_start; +@@ -8598,9 +8594,9 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + } + + dprintf_cont(" Rebuild done, still degraded"); +- dev->vol.migr_state = 0; +- set_migr_type(dev, 0); +- dev->vol.curr_migr_unit = 0; ++ end_migration(dev, super, map_state); ++ a->last_checkpoint = 0; ++ super->updates_pending++; + + for (i = 0; i < map->num_members; i++) { + int idx = get_imsm_ord_tbl_ent(dev, i, MAP_0); +-- +2.7.5 + diff --git a/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch b/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch new file mode 100644 index 0000000..19b4803 --- /dev/null +++ b/SOURCES/0013-imsm-fix-reshape-for-2TB-drives.patch @@ -0,0 +1,322 @@ +From 9f4218274cd4a1e1f356a1617f9a1d09960cf255 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Mon, 28 Jan 2019 17:10:41 +0100 +Subject: [RHEL7.7 PATCH 13/24] imsm: fix reshape for >2TB drives + +If reshape is performed on drives larger then 2 TB, +migration checkpoint area that is calculated exeeds 32-bit value. +This checkpoint area is a reserved space threated as backup +during reshape - at the end of the drive, right before metadata. +As a result - wrong space is used and the data that may exists there +is overwritten. + +Adding additional field to migration record to track high order 32-bits +of pba of this area. Three other fields that may exceed 32-bit value +for large drives are added as well. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 149 +++++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 107 insertions(+), 42 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 38a1b6c..1cc7d5f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -296,7 +296,7 @@ struct migr_record { + __u32 rec_status; /* Status used to determine how to restart + * migration in case it aborts + * in some fashion */ +- __u32 curr_migr_unit; /* 0..numMigrUnits-1 */ ++ __u32 curr_migr_unit_lo; /* 0..numMigrUnits-1 */ + __u32 family_num; /* Family number of MPB + * containing the RaidDev + * that is migrating */ +@@ -306,16 +306,23 @@ struct migr_record { + __u32 dest_depth_per_unit; /* Num member blocks each destMap + * member disk + * advances per unit-of-operation */ +- __u32 ckpt_area_pba; /* Pba of first block of ckpt copy area */ +- __u32 dest_1st_member_lba; /* First member lba on first +- * stripe of destination */ +- __u32 num_migr_units; /* Total num migration units-of-op */ ++ __u32 ckpt_area_pba_lo; /* Pba of first block of ckpt copy area */ ++ __u32 dest_1st_member_lba_lo; /* First member lba on first ++ * stripe of destination */ ++ __u32 num_migr_units_lo; /* Total num migration units-of-op */ + __u32 post_migr_vol_cap; /* Size of volume after + * migration completes */ + __u32 post_migr_vol_cap_hi; /* Expansion space for LBA64 */ + __u32 ckpt_read_disk_num; /* Which member disk in destSubMap[0] the + * migration ckpt record was read from + * (for recovered migrations) */ ++ __u32 curr_migr_unit_hi; /* 0..numMigrUnits-1 high order 32 bits */ ++ __u32 ckpt_area_pba_hi; /* Pba of first block of ckpt copy area ++ * high order 32 bits */ ++ __u32 dest_1st_member_lba_hi; /* First member lba on first stripe of ++ * destination - high order 32 bits */ ++ __u32 num_migr_units_hi; /* Total num migration units-of-op ++ * high order 32 bits */ + } __attribute__ ((__packed__)); + + struct md_list { +@@ -1208,6 +1215,38 @@ static unsigned long long imsm_dev_size(struct imsm_dev *dev) + return join_u32(dev->size_low, dev->size_high); + } + ++static unsigned long long migr_chkp_area_pba(struct migr_record *migr_rec) ++{ ++ if (migr_rec == NULL) ++ return 0; ++ return join_u32(migr_rec->ckpt_area_pba_lo, ++ migr_rec->ckpt_area_pba_hi); ++} ++ ++static unsigned long long current_migr_unit(struct migr_record *migr_rec) ++{ ++ if (migr_rec == NULL) ++ return 0; ++ return join_u32(migr_rec->curr_migr_unit_lo, ++ migr_rec->curr_migr_unit_hi); ++} ++ ++static unsigned long long migr_dest_1st_member_lba(struct migr_record *migr_rec) ++{ ++ if (migr_rec == NULL) ++ return 0; ++ return join_u32(migr_rec->dest_1st_member_lba_lo, ++ migr_rec->dest_1st_member_lba_hi); ++} ++ ++static unsigned long long get_num_migr_units(struct migr_record *migr_rec) ++{ ++ if (migr_rec == NULL) ++ return 0; ++ return join_u32(migr_rec->num_migr_units_lo, ++ migr_rec->num_migr_units_hi); ++} ++ + static void set_total_blocks(struct imsm_disk *disk, unsigned long long n) + { + split_ull(n, &disk->total_blocks_lo, &disk->total_blocks_hi); +@@ -1233,6 +1272,33 @@ static void set_imsm_dev_size(struct imsm_dev *dev, unsigned long long n) + split_ull(n, &dev->size_low, &dev->size_high); + } + ++static void set_migr_chkp_area_pba(struct migr_record *migr_rec, ++ unsigned long long n) ++{ ++ split_ull(n, &migr_rec->ckpt_area_pba_lo, &migr_rec->ckpt_area_pba_hi); ++} ++ ++static void set_current_migr_unit(struct migr_record *migr_rec, ++ unsigned long long n) ++{ ++ split_ull(n, &migr_rec->curr_migr_unit_lo, ++ &migr_rec->curr_migr_unit_hi); ++} ++ ++static void set_migr_dest_1st_member_lba(struct migr_record *migr_rec, ++ unsigned long long n) ++{ ++ split_ull(n, &migr_rec->dest_1st_member_lba_lo, ++ &migr_rec->dest_1st_member_lba_hi); ++} ++ ++static void set_num_migr_units(struct migr_record *migr_rec, ++ unsigned long long n) ++{ ++ split_ull(n, &migr_rec->num_migr_units_lo, ++ &migr_rec->num_migr_units_hi); ++} ++ + static unsigned long long per_dev_array_size(struct imsm_map *map) + { + unsigned long long array_size = 0; +@@ -1629,12 +1695,14 @@ void convert_to_4k_imsm_migr_rec(struct intel_super *super) + struct migr_record *migr_rec = super->migr_rec; + + migr_rec->blocks_per_unit /= IMSM_4K_DIV; +- migr_rec->ckpt_area_pba /= IMSM_4K_DIV; +- migr_rec->dest_1st_member_lba /= IMSM_4K_DIV; + migr_rec->dest_depth_per_unit /= IMSM_4K_DIV; + split_ull((join_u32(migr_rec->post_migr_vol_cap, + migr_rec->post_migr_vol_cap_hi) / IMSM_4K_DIV), + &migr_rec->post_migr_vol_cap, &migr_rec->post_migr_vol_cap_hi); ++ set_migr_chkp_area_pba(migr_rec, ++ migr_chkp_area_pba(migr_rec) / IMSM_4K_DIV); ++ set_migr_dest_1st_member_lba(migr_rec, ++ migr_dest_1st_member_lba(migr_rec) / IMSM_4K_DIV); + } + + void convert_to_4k_imsm_disk(struct imsm_disk *disk) +@@ -1727,8 +1795,8 @@ void examine_migr_rec_imsm(struct intel_super *super) + printf("Normal\n"); + else + printf("Contains Data\n"); +- printf(" Current Unit : %u\n", +- __le32_to_cpu(migr_rec->curr_migr_unit)); ++ printf(" Current Unit : %llu\n", ++ current_migr_unit(migr_rec)); + printf(" Family : %u\n", + __le32_to_cpu(migr_rec->family_num)); + printf(" Ascending : %u\n", +@@ -1737,16 +1805,15 @@ void examine_migr_rec_imsm(struct intel_super *super) + __le32_to_cpu(migr_rec->blocks_per_unit)); + printf(" Dest. Depth Per Unit : %u\n", + __le32_to_cpu(migr_rec->dest_depth_per_unit)); +- printf(" Checkpoint Area pba : %u\n", +- __le32_to_cpu(migr_rec->ckpt_area_pba)); +- printf(" First member lba : %u\n", +- __le32_to_cpu(migr_rec->dest_1st_member_lba)); +- printf(" Total Number of Units : %u\n", +- __le32_to_cpu(migr_rec->num_migr_units)); +- printf(" Size of volume : %u\n", +- __le32_to_cpu(migr_rec->post_migr_vol_cap)); +- printf(" Expansion space for LBA64 : %u\n", +- __le32_to_cpu(migr_rec->post_migr_vol_cap_hi)); ++ printf(" Checkpoint Area pba : %llu\n", ++ migr_chkp_area_pba(migr_rec)); ++ printf(" First member lba : %llu\n", ++ migr_dest_1st_member_lba(migr_rec)); ++ printf(" Total Number of Units : %llu\n", ++ get_num_migr_units(migr_rec)); ++ printf(" Size of volume : %llu\n", ++ join_u32(migr_rec->post_migr_vol_cap, ++ migr_rec->post_migr_vol_cap_hi)); + printf(" Record was read from : %u\n", + __le32_to_cpu(migr_rec->ckpt_read_disk_num)); + +@@ -1759,13 +1826,15 @@ void convert_from_4k_imsm_migr_rec(struct intel_super *super) + struct migr_record *migr_rec = super->migr_rec; + + migr_rec->blocks_per_unit *= IMSM_4K_DIV; +- migr_rec->ckpt_area_pba *= IMSM_4K_DIV; +- migr_rec->dest_1st_member_lba *= IMSM_4K_DIV; + migr_rec->dest_depth_per_unit *= IMSM_4K_DIV; + split_ull((join_u32(migr_rec->post_migr_vol_cap, + migr_rec->post_migr_vol_cap_hi) * IMSM_4K_DIV), + &migr_rec->post_migr_vol_cap, + &migr_rec->post_migr_vol_cap_hi); ++ set_migr_chkp_area_pba(migr_rec, ++ migr_chkp_area_pba(migr_rec) * IMSM_4K_DIV); ++ set_migr_dest_1st_member_lba(migr_rec, ++ migr_dest_1st_member_lba(migr_rec) * IMSM_4K_DIV); + } + + void convert_from_4k(struct intel_super *super) +@@ -3096,7 +3165,7 @@ static int imsm_create_metadata_checkpoint_update( + return 0; + } + (*u)->type = update_general_migration_checkpoint; +- (*u)->curr_migr_unit = __le32_to_cpu(super->migr_rec->curr_migr_unit); ++ (*u)->curr_migr_unit = current_migr_unit(super->migr_rec); + dprintf("prepared for %u\n", (*u)->curr_migr_unit); + + return update_memory_size; +@@ -3397,13 +3466,13 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, + case MIGR_GEN_MIGR: { + __u64 blocks_per_unit = blocks_per_migr_unit(super, + dev); +- __u64 units = __le32_to_cpu(migr_rec->curr_migr_unit); ++ __u64 units = current_migr_unit(migr_rec); + unsigned long long array_blocks; + int used_disks; + + if (__le32_to_cpu(migr_rec->ascending_migr) && + (units < +- (__le32_to_cpu(migr_rec->num_migr_units)-1)) && ++ (get_num_migr_units(migr_rec)-1)) && + (super->migr_rec->rec_status == + __cpu_to_le32(UNIT_SRC_IN_CP_AREA))) + units++; +@@ -10697,7 +10766,7 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev, + + if (array_blocks % __le32_to_cpu(migr_rec->blocks_per_unit)) + num_migr_units++; +- migr_rec->num_migr_units = __cpu_to_le32(num_migr_units); ++ set_num_migr_units(migr_rec, num_migr_units); + + migr_rec->post_migr_vol_cap = dev->size_low; + migr_rec->post_migr_vol_cap_hi = dev->size_high; +@@ -10714,7 +10783,7 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev, + min_dev_sectors = dev_sectors; + close(fd); + } +- migr_rec->ckpt_area_pba = __cpu_to_le32(min_dev_sectors - ++ set_migr_chkp_area_pba(migr_rec, min_dev_sectors - + RAID_DISK_RESERVED_BLOCKS_IMSM_HI); + + write_imsm_migr_rec(st); +@@ -10765,8 +10834,7 @@ int save_backup_imsm(struct supertype *st, + + start = info->reshape_progress * 512; + for (i = 0; i < new_disks; i++) { +- target_offsets[i] = (unsigned long long) +- __le32_to_cpu(super->migr_rec->ckpt_area_pba) * 512; ++ target_offsets[i] = migr_chkp_area_pba(super->migr_rec) * 512; + /* move back copy area adderss, it will be moved forward + * in restore_stripes() using start input variable + */ +@@ -10845,12 +10913,11 @@ int save_checkpoint_imsm(struct supertype *st, struct mdinfo *info, int state) + if (info->reshape_progress % blocks_per_unit) + curr_migr_unit++; + +- super->migr_rec->curr_migr_unit = +- __cpu_to_le32(curr_migr_unit); ++ set_current_migr_unit(super->migr_rec, curr_migr_unit); + super->migr_rec->rec_status = __cpu_to_le32(state); +- super->migr_rec->dest_1st_member_lba = +- __cpu_to_le32(curr_migr_unit * +- __le32_to_cpu(super->migr_rec->dest_depth_per_unit)); ++ set_migr_dest_1st_member_lba(super->migr_rec, ++ super->migr_rec->dest_depth_per_unit * curr_migr_unit); ++ + if (write_imsm_migr_rec(st) < 0) { + dprintf("imsm: Cannot write migration record outside backup area\n"); + return 1; +@@ -10884,8 +10951,8 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) + char *buf = NULL; + int retval = 1; + unsigned int sector_size = super->sector_size; +- unsigned long curr_migr_unit = __le32_to_cpu(migr_rec->curr_migr_unit); +- unsigned long num_migr_units = __le32_to_cpu(migr_rec->num_migr_units); ++ unsigned long curr_migr_unit = current_migr_unit(migr_rec); ++ unsigned long num_migr_units = get_num_migr_units(migr_rec); + char buffer[20]; + int skipped_disks = 0; + +@@ -10912,11 +10979,9 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) + map_dest = get_imsm_map(id->dev, MAP_0); + new_disks = map_dest->num_members; + +- read_offset = (unsigned long long) +- __le32_to_cpu(migr_rec->ckpt_area_pba) * 512; ++ read_offset = migr_chkp_area_pba(migr_rec) * 512; + +- write_offset = ((unsigned long long) +- __le32_to_cpu(migr_rec->dest_1st_member_lba) + ++ write_offset = (migr_dest_1st_member_lba(migr_rec) + + pba_of_lba0(map_dest)) * 512; + + unit_len = __le32_to_cpu(migr_rec->dest_depth_per_unit) * 512; +@@ -12019,12 +12084,12 @@ static int imsm_manage_reshape( + max_position = sra->component_size * ndata; + source_layout = imsm_level_to_layout(map_src->raid_level); + +- while (__le32_to_cpu(migr_rec->curr_migr_unit) < +- __le32_to_cpu(migr_rec->num_migr_units)) { ++ while (current_migr_unit(migr_rec) < ++ get_num_migr_units(migr_rec)) { + /* current reshape position [blocks] */ + unsigned long long current_position = + __le32_to_cpu(migr_rec->blocks_per_unit) +- * __le32_to_cpu(migr_rec->curr_migr_unit); ++ * current_migr_unit(migr_rec); + unsigned long long border; + + /* Check that array hasn't become failed. +-- +2.7.5 + diff --git a/SOURCES/0014-Fix-spelling-typos.patch b/SOURCES/0014-Fix-spelling-typos.patch new file mode 100644 index 0000000..838709c --- /dev/null +++ b/SOURCES/0014-Fix-spelling-typos.patch @@ -0,0 +1,101 @@ +From ebf3be9931f31df54df52b1821479e6a80a4d9c6 Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Tue, 15 Jan 2019 19:08:37 +0000 +Subject: [RHEL7.7 PATCH 14/24] Fix spelling typos. + +Signed-off-by: Dimitri John Ledkov +Signed-off-by: Jes Sorensen +--- + Assemble.c | 2 +- + Create.c | 2 +- + Grow.c | 6 +++--- + super-ddf.c | 2 +- + super-intel.c | 2 +- + 5 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9f75c68..9f050c1 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -879,7 +879,7 @@ static int force_array(struct mdinfo *content, + current_events = devices[chosen_drive].i.events; + add_another: + if (c->verbose >= 0) +- pr_err("forcing event count in %s(%d) from %d upto %d\n", ++ pr_err("forcing event count in %s(%d) from %d up to %d\n", + devices[chosen_drive].devname, + devices[chosen_drive].i.disk.raid_disk, + (int)(devices[chosen_drive].i.events), +diff --git a/Create.c b/Create.c +index 04b1dfc..6f1b228 100644 +--- a/Create.c ++++ b/Create.c +@@ -823,7 +823,7 @@ int Create(struct supertype *st, char *mddev, + } + bitmap_fd = open(s->bitmap_file, O_RDWR); + if (bitmap_fd < 0) { +- pr_err("weird: %s cannot be openned\n", ++ pr_err("weird: %s cannot be opened\n", + s->bitmap_file); + goto abort_locked; + } +diff --git a/Grow.c b/Grow.c +index 363b209..6d32661 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -446,7 +446,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) + if (offset_setable) { + st->ss->getinfo_super(st, mdi, NULL); + if (sysfs_init(mdi, fd, NULL)) { +- pr_err("failed to intialize sysfs.\n"); ++ pr_err("failed to initialize sysfs.\n"); + free(mdi); + } + rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", +@@ -2178,7 +2178,7 @@ size_change_error: + memset(&info, 0, sizeof(info)); + info.array = array; + if (sysfs_init(&info, fd, NULL)) { +- pr_err("failed to intialize sysfs.\n"); ++ pr_err("failed to initialize sysfs.\n"); + rv = 1; + goto release; + } +@@ -2903,7 +2903,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) + struct mdinfo info; + + if (sysfs_init(&info, fd, NULL)) { +- pr_err("failed to intialize sysfs.\n"); ++ pr_err("failed to initialize sysfs.\n"); + return 1; + } + +diff --git a/super-ddf.c b/super-ddf.c +index 618542c..c095e8a 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1900,7 +1900,7 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst, + return conf; + } + bad: +- pr_err("Could't find disk %d in array %u\n", n, inst); ++ pr_err("Couldn't find disk %d in array %u\n", n, inst); + return NULL; + } + +diff --git a/super-intel.c b/super-intel.c +index 1cc7d5f..c399433 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -10034,7 +10034,7 @@ static void imsm_process_update(struct supertype *st, + break; + } + default: +- pr_err("error: unsuported process update type:(type: %d)\n", type); ++ pr_err("error: unsupported process update type:(type: %d)\n", type); + } + } + +-- +2.7.5 + diff --git a/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch b/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch new file mode 100644 index 0000000..2af2fa9 --- /dev/null +++ b/SOURCES/0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch @@ -0,0 +1,46 @@ +From e3615ecb5b6ad8eb408296878aad5628e0e27166 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Tue, 12 Feb 2019 12:53:18 +0800 +Subject: [RHEL7.7 PATCH 15/24] Detail.c: do not skip first character when + calling xstrdup in Detail() + +'Commit b9c9bd9bacaa ("Detail: ensure --export names are acceptable as +shell variables")' duplicates mdi->sys_name to sysdev string by, + char *sysdev = xstrdup(mdi->sys_name + 1); +which skips the first character of mdi->sys_name. Then when running +mdadm --detail --export, the output looks like, + MD_DEVICE_ev_sda2_ROLE=1 + MD_DEVICE_ev_sda2_DEV=/dev/sda2 +The first character of md device (between MD_DEVICE and _ROLE/_DEV) +is dropped. The expected output should be, + MD_DEVICE_dev_sda2_ROLE=1 + MD_DEVICE_dev_sda2_DEV=/dev/sda2 + +This patch removes the '+ 1' from calling xstrdup() in Detail(), which +gets the dropped first character back. + +Reported-by: Arvin Schnell +Fixes: b9c9bd9bacaa ("Detail: ensure --export names are acceptable as 4 shell variables") +Signed-off-by: Coly Li +Cc: NeilBrown +Signed-off-by: Jes Sorensen +--- + Detail.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Detail.c b/Detail.c +index b3e857a..20ea03a 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -284,7 +284,7 @@ int Detail(char *dev, struct context *c) + struct mdinfo *mdi; + for (mdi = sra->devs; mdi; mdi = mdi->next) { + char *path; +- char *sysdev = xstrdup(mdi->sys_name + 1); ++ char *sysdev = xstrdup(mdi->sys_name); + char *cp; + + path = map_dev(mdi->disk.major, +-- +2.7.5 + diff --git a/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch b/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch new file mode 100644 index 0000000..72340f5 --- /dev/null +++ b/SOURCES/0016-Fix-reshape-for-decreasing-data-offset.patch @@ -0,0 +1,70 @@ +From cab114c5ca870e5f1b57fb2602cd9a038271c2e0 Mon Sep 17 00:00:00 2001 +From: Corey Hickey +Date: Mon, 11 Feb 2019 17:18:38 -0800 +Subject: [RHEL7.7 PATCH 16/24] Fix reshape for decreasing data offset + +...when not changing the number of disks. + +This patch needs context to explain. These are the relevant parts of +the original code (condensed and annotated): + +if (dir > 0) { + /* Increase data offset (reshape backwards) */ + if (data_offset < sd->data_offset + min) { + pr_err("--data-offset too small on %s\n", + dn); + goto release; + } +} else { + /* Decrease data offset (reshape forwards) */ + if (data_offset < sd->data_offset - min) { + pr_err("--data-offset too small on %s\n", + dn); + goto release; + } +} + +When this code is reached, mdadm has already decided on a reshape +direction. When increasing the data offset, the reshape runs backwards +(dir==1); when decreasing the data offset, the reshape runs forwards +(dir==-1). + +The conditional within the backwards reshape is correct: the requested +offset must be larger than the old offset plus a minimum delta; thus the +reshape has room to work. + +For the forwards reshape, the requested offset needs to be smaller than +the old offset minus a minimum delta; to do this correctly, the +comparison must be reversed. + +Also update the error message. + +Note: I have tested this change on a RAID 5 on Linux 4.18.0 and verified +that there were no errors from the kernel and that the device data +remained intact. I do not know if there are considerations for different +RAID levels. + +Signed-off-by: Corey Hickey +Signed-off-by: Jes Sorensen +--- + Grow.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 6d32661..764374f 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2613,8 +2613,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st, + goto release; + } + if (data_offset != INVALID_SECTORS && +- data_offset < sd->data_offset - min) { +- pr_err("--data-offset too small on %s\n", ++ data_offset > sd->data_offset - min) { ++ pr_err("--data-offset too large on %s\n", + dn); + goto release; + } +-- +2.7.5 + diff --git a/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch b/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch new file mode 100644 index 0000000..1086a9d --- /dev/null +++ b/SOURCES/0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch @@ -0,0 +1,100 @@ +From 76b906d2406cdf136f64de77e881eb2d180108d9 Mon Sep 17 00:00:00 2001 +From: Gioh Kim +Date: Fri, 7 Dec 2018 14:30:09 +0100 +Subject: [RHEL7.7 PATCH 17/24] mdadm/tests: add one test case for failfast of + raid1 + +This creates raid1 device with the failfast option and check all +slaves have the failfast flag. And it does assembling and growing +the raid1 device and check the failfast works fine. + +Signed-off-by: Gioh Kim +Signed-off-by: Jes Sorensen +--- + tests/05r1-failfast | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + create mode 100644 tests/05r1-failfast + +diff --git a/tests/05r1-failfast b/tests/05r1-failfast +new file mode 100644 +index 0000000..823dd6f +--- /dev/null ++++ b/tests/05r1-failfast +@@ -0,0 +1,74 @@ ++ ++# create a simple mirror and check failfast flag works ++mdadm -CR $md0 -e1.2 --level=raid1 --failfast -n2 $dev0 $dev1 ++check raid1 ++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null ++then ++ die "failfast missing" ++fi ++ ++# Removing works with the failfast flag ++mdadm $md0 -f $dev0 ++mdadm $md0 -r $dev0 ++if grep -v failfast /sys/block/md0/md/rd1/state > /dev/null ++then ++ die "failfast missing" ++fi ++ ++# Adding works with the failfast flag ++mdadm $md0 -a --failfast $dev0 ++check wait ++if grep -v failfast /sys/block/md0/md/rd0/state > /dev/null ++then ++ die "failfast missing" ++fi ++ ++mdadm -S $md0 ++ ++# Assembling works with the failfast flag ++mdadm -A $md0 $dev0 $dev1 ++check raid1 ++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null ++then ++ die "failfast missing" ++fi ++ ++# Adding works with the nofailfast flag ++mdadm $md0 -f $dev0 ++mdadm $md0 -r $dev0 ++mdadm $md0 -a --nofailfast $dev0 ++check wait ++if grep failfast /sys/block/md0/md/rd0/state > /dev/null ++then ++ die "failfast should be missing" ++fi ++ ++# Assembling with one faulty slave works with the failfast flag ++mdadm $md0 -f $dev0 ++mdadm $md0 -r $dev0 ++mdadm -S $md0 ++mdadm -A $md0 $dev0 $dev1 ++check raid1 ++mdadm -S $md0 ++ ++# Spare works with the failfast flag ++mdadm -CR $md0 -e1.2 --level=raid1 --failfast -n2 $dev0 $dev1 ++check raid1 ++mdadm $md0 -a --failfast $dev2 ++check wait ++check spares 1 ++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null ++then ++ die "failfast missing" ++fi ++ ++# Grow works with the failfast flag ++mdadm -G $md0 --raid-devices=3 ++check wait ++if grep -v failfast /sys/block/md0/md/rd*/state > /dev/null ++then ++ die "failfast missing" ++fi ++mdadm -S $md0 ++ ++exit 0 +-- +2.7.5 + diff --git a/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch b/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch new file mode 100644 index 0000000..1df909b --- /dev/null +++ b/SOURCES/0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch @@ -0,0 +1,50 @@ +From 69d084784de196acec8ab703cd1b379af211d624 Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Fri, 22 Feb 2019 10:15:45 +0100 +Subject: [RHEL7.7 PATCH 18/24] mdmon: don't attempt to manage new arrays when + terminating + +When mdmon gets a SIGTERM, it stops managing arrays that are clean. If +there is more that one array in the container and one of them is dirty +and the clean one is still present in mdstat, mdmon will treat it as a +new array and start managing it again. This leads to a cycle of +remove_old() / manage_new() calls for the clean array, until the other +one also becomes clean. + +Prevent this by not calling manage_new() if sigterm is set. Also, remove +a check for sigterm in manage_new() because the condition will never be +true. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + managemon.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/managemon.c b/managemon.c +index 101231c..29b91ba 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -727,9 +727,7 @@ static void manage_new(struct mdstat_ent *mdstat, + dprintf("inst: %s action: %d state: %d\n", inst, + new->action_fd, new->info.state_fd); + +- if (sigterm) +- new->info.safe_mode_delay = 1; +- else if (mdi->safe_mode_delay >= 50) ++ if (mdi->safe_mode_delay >= 50) + /* Normal start, mdadm set this. */ + new->info.safe_mode_delay = mdi->safe_mode_delay; + else +@@ -803,7 +801,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container) + break; + } + } +- if (a == NULL || !a->container) ++ if ((a == NULL || !a->container) && !sigterm) + manage_new(mdstat, container, a); + } + } +-- +2.7.5 + diff --git a/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch b/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch new file mode 100644 index 0000000..fc6ead8 --- /dev/null +++ b/SOURCES/0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch @@ -0,0 +1,58 @@ +From d2e11da4b7fd0453e942f43e4196dc63b3dbd708 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Fri, 22 Feb 2019 13:30:27 +0100 +Subject: [RHEL7.7 PATCH 19/24] mdmon: wait for previous mdmon to exit during + takeover + +Since the patch c76242c5("mdmon: get safe mode delay file descriptor +early"), safe_mode_dalay is set properly by initrd mdmon. But in some +cases with filesystem traffic since the very start of the system, it +might take a while to transit to clean state. Due to fact that new +mdmon does not wait for the old one to exit - it might happen that the +new one switches safe_mode_delay back to seconds, before old one exits. +As the result two mdmons are running concurrently on same array. + +Wait for the old mdmon to exit by pinging it with SIGUSR1 signal, just +in case it is sleeping. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + mdmon.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/mdmon.c b/mdmon.c +index 0955fcc..ff985d2 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -171,6 +171,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) + int fd; + int n; + long fl; ++ int rv; + + /* first rule of survival... don't off yourself */ + if (pid == getpid()) +@@ -201,9 +202,16 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock) + fl &= ~O_NONBLOCK; + fcntl(sock, F_SETFL, fl); + n = read(sock, buf, 100); +- /* Ignore result, it is just the wait that +- * matters +- */ ++ ++ /* If there is I/O going on it might took some time to get to ++ * clean state. Wait for monitor to exit fully to avoid races. ++ * Ping it with SIGUSR1 in case that it is sleeping */ ++ for (n = 0; n < 25; n++) { ++ rv = kill(pid, SIGUSR1); ++ if (rv < 0) ++ break; ++ usleep(200000); ++ } + } + + void remove_pidfile(char *devname) +-- +2.7.5 + diff --git a/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch b/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch new file mode 100644 index 0000000..498cf61 --- /dev/null +++ b/SOURCES/0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch @@ -0,0 +1,52 @@ +From 2b57e4fe041d52ae29866c93a878a11c07223cff Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Fri, 22 Feb 2019 12:56:27 +0100 +Subject: [RHEL7.7 PATCH 20/24] Assemble: Fix starting array with initial + reshape checkpoint + +If array was stopped during reshape initialization, +there might be a "0" checkpoint recorded in metadata. +If array with such condition (reshape with position 0) +is passed to kernel - it will refuse to start such array. + +Treat such array as normal during assemble, Grow_continue() will +reinitialize and start the reshape. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + Assemble.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 9f050c1..420c7b3 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -2061,8 +2061,22 @@ int assemble_container_content(struct supertype *st, int mdfd, + spare, &c->backup_file, c->verbose) == 1) + return 1; + +- err = sysfs_set_str(content, NULL, +- "array_state", "readonly"); ++ if (content->reshape_progress == 0) { ++ /* If reshape progress is 0 - we are assembling the ++ * array that was stopped, before reshape has started. ++ * Array needs to be started as active, Grow_continue() ++ * will start the reshape. ++ */ ++ sysfs_set_num(content, NULL, "reshape_position", ++ MaxSector); ++ err = sysfs_set_str(content, NULL, ++ "array_state", "active"); ++ sysfs_set_num(content, NULL, "reshape_position", 0); ++ } else { ++ err = sysfs_set_str(content, NULL, ++ "array_state", "readonly"); ++ } ++ + if (err) + return 1; + +-- +2.7.5 + diff --git a/SOURCES/0021-add-missing-units-to-examine.patch b/SOURCES/0021-add-missing-units-to-examine.patch new file mode 100644 index 0000000..2ebb91e --- /dev/null +++ b/SOURCES/0021-add-missing-units-to-examine.patch @@ -0,0 +1,59 @@ +From 227aeaa872d4898273cf87a4253898823d556c43 Mon Sep 17 00:00:00 2001 +From: Corey Hickey +Date: Mon, 11 Feb 2019 17:42:27 -0800 +Subject: [RHEL7.7 PATCH 21/24] add missing units to --examine + +Within the output of "mdadm --examine", there are three sizes reported +on adjacent lines. For example: + +$ sudo mdadm --examine /dev/md3 +[...] + Avail Dev Size : 17580545024 (8383.06 GiB 9001.24 GB) + Array Size : 17580417024 (16765.99 GiB 18002.35 GB) + Used Dev Size : 11720278016 (5588.66 GiB 6000.78 GB) +[...] + +This can be confusing, since the first and third line are in 512-byte +sectors, and the second is in KiB. + +Add units to avoid ambiguity. + +(I don't particularly like the "KiB" notation, but it is at least +unambiguous.) + +Signed-off-by: Corey Hickey +Signed-off-by: Jes Sorensen +--- + super1.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/super1.c b/super1.c +index 636a286..b85dc20 100644 +--- a/super1.c ++++ b/super1.c +@@ -360,7 +360,7 @@ static void examine_super1(struct supertype *st, char *homehost) + printf(" Raid Level : %s\n", c?c:"-unknown-"); + printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks)); + printf("\n"); +- printf(" Avail Dev Size : %llu%s\n", ++ printf(" Avail Dev Size : %llu sectors%s\n", + (unsigned long long)__le64_to_cpu(sb->data_size), + human_size(__le64_to_cpu(sb->data_size)<<9)); + if (__le32_to_cpu(sb->level) > 0) { +@@ -378,11 +378,11 @@ static void examine_super1(struct supertype *st, char *homehost) + if (ddsks) { + long long asize = __le64_to_cpu(sb->size); + asize = (asize << 9) * ddsks / ddsks_denom; +- printf(" Array Size : %llu%s\n", ++ printf(" Array Size : %llu KiB%s\n", + asize >> 10, human_size(asize)); + } + if (sb->size != sb->data_size) +- printf(" Used Dev Size : %llu%s\n", ++ printf(" Used Dev Size : %llu sectors%s\n", + (unsigned long long)__le64_to_cpu(sb->size), + human_size(__le64_to_cpu(sb->size)<<9)); + } +-- +2.7.5 + diff --git a/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch b/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch new file mode 100644 index 0000000..b99afa6 --- /dev/null +++ b/SOURCES/0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch @@ -0,0 +1,117 @@ +From 05501181f18cdccdb0b3cec1d8cf59f0995504d7 Mon Sep 17 00:00:00 2001 +From: Pawel Baldysiak +Date: Fri, 8 Mar 2019 12:19:11 +0100 +Subject: [RHEL7.7 PATCH 22/24] imsm: fix spare activation for old matrix + arrays + +During spare activation get_extents() calculates metadata reserved space based +on smallest active RAID member or it will take the defaults. Since patch +611d9529("imsm: change reserved space to 4MB") default is extended. If array +was created prior that patch, reserved space is smaller. In case of matrix +RAID - spare is activated in each array one-by-one, so it is spare for first +activation, but treated as "active" during second one. + +In case of adding spare drive to old matrix RAID with the size the same as +already existing member drive the routine will take the defaults during second +run and mdmon will refuse to rebuild second volume, claiming that the drive +does not have enough free space. + +Add parameter to get_extents(), so the during spare activation reserved space +is always based on smallest active drive - even if given drive is already +active in some other array of matrix RAID. + +Signed-off-by: Pawel Baldysiak +Signed-off-by: Jes Sorensen +--- + super-intel.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index c399433..5a7c9f8 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1313,7 +1313,8 @@ static unsigned long long per_dev_array_size(struct imsm_map *map) + return array_size; + } + +-static struct extent *get_extents(struct intel_super *super, struct dl *dl) ++static struct extent *get_extents(struct intel_super *super, struct dl *dl, ++ int get_minimal_reservation) + { + /* find a list of used extents on the given physical device */ + struct extent *rv, *e; +@@ -1325,7 +1326,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl) + * regardless of whether the OROM has assigned sectors from the + * IMSM_RESERVED_SECTORS region + */ +- if (dl->index == -1) ++ if (dl->index == -1 || get_minimal_reservation) + reservation = imsm_min_reserved_sectors(super); + else + reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS; +@@ -1386,7 +1387,7 @@ static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl) + if (dl->index == -1) + return MPB_SECTOR_CNT; + +- e = get_extents(super, dl); ++ e = get_extents(super, dl, 0); + if (!e) + return MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS; + +@@ -1478,7 +1479,7 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super) + return rv; + + /* find last lba used by subarrays on the smallest active disk */ +- e = get_extents(super, dl_min); ++ e = get_extents(super, dl_min, 0); + if (!e) + return rv; + for (i = 0; e[i].size; i++) +@@ -1519,7 +1520,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c) + if (!dl) + return -EINVAL; + /* find last lba used by subarrays */ +- e = get_extents(super, dl); ++ e = get_extents(super, dl, 0); + if (!e) + return -EINVAL; + for (i = 0; e[i].size; i++) +@@ -7203,7 +7204,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + + pos = 0; + i = 0; +- e = get_extents(super, dl); ++ e = get_extents(super, dl, 0); + if (!e) continue; + do { + unsigned long long esize; +@@ -7261,7 +7262,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + } + + /* retrieve the largest free space block */ +- e = get_extents(super, dl); ++ e = get_extents(super, dl, 0); + maxsize = 0; + i = 0; + if (e) { +@@ -7359,7 +7360,7 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, + if (super->orom && dl->index < 0 && mpb->num_raid_devs) + continue; + +- e = get_extents(super, dl); ++ e = get_extents(super, dl, 0); + if (!e) + continue; + for (i = 1; e[i-1].size; i++) +@@ -8846,7 +8847,7 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot, + /* Does this unused device have the requisite free space? + * It needs to be able to cover all member volumes + */ +- ex = get_extents(super, dl); ++ ex = get_extents(super, dl, 1); + if (!ex) { + dprintf("cannot get extents\n"); + continue; +-- +2.7.5 + diff --git a/SOURCES/0023-Create-Block-rounding-size-to-max.patch b/SOURCES/0023-Create-Block-rounding-size-to-max.patch new file mode 100644 index 0000000..e8b8102 --- /dev/null +++ b/SOURCES/0023-Create-Block-rounding-size-to-max.patch @@ -0,0 +1,94 @@ +From 22dc741f63e6403d59c2c14f56fd4791265f9bbb Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 1 Apr 2019 16:53:41 +0200 +Subject: [RHEL7.7 PATCH 23/24] Create: Block rounding size to max + +When passed size is smaller than chunk, mdadm rounds it to 0 but 0 there +means max available space. +Block it for every metadata. Remove the same check from imsm routine. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Create.c | 23 ++++++++++++++++++++--- + super-intel.c | 5 ++--- + 2 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/Create.c b/Create.c +index 6f1b228..292f92a 100644 +--- a/Create.c ++++ b/Create.c +@@ -27,6 +27,18 @@ + #include "md_p.h" + #include + ++static int round_size_and_verify(unsigned long long *size, int chunk) ++{ ++ if (*size == 0) ++ return 0; ++ *size &= ~(unsigned long long)(chunk - 1); ++ if (*size == 0) { ++ pr_err("Size cannot be smaller than chunk.\n"); ++ return 1; ++ } ++ return 0; ++} ++ + static int default_layout(struct supertype *st, int level, int verbose) + { + int layout = UnSet; +@@ -248,11 +260,14 @@ int Create(struct supertype *st, char *mddev, + pr_err("unknown level %d\n", s->level); + return 1; + } ++ + if (s->size == MAX_SIZE) + /* use '0' to mean 'max' now... */ + s->size = 0; + if (s->size && s->chunk && s->chunk != UnSet) +- s->size &= ~(unsigned long long)(s->chunk - 1); ++ if (round_size_and_verify(&s->size, s->chunk)) ++ return 1; ++ + newsize = s->size * 2; + if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks, + &s->chunk, s->size*2, +@@ -267,7 +282,8 @@ int Create(struct supertype *st, char *mddev, + /* default chunk was just set */ + if (c->verbose > 0) + pr_err("chunk size defaults to %dK\n", s->chunk); +- s->size &= ~(unsigned long long)(s->chunk - 1); ++ if (round_size_and_verify(&s->size, s->chunk)) ++ return 1; + do_default_chunk = 0; + } + } +@@ -413,7 +429,8 @@ int Create(struct supertype *st, char *mddev, + /* default chunk was just set */ + if (c->verbose > 0) + pr_err("chunk size defaults to %dK\n", s->chunk); +- s->size &= ~(unsigned long long)(s->chunk - 1); ++ if (round_size_and_verify(&s->size, s->chunk)) ++ return 1; + do_default_chunk = 0; + } + } +diff --git a/super-intel.c b/super-intel.c +index 5a7c9f8..2ba045a 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7455,9 +7455,8 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, + verbose); + } + +- if (size && ((size < 1024) || (*chunk != UnSet && +- size < (unsigned long long) *chunk))) { +- pr_err("Given size must be greater than 1M and chunk size.\n"); ++ if (size && (size < 1024)) { ++ pr_err("Given size must be greater than 1M.\n"); + /* Depends on algorithm in Create.c : + * if container was given (dev == NULL) return -1, + * if block device was given ( dev != NULL) return 0. +-- +2.7.5 + diff --git a/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch b/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch new file mode 100644 index 0000000..35b8741 --- /dev/null +++ b/SOURCES/0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch @@ -0,0 +1,31 @@ +From 3c9b46cf9ae15a9be98fc47e2080bd9494496246 Mon Sep 17 00:00:00 2001 +From: Liwei Song +Date: Tue, 19 Mar 2019 23:51:05 -0400 +Subject: [RHEL7.7 PATCH 24/24] udev: Add udev rules to create by-partuuid for + md device + +This rules will create link under /dev/disk/by-partuuid/ for +MD devices partition, with which will support specify +root=PARTUUID=XXX to boot rootfs. + +Signed-off-by: Liwei Song +Signed-off-by: Jes Sorensen +--- + udev-md-raid-arrays.rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index c95ec7b..5b99d58 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -30,6 +30,7 @@ IMPORT{builtin}="blkid" + OPTIONS+="link_priority=100" + OPTIONS+="watch" + ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" ++ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}" + ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" + + ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" +-- +2.7.5 + diff --git a/SOURCES/add-tech-preview-msg-to-raid1-cluster.patch b/SOURCES/add-tech-preview-msg-to-raid1-cluster.patch deleted file mode 100644 index 67ddf22..0000000 --- a/SOURCES/add-tech-preview-msg-to-raid1-cluster.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- mdadm-4.1/mdadm.c~ 2018-12-12 17:15:41.359619760 +0800 -+++ mdadm-4.1/mdadm.c 2018-12-12 17:16:09.265626436 +0800 -@@ -1553,6 +1553,10 @@ - c.delay = DEFAULT_BITMAP_DELAY; - - if (c.nodes) { -+ pr_err("WARNING: bitmap=clustered is Technology Preview.\n"); -+ pr_err("For more information on Technology Preview features, visit:\n"); -+ pr_err("https://access.redhat.com/support/offerings/techpreview/ \n"); -+ - if (!s.bitmap_file || - strcmp(s.bitmap_file, "clustered") != 0) { - pr_err("--nodes argument only compatible with --bitmap=clustered\n"); diff --git a/SOURCES/disable-journal.patch b/SOURCES/disable-journal.patch deleted file mode 100644 index e2e05d7..0000000 --- a/SOURCES/disable-journal.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- 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 rhel8.0*/ - {"write-journal",1, 0, WriteJournal}, -+#endif - {"consistency-policy", 1, 0, 'k'}, - - /* For assemble */ -@@ -163,7 +165,9 @@ - /* Management */ - {"add", 0, 0, Add}, - {"add-spare", 0, 0, AddSpare}, -+#if 0 /*Disable for rhel8.0*/ - {"add-journal", 0, 0, AddJournal}, -+#endif - {"remove", 0, 0, Remove}, - {"fail", 0, 0, Fail}, - {"set-faulty",0, 0, Fail}, -@@ -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 rhel8.0*/ - " --write-journal= : Specify journal device for RAID-4/5/6 array\n" -+#endif - " --consistency-policy= : Specify the policy that determines how the array\n" - " -k : maintains consistency in case of unexpected shutdown.\n" - "\n" diff --git a/SOURCES/imsm-update-metadata-correctly-while-raid10-double-degradation.patch b/SOURCES/imsm-update-metadata-correctly-while-raid10-double-degradation.patch deleted file mode 100644 index 4f5067f..0000000 --- a/SOURCES/imsm-update-metadata-correctly-while-raid10-double-degradation.patch +++ /dev/null @@ -1,77 +0,0 @@ -commit d7a1fda2769ba272d89de6caeab35d52b73a9c3c -Author: Mariusz Tkaczyk -Date: Wed Oct 17 12:11:41 2018 +0200 - - imsm: update metadata correctly while raid10 double degradation - - Mdmon calls end_migration() when map state changes from normal to - degraded. It is not valid because in raid 10 double degradation case - mdmon breaks checkpointing but array is still rebuilding. - In this case mdmon has to mark map as degraded and continues marking - recovery checkpoint in metadata. Migration can be finished only if newly - failed device is a rebuilding device. - - Add catching double degraded to degraded transition. Migration is - finished but map state doesn't change, array is still degraded. - - Update failed_disk_num correctly. If double degradation - happens rebuild will start on the lowest slot, but this variable points - to the first failed slot. If second fail happens while rebuild this - variable shouldn't be updated until rebuild is not finished. - - Signed-off-by: Mariusz Tkaczyk - Signed-off-by: Jes Sorensen - -diff --git a/super-intel.c b/super-intel.c -index 6438987..d2035cc 100644 ---- a/super-intel.c -+++ b/super-intel.c -@@ -8136,7 +8136,8 @@ static int mark_failure(struct intel_super *super, - set_imsm_ord_tbl_ent(map2, slot2, - idx | IMSM_ORD_REBUILD); - } -- if (map->failed_disk_num == 0xff) -+ if (map->failed_disk_num == 0xff || -+ (!is_rebuilding(dev) && map->failed_disk_num > slot)) - map->failed_disk_num = slot; - - clear_disk_badblocks(super->bbm_log, ord_to_idx(ord)); -@@ -8558,13 +8559,25 @@ static void imsm_set_disk(struct active_array *a, int n, int state) - break; - } - if (is_rebuilding(dev)) { -- dprintf_cont("while rebuilding."); -+ dprintf_cont("while rebuilding "); - if (map->map_state != map_state) { -- dprintf_cont(" Map state change"); -- end_migration(dev, super, map_state); -+ dprintf_cont("map state change "); -+ if (n == map->failed_disk_num) { -+ dprintf_cont("end migration"); -+ end_migration(dev, super, map_state); -+ } else { -+ dprintf_cont("raid10 double degradation, map state change"); -+ map->map_state = map_state; -+ } - super->updates_pending++; -- } else if (!rebuild_done) { -+ } else if (!rebuild_done) - break; -+ else if (n == map->failed_disk_num) { -+ /* r10 double degraded to degraded transition */ -+ dprintf_cont("raid10 double degradation end migration"); -+ end_migration(dev, super, map_state); -+ a->last_checkpoint = 0; -+ super->updates_pending++; - } - - /* check if recovery is really finished */ -@@ -8575,7 +8588,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) - } - if (recovery_not_finished) { - dprintf_cont("\n"); -- dprintf("Rebuild has not finished yet, state not changed"); -+ dprintf_cont("Rebuild has not finished yet, map state changes only if raid10 double degradation happens"); - if (a->last_checkpoint < mdi->recovery_start) { - a->last_checkpoint = - mdi->recovery_start; diff --git a/SOURCES/mdadm.rules b/SOURCES/mdadm.rules index e8907c3..b622c6b 100644 --- a/SOURCES/mdadm.rules +++ b/SOURCES/mdadm.rules @@ -42,6 +42,8 @@ ENV{noiswmd}=="?*", GOTO="md_imsm_inc_end" ENV{nodmraid}=="?*", GOTO="md_imsm_inc_end" SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="isw_raid_member", \ RUN+="/sbin/mdadm -I $env{DEVNAME}" +SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="ddf_raid_member", \ + RUN+="/sbin/mdadm -I $env{DEVNAME}" SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \ ENV{ID_FS_TYPE}=="isw_raid_member", \ RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}" diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec index 2417ec3..9250d14 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.1 -Release: 4%{?dist} +Release: 9%{?dist} Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz Source1: mdmonitor.init Source2: raid-check @@ -12,12 +12,33 @@ Source6: mdmonitor.service Source7: mdadm.conf Source8: mdadm_event.conf -Patch1: add-tech-preview-msg-to-raid1-cluster.patch -Patch2: imsm-update-metadata-correctly-while-raid10-double-degradation.patch +Patch1: 0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch +Patch2: 0002-Document-PART-POLICY-lines.patch +Patch3: 0003-policy-support-devices-with-multiple-paths.patch +Patch4: 0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch +Patch5: 0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch +Patch6: 0006-imsm-update-metadata-correctly-while-raid10-double-d.patch +Patch7: 0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch +Patch8: 0008-Grow-avoid-overflow-in-compute_backup_blocks.patch +Patch9: 0009-Grow-report-correct-new-chunk-size.patch +Patch10: 0010-policy.c-prevent-NULL-pointer-referencing.patch +Patch11: 0011-policy.c-Fix-for-compiler-error.patch +Patch12: 0012-imsm-finish-recovery-when-drive-with-rebuild-fails.patch +Patch13: 0013-imsm-fix-reshape-for-2TB-drives.patch +Patch14: 0014-Fix-spelling-typos.patch +Patch15: 0015-Detail.c-do-not-skip-first-character-when-calling-xs.patch +Patch16: 0016-Fix-reshape-for-decreasing-data-offset.patch +Patch17: 0017-mdadm-tests-add-one-test-case-for-failfast-of-raid1.patch +Patch18: 0018-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch +Patch19: 0019-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch +Patch20: 0020-Assemble-Fix-starting-array-with-initial-reshape-che.patch +Patch21: 0021-add-missing-units-to-examine.patch +Patch22: 0022-imsm-fix-spare-activation-for-old-matrix-arrays.patch +Patch23: 0023-Create-Block-rounding-size-to-max.patch +Patch24: 0024-udev-Add-udev-rules-to-create-by-partuuid-for-md-dev.patch # RHEL customization patches Patch97: mdadm-3.3-udev.patch Patch98: mdadm-2.5.2-static.patch -Patch99: disable-journal.patch URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -44,12 +65,34 @@ file can be used to help with some common tasks. %prep %setup -q -%patch1 -p1 -b .preview -%patch2 -p1 -b .degradation +%patch1 -p1 -b .0001 +%patch2 -p1 -b .0002 +%patch3 -p1 -b .0003 +%patch4 -p1 -b .0004 +%patch5 -p1 -b .0005 +%patch6 -p1 -b .0006 +%patch7 -p1 -b .0007 +%patch8 -p1 -b .0008 +%patch9 -p1 -b .0009 +%patch10 -p1 -b .0010 +%patch11 -p1 -b .0011 +%patch12 -p1 -b .0012 +%patch13 -p1 -b .0013 +%patch14 -p1 -b .0014 +%patch15 -p1 -b .0015 +%patch16 -p1 -b .0016 +%patch17 -p1 -b .0017 +%patch18 -p1 -b .0018 +%patch19 -p1 -b .0019 +%patch20 -p1 -b .0020 +%patch21 -p1 -b .0021 +%patch22 -p1 -b .0022 +%patch23 -p1 -b .0023 +%patch24 -p1 -b .0024 + # RHEL customization patches %patch97 -p1 -b .udev %patch98 -p1 -b .static -%patch99 -p1 -b .journal %build make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon @@ -111,6 +154,26 @@ rm -rf %{buildroot} /etc/libreport/events.d/* %changelog +* Thu Jul 10 2019 Xiao Ni - 4.1.9 +- Add --incremental for ddf member disk in udev rule +- Resolves rhbz#1693583 + +* Thu Jun 13 2019 Xiao Ni - 4.1.8 +- Update to latest upstream +- Resolves rhbz#1661203 + +* Wed Jun 12 2019 Xiao Ni - 4.1.7 +- Fix gating test error +- Resolves rhbz#1682396 + +* Thu May 23 2019 Xiao Ni - 4.1.6 +- Enable raid5 journal +- Resolves rhbz#1691202 + +* Fri Apr 12 2019 Xiao Ni - 4.1.5 +- add gating tests +- Resolves rhbz#1682396 + * Fri Jan 11 2019 Xiao Ni - 4.1.4 - Disable raid5 journal - Resolves rhbz#1664961