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:
parent
98d27e3964
commit
29ba480497
|
@ -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);
|
||||
}
|
||||
|
|
4
Manage.c
4
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 */
|
||||
|
|
16
ReadMe.c
16
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[] =
|
||||
|
|
24
mdadm.8.in
24
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
|
||||
|
|
12
mdadm.c
12
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;
|
||||
|
|
2
mdadm.h
2
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,
|
||||
|
|
Loading…
Reference in New Issue