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
|
||||
|
||||
|
18
mdadm.spec
18
mdadm.spec
@ -43,6 +43,8 @@ Source5: mkinitrd-setup.sh
|
||||
Source6: mkinitrd-boot.sh
|
||||
Source7: mdadm.cron
|
||||
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
|
||||
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
|
||||
@ -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
|
||||
# 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
|
||||
# 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 _systemdshutdowndir %{_unitdir}/../system-shutdown
|
||||
@ -90,6 +100,10 @@ programs but with a very different interface.
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
|
||||
%build
|
||||
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
|
||||
install -d %{buildroot}%{_systemdshutdowndir}
|
||||
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
|
||||
[ -x /sbin/mkinitrd_setup ] && mkinitrd_setup
|
||||
@ -162,5 +178,7 @@ rm -rf %{buildroot}
|
||||
/etc/cron.daily/mdadm
|
||||
%{_systemdshutdowndir}/mdadm.shutdown
|
||||
%{_unitdir}/mdmon@.service
|
||||
%{_unitdir}/mdadm-last-resort@.timer
|
||||
%{_unitdir}/mdadm-last-resort@.service
|
||||
|
||||
%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