mdadm/Make-IRs-and-run-work-properly-for-containers.patch
Neil Brown 231108cf6e Multiple fixes for mdadm:
- upstream bugfixes in 3.3
 - simplify array assembly in initrd and normal boot.

OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=93
2013-09-13 01:49:53 +00:00

253 lines
8.0 KiB
Diff

From d5a4041647d2b3328ce45ff727afe37477f07c75 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 13 Sep 2013 10:51:20 +1000
Subject: [PATCH] Make -IRs and --run work properly for containers.
We really need to make sure assemble_container_content()
gets called to finished the assembly of these.
Reported-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 2 +-
Incremental.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
Manage.c | 4 ++--
mdadm.c | 7 ++++---
mdadm.h | 4 ++--
5 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index bc85603..86b4c89 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1817,7 +1817,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
working++;
} else if (errno == EEXIST)
preexist++;
- if (working + expansion == 0)
+ if (working + expansion == 0 && c->runstop <= 0)
return 1;/* Nothing new, don't try to start */
map_update(&map, fd2devnm(mdfd),
diff --git a/Incremental.c b/Incremental.c
index f256b48..1bb3638 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -44,7 +44,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct supertype *st, int verbose);
static int Incremental_container(struct supertype *st, char *devname,
- struct context *c);
+ struct context *c, char *only);
int Incremental(char *devname, struct context *c,
struct supertype *st)
@@ -138,7 +138,7 @@ int Incremental(char *devname, struct context *c,
if (map_lock(&map))
pr_err("failed to get "
"exclusive lock on mapfile\n");
- rv = Incremental_container(st, devname, c);
+ rv = Incremental_container(st, devname, c, NULL);
map_unlock(&map);
return rv;
}
@@ -478,7 +478,7 @@ int Incremental(char *devname, struct context *c,
close(mdfd);
sysfs_free(sra);
if (!rv)
- rv = Incremental_container(st, chosen_name, c);
+ rv = Incremental_container(st, chosen_name, c, NULL);
map_unlock(&map);
if (rv == 1)
/* Don't fail the whole -I if a subarray didn't
@@ -1278,7 +1278,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
return rv;
}
-int IncrementalScan(int verbose, char *devnm)
+int IncrementalScan(struct context *c, char *devnm)
{
/* look at every device listed in the 'map' file.
* If one is found that is not running then:
@@ -1290,10 +1290,13 @@ int IncrementalScan(int verbose, char *devnm)
struct map_ent *me;
struct mddev_ident *devs, *mddev;
int rv = 0;
+ char container[32];
+ char *only = NULL;
map_read(&mapl);
devs = conf_get_ident(NULL);
+restart:
for (me = mapl ; me ; me = me->next) {
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
@@ -1302,10 +1305,42 @@ int IncrementalScan(int verbose, char *devnm)
if (devnm && strcmp(devnm, me->devnm) != 0)
continue;
+ if (devnm && me->metadata[0] == '/') {
+ char *sl;
+ /* member array, need to work on container */
+ strncpy(container, me->metadata+1, 32);
+ container[31] = 0;
+ sl = strchr(container, '/');
+ if (sl)
+ *sl = 0;
+ only = devnm;
+ devnm = container;
+ goto restart;
+ }
mdfd = open_dev(me->devnm);
if (mdfd < 0)
continue;
+ if (!isdigit(me->metadata[0])) {
+ /* must be a container */
+ struct supertype *st = super_by_fd(mdfd, NULL);
+ int ret = 0;
+ struct map_ent *map = NULL;
+ if (st)
+ st->ignore_hw_compat = 1;
+ if (st && st->ss->load_container)
+ ret = st->ss->load_container(st, mdfd, NULL);
+ close(mdfd);
+ if (!ret && st->ss->container_content) {
+ if (map_lock(&map))
+ pr_err("failed to get exclusive lock on mapfile\n");
+ ret = Incremental_container(st, me->path, c, only);
+ map_unlock(&map);
+ }
+ if (ret)
+ rv = 1;
+ continue;
+ }
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
errno != ENODEV) {
close(mdfd);
@@ -1330,7 +1365,7 @@ int IncrementalScan(int verbose, char *devnm)
close(bmfd);
}
}
- if (verbose >= 0) {
+ if (c->verbose >= 0) {
if (added == 0)
pr_err("Added bitmap %s to %s\n",
mddev->bitmap_file, me->path);
@@ -1346,7 +1381,7 @@ int IncrementalScan(int verbose, char *devnm)
if (sra) {
if (sysfs_set_str(sra, NULL,
"array_state", "read-auto") == 0) {
- if (verbose >= 0)
+ if (c->verbose >= 0)
pr_err("started array %s\n",
me->path ?: me->devnm);
} else {
@@ -1387,7 +1422,7 @@ static char *container2devname(char *devname)
}
static int Incremental_container(struct supertype *st, char *devname,
- struct context *c)
+ struct context *c, char *only)
{
/* Collect the contents of this container and for each
* array, choose a device name and assemble the array.
@@ -1458,7 +1493,7 @@ static int Incremental_container(struct supertype *st, char *devname,
strcpy(chosen_name, mp->path);
else
strcpy(chosen_name, mp->devnm);
- } else {
+ } else if (!only) {
/* Check in mdadm.conf for container == devname and
* member == ra->text_version after second slash.
@@ -1515,6 +1550,8 @@ static int Incremental_container(struct supertype *st, char *devname,
trustworthy,
chosen_name);
}
+ if (only && (!mp || strcmp(mp->devnm, only) != 0))
+ continue;
if (mdfd < 0) {
pr_err("failed to open %s: %s.\n",
diff --git a/Manage.c b/Manage.c
index 910caa6..c8276ca 100644
--- a/Manage.c
+++ b/Manage.c
@@ -170,7 +170,7 @@ static void remove_devices(char *devnm, char *path)
free(path2);
}
-int Manage_run(char *devname, int fd, int verbose)
+int Manage_run(char *devname, int fd, struct context *c)
{
/* Run the array. Array must already be configured
* Requires >= 0.90.0
@@ -187,7 +187,7 @@ int Manage_run(char *devname, int fd, int verbose)
return 1;
}
strcpy(nm, nmp);
- return IncrementalScan(verbose, nm);
+ return IncrementalScan(c, nm);
}
int Manage_stop(char *devname, int fd, int verbose, int will_retry)
diff --git a/mdadm.c b/mdadm.c
index 1ada607..f55a035 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
if (!rv && c.readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, c.readonly);
if (!rv && c.runstop > 0)
- rv = Manage_run(devlist->devname, mdfd, c.verbose);
+ rv = Manage_run(devlist->devname, mdfd, &c);
if (!rv && c.runstop < 0)
rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
break;
@@ -1535,7 +1535,7 @@ int main(int argc, char *argv[])
pr_err("--incremental --scan --fail not supported.\n");
break;
}
- rv = IncrementalScan(c.verbose, NULL);
+ rv = IncrementalScan(&c, NULL);
}
if (!devlist) {
if (!rebuild_map && !c.scan) {
@@ -1804,7 +1804,8 @@ static int misc_list(struct mddev_dev *devlist,
if (mdfd>=0) {
switch(dv->disposition) {
case 'R':
- rv |= Manage_run(dv->devname, mdfd, c->verbose); break;
+ c->runstop = 1;
+ rv |= Manage_run(dv->devname, mdfd, c); break;
case 'S':
rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
case 'o':
diff --git a/mdadm.h b/mdadm.h
index 2eca603..c90fe10 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1171,7 +1171,7 @@ struct stat64;
extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s);
extern int Manage_ro(char *devname, int fd, int readonly);
-extern int Manage_run(char *devname, int fd, int quiet);
+extern int Manage_run(char *devname, int fd, struct context *c);
extern int Manage_stop(char *devname, int fd, int quiet,
int will_retry);
extern int Manage_subdevs(char *devname, int fd,
@@ -1237,7 +1237,7 @@ extern int WaitClean(char *dev, int sock, int verbose);
extern int Incremental(char *devname, struct context *c,
struct supertype *st);
extern void RebuildMap(void);
-extern int IncrementalScan(int verbose, char *devnm);
+extern int IncrementalScan(struct context *c, char *devnm);
extern int IncrementalRemove(char *devname, char *path, int verbose);
extern int CreateBitmap(char *filename, int force, char uuid[16],
unsigned long chunksize, unsigned long daemon_sleep,
--
1.8.3.1.487.g3e7a5b4