231108cf6e
- 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
253 lines
8.0 KiB
Diff
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
|
|
|