diff options
author | NeilBrown <neilb@suse.de> | 2013-05-13 12:07:40 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-05-13 12:07:40 +1000 |
commit | 6b63c1a4570412c06a40ffa57d35577816259a94 (patch) | |
tree | ee627c23b6e2a92e5b9761c764f12c6f66d19ae1 /Incremental.c | |
parent | 7df8a7b971b3d0dd5b45d646fd601f0acccafabc (diff) |
Incrmental: tell udevs to unmount when array looks to have disappeared.
If a device is removed which appears to be busy in an md array, then
it is very like the array cannot be used.
We currently try to stop it, but that could fail if udisks had
automatically mounted it.
So tell udisks to unmount it, but ignore any error.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r-- | Incremental.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/Incremental.c b/Incremental.c index 1b7ebfaf..d5656ccd 100644 --- a/Incremental.c +++ b/Incremental.c @@ -29,6 +29,7 @@ */ #include "mdadm.h" +#include <sys/wait.h> #include <dirent.h> #include <ctype.h> @@ -1565,6 +1566,19 @@ static int Incremental_container(struct supertype *st, char *devname, return 0; } +static void run_udisks(char *arg1, char *arg2) +{ + int pid = fork(); + int status; + if (pid == 0) { + execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); + execl("/bin/udisks", "udisks", arg1, arg2, NULL); + exit(1); + } + while (pid > 0 && wait(&status) != pid) + ; +} + /* * IncrementalRemove - Attempt to see if the passed in device belongs to any * raid arrays, and if so first fail (if needed) and then remove the device. @@ -1647,13 +1661,20 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) rv |= Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL, 0); if (rv & 2) { - /* Failed due to EBUSY, try to stop the array + /* Failed due to EBUSY, try to stop the array. + * Give udisks a chance to unmount it first. */ + int devid = devnm2devid(ent->devnm); + run_udisks("--unmount", map_dev(major(devid),minor(devid), 0)); rv = Manage_runstop(ent->dev, mdfd, -1, verbose, 1); if (rv) /* At least we can try to trigger a 'remove' */ sysfs_uevent(&mdi, "remove"); + if (verbose) { + if (rv) + pr_err("Fail to stop %s too.\n", ent->devnm); + } } else { devlist.disposition = 'r'; rv = Manage_subdevs(ent->dev, mdfd, &devlist, |