]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assemble/Incremental: don't hold O_EXCL on mddev after assembly.
authorNeilBrown <neilb@suse.de>
Wed, 4 Dec 2013 23:35:16 +0000 (10:35 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 4 Dec 2013 23:35:16 +0000 (10:35 +1100)
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
Incremental.c
mdadm.h
util.c

index 44e905bb8667a8dbbdce1d9a256efc1c62c50046..7e8e7957035239eae63f20debcf2b615186e0d9c 100644 (file)
@@ -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",
index f548bad9785dbfe5e78ad67cc047ba16750db136..c9372587f518dc57693b1d04d746a723423e57b2 100644 (file)
@@ -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 69facaf329560690bc907311e9de54033f139555..7f222a6d7a78ebbe7611e81955fc50e51ef5edca 100644 (file)
--- 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 12a19e7a5a3ac765bbd088ebc304ebd9bddcaead..e32d97a011e7a791870f1015830a363e19167a0e 100644 (file)
--- 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);
+}