From 8832342d3aad09d3c86af6dc9b137d6fd83af1ae Mon Sep 17 00:00:00 2001 From: NeilBrown 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 --- 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 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); +} -- 2.39.2