summaryrefslogtreecommitdiff
path: root/Incremental.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-05-13 12:07:40 +1000
committerNeilBrown <neilb@suse.de>2013-05-13 12:07:40 +1000
commit6b63c1a4570412c06a40ffa57d35577816259a94 (patch)
treeee627c23b6e2a92e5b9761c764f12c6f66d19ae1 /Incremental.c
parent7df8a7b971b3d0dd5b45d646fd601f0acccafabc (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.c23
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,