b646ad77a6
- 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
238 lines
6.9 KiB
Diff
238 lines
6.9 KiB
Diff
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
|
|
|