forked from pool/mdadm
- Restructure-assemble_container_content-and-improve-m.patch
- Incremental-add-export-handling.patch - udev-rules.degraded - systemd-mdadm-last-resort@.service - systemd-mdadm-last-resort@.timer Teach systemd to start degraded arrays after a timeout if some missing devices never appear (bnc#832501) - Incremental-improve-support-for-DEVICE-based-restric.patch Teach "mdadm --incremental" to handle "DEVICE" lists from mdadm.conf properly (bnc@851993) OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=98
This commit is contained in:
parent
9eeca8cc12
commit
b646ad77a6
294
Incremental-add-export-handling.patch
Normal file
294
Incremental-add-export-handling.patch
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
From 9ca39acb3e8bc31811e463d19fae81c5501aea65 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Thu, 28 Nov 2013 15:15:30 +1100
|
||||||
|
Subject: [PATCH] Incremental: add --export handling.
|
||||||
|
|
||||||
|
If --export is given with --incremental, then
|
||||||
|
MD_DEVNAME
|
||||||
|
is output which gives the name of the device (in /dev/md) that
|
||||||
|
is the array (or container) that the device would be added to.
|
||||||
|
Also
|
||||||
|
MD_STARTED
|
||||||
|
is set to one of
|
||||||
|
no
|
||||||
|
unsafe
|
||||||
|
yes
|
||||||
|
nothing
|
||||||
|
|
||||||
|
to indicate if the array was started. IF MD_STARTED=unsafe
|
||||||
|
then it may be appropriate to run
|
||||||
|
mdadm -R /dev/md/$MD_DEVNAME
|
||||||
|
after a timeout to ensure newly degraded array are started.
|
||||||
|
|
||||||
|
If
|
||||||
|
MD_FOREIGN=yes
|
||||||
|
it might be appropriate to suppress this as the array is
|
||||||
|
probably not critical.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
---
|
||||||
|
Assemble.c | 19 ++++++++++++-----
|
||||||
|
Incremental.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
|
||||||
|
mdadm.8.in | 21 +++++++++++++++++--
|
||||||
|
mdadm.h | 6 ++++-
|
||||||
|
4 files changed, 94 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
--- mdadm-3.3.orig/Assemble.c
|
||||||
|
+++ mdadm-3.3/Assemble.c
|
||||||
|
@@ -1419,7 +1419,7 @@ try_again:
|
||||||
|
/* This is a member of a container. Try starting the array. */
|
||||||
|
int err;
|
||||||
|
err = assemble_container_content(st, mdfd, content, c,
|
||||||
|
- chosen_name);
|
||||||
|
+ chosen_name, NULL);
|
||||||
|
close(mdfd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@@ -1771,7 +1771,7 @@ try_again:
|
||||||
|
#ifndef MDASSEMBLE
|
||||||
|
int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
struct mdinfo *content, struct context *c,
|
||||||
|
- char *chosen_name)
|
||||||
|
+ char *chosen_name, int *result)
|
||||||
|
{
|
||||||
|
struct mdinfo *dev, *sra;
|
||||||
|
int working = 0, preexist = 0;
|
||||||
|
@@ -1838,7 +1838,9 @@ int assemble_container_content(struct su
|
||||||
|
|
||||||
|
if (enough(content->array.level, content->array.raid_disks,
|
||||||
|
content->array.layout, content->array.state & 1, avail) == 0) {
|
||||||
|
- if (c->verbose >= 0) {
|
||||||
|
+ if (c->export && result)
|
||||||
|
+ *result |= INCR_NO;
|
||||||
|
+ else if (c->verbose >= 0) {
|
||||||
|
pr_err("%s assembled with %d device%s",
|
||||||
|
chosen_name, preexist + working,
|
||||||
|
preexist + working == 1 ? "":"s");
|
||||||
|
@@ -1854,7 +1856,9 @@ int assemble_container_content(struct su
|
||||||
|
if (c->runstop <= 0 &&
|
||||||
|
(working + preexist + expansion) <
|
||||||
|
content->array.working_disks) {
|
||||||
|
- if (c->verbose >= 0) {
|
||||||
|
+ if (c->export && result)
|
||||||
|
+ *result |= INCR_UNSAFE;
|
||||||
|
+ else if (c->verbose >= 0) {
|
||||||
|
pr_err("%s assembled with %d device%s",
|
||||||
|
chosen_name, preexist + working,
|
||||||
|
preexist + working == 1 ? "":"s");
|
||||||
|
@@ -1918,7 +1922,12 @@ int assemble_container_content(struct su
|
||||||
|
!start_reshape)
|
||||||
|
block_subarray(content);
|
||||||
|
|
||||||
|
- if (c->verbose >= 0) {
|
||||||
|
+ if (c->export && result) {
|
||||||
|
+ if (err)
|
||||||
|
+ *result |= INCR_NO;
|
||||||
|
+ else
|
||||||
|
+ *result |= INCR_YES;
|
||||||
|
+ } else if (c->verbose >= 0) {
|
||||||
|
if (err)
|
||||||
|
pr_err("array %s now has %d device%s",
|
||||||
|
chosen_name, working + preexist,
|
||||||
|
--- mdadm-3.3.orig/Incremental.c
|
||||||
|
+++ mdadm-3.3/Incremental.c
|
||||||
|
@@ -91,6 +91,7 @@ int Incremental(char *devname, struct co
|
||||||
|
struct mdinfo *sra = NULL, *d;
|
||||||
|
struct mddev_ident *match;
|
||||||
|
char chosen_name[1024];
|
||||||
|
+ char *md_devname;
|
||||||
|
int rv = 1;
|
||||||
|
struct map_ent *mp, *map = NULL;
|
||||||
|
int dfd = -1, mdfd = -1;
|
||||||
|
@@ -138,6 +139,8 @@ int Incremental(char *devname, struct co
|
||||||
|
if (map_lock(&map))
|
||||||
|
pr_err("failed to get "
|
||||||
|
"exclusive lock on mapfile\n");
|
||||||
|
+ if (c->export)
|
||||||
|
+ printf("MD_DEVNAME=%s\n", devname);
|
||||||
|
rv = Incremental_container(st, devname, c, NULL);
|
||||||
|
map_unlock(&map);
|
||||||
|
return rv;
|
||||||
|
@@ -459,6 +462,15 @@ int Incremental(char *devname, struct co
|
||||||
|
info.array.working_disks ++;
|
||||||
|
|
||||||
|
}
|
||||||
|
+ if (strncmp(chosen_name, "/dev/md/", 8) == 0)
|
||||||
|
+ md_devname = chosen_name+8;
|
||||||
|
+ else
|
||||||
|
+ md_devname = chosen_name;
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_DEVICE=%s\n", fd2devnm(mdfd));
|
||||||
|
+ printf("MD_DEVNAME=%s\n", md_devname);
|
||||||
|
+ printf("MD_FOREIGN=%s\n", trustworthy == FOREIGN ? "yes" : "no");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* 7/ Is there enough devices to possibly start the array? */
|
||||||
|
/* 7a/ if not, finish with success. */
|
||||||
|
@@ -466,7 +478,7 @@ int Incremental(char *devname, struct co
|
||||||
|
char devnm[32];
|
||||||
|
/* Try to assemble within the container */
|
||||||
|
sysfs_uevent(sra, "change");
|
||||||
|
- if (c->verbose >= 0)
|
||||||
|
+ if (!c->export && c->verbose >= 0)
|
||||||
|
pr_err("container %s now has %d device%s\n",
|
||||||
|
chosen_name, info.array.working_disks,
|
||||||
|
info.array.working_disks == 1?"":"s");
|
||||||
|
@@ -503,7 +515,9 @@ int Incremental(char *devname, struct co
|
||||||
|
if (enough(info.array.level, info.array.raid_disks,
|
||||||
|
info.array.layout, info.array.state & 1,
|
||||||
|
avail) == 0) {
|
||||||
|
- if (c->verbose >= 0)
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=no\n");
|
||||||
|
+ } else if (c->verbose >= 0)
|
||||||
|
pr_err("%s attached to %s, not enough to start (%d).\n",
|
||||||
|
devname, chosen_name, active_disks);
|
||||||
|
rv = 0;
|
||||||
|
@@ -517,7 +531,9 @@ int Incremental(char *devname, struct co
|
||||||
|
/* + start the array (auto-readonly). */
|
||||||
|
|
||||||
|
if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
|
||||||
|
- if (c->verbose >= 0)
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=already\n");
|
||||||
|
+ } else if (c->verbose >= 0)
|
||||||
|
pr_err("%s attached to %s which is already active.\n",
|
||||||
|
devname, chosen_name);
|
||||||
|
rv = 0;
|
||||||
|
@@ -564,7 +580,9 @@ int Incremental(char *devname, struct co
|
||||||
|
rv = sysfs_set_str(sra, NULL,
|
||||||
|
"array_state", "read-auto");
|
||||||
|
if (rv == 0) {
|
||||||
|
- if (c->verbose >= 0)
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=yes\n");
|
||||||
|
+ } else if (c->verbose >= 0)
|
||||||
|
pr_err("%s attached to %s, which has been started.\n",
|
||||||
|
devname, chosen_name);
|
||||||
|
rv = 0;
|
||||||
|
@@ -587,7 +605,9 @@ int Incremental(char *devname, struct co
|
||||||
|
rv = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- if (c->verbose >= 0)
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=unsafe\n");
|
||||||
|
+ } else if (c->verbose >= 0)
|
||||||
|
pr_err("%s attached to %s, not enough to start safely.\n",
|
||||||
|
devname, chosen_name);
|
||||||
|
rv = 0;
|
||||||
|
@@ -1441,6 +1461,7 @@ static int Incremental_container(struct
|
||||||
|
int sfd;
|
||||||
|
int ra_blocked = 0;
|
||||||
|
int ra_all = 0;
|
||||||
|
+ int result = 0;
|
||||||
|
|
||||||
|
st->ss->getinfo_super(st, &info, NULL);
|
||||||
|
|
||||||
|
@@ -1448,7 +1469,9 @@ static int Incremental_container(struct
|
||||||
|
info.container_enough > 0)
|
||||||
|
/* pass */;
|
||||||
|
else {
|
||||||
|
- if (c->verbose)
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=no\n");
|
||||||
|
+ } else if (c->verbose)
|
||||||
|
pr_err("not enough devices to start the container\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1469,8 +1492,12 @@ static int Incremental_container(struct
|
||||||
|
|
||||||
|
list = st->ss->container_content(st, NULL);
|
||||||
|
/* when nothing to activate - quit */
|
||||||
|
- if (list == NULL)
|
||||||
|
+ if (list == NULL) {
|
||||||
|
+ if (c->export) {
|
||||||
|
+ printf("MD_STARTED=nothing\n");
|
||||||
|
+ }
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
for (ra = list ; ra ; ra = ra->next) {
|
||||||
|
int mdfd;
|
||||||
|
char chosen_name[1024];
|
||||||
|
@@ -1560,9 +1587,30 @@ static int Incremental_container(struct
|
||||||
|
}
|
||||||
|
|
||||||
|
assemble_container_content(st, mdfd, ra, c,
|
||||||
|
- chosen_name);
|
||||||
|
+ chosen_name, &result);
|
||||||
|
close(mdfd);
|
||||||
|
}
|
||||||
|
+ if (c->export && result) {
|
||||||
|
+ char sep = '=';
|
||||||
|
+ printf("MD_STARTED");
|
||||||
|
+ if (result & INCR_NO) {
|
||||||
|
+ printf("%cno", sep);
|
||||||
|
+ sep = ',';
|
||||||
|
+ }
|
||||||
|
+ if (result & INCR_UNSAFE) {
|
||||||
|
+ printf("%cunsafe", sep);
|
||||||
|
+ sep = ',';
|
||||||
|
+ }
|
||||||
|
+ if (result & INCR_ALREADY) {
|
||||||
|
+ printf("%calready", sep);
|
||||||
|
+ sep = ',';
|
||||||
|
+ }
|
||||||
|
+ if (result & INCR_YES) {
|
||||||
|
+ printf("%cyes", sep);
|
||||||
|
+ sep = ',';
|
||||||
|
+ }
|
||||||
|
+ printf("\n");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* don't move spares to container with volume being activated
|
||||||
|
when all volumes are blocked */
|
||||||
|
--- mdadm-3.3.orig/mdadm.8.in
|
||||||
|
+++ mdadm-3.3/mdadm.8.in
|
||||||
|
@@ -1428,13 +1428,30 @@ absolute filepath or a link, e.g.
|
||||||
|
.TP
|
||||||
|
.BR \-Y ", " \-\-export
|
||||||
|
When used with
|
||||||
|
-.B \-\-detail , \-\-detail-platform
|
||||||
|
-or
|
||||||
|
+.BR \-\-detail ,
|
||||||
|
+.BR \-\-detail-platform ,
|
||||||
|
.BR \-\-examine ,
|
||||||
|
+or
|
||||||
|
+.B \-\-incremental
|
||||||
|
output will be formatted as
|
||||||
|
.B key=value
|
||||||
|
pairs for easy import into the environment.
|
||||||
|
|
||||||
|
+With
|
||||||
|
+.B \-\-incremental
|
||||||
|
+The value
|
||||||
|
+.B MD_STARTED
|
||||||
|
+indicates whether an array was started
|
||||||
|
+.RB ( yes )
|
||||||
|
+or not, which may include a reason
|
||||||
|
+.RB ( unsafe ", " nothing ", " no ).
|
||||||
|
+Also the value
|
||||||
|
+.B MD_FOREIGN
|
||||||
|
+indicates if the array is expected on this host
|
||||||
|
+.RB ( no ),
|
||||||
|
+or seems to be from elsewhere
|
||||||
|
+.RB ( yes ).
|
||||||
|
+
|
||||||
|
.TP
|
||||||
|
.BR \-E ", " \-\-examine
|
||||||
|
Print contents of the metadata stored on the named device(s).
|
||||||
|
--- mdadm-3.3.orig/mdadm.h
|
||||||
|
+++ mdadm-3.3/mdadm.h
|
||||||
|
@@ -1328,7 +1328,11 @@ extern void append_metadata_update(struc
|
||||||
|
extern int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
struct mdinfo *content,
|
||||||
|
struct context *c,
|
||||||
|
- char *chosen_name);
|
||||||
|
+ char *chosen_name, int *result);
|
||||||
|
+#define INCR_NO 1
|
||||||
|
+#define INCR_UNSAFE 2
|
||||||
|
+#define INCR_ALREADY 4
|
||||||
|
+#define INCR_YES 8
|
||||||
|
extern struct mdinfo *container_choose_spares(struct supertype *st,
|
||||||
|
unsigned long long min_size,
|
||||||
|
struct domainlist *domlist,
|
154
Incremental-improve-support-for-DEVICE-based-restric.patch
Normal file
154
Incremental-improve-support-for-DEVICE-based-restric.patch
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
From b11fe74db0d764c3a245d95bc3651be9bbd59463 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Tue, 3 Dec 2013 14:01:24 +1100
|
||||||
|
Subject: [PATCH] Incremental: improve support for "DEVICE" based restriction
|
||||||
|
in mdadm.conf
|
||||||
|
|
||||||
|
--incremental currently fails if the device name passed does not
|
||||||
|
textually match the names permitted by the DEVICE line in mdadm.conf.
|
||||||
|
This is problematic when "mdadm -I" is run by udev as the name given
|
||||||
|
can be a temp name.
|
||||||
|
|
||||||
|
This patch makes two improvements:
|
||||||
|
1/ We generate a list of all existing devices that match the names
|
||||||
|
in mdadm.conf, and allow rdev based matching
|
||||||
|
2/ We allows extra aliases to be provided on the command line, and
|
||||||
|
perform textual matching on those. This is particularly suitable
|
||||||
|
for udev usages as ${DEVLINKS} can be provided even though the links
|
||||||
|
make not yet be created.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
---
|
||||||
|
Incremental.c | 18 ++++++++++++++++--
|
||||||
|
mdadm.8.in | 12 ++++++++++--
|
||||||
|
mdadm.c | 16 ++++++++--------
|
||||||
|
mdadm.h | 2 +-
|
||||||
|
udev-md-raid-assembly.rules | 2 +-
|
||||||
|
5 files changed, 36 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
--- mdadm-3.3.orig/Incremental.c
|
||||||
|
+++ mdadm-3.3/Incremental.c
|
||||||
|
@@ -46,7 +46,7 @@ static int try_spare(char *devname, int
|
||||||
|
static int Incremental_container(struct supertype *st, char *devname,
|
||||||
|
struct context *c, char *only);
|
||||||
|
|
||||||
|
-int Incremental(char *devname, struct context *c,
|
||||||
|
+int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||||
|
struct supertype *st)
|
||||||
|
{
|
||||||
|
/* Add this device to an array, creating the array if necessary
|
||||||
|
@@ -103,6 +103,7 @@ int Incremental(char *devname, struct co
|
||||||
|
struct dev_policy *policy = NULL;
|
||||||
|
struct map_ent target_array;
|
||||||
|
int have_target;
|
||||||
|
+ char *devname = devlist->devname;
|
||||||
|
|
||||||
|
struct createinfo *ci = conf_get_create_info();
|
||||||
|
|
||||||
|
@@ -153,7 +154,20 @@ int Incremental(char *devname, struct co
|
||||||
|
|
||||||
|
/* 1/ Check if device is permitted by mdadm.conf */
|
||||||
|
|
||||||
|
- if (!conf_test_dev(devname)) {
|
||||||
|
+ for (;devlist; devlist = devlist->next)
|
||||||
|
+ if (conf_test_dev(devlist->devname))
|
||||||
|
+ break;
|
||||||
|
+ if (!devlist) {
|
||||||
|
+ devlist = conf_get_devs();
|
||||||
|
+ for (;devlist; devlist = devlist->next) {
|
||||||
|
+ struct stat st2;
|
||||||
|
+ if (stat(devlist->devname, &st2) == 0 &&
|
||||||
|
+ (st2.st_mode & S_IFMT) == S_IFBLK &&
|
||||||
|
+ st2.st_rdev == stb.st_rdev)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (!devlist) {
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
pr_err("%s not permitted by mdadm.conf.\n",
|
||||||
|
devname);
|
||||||
|
--- mdadm-3.3.orig/mdadm.8.in
|
||||||
|
+++ mdadm-3.3/mdadm.8.in
|
||||||
|
@@ -2664,6 +2664,7 @@ Usage:
|
||||||
|
.RB [ \-\-run ]
|
||||||
|
.RB [ \-\-quiet ]
|
||||||
|
.I component-device
|
||||||
|
+.RI [ optional-aliases-for-device ]
|
||||||
|
.HP 12
|
||||||
|
Usage:
|
||||||
|
.B mdadm \-\-incremental \-\-fail
|
||||||
|
@@ -2718,16 +2719,23 @@ That is, is it listed in a
|
||||||
|
.B DEVICES
|
||||||
|
line in that file. If
|
||||||
|
.B DEVICES
|
||||||
|
-is absent then the default it to allow any device. Similar if
|
||||||
|
+is absent then the default it to allow any device. Similarly if
|
||||||
|
.B DEVICES
|
||||||
|
contains the special word
|
||||||
|
.B partitions
|
||||||
|
then any device is allowed. Otherwise the device name given to
|
||||||
|
-.I mdadm
|
||||||
|
+.IR mdadm ,
|
||||||
|
+or one of the aliases given, or an alias found in the filesystem,
|
||||||
|
must match one of the names or patterns in a
|
||||||
|
.B DEVICES
|
||||||
|
line.
|
||||||
|
|
||||||
|
+This is the only context where the aliases are used. They are
|
||||||
|
+usually provided by a
|
||||||
|
+.I udev
|
||||||
|
+rules mentioning
|
||||||
|
+.BR ${DEVLINKS} .
|
||||||
|
+
|
||||||
|
.IP +
|
||||||
|
Does the device have a valid md superblock? If a specific metadata
|
||||||
|
version is requested with
|
||||||
|
--- mdadm-3.3.orig/mdadm.c
|
||||||
|
+++ mdadm-3.3/mdadm.c
|
||||||
|
@@ -1544,16 +1544,16 @@ int main(int argc, char *argv[])
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- if (devlist->next) {
|
||||||
|
- pr_err("--incremental can only handle one device.\n");
|
||||||
|
- rv = 1;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- if (devmode == 'f')
|
||||||
|
+ if (devmode == 'f') {
|
||||||
|
+ if (devlist->next) {
|
||||||
|
+ pr_err("'--incremental --fail' can only handle one device.\n");
|
||||||
|
+ rv = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
rv = IncrementalRemove(devlist->devname, remove_path,
|
||||||
|
c.verbose);
|
||||||
|
- else
|
||||||
|
- rv = Incremental(devlist->devname, &c, ss);
|
||||||
|
+ } else
|
||||||
|
+ rv = Incremental(devlist, &c, ss);
|
||||||
|
break;
|
||||||
|
case AUTODETECT:
|
||||||
|
autodetect();
|
||||||
|
--- mdadm-3.3.orig/mdadm.h
|
||||||
|
+++ mdadm-3.3/mdadm.h
|
||||||
|
@@ -1232,7 +1232,7 @@ extern int Update_subarray(char *dev, ch
|
||||||
|
extern int Wait(char *dev);
|
||||||
|
extern int WaitClean(char *dev, int sock, int verbose);
|
||||||
|
|
||||||
|
-extern int Incremental(char *devname, struct context *c,
|
||||||
|
+extern int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||||
|
struct supertype *st);
|
||||||
|
extern void RebuildMap(void);
|
||||||
|
extern int IncrementalScan(struct context *c, char *devnm);
|
||||||
|
--- mdadm-3.3.orig/udev-md-raid-assembly.rules
|
||||||
|
+++ mdadm-3.3/udev-md-raid-assembly.rules
|
||||||
|
@@ -12,7 +12,7 @@ LABEL="md_inc"
|
||||||
|
|
||||||
|
# remember you can limit what gets auto/incrementally assembled by
|
||||||
|
# mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
|
||||||
|
-ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot"
|
||||||
|
+ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot ${DEVLINKS}"
|
||||||
|
ACTION=="add", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
|
||||||
|
ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||||||
|
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name"
|
237
Restructure-assemble_container_content-and-improve-m.patch
Normal file
237
Restructure-assemble_container_content-and-improve-m.patch
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
From c1736844ba49ec1a8731b5815abfd6530b982a3b Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Thu, 28 Nov 2013 14:47:41 +1100
|
||||||
|
Subject: [PATCH 1/2] Restructure assemble_container_content and improve
|
||||||
|
messages.
|
||||||
|
|
||||||
|
We lose one level of indent, and now get told the difference between
|
||||||
|
'not assemble because not safe' and 'not assembled because not enough
|
||||||
|
devices'.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
---
|
||||||
|
Assemble.c | 176 ++++++++++++++++++++++++++++++++++---------------------------
|
||||||
|
1 file changed, 99 insertions(+), 77 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index 4d5ceeac8674..11b77c288608 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -1779,6 +1779,8 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
struct map_ent *map = NULL;
|
||||||
|
int old_raid_disks;
|
||||||
|
int start_reshape;
|
||||||
|
+ char *avail = NULL;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
sysfs_init(content, mdfd, NULL);
|
||||||
|
|
||||||
|
@@ -1812,7 +1814,10 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
if (sra)
|
||||||
|
sysfs_free(sra);
|
||||||
|
old_raid_disks = content->array.raid_disks - content->delta_disks;
|
||||||
|
- for (dev = content->devs; dev; dev = dev->next)
|
||||||
|
+ avail = xcalloc(content->array.raid_disks, 1);
|
||||||
|
+ for (dev = content->devs; dev; dev = dev->next) {
|
||||||
|
+ if (dev->disk.raid_disk >= 0)
|
||||||
|
+ avail[dev->disk.raid_disk] = 1;
|
||||||
|
if (sysfs_add_disk(content, dev, 1) == 0) {
|
||||||
|
if (dev->disk.raid_disk >= old_raid_disks &&
|
||||||
|
content->reshape_active)
|
||||||
|
@@ -1821,100 +1826,117 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
working++;
|
||||||
|
} else if (errno == EEXIST)
|
||||||
|
preexist++;
|
||||||
|
- if (working + expansion == 0 && c->runstop <= 0)
|
||||||
|
+ }
|
||||||
|
+ if (working + expansion == 0 && c->runstop <= 0) {
|
||||||
|
+ free(avail);
|
||||||
|
return 1;/* Nothing new, don't try to start */
|
||||||
|
-
|
||||||
|
+ }
|
||||||
|
map_update(&map, fd2devnm(mdfd),
|
||||||
|
content->text_version,
|
||||||
|
content->uuid, chosen_name);
|
||||||
|
|
||||||
|
- if (c->runstop > 0 ||
|
||||||
|
- (working + preexist + expansion) >=
|
||||||
|
- content->array.working_disks) {
|
||||||
|
- int err;
|
||||||
|
-
|
||||||
|
- if (start_reshape) {
|
||||||
|
- int spare = content->array.raid_disks + expansion;
|
||||||
|
- if (restore_backup(st, content,
|
||||||
|
- working,
|
||||||
|
- spare, c->backup_file, c->verbose) == 1)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- err = sysfs_set_str(content, NULL,
|
||||||
|
- "array_state", "readonly");
|
||||||
|
- if (err)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- if (st->ss->external) {
|
||||||
|
- if (!mdmon_running(st->container_devnm))
|
||||||
|
- start_mdmon(st->container_devnm);
|
||||||
|
- ping_monitor(st->container_devnm);
|
||||||
|
- if (mdmon_running(st->container_devnm) &&
|
||||||
|
- st->update_tail == NULL)
|
||||||
|
- st->update_tail = &st->updates;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- err = Grow_continue(mdfd, st, content, c->backup_file,
|
||||||
|
- c->freeze_reshape);
|
||||||
|
- } else switch(content->array.level) {
|
||||||
|
- case LEVEL_LINEAR:
|
||||||
|
- case LEVEL_MULTIPATH:
|
||||||
|
- case 0:
|
||||||
|
- err = sysfs_set_str(content, NULL, "array_state",
|
||||||
|
- c->readonly ? "readonly" : "active");
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- err = sysfs_set_str(content, NULL, "array_state",
|
||||||
|
- "readonly");
|
||||||
|
- /* start mdmon if needed. */
|
||||||
|
- if (!err) {
|
||||||
|
- if (!mdmon_running(st->container_devnm))
|
||||||
|
- start_mdmon(st->container_devnm);
|
||||||
|
- ping_monitor(st->container_devnm);
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- if (!err)
|
||||||
|
- sysfs_set_safemode(content, content->safe_mode_delay);
|
||||||
|
-
|
||||||
|
- /* Block subarray here if it is not reshaped now
|
||||||
|
- * It has be blocked a little later to allow mdmon to switch in
|
||||||
|
- * in to R/W state
|
||||||
|
- */
|
||||||
|
- if (st->ss->external && content->recovery_blocked &&
|
||||||
|
- !start_reshape)
|
||||||
|
- block_subarray(content);
|
||||||
|
|
||||||
|
+ if (enough(content->array.level, content->array.raid_disks,
|
||||||
|
+ content->array.layout, content->array.state & 1, avail) == 0) {
|
||||||
|
if (c->verbose >= 0) {
|
||||||
|
- if (err)
|
||||||
|
- pr_err("array %s now has %d device%s",
|
||||||
|
- chosen_name, working + preexist,
|
||||||
|
- working + preexist == 1 ? "":"s");
|
||||||
|
- else
|
||||||
|
- pr_err("Started %s with %d device%s",
|
||||||
|
- chosen_name, working + preexist,
|
||||||
|
- working + preexist == 1 ? "":"s");
|
||||||
|
+ pr_err("%s assembled with %d device%s",
|
||||||
|
+ chosen_name, preexist + working,
|
||||||
|
+ preexist + working == 1 ? "":"s");
|
||||||
|
if (preexist)
|
||||||
|
fprintf(stderr, " (%d new)", working);
|
||||||
|
- if (expansion)
|
||||||
|
- fprintf(stderr, " ( + %d for expansion)",
|
||||||
|
- expansion);
|
||||||
|
- fprintf(stderr, "\n");
|
||||||
|
+ fprintf(stderr, " but not started\n");
|
||||||
|
}
|
||||||
|
- if (!err)
|
||||||
|
- wait_for(chosen_name, mdfd);
|
||||||
|
- return err;
|
||||||
|
- /* FIXME should have an O_EXCL and wait for read-auto */
|
||||||
|
- } else {
|
||||||
|
+ free(avail);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ free(avail);
|
||||||
|
+
|
||||||
|
+ if (c->runstop <= 0 &&
|
||||||
|
+ (working + preexist + expansion) <
|
||||||
|
+ content->array.working_disks) {
|
||||||
|
if (c->verbose >= 0) {
|
||||||
|
pr_err("%s assembled with %d device%s",
|
||||||
|
chosen_name, preexist + working,
|
||||||
|
preexist + working == 1 ? "":"s");
|
||||||
|
if (preexist)
|
||||||
|
fprintf(stderr, " (%d new)", working);
|
||||||
|
- fprintf(stderr, " but not started\n");
|
||||||
|
+ fprintf(stderr, " but not safe to start\n");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ if (start_reshape) {
|
||||||
|
+ int spare = content->array.raid_disks + expansion;
|
||||||
|
+ if (restore_backup(st, content,
|
||||||
|
+ working,
|
||||||
|
+ spare, c->backup_file, c->verbose) == 1)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ err = sysfs_set_str(content, NULL,
|
||||||
|
+ "array_state", "readonly");
|
||||||
|
+ if (err)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (st->ss->external) {
|
||||||
|
+ if (!mdmon_running(st->container_devnm))
|
||||||
|
+ start_mdmon(st->container_devnm);
|
||||||
|
+ ping_monitor(st->container_devnm);
|
||||||
|
+ if (mdmon_running(st->container_devnm) &&
|
||||||
|
+ st->update_tail == NULL)
|
||||||
|
+ st->update_tail = &st->updates;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = Grow_continue(mdfd, st, content, c->backup_file,
|
||||||
|
+ c->freeze_reshape);
|
||||||
|
+ } else switch(content->array.level) {
|
||||||
|
+ case LEVEL_LINEAR:
|
||||||
|
+ case LEVEL_MULTIPATH:
|
||||||
|
+ case 0:
|
||||||
|
+ err = sysfs_set_str(content, NULL, "array_state",
|
||||||
|
+ c->readonly ? "readonly" : "active");
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ err = sysfs_set_str(content, NULL, "array_state",
|
||||||
|
+ "readonly");
|
||||||
|
+ /* start mdmon if needed. */
|
||||||
|
+ if (!err) {
|
||||||
|
+ if (!mdmon_running(st->container_devnm))
|
||||||
|
+ start_mdmon(st->container_devnm);
|
||||||
|
+ ping_monitor(st->container_devnm);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (!err)
|
||||||
|
+ sysfs_set_safemode(content, content->safe_mode_delay);
|
||||||
|
+
|
||||||
|
+ /* Block subarray here if it is not reshaped now
|
||||||
|
+ * It has be blocked a little later to allow mdmon to switch in
|
||||||
|
+ * in to R/W state
|
||||||
|
+ */
|
||||||
|
+ if (st->ss->external && content->recovery_blocked &&
|
||||||
|
+ !start_reshape)
|
||||||
|
+ block_subarray(content);
|
||||||
|
+
|
||||||
|
+ if (c->verbose >= 0) {
|
||||||
|
+ if (err)
|
||||||
|
+ pr_err("array %s now has %d device%s",
|
||||||
|
+ chosen_name, working + preexist,
|
||||||
|
+ working + preexist == 1 ? "":"s");
|
||||||
|
+ else
|
||||||
|
+ 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)
|
||||||
|
+ fprintf(stderr, " ( + %d for expansion)",
|
||||||
|
+ expansion);
|
||||||
|
+ fprintf(stderr, "\n");
|
||||||
|
+ }
|
||||||
|
+ if (!err)
|
||||||
|
+ wait_for(chosen_name, mdfd);
|
||||||
|
+ return err;
|
||||||
|
+ /* FIXME should have an O_EXCL and wait for read-auto */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.8.3.1.487.g3e7a5b4
|
||||||
|
|
@ -1,3 +1,17 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Dec 3 03:06:07 UTC 2013 - nfbrown@suse.com
|
||||||
|
|
||||||
|
- Restructure-assemble_container_content-and-improve-m.patch
|
||||||
|
- Incremental-add-export-handling.patch
|
||||||
|
- udev-rules.degraded
|
||||||
|
- systemd-mdadm-last-resort@.service
|
||||||
|
- systemd-mdadm-last-resort@.timer
|
||||||
|
Teach systemd to start degraded arrays after a timeout if
|
||||||
|
some missing devices never appear (bnc#832501)
|
||||||
|
- Incremental-improve-support-for-DEVICE-based-restric.patch
|
||||||
|
Teach "mdadm --incremental" to handle "DEVICE" lists from
|
||||||
|
mdadm.conf properly (bnc@851993)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Nov 11 00:45:03 UTC 2013 - nfbrown@suse.com
|
Mon Nov 11 00:45:03 UTC 2013 - nfbrown@suse.com
|
||||||
|
|
||||||
|
18
mdadm.spec
18
mdadm.spec
@ -43,6 +43,8 @@ Source5: mkinitrd-setup.sh
|
|||||||
Source6: mkinitrd-boot.sh
|
Source6: mkinitrd-boot.sh
|
||||||
Source7: mdadm.cron
|
Source7: mdadm.cron
|
||||||
Source8: mdadm.shutdown
|
Source8: mdadm.shutdown
|
||||||
|
Source9: systemd-mdadm-last-resort@.timer
|
||||||
|
Source10: systemd-mdadm-last-resort@.service
|
||||||
# PATCH-FIX-UPSTREAM config-set-auto_seen-after-processing-the-auto-line.patch upstream-bugfix nfbrown@suse.de
|
# PATCH-FIX-UPSTREAM config-set-auto_seen-after-processing-the-auto-line.patch upstream-bugfix nfbrown@suse.de
|
||||||
Patch1: config-set-auto_seen-after-processing-the-auto-line.patch
|
Patch1: config-set-auto_seen-after-processing-the-auto-line.patch
|
||||||
# PATCH-FIX-UPSTREAM DDF-allow-for-possibility-that-there-is-no-secondary.patch upstream-bugfix nfbrown@suse.de
|
# PATCH-FIX-UPSTREAM DDF-allow-for-possibility-that-there-is-no-secondary.patch upstream-bugfix nfbrown@suse.de
|
||||||
@ -67,6 +69,14 @@ Patch10: DDF-add_to_super_ddf-be-careful-with-workspace_lba.patch
|
|||||||
Patch11: Monitor-write-meta-data-in-readonly-state-sometimes.patch
|
Patch11: Monitor-write-meta-data-in-readonly-state-sometimes.patch
|
||||||
# PATCH-FIX-UPSTREAM Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch upstream-bugfix nfbrown@suse.de
|
# PATCH-FIX-UPSTREAM Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch upstream-bugfix nfbrown@suse.de
|
||||||
Patch12: Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
|
Patch12: Assembe-fix-bug-in-force_array-it-wasn-t-forcing-pro.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM Restructure-assemble_container_content-and-improve-m.patch bnc#832501 nfbrown@suse.de
|
||||||
|
Patch13: Restructure-assemble_container_content-and-improve-m.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM Incremental-add-export-handling.patch bnc#832501 nfbrown@suse.de
|
||||||
|
Patch14: Incremental-add-export-handling.patch
|
||||||
|
# PATCH-FEATURE-UPSTREAM udev-rules.degraded bnc#832501 nfbrown@suse.de
|
||||||
|
Patch15: udev-rules.degraded
|
||||||
|
# PATCH-FEATURE-UPSTREAM Incremental-improve-support-for-DEVICE-based-restric.patch bnc#851993 nfbrown@suse.de
|
||||||
|
Patch16: Incremental-improve-support-for-DEVICE-based-restric.patch
|
||||||
|
|
||||||
%define _udevdir %(pkg-config --variable=udevdir udev)
|
%define _udevdir %(pkg-config --variable=udevdir udev)
|
||||||
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
|
%define _systemdshutdowndir %{_unitdir}/../system-shutdown
|
||||||
@ -90,6 +100,10 @@ programs but with a very different interface.
|
|||||||
%patch10 -p1
|
%patch10 -p1
|
||||||
%patch11 -p1
|
%patch11 -p1
|
||||||
%patch12 -p1
|
%patch12 -p1
|
||||||
|
%patch13 -p1
|
||||||
|
%patch14 -p1
|
||||||
|
%patch15 -p1
|
||||||
|
%patch16 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error"
|
make %{?_smp_mflags} CC="%__cc" CXFLAGS="$RPM_OPT_FLAGS -Wno-error"
|
||||||
@ -112,6 +126,8 @@ install -m 644 %{S:2} %{buildroot}%{_var}/adm/fillup-templates/
|
|||||||
ln -sf ../../etc/init.d/mdadmd %{buildroot}/%{_sbindir}/rcmdadmd
|
ln -sf ../../etc/init.d/mdadmd %{buildroot}/%{_sbindir}/rcmdadmd
|
||||||
install -d %{buildroot}%{_systemdshutdowndir}
|
install -d %{buildroot}%{_systemdshutdowndir}
|
||||||
install -m 755 %{S:8} %{buildroot}%{_systemdshutdowndir}/mdadm.shutdown
|
install -m 755 %{S:8} %{buildroot}%{_systemdshutdowndir}/mdadm.shutdown
|
||||||
|
install -m 644 %{S:9} %{buildroot}%{_unitdir}/mdadm-last-resort@.timer
|
||||||
|
install -m 644 %{S:10} %{buildroot}%{_unitdir}/mdadm-last-resort@.service
|
||||||
|
|
||||||
%post
|
%post
|
||||||
[ -x /sbin/mkinitrd_setup ] && mkinitrd_setup
|
[ -x /sbin/mkinitrd_setup ] && mkinitrd_setup
|
||||||
@ -162,5 +178,7 @@ rm -rf %{buildroot}
|
|||||||
/etc/cron.daily/mdadm
|
/etc/cron.daily/mdadm
|
||||||
%{_systemdshutdowndir}/mdadm.shutdown
|
%{_systemdshutdowndir}/mdadm.shutdown
|
||||||
%{_unitdir}/mdmon@.service
|
%{_unitdir}/mdmon@.service
|
||||||
|
%{_unitdir}/mdadm-last-resort@.timer
|
||||||
|
%{_unitdir}/mdadm-last-resort@.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
7
systemd-mdadm-last-resort@.service
Normal file
7
systemd-mdadm-last-resort@.service
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Activate md array even though degraded
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/sbin/mdadm --run /dev/%i
|
6
systemd-mdadm-last-resort@.timer
Normal file
6
systemd-mdadm-last-resort@.timer
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Timer to wait for more drives before activating degraded array.
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnActiveSec=30
|
16
udev-rules.degraded
Normal file
16
udev-rules.degraded
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
udev-md-raid-assembly.rules | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- mdadm-3.3.orig/udev-md-raid-assembly.rules
|
||||||
|
+++ mdadm-3.3/udev-md-raid-assembly.rules
|
||||||
|
@@ -12,7 +12,8 @@ LABEL="md_inc"
|
||||||
|
|
||||||
|
# remember you can limit what gets auto/incrementally assembled by
|
||||||
|
# mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
|
||||||
|
-ACTION=="add", RUN+="/sbin/mdadm --incremental $devnode --offroot"
|
||||||
|
+ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot"
|
||||||
|
+ACTION=="add", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
|
||||||
|
ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||||||
|
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user