summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c1
-rw-r--r--Incremental.c10
-rw-r--r--mdadm.h1
-rw-r--r--util.c14
4 files changed, 23 insertions, 3 deletions
diff --git a/Assemble.c b/Assemble.c
index 44e905bb..7e8e7957 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 f548bad9..c9372587 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 69facaf3..7f222a6d 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 12a19e7a..e32d97a0 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);
+}