File Make-IRs-and-run-work-properly-for-containers.patch of Package mdadm.2874

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

openSUSE Build Service is sponsored by