summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Incremental.c39
-rw-r--r--Manage.c4
-rw-r--r--ReadMe.c16
-rw-r--r--mdadm.8.in24
-rw-r--r--mdadm.c12
-rw-r--r--mdadm.h2
6 files changed, 88 insertions, 9 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);
+}
diff --git a/Manage.c b/Manage.c
index b2ea976..6bc5d0a 100644
--- a/Manage.c
+++ b/Manage.c
@@ -892,8 +892,8 @@ int Manage_subdevs(char *devname, int fd,
if (lfd >= 0)
close(lfd);
if (verbose >= 0)
- fprintf(stderr, Name ": hot removed %s\n",
- dnprintable);
+ fprintf(stderr, Name ": hot removed %s from %s\n",
+ dnprintable, devname);
break;
case 'f': /* set faulty */
diff --git a/ReadMe.c b/ReadMe.c
index a3f556a..4ade87e 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -213,7 +213,7 @@ char Help[] =
" mdadm --grow options device\n"
" resize/reshape an active array\n"
" mdadm --incremental device\n"
-" add a device to an array as appropriate\n"
+" add/remove a device to/from an array as appropriate\n"
" mdadm --monitor options...\n"
" Monitor one or more array for significant changes.\n"
" mdadm device options...\n"
@@ -256,7 +256,7 @@ char OptionHelp[] =
" --examine-bitmap -X: Display the detail of a bitmap file\n"
" --monitor -F : monitor (follow) some arrays\n"
" --grow -G : resize/ reshape and array\n"
-" --incremental -I : add a single device to an array as appropriate\n"
+" --incremental -I : add/remove a single device to/from an array as appropriate\n"
" --query -Q : Display general information about how a\n"
" device relates to the md driver\n"
" --auto-detect : Start arrays auto-detected by the kernel\n"
@@ -535,20 +535,26 @@ char Help_grow[] =
;
char Help_incr[] =
-"Usage: mdadm --incremental [-Rqrs] device\n"
+"Usage: mdadm --incremental [-Rqrsf] device\n"
"\n"
"This usage allows for incremental assembly of md arrays. Devices can be\n"
"added one at a time as they are discovered. Once an array has all expected\n"
"devices, it will be started.\n"
"\n"
-"Options that are valid with incremental assembly (-I --incremental) more are:\n"
-" --run -R : run arrays as soon as a minimal number of devices are\n"
+"Optionally, the process can be reversed by using the fail option.\n"
+"When fail mode is invoked, mdadm will see if the device belongs to an array\n"
+"and then both fail (if needed) and remove the device from that array.\n"
+"\n"
+"Options that are valid with incremental assembly (-I --incremental) are:\n"
+" --run -R : Run arrays as soon as a minimal number of devices are\n"
" : present rather than waiting for all expected.\n"
" --quiet -q : Don't print any information messages, just errors.\n"
" --rebuild-map -r : Rebuild the 'map' file that mdadm uses for tracking\n"
" : partial arrays.\n"
" --scan -s : Use with -R to start any arrays that have the minimal\n"
" : required number of devices, but are not yet started.\n"
+" --fail -f : First fail (if needed) and then remove device from\n"
+" : any array that it is a member of.\n"
;
char Help_config[] =
diff --git a/mdadm.8.in b/mdadm.8.in
index e5cc89e..f6f6b75 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -136,6 +136,10 @@ This provides a convenient interface to a
system. As each device is detected,
.I mdadm
has a chance to include it in some array as appropriate.
+Optionally, when the
+.I \-\-fail
+flag is passed in we will remove the device from any active array
+instead of adding it.
If a
.B CONTAINER
@@ -189,7 +193,7 @@ Change the size or shape of an active array.
.TP
.BR \-I ", " \-\-incremental
-Add a single device into an appropriate array, and possibly start the array.
+Add/remove a single device to/from an appropriate array, and possibly start the array.
.TP
.B \-\-auto-detect
@@ -1239,6 +1243,15 @@ in
.B mdadm.conf
as requiring an external bitmap, that bitmap will be attached first.
+.TP
+.BR \-\-fail ", " \-f
+This allows the hot-plug system to remove devices that have fully disappeared
+from the kernel. It will first fail and then remove the device from any
+array it belongs to.
+The device name given should be a kernel device name such as "sda",
+not a name in
+.IR /dev .
+
.SH For Monitor mode:
.TP
.BR \-m ", " \-\-mail
@@ -2145,6 +2158,10 @@ Usage:
.I component-device
.HP 12
Usage:
+.B mdadm \-\-incremental \-\-fail
+.I component-device
+.HP 12
+Usage:
.B mdadm \-\-incremental \-\-rebuild\-map
.HP 12
Usage:
@@ -2157,6 +2174,11 @@ passed to
.B "mdadm \-\-incremental"
to be conditionally added to an appropriate array.
+Conversely, it can also be used with the
+.B \-\-fail
+flag to do just the opposite and find whatever array a particular device
+is part of and remove the device from that array.
+
If the device passed is a
.B CONTAINER
device created by a previous call to
diff --git a/mdadm.c b/mdadm.c
index a401be2..770fdfd 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -773,6 +773,9 @@ int main(int argc, char *argv[])
devmode = 'r';
continue;
case O(MANAGE,'f'): /* set faulty */
+ case O(INCREMENTAL,'f'): /* r for incremental is taken, use f
+ * even though we will both fail and
+ * remove the device */
devmode = 'f';
continue;
case O(INCREMENTAL,'R'):
@@ -1516,6 +1519,11 @@ int main(int argc, char *argv[])
": --incremental --scan meaningless without --run.\n");
break;
}
+ if (devmode == 'f') {
+ fprintf(stderr, Name
+ ": --incremental --scan --fail not supported.\n");
+ break;
+ }
rv = IncrementalScan(verbose);
}
if (!devlist) {
@@ -1532,6 +1540,10 @@ int main(int argc, char *argv[])
rv = 1;
break;
}
+ if (devmode == 'f') {
+ rv = IncrementalRemove(devlist->devname, verbose-quiet);
+ break;
+ }
rv = Incremental(devlist->devname, verbose-quiet, runstop,
ss, homehost, require_homehost, autof);
break;
diff --git a/mdadm.h b/mdadm.h
index cdf6acb..d15e73e 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -823,7 +823,7 @@ extern int Incremental_container(struct supertype *st, char *devname,
int trustworthy);
extern void RebuildMap(void);
extern int IncrementalScan(int verbose);
-
+extern int IncrementalRemove(char *devname, int verbose);
extern int CreateBitmap(char *filename, int force, char uuid[16],
unsigned long chunksize, unsigned long daemon_sleep,
unsigned long write_behind,