From 5d54666d5bd6eb25a5f8eb7bd7fbeddf33d2c747 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 23 2020 22:39:39 +0000 Subject: import mdadm-4.1-13.el8 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88c376b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/mdadm-4.1.tar.xz diff --git a/.mdadm.metadata b/.mdadm.metadata new file mode 100644 index 0000000..b2205ce --- /dev/null +++ b/.mdadm.metadata @@ -0,0 +1 @@ +4bbbd02674ac67dc9773f41aace7677aa5374c1c SOURCES/mdadm-4.1.tar.xz 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/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch b/SOURCES/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch new file mode 100644 index 0000000..7b03614 --- /dev/null +++ b/SOURCES/0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch @@ -0,0 +1,109 @@ +From ae7d61e35ec2ab6361c3e509a8db00698ef3396f Mon Sep 17 00:00:00 2001 +From: Artur Paszkiewicz +Date: Tue, 7 May 2019 16:08:47 +0200 +Subject: [RHEL7.8 PATCH V2 25/47] mdmon: fix wrong array state when disk fails + during mdmon startup + +If a member drive disappears and is set faulty by the kernel during +mdmon startup, after ss->load_container() but before manage_new(), mdmon +will try to readd the faulty drive to the array and start rebuilding. +Metadata on the active drive is updated, but the faulty drive is not +removed from the array and is left in a "blocked" state and any write +request to the array will block. If the faulty drive reappears in the +system e.g. after a reboot, the array will not assemble because metadata +on the drives will be incompatible (at least on imsm). + +Fix this by adding a new option for sysfs_read(): "GET_DEVS_ALL". This +is an extension for the "GET_DEVS" option and causes all member devices +to be returned, even if the associated block device has been removed. +Use this option in manage_new() to include the faulty device on the +active_array's devices list. Mdmon will then properly remove the faulty +device from the array and update the metadata to reflect the degraded +state. + +Signed-off-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + managemon.c | 2 +- + mdadm.h | 1 + + super-intel.c | 2 +- + sysfs.c | 23 ++++++++++++++--------- + 4 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/managemon.c b/managemon.c +index 29b91ba..200cf83 100644 +--- a/managemon.c ++++ b/managemon.c +@@ -678,7 +678,7 @@ static void manage_new(struct mdstat_ent *mdstat, + mdi = sysfs_read(-1, mdstat->devnm, + GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT| + GET_SAFEMODE|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE| +- GET_LAYOUT); ++ GET_LAYOUT|GET_DEVS_ALL); + + if (!mdi) + return; +diff --git a/mdadm.h b/mdadm.h +index 705bd9b..427cc52 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -647,6 +647,7 @@ enum sysfs_read_flags { + GET_ERROR = (1 << 24), + GET_ARRAY_STATE = (1 << 25), + GET_CONSISTENCY_POLICY = (1 << 26), ++ GET_DEVS_ALL = (1 << 27), + }; + + /* If fd >= 0, get the array it is open on, +diff --git a/super-intel.c b/super-intel.c +index 2ba045a..4fd5e84 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -8560,7 +8560,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) + disk = get_imsm_disk(super, ord_to_idx(ord)); + + /* check for new failures */ +- if (state & DS_FAULTY) { ++ if (disk && (state & DS_FAULTY)) { + if (mark_failure(super, dev, disk, ord_to_idx(ord))) + super->updates_pending++; + } +diff --git a/sysfs.c b/sysfs.c +index df6fdda..2dd9ab6 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -313,17 +313,22 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) + /* assume this is a stale reference to a hot + * removed device + */ +- free(dev); +- continue; ++ if (!(options & GET_DEVS_ALL)) { ++ free(dev); ++ continue; ++ } ++ } else { ++ sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor); + } +- sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor); + +- /* special case check for block devices that can go 'offline' */ +- strcpy(dbase, "block/device/state"); +- if (load_sys(fname, buf, sizeof(buf)) == 0 && +- strncmp(buf, "offline", 7) == 0) { +- free(dev); +- continue; ++ if (!(options & GET_DEVS_ALL)) { ++ /* special case check for block devices that can go 'offline' */ ++ strcpy(dbase, "block/device/state"); ++ if (load_sys(fname, buf, sizeof(buf)) == 0 && ++ strncmp(buf, "offline", 7) == 0) { ++ free(dev); ++ continue; ++ } + } + + /* finally add this disk to the array */ +-- +2.7.5 + diff --git a/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch b/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch new file mode 100644 index 0000000..8aaa33f --- /dev/null +++ b/SOURCES/0026-Enable-probe_roms-to-scan-more-than-6-roms.patch @@ -0,0 +1,212 @@ +From 4ec389e3f0c1233f5aa2d5b4e63d96e33d2a37f0 Mon Sep 17 00:00:00 2001 +From: Roman Sobanski +Date: Tue, 2 Jul 2019 13:29:27 +0200 +Subject: [RHEL7.8 PATCH V2 26/47] Enable probe_roms to scan more than 6 roms. + +In some cases if more than 6 oroms exist, resource for particular +controller may not be found. Change method for storing +adapter_rom_resources from array to list. + +Signed-off-by: Roman Sobanski +Signed-off-by: Jes Sorensen +--- + probe_roms.c | 98 ++++++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 56 insertions(+), 42 deletions(-) + +diff --git a/probe_roms.c b/probe_roms.c +index b0b0883..7ea04c7 100644 +--- a/probe_roms.c ++++ b/probe_roms.c +@@ -35,6 +35,9 @@ static const int rom_len = 0xf0000 - 0xc0000; /* option-rom memory region */ + static int _sigbus; + static unsigned long rom_align; + ++static void roms_deinit(void); ++static int roms_init(void); ++ + static void sigbus(int sig) + { + _sigbus = 1; +@@ -75,6 +78,7 @@ void probe_roms_exit(void) + munmap(rom_mem, rom_len); + rom_mem = MAP_FAILED; + } ++ roms_deinit(); + } + + int probe_roms_init(unsigned long align) +@@ -91,6 +95,9 @@ int probe_roms_init(unsigned long align) + else + return -1; + ++ if (roms_init()) ++ return -1; ++ + if (signal(SIGBUS, sigbus) == SIG_ERR) + rc = -1; + if (rc == 0) { +@@ -131,6 +138,7 @@ struct resource { + unsigned long end; + unsigned long data; + const char *name; ++ struct resource *next; + }; + + static struct resource system_rom_resource = { +@@ -147,37 +155,7 @@ static struct resource extension_rom_resource = { + .end = 0xeffff, + }; + +-static struct resource adapter_rom_resources[] = { { +- .name = "Adapter ROM", +- .start = 0xc8000, +- .data = 0, +- .end = 0, +-}, { +- .name = "Adapter ROM", +- .start = 0, +- .data = 0, +- .end = 0, +-}, { +- .name = "Adapter ROM", +- .start = 0, +- .data = 0, +- .end = 0, +-}, { +- .name = "Adapter ROM", +- .start = 0, +- .data = 0, +- .end = 0, +-}, { +- .name = "Adapter ROM", +- .start = 0, +- .data = 0, +- .end = 0, +-}, { +- .name = "Adapter ROM", +- .start = 0, +- .data = 0, +- .end = 0, +-} }; ++static struct resource *adapter_rom_resources; + + static struct resource video_rom_resource = { + .name = "Video ROM", +@@ -186,8 +164,35 @@ static struct resource video_rom_resource = { + .end = 0xc7fff, + }; + ++static int roms_init(void) ++{ ++ adapter_rom_resources = malloc(sizeof(struct resource)); ++ if (adapter_rom_resources == NULL) ++ return 1; ++ adapter_rom_resources->name = "Adapter ROM"; ++ adapter_rom_resources->start = 0xc8000; ++ adapter_rom_resources->data = 0; ++ adapter_rom_resources->end = 0; ++ adapter_rom_resources->next = NULL; ++ return 0; ++} ++ ++static void roms_deinit(void) ++{ ++ struct resource *res; ++ ++ res = adapter_rom_resources; ++ while (res) { ++ struct resource *tmp = res; ++ ++ res = res->next; ++ free(tmp); ++ } ++} ++ + #define ROMSIGNATURE 0xaa55 + ++ + static int romsignature(const unsigned char *rom) + { + const unsigned short * const ptr = (const unsigned short *)rom; +@@ -208,16 +213,14 @@ static int romchecksum(const unsigned char *rom, unsigned long length) + int scan_adapter_roms(scan_fn fn) + { + /* let scan_fn examing each of the adapter roms found by probe_roms */ +- unsigned int i; ++ struct resource *res = adapter_rom_resources; + int found; + + if (rom_fd < 0) + return 0; + + found = 0; +- for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) { +- struct resource *res = &adapter_rom_resources[i]; +- ++ while (res) { + if (res->start) { + found = fn(isa_bus_to_virt(res->start), + isa_bus_to_virt(res->end), +@@ -226,6 +229,7 @@ int scan_adapter_roms(scan_fn fn) + break; + } else + break; ++ res = res->next; + } + + return found; +@@ -241,14 +245,14 @@ void probe_roms(void) + const void *rom; + unsigned long start, length, upper; + unsigned char c; +- unsigned int i; ++ struct resource *res = adapter_rom_resources; + __u16 val=0; + + if (rom_fd < 0) + return; + + /* video rom */ +- upper = adapter_rom_resources[0].start; ++ upper = res->start; + for (start = video_rom_resource.start; start < upper; start += rom_align) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) +@@ -283,8 +287,9 @@ void probe_roms(void) + upper = extension_rom_resource.start; + } + ++ struct resource *prev_res = res; + /* check for adapter roms on 2k boundaries */ +- for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += rom_align) { ++ for (; start < upper; start += rom_align) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; +@@ -308,10 +313,19 @@ void probe_roms(void) + if (!length || start + length > upper || !romchecksum(rom, length)) + continue; + +- adapter_rom_resources[i].start = start; +- adapter_rom_resources[i].data = start + (unsigned long) val; +- adapter_rom_resources[i].end = start + length - 1; ++ if (res == NULL) { ++ res = calloc(1, sizeof(struct resource)); ++ if (res == NULL) ++ return; ++ prev_res->next = res; ++ } ++ ++ res->start = start; ++ res->data = start + (unsigned long)val; ++ res->end = start + length - 1; + +- start = adapter_rom_resources[i++].end & ~(rom_align - 1); ++ start = res->end & ~(rom_align - 1); ++ prev_res = res; ++ res = res->next; + } + } +-- +2.7.5 + diff --git a/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch b/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch new file mode 100644 index 0000000..6783118 --- /dev/null +++ b/SOURCES/0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch @@ -0,0 +1,39 @@ +From a4f7290c20c2ff78328c9db0b18029165cfb05b2 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 Jul 2019 13:26:08 -0400 +Subject: [RHEL7.8 PATCH V2 27/47] super-intel: Fix issue with abs() being + irrelevant + +gcc9 complains about subtracting unsigned from unsigned and code +assuming the result can be negative. + +Signed-off-by: Jes Sorensen +--- + super-intel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 4fd5e84..230e164 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2875,7 +2875,7 @@ static unsigned long long calc_component_size(struct imsm_map *map, + { + unsigned long long component_size; + unsigned long long dev_size = imsm_dev_size(dev); +- unsigned long long calc_dev_size = 0; ++ long long calc_dev_size = 0; + unsigned int member_disks = imsm_num_data_members(map); + + if (member_disks == 0) +@@ -2889,7 +2889,7 @@ static unsigned long long calc_component_size(struct imsm_map *map, + * 2048 blocks per each device. If the difference is higher it means + * that array size was expanded and num_data_stripes was not updated. + */ +- if ((unsigned int)abs(calc_dev_size - dev_size) > ++ if (llabs(calc_dev_size - (long long)dev_size) > + (1 << SECT_PER_MB_SHIFT) * member_disks) { + component_size = dev_size / member_disks; + dprintf("Invalid num_data_stripes in metadata; expected=%llu, found=%llu\n", +-- +2.7.5 + diff --git a/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch b/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch new file mode 100644 index 0000000..7daa513 --- /dev/null +++ b/SOURCES/0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch @@ -0,0 +1,57 @@ +From 7039d1f8200b9599b23db5953934fdb43b0442e0 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 Jul 2019 14:15:38 -0400 +Subject: [RHEL7.8 PATCH V2 28/47] mdadm.h: Introduced unaligned + {get,put}_unaligned{16,32}() + +We need these to avoid gcc9 going all crazy on us. + +Signed-off-by: Jes Sorensen +--- + mdadm.h | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/mdadm.h b/mdadm.h +index 427cc52..0fa9e1b 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -192,6 +192,36 @@ struct dlm_lksb { + #endif /* __KLIBC__ */ + + /* ++ * Partially stolen from include/linux/unaligned/packed_struct.h ++ */ ++struct __una_u16 { __u16 x; } __attribute__ ((packed)); ++struct __una_u32 { __u32 x; } __attribute__ ((packed)); ++ ++static inline __u16 __get_unaligned16(const void *p) ++{ ++ const struct __una_u16 *ptr = (const struct __una_u16 *)p; ++ return ptr->x; ++} ++ ++static inline __u32 __get_unaligned32(const void *p) ++{ ++ const struct __una_u32 *ptr = (const struct __una_u32 *)p; ++ return ptr->x; ++} ++ ++static inline void __put_unaligned16(__u16 val, void *p) ++{ ++ struct __una_u16 *ptr = (struct __una_u16 *)p; ++ ptr->x = val; ++} ++ ++static inline void __put_unaligned32(__u32 val, void *p) ++{ ++ struct __una_u32 *ptr = (struct __una_u32 *)p; ++ ptr->x = val; ++} ++ ++/* + * Check at compile time that something is of a particular type. + * Always evaluates to 1 so you may use it easily in comparisons. + */ +-- +2.7.5 + diff --git a/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch b/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch new file mode 100644 index 0000000..0b643b1 --- /dev/null +++ b/SOURCES/0029-super-intel-Use-put_unaligned-in-split_ull.patch @@ -0,0 +1,38 @@ +From 486720e0c2418e7e2e0a16221f7c42a308622254 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Tue, 9 Jul 2019 14:49:22 -0400 +Subject: [RHEL7.8 PATCH V2 29/47] super-intel: Use put_unaligned in split_ull + +Shut up some gcc9 errors by using put_unaligned() accessors. Not pretty, +but better than it was. + +Also correct to the correct swap macros. + +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 230e164..d7e8a65 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -1165,12 +1165,12 @@ static int count_memberships(struct dl *dl, struct intel_super *super) + + static __u32 imsm_min_reserved_sectors(struct intel_super *super); + +-static int split_ull(unsigned long long n, __u32 *lo, __u32 *hi) ++static int split_ull(unsigned long long n, void *lo, void *hi) + { + if (lo == 0 || hi == 0) + return 1; +- *lo = __le32_to_cpu((unsigned)n); +- *hi = __le32_to_cpu((unsigned)(n >> 32)); ++ __put_unaligned32(__cpu_to_le32((__u32)n), lo); ++ __put_unaligned32(__cpu_to_le32((n >> 32)), hi); + return 0; + } + +-- +2.7.5 + diff --git a/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch b/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch new file mode 100644 index 0000000..8941a5e --- /dev/null +++ b/SOURCES/0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch @@ -0,0 +1,345 @@ +From b06815989179e0f153e44e4336290e655edce9a1 Mon Sep 17 00:00:00 2001 +From: Mariusz Dabrowski +Date: Wed, 10 Jul 2019 13:38:53 +0200 +Subject: [RHEL7.8 PATCH V2 30/47] mdadm: load default sysfs attributes after + assemblation + +Added new type of line to mdadm.conf which allows to specify values of +sysfs attributes for MD devices that should be loaded after the array is +assembled. Each line is interpreted as list of structures containing +sysname of MD device (md126 etc.) and list of sysfs attributes and their +values. + +Signed-off-by: Mariusz Dabrowski +Signed-off-by: Krzysztof Smolinski +Signed-off-by: Jes Sorensen +--- + Assemble.c | 12 +++-- + Incremental.c | 1 + + config.c | 7 ++- + mdadm.conf.5 | 25 ++++++++++ + mdadm.h | 3 ++ + sysfs.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 202 insertions(+), 4 deletions(-) + +diff --git a/Assemble.c b/Assemble.c +index 420c7b3..b2e6914 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1063,9 +1063,12 @@ static int start_array(int mdfd, + mddev, okcnt + sparecnt + journalcnt, + okcnt + sparecnt + journalcnt == 1 ? "" : "s"); + if (okcnt < (unsigned)content->array.raid_disks) +- fprintf(stderr, " (out of %d)", ++ fprintf(stderr, " (out of %d)\n", + content->array.raid_disks); +- fprintf(stderr, "\n"); ++ else { ++ fprintf(stderr, "\n"); ++ sysfs_rules_apply(mddev, content); ++ } + } + + if (st->ss->validate_container) { +@@ -1139,6 +1142,7 @@ static int start_array(int mdfd, + rv = ioctl(mdfd, RUN_ARRAY, NULL); + reopen_mddev(mdfd); /* drop O_EXCL */ + if (rv == 0) { ++ sysfs_rules_apply(mddev, content); + if (c->verbose >= 0) { + pr_err("%s has been started with %d drive%s", + mddev, okcnt, okcnt==1?"":"s"); +@@ -2130,10 +2134,12 @@ int assemble_container_content(struct supertype *st, int mdfd, + pr_err("array %s now has %d device%s", + chosen_name, working + preexist, + working + preexist == 1 ? "":"s"); +- else ++ else { ++ sysfs_rules_apply(chosen_name, content); + pr_err("Started %s with %d device%s", + chosen_name, working + preexist, + working + preexist == 1 ? "":"s"); ++ } + if (preexist) + fprintf(stderr, " (%d new)", working); + if (expansion) +diff --git a/Incremental.c b/Incremental.c +index d4d3c35..98dbcd9 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -480,6 +480,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, + pr_err("container %s now has %d device%s\n", + chosen_name, info.array.working_disks, + info.array.working_disks == 1?"":"s"); ++ sysfs_rules_apply(chosen_name, &info); + wait_for(chosen_name, mdfd); + if (st->ss->external) + strcpy(devnm, fd2devnm(mdfd)); +diff --git a/config.c b/config.c +index e14eae0..7592b2d 100644 +--- a/config.c ++++ b/config.c +@@ -80,7 +80,8 @@ char DefaultAltConfFile[] = CONFFILE2; + char DefaultAltConfDir[] = CONFFILE2 ".d"; + + enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev, +- Homehost, HomeCluster, AutoMode, Policy, PartPolicy, LTEnd }; ++ Homehost, HomeCluster, AutoMode, Policy, PartPolicy, Sysfs, ++ LTEnd }; + char *keywords[] = { + [Devices] = "devices", + [Array] = "array", +@@ -93,6 +94,7 @@ char *keywords[] = { + [AutoMode] = "auto", + [Policy] = "policy", + [PartPolicy]="part-policy", ++ [Sysfs] = "sysfs", + [LTEnd] = NULL + }; + +@@ -764,6 +766,9 @@ void conf_file(FILE *f) + case PartPolicy: + policyline(line, rule_part); + break; ++ case Sysfs: ++ sysfsline(line); ++ break; + default: + pr_err("Unknown keyword %s\n", line); + } +diff --git a/mdadm.conf.5 b/mdadm.conf.5 +index 47c962a..27dbab1 100644 +--- a/mdadm.conf.5 ++++ b/mdadm.conf.5 +@@ -587,6 +587,26 @@ be based on the domain, but with + appended, when N is the partition number for the partition that was + found. + ++.TP ++.B SYSFS ++The SYSFS line lists custom values of MD device's sysfs attributes which will be ++stored in sysfs after the array is assembled. Multiple lines are allowed and each ++line has to contain the uuid or the name of the device to which it relates. ++.RS 4 ++.TP ++.B uuid= ++hexadecimal identifier of MD device. This has to match the uuid stored in the ++superblock. ++.TP ++.B name= ++name of the MD device as was given to ++.I mdadm ++when the array was created. It will be ignored if ++.B uuid ++is not empty. ++.TP ++.RS 7 ++ + .SH EXAMPLE + DEVICE /dev/sd[bcdjkl]1 + .br +@@ -657,6 +677,11 @@ CREATE group=system mode=0640 auto=part\-8 + HOMEHOST + .br + AUTO +1.x homehost \-all ++.br ++SYSFS name=/dev/md/raid5 group_thread_cnt=4 sync_speed_max=1000000 ++.br ++SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4 ++sync_speed_max=1000000 + + .SH SEE ALSO + .BR mdadm (8), +diff --git a/mdadm.h b/mdadm.h +index 0fa9e1b..c36d7fd 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1322,6 +1322,9 @@ void domain_add(struct domainlist **domp, char *domain); + extern void policy_save_path(char *id_path, struct map_ent *array); + extern int policy_check_path(struct mdinfo *disk, struct map_ent *array); + ++extern void sysfs_rules_apply(char *devnm, struct mdinfo *dev); ++extern void sysfsline(char *line); ++ + #if __GNUC__ < 3 + struct stat64; + #endif +diff --git a/sysfs.c b/sysfs.c +index 2dd9ab6..c313781 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -26,9 +26,22 @@ + #include "mdadm.h" + #include + #include ++#include "dlink.h" + + #define MAX_SYSFS_PATH_LEN 120 + ++struct dev_sysfs_rule { ++ struct dev_sysfs_rule *next; ++ char *devname; ++ int uuid[4]; ++ int uuid_set; ++ struct sysfs_entry { ++ struct sysfs_entry *next; ++ char *name; ++ char *value; ++ } *entry; ++}; ++ + int load_sys(char *path, char *buf, int len) + { + int fd = open(path, O_RDONLY); +@@ -999,3 +1012,148 @@ int sysfs_wait(int fd, int *msec) + } + return n; + } ++ ++int sysfs_rules_apply_check(const struct mdinfo *sra, ++ const struct sysfs_entry *ent) ++{ ++ /* Check whether parameter is regular file, ++ * exists and is under specified directory. ++ */ ++ char fname[MAX_SYSFS_PATH_LEN]; ++ char dname[MAX_SYSFS_PATH_LEN]; ++ char resolved_path[PATH_MAX]; ++ char resolved_dir[PATH_MAX]; ++ ++ if (sra == NULL || ent == NULL) ++ return -1; ++ ++ snprintf(dname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md/", sra->sys_name); ++ snprintf(fname, MAX_SYSFS_PATH_LEN, "%s/%s", dname, ent->name); ++ ++ if (realpath(fname, resolved_path) == NULL || ++ realpath(dname, resolved_dir) == NULL) ++ return -1; ++ ++ if (strncmp(resolved_dir, resolved_path, ++ strnlen(resolved_dir, PATH_MAX)) != 0) ++ return -1; ++ ++ return 0; ++} ++ ++static struct dev_sysfs_rule *sysfs_rules; ++ ++void sysfs_rules_apply(char *devnm, struct mdinfo *dev) ++{ ++ struct dev_sysfs_rule *rules = sysfs_rules; ++ ++ while (rules) { ++ struct sysfs_entry *ent = rules->entry; ++ int match = 0; ++ ++ if (!rules->uuid_set) { ++ if (rules->devname) ++ match = strcmp(devnm, rules->devname) == 0; ++ } else { ++ match = memcmp(dev->uuid, rules->uuid, ++ sizeof(int[4])) == 0; ++ } ++ ++ while (match && ent) { ++ if (sysfs_rules_apply_check(dev, ent) < 0) ++ pr_err("SYSFS: failed to write '%s' to '%s'\n", ++ ent->value, ent->name); ++ else ++ sysfs_set_str(dev, NULL, ent->name, ent->value); ++ ent = ent->next; ++ } ++ rules = rules->next; ++ } ++} ++ ++static void sysfs_rule_free(struct dev_sysfs_rule *rule) ++{ ++ struct sysfs_entry *entry; ++ ++ while (rule) { ++ struct dev_sysfs_rule *tmp = rule->next; ++ ++ entry = rule->entry; ++ while (entry) { ++ struct sysfs_entry *tmp = entry->next; ++ ++ free(entry->name); ++ free(entry->value); ++ free(entry); ++ entry = tmp; ++ } ++ ++ if (rule->devname) ++ free(rule->devname); ++ free(rule); ++ rule = tmp; ++ } ++} ++ ++void sysfsline(char *line) ++{ ++ struct dev_sysfs_rule *sr; ++ char *w; ++ ++ sr = xcalloc(1, sizeof(*sr)); ++ for (w = dl_next(line); w != line ; w = dl_next(w)) { ++ if (strncasecmp(w, "name=", 5) == 0) { ++ char *devname = w + 5; ++ ++ if (strncmp(devname, "/dev/md/", 8) == 0) { ++ if (sr->devname) ++ pr_err("Only give one device per SYSFS line: %s\n", ++ devname); ++ else ++ sr->devname = xstrdup(devname); ++ } else { ++ pr_err("%s is an invalid name for an md device - ignored.\n", ++ devname); ++ } ++ } else if (strncasecmp(w, "uuid=", 5) == 0) { ++ char *uuid = w + 5; ++ ++ if (sr->uuid_set) { ++ pr_err("Only give one uuid per SYSFS line: %s\n", ++ uuid); ++ } else { ++ if (parse_uuid(w + 5, sr->uuid) && ++ memcmp(sr->uuid, uuid_zero, ++ sizeof(int[4])) != 0) ++ sr->uuid_set = 1; ++ else ++ pr_err("Invalid uuid: %s\n", uuid); ++ } ++ } else { ++ struct sysfs_entry *prop; ++ ++ char *sep = strchr(w, '='); ++ ++ if (sep == NULL || *(sep + 1) == 0) { ++ pr_err("Cannot parse \"%s\" - ignoring.\n", w); ++ continue; ++ } ++ ++ prop = xmalloc(sizeof(*prop)); ++ prop->value = xstrdup(sep + 1); ++ *sep = 0; ++ prop->name = xstrdup(w); ++ prop->next = sr->entry; ++ sr->entry = prop; ++ } ++ } ++ ++ if (!sr->devname && !sr->uuid_set) { ++ pr_err("Device name not found in sysfs config entry - ignoring.\n"); ++ sysfs_rule_free(sr); ++ return; ++ } ++ ++ sr->next = sysfs_rules; ++ sysfs_rules = sr; ++} +-- +2.7.5 + diff --git a/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch b/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch new file mode 100644 index 0000000..3ef846a --- /dev/null +++ b/SOURCES/0031-mdadm.h-include-sysmacros.h-unconditionally.patch @@ -0,0 +1,34 @@ +From 452dc4d13a012cdcb05088c0dbc699959c4d6c73 Mon Sep 17 00:00:00 2001 +From: Baruch Siach +Date: Tue, 6 Aug 2019 16:05:23 +0300 +Subject: [RHEL7.8 PATCH V2 31/47] mdadm.h: include sysmacros.h unconditionally + +musl libc now also requires sys/sysmacros.h for the major/minor macros. +All supported libc implementations carry sys/sysmacros.h, including +diet-libc, klibc, and uclibc-ng. + +Cc: Hauke Mehrtens +Signed-off-by: Baruch Siach +Signed-off-by: Jes Sorensen +--- + mdadm.h | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/mdadm.h b/mdadm.h +index c36d7fd..d61a9ca 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -45,10 +45,8 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); + #include + #include + #include +-#ifdef __GLIBC__ + /* Newer glibc requires sys/sysmacros.h directly for makedev() */ + #include +-#endif + #ifdef __dietlibc__ + #include + /* dietlibc has deprecated random and srandom!! */ +-- +2.7.5 + diff --git a/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch b/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch new file mode 100644 index 0000000..bf58eb9 --- /dev/null +++ b/SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch @@ -0,0 +1,161 @@ +From d11abe4bd5cad39803726ddff1888674e417bda5 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Wed, 31 Jul 2019 13:29:29 +0800 +Subject: [RHEL7.8 PATCH V2 32/47] mdadm: add --no-devices to avoid component + devices detail information + +When people assemble a md raid device with a large number of +component deivces (e.g. 1500 DASD disks), the raid device detail +information generated by 'mdadm --detail --export $devnode' is very +large. It is because the detail information contains information of +all the component disks (even the missing/failed ones). + +In such condition, when udev-md-raid-arrays.rules is triggered and +internally calls "mdadm --detail --no-devices --export $devnode", +user may observe systemd error message ""invalid message length". It +is because the following on-stack raw message buffer in systemd code +is not big enough, + systemd/src/libudev/libudev-monitor.c + _public_ struct udev_device *udev_monito ... + struct ucred *cred; + union { + struct udev_monitor_netlink_header nlh; + char raw[8192]; + } buf; +Even change size of raw[] from 8KB to larger size, it may still be not +enough for detail message of a md raid device with much larger number of +component devices. + +To fix this problem, an extra option '--no-devices' is added (the +original idea is proposed by Neil Brown). When printing detailed +information of a md raid device, if '--no-devices' is specified, then +all component devices information will not be printed, then the output +message size can be restricted to a small number, even with the systemd +only has 8KB on-disk raw buffer, the md raid array udev rules can work +correctly without failure message. + +Signed-off-by: Coly Li +Reviewed-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Detail.c | 24 ++++++++++++++++-------- + ReadMe.c | 1 + + mdadm.c | 4 ++++ + mdadm.h | 2 ++ + 4 files changed, 23 insertions(+), 8 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 20ea03a..ad60434 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -56,7 +56,7 @@ int Detail(char *dev, struct context *c) + */ + int fd = open(dev, O_RDONLY); + mdu_array_info_t array; +- mdu_disk_info_t *disks; ++ mdu_disk_info_t *disks = NULL; + int next; + int d; + time_t atime; +@@ -280,7 +280,7 @@ int Detail(char *dev, struct context *c) + } + map_free(map); + } +- if (sra) { ++ if (!c->no_devices && sra) { + struct mdinfo *mdi; + for (mdi = sra->devs; mdi; mdi = mdi->next) { + char *path; +@@ -655,12 +655,17 @@ This is pretty boring + printf("\n\n"); + } + +- if (array.raid_disks) +- printf(" Number Major Minor RaidDevice State\n"); +- else +- printf(" Number Major Minor RaidDevice\n"); ++ if (!c->no_devices) { ++ if (array.raid_disks) ++ printf(" Number Major Minor RaidDevice State\n"); ++ else ++ printf(" Number Major Minor RaidDevice\n"); ++ } + } +- free(info); ++ ++ /* if --no_devices specified, not print component devices info */ ++ if (c->no_devices) ++ goto skip_devices_state; + + for (d = 0; d < max_disks * 2; d++) { + char *dv; +@@ -747,6 +752,8 @@ This is pretty boring + if (!c->brief) + printf("\n"); + } ++ ++skip_devices_state: + if (spares && c->brief && array.raid_disks) + printf(" spares=%d", spares); + if (c->brief && st && st->sb) +@@ -766,8 +773,9 @@ This is pretty boring + !enough(array.level, array.raid_disks, array.layout, 1, avail)) + rv = 2; + +- free(disks); + out: ++ free(info); ++ free(disks); + close(fd); + free(subarray); + free(avail); +diff --git a/ReadMe.c b/ReadMe.c +index 12ccf83..eaf1042 100644 +--- a/ReadMe.c ++++ b/ReadMe.c +@@ -181,6 +181,7 @@ struct option long_options[] = { + + /* For Detail/Examine */ + {"brief", 0, 0, Brief}, ++ {"no-devices",0, 0, NoDevices}, + {"export", 0, 0, 'Y'}, + {"sparc2.2", 0, 0, Sparc22}, + {"test", 0, 0, 't'}, +diff --git a/mdadm.c b/mdadm.c +index 25a1abd..1fb8086 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -159,6 +159,10 @@ int main(int argc, char *argv[]) + c.brief = 1; + continue; + ++ case NoDevices: ++ c.no_devices = 1; ++ continue; ++ + case 'Y': c.export++; + continue; + +diff --git a/mdadm.h b/mdadm.h +index d61a9ca..43b07d5 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -440,6 +440,7 @@ enum special_options { + NoSharing, + HelpOptions, + Brief, ++ NoDevices, + ManageOpt, + Add, + AddSpare, +@@ -550,6 +551,7 @@ struct context { + int runstop; + int verbose; + int brief; ++ int no_devices; + int force; + char *homehost; + int require_homehost; +-- +2.7.5 + diff --git a/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch b/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch new file mode 100644 index 0000000..53463f0 --- /dev/null +++ b/SOURCES/0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch @@ -0,0 +1,42 @@ +From 1a52f1fc0266d438c996789d4addbfac999a6139 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Wed, 31 Jul 2019 13:29:30 +0800 +Subject: [RHEL7.8 PATCH V2 33/47] udev: add --no-devices option for calling + 'mdadm --detail' + +When creating symlink of a md raid device, the detailed information of +component disks are unnecessary for rule udev-md-raid-arrays.rules. For +md raid devices with huge number of component disks (e.g. 1500 DASD +disks), the detail information of component devices can be very large +and exceed udev monitor's on-stack message buffer. + +This patch adds '--no-devices' option when calling mdadm by, +IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode" + +Now the detailed output won't include component disks information, +and the error message "invalid message length" reported by systemd can +be removed. + +Signed-off-by: Coly Li +Reviewed-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + udev-md-raid-arrays.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index 5b99d58..d391665 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -17,7 +17,7 @@ TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end" + ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" + LABEL="md_ignore_state" + +-IMPORT{program}="BINDIR/mdadm --detail --export $devnode" ++IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode" + ENV{DEVTYPE}=="disk", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}", OPTIONS+="string_escape=replace" + ENV{DEVTYPE}=="disk", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}" + ENV{DEVTYPE}=="disk", ENV{MD_DEVNAME}=="?*", SYMLINK+="md/$env{MD_DEVNAME}" +-- +2.7.5 + diff --git a/SOURCES/0034-imsm-close-removed-drive-fd.patch b/SOURCES/0034-imsm-close-removed-drive-fd.patch new file mode 100644 index 0000000..9abd879 --- /dev/null +++ b/SOURCES/0034-imsm-close-removed-drive-fd.patch @@ -0,0 +1,44 @@ +From 91c97c5432028875db5f8abeddb5cb5f31902001 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 15 Jul 2019 09:25:35 +0200 +Subject: [RHEL7.8 PATCH V2 34/47] imsm: close removed drive fd. + +When member drive fails, managemon prepares metadata update and adds +the drive to disk_mgmt_list with DISK_REMOVE flag. It fills only +minor and major. It is enough to recognize the device later. + +Monitor thread while processing this update will remove the drive from +super only if it is a spare. It never removes failed member from +disks list. As a result, it still keeps opened descriptor to +non-existing device. + +If removed drive is not a spare fill fd in disk_cfg structure +(prepared by managemon), monitor will close fd during freeing it. + +Also set this drive fd to -1 in super to avoid double closing because +monitor will close the fd (if needed) while replacing removed drive +in array. + +Signed-off-by: Mariusz Tkaczyk +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 d7e8a65..a103a3f 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -9200,6 +9200,9 @@ static int add_remove_disk_update(struct intel_super *super) + remove_disk_super(super, + disk_cfg->major, + disk_cfg->minor); ++ } else { ++ disk_cfg->fd = disk->fd; ++ disk->fd = -1; + } + } + /* release allocate disk structure */ +-- +2.7.5 + diff --git a/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch b/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch new file mode 100644 index 0000000..8395e0b --- /dev/null +++ b/SOURCES/0035-mdadm-check-value-returned-by-snprintf-against-error.patch @@ -0,0 +1,46 @@ +From fd5b09c9a9107f0393ce194c4aac6e7b8f163e85 Mon Sep 17 00:00:00 2001 +From: Krzysztof Smolinski +Date: Fri, 16 Aug 2019 11:06:17 +0200 +Subject: [RHEL7.8 PATCH V2 35/47] mdadm: check value returned by snprintf + against errors + +GCC 8 checks possible truncation during snprintf more strictly +than GCC 7 which result in compilation errors. To fix this +problem checking result of snprintf against errors has been added. + +Signed-off-by: Krzysztof Smolinski +Signed-off-by: Jes Sorensen +--- + sysfs.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/sysfs.c b/sysfs.c +index c313781..2995713 100644 +--- a/sysfs.c ++++ b/sysfs.c +@@ -1023,12 +1023,20 @@ int sysfs_rules_apply_check(const struct mdinfo *sra, + char dname[MAX_SYSFS_PATH_LEN]; + char resolved_path[PATH_MAX]; + char resolved_dir[PATH_MAX]; ++ int result; + + if (sra == NULL || ent == NULL) + return -1; + +- snprintf(dname, MAX_SYSFS_PATH_LEN, "/sys/block/%s/md/", sra->sys_name); +- snprintf(fname, MAX_SYSFS_PATH_LEN, "%s/%s", dname, ent->name); ++ result = snprintf(dname, MAX_SYSFS_PATH_LEN, ++ "/sys/block/%s/md/", sra->sys_name); ++ if (result < 0 || result >= MAX_SYSFS_PATH_LEN) ++ return -1; ++ ++ result = snprintf(fname, MAX_SYSFS_PATH_LEN, ++ "%s/%s", dname, ent->name); ++ if (result < 0 || result >= MAX_SYSFS_PATH_LEN) ++ return -1; + + if (realpath(fname, resolved_path) == NULL || + realpath(dname, resolved_dir) == NULL) +-- +2.7.5 + diff --git a/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch b/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch new file mode 100644 index 0000000..3a26484 --- /dev/null +++ b/SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch @@ -0,0 +1,163 @@ +From 43ebc9105e9dafe5145b3e801c05da4736bf6e02 Mon Sep 17 00:00:00 2001 +From: "Guilherme G. Piccoli" +Date: Tue, 3 Sep 2019 16:49:01 -0300 +Subject: [RHEL7.8 PATCH V2 36/47] mdadm: Introduce new array state 'broken' + for raid0/linear + +Currently if a md raid0/linear array gets one or more members removed while +being mounted, kernel keeps showing state 'clean' in the 'array_state' +sysfs attribute. Despite udev signaling the member device is gone, 'mdadm' +cannot issue the STOP_ARRAY ioctl successfully, given the array is mounted. + +Nothing else hints that something is wrong (except that the removed devices +don't show properly in the output of mdadm 'detail' command). There is no +other property to be checked, and if user is not performing reads/writes +to the array, even kernel log is quiet and doesn't give a clue about the +missing member. + +This patch is the mdadm counterpart of kernel new array state 'broken'. +The 'broken' state mimics the state 'clean' in every aspect, being useful +only to distinguish if an array has some member missing. All necessary +paths in mdadm were changed to deal with 'broken' state, and in case the +tool runs in a kernel that is not updated, it'll work normally, i.e., it +doesn't require the 'broken' state in order to work. +Also, this patch changes the way the array state is showed in the 'detail' +command (for raid0/linear only) - now it takes the 'array_state' sysfs +attribute into account instead of only rely in the MD_SB_CLEAN flag. + +Cc: Jes Sorensen +Cc: NeilBrown +Cc: Song Liu +Signed-off-by: Guilherme G. Piccoli +Signed-off-by: Jes Sorensen +--- + Detail.c | 14 ++++++++++++-- + Monitor.c | 8 ++++++-- + maps.c | 1 + + mdadm.h | 1 + + mdmon.h | 2 +- + monitor.c | 4 ++-- + 6 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/Detail.c b/Detail.c +index ad60434..3e61e37 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -81,6 +81,7 @@ int Detail(char *dev, struct context *c) + int external; + int inactive; + int is_container = 0; ++ char *arrayst; + + if (fd < 0) { + pr_err("cannot open %s: %s\n", +@@ -485,9 +486,18 @@ int Detail(char *dev, struct context *c) + else + st = ", degraded"; + ++ if (array.state & (1 << MD_SB_CLEAN)) { ++ if ((array.level == 0) || ++ (array.level == LEVEL_LINEAR)) ++ arrayst = map_num(sysfs_array_states, ++ sra->array_state); ++ else ++ arrayst = "clean"; ++ } else ++ arrayst = "active"; ++ + printf(" State : %s%s%s%s%s%s \n", +- (array.state & (1 << MD_SB_CLEAN)) ? +- "clean" : "active", st, ++ arrayst, st, + (!e || (e->percent < 0 && + e->percent != RESYNC_PENDING && + e->percent != RESYNC_DELAYED)) ? +diff --git a/Monitor.c b/Monitor.c +index 036103f..b527165 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -1055,8 +1055,11 @@ int Wait(char *dev) + } + } + ++/* The state "broken" is used only for RAID0/LINEAR - it's the same as ++ * "clean", but used in case the array has one or more members missing. ++ */ + static char *clean_states[] = { +- "clear", "inactive", "readonly", "read-auto", "clean", NULL }; ++ "clear", "inactive", "readonly", "read-auto", "clean", "broken", NULL }; + + int WaitClean(char *dev, int verbose) + { +@@ -1116,7 +1119,8 @@ int WaitClean(char *dev, int verbose) + rv = read(state_fd, buf, sizeof(buf)); + if (rv < 0) + break; +- if (sysfs_match_word(buf, clean_states) <= 4) ++ if (sysfs_match_word(buf, clean_states) < ++ (int)ARRAY_SIZE(clean_states) - 1) + break; + rv = sysfs_wait(state_fd, &delay); + if (rv < 0 && errno != EINTR) +diff --git a/maps.c b/maps.c +index 02a0474..49b7f2c 100644 +--- a/maps.c ++++ b/maps.c +@@ -150,6 +150,7 @@ mapping_t sysfs_array_states[] = { + { "read-auto", ARRAY_READ_AUTO }, + { "clean", ARRAY_CLEAN }, + { "write-pending", ARRAY_WRITE_PENDING }, ++ { "broken", ARRAY_BROKEN }, + { NULL, ARRAY_UNKNOWN_STATE } + }; + +diff --git a/mdadm.h b/mdadm.h +index 43b07d5..c88ceab 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -373,6 +373,7 @@ struct mdinfo { + ARRAY_ACTIVE, + ARRAY_WRITE_PENDING, + ARRAY_ACTIVE_IDLE, ++ ARRAY_BROKEN, + ARRAY_UNKNOWN_STATE, + } array_state; + struct md_bb bb; +diff --git a/mdmon.h b/mdmon.h +index 818367c..b3d72ac 100644 +--- a/mdmon.h ++++ b/mdmon.h +@@ -21,7 +21,7 @@ + extern const char Name[]; + + enum array_state { clear, inactive, suspended, readonly, read_auto, +- clean, active, write_pending, active_idle, bad_word}; ++ clean, active, write_pending, active_idle, broken, bad_word}; + + enum sync_action { idle, reshape, resync, recover, check, repair, bad_action }; + +diff --git a/monitor.c b/monitor.c +index 81537ed..e0d3be6 100644 +--- a/monitor.c ++++ b/monitor.c +@@ -26,7 +26,7 @@ + + static char *array_states[] = { + "clear", "inactive", "suspended", "readonly", "read-auto", +- "clean", "active", "write-pending", "active-idle", NULL }; ++ "clean", "active", "write-pending", "active-idle", "broken", NULL }; + static char *sync_actions[] = { + "idle", "reshape", "resync", "recover", "check", "repair", NULL + }; +@@ -476,7 +476,7 @@ static int read_and_act(struct active_array *a, fd_set *fds) + a->next_state = clean; + ret |= ARRAY_DIRTY; + } +- if (a->curr_state == clean) { ++ if ((a->curr_state == clean) || (a->curr_state == broken)) { + a->container->ss->set_array_state(a, 1); + } + if (a->curr_state == active || +-- +2.7.5 + diff --git a/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch b/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch new file mode 100644 index 0000000..6c47ae8 --- /dev/null +++ b/SOURCES/0037-mdadm-force-a-uuid-swap-on-big-endian.patch @@ -0,0 +1,40 @@ +From 2c2d9c48d2daf0d78d20494c3779c0f6dc4bfa75 Mon Sep 17 00:00:00 2001 +From: Nigel Croxon +Date: Tue, 24 Sep 2019 11:39:24 -0400 +Subject: [RHEL7.8 PATCH V2 37/47] mdadm: force a uuid swap on big endian + +The code path for metadata 0.90 calls a common routine +fname_from_uuid that uses metadata 1.2. The code expects member +swapuuid to be setup and usable. But it is only setup when using +metadata 1.2. Since the metadata 0.90 did not create swapuuid +and set it. The test (st->ss == &super1) ? 1 : st->ss->swapuuid +fails. The swapuuid is set at compile time based on byte order. +Any call based on metadata 0.90 and on big endian processors, +the --export uuid will be incorrect. + +Signed-Off-by: Nigel Croxon +Signed-off-by: Jes Sorensen +--- + util.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/util.c b/util.c +index c26cf5f..64dd409 100644 +--- a/util.c ++++ b/util.c +@@ -685,8 +685,12 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info, + // 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 ++#if __BYTE_ORDER == BIG_ENDIAN ++ return __fname_from_uuid(info->uuid, 1, buf, sep); ++#else + return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 : + st->ss->swapuuid, buf, sep); ++#endif + } + + int check_ext2(int fd, char *name) +-- +2.7.5 + diff --git a/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch b/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch new file mode 100644 index 0000000..0e2f390 --- /dev/null +++ b/SOURCES/0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch @@ -0,0 +1,99 @@ +From e53cb968691d9e40d83caf5570da3bb7b83c64e1 Mon Sep 17 00:00:00 2001 +From: Guoqing Jiang +Date: Fri, 31 May 2019 10:10:00 +0800 +Subject: [RHEL7.8 PATCH V2 38/47] mdadm/md.4: add the descriptions for bitmap + sysfs nodes + +The sysfs nodes under bitmap are not recorded in md.4, +add them based on md.rst and kernel source code. + +Cc: NeilBrown +Signed-off-by: Guoqing Jiang +Signed-off-by: Jes Sorensen +--- + md.4 | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/md.4 b/md.4 +index 3a1d677..e86707a 100644 +--- a/md.4 ++++ b/md.4 +@@ -1101,6 +1101,75 @@ stripe that requires some "prereading". For fairness this defaults to + maximizes sequential-write throughput at the cost of fairness to threads + doing small or random writes. + ++.TP ++.B md/bitmap/backlog ++The value stored in the file only has any effect on RAID1 when write-mostly ++devices are active, and write requests to those devices are proceed in the ++background. ++ ++This variable sets a limit on the number of concurrent background writes, ++the valid values are 0 to 16383, 0 means that write-behind is not allowed, ++while any other number means it can happen. If there are more write requests ++than the number, new writes will by synchronous. ++ ++.TP ++.B md/bitmap/can_clear ++This is for externally managed bitmaps, where the kernel writes the bitmap ++itself, but metadata describing the bitmap is managed by mdmon or similar. ++ ++When the array is degraded, bits mustn't be cleared. When the array becomes ++optimal again, bit can be cleared, but first the metadata needs to record ++the current event count. So md sets this to 'false' and notifies mdmon, ++then mdmon updates the metadata and writes 'true'. ++ ++There is no code in mdmon to actually do this, so maybe it doesn't even ++work. ++ ++.TP ++.B md/bitmap/chunksize ++The bitmap chunksize can only be changed when no bitmap is active, and ++the value should be power of 2 and at least 512. ++ ++.TP ++.B md/bitmap/location ++This indicates where the write-intent bitmap for the array is stored. ++It can be "none" or "file" or a signed offset from the array metadata ++- measured in sectors. You cannot set a file by writing here - that can ++only be done with the SET_BITMAP_FILE ioctl. ++ ++Write 'none' to 'bitmap/location' will clear bitmap, and the previous ++location value must be write to it to restore bitmap. ++ ++.TP ++.B md/bitmap/max_backlog_used ++This keeps track of the maximum number of concurrent write-behind requests ++for an md array, writing any value to this file will clear it. ++ ++.TP ++.B md/bitmap/metadata ++This can be 'internal' or 'clustered' or 'external'. 'internal' is set ++by default, which means the metadata for bitmap is stored in the first 256 ++bytes of the bitmap space. 'clustered' means separate bitmap metadata are ++used for each cluster node. 'external' means that bitmap metadata is managed ++externally to the kernel. ++ ++.TP ++.B md/bitmap/space ++This shows the space (in sectors) which is available at md/bitmap/location, ++and allows the kernel to know when it is safe to resize the bitmap to match ++a resized array. It should big enough to contain the total bytes in the bitmap. ++ ++For 1.0 metadata, assume we can use up to the superblock if before, else ++to 4K beyond superblock. For other metadata versions, assume no change is ++possible. ++ ++.TP ++.B md/bitmap/time_base ++This shows the time (in seconds) between disk flushes, and is used to looking ++for bits in the bitmap to be cleared. ++ ++The default value is 5 seconds, and it should be an unsigned long value. ++ + .SS KERNEL PARAMETERS + + The md driver recognised several different kernel parameters. +-- +2.7.5 + diff --git a/SOURCES/0039-Init-devlist-as-an-array.patch b/SOURCES/0039-Init-devlist-as-an-array.patch new file mode 100644 index 0000000..12c7fba --- /dev/null +++ b/SOURCES/0039-Init-devlist-as-an-array.patch @@ -0,0 +1,35 @@ +From 8063fd0f9e8abd718bd65928c19bc607cee5acd8 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Mon, 30 Sep 2019 19:47:59 +0800 +Subject: [RHEL7.8 PATCH V2 39/47] Init devlist as an array + +devlist is an string. It will change to an array if there is disk that +is sbd disk. If one device is sbd, it runs devlist=(). +This line code changes devlist from a string to an array. If there is +no sbd device, it can't run this line code. So it will still be a string. +The later codes need an array, rather than an string. So init devlist +as an array to fix this problem. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + clustermd_tests/func.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/clustermd_tests/func.sh b/clustermd_tests/func.sh +index 642cc96..801d604 100644 +--- a/clustermd_tests/func.sh ++++ b/clustermd_tests/func.sh +@@ -39,6 +39,9 @@ fetch_devlist() + devlist=($(ls /dev/disk/by-path/*$ISCSI_ID*)) + fi + # sbd disk cannot use in testing ++ # Init devlist as an array ++ i='' ++ devlist=(${devlist[@]#$i}) + for i in ${devlist[@]} + do + sbd -d $i dump &> /dev/null +-- +2.7.5 + diff --git a/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch b/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch new file mode 100644 index 0000000..c47173d --- /dev/null +++ b/SOURCES/0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch @@ -0,0 +1,31 @@ +From 611093148574164fcf4f24f8c076d09473f655d7 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Mon, 30 Sep 2019 19:48:00 +0800 +Subject: [RHEL7.8 PATCH V2 40/47] Don't need to check recovery after re-add + when no I/O writes to raid + +If there is no write I/O between removing member disk and re-add it, there is no +recovery after re-adding member disk. + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + clustermd_tests/02r1_Manage_re-add | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/clustermd_tests/02r1_Manage_re-add b/clustermd_tests/02r1_Manage_re-add +index dd9c416..d0d13e5 100644 +--- a/clustermd_tests/02r1_Manage_re-add ++++ b/clustermd_tests/02r1_Manage_re-add +@@ -9,8 +9,6 @@ check all state UU + check all dmesg + mdadm --manage $md0 --fail $dev0 --remove $dev0 + mdadm --manage $md0 --re-add $dev0 +-check $NODE1 recovery +-check all wait + check all state UU + check all dmesg + stop_md all $md0 +-- +2.7.5 + diff --git a/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch b/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch new file mode 100644 index 0000000..099b937 --- /dev/null +++ b/SOURCES/0041-udev-allow-for-udev-attribute-reading-bug.patch @@ -0,0 +1,47 @@ +From 7bd59e7926c6921121087eb067befaa896c900a4 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 18 Sep 2019 15:12:55 +1000 +Subject: [RHEL7.8 PATCH V2 41/47] udev: allow for udev attribute reading bug. + +There is a bug in udev (which will hopefully get fixed, but +we should allow for it anways). +When reading a sysfs attribute, it first reads the whole +value of the attribute, then reads again expecting to get +a read of 0 bytes, like you would with an ordinary file. +If the sysfs attribute changed between these two reads, it can +get a mixture of two values. + +In particular, if it reads when 'array_state' is changing from +'clear' to 'inactive', it can find the value as "clear\nve". + +This causes the test for "|clear|active" to fail, so systemd is allowed +to think that the array is ready - when it isn't. + +So change the pattern to allow for this but adding a wildcard at +the end. +Also don't allow for an empty string - reading array_state will +never return an empty string - if it exists at all, it will be +non-empty. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + udev-md-raid-arrays.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index d391665..c8fa8e8 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -14,7 +14,7 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state" + # never leave state 'inactive' + ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state" + TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end" +-ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" ++ATTR{md/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" + LABEL="md_ignore_state" + + IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode" +-- +2.7.5 + diff --git a/SOURCES/0042-imsm-save-current_vol-number.patch b/SOURCES/0042-imsm-save-current_vol-number.patch new file mode 100644 index 0000000..5699f84 --- /dev/null +++ b/SOURCES/0042-imsm-save-current_vol-number.patch @@ -0,0 +1,40 @@ +From b6180160f78f0182b296bdceed6419b26a6fccc7 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 4 Oct 2019 12:07:28 +0200 +Subject: [RHEL7.8 PATCH V2 42/47] imsm: save current_vol number + +The imsm container_content routine will set curr_volume index in super +for getting volume information. This flag has never been restored to +original value, later other function may rely on it. + +Restore this flag to original value. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + super-intel.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/super-intel.c b/super-intel.c +index a103a3f..e02bbd7 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7826,6 +7826,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + int sb_errors = 0; + struct dl *d; + int spare_disks = 0; ++ int current_vol = super->current_vol; + + /* do not assemble arrays when not all attributes are supported */ + if (imsm_check_attributes(mpb->attributes) == 0) { +@@ -7993,6 +7994,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + rest = this; + } + ++ super->current_vol = current_vol; + return rest; + } + +-- +2.7.5 + diff --git a/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch b/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch new file mode 100644 index 0000000..ba34896 --- /dev/null +++ b/SOURCES/0043-imsm-allow-to-specify-second-volume-size.patch @@ -0,0 +1,50 @@ +From 1a1ced1e2e64a6b4b349a3fb559f6b39e4cf7103 Mon Sep 17 00:00:00 2001 +From: Krzysztof Smolinski +Date: Fri, 8 Nov 2019 11:59:11 +0100 +Subject: [RHEL7.8 PATCH V2 43/47] imsm: allow to specify second volume size + +Removed checks which limited second volume size only to max value (the +largest size that fits on all current drives). It is now permitted +to create second volume with size lower then maximum possible. + +Signed-off-by: Krzysztof Smolinski +Signed-off-by: Jes Sorensen +--- + super-intel.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index e02bbd7..713058c 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7298,11 +7298,8 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, + + maxsize = merge_extents(super, i); + +- if (!check_env("IMSM_NO_PLATFORM") && +- mpb->num_raid_devs > 0 && size && size != maxsize) { +- pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n"); +- return 0; +- } ++ if (mpb->num_raid_devs > 0 && size && size != maxsize) ++ pr_err("attempting to create a second volume with size less then remaining space.\n"); + + if (maxsize < size || maxsize == 0) { + if (verbose) { +@@ -7393,11 +7390,8 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, + } + maxsize = size; + } +- if (!check_env("IMSM_NO_PLATFORM") && +- mpb->num_raid_devs > 0 && size && size != maxsize) { +- pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n"); +- return 0; +- } ++ if (mpb->num_raid_devs > 0 && size && size != maxsize) ++ pr_err("attempting to create a second volume with size less then remaining space.\n"); + cnt = 0; + for (dl = super->disks; dl; dl = dl->next) + if (dl->e) +-- +2.7.5 + diff --git a/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch b/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch new file mode 100644 index 0000000..bff9eaa --- /dev/null +++ b/SOURCES/0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch @@ -0,0 +1,45 @@ +From 6636788aaf4ec0cacaefb6e77592e4a68e70a957 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 30 Oct 2019 10:32:41 +1100 +Subject: [RHEL7.8 PATCH V2 44/47] mdcheck: when mdcheck_start is enabled, + enable mdcheck_continue too. + +mdcheck_continue continues a regular array scan that was started by +mdcheck_start. +mdcheck_start will ensure that mdcheck_continue is active. +Howver if you reboot after a check has started, but before it finishes, +then mdcheck_continue won't cause it to continue, because nothing +starts it on boot. + +So add an install option for mdcheck_contine, and make sure it +gets enabled when mdcheck_start is enabled. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.timer | 2 ++ + systemd/mdcheck_start.timer | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/systemd/mdcheck_continue.timer b/systemd/mdcheck_continue.timer +index 3ccfd78..dba1074 100644 +--- a/systemd/mdcheck_continue.timer ++++ b/systemd/mdcheck_continue.timer +@@ -11,3 +11,5 @@ Description=MD array scrubbing - continuation + [Timer] + OnCalendar= 1:05:00 + ++[Install] ++WantedBy= mdmonitor.service +diff --git a/systemd/mdcheck_start.timer b/systemd/mdcheck_start.timer +index 6480736..9e7e02a 100644 +--- a/systemd/mdcheck_start.timer ++++ b/systemd/mdcheck_start.timer +@@ -13,3 +13,4 @@ OnCalendar=Sun *-*-1..7 1:00:00 + + [Install] + WantedBy= mdmonitor.service ++Also= mdcheck_continue.timer +-- +2.7.5 + diff --git a/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch b/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch new file mode 100644 index 0000000..6b13d18 --- /dev/null +++ b/SOURCES/0045-mdcheck-use-to-pass-variable-to-mdcheck.patch @@ -0,0 +1,51 @@ +From 4ca799c581703d4d0ad840833c037c2fff088ca7 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 30 Oct 2019 10:32:41 +1100 +Subject: [RHEL7.8 PATCH V2 45/47] mdcheck: use ${} to pass variable to mdcheck + +$MDADM_CHECK_DURATION allows the value to be split on spaces. +${MDADM_CHECK_DURATION} avoids such splitting. + +Making this change removes the need for double quoting when setting +the default Environment, and means that double quoting isn't needed +in the EnvironmentFile. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.service | 5 ++--- + systemd/mdcheck_start.service | 4 ++-- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index 592c607..deac695 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -11,8 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* + + [Service] + Type=oneshot +-Environment= MDADM_CHECK_DURATION='"6 hours"' ++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 +- ++ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index 812141b..f17f1aa 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer + + [Service] + Type=oneshot +-Environment= MDADM_CHECK_DURATION='"6 hours"' ++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 ++ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} +-- +2.7.5 + diff --git a/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch b/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch new file mode 100644 index 0000000..d88de9e --- /dev/null +++ b/SOURCES/0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch @@ -0,0 +1,29 @@ +From 85b83a7920bca5b93d2458f093f2c640a130614c Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 30 Oct 2019 10:32:41 +1100 +Subject: [RHEL7.8 PATCH V2 46/47] SUSE-mdadm_env.sh: handle + MDADM_CHECK_DURATION + +The suse sysconfig/mdadm allows MDADM_CHECK_DURATION +to be set, but it is currently ignored. + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + systemd/SUSE-mdadm_env.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/systemd/SUSE-mdadm_env.sh b/systemd/SUSE-mdadm_env.sh +index 10b2e74..c13b48a 100644 +--- a/systemd/SUSE-mdadm_env.sh ++++ b/systemd/SUSE-mdadm_env.sh +@@ -43,3 +43,6 @@ fi + + mkdir -p /run/sysconfig + echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm ++if [ -n "$MDADM_CHECK_DURATION" ]; then ++ echo "MDADM_CHECK_DURATION=$MDADM_CHECK_DURATION" >> /run/sysconfig/mdadm ++fi +-- +2.7.5 + diff --git a/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch b/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch new file mode 100644 index 0000000..3eda582 --- /dev/null +++ b/SOURCES/0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch @@ -0,0 +1,122 @@ +From 761e3bd9f5e3aafa95ad3ae50a637dc67c8774f0 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 31 Oct 2019 15:15:38 +1100 +Subject: [RHEL7.8 PATCH V2 47/47] super-intel: don't mark structs 'packed' + unnecessarily + +super-intel marks a number of structures 'packed', but this +doesn't change the layout - they are already well organized. + +This is a problem a gcc warns when code takes the address +of a field in a packet struct - as super-intel sometimes does. + +So remove the marking where isn't needed. +Do ensure this does introduce a regression, add a compile-time +assertion that the size of the structure is exactly the value +it had before the 'packed' notation was removed. + +Note that a couple of structure do need to be packed. +As the address of fields is never taken, that is safe. + +Signed-off-by: NeilBrown +Acked-by: Artur Paszkiewicz +Signed-off-by: Jes Sorensen +--- + super-intel.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 713058c..a7fbed4 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -96,6 +96,19 @@ + * mutliple PPL area + */ + ++/* ++ * This macro let's us ensure that no-one accidentally ++ * changes the size of a struct ++ */ ++#define ASSERT_SIZE(_struct, size) \ ++static inline void __assert_size_##_struct(void) \ ++{ \ ++ switch (0) { \ ++ case 0: break; \ ++ case (sizeof(struct _struct) == size): break; \ ++ } \ ++} ++ + /* Disk configuration info. */ + #define IMSM_MAX_DEVICES 255 + struct imsm_disk { +@@ -112,6 +125,7 @@ struct imsm_disk { + #define IMSM_DISK_FILLERS 3 + __u32 filler[IMSM_DISK_FILLERS]; /* 0xF5 - 0x107 MPB_DISK_FILLERS for future expansion */ + }; ++ASSERT_SIZE(imsm_disk, 48) + + /* map selector for map managment + */ +@@ -146,7 +160,8 @@ struct imsm_map { + __u32 disk_ord_tbl[1]; /* disk_ord_tbl[num_members], + * top byte contains some flags + */ +-} __attribute__ ((packed)); ++}; ++ASSERT_SIZE(imsm_map, 52) + + struct imsm_vol { + __u32 curr_migr_unit; +@@ -169,7 +184,8 @@ struct imsm_vol { + __u32 filler[4]; + struct imsm_map map[1]; + /* here comes another one if migr_state */ +-} __attribute__ ((packed)); ++}; ++ASSERT_SIZE(imsm_vol, 84) + + struct imsm_dev { + __u8 volume[MAX_RAID_SERIAL_LEN]; +@@ -220,7 +236,8 @@ struct imsm_dev { + #define IMSM_DEV_FILLERS 3 + __u32 filler[IMSM_DEV_FILLERS]; + struct imsm_vol vol; +-} __attribute__ ((packed)); ++}; ++ASSERT_SIZE(imsm_dev, 164) + + struct imsm_super { + __u8 sig[MAX_SIGNATURE_LENGTH]; /* 0x00 - 0x1F */ +@@ -248,7 +265,8 @@ struct imsm_super { + struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */ + /* here comes imsm_dev[num_raid_devs] */ + /* here comes BBM logs */ +-} __attribute__ ((packed)); ++}; ++ASSERT_SIZE(imsm_super, 264) + + #define BBM_LOG_MAX_ENTRIES 254 + #define BBM_LOG_MAX_LBA_ENTRY_VAL 256 /* Represents 256 LBAs */ +@@ -269,7 +287,8 @@ struct bbm_log { + __u32 signature; /* 0xABADB10C */ + __u32 entry_count; + struct bbm_log_entry marked_block_entries[BBM_LOG_MAX_ENTRIES]; +-} __attribute__ ((__packed__)); ++}; ++ASSERT_SIZE(bbm_log, 2040) + + static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" }; + +@@ -323,7 +342,8 @@ struct migr_record { + * destination - high order 32 bits */ + __u32 num_migr_units_hi; /* Total num migration units-of-op + * high order 32 bits */ +-} __attribute__ ((__packed__)); ++}; ++ASSERT_SIZE(migr_record, 64) + + struct md_list { + /* usage marker: +-- +2.7.5 + diff --git a/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch b/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch new file mode 100644 index 0000000..a106dd2 --- /dev/null +++ b/SOURCES/0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch @@ -0,0 +1,45 @@ +From e1512e7b7d060f0346738b237ea34eac21b29a26 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Wed, 18 Dec 2019 14:46:21 +0800 +Subject: [RHEL8.2 PATCH 1/1] mdcheck service can't start succesfully because + of syntax error + +It reports error when starting mdcheck_start and mdcheck_continue service. +Invalid environment assignment, ignoring: MDADM_CHECK_DURATION="6 hours" + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + systemd/mdcheck_continue.service | 2 +- + systemd/mdcheck_start.service | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index deac695..aa02dde 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* + + [Service] + Type=oneshot +-Environment= MDADM_CHECK_DURATION="6 hours" ++Environment= "MDADM_CHECK_DURATION=6 hours" + EnvironmentFile=-/run/sysconfig/mdadm + ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index f17f1aa..da62d5f 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer + + [Service] + Type=oneshot +-Environment= MDADM_CHECK_DURATION="6 hours" ++Environment= "MDADM_CHECK_DURATION=6 hours" + EnvironmentFile=-/run/sysconfig/mdadm + ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION} +-- +2.7.5 + diff --git a/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch b/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch new file mode 100644 index 0000000..e9e7674 --- /dev/null +++ b/SOURCES/0049-Remove-last-traces-of-HOT_ADD_DISK.patch @@ -0,0 +1,41 @@ +From 02af379337c73e751ad97c0fed9123121f8b4289 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 27 Nov 2019 10:19:54 -0500 +Subject: [RHEL8.2 PATCH 49/61] Remove last traces of HOT_ADD_DISK + +This ioctl is no longer used, so remove all references to it. + +Signed-off-by: Jes Sorensen +--- + Manage.c | 2 -- + md_u.h | 1 - + 2 files changed, 3 deletions(-) + +diff --git a/Manage.c b/Manage.c +index ffe55f8..deeba2b 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1289,8 +1289,6 @@ int Manage_subdevs(char *devname, int fd, + /* Do something to each dev. + * devmode can be + * 'a' - add the device +- * try HOT_ADD_DISK +- * If that fails EINVAL, try ADD_NEW_DISK + * 'S' - add the device as a spare - don't try re-add + * 'j' - add the device as a journal device + * 'A' - re-add the device +diff --git a/md_u.h b/md_u.h +index 2d66d52..b30893c 100644 +--- a/md_u.h ++++ b/md_u.h +@@ -28,7 +28,6 @@ + #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 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.5 + diff --git a/SOURCES/0050-Fix-up-a-few-formatting-issues.patch b/SOURCES/0050-Fix-up-a-few-formatting-issues.patch new file mode 100644 index 0000000..f74c9b7 --- /dev/null +++ b/SOURCES/0050-Fix-up-a-few-formatting-issues.patch @@ -0,0 +1,51 @@ +From 9cf361f8791d86aaced821c19af556819bc03732 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +Date: Wed, 27 Nov 2019 11:33:15 -0500 +Subject: [RHEL8.2 PATCH 50/61] Fix up a few formatting issues + +Signed-off-by: Jes Sorensen +--- + Manage.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/Manage.c b/Manage.c +index deeba2b..b22c396 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -1728,8 +1728,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + int fd2 = open(from_devname, O_RDONLY); + + if (fd1 < 0 || fd2 < 0) { +- if (fd1>=0) close(fd1); +- if (fd2>=0) close(fd2); ++ if (fd1 >= 0) ++ close(fd1); ++ if (fd2 >= 0) ++ close(fd2); + return 0; + } + +@@ -1743,7 +1745,8 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + devlist.disposition = 'r'; + if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) { + devlist.disposition = 'a'; +- if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL, 0) == 0) { ++ if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, ++ NULL, 0) == 0) { + /* make sure manager is aware of changes */ + ping_manager(to_devname); + ping_manager(from_devname); +@@ -1751,7 +1754,9 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid) + close(fd2); + return 1; + } +- else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0); ++ else ++ Manage_subdevs(from_devname, fd2, &devlist, ++ -1, 0, NULL, 0); + } + close(fd1); + close(fd2); +-- +2.7.5 + diff --git a/SOURCES/0051-Remove-unused-code.patch b/SOURCES/0051-Remove-unused-code.patch new file mode 100644 index 0000000..cd4aa2a --- /dev/null +++ b/SOURCES/0051-Remove-unused-code.patch @@ -0,0 +1,26 @@ +From 4b31846f3f90aa24f883ceed80e91f204c0a9389 Mon Sep 17 00:00:00 2001 +From: Xiao Ni +Date: Fri, 29 Nov 2019 17:14:47 +0800 +Subject: [RHEL8.2 PATCH 51/61] Remove unused code + +Signed-off-by: Xiao Ni +Signed-off-by: Jes Sorensen +--- + platform-intel.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/platform-intel.h b/platform-intel.h +index 29c85f1..7cb370e 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -169,7 +169,6 @@ static inline int fls(int x) + r -= 2; + } + if (!(x & 0x80000000u)) { +- x <<= 1; + r -= 1; + } + return r; +-- +2.7.5 + diff --git a/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch b/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch new file mode 100644 index 0000000..642297f --- /dev/null +++ b/SOURCES/0052-imsm-return-correct-uuid-for-volume-in-detail.patch @@ -0,0 +1,176 @@ +From b771faef931c798a4553db0a8c1366aff90079c6 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 29 Nov 2019 15:21:08 +0100 +Subject: [RHEL8.2 PATCH 52/61] imsm: return correct uuid for volume in detail + +Fixes the side effect of the patch b6180160f ("imsm: save current_vol number") +- wrong UUID is printed in detail for each volume. +New parameter "subarray" is added to determine what info should be extracted +from metadata (subarray or container). +The parameter affects only IMSM metadata. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + Detail.c | 4 ++-- + mdadm.h | 5 +++-- + super-ddf.c | 5 +++-- + super-intel.c | 20 ++++++++++++++++++-- + super0.c | 4 ++-- + super1.c | 4 ++-- + 6 files changed, 30 insertions(+), 12 deletions(-) + +diff --git a/Detail.c b/Detail.c +index 3e61e37..24fa462 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -623,7 +623,7 @@ This is pretty boring + free_mdstat(ms); + + if (st && st->sb) +- st->ss->detail_super(st, c->homehost); ++ st->ss->detail_super(st, c->homehost, subarray); + + if (array.raid_disks == 0 && sra && + sra->array.major_version == -1 && +@@ -767,7 +767,7 @@ skip_devices_state: + if (spares && c->brief && array.raid_disks) + printf(" spares=%d", spares); + if (c->brief && st && st->sb) +- st->ss->brief_detail_super(st); ++ st->ss->brief_detail_super(st, subarray); + if (st) + st->ss->free_super(st); + +diff --git a/mdadm.h b/mdadm.h +index c88ceab..91f1338 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -847,8 +847,9 @@ extern struct superswitch { + /* Used to report details of an active array. + * ->load_super was possibly given a 'component' string. + */ +- void (*detail_super)(struct supertype *st, char *homehost); +- void (*brief_detail_super)(struct supertype *st); ++ void (*detail_super)(struct supertype *st, char *homehost, ++ char *subarray); ++ void (*brief_detail_super)(struct supertype *st, char *subarray); + void (*export_detail_super)(struct supertype *st); + + /* Optional: platform hardware / firmware details */ +diff --git a/super-ddf.c b/super-ddf.c +index c095e8a..7802063 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1730,7 +1730,8 @@ err: + return 1; + } + +-static void detail_super_ddf(struct supertype *st, char *homehost) ++static void detail_super_ddf(struct supertype *st, char *homehost, ++ char *subarray) + { + struct ddf_super *sb = st->sb; + int cnt = be16_to_cpu(sb->virt->populated_vdes); +@@ -1787,7 +1788,7 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf, + memcpy(uuid, sha, 4*4); + } + +-static void brief_detail_super_ddf(struct supertype *st) ++static void brief_detail_super_ddf(struct supertype *st, char *subarray) + { + struct mdinfo info; + char nbuf[64]; +diff --git a/super-intel.c b/super-intel.c +index a7fbed4..86dcb69 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2183,23 +2183,39 @@ err: + return 1; + } + +-static void detail_super_imsm(struct supertype *st, char *homehost) ++static void detail_super_imsm(struct supertype *st, char *homehost, ++ char *subarray) + { + struct mdinfo info; + char nbuf[64]; ++ struct intel_super *super = st->sb; ++ int temp_vol = super->current_vol; ++ ++ if (subarray) ++ super->current_vol = strtoul(subarray, NULL, 10); + + getinfo_super_imsm(st, &info, NULL); + fname_from_uuid(st, &info, nbuf, ':'); + printf("\n UUID : %s\n", nbuf + 5); ++ ++ super->current_vol = temp_vol; + } + +-static void brief_detail_super_imsm(struct supertype *st) ++static void brief_detail_super_imsm(struct supertype *st, char *subarray) + { + struct mdinfo info; + char nbuf[64]; ++ struct intel_super *super = st->sb; ++ int temp_vol = super->current_vol; ++ ++ if (subarray) ++ super->current_vol = strtoul(subarray, NULL, 10); ++ + getinfo_super_imsm(st, &info, NULL); + fname_from_uuid(st, &info, nbuf, ':'); + printf(" UUID=%s", nbuf + 5); ++ ++ super->current_vol = temp_vol; + } + + static int imsm_read_serial(int fd, char *devname, __u8 *serial); +diff --git a/super0.c b/super0.c +index 42989b9..6b7c0e3 100644 +--- a/super0.c ++++ b/super0.c +@@ -348,7 +348,7 @@ err: + return 1; + } + +-static void detail_super0(struct supertype *st, char *homehost) ++static void detail_super0(struct supertype *st, char *homehost, char *subarray) + { + mdp_super_t *sb = st->sb; + printf(" UUID : "); +@@ -368,7 +368,7 @@ static void detail_super0(struct supertype *st, char *homehost) + printf("\n Events : %d.%d\n\n", sb->events_hi, sb->events_lo); + } + +-static void brief_detail_super0(struct supertype *st) ++static void brief_detail_super0(struct supertype *st, char *subarray) + { + mdp_super_t *sb = st->sb; + printf(" UUID="); +diff --git a/super1.c b/super1.c +index b85dc20..929466d 100644 +--- a/super1.c ++++ b/super1.c +@@ -833,7 +833,7 @@ err: + return 1; + } + +-static void detail_super1(struct supertype *st, char *homehost) ++static void detail_super1(struct supertype *st, char *homehost, char *subarray) + { + struct mdp_superblock_1 *sb = st->sb; + bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); +@@ -857,7 +857,7 @@ static void detail_super1(struct supertype *st, char *homehost) + (unsigned long long)__le64_to_cpu(sb->events)); + } + +-static void brief_detail_super1(struct supertype *st) ++static void brief_detail_super1(struct supertype *st, char *subarray) + { + struct mdp_superblock_1 *sb = st->sb; + int i; +-- +2.7.5 + diff --git a/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch b/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch new file mode 100644 index 0000000..3c1c221 --- /dev/null +++ b/SOURCES/0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch @@ -0,0 +1,208 @@ +From 6da53c0e2aab200605722795798b1e4f2352cd64 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Mon, 2 Dec 2019 10:52:05 +0100 +Subject: [RHEL8.2 PATCH 53/61] imsm: Change the way of printing nvme drives in + detail-platform. + +Change NVMe controller path to device node path +in mdadm --detail-platform and print serial number. +The method imsm_read_serial always trimes serial to +MAX_RAID_SERIAL_LEN, added parameter 'serial_buf_len' +will be used to check the serial fit +to passed buffor, if not, will be trimed. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + super-intel.c | 97 ++++++++++++++++++++++++++++------------------------------- + 1 file changed, 46 insertions(+), 51 deletions(-) + +diff --git a/super-intel.c b/super-intel.c +index 86dcb69..5c1f759 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2218,7 +2218,8 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray) + super->current_vol = temp_vol; + } + +-static int imsm_read_serial(int fd, char *devname, __u8 *serial); ++static int imsm_read_serial(int fd, char *devname, __u8 *serial, ++ size_t serial_buf_len); + static void fd2devname(int fd, char *name); + + static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose) +@@ -2364,8 +2365,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + else { + fd2devname(fd, buf); + printf(" Port%d : %s", port, buf); +- if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0) +- printf(" (%.*s)\n", MAX_RAID_SERIAL_LEN, buf); ++ if (imsm_read_serial(fd, NULL, (__u8 *)buf, ++ sizeof(buf)) == 0) ++ printf(" (%s)\n", buf); + else + printf(" ()\n"); + close(fd); +@@ -2388,52 +2390,45 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b + return err; + } + +-static int print_vmd_attached_devs(struct sys_dev *hba) ++static int print_nvme_info(struct sys_dev *hba) + { ++ char buf[1024]; + struct dirent *ent; + DIR *dir; +- char path[292]; +- char link[256]; +- char *c, *rp; +- +- if (hba->type != SYS_DEV_VMD) +- return 1; ++ char *rp; ++ int fd; + +- /* scroll through /sys/dev/block looking for devices attached to +- * this hba +- */ +- dir = opendir("/sys/bus/pci/drivers/nvme"); ++ dir = opendir("/sys/block/"); + if (!dir) + return 1; + + for (ent = readdir(dir); ent; ent = readdir(dir)) { +- int n; +- +- /* is 'ent' a device? check that the 'subsystem' link exists and +- * that its target matches 'bus' +- */ +- sprintf(path, "/sys/bus/pci/drivers/nvme/%s/subsystem", +- ent->d_name); +- n = readlink(path, link, sizeof(link)); +- if (n < 0 || n >= (int)sizeof(link)) +- continue; +- link[n] = '\0'; +- c = strrchr(link, '/'); +- if (!c) +- continue; +- if (strncmp("pci", c+1, strlen("pci")) != 0) +- continue; +- +- sprintf(path, "/sys/bus/pci/drivers/nvme/%s", ent->d_name); +- +- rp = realpath(path, NULL); +- if (!rp) +- continue; ++ if (strstr(ent->d_name, "nvme")) { ++ sprintf(buf, "/sys/block/%s", ent->d_name); ++ rp = realpath(buf, NULL); ++ if (!rp) ++ continue; ++ if (path_attached_to_hba(rp, hba->path)) { ++ fd = open_dev(ent->d_name); ++ if (fd < 0) { ++ free(rp); ++ continue; ++ } + +- if (path_attached_to_hba(rp, hba->path)) { +- printf(" NVMe under VMD : %s\n", rp); ++ fd2devname(fd, buf); ++ if (hba->type == SYS_DEV_VMD) ++ printf(" NVMe under VMD : %s", buf); ++ else if (hba->type == SYS_DEV_NVME) ++ printf(" NVMe Device : %s", buf); ++ if (!imsm_read_serial(fd, NULL, (__u8 *)buf, ++ sizeof(buf))) ++ printf(" (%s)\n", buf); ++ else ++ printf("()\n"); ++ close(fd); ++ } ++ free(rp); + } +- free(rp); + } + + closedir(dir); +@@ -2648,7 +2643,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle + char buf[PATH_MAX]; + printf(" I/O Controller : %s (%s)\n", + vmd_domain_to_controller(hba, buf), get_sys_dev_type(hba->type)); +- if (print_vmd_attached_devs(hba)) { ++ if (print_nvme_info(hba)) { + if (verbose > 0) + pr_err("failed to get devices attached to VMD domain.\n"); + result |= 2; +@@ -2663,7 +2658,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle + if (entry->type == SYS_DEV_NVME) { + for (hba = list; hba; hba = hba->next) { + if (hba->type == SYS_DEV_NVME) +- printf(" NVMe Device : %s\n", hba->path); ++ print_nvme_info(hba); + } + printf("\n"); + continue; +@@ -4028,11 +4023,11 @@ static int nvme_get_serial(int fd, void *buf, size_t buf_len) + extern int scsi_get_serial(int fd, void *buf, size_t buf_len); + + static int imsm_read_serial(int fd, char *devname, +- __u8 serial[MAX_RAID_SERIAL_LEN]) ++ __u8 *serial, size_t serial_buf_len) + { + char buf[50]; + int rv; +- int len; ++ size_t len; + char *dest; + char *src; + unsigned int i; +@@ -4075,13 +4070,13 @@ static int imsm_read_serial(int fd, char *devname, + len = dest - buf; + dest = buf; + +- /* truncate leading characters */ +- if (len > MAX_RAID_SERIAL_LEN) { +- dest += len - MAX_RAID_SERIAL_LEN; +- len = MAX_RAID_SERIAL_LEN; ++ if (len > serial_buf_len) { ++ /* truncate leading characters */ ++ dest += len - serial_buf_len; ++ len = serial_buf_len; + } + +- memset(serial, 0, MAX_RAID_SERIAL_LEN); ++ memset(serial, 0, serial_buf_len); + memcpy(serial, dest, len); + + return 0; +@@ -4136,7 +4131,7 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd) + char name[40]; + __u8 serial[MAX_RAID_SERIAL_LEN]; + +- rv = imsm_read_serial(fd, devname, serial); ++ rv = imsm_read_serial(fd, devname, serial, MAX_RAID_SERIAL_LEN); + + if (rv != 0) + return 2; +@@ -5844,7 +5839,7 @@ int mark_spare(struct dl *disk) + return ret_val; + + ret_val = 0; +- if (!imsm_read_serial(disk->fd, NULL, serial)) { ++ if (!imsm_read_serial(disk->fd, NULL, serial, MAX_RAID_SERIAL_LEN)) { + /* Restore disk serial number, because takeover marks disk + * as failed and adds to serial ':0' before it becomes + * a spare disk. +@@ -5895,7 +5890,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, + dd->fd = fd; + dd->e = NULL; + dd->action = DISK_ADD; +- rv = imsm_read_serial(fd, devname, dd->serial); ++ rv = imsm_read_serial(fd, devname, dd->serial, MAX_RAID_SERIAL_LEN); + if (rv) { + pr_err("failed to retrieve scsi serial, aborting\n"); + if (dd->devname) +-- +2.7.5 + diff --git a/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch b/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch new file mode 100644 index 0000000..b87e668 --- /dev/null +++ b/SOURCES/0054-Create-add-support-for-RAID0-layouts.patch @@ -0,0 +1,342 @@ +From 329dfc28debb58ffe7bd1967cea00fc583139aca Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 4 Nov 2019 14:27:49 +1100 +Subject: [RHEL8.2 PATCH 54/61] Create: add support for RAID0 layouts. + +Since Linux 5.4 a layout is needed for RAID0 arrays with +varying device sizes. +This patch makes the layout of an array visible (via --examine) +and sets the layout on newly created arrays. +--layout=dangerous +can be used to avoid setting a layout so that they array +can be used on older kernels. + +Tested-by: dann frazier +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Create.c | 11 +++++++++++ + Detail.c | 5 +++++ + maps.c | 12 ++++++++++++ + md.4 | 14 ++++++++++++++ + mdadm.8.in | 30 +++++++++++++++++++++++++++++- + mdadm.c | 8 ++++++++ + mdadm.h | 8 +++++++- + super0.c | 6 ++++++ + super1.c | 30 +++++++++++++++++++++++++++++- + 9 files changed, 121 insertions(+), 3 deletions(-) + +diff --git a/Create.c b/Create.c +index 292f92a..6f84e5b 100644 +--- a/Create.c ++++ b/Create.c +@@ -51,6 +51,9 @@ static int default_layout(struct supertype *st, int level, int verbose) + default: /* no layout */ + layout = 0; + break; ++ case 0: ++ layout = RAID0_ORIG_LAYOUT; ++ break; + case 10: + layout = 0x102; /* near=2, far=1 */ + if (verbose > 0) +@@ -950,6 +953,11 @@ int Create(struct supertype *st, char *mddev, + if (rv) { + pr_err("ADD_NEW_DISK for %s failed: %s\n", + dv->devname, strerror(errno)); ++ if (errno == EINVAL && ++ info.array.level == 0) { ++ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n"); ++ pr_err("Either upgrade, or use --layout=dangerous\n"); ++ } + goto abort_locked; + } + break; +@@ -1046,6 +1054,9 @@ int Create(struct supertype *st, char *mddev, + if (ioctl(mdfd, RUN_ARRAY, ¶m)) { + pr_err("RUN_ARRAY failed: %s\n", + strerror(errno)); ++ if (errno == 524 /* ENOTSUP */ && ++ info.array.level == 0) ++ cont_err("Please use --layout=original or --layout=alternate\n"); + if (info.array.chunk_size & (info.array.chunk_size-1)) { + cont_err("Problem may be that chunk size is not a power of 2\n"); + } +diff --git a/Detail.c b/Detail.c +index 24fa462..832485f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -525,6 +525,11 @@ int Detail(char *dev, struct context *c) + printf(" Layout : %s\n", + str ? str : "-unknown-"); + } ++ if (array.level == 0 && array.layout) { ++ str = map_num(r0layout, array.layout); ++ printf(" Layout : %s\n", ++ str ? str : "-unknown-"); ++ } + if (array.level == 6) { + str = map_num(r6layout, array.layout); + printf(" Layout : %s\n", +diff --git a/maps.c b/maps.c +index 49b7f2c..a4fd279 100644 +--- a/maps.c ++++ b/maps.c +@@ -73,6 +73,18 @@ mapping_t r6layout[] = { + { NULL, UnSet } + }; + ++/* raid0 layout is only needed because of a bug in 3.14 which changed ++ * the effective layout of raid0 arrays with varying device sizes. ++ */ ++mapping_t r0layout[] = { ++ { "original", RAID0_ORIG_LAYOUT}, ++ { "alternate", RAID0_ALT_MULTIZONE_LAYOUT}, ++ { "1", 1}, /* aka ORIG */ ++ { "2", 2}, /* aka ALT */ ++ { "dangerous", 0}, ++ { NULL, UnSet}, ++}; ++ + mapping_t pers[] = { + { "linear", LEVEL_LINEAR}, + { "raid0", 0}, +diff --git a/md.4 b/md.4 +index e86707a..6fe2755 100644 +--- a/md.4 ++++ b/md.4 +@@ -193,6 +193,20 @@ smallest device has been exhausted, the RAID0 driver starts + collecting chunks into smaller stripes that only span the drives which + still have remaining space. + ++A bug was introduced in linux 3.14 which changed the layout of blocks in ++a RAID0 beyond the region that is striped over all devices. This bug ++does not affect an array with all devices the same size, but can affect ++other RAID0 arrays. ++ ++Linux 5.4 (and some stable kernels to which the change was backported) ++will not normally assemble such an array as it cannot know which layout ++to use. There is a module parameter "raid0.default_layout" which can be ++set to "1" to force the kernel to use the pre-3.14 layout or to "2" to ++force it to use the 3.14-and-later layout. when creating a new RAID0 ++array, ++.I mdadm ++will record the chosen layout in the metadata in a way that allows newer ++kernels to assemble the array without needing a module parameter. + + .SS RAID1 + +diff --git a/mdadm.8.in b/mdadm.8.in +index 9aec9f4..fc9b6a6 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -593,6 +593,8 @@ to change the RAID level in some cases. See LEVEL CHANGES below. + This option configures the fine details of data layout for RAID5, RAID6, + and RAID10 arrays, and controls the failure modes for + .IR faulty . ++It can also be used for working around a kernel bug with RAID0, but generally ++doesn't need to be used explicitly. + + The layout of the RAID5 parity block can be one of + .BR left\-asymmetric , +@@ -652,7 +654,7 @@ option to set subsequent failure modes. + "clear" or "none" will remove any pending or periodic failure modes, + and "flush" will clear any persistent faults. + +-Finally, the layout options for RAID10 are one of 'n', 'o' or 'f' followed ++The layout options for RAID10 are one of 'n', 'o' or 'f' followed + by a small number. The default is 'n2'. The supported options are: + + .I 'n' +@@ -677,6 +679,32 @@ devices in the array. It does not need to divide evenly into that + number (e.g. it is perfectly legal to have an 'n2' layout for an array + with an odd number of devices). + ++A bug introduced in Linux 3.14 means that RAID0 arrays ++.B "with devices of differing sizes" ++started using a different layout. This could lead to ++data corruption. Since Linux 5.4 (and various stable releases that received ++backports), the kernel will not accept such an array unless ++a layout is explictly set. It can be set to ++.RB ' original ' ++or ++.RB ' alternate '. ++When creating a new array, ++.I mdadm ++will select ++.RB ' original ' ++by default, so the layout does not normally need to be set. ++An array created for either ++.RB ' original ' ++or ++.RB ' alternate ' ++will not be recognized by an (unpatched) kernel prior to 5.4. To create ++a RAID0 array with devices of differing sizes that can be used on an ++older kernel, you can set the layout to ++.RB ' dangerous '. ++This will use whichever layout the running kernel supports, so the data ++on the array may become corrupt when changing kernel from pre-3.14 to a ++later kernel. ++ + When an array is converted between RAID5 and RAID6 an intermediate + RAID6 layout is used in which the second parity block (Q) is always on + the last device. To convert a RAID5 to RAID6 and leave it in this new +diff --git a/mdadm.c b/mdadm.c +index 1fb8086..e438f9c 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -550,6 +550,14 @@ int main(int argc, char *argv[]) + pr_err("raid level must be given before layout.\n"); + exit(2); + ++ case 0: ++ s.layout = map_name(r0layout, optarg); ++ if (s.layout == UnSet) { ++ pr_err("layout %s not understood for raid0.\n", ++ optarg); ++ exit(2); ++ } ++ break; + case 5: + s.layout = map_name(r5layout, optarg); + if (s.layout == UnSet) { +diff --git a/mdadm.h b/mdadm.h +index 91f1338..9e98778 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -763,7 +763,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[]; ++extern mapping_t r0layout[], r5layout[], r6layout[], ++ pers[], modes[], faultylayout[]; + extern mapping_t consistency_policies[], sysfs_array_states[]; + + extern char *map_dev_preferred(int major, int minor, int create, +@@ -1758,6 +1759,11 @@ char *xstrdup(const char *str); + #define makedev(M,m) (((M)<<8) | (m)) + #endif + ++enum r0layout { ++ RAID0_ORIG_LAYOUT = 1, ++ RAID0_ALT_MULTIZONE_LAYOUT = 2, ++}; ++ + /* for raid4/5/6 */ + #define ALGORITHM_LEFT_ASYMMETRIC 0 + #define ALGORITHM_RIGHT_ASYMMETRIC 1 +diff --git a/super0.c b/super0.c +index 6b7c0e3..6af140b 100644 +--- a/super0.c ++++ b/super0.c +@@ -1291,6 +1291,12 @@ static int validate_geometry0(struct supertype *st, int level, + if (*chunk == UnSet) + *chunk = DEFAULT_CHUNK; + ++ if (level == 0 && layout != UnSet) { ++ if (verbose) ++ pr_err("0.90 metadata does not support layouts for RAID0\n"); ++ return 0; ++ } ++ + if (!subdev) + return 1; + +diff --git a/super1.c b/super1.c +index 929466d..cedbb53 100644 +--- a/super1.c ++++ b/super1.c +@@ -43,7 +43,7 @@ struct mdp_superblock_1 { + + __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/ + __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ +- __u32 layout; /* only for raid5 currently */ ++ __u32 layout; /* used for raid5, raid6, raid10, and raid0 */ + __u64 size; /* used size of component devices, in 512byte sectors */ + + __u32 chunksize; /* in 512byte sectors */ +@@ -144,6 +144,7 @@ struct misc_dev_info { + #define MD_FEATURE_JOURNAL 512 /* support write journal */ + #define MD_FEATURE_PPL 1024 /* support PPL */ + #define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */ ++#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in RAID0 */ + #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ + |MD_FEATURE_RECOVERY_OFFSET \ + |MD_FEATURE_RESHAPE_ACTIVE \ +@@ -155,6 +156,7 @@ struct misc_dev_info { + |MD_FEATURE_JOURNAL \ + |MD_FEATURE_PPL \ + |MD_FEATURE_MULTIPLE_PPLS \ ++ |MD_FEATURE_RAID0_LAYOUT \ + ) + + static int role_from_sb(struct mdp_superblock_1 *sb) +@@ -498,6 +500,11 @@ static void examine_super1(struct supertype *st, char *homehost) + printf(" Events : %llu\n", + (unsigned long long)__le64_to_cpu(sb->events)); + printf("\n"); ++ if (__le32_to_cpu(sb->level) == 0 && ++ (sb->feature_map & __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT))) { ++ c = map_num(r0layout, __le32_to_cpu(sb->layout)); ++ printf(" Layout : %s\n", c?c:"-unknown-"); ++ } + if (__le32_to_cpu(sb->level) == 5) { + c = map_num(r5layout, __le32_to_cpu(sb->layout)); + printf(" Layout : %s\n", c?c:"-unknown-"); +@@ -1646,6 +1653,7 @@ struct devinfo { + int fd; + char *devname; + long long data_offset; ++ unsigned long long dev_size; + mdu_disk_info_t disk; + struct devinfo *next; + }; +@@ -1687,6 +1695,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, + di->devname = devname; + di->disk = *dk; + di->data_offset = data_offset; ++ get_dev_size(fd, NULL, &di->dev_size); + di->next = NULL; + *dip = di; + +@@ -1888,10 +1897,25 @@ static int write_init_super1(struct supertype *st) + unsigned long long sb_offset; + unsigned long long data_offset; + long bm_offset; ++ int raid0_need_layout = 0; + + for (di = st->info; di; di = di->next) { + if (di->disk.state & (1 << MD_DISK_JOURNAL)) + sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); ++ if (sb->level == 0 && sb->layout != 0) { ++ struct devinfo *di2 = st->info; ++ unsigned long long s1, s2; ++ s1 = di->dev_size; ++ if (di->data_offset != INVALID_SECTORS) ++ s1 -= di->data_offset; ++ s1 /= __le32_to_cpu(sb->chunksize); ++ s2 = di2->dev_size; ++ if (di2->data_offset != INVALID_SECTORS) ++ s2 -= di2->data_offset; ++ s2 /= __le32_to_cpu(sb->chunksize); ++ if (s1 != s2) ++ raid0_need_layout = 1; ++ } + } + + for (di = st->info; di; di = di->next) { +@@ -2039,6 +2063,10 @@ static int write_init_super1(struct supertype *st) + sb->bblog_offset = 0; + } + ++ /* RAID0 needs a layout if devices aren't all the same size */ ++ if (raid0_need_layout) ++ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); ++ + sb->sb_csum = calc_sb_1_csum(sb); + rv = store_super1(st, di->fd); + +-- +2.7.5 + diff --git a/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch b/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch new file mode 100644 index 0000000..c747892 --- /dev/null +++ b/SOURCES/0055-Assemble-add-support-for-RAID0-layouts.patch @@ -0,0 +1,150 @@ +From 027c099fd1a31fb3815e592de75d0791a22353b4 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Mon, 4 Nov 2019 14:27:49 +1100 +Subject: [RHEL8.2 PATCH 55/61] Assemble: add support for RAID0 layouts. + +If you have a RAID0 array with varying sized devices +on a kernel before 5.4, you cannot assembling it on +5.4 or later without explicitly setting the layout. +This is now possible with + --update=layout-original (For 3.13 and earlier kernels) +or + --update=layout-alternate (for 3.14 and later kernels) + +Signed-off-by: NeilBrown +Signed-off-by: Jes Sorensen +--- + Assemble.c | 8 ++++++++ + md.4 | 7 +++++++ + mdadm.8.in | 17 +++++++++++++++++ + mdadm.c | 4 ++++ + super1.c | 12 +++++++++++- + 5 files changed, 47 insertions(+), 1 deletion(-) + +diff --git a/Assemble.c b/Assemble.c +index b2e6914..6b5a7c8 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -1031,6 +1031,11 @@ static int start_array(int mdfd, + pr_err("failed to add %s to %s: %s\n", + devices[j].devname, mddev, + strerror(errno)); ++ if (errno == EINVAL && content->array.level == 0 && ++ content->array.layout != 0) { ++ cont_err("Possibly your kernel doesn't support RAID0 layouts.\n"); ++ cont_err("Please upgrade.\n"); ++ } + if (i < content->array.raid_disks * 2 || + i == bestcnt) + okcnt--; +@@ -1220,6 +1225,9 @@ static int start_array(int mdfd, + return 0; + } + pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno)); ++ if (errno == 524 /* ENOTSUP */ && ++ content->array.level == 0 && content->array.layout == 0) ++ cont_err("Please use --update=layout-original or --update=layout-alternate\n"); + + if (!enough(content->array.level, content->array.raid_disks, + content->array.layout, 1, avail)) +diff --git a/md.4 b/md.4 +index 6fe2755..0712af2 100644 +--- a/md.4 ++++ b/md.4 +@@ -208,6 +208,13 @@ array, + will record the chosen layout in the metadata in a way that allows newer + kernels to assemble the array without needing a module parameter. + ++To assemble an old array on a new kernel without using the module parameter, ++use either the ++.B "--update=layout-original" ++option or the ++.B "--update=layout-alternate" ++option. ++ + .SS RAID1 + + A RAID1 array is also known as a mirrored set (though mirrors tend to +diff --git a/mdadm.8.in b/mdadm.8.in +index fc9b6a6..6b63bb4 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -1213,6 +1213,8 @@ argument given to this flag can be one of + .BR no\-bbl , + .BR ppl , + .BR no\-ppl , ++.BR layout\-original , ++.BR layout\-alternate , + .BR metadata , + or + .BR super\-minor . +@@ -1364,6 +1366,21 @@ The + .B no\-ppl + option will disable PPL in the superblock. + ++The ++.B layout\-original ++and ++.B layout\-alternate ++options are for RAID0 arrays in use before Linux 5.4. If the array was being ++used with Linux 3.13 or earlier, then to assemble the array on a new kernel, ++.B \-\-update=layout\-original ++must be given. If the array was created and used with a kernel from Linux 3.14 to ++Linux 5.3, then ++.B \-\-update=layout\-alternate ++must be given. This only needs to be given once. Subsequent assembly of the array ++will happen normally. ++For more information, see ++.IR md (4). ++ + .TP + .BR \-\-freeze\-reshape + Option is intended to be used in start-up scripts during initrd boot phase. +diff --git a/mdadm.c b/mdadm.c +index e438f9c..256a97e 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -795,6 +795,9 @@ int main(int argc, char *argv[]) + continue; + if (strcmp(c.update, "revert-reshape") == 0) + continue; ++ if (strcmp(c.update, "layout-original") == 0 || ++ strcmp(c.update, "layout-alternate") == 0) ++ continue; + if (strcmp(c.update, "byteorder") == 0) { + if (ss) { + pr_err("must not set metadata type with --update=byteorder.\n"); +@@ -825,6 +828,7 @@ int main(int argc, char *argv[]) + " 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n" + " 'no-bitmap', 'metadata', 'revert-reshape'\n" + " 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n" ++ " 'layout-original', 'layout-alternate'\n" + ); + exit(outf == stdout ? 0 : 2); + +diff --git a/super1.c b/super1.c +index cedbb53..e0d80be 100644 +--- a/super1.c ++++ b/super1.c +@@ -1550,7 +1550,17 @@ static int update_super1(struct supertype *st, struct mdinfo *info, + sb->devflags |= FailFast1; + else if (strcmp(update, "nofailfast") == 0) + sb->devflags &= ~FailFast1; +- else ++ else if (strcmp(update, "layout-original") == 0 || ++ strcmp(update, "layout-alternate") == 0) { ++ if (__le32_to_cpu(sb->level) != 0) { ++ pr_err("%s: %s only supported for RAID0\n", ++ devname?:"", update); ++ rv = -1; ++ } else { ++ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT); ++ sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); ++ } ++ } else + rv = -1; + + sb->sb_csum = calc_sb_1_csum(sb); +-- +2.7.5 + diff --git a/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch b/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch new file mode 100644 index 0000000..9219ae8 --- /dev/null +++ b/SOURCES/0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch @@ -0,0 +1,36 @@ +From aced6fc9542077a69b00d05bc9cd66c12fc34950 Mon Sep 17 00:00:00 2001 +From: dann frazier +Date: Mon, 9 Dec 2019 13:54:13 -0700 +Subject: [RHEL8.2 PATCH 56/61] Respect $(CROSS_COMPILE) when $(CC) is the + default + +Commit 1180ed5 told make to only respect $(CROSS_COMPILE) when $(CC) +was unset. But that will never be the case, as make provides +a default value for $(CC). Change this logic to respect $(CROSS_COMPILE) +when $(CC) is the default. Patch originally by Helmet Grohne. + +Fixes: 1180ed5 ("Makefile: make the CC definition conditional") +Signed-off-by: dann frazier +Signed-off-by: Jes Sorensen +--- + Makefile | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index dfe00b0..a33319a 100644 +--- a/Makefile ++++ b/Makefile +@@ -46,7 +46,9 @@ ifdef COVERITY + COVERITY_FLAGS=-include coverity-gcc-hack.h + endif + +-CC ?= $(CROSS_COMPILE)gcc ++ifeq ($(origin CC),default) ++CC := $(CROSS_COMPILE)gcc ++endif + CXFLAGS ?= -ggdb + CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter + ifdef WARN_UNUSED +-- +2.7.5 + diff --git a/SOURCES/0057-Change-warning-message.patch b/SOURCES/0057-Change-warning-message.patch new file mode 100644 index 0000000..312cc13 --- /dev/null +++ b/SOURCES/0057-Change-warning-message.patch @@ -0,0 +1,39 @@ +From 1a87493014050e3bd94000cd36122c3cadf21270 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 10 Dec 2019 12:21:21 +0100 +Subject: [RHEL8.2 PATCH 57/61] Change warning message + +In commit 039b7225e6 ("md: allow creation of mdNNN arrays via +md_mod/parameters/new_array") support for name like mdNNN +was added. Special warning, when kernel is unable to handle +request, was added in commit 7105228e19 +("mdadm/mdopen: create new function create_named_array for +writing to new_array"), but it was not adequate enough, +because in this situation mdadm tries to do it in old way. +This commit changes warning to be more relevant when +creating RAID container with "/dev/mdNNN" name and mdadm +back to old approach. + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + mdopen.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/mdopen.c b/mdopen.c +index 98c54e4..245be53 100644 +--- a/mdopen.c ++++ b/mdopen.c +@@ -120,7 +120,8 @@ int create_named_array(char *devnm) + close(fd); + } + if (fd < 0 || n != (int)strlen(devnm)) { +- pr_err("Fail create %s when using %s\n", devnm, new_array_file); ++ pr_err("Fail to create %s when using %s, fallback to creation via node\n", ++ devnm, new_array_file); + return 0; + } + +-- +2.7.5 + diff --git a/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch b/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch new file mode 100644 index 0000000..9f664ff --- /dev/null +++ b/SOURCES/0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch @@ -0,0 +1,52 @@ +From 1cc3965d48deb0fb3e0657159c608ffb124643c1 Mon Sep 17 00:00:00 2001 +From: Xiao Yang +Date: Wed, 27 Nov 2019 11:59:24 +0800 +Subject: [RHEL8.2 PATCH 48/61] Manage: Remove the legacy code for md driver + prior to 0.90.03 + +Previous re-add operation only calls ioctl(HOT_ADD_DISK) for array without +metadata(e.g. mdadm -B/--build) when md driver is less than 0.90.02, but +commit 091e8e6 breaks the logic and current re-add operation can call +ioctl(HOT_ADD_DISK) even if md driver is 0.90.03. + +This issue is reproduced by 05r1-re-add-nosuper: +------------------------------------------------ +++ die 'resync or recovery is happening!' +++ echo -e '\n\tERROR: resync or recovery is happening! \n' +ERROR: resync or recovery is happening! +------------------------------------------------ + +Fixes: 091e8e6("Manage: Remove all references to md_get_version()") +Reported-by: kernel test robot +Signed-off-by: Xiao Yang +Signed-off-by: Jes Sorensen +--- + Manage.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/Manage.c b/Manage.c +index 21536f5..ffe55f8 100644 +--- a/Manage.c ++++ b/Manage.c +@@ -741,18 +741,6 @@ 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) { +- if (ioctl(fd, HOT_ADD_DISK, rdev)==0) { +- if (verbose >= 0) +- pr_err("hot added %s\n", +- dv->devname); +- return 1; +- } +- +- pr_err("hot add failed for %s: %s\n", +- dv->devname, strerror(errno)); +- return -1; +- } + + if (array->not_persistent == 0 || tst->ss->external) { + +-- +2.7.5 + diff --git a/SOURCES/0059-imsm-Update-grow-manual.patch b/SOURCES/0059-imsm-Update-grow-manual.patch new file mode 100644 index 0000000..2b54b8f --- /dev/null +++ b/SOURCES/0059-imsm-Update-grow-manual.patch @@ -0,0 +1,43 @@ +From 4431efebabd0dd39f33dc1dd8ada312b8da1c9d8 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Thu, 16 Jan 2020 09:34:44 +0100 +Subject: [RHEL8.2 PATCH 59/61] imsm: Update grow manual. + +Update --grow option description in manual, according to +the supported grow operations by IMSM. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index 6b63bb4..ca02a33 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -481,9 +481,7 @@ still be larger than any replacement. + This value can be set with + .B \-\-grow + for RAID level 1/4/5/6 though +-.B CONTAINER +-based arrays such as those with IMSM metadata may not be able to +-support this. ++DDF arrays may not be able to support this. + If the array was created with a size smaller than the currently + active drives, the extra space can be accessed using + .BR \-\-grow . +@@ -2759,9 +2757,7 @@ container format. The number of devices in a container can be + increased - which affects all arrays in the container - or an array + in a container can be converted between levels where those levels are + supported by the container, and the conversion is on of those listed +-above. Resizing arrays in an IMSM container with +-.B "--grow --size" +-is not yet supported. ++above. + + .PP + Notes: +-- +2.7.5 + diff --git a/SOURCES/0060-Add-support-for-Tebibytes.patch b/SOURCES/0060-Add-support-for-Tebibytes.patch new file mode 100644 index 0000000..45d288e --- /dev/null +++ b/SOURCES/0060-Add-support-for-Tebibytes.patch @@ -0,0 +1,192 @@ +From 42e641abeb312a91b841f1b1ea73661e4bd5a31c Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Tue, 21 Jan 2020 10:38:52 +0100 +Subject: [RHEL8.2 PATCH 60/61] Add support for Tebibytes + +Adding support for Tebibytes enables display size of +volumes in Tebibytes and Terabytes when they are +bigger than 2048 GiB (or GB). + +Signed-off-by: Kinga Tanska +Signed-off-by: Jes Sorensen +--- + mdadm.8.in | 20 ++++++++++---------- + util.c | 47 +++++++++++++++++++++++++++++++++-------------- + 2 files changed, 43 insertions(+), 24 deletions(-) + +diff --git a/mdadm.8.in b/mdadm.8.in +index ca02a33..5d00faf 100644 +--- a/mdadm.8.in ++++ b/mdadm.8.in +@@ -467,8 +467,8 @@ If this is not specified + size, though if there is a variance among the drives of greater than 1%, a warning is + issued. + +-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or +-Gigabytes respectively. ++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, ++Megabytes, Gigabytes or Terabytes respectively. + + Sometimes a replacement drive can be a little smaller than the + original drives though this should be minimised by IDEMA standards. +@@ -532,8 +532,8 @@ problems the array can be made bigger again with no loss with another + .B "\-\-grow \-\-array\-size=" + command. + +-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or +-Gigabytes respectively. ++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, ++Megabytes, Gigabytes or Terabytes respectively. + A value of + .B max + restores the apparent size of the array to be whatever the real +@@ -551,8 +551,8 @@ This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10. + RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power + of 2. In any case it must be a multiple of 4KB. + +-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or +-Gigabytes respectively. ++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, ++Megabytes, Gigabytes or Terabytes respectively. + + .TP + .BR \-\-rounding= +@@ -767,8 +767,8 @@ When using an + bitmap, the chunksize defaults to 64Meg, or larger if necessary to + fit the bitmap into the available space. + +-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or +-Gigabytes respectively. ++A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes, ++Megabytes, Gigabytes or Terabytes respectively. + + .TP + .BR \-W ", " \-\-write\-mostly +@@ -857,8 +857,8 @@ an array which was originally created using a different version of + which computed a different offset. + + Setting the offset explicitly over-rides the default. The value given +-is in Kilobytes unless a suffix of 'K', 'M' or 'G' is used to explicitly +-indicate Kilobytes, Megabytes or Gigabytes respectively. ++is in Kilobytes unless a suffix of 'K', 'M', 'G' or 'T' is used to explicitly ++indicate Kilobytes, Megabytes, Gigabytes or Terabytes respectively. + + Since Linux 3.4, + .B \-\-data\-offset +diff --git a/util.c b/util.c +index 64dd409..07f9dc3 100644 +--- a/util.c ++++ b/util.c +@@ -389,7 +389,7 @@ int mdadm_version(char *version) + unsigned long long parse_size(char *size) + { + /* parse 'size' which should be a number optionally +- * followed by 'K', 'M', or 'G'. ++ * followed by 'K', 'M'. 'G' or 'T'. + * Without a suffix, K is assumed. + * Number returned is in sectors (half-K) + * INVALID_SECTORS returned on error. +@@ -411,6 +411,10 @@ unsigned long long parse_size(char *size) + c++; + s *= 1024 * 1024 * 2; + break; ++ case 'T': ++ c++; ++ s *= 1024 * 1024 * 1024 * 2LL; ++ break; + case 's': /* sectors */ + c++; + break; +@@ -893,13 +897,14 @@ char *human_size(long long bytes) + { + static char buf[47]; + +- /* We convert bytes to either centi-M{ega,ibi}bytes or +- * centi-G{igi,ibi}bytes, with appropriate rounding, +- * and then print 1/100th of those as a decimal. ++ /* We convert bytes to either centi-M{ega,ibi}bytes, ++ * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes ++ * with appropriate rounding, and then print ++ * 1/100th of those as a decimal. + * We allow upto 2048Megabytes before converting to +- * gigabytes, as that shows more precision and isn't ++ * gigabytes and 2048Gigabytes before converting to ++ * terabytes, as that shows more precision and isn't + * too large a number. +- * Terabytes are not yet handled. + */ + + if (bytes < 5000*1024) +@@ -909,11 +914,16 @@ char *human_size(long long bytes) + 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); +- } else { ++ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) { + 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); ++ } else { ++ long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2; ++ long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2; ++ snprintf(buf, sizeof(buf), " (%ld.%02ld TiB %ld.%02ld TB)", ++ cTiB/100, cTiB % 100, cTB/100, cTB % 100); + } + return buf; + } +@@ -922,13 +932,14 @@ char *human_size_brief(long long bytes, int prefix) + { + static char buf[30]; + +- /* We convert bytes to either centi-M{ega,ibi}bytes or +- * centi-G{igi,ibi}bytes, with appropriate rounding, +- * and then print 1/100th of those as a decimal. ++ /* We convert bytes to either centi-M{ega,ibi}bytes, ++ * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes ++ * with appropriate rounding, and then print ++ * 1/100th of those as a decimal. + * We allow upto 2048Megabytes before converting to +- * gigabytes, as that shows more precision and isn't ++ * gigabytes and 2048Gigabytes before converting to ++ * terabytes, as that shows more precision and isn't + * too large a number. +- * Terabytes are not yet handled. + * + * If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc. + * If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc. +@@ -941,10 +952,14 @@ char *human_size_brief(long long bytes, int prefix) + long cMiB = (bytes * 200LL / (1LL<<20) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldMiB", + cMiB/100, cMiB % 100); +- } else { ++ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) { + long cGiB = (bytes * 200LL / (1LL<<30) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldGiB", + cGiB/100, cGiB % 100); ++ } else { ++ long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2; ++ snprintf(buf, sizeof(buf), "%ld.%02ldTiB", ++ cTiB/100, cTiB % 100); + } + } + else if (prefix == JEDEC) { +@@ -952,10 +967,14 @@ char *human_size_brief(long long bytes, int prefix) + long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldMB", + cMB/100, cMB % 100); +- } else { ++ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) { + long cGB = (bytes / (1000000000LL/200LL ) +1) /2; + snprintf(buf, sizeof(buf), "%ld.%02ldGB", + cGB/100, cGB % 100); ++ } else { ++ long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2; ++ snprintf(buf, sizeof(buf), "%ld.%02ldTB", ++ cTB/100, cTB % 100); + } + } + else +-- +2.7.5 + diff --git a/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch b/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch new file mode 100644 index 0000000..8171435 --- /dev/null +++ b/SOURCES/0061-imsm-fill-working_disks-according-to-metadata.patch @@ -0,0 +1,65 @@ +From 1e93d0d15913c3fa6d0de5af3fb5e4e3b3f068da Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +Date: Fri, 17 Jan 2020 15:24:04 +0100 +Subject: [RHEL8.2 PATCH 61/61] imsm: fill working_disks according to metadata. + +Imsm tracks as "working_disk" each visible drive. +Assemble routine expects that the value will return count +of active member drives recorded in metadata. +As a side effect "--no-degraded" doesn't work correctly for imsm. +Align this field to others. +Added check, if the option --no-degraded is called with --scan. + +Signed-off-by: Blazej Kucman +Signed-off-by: Jes Sorensen +--- + mdadm.c | 9 ++++++--- + super-intel.c | 5 ++--- + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/mdadm.c b/mdadm.c +index 256a97e..13dc24e 100644 +--- a/mdadm.c ++++ b/mdadm.c +@@ -1485,9 +1485,12 @@ int main(int argc, char *argv[]) + rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0); + break; + case ASSEMBLE: +- if (devs_found == 1 && ident.uuid_set == 0 && +- ident.super_minor == UnSet && ident.name[0] == 0 && +- !c.scan ) { ++ if (!c.scan && c.runstop == -1) { ++ pr_err("--no-degraded not meaningful without a --scan assembly.\n"); ++ exit(1); ++ } else if (devs_found == 1 && ident.uuid_set == 0 && ++ ident.super_minor == UnSet && ident.name[0] == 0 && ++ !c.scan) { + /* Only a device has been given, so get details from config file */ + struct mddev_ident *array_ident = conf_get_ident(devlist->devname); + if (array_ident == NULL) { +diff --git a/super-intel.c b/super-intel.c +index 5c1f759..47809bc 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -7946,7 +7946,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + skip = 1; + if (!skip && (ord & IMSM_ORD_REBUILD)) + recovery_start = 0; +- ++ if (!(ord & IMSM_ORD_REBUILD)) ++ this->array.working_disks++; + /* + * if we skip some disks the array will be assmebled degraded; + * reset resync start to avoid a dirty-degraded +@@ -7988,8 +7989,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra + else + this->array.spare_disks++; + } +- if (info_d->recovery_start == MaxSector) +- this->array.working_disks++; + + info_d->events = __le32_to_cpu(mpb->generation_num); + info_d->data_offset = pba_of_lba0(map); +-- +2.7.5 + diff --git a/SOURCES/0062-Remove-the-legacy-whitespace.patch b/SOURCES/0062-Remove-the-legacy-whitespace.patch new file mode 100644 index 0000000..31c764a --- /dev/null +++ b/SOURCES/0062-Remove-the-legacy-whitespace.patch @@ -0,0 +1,52 @@ +commit fd38b8ea80ff8e0317e12d1d70431148ceedd5fd +Author: Xiao Ni +Date: Tue Feb 11 21:44:15 2020 +0800 + + Remove the legacy whitespace + + The whitespace between Environment= and the true value causes confusion. + To avoid confusing other people in future, remove the whitespace to keep + it a simple, unambiguous syntax + + Signed-off-by: Xiao Ni + Signed-off-by: Jes Sorensen + +diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service +index aa02dde..854317f 100644 +--- a/systemd/mdcheck_continue.service ++++ b/systemd/mdcheck_continue.service +@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_* + + [Service] + Type=oneshot +-Environment= "MDADM_CHECK_DURATION=6 hours" ++Environment="MDADM_CHECK_DURATION=6 hours" + EnvironmentFile=-/run/sysconfig/mdadm + ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh + ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION} +diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service +index da62d5f..3bb3d13 100644 +--- a/systemd/mdcheck_start.service ++++ b/systemd/mdcheck_start.service +@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer + + [Service] + Type=oneshot +-Environment= "MDADM_CHECK_DURATION=6 hours" ++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/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service +index fd469b1..373955a 100644 +--- a/systemd/mdmonitor-oneshot.service ++++ b/systemd/mdmonitor-oneshot.service +@@ -9,7 +9,7 @@ + Description=Reminder for degraded MD arrays + + [Service] +-Environment= MDADM_MONITOR_ARGS=--scan ++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/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch new file mode 100644 index 0000000..1eb335a --- /dev/null +++ b/SOURCES/mdadm-2.5.2-static.patch @@ -0,0 +1,23 @@ +--- mdadm-3.2.1/Makefile.static 2011-03-27 22:31:20.000000000 -0400 ++++ mdadm-3.2.1/Makefile 2011-03-28 10:16:55.277900184 -0400 +@@ -238,16 +238,16 @@ install : mdadm mdmon install-man instal + $(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon + + install-static : mdadm.static install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static + + install-tcc : mdadm.tcc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm.tcc + + install-uclibc : mdadm.uclibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm.uclibc + + install-klibc : mdadm.klibc install-man +- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm.klibc + + install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 + $(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8 diff --git a/SOURCES/mdadm-3.3-udev.patch b/SOURCES/mdadm-3.3-udev.patch new file mode 100644 index 0000000..50c0074 --- /dev/null +++ b/SOURCES/mdadm-3.3-udev.patch @@ -0,0 +1,13 @@ +--- mdadm-4.1_rc1/udev-md-raid-assembly.rules~ 2018-06-22 13:10:58.196250086 +0800 ++++ mdadm-4.1_rc1/udev-md-raid-assembly.rules 2018-06-22 13:11:37.761241080 +0800 +@@ -5,6 +5,10 @@ + ENV{ANACONDA}=="?*", GOTO="md_inc_end" + # assemble md arrays + ++# In Fedora we handle the raid components in 65-md-incremental.rules so that ++# we can do things like honor anaconda command line options and such ++GOTO="md_inc_end" ++ + SUBSYSTEM!="block", GOTO="md_inc_end" + + # skip non-initialized devices diff --git a/SOURCES/mdadm-cron b/SOURCES/mdadm-cron new file mode 100644 index 0000000..4e05d68 --- /dev/null +++ b/SOURCES/mdadm-cron @@ -0,0 +1,3 @@ +# Run system wide raid-check once a week on Sunday at 1am by default +0 1 * * Sun root /usr/sbin/raid-check + diff --git a/SOURCES/mdadm-raid-check-sysconfig b/SOURCES/mdadm-raid-check-sysconfig new file mode 100644 index 0000000..8e82270 --- /dev/null +++ b/SOURCES/mdadm-raid-check-sysconfig @@ -0,0 +1,60 @@ +#!/bin/bash +# +# Configuration file for /etc/cron.weekly/raid-check +# +# options: +# ENABLED - must be yes in order for the raid check to proceed +# CHECK - can be either check or repair depending on the type of +# operation the user desires. A check operation will scan +# the drives looking for bad sectors and automatically +# repairing only bad sectors. If it finds good sectors that +# contain bad data (meaning that the data in a sector does +# not agree with what the data from another disk indicates +# the data should be, for example the parity block + the other +# data blocks would cause us to think that this data block +# is incorrect), then it does nothing but increments the +# counter in the file /sys/block/$dev/md/mismatch_count. +# This allows the sysadmin to inspect the data in the sector +# and the data that would be produced by rebuilding the +# sector from redundant information and pick the correct +# data to keep. The repair option does the same thing, but +# when it encounters a mismatch in the data, it automatically +# updates the data to be consistent. However, since we really +# don't know whether it's the parity or the data block that's +# correct (or which data block in the case of raid1), it's +# luck of the draw whether or not the user gets the right +# data instead of the bad data. This option is the default +# option for devices not listed in either CHECK_DEVS or +# REPAIR_DEVS. +# CHECK_DEVS - a space delimited list of devs that the user specifically +# wants to run a check operation on. +# REPAIR_DEVS - a space delimited list of devs that the user +# specifically wants to run a repair on. +# SKIP_DEVS - a space delimited list of devs that should be skipped +# NICE - Change the raid check CPU and IO priority in order to make +# the system more responsive during lengthy checks. Valid +# values are high, normal, low, idle. +# MAXCONCURENT - Limit the number of devices to be checked at a time. +# By default all devices will be checked at the same time. +# +# Note: the raid-check script intentionaly runs last in the cron.weekly +# sequence. This is so we can wait for all the resync operations to complete +# and then check the mismatch_count on each array without unduly delaying +# other weekly cron jobs. If any arrays have a non-0 mismatch_count after +# the check completes, we echo a warning to stdout which will then me emailed +# to the admin as long as mails from cron jobs have not been redirected to +# /dev/null. We do not wait for repair operations to complete as the +# md stack will correct any mismatch_cnts automatically. +# +# Note2: you can not use symbolic names for the raid devices, such as you +# /dev/md/root. The names used in this file must match the names seen in +# /proc/mdstat and in /sys/block. + +ENABLED=yes +CHECK=check +NICE=low +# To check devs /dev/md0 and /dev/md3, use "md0 md3" +CHECK_DEVS="" +REPAIR_DEVS="" +SKIP_DEVS="" +MAXCONCURRENT= diff --git a/SOURCES/mdadm.conf b/SOURCES/mdadm.conf new file mode 100644 index 0000000..3207dda --- /dev/null +++ b/SOURCES/mdadm.conf @@ -0,0 +1 @@ +d /run/mdadm 0710 root root - diff --git a/SOURCES/mdadm.rules b/SOURCES/mdadm.rules new file mode 100644 index 0000000..b622c6b --- /dev/null +++ b/SOURCES/mdadm.rules @@ -0,0 +1,69 @@ +# This file causes block devices with Linux RAID (mdadm) signatures to +# automatically cause mdadm to be run. +# See udev(8) for syntax + +# Don't process any events if anaconda is running as anaconda brings up +# raid devices manually +ENV{ANACONDA}=="?*", GOTO="md_end" + +# Also don't process disks that are slated to be a multipath device +ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end" + +# We process add events on block devices (since they are ready as soon as +# they are added to the system), but we must process change events as well +# on any dm devices (like LUKS partitions or LVM logical volumes) and on +# md devices because both of these first get added, then get brought live +# and trigger a change event. The reason we don't process change events +# on bare hard disks is because if you stop all arrays on a disk, then +# run fdisk on the disk to change the partitions, when fdisk exits it +# triggers a change event, and we want to wait until all the fdisks on +# all member disks are done before we do anything. Unfortunately, we have +# no way of knowing that, so we just have to let those arrays be brought +# up manually after fdisk has been run on all of the disks. + +# First, process all add events (md and dm devices will not really do +# anything here, just regular disks, and this also won't get any imsm +# array members either) +SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \ + IMPORT{program}="/sbin/mdadm -I $env{DEVNAME} --export $devnode --offroot ${DEVLINKS}" +SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \ + ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" +SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \ + ENV{ID_FS_TYPE}=="linux_raid_member", \ + RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}" +SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \ + ENV{ID_FS_TYPE}=="linux_raid_member", \ + RUN+="/sbin/mdadm -If $name" + +# Next, check to make sure the BIOS raid stuff wasn't turned off via cmdline +IMPORT{cmdline}="noiswmd" +IMPORT{cmdline}="nodmraid" +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}" +SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \ + ENV{ID_FS_TYPE}=="isw_raid_member", \ + RUN+="/sbin/mdadm -If $name" +LABEL="md_imsm_inc_end" + +# Next make sure that this isn't a dm device we should skip for some reason +ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="dm_change_end" +ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="dm_change_end" +ENV{DM_SUSPENDED}=="1", GOTO="dm_change_end" +KERNEL=="dm-*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \ + ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}" +LABEL="dm_change_end" + +# Finally catch any nested md raid arrays. If we brought up an md raid +# array that's part of another md raid array, it won't be ready to be used +# until the change event that occurs when it becomes live +KERNEL=="md*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \ + ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}" + +LABEL="md_end" diff --git a/SOURCES/mdadm_env.sh b/SOURCES/mdadm_env.sh new file mode 100644 index 0000000..c13b48a --- /dev/null +++ b/SOURCES/mdadm_env.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +# extract configuration from /etc/sysconfig/mdadm and write +# environment to /run/sysconfig/mdadm to be used by +# systemd unit files. + +MDADM_SCAN="yes" + +# Following adapted from /etc/init.d/mdadmd on openSUSE + +mdadmd_CONFIG=/etc/sysconfig/mdadm +if test -r $mdadmd_CONFIG; then + . $mdadmd_CONFIG +fi + +if [ x$MDADM_DELAY != x"" ]; then + MDADM_DELAY="-d "$MDADM_DELAY; +fi + +if [ x$MDADM_MAIL != x"" ]; then + MDADM_MAIL="-m \"$MDADM_MAIL\"" +fi + +if [ x$MDADM_PROGRAM != x"" ]; then + MDADM_PROGRAM="-p \"$MDADM_PROGRAM\"" +fi + +if [ x$MDADM_SCAN = x"yes" ]; then + MDADM_SCAN="--scan" +else + MDADM_SCAN="" +fi + +if [ x$MDADM_SEND_MAIL_ON_START = x"yes" ]; then + MDADM_SEND_MAIL="-t" +else + MDADM_SEND_MAIL="" +fi + +if [ x$MDADM_CONFIG != x"" ]; then + MDADM_CONFIG="-c \"$MDADM_CONFIG\"" +fi + +mkdir -p /run/sysconfig +echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm +if [ -n "$MDADM_CHECK_DURATION" ]; then + echo "MDADM_CHECK_DURATION=$MDADM_CHECK_DURATION" >> /run/sysconfig/mdadm +fi diff --git a/SOURCES/mdadm_event.conf b/SOURCES/mdadm_event.conf new file mode 100644 index 0000000..1a6c479 --- /dev/null +++ b/SOURCES/mdadm_event.conf @@ -0,0 +1,5 @@ +# Save /proc/mdstat in case of crash in mdadm/mdmon + +EVENT=post-create component=mdadm + cat /proc/mdstat >> mdstat_data + echo "Saved output of /proc/mdstat" diff --git a/SOURCES/mdcheck b/SOURCES/mdcheck new file mode 100644 index 0000000..42d4094 --- /dev/null +++ b/SOURCES/mdcheck @@ -0,0 +1,164 @@ +#!/bin/bash + +# Copyright (C) 2014-2017 Neil Brown +# +# +# 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. +# +# Author: Neil Brown +# Email: + +# This script should be run periodically to automatically +# perform a 'check' on any md arrays. +# +# It supports a 'time budget' such that any incomplete 'check' +# will be checkpointed when that time has expired. +# A subsequent invocation can allow the 'check' to continue. +# +# Options are: +# --continue Don't start new checks, only continue old ones. +# --duration This is passed to "date --date=$duration" to find out +# when to finish +# +# To support '--continue', arrays are identified by UUID and the 'sync_completed' +# value is stored in /var/lib/mdcheck/$UUID + +# convert a /dev/md name into /sys/.../md equivalent +sysname() { + set `ls -lLd $1` + maj=${5%,} + min=$6 + readlink -f /sys/dev/block/$maj:$min +} + +args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@") +rv=$? +if [ $rv -ne 0 ]; then exit $rv; fi + +eval set -- $args + +cont= +endtime= +while [ " $1" != " --" ] +do + case $1 in + --help ) + echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]' + echo >&2 ' time-offset must be understood by "date --date"' + exit 0 + ;; + --continue ) cont=yes ;; + --duration ) shift; dur=$1 + endtime=$(date --date "$dur" "+%s") + ;; + esac + shift +done +shift + +# We need a temp file occasionally... +tmp=/var/lib/mdcheck/.md-check-$$ +trap 'rm -f "$tmp"' 0 2 3 15 + + +# firstly, clean out really old state files +mkdir -p /var/lib/mdcheck +find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \; + +# Now look at each md device. +cnt=0 +for dev in /dev/md?* +do + [ -e "$dev" ] || continue + sys=`sysname $dev` + if [ ! -f "$sys/md/sync_action" ] + then # cannot check this array + continue + fi + if [ "`cat $sys/md/sync_action`" != 'idle' ] + then # This array is busy + continue + fi + + mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue + source $tmp + fl="/var/lib/mdcheck/MD_UUID_$MD_UUID" + if [ -z "$cont" ] + then + start=0 + logger -p daemon.info mdcheck start checking $dev + elif [ -z "$MD_UUID" -o ! -f "$fl" ] + then + # Nothing to continue here + continue + else + start=`cat "$fl"` + logger -p daemon.info mdcheck continue checking $dev from $start + fi + + cnt=$[cnt+1] + eval MD_${cnt}_fl=\$fl + eval MD_${cnt}_sys=\$sys + eval MD_${cnt}_dev=\$dev + echo $start > $fl + echo $start > $sys/md/sync_min + echo check > $sys/md/sync_action +done + +if [ -z "$endtime" ] +then + exit 0 +fi + +while [ `date +%s` -lt $endtime ] +do + any= + for i in `eval echo {1..$cnt}` + do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + eval MD_${i}_fl= + rm -f $fl + continue; + fi + read a rest < $sys/md/sync_completed + echo $a > $fl + any=yes + done + if [ -z "$any" ]; then exit 0; fi + sleep 120 +done + +# We've waited, and there are still checks running. +# Time to stop them. +for i in `eval echo {1..$cnt}` +do + eval fl=\$MD_${i}_fl + eval sys=\$MD_${i}_sys + eval dev=\$MD_${i}_dev + + if [ -z "$fl" ]; then continue; fi + + if [ "`cat $sys/md/sync_action`" != 'check' ] + then + eval MD_${i}_fl= + rm -f $fl + continue; + fi + echo idle > $sys/md/sync_action + cat $sys/md/sync_min > $fl + logger -p daemon.info pause checking $dev at `cat $fl` +done diff --git a/SOURCES/mdmonitor.init b/SOURCES/mdmonitor.init new file mode 100755 index 0000000..03f3e95 --- /dev/null +++ b/SOURCES/mdmonitor.init @@ -0,0 +1,118 @@ +#!/bin/bash +# +# mdmonitor This starts, stops, and reloads the mdadm-based +# software RAID monitoring and management facility +# +# chkconfig: 2345 15 85 +# description: software RAID monitoring and management +# config: /etc/mdadm.conf +# +# Copyright 2002 Red Hat, Inc. +# +### BEGIN INIT INFO +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start and stop the MD software RAID monitor +# Description: The mdmonitor service checks the status of all software +# RAID arrays on the system. In the event that any of the arrays +# transition into a degraded state, it notifies the system +# administrator. Other options are available, see the mdadm.conf +# and mdadm man pages for possible ways to configure this service. +### END INIT INFO + +PIDPATH=/var/run/mdadm +PIDFILE=/var/run/mdadm/mdadm.pid +PATH=/sbin:/usr/sbin:$PATH +RETVAL=0 +OPTIONS="--monitor --scan -f --pid-file=$PIDFILE" + +prog=mdmonitor + +# Source function library. +. /etc/rc.d/init.d/functions + + +usage () +{ + echo "Usage: service $prog {start|stop|status|restart|try-restart|force-reload}" + RETVAL=1 +} + + +start () +{ +# (Re)start mdmon to take over monitoring of mdmon started from the initrd + for i in /dev/md/*.pid; do + if [ -r $i ]; then + origprog="$prog"; prog="mdmon" + action $"Starting $prog: " /sbin/mdmon --takeover --all + prog="$origprog" + break + fi + done +# Make sure configuration file exists and has information we can use +# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor + [ -f /etc/mdadm.conf ] || return 6 + grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || return 6 + # Create our directory if it isn't there yet + if [ ! -d $PIDPATH ]; then + mkdir -m 0700 $PIDPATH >&/dev/null + RC=$? + [ -x /sbin/restorecon ] && /sbin/restorecon $PIDPATH + if [ $RC -ne 0 ]; then + echo -n "Failed to create /var/run/mdadm" + failure + echo + return 1 + fi + fi + if [ -f "$PIDFILE" ]; then + checkpid `cat $PIDFILE` && return 0 + fi + echo -n $"Starting $prog: " + cd / + daemon --user=root mdadm ${OPTIONS} + ret=$? + [ $ret -eq "0" ] && touch /var/lock/subsys/$prog + echo + return $ret +} + +stop () +{ + [ -f /var/lock/subsys/$prog ] || return 0 + echo -n "Killing $prog: " + killproc mdadm + echo + rm -f $PIDFILE + rm -f /var/lock/subsys/$prog +} + +restart () +{ + stop + start +} + +condrestart () +{ + [ -e /var/lock/subsys/$prog ] && restart || return 0 +} + + +case "$1" in + start|stop|restart|condrestart|try-restart|force-reload) + [ `id -u` != "0" ] && exit 4 ;; +esac + +case "$1" in + start) start; RETVAL=$? ;; + stop) stop; RETVAL=$? ;; + status) status -p $PIDFILE $prog ; RETVAL=$? ;; + restart) restart; RETVAL=$? ;; + reload) RETVAL=3 ;; + condrestart|try-restart|force-reload) condrestart; RETVAL=$? ;; + *) usage ; RETVAL=2 ;; +esac + +exit $RETVAL diff --git a/SOURCES/mdmonitor.service b/SOURCES/mdmonitor.service new file mode 100644 index 0000000..123ae8a --- /dev/null +++ b/SOURCES/mdmonitor.service @@ -0,0 +1,12 @@ +[Unit] +Description=Software RAID monitoring and management +ConditionPathExists=/etc/mdadm.conf + +[Service] +Type=forking +PIDFile=/var/run/mdadm/mdadm.pid +EnvironmentFile=-/etc/sysconfig/mdmonitor +ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/raid-check b/SOURCES/raid-check new file mode 100644 index 0000000..7b2fb59 --- /dev/null +++ b/SOURCES/raid-check @@ -0,0 +1,135 @@ +#!/bin/bash +# +# This script reads it's configuration from /etc/sysconfig/raid-check +# Please use that file to enable/disable this script or to set the +# type of check you wish performed. + +# We might be on a kernel with no raid support at all, exit if so +[ -f /proc/mdstat ] || exit 0 + +# and exit if we haven't been set up properly +[ -f /etc/sysconfig/raid-check ] || exit 0 +. /etc/sysconfig/raid-check + +# Wait until no more than arg1 arrays in arg2 list are busy +waitbusy() { + local threshold=$(($1 + 1)) + local dev_list="$2" + while true + do + local busy=0 + local dev="" + for dev in $dev_list; do + local sync_action=`cat /sys/block/$dev/md/sync_action` + if [ "$sync_action" != "idle" ]; then + let busy++ + fi + done + [ $busy -lt $threshold ] && break + sleep 60 + done +} + +[ "$ENABLED" != "yes" ] && exit 0 + +case "$CHECK" in + check) ;; + repair) ;; + *) exit 0;; +esac + +ionice="" +renice="" +case $NICE in + high) + renice="-n -5" + ;; + low) + renice="-n 5" + ionice="-c2 -n7" + ;; + idle) + renice="-n 15" + ionice="-c3" + ;; + *) + ;; +esac + +active_list=`grep "^md.*: active" /proc/mdstat | cut -f 1 -d ' '` +[ -z "$active_list" ] && exit 0 + +declare -A check +dev_list="" +check_list="" +for dev in $active_list; do + echo $SKIP_DEVS | grep -w $dev >&/dev/null && continue + if [ -f /sys/block/$dev/md/sync_action ]; then + # Only perform the checks on idle, healthy arrays, but delay + # actually writing the check field until the next loop so we + # don't switch currently idle arrays to active, which happens + # when two or more arrays are on the same physical disk + array_state=`cat /sys/block/$dev/md/array_state` + if [ "$array_state" != "clean" -a "$array_state" != "active" ]; then + continue + fi + sync_action=`cat /sys/block/$dev/md/sync_action` + if [ "$sync_action" != idle ]; then + continue + fi + ck="" + echo $REPAIR_DEVS | grep -w $dev >&/dev/null && ck="repair" + echo $CHECK_DEVS | grep -w $dev >&/dev/null && ck="check" + [ -z "$ck" ] && ck=$CHECK + dev_list="$dev_list $dev" + check[$dev]=$ck + [ "$ck" = "check" ] && check_list="$check_list $dev" + fi +done +[ -z "$dev_list" ] && exit 0 + +for dev in $dev_list; do + #Only run $MAXCONCURRENT checks at a time + if [ -n "$MAXCONCURRENT" ]; then + waitbusy $((MAXCONCURRENT - 1)) "$dev_list" + fi + echo "${check[$dev]}" > /sys/block/$dev/md/sync_action + + resync_pid="" + wait=10 + while [ $wait -gt 0 -a -z "$resync_pid" ]; do + sleep 6 + let wait-- + resync_pid=$(ps -ef | awk -v mddev=$dev 'BEGIN { pattern = "^\\[" mddev "_resync]$" } $8 ~ pattern { print $2 }') + done + [ -n "$resync_pid" -a -n "$renice" ] && + renice $renice -p $resync_pid >&/dev/null + [ -n "$resync_pid" -a -n "$ionice" ] && + ionice $ionice -p $resync_pid >&/dev/null +done +[ -z "$check_list" ] && exit 0 + +waitbusy 0 "$check_list" + +for dev in $check_list; do + mismatch_cnt=`cat /sys/block/$dev/md/mismatch_cnt` + # Due to the fact that raid1/10 writes in the kernel are unbuffered, + # a raid1 array can have non-0 mismatch counts even when the + # array is healthy. These non-0 counts will only exist in + # transient data areas where they don't pose a problem. However, + # since we can't tell the difference between a non-0 count that + # is just in transient data or a non-0 count that signifies a + # real problem, simply don't check the mismatch_cnt on raid1 + # devices as it's providing far too many false positives. But by + # leaving the raid1 device in the check list and performing the + # check, we still catch and correct any bad sectors there might + # be in the device. + raid_lvl=`cat /sys/block/$dev/md/level` + if [ "$raid_lvl" = "raid1" -o "$raid_lvl" = "raid10" ]; then + continue + fi + if [ "$mismatch_cnt" -ne 0 ]; then + echo "WARNING: mismatch_cnt is not 0 on /dev/$dev" + fi +done + diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec new file mode 100644 index 0000000..98733d2 --- /dev/null +++ b/SPECS/mdadm.spec @@ -0,0 +1,1232 @@ +Summary: The mdadm program controls Linux md devices (software RAID arrays) +Name: mdadm +Version: 4.1 +Release: 13%{?dist} +Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz +Source1: mdmonitor.init +Source2: raid-check +Source3: mdadm.rules +Source4: mdadm-raid-check-sysconfig +Source5: mdadm-cron +Source6: mdmonitor.service +Source7: mdadm.conf +Source8: mdadm_event.conf +Source9: mdcheck +Source10: mdadm_env.sh + +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 +Patch25: 0025-mdmon-fix-wrong-array-state-when-disk-fails-during-m.patch +Patch26: 0026-Enable-probe_roms-to-scan-more-than-6-roms.patch +Patch27: 0027-super-intel-Fix-issue-with-abs-being-irrelevant.patch +Patch28: 0028-mdadm.h-Introduced-unaligned-get-put-_unaligned-16-3.patch +Patch29: 0029-super-intel-Use-put_unaligned-in-split_ull.patch +Patch30: 0030-mdadm-load-default-sysfs-attributes-after-assemblati.patch +Patch31: 0031-mdadm.h-include-sysmacros.h-unconditionally.patch +Patch32: 0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch +Patch33: 0033-udev-add-no-devices-option-for-calling-mdadm-detail.patch +Patch34: 0034-imsm-close-removed-drive-fd.patch +Patch35: 0035-mdadm-check-value-returned-by-snprintf-against-error.patch +Patch36: 0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch +Patch37: 0037-mdadm-force-a-uuid-swap-on-big-endian.patch +Patch38: 0038-mdadm-md.4-add-the-descriptions-for-bitmap-sysfs-nod.patch +Patch39: 0039-Init-devlist-as-an-array.patch +Patch40: 0040-Don-t-need-to-check-recovery-after-re-add-when-no-I-.patch +Patch41: 0041-udev-allow-for-udev-attribute-reading-bug.patch +Patch42: 0042-imsm-save-current_vol-number.patch +Patch43: 0043-imsm-allow-to-specify-second-volume-size.patch +Patch44: 0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch +Patch45: 0045-mdcheck-use-to-pass-variable-to-mdcheck.patch +Patch46: 0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch +Patch47: 0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch +Patch48: 0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch +Patch49: 0049-Remove-last-traces-of-HOT_ADD_DISK.patch +Patch50: 0050-Fix-up-a-few-formatting-issues.patch +Patch51: 0051-Remove-unused-code.patch +Patch52: 0052-imsm-return-correct-uuid-for-volume-in-detail.patch +Patch53: 0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch +Patch54: 0054-Create-add-support-for-RAID0-layouts.patch +Patch55: 0055-Assemble-add-support-for-RAID0-layouts.patch +Patch56: 0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch +Patch57: 0057-Change-warning-message.patch +Patch58: 0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch +Patch59: 0059-imsm-Update-grow-manual.patch +Patch60: 0060-Add-support-for-Tebibytes.patch +Patch61: 0061-imsm-fill-working_disks-according-to-metadata.patch +Patch62: 0062-Remove-the-legacy-whitespace.patch + +# RHEL customization patches +Patch97: mdadm-3.3-udev.patch +Patch98: mdadm-2.5.2-static.patch + +URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ +License: GPLv2+ +Group: System Environment/Base +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Obsoletes: mdctl,raidtools +Obsoletes: mdadm-sysvinit +Conflicts: dracut < 034-1 +Requires(post): systemd-units chkconfig coreutils +BuildRequires: systemd-units binutils-devel +Requires(preun): systemd-units +Requires(postun): systemd-units coreutils +Requires: libreport-filesystem + +%define _hardened_build 1 + +%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 +almost all functions without a configuration file, though a configuration +file can be used to help with some common tasks. + +%prep +%setup -q + +%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 +%patch25 -p1 -b .0025 +%patch26 -p1 -b .0026 +%patch27 -p1 -b .0027 +%patch28 -p1 -b .0028 +%patch29 -p1 -b .0029 +%patch30 -p1 -b .0030 +%patch31 -p1 -b .0031 +%patch32 -p1 -b .0032 +%patch33 -p1 -b .0033 +%patch34 -p1 -b .0034 +%patch35 -p1 -b .0035 +%patch36 -p1 -b .0036 +%patch37 -p1 -b .0037 +%patch38 -p1 -b .0038 +%patch39 -p1 -b .0039 +%patch40 -p1 -b .0040 +%patch41 -p1 -b .0041 +%patch42 -p1 -b .0042 +%patch43 -p1 -b .0043 +%patch44 -p1 -b .0044 +%patch45 -p1 -b .0045 +%patch46 -p1 -b .0046 +%patch47 -p1 -b .0047 +%patch48 -p1 -b .0048 +%patch49 -p1 -b .0049 +%patch50 -p1 -b .0050 +%patch51 -p1 -b .0051 +%patch52 -p1 -b .0052 +%patch53 -p1 -b .0053 +%patch54 -p1 -b .0054 +%patch55 -p1 -b .0055 +%patch56 -p1 -b .0056 +%patch57 -p1 -b .0057 +%patch58 -p1 -b .0058 +%patch59 -p1 -b .0059 +%patch60 -p1 -b .0060 +%patch61 -p1 -b .0061 +%patch62 -p1 -b .0062 + +# RHEL customization patches +%patch97 -p1 -b .udev +%patch98 -p1 -b .static + +%build +make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon + +%install +rm -rf %{buildroot} +make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} install install-systemd +install -Dp -m 755 %{SOURCE2} %{buildroot}%{_sbindir}/raid-check +install -Dp -m 644 %{SOURCE3} %{buildroot}%{_udevrulesdir}/65-md-incremental.rules +install -Dp -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/raid-check +install -Dp -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/raid-check +mkdir -p -m 710 %{buildroot}/var/run/mdadm +mkdir -p -m 700 %{buildroot}/usr/share/mdadm +mkdir -p -m 700 %{buildroot}/usr/lib/mdadm +install -Dp -m 755 %{SOURCE9} %{buildroot}/usr/share/mdadm/mdcheck +install -Dp -m 755 %{SOURCE10} %{buildroot}/usr/lib/mdadm/mdadm_env.sh + +# systemd +mkdir -p %{buildroot}%{_unitdir} +install -m644 %{SOURCE6} %{buildroot}%{_unitdir} + +# tmpfile +mkdir -p %{buildroot}%{_tmpfilesdir} +install -m 0644 %{SOURCE7} %{buildroot}%{_tmpfilesdir}/%{name}.conf +mkdir -p %{buildroot}%{_localstatedir}/run/ +install -d -m 0710 %{buildroot}%{_localstatedir}/run/%{name}/ + +# abrt +mkdir -p %{buildroot}/etc/libreport/events.d +install -m644 %{SOURCE8} %{buildroot}/etc/libreport/events.d + +%clean +rm -rf %{buildroot} + +%post +%systemd_post mdmonitor.service +/usr/bin/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || : + +%preun +%systemd_preun mdmonitor.service + +%postun +%systemd_postun_with_restart mdmonitor.service + +%triggerun -- %{name} < 3.2.2-3 +%{_bindir}/systemd-sysv-convert --save mdmonitor >/dev/null 2>&1 || : +/bin/systemctl --no-reload enable mdmonitor.service >/dev/null 2>&1 || : +/sbin/chkconfig --del mdmonitor >/dev/null 2>&1 || : +/bin/systemctl try-restart mdmonitor.service >/dev/null 2>&1 || : + +%files +%defattr(-,root,root,-) +%doc TODO ChangeLog mdadm.conf-example COPYING misc/* +%{_udevrulesdir}/* +%{_sbindir}/* +%{_unitdir}/* +%{_mandir}/man*/md* +/usr/lib/systemd/system-shutdown/* +%config(noreplace) %{_sysconfdir}/cron.d/* +%config(noreplace) %{_sysconfdir}/sysconfig/* +%dir %{_localstatedir}/run/%{name}/ +%config(noreplace) %{_tmpfilesdir}/%{name}.conf +/etc/libreport/events.d/* +/usr/share/mdadm/mdcheck +/usr/lib/mdadm/mdadm_env.sh + +%changelog +* Fri Feb 28 2020 Xiao Ni - 4.1.13 +- Remove the unnecessary whitespace in .service file +- Resolves rhbz#1803470 + +* Tue Feb 11 2020 Xiao Ni - 4.1.12 +- Update mdadm to latest upstream && change tmpfiles directory && correct changelog date +- Resolves rhbz#1800521 and rhbz#1657265 + +* Sun Feb 09 2020 Xiao Ni - 4.1.11 +- mdcheck start service can't start +- Resolves rhbz#1769823 + +* Fri Nov 15 2019 Xiao Ni - 4.1.10 +- Update mdadm to latest upstream +- Resolves rhbz#1721937 + +* Wed 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 + +* Fri Dec 21 2018 Xiao Ni - 4.1.3 +- Recovery isn't noticed while raid10 double degradation +- Resolves rhbz#1654482 + +* Wed Dec 12 2018 Xiao Ni - 4.1.2 +- Add warning message for using raid1 cluster +- Resolves rhbz#1654482 + +* Fri Oct 26 2018 Xiao Ni - 4.1.1 +- Update to upstream 4.1 +- Resolves rhbz#1642206 + +* Wed Oct 24 2018 Xiao Ni - 4.1-rc1-3 +- Can't find md device when install rhel8 +- Resolves rhbz#1628774 + +* Thu Aug 16 2018 Xiao Ni - 4.1-rc1-2 +- Fix two IMSM bugs +- Resolves rhbz#1602420 and rhbz#1602422 + +* Fri Jun 22 2018 Xiao Ni - 4.1-rc1-1 +- Upgrade to upstream mdadm-4.1-rc1 +- Resolves rhbz#1493605 and rhbz#1494477 and rhbz#1502118 + +* Thu Aug 03 2017 Fedora Release Engineering - 4.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 4.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Apr 26 2017 Xiao Ni - 4.0-3 +- Fix building errors against newer gcc (>=7.0) +- Resolves bz1444756 + +* Fri Feb 10 2017 Fedora Release Engineering - 4.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Xiao Ni - 4.0-1 +- Upgrade to mdadm-4.0 +- Resolves bz1411555 + +* Mon Aug 15 2016 Jes Sorensen - 3.4-3 +- Fix build against newer glibc (Fedora 26+) + +* Fri Aug 12 2016 Jes Sorensen - 3.4-2 +- Fix i686 build error +- Fix problem where it was not possible to stop an IMSM array during reshape +- Fix Degraded Raid1 array becomes inactive after rebooting +- Fix problem with raid0 arrays not being detected by Anaconda due to it + setting MALLOC_PERTURB_ +- Fix problem with reshaping IMSM arrays, where a new reshape could be + launched before the first reshape had fully completed, leading to + unpected results. +- Fix problem with mdadm large device names overflowing an internal buffer +- Fix problem about reshape stuck at beginning +- Resolves bz1303380 + +* Fri Aug 12 2016 Jes Sorensen - 3.4-1 +- Upgrade to mdadm-3.4 +- Resolves bz1303380 + +* Mon May 30 2016 Xiao Ni - 3.3.4-4 +- Fix Degraded Raid1 array becomes inactive after rebooting +- Resolves bz1337004 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.3.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Oct 5 2015 Jes Sorensen - 3.3.4-2 +- Fix race when assembling or stopping IMSM RAID arrays +- Resolves bz1268955 + +* Mon Oct 5 2015 Jes Sorensen - 3.3.4-1 +- Upgrade to mdadm-3.3.4 +- Resolves bz1246474 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Aug 26 2014 Jes Sorensen - 3.3.2-1 +- Upgrade to mdadm-3.3.2 +- Resolves bz1132847 +* Sun Aug 17 2014 Fedora Release Engineering - 3.3.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Aug 5 2014 Jes Sorensen - 3.3.1-6 +- Apply proper fix for bz1125883, clean up after rogue patch application +- Resolves bz1125883 + +* Mon Aug 04 2014 Dan Horák - 3.3.1-5 +- revert the previous fix, not upstream yet + +* Mon Aug 04 2014 Dan Horák - 3.3.1-4 +- fix FTBFS on ppc64 (#1125883) + +* Tue Jul 29 2014 Jes Sorensen - 3.3.1-3 +- Improve error message for "--grow -n2" when used on Linear arrays +- Fix problem where explicitly specified arrays were not assembled if + they were disabled in /etc/mdadm.conf +- Resolves bz1122146, bz1124310 + +* Thu Jun 12 2014 Jes Sorensen - 3.3.1-2 +- Revert 'change' event support fix from 3.3.1-1 - this requires a lot + more testing if we are to go there. + +* Tue Jun 10 2014 Jes Sorensen - 3.3.1-1 +- Update to mdadm-3.3.1 +- Fixup mdadm.rules to honor 'change' events +- Resolvez bz1105136 + +* Sat Jun 07 2014 Fedora Release Engineering - 3.3-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Mar 14 2014 Jes Sorensen - 3.3-7 +- Don't depend on syslog.target in mdmonitor.service +- Resolves bz1055202 + +* Fri Jan 31 2014 Jes Sorensen - 3.3-6 +- Revert changes introduced in 3.3-5, they were based on incorrect + recommendations. +- Resolves bz1053176 + +* Thu Jan 30 2014 Jes Sorensen - 3.3-5 +- Do not create /var/run/mdadm in the rpm file, since this is sitting on + tmpfs and is created by tmpfiles during boot. +- Resolves bz1053176 + +* Thu Oct 10 2013 Jes Sorensen - 3.3-4 +- Fix byteswap macros return types to allow for building on big endian + architectures again. +- Resolves bz1015494 + +* Wed Oct 9 2013 Jes Sorensen - 3.3-3 +- Check for DM_UDEV_DISABLE_OTHER_RULES_FLAG instead of + DM_UDEV_DISABLE_DISK_RULES_FLAG in 65-md-incremental.rules +- Resolves bz1015521 + +* Tue Oct 8 2013 Jes Sorensen - 3.3-2 +- Fix dracut requirement, minimum version 034-1 + +* Thu Sep 5 2013 Jes Sorensen - 3.3-1 +- Update to mdadm-3.3 +- Resolves bz977826 + +* Tue Aug 13 2013 Jes Sorensen - 3.2.6-21 +- Fix pointless rpmbuild noise over mismatching date info +- Remove Fedora 17 support +- Fix problem where first stop command doesn't stop container during + IMSM volume's reshape bz956053 (f18), bz956056 (f19) + +* Sat Aug 03 2013 Fedora Release Engineering - 3.2.6-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* 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 +- Resolves bz956021 (f18), bz956026 (f17), bz956031 (f19) + +* Tue Apr 23 2013 Jes Sorensen - 3.2.6-18 +- Fix problem with IMSM metadata where resync progress would be lost + if an array was stopped during ongoing expansion of a RAID1/5 volume. +- Resolves bz948745 + +* Tue Apr 23 2013 Jes Sorensen - 3.2.6-17 +- Reorder patches to allow for udev query patch to be applied on + Fedora 17 as well. + +* Mon Apr 22 2013 Jes Sorensen - 3.2.6-16 +- Rely on rpm macros to place files in correct directories, and match /usr + move +- Resolves bz955248 + +* Thu Mar 7 2013 Jes Sorensen - 3.2.6-15 +- Cleanup .spec file handling of different Fedora versions +- Resolves bz914629 + +* Tue Feb 5 2013 Jes Sorensen - 3.2.6-14 +- Resync with final version of upstream patches for launching mdmon + via systemctl. Require dracut 024-025 or later to match. +- Resolves bz879327 + +* Fri Feb 1 2013 Jes Sorensen - 3.2.6-13 +- Update to upstream solution for launching mdmon via systemctl +- Resolves bz879327 + +* Mon Jan 21 2013 Jes Sorensen - 3.2.6-12 +- Launch mdmon via systemctl to avoid it ending up in the wrong cgroup + and getting killed in the boot process when switching from the + initrd to the real root. +- Resolves bz879327 + +* Tue Jan 8 2013 Jes Sorensen - 3.2.6-11 +- Move code to leave udev cgroup into mdmon and excute it after we + work, to make sure it actually does the right thing. + +* Mon Jan 7 2013 Jes Sorensen - 3.2.6-10 +- Fix mdmonitor-takeover.service dangling symlink problem for real + +* Mon Jan 7 2013 Jes Sorensen - 3.2.6-9 +- Reintroduce fix for removing dangling symlink of + mdmonitor-takeover.service which got lost in the fix introduced in + 3.2.6-8 + +* Fri Jan 4 2013 Jes Sorensen - 3.2.6-8 +- mdmonitor-takeover.service is obsolete with the --offroot support, + and it is harmful as of 3.2.6 +- Resolves bz834245 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-7 +- Fix issue with udev scripts where if an raid volume with one of + the disks failing, the failed disk is still present in the volume + and container. The raid volume stays is in normal state (should be + degraded) and the rebuild cannot start. +- Resolves bz886123 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-5 +- mdadm-sysvinit is obsolete given that we no longer support booting + using sysvinit scripts +- Resolves bz884993 + +* Mon Dec 10 2012 Jes Sorensen - 3.2.6-4 +- Fix typo in error message in fix for 880972. No functional changes + +* Fri Nov 30 2012 Jes Sorensen - 3.2.6-3 +- Disallow creating a second IMSM RAID array size 0 (bz880972) +- Disallow creating IMSM RAIDs that spans multiple controllers (bz880974) +- Resolves bz880972, bz880974 + +* Thu Nov 15 2012 Doug Ledford - 3.2.6-2 +- Modify mdadm to set the cgroup of mdmon to systemd if it's available +- Related bz873576 (and others) + +* Thu Oct 25 2012 Jes Sorensen - 3.2.6-1 +- Upgrade to mdadm-3.2.6 +- Resolves bz869930 + +* Fri Oct 19 2012 Jes Sorensen - 3.2.5-14 +- Dummy update to work around bodhi breakage. No actual code changes. + +* Fri Oct 19 2012 Jes Sorensen - 3.2.5-13 +- Relax installation requirements for abrt script to only depend on + libreport-filesystem rather than the full abrt package + +* Thu Oct 18 2012 Jes Sorensen - 3.2.5-12 +- Add abrt script to retrieve /proc/mdstat output in case of crash +- Resolves bz867842 + +* Wed Oct 17 2012 Jes Sorensen - 3.2.5-11 +- Remove package requirements for udev and initscripts for F18+ +- Resolves bz864562 + +* Wed Oct 3 2012 Jes Sorensen - 3.2.5-9 +- Resolve issue with ambiguous licenses +- Resolves bz862761 + +* Mon Sep 10 2012 Jes Sorensen - 3.2.5-8 +- Switch to using new systemd macros for F18+ +- Resolves bz850202 + +* Thu Aug 2 2012 Jes Sorensen - 3.2.5-7 +- Remove bogus rogue patch applied in 3.2.5-5 with justification and + without following the structure of the mdadm package. + +* Fri Jul 27 2012 Fedora Release Engineering - 3.2.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 18 2012 Karsten Hopp 3.2.5-5 +- include in some to avoid type clashes. + 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 + Fedora tmpfile rules +- Resolves bz840187 + +* Mon Jun 25 2012 Jes Sorensen - 3.2.5-3 +- Fix problem where reshape of RAID volume is broken after trying to + stop all MD devices. +- Enhance raid-check to allow the adming to specify the max number of + concurrent arrays to be checked at any given time. +- Resolves bz830177, bz820124 + +* Wed Jun 13 2012 Jes Sorensen - 3.2.5-2 +- Fix uninstall script to remove dangling symlink to + mdmonitor-takeover.service, if the mdadm package is uninstalled from + the system. +- Resolves bz828354 + +* Mon May 21 2012 Jes Sorensen - 3.2.5-1 +- Upgrade to mdadm-3.2.5 +- Resolves bz822850 + +* Tue May 15 2012 Jes Sorensen - 3.2.4-3 +- Fix mdadm-3.2.4 introduced bug where --add fails in common cases +- Resolves bz821717 (f17) bz821718 (f16) bz821719 (f15) + +* Thu May 10 2012 Jes Sorensen - 3.2.4-2 +- Fix mdadm.conf to use 'd' for /var/run/mdadm creation, to avoid the + map file getting deleted during boot. + +* Thu May 10 2012 Jes Sorensen - 3.2.4-1 +- Upgrade to mdadm-3.2.4 +- Resolves bz820534 (rawhide) bz820527 (f17) bz820531 (f16) bz820532 (f15) + +* Mon Apr 30 2012 Jes Sorensen - 3.2.3-9 +- Fix Monitor mode sometimes crashes when a resync completes +- Fix missing symlink for mdadm container device when incremental creates + the array +- Make sure when creating a second array in a container that the second + array uses all available space since leaving space for a third array + is invalid +- Validate the number of imsm volumes per controller +- Fix issues with imsm arrays and disks larger than 2TB +- Add support for expanding imsm arrays/containers +- The support for expanding imsm arrays/containers was accepted upstream, + update to the official patches from there +- Fix for the issue of --add not being very smart +- Fix an issue causing rebuilds to fail to restart on reboot (data + corrupter level problem) +- Reset the bad flag on map file updates +- Correctly fix failure when trying to add internal bitmap to 1.0 arrays +- Resolves: bz817023 (f17) bz817024 (f17) bz817026 (f17) bz817028 (f17) +- Resolves: bz817029 (f17) bz817032 (f17) bz817038 (f17) bz808774 (f17) +- Resolves: bz817039 (f17) bz817042 (f17) + +* Mon Apr 30 2012 Jes Sorensen - 3.2.3-8 +- Fix bug where IMSM arrays stay inactive in case a reboot is +- performed during the reshape process. +- Resolves: bz817522 (f17) bz817535 (f16) bz817537 (f15) + +* Wed Mar 28 2012 Jes Sorensen - 3.2.3-7 +- Fix issue when re-adding drive to a raid1 array with bitmap +- Resolves: bz807743 (f17) bz769323 (f16) bz791159 (f15) + +* Thu Feb 23 2012 Jes Sorensen - 3.2.3-6 +- Fix double free on buggy old kernel sysfs read +- Fix segfault if trying to write superblock to non existing device +- Resolves: bz795707 (f17) bz795747 (f16) bz795748 (f15) +- Resolves: bz795461 (f17) bz795749 (f16) bz795750 (f15) + +* 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 +- Resolves: bz789898 (f16) bz791189 (f15) + +* Mon Jan 30 2012 Jes Sorensen - 3.2.3-4 +- Add support for --offroot to mdadm/mdmon +- Resolves: bz785739 (rawhide) bz785737 (f16) bz771405 (f15) + +* Thu Jan 12 2012 Jes Sorensen - 3.2.3-3 +- Fix case where we have to retry in case a remove fails due to an array + being busy +- Resolves: bz773337 (rawhide) bz773340 (f16) bz773341 (f15) + +* Thu Jan 5 2012 Jes Sorensen - 3.2.3-2 +- Workaround for gcc-4.7 strict aliasing breaking the build + +* Wed Jan 4 2012 Jes Sorensen - 3.2.3-1 +- Update to upstream 3.2.3 +- Resolves: bz770110 (rawhide) bz771413 (f16) bz759014 (rawhide) +- Resolves: bz759015 (f16) bz759035 (rawhide) bz759036 (f16) +- Resolves: bz771608 (f15) bz759016 (f15) bz759039 (f15) + +* Mon Nov 21 2011 Jes Sorensen - 3.2.2-15 +- Backport upstream fix for memory leak that can prevent migration to + RAID5 from completing. +- Backport upstream fix preventing mounting a device while it is in + process of reshaping +- Resolves: bz755005 bz755009 + +* Wed Nov 9 2011 Jes Sorensen - 3.2.2-14 +- Backport upstream fixes to prevent growing v0.90 metadata raid out + of supported size. +- Add missing 'disable' argument to systemctl in preun script +- Resolves: bz735306 (Fedora 15) bz748731 (Fedora 16) bz748732 (rawhide), + Resolves: bz751716 + +* Wed Oct 26 2011 Fedora Release Engineering - 3.2.2-13 +- Rebuilt for glibc bug#747377 + +* Sat Oct 22 2011 Jes Sorensen - 3.2.2-12 +- Backport upstream version of fix for IMSM RAID assembly problem, + which resolves issues when booting off sysvinit based system. +- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16) + +* Wed Oct 19 2011 Jes Sorensen - 3.2.2-11 +- Fix systemd dependency problem +- Resolves: bz741115 (F16) bz744226 (rawhide) + +* Wed Oct 19 2011 Jes Sorensen - 3.2.2-10 +- Fix problem where a dirty IMSM RAID isn't assembled correctly during + boot, preventing booting from this RAID device. +- Resolves: bz736387 (Fedora 15) bz744217 (Fedora 16) +- Fix race between udev and mdadm when assembling md device using + mdadm -I, where udev would spawn an additional mdadm command to + perform the assembly in parallel. + +* Wed Aug 31 2011 Doug Ledford - 3.2.2-9 +- Fix boot with older imsm arrays that have an unused attribute set +- Resolves: bz729205 + +* Thu Aug 25 2011 Doug Ledford - 3.2.2-8 +- Rework the 65-md-incremental.rules file to add the following support: + Nested md raid arrays should now work + MD on top of LUKS or other lvm based devices should now work + We should no longer grab multipath paths before multipath can + +* Wed Jul 27 2011 Doug Ledford - 3.2.2-7 +- Fix a bug with readding a device +- Fix a bug with writemostly flag handling + +* Mon Jul 18 2011 Doug Ledford - 3.2.2-6 +- Bump and rebuild again + +* Fri Jul 15 2011 Doug Ledford - 3.2.2-5 +- Bump and rebuild to keep version ahead of f15 version + +* Thu Jul 14 2011 Doug Ledford - 3.2.2-4 +- Fix minor issue in man page +- Resolves: bz717795 + +* Thu Jul 07 2011 Milan Broz - 3.2.2-3 +- Use unit files with systemd. (johannbg) +- Add sub-package sysvinit for SysV init script. +- Resolves: bz713573 + +* Wed Jul 06 2011 Milan Broz - 3.2.2-2 +- Fix build on PPC. +- Resolves: bz719380 + +* Tue Jun 28 2011 Milan Broz - 3.2.2-1 +- Update to latest upstream version +- Resolves: bz714083 + +* Tue Jun 14 2011 Doug Ledford - 3.2.1-5 +- Fix for bz710646 + +* Thu Mar 31 2011 Doug Ledford - 3.2.1-4 +- Somehow the 64-md-raid.rules file went missing. Put it back. +- Resolves: bz692248 + +* Thu Mar 31 2011 Doug Ledford - 3.2.1-3 +- Fix mdmonitor init script setup of SELinux on PIDPATH +- Resolves: bz692559 + +* Mon Mar 28 2011 Doug Ledford - 3.2.1-2 +- Restore build command to sane command instead of test command + +* Mon Mar 28 2011 Doug Ledford - 3.2.1-1 +- Update to latest upstream version +- Resolves: 691353 + +* Fri Mar 25 2011 Doug Ledford - 3.1.5-1 +- Update to latest upstream stable release +- Update mdadm.rules file to honor noiswmd and nodmraid command line options +- Ghost the directory in /var/run, create /var/run/mdadm in mdmonitor init + script +- Don't report mismatch counts on either raid1 or raid10 +- Check both active and idle arrays during raid check runs +- Move the raid-check script from cron.weekly to /usr/sbin, add a crontab + file to /etc/cron.d and mark it config(noreplace). This way users can + select their own raid-check frequency and have it honored through + upgrades. +- Allow the raid-check script to set the process and io priority of the + thread performing the check in order to preserve responsiveness of the + machine during the check. +- Resolves: 633229, 656620. 679843, 671076, 659933 + +* Tue Feb 08 2011 Fedora Release Engineering - 3.1.3-0.git20100804.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Aug 04 2010 Doug Ledford - 3.1.3-0.git20100804.2 +- Add udev patch to not have incremental assembly in two rules files + +* Wed Aug 04 2010 Doug Ledford - 3.1.3-0.git20100804.1 +- Update to latest upstream release (resolves an issue with stale lock + files on the md device map file) + +* Thu Jul 22 2010 Doug Ledford - 3.1.3-0.git20100722.2 +- Remove the glibc-static buildreq and don't build the static mdadm since + we don't install it anyway +- Remove the udev file since adding it was supposed to be a rawhide only change + +* Thu Jul 22 2010 Doug Ledford - 3.1.3-0.git20100722.1 +- Change git date format to the correct format (YYYYMMDD) +- Update to latest upstream push (fixes bz604023) + +* Tue Jul 20 2010 Doug Ledford - 3.1.3-0.git07202010.2 +- Fix racy locking of mapfile (bz616596) + +* Tue Jul 20 2010 Doug Ledford - 3.1.3-0.git07202010.1 +- Update to latest git repo (3.1.2 plus pending changes, fixes bz602457) +- Add in 64-md-raid.rules to compensate for it no longer being in udev + (bz581905) +- Remove mdadm.static as its no longer used in initrd creation + +* Tue Apr 13 2010 Doug Ledford - 3.1.2-10 +- Minor update to mdadm.rules to make anaconda happy + +* Thu Apr 08 2010 Doug Ledford - 3.1.2-9 +- Slight fix on container patch + +* Thu Apr 08 2010 Doug Ledford - 3.1.2-8 +- Updated container patch that also enables mdadm -IRs for imsm devices + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-7 +- Fix up directory in mdmonitor init script so that we restart mdmon like we + are supposed to +- Add a rule to run incremental assembly on containers in case there are + multiple volumes in a container and we only started some of them in the + initramfs +- Make -If work with imsm arrays. We had too restrictive of a test in + sysfs_unique_holder. +- Make incremental assembly of containers act like incremental assembly of + regular devices (aka, --run is needed to start a degraded array) + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-6 +- Typo in new rules file + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-5 +- Enable incremental support for imsm devices + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-4 +- One line fix for ppc64 compiles + +* Tue Apr 06 2010 Doug Ledford - 3.1.2-3 +- Clean up directory mess once and for all +- Add incremental remove support + +* Wed Mar 17 2010 Doug Ledford - 3.1.2-2 +- Add a little more paranoia checking to the RebuildMap code to avoid ever + having the same infinite loop as in bz569019 again even if we change file + locations to somewhere where we can't create a mapfile + +* Tue Mar 16 2010 Doug Ledford - 3.1.2-1 +- Grab latest upstream release instead of git repo snapshot (bz552344, bz572561) +- The lack of /dev/md is causing problems, so add code to mapfile.c to cause + us to create /dev/md if it doesn't exist (bz569019) + +* Tue Feb 23 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.6 +- Newer version of imsm patch that leaves warning, but only when there + actually are too many devices on the command line (bz554974) + +* Sun Feb 21 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.5 +- The uuid patch cause a different problem during assembly, so use a gross + hack to work around the uuid issue that won't break assembly until fixed + properly upstream (bz567132) + +* Sun Feb 21 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.4 +- Fix problem with booting multiple imsm containers when they aren't listed + "just so" in the mdadm.conf file (bz554974) + +* Fri Feb 19 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.3 +- Don't run the raid-check script if the kernel doesn't support + md devices (bz557053) +- Don't report any mismatch_cnt issues on raid1 devices as there are + legitimate reasons why the count may not be 0 and we are getting enough + false positives that it renders the check useless (bz554217, bz547128) + +* Thu Feb 18 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.2 +- Fix s390/ppc64 UUID byte swap issue + +* Wed Feb 17 2010 Doug Ledford - 3.1.1-0.gcd9a8b5.1 +- Update to head of upstream git repo, which contains a significant number + of bug fixes we need (bz543746) + +* Fri Jan 15 2010 Doug Ledford - 3.0.3-3 +- Fix crash when AUTO keyword is in mdadm.conf (bz552342) + +* Tue Dec 01 2009 Doug Ledford - 3.0.3-2 +- Minor tweak to init script for LSB compliance (bz527957) + +* Wed Nov 04 2009 Doug Ledford - 3.0.3-1 +- New upstream release 3.0.3 (bz523320, bz527281) +- Update a couple internal patches +- Drop a patch in that was in Neil's tree for 3.0.3 that we had pulled for + immediate use to resolve a bug +- Drop the endian patch because it no longer applied cleanly and all attempts + to reproduce the original problem as reported in bz510605 failed, even up + to and including downloading the specific package that was reported as + failing in that bug and trying to reproduce with it on both ppc and ppc64 + hardware and with both ppc and ppc64 versions on the 64bit hardware. + Without a reproducer, it is impossible to determine if a rehashed patch + to apply to this code would actually solve the problem, so remove the patch + entirely since the original problem, as reported, was an easy to detect DOA + issue where installing to a raid array was bound to fail on reboot and so + we should be able to quickly and definitively tell if the problem resurfaces. +- Update the mdmonitor init script for LSB compliance (bz527957) +- Link from mdadm.static man page to mdadm man page (bz529314) +- Fix a problem in the raid-check script (bz523000) +- Fix the intel superblock handler so we can test on non-scsi block devices + +* Fri Oct 2 2009 Hans de Goede - 3.0.2-1 +- New upstream release 3.0.2 +- Add a patch fixing mdadm --detail -export segfaults (bz526761, bz523862) +- Add a patch making mdmon store its state under /dev/.mdadm for initrd + mdmon, rootfs mdmon handover +- Restart mdmon from initscript (when running) for rootfs mdmon handover + +* Thu Sep 17 2009 Doug Ledford - 3.0-4 +- Stop some mdmon segfaults (bz523860) + +* Tue Sep 15 2009 Doug Ledford - 3.0-3 +- Update to current head of upstream git repo for various imsm related fixes + (fixes bz523262) +- Fix display of metadata version in output of Detail mode +- Add UUID output to --detail --export (bz523314) + +* Fri Jul 24 2009 Doug Ledford - 3.0-2 +- Improved raid-check script as well as the ability to configure what devices + get checked +- Endian patch for uuid generation + +* Mon Jun 29 2009 Doug Ledford - 3.0-1 +- Remove stale patches already accepted by upstream +- Fix the raid-check script to only try and check a device if it is + checkable +- Update to official mdadm-3.0 version +- Resolves: bz505587, bz505552 + +* Tue May 19 2009 Doug Ledford - 3.0-0.devel3.7 +- Move the mdadm.map file from /dev/md/ to /dev/ so the installer doesn't + need to precreate the /dev/md/ directory in order for incremental + assembly to work + +* Tue May 19 2009 Doug Ledford - 3.0-0.devel3.6 +- Only check raid devices automatically, do not attempt to repair them + during the weekly data scrubbing + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.5 +- Fix a few issues with the new code to determine when a device gets to + keep its name and when it doesn't + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.4 +- Change the perms on the udev rules file, it doesn't need to be +x + +* Fri Mar 20 2009 Doug Ledford - 3.0-0.devel3.3 +- Slightly tweak the udev rules to make sure we don't start arrays + while running in rc.sysinit...leave array starting to it instead +- 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 + preferred name or a random name to avoid possible conflicts when plugging + a foreign array into a host + +* Wed Mar 18 2009 Doug Ledford - 3.0-0.devel3.2 +- Change around the mdadm udev rules we ship to avoid a udev file conflict + +* Tue Mar 17 2009 Doug Ledford - 3.0-0.devel3.1 +- Update to latest devel release +- Remove the no longer necessary udev patch +- Remove the no longer necessary warn patch +- Remove the no longer necessary alias patch +- Update the mdadm.rules file to only pay attention to device adds, not + changes and to enable incremental assembly +- Add a cron job to run a weekly repair of the array to correct bad sectors +- Resolves: bz474436, bz490972 + +* Wed Feb 25 2009 Fedora Release Engineering - 3.0-0.devel2.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Doug Ledford - 3.0-0.devel2.2 +- Readd our old mdadm rules file that does incremental assembly +- Remove the new mdadm rules file from upstream as we already have this in + our udev package (and the one in the udev package already has a bug fixed) + +* Thu Feb 12 2009 Doug Ledford - 3.0-0.devel2.1 +- Update to latest upstream devel release +- Use the udev rules file included with mdadm instead of our own +- Drop all the no longer relevant patches +- Fix a build error in mdopen.c +- Fix the udev rules path in Makefile +- Fix a compile issue with the __le32_to_cpu() macro usage (bad juju to + to operations on the target of the macro as it could get executed + multiple times, and gcc now throws an error on that) +- Add some casts to some print statements to keep gcc from complaining + +* Fri Oct 24 2008 Doug Ledford - 2.6.7.1-1 +- Updated to latest upstream stable release (#466803) +- Change udev rule to not assemble degraded arrays (#453314) +- Fix metadata matching in config file (#466078) +- Fix assembly of raid10 devices (#444237) +- Fix incremental assembly of partitioned raid devices (#447818) + +* Thu Jun 26 2008 Doug Ledford - 2.6.7-1 +- Update to latest upstream version (should resolve #444237) +- Drop incremental patch as it's now part of upstream +- Clean up all the open() calls in the code (#437145) +- Fix the build process to actually generate mdassemble (#446988) +- Update the udev rules to get additional info about arrays being assembled + from the /etc/mdadm.conf file (--scan option) (#447818) +- Update the udev rules to run degraded arrays (--run option) (#452459) + +* 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) + +* Fri Jan 18 2008 Doug Ledford - 2.6.4-2 +- Bump version and rebuild + +* Fri Oct 19 2007 Doug Ledford - 2.6.4-1 +- Update to latest upstream and remove patches upstream has taken + +* Tue Aug 28 2007 Fedora Release Engineering - 2.6.2-5 +- Rebuild for selinux ppc32 issue. + +* Mon Jul 09 2007 Doug Ledford - 2.6.2-4 +- Oops, if we call -C -e1, minor_version is no longer properly set, fix that + up +- Related: bz230207 + +* Fri Jul 06 2007 Doug Ledford - 2.6.2-3 +- Oops, had to update the file leak patch, missed one thing +- Minor tweak to return codes in init script and add LSB header +- Resolves: bz244582, bz246980 + +* Mon Jul 02 2007 Doug Ledford - 2.6.2-2 +- Fix a file leak issue when mdadm is in monitor mode +- Update mdadm init script so that status will always run and so + return codes are standards compliant +- Fix assembly of version 1 superblock devices +- Make the attempt to create an already running device have a clearer + error message +- Allow the creation of a degraded raid4 array like we allow for raid5 +- Make mdadm actually pay attention to raid4 devices when in monitor mode +- Make the mdmonitor script use daemon() correctly +- Fix a bug where manage mode would not add disks correctly under certain + conditions +- Resolves: bz244582, bz242688, bz230207, bz169516, bz171862, bz171938 +- Resolves: bz174642, bz224272, bz186524 + +* Mon Jul 02 2007 Doug Ledford - 2.6.2-1 +- Update to latest upstream +- Remove requirement for /usr/sbin/sendmail - it's optional and not on by + default, and sendmail isn't *required* for mdadm itself to work, and isn't + even required for the monitoring capability to work, just if you want to + have the monitoring capability do the automatic email thing instead of + run your own program (and if you use the program option of the monitor + capability, your program could email you in a different manner entirely) + +* Mon Apr 16 2007 Doug Ledford - 2.6.1-4 +- More cleanups for merge review process +- Related: bz226134 + +* Wed Apr 11 2007 Doug Ledford - 2.6.1-3 +- Various cleanups as part of merge review process +- Related: bz226134 + +* Sat Mar 31 2007 Doug Ledford - 2.6.1-2 +- Oops, missing a dependency in the Makefile + +* Sat Mar 31 2007 Doug Ledford - 2.6.1-1 +- Update to latest upstream version +- Resolves: bz233422 + +* Fri Jan 26 2007 Doug Ledford - 2.6-1 +- Update to latest upstream version +- Remove the mdmpd daemon entirely. Now that multipath tools from the lvm/dm + packages handles multipath devices well, this is no longer needed. +- Various cleanups in the spec file + +* Thu Nov 09 2006 Doug Ledford - 2.5.4-3 +- Add a fix for the broken printout of array GUID when using the -E --brief + flags + +* Fri Oct 13 2006 Doug Ledford - 2.5.4-2 +- tag present on another branch and can't be forcibly moved + required number bump + +* Fri Oct 13 2006 Doug Ledford - 2.5.4-1 +- Update to 2.5.4 (listed as a bugfix update by upstream) +- Remove previous bitmap patch that's now part of 2.5.4 + +* Sun Oct 8 2006 Doug Ledford - 2.5.3-2 +- Fix a big-endian machine error in the bitmap code (Paul Clements) + +* Mon Aug 7 2006 Doug Ledford - 2.5.3-1 +- Update to 2.5.3 which upstream calls a "bug fix" release + +* Wed Jul 12 2006 Jesse Keating - 2.5.2-1.1 +- rebuild + +* Fri Jul 7 2006 Doug Ledford - 2.5.2-1 +- Update to 2.5.2 +- Remove auto default patch as upstream now has a preferred default auto method + +* Wed Mar 8 2006 Peter Jones - 2.3.1-3 +- fix build on ppc64 + +* Wed Mar 8 2006 Jeremy Katz - 2.3.1-2 +- fix build on ppc + +* Wed Mar 8 2006 Jeremy Katz - 2.3.1-1 +- update to 2.3.1 to fix raid5 (#184284) + +* Fri Feb 10 2006 Jesse Keating - 2.2-1.fc5.2.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2.2-1.fc5.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Mon Dec 05 2005 Warren Togami 2.2-1 +- 2.2 upgrade (#167897) +- disable diet because we don't ship it anymore + and we don't actually use mdassemble now + +* Mon May 16 2005 Doug Ledford 1.11.0-4.fc4 +- Make the mdmonitor init script use the pid-file option, major cleanup + of the script now possible (#134459) + +* Mon May 16 2005 Doug Ledford 1.11.0-3.fc4 +- Put back the obsoletes: raidtools that was present in 1.11.0-1.fc4 + +* Mon May 16 2005 Doug Ledford 1.11.0-2.fc4 +- Change the default auto= mode so it need not be on the command line to + work with udev, however it is still supported on the command line (#132706) +- Add a man page (from Luca Berra) for mdassemble + +* Wed May 11 2005 Doug Ledford - 1.11.0-1.fc4 +- Upgrade to 1.11.0 + +* Wed Apr 27 2005 Jeremy Katz - 1.9.0-3.fc4 +- fix mdmonitor initscript (#144717) + +* Mon Mar 21 2005 Doug Ledford 1.9.0-2 +- Build mdadm.static and mdassemble (static as well) to be used in initrd + images + +* Wed Mar 09 2005 Doug Ledford 1.9.0-1 +- Initial upgrade to 1.9.0 and update of doc files +- Fix an s390 build error + +* Mon Oct 04 2004 Doug Ledford 1.6.0-2 +- Remove /etc/mdadm.conf from the file list. Anaconda will write one out + if it's needed. + +* Fri Oct 01 2004 Doug Ledford 1.6.0-1 +- Update to newer upstream version +- Make mdmpd work on kernels that don't have the event interface patch + +* Fri Jul 30 2004 Dan Walsh 1.5.0-11 +- Create a directory /var/run/mdadm to contain mdadm.pid +- This cleans up SELinux problem + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Sat May 22 2004 Doug Ledford - 1.5.0-9 +- Fix Makefile and build method to satisfy bz #123769 +- Add mdmpd man page, update mdmpd version to 0.3 - bz #117160 +- Make sure mdadm --monitor closes all md device files so that md devices + can be stopped while mdadm is still running - bz #119532 + +* Thu May 20 2004 Jeremy Katz - 1.5.0-8 +- remove unneeded patch, can use --run instead + +* Wed May 19 2004 Jeremy Katz - 1.5.0-7 +- add patch with reallyforce mode on creation to be used by anaconda + +* Wed May 12 2004 Doug Ledford 2.5.0-6 +- Fix a bug in the postun scriptlet related to downgrading to a version + of mdadm that doesn't include the mdmpd daemon. + +* Fri May 07 2004 Doug Ledford 1.5.0-5 +- Disable service mdmpd by default to avoid [Failed] messages on + current 2.6 kernels. Possibly re-enable it by default once the + 2.6 kernels have the md event interface. + +* Thu Apr 22 2004 Doug Ledford 1.5.0-4 +- Update mdmonitor script to start daemon more cleanly +- Repackage mdmpd tarball to include gcc-3.4 changes and to make + mdmpd properly daemonize at startup instead of forking and leaving + the child attached to the terminal. + +* Thu Mar 4 2004 Bill Nottingham 1.5.0-3 +- ship /var/run/mpmpd (#117497) + +* Thu Feb 26 2004 Doug Ledford 1.5.0-2 +- Add a default MAILADDR line to the mdadm.conf file installed by default + (Bugzilla #92447) +- Make it build with gcc-3.4 + +* Mon Feb 23 2004 Doug Ledford 1.5.0-1 +- Update to 1.5.0 (from Matthew J. Galgoci ) + +* Sun Nov 16 2003 Doug Ledford 1.4.0-1 +- fix problem with recovery thread sleeping in mdmpd + +* Fri Nov 14 2003 Doug Ledford +- sync upstream +- add mdmpd package into mdadm package + +* Wed Sep 10 2003 Michael K. Johnson 1.3.0-1 +- sync upstream + +* Tue Mar 11 2003 Michael K. Johnson 1.1.0-1 +- sync upstream + +* Tue Jan 28 2003 Michael K. Johnson 1.0.1-1 +- update for rebuild + +* Wed Dec 25 2002 Tim Powers 1.0.0-8 +- fix references to %%install in the changelog so that it will build + +* Fri Dec 13 2002 Elliot Lee 1.0.0-7 +- Rebuild + +* Fri Jul 12 2002 Michael K. Johnson +- Changed RPM Group to System Environment/Base + +* Wed May 15 2002 Michael K. Johnson +- minor cleanups to the text, conditionalize rm -rf +- added mdmonitor init script + +* Fri May 10 2002 +- update to 1.0.0 +- Set CXFLAGS instead of CFLAGS + +* Sat Apr 6 2002 +- change %%install to use "make install" + +* Fri Mar 15 2002 +- beautification +- made mdadm.conf non-replaceable config +- renamed Copyright to License in the header +- added missing license file +- used macros for file paths + +* Fri Mar 15 2002 Luca Berra +- Added Obsoletes: mdctl +- missingok for configfile + +* Tue Mar 12 2002 NeilBrown +- Add md.4 and mdadm.conf.5 man pages + +* Fri Mar 08 2002 Chris Siebenmann +- builds properly as non-root. + +* Fri Mar 08 2002 Derek Vadala +- updated for 0.7, fixed /usr/share/doc and added manpage + +* Tue Aug 07 2001 Danilo Godec +- initial RPM build