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>
This commit is contained in:
NeilBrown 2010-06-30 16:55:17 +10:00
parent 98d27e3964
commit 29ba480497
6 changed files with 88 additions and 9 deletions

View File

@ -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);
}

View File

@ -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 */

View File

@ -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[] =

View File

@ -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

12
mdadm.c
View File

@ -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;

View File

@ -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,