summaryrefslogtreecommitdiffstats
path: root/Incremental.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-06-30 16:55:17 +1000
committerNeilBrown <neilb@suse.de>2010-06-30 16:55:17 +1000
commit29ba480497f8c45032180d4e358139e134454f4d (patch)
treef7ba9f43d1e2bb1cc25d7720c0d2d3286e8dc95f /Incremental.c
parent98d27e39642cc115729cac20d5394bf820dd9c8e (diff)
downloadmdadm-29ba480497f8c45032180d4e358139e134454f4d.tar.gz
mdadm-29ba480497f8c45032180d4e358139e134454f4d.tar.xz
mdadm-29ba480497f8c45032180d4e358139e134454f4d.zip
Add -fail support to --incremental
This can be used for hot-unplug. When a device has been remove, udev can call mdadm --incremental --fail sda and mdadm will find the array holding sda and remove sda from the array. Based on code from Doug Ledford <dledford@redhat.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r--Incremental.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/Incremental.c b/Incremental.c
index d6dd0f4..a99811d 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -849,3 +849,42 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
map_unlock(&map);
return 0;
}
+
+/*
+ * 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.
+ *
+ * @devname - The device we want to remove
+ *
+ * Note: the device name must be a kernel name like "sda", so
+ * that we can find it in /proc/mdstat
+ */
+int IncrementalRemove(char *devname, int verbose)
+{
+ int mdfd;
+ struct mdstat_ent *ent;
+ struct mddev_dev_s devlist;
+
+ if (strchr(devname, '/')) {
+ fprintf(stderr, Name ": incremental removal requires a "
+ "kernel device name, not a file: %s\n", devname);
+ return 1;
+ }
+ ent = mdstat_by_component(devname);
+ if (!ent) {
+ fprintf(stderr, Name ": %s does not appear to be a component "
+ "of any array\n", devname);
+ return 1;
+ }
+ mdfd = open_dev(ent->devnum);
+ if (mdfd < 0) {
+ fprintf(stderr, Name ": Cannot open array %s!!\n", ent->dev);
+ return 1;
+ }
+ memset(&devlist, 0, sizeof(devlist));
+ devlist.devname = devname;
+ devlist.disposition = 'f';
+ Manage_subdevs(ent->dev, mdfd, &devlist, verbose);
+ devlist.disposition = 'r';
+ return Manage_subdevs(ent->dev, mdfd, &devlist, verbose);
+}