basebuilder_pel7x64builder0
4 years ago
51 changed files with 4334 additions and 401 deletions
@ -0,0 +1,39 @@ |
|||||||
|
From 0833f9c3dbaaee202b92ea956f9e2decc7b9593a Mon Sep 17 00:00:00 2001 |
||||||
|
From: Gioh Kim <gi-oh.kim@profitbricks.com> |
||||||
|
Date: Tue, 6 Nov 2018 15:27:42 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 01/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Gioh Kim <gi-oh.kim@profitbricks.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC); |
||||||
|
|
||||||
|
+ desired_state |= devices[j].i.disk.state & ((1<<MD_DISK_FAILFAST) | |
||||||
|
+ (1<<MD_DISK_WRITEMOSTLY)); |
||||||
|
+ |
||||||
|
if (!devices[j].uptodate) |
||||||
|
continue; |
||||||
|
|
||||||
|
-- |
||||||
|
2.7.5 |
||||||
|
|
@ -0,0 +1,77 @@ |
|||||||
|
From 6b6112842030309c297a521918d1a2e982426fa3 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Fri, 9 Nov 2018 17:12:33 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 02/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,334 @@ |
|||||||
|
From cd72f9d114da206baa01fd56ff2d8ffcc08f3239 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Fri, 9 Nov 2018 17:12:33 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 03/21] 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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,137 @@ |
|||||||
|
From 4199d3c629c14866505923d19fa50017ee92d2e1 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Wed, 5 Dec 2018 16:35:00 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 04/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,83 @@ |
|||||||
|
From 7cd7e91ab3de5aa75dc963cb08b0618c1885cf0d Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Wed, 5 Dec 2018 16:35:00 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 05/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,83 @@ |
|||||||
|
From d7a1fda2769ba272d89de6caeab35d52b73a9c3c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
Date: Wed, 17 Oct 2018 12:11:41 +0200 |
||||||
|
Subject: [RHEL7.7 PATCH 06/21] 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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
From 563ac108659980b3d1e226fe416254a86656235f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Gioh Kim <gi-oh.kim@cloud.ionos.com> |
||||||
|
Date: Tue, 6 Nov 2018 16:20:17 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 07/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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<<MD_DISK_FAILFAST) | |
||||||
|
+ (1<<MD_DISK_WRITEMOSTLY)); |
||||||
|
+ if (disk_state == ((1<<MD_DISK_ACTIVE) | (1<<MD_DISK_SYNC))) { |
||||||
|
if (most_recent < 0 || |
||||||
|
devices[devcnt].i.events |
||||||
|
> devices[most_recent].i.events) { |
||||||
|
-- |
||||||
|
2.7.5 |
||||||
|
|
@ -0,0 +1,34 @@ |
|||||||
|
From 085df42259cba7863cd6ebe5cd0d8492ac5b869e Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Thu, 6 Dec 2018 10:35:41 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 08/21] 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 <edo.rus@gmail.com> |
||||||
|
Signed-off-by: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,30 @@ |
|||||||
|
From 76d505dec6c9f92564553596fc8350324be82463 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.com> |
||||||
|
Date: Thu, 6 Dec 2018 10:36:28 +1100 |
||||||
|
Subject: [RHEL7.7 PATCH 09/21] 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 <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,31 @@ |
|||||||
|
From 467e6a1b4ece8e552ee638dab7f44a4d235ece1a Mon Sep 17 00:00:00 2001 |
||||||
|
From: Gioh Kim <gi-oh.kim@cloud.ionos.com> |
||||||
|
Date: Fri, 7 Dec 2018 12:04:44 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 10/21] policy.c: prevent NULL pointer referencing |
||||||
|
|
||||||
|
paths could be NULL and paths[0] should be followed by NULL pointer |
||||||
|
checking. |
||||||
|
|
||||||
|
Reviewed-by: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,36 @@ |
|||||||
|
From 757e55435997e355ee9b03e5d913b5496a3c39a8 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
Date: Tue, 11 Dec 2018 15:04:07 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 11/21] 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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,95 @@ |
|||||||
|
From a4e96fd8f3f0b5416783237c1cb6ee87e7eff23d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
Date: Fri, 8 Feb 2019 11:07:10 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 12/21] 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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,322 @@ |
|||||||
|
From 9f4218274cd4a1e1f356a1617f9a1d09960cf255 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Pawel Baldysiak <pawel.baldysiak@intel.com> |
||||||
|
Date: Mon, 28 Jan 2019 17:10:41 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 13/21] 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 <pawel.baldysiak@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,101 @@ |
|||||||
|
From ebf3be9931f31df54df52b1821479e6a80a4d9c6 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Dimitri John Ledkov <xnox@ubuntu.com> |
||||||
|
Date: Tue, 15 Jan 2019 19:08:37 +0000 |
||||||
|
Subject: [RHEL7.7 PATCH 14/21] Fix spelling typos. |
||||||
|
|
||||||
|
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,46 @@ |
|||||||
|
From e3615ecb5b6ad8eb408296878aad5628e0e27166 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Coly Li <colyli@suse.de> |
||||||
|
Date: Tue, 12 Feb 2019 12:53:18 +0800 |
||||||
|
Subject: [RHEL7.7 PATCH 15/21] 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 <md device> --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 <aschnell@suse.com> |
||||||
|
Fixes: b9c9bd9bacaa ("Detail: ensure --export names are acceptable as 4 shell variables") |
||||||
|
Signed-off-by: Coly Li <colyli@suse.de> |
||||||
|
Cc: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,70 @@ |
|||||||
|
From cab114c5ca870e5f1b57fb2602cd9a038271c2e0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Corey Hickey <bugfood-c@fatooh.org> |
||||||
|
Date: Mon, 11 Feb 2019 17:18:38 -0800 |
||||||
|
Subject: [RHEL7.7 PATCH 16/21] 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 <bugfood-c@fatooh.org> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,100 @@ |
|||||||
|
From 76b906d2406cdf136f64de77e881eb2d180108d9 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Gioh Kim <gi-oh.kim@cloud.ionos.com> |
||||||
|
Date: Fri, 7 Dec 2018 14:30:09 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 17/21] 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 <gi-oh.kim@cloud.ionos.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,50 @@ |
|||||||
|
From 69d084784de196acec8ab703cd1b379af211d624 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
||||||
|
Date: Fri, 22 Feb 2019 10:15:45 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 18/21] 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 <artur.paszkiewicz@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,58 @@ |
|||||||
|
From d2e11da4b7fd0453e942f43e4196dc63b3dbd708 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Pawel Baldysiak <pawel.baldysiak@intel.com> |
||||||
|
Date: Fri, 22 Feb 2019 13:30:27 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 19/21] 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 <pawel.baldysiak@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,52 @@ |
|||||||
|
From 2b57e4fe041d52ae29866c93a878a11c07223cff Mon Sep 17 00:00:00 2001 |
||||||
|
From: Pawel Baldysiak <pawel.baldysiak@intel.com> |
||||||
|
Date: Fri, 22 Feb 2019 12:56:27 +0100 |
||||||
|
Subject: [RHEL7.7 PATCH 20/21] 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 <pawel.baldysiak@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,59 @@ |
|||||||
|
From 227aeaa872d4898273cf87a4253898823d556c43 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Corey Hickey <bugfood-c@fatooh.org> |
||||||
|
Date: Mon, 11 Feb 2019 17:42:27 -0800 |
||||||
|
Subject: [RHEL7.7 PATCH 21/21] 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 <bugfood-c@fatooh.org> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,117 @@ |
|||||||
|
From 05501181f18cdccdb0b3cec1d8cf59f0995504d7 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Pawel Baldysiak <pawel.baldysiak@intel.com> |
||||||
|
Date: Fri, 8 Mar 2019 12:19:11 +0100 |
||||||
|
Subject: [RHEL7.8 PATCH V2 22/47] 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 <pawel.baldysiak@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,94 @@ |
|||||||
|
From 22dc741f63e6403d59c2c14f56fd4791265f9bbb Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
Date: Mon, 1 Apr 2019 16:53:41 +0200 |
||||||
|
Subject: [RHEL7.8 PATCH V2 23/47] 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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 <ctype.h> |
||||||
|
|
||||||
|
+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 |
||||||
|
|
@ -0,0 +1,31 @@ |
|||||||
|
From 3c9b46cf9ae15a9be98fc47e2080bd9494496246 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Liwei Song <liwei.song@windriver.com> |
||||||
|
Date: Tue, 19 Mar 2019 23:51:05 -0400 |
||||||
|
Subject: [RHEL7.8 PATCH V2 24/47] 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 <liwei.song@windriver.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,109 @@ |
|||||||
|
From ae7d61e35ec2ab6361c3e509a8db00698ef3396f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
||||||
|
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 <artur.paszkiewicz@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,212 @@ |
|||||||
|
From 4ec389e3f0c1233f5aa2d5b4e63d96e33d2a37f0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Roman Sobanski <roman.sobanski@intel.com> |
||||||
|
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 <roman.sobanski@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,39 @@ |
|||||||
|
From a4f7290c20c2ff78328c9db0b18029165cfb05b2 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Jes Sorensen <jsorensen@fb.com> |
||||||
|
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 <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,57 @@ |
|||||||
|
From 7039d1f8200b9599b23db5953934fdb43b0442e0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Jes Sorensen <jsorensen@fb.com> |
||||||
|
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 <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,38 @@ |
|||||||
|
From 486720e0c2418e7e2e0a16221f7c42a308622254 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Jes Sorensen <jsorensen@fb.com> |
||||||
|
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 <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,345 @@ |
|||||||
|
From b06815989179e0f153e44e4336290e655edce9a1 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Dabrowski <mariusz.dabrowski@intel.com> |
||||||
|
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 <mariusz.dabrowski@intel.com> |
||||||
|
Signed-off-by: Krzysztof Smolinski <krzysztof.smolinski@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 <system> |
||||||
|
.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 <dirent.h> |
||||||
|
#include <ctype.h> |
||||||
|
+#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 |
||||||
|
|
@ -0,0 +1,34 @@ |
|||||||
|
From 452dc4d13a012cdcb05088c0dbc699959c4d6c73 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Baruch Siach <baruch@tkos.co.il> |
||||||
|
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 <hauke@hauke-m.de> |
||||||
|
Signed-off-by: Baruch Siach <baruch@tkos.co.il> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 <errno.h> |
||||||
|
#include <string.h> |
||||||
|
#include <syslog.h> |
||||||
|
-#ifdef __GLIBC__ |
||||||
|
/* Newer glibc requires sys/sysmacros.h directly for makedev() */ |
||||||
|
#include <sys/sysmacros.h> |
||||||
|
-#endif |
||||||
|
#ifdef __dietlibc__ |
||||||
|
#include <strings.h> |
||||||
|
/* dietlibc has deprecated random and srandom!! */ |
||||||
|
-- |
||||||
|
2.7.5 |
||||||
|
|
@ -0,0 +1,161 @@ |
|||||||
|
From d11abe4bd5cad39803726ddff1888674e417bda5 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Coly Li <colyli@suse.de> |
||||||
|
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 <colyli@suse.de> |
||||||
|
Reviewed-by: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,42 @@ |
|||||||
|
From 1a52f1fc0266d438c996789d4addbfac999a6139 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Coly Li <colyli@suse.de> |
||||||
|
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 <colyli@suse.de> |
||||||
|
Reviewed-by: NeilBrown <neilb@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,44 @@ |
|||||||
|
From 91c97c5432028875db5f8abeddb5cb5f31902001 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,46 @@ |
|||||||
|
From fd5b09c9a9107f0393ce194c4aac6e7b8f163e85 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Krzysztof Smolinski <krzysztof.smolinski@intel.com> |
||||||
|
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 <krzysztof.smolinski@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,163 @@ |
|||||||
|
From 43ebc9105e9dafe5145b3e801c05da4736bf6e02 Mon Sep 17 00:00:00 2001 |
||||||
|
From: "Guilherme G. Piccoli" <gpiccoli@canonical.com> |
||||||
|
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 <jes.sorensen@gmail.com> |
||||||
|
Cc: NeilBrown <neilb@suse.de> |
||||||
|
Cc: Song Liu <songliubraving@fb.com> |
||||||
|
Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,40 @@ |
|||||||
|
From 2c2d9c48d2daf0d78d20494c3779c0f6dc4bfa75 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nigel Croxon <ncroxon@redhat.com> |
||||||
|
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 <ncroxon@redhat.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,99 @@ |
|||||||
|
From e53cb968691d9e40d83caf5570da3bb7b83c64e1 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Guoqing Jiang <gqjiang@suse.com> |
||||||
|
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 <neilb@suse.com> |
||||||
|
Signed-off-by: Guoqing Jiang <gqjiang@suse.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,35 @@ |
|||||||
|
From 8063fd0f9e8abd718bd65928c19bc607cee5acd8 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Xiao Ni <xni@redhat.com> |
||||||
|
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 <xni@redhat.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,31 @@ |
|||||||
|
From 611093148574164fcf4f24f8c076d09473f655d7 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Xiao Ni <xni@redhat.com> |
||||||
|
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 <xni@redhat.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,47 @@ |
|||||||
|
From 7bd59e7926c6921121087eb067befaa896c900a4 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.de> |
||||||
|
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 <neilb@suse.de> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,40 @@ |
|||||||
|
From b6180160f78f0182b296bdceed6419b26a6fccc7 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com> |
||||||
|
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 <mariusz.tkaczyk@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,50 @@ |
|||||||
|
From 1a1ced1e2e64a6b4b349a3fb559f6b39e4cf7103 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Krzysztof Smolinski <krzysztof.smolinski@intel.com> |
||||||
|
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 <krzysztof.smolinski@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,45 @@ |
|||||||
|
From 6636788aaf4ec0cacaefb6e77592e4a68e70a957 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.de> |
||||||
|
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 <neilb@suse.de> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,51 @@ |
|||||||
|
From 4ca799c581703d4d0ad840833c037c2fff088ca7 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.de> |
||||||
|
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 <neilb@suse.de> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,29 @@ |
|||||||
|
From 85b83a7920bca5b93d2458f093f2c640a130614c Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.de> |
||||||
|
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 <neilb@suse.de> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,122 @@ |
|||||||
|
From 761e3bd9f5e3aafa95ad3ae50a637dc67c8774f0 Mon Sep 17 00:00:00 2001 |
||||||
|
From: NeilBrown <neilb@suse.de> |
||||||
|
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 <neilb@suse.de> |
||||||
|
Acked-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
From 66cf514d43e93ff5258f09c60f1d0734d4c473a2 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Xiao Ni <xni@redhat.com> |
||||||
|
Date: Fri, 29 Nov 2019 17:09:18 +0800 |
||||||
|
Subject: [RHEL7.8 PATCH V2 1/1] Remove unused code |
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
@ -0,0 +1,176 @@ |
|||||||
|
From b771faef931c798a4553db0a8c1366aff90079c6 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com> |
||||||
|
Date: Fri, 29 Nov 2019 15:21:08 +0100 |
||||||
|
Subject: [RHEL7.8 PATCH 49/49] 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 <blazej.kucman@intel.com> |
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
||||||
|
--- |
||||||
|
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 |
||||||
|
|
Loading…
Reference in new issue