File Assemble-Incremental-don-t-hold-O_EXCL-on-mddev-afte.patch of Package mdadm.openSUSE_13.1_Update

From 8832342d3aad09d3c86af6dc9b137d6fd83af1ae Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Thu, 5 Dec 2013 10:35:16 +1100
Subject: [PATCH] Assemble/Incremental: don't hold O_EXCL on mddev after
 assembly.

As soon as the array is assembled, udev or systemd might run
fsck and mount it.  So we need to drop O_EXCL promptly.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 Assemble.c    |  1 +
 Incremental.c | 10 +++++++---
 mdadm.h       |  1 +
 util.c        | 14 ++++++++++++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 44e905bb8667..7e8e79570352 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1037,6 +1037,7 @@ static int start_array(int mdfd,
 		} else
 #endif
 			rv = ioctl(mdfd, RUN_ARRAY, NULL);
+		reopen_mddev(mdfd); /* drop O_EXCL */
 		if (rv == 0) {
 			if (c->verbose >= 0) {
 				pr_err("%s has been started with %d drive%s",
diff --git a/Incremental.c b/Incremental.c
index f548bad9785d..c9372587f518 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -588,10 +588,14 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
 		else
 			rv = sysfs_set_str(sra, NULL,
 					   "array_state", "read-auto");
+		/* Array might be O_EXCL which  will interfere with
+		 * fsck and mount.  So re-open without O_EXCL.
+		 */
+		reopen_mddev(mdfd);
 		if (rv == 0) {
-		if (c->export) {
-			printf("MD_STARTED=yes\n");
-		} else 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;
diff --git a/mdadm.h b/mdadm.h
index 69facaf32956..7f222a6d7a78 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1272,6 +1272,7 @@ extern int check_partitions(int fd, char *dname,
 extern int get_mdp_major(void);
 extern int dev_open(char *dev, int flags);
 extern int open_dev(char *devnm);
+extern void reopen_mddev(int mdfd);
 extern int open_dev_flags(char *devnm, int flags);
 extern int open_dev_excl(char *devnm);
 extern int is_standard(char *dev, int *nump);
diff --git a/util.c b/util.c
index 12a19e7a5a3a..e32d97a011e7 100644
--- a/util.c
+++ b/util.c
@@ -1950,3 +1950,17 @@ int in_initrd(void)
 		((unsigned long)s.f_type == TMPFS_MAGIC ||
 		 (unsigned long)s.f_type == RAMFS_MAGIC);
 }
+
+void reopen_mddev(int mdfd)
+{
+	/* Re-open without any O_EXCL, but keep
+	 * the same fd
+	 */
+	char *devnm;
+	int fd;
+	devnm = fd2devnm(mdfd);
+	close(mdfd);
+	fd = open_dev(devnm);
+	if (fd >= 0 && fd != mdfd)
+		dup2(fd, mdfd);
+}
-- 
1.8.3.1.487.g3e7a5b4

openSUSE Build Service is sponsored by