Incremental: improve support for "DEVICE" based restriction in mdadm.conf
--incremental currently fails if the device name passed does not textually match the names permitted by the DEVICE line in mdadm.conf. This is problematic when "mdadm -I" is run by udev as the name given can be a temp name. This patch makes two improvements: 1/ We generate a list of all existing devices that match the names in mdadm.conf, and allow rdev based matching 2/ We allows extra aliases to be provided on the command line, and perform textual matching on those. This is particularly suitable for udev usages as ${DEVLINKS} can be provided even though the links make not yet be created. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
169ffac7ad
commit
b11fe74db0
|
@ -46,7 +46,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
|||
static int Incremental_container(struct supertype *st, char *devname,
|
||||
struct context *c, char *only);
|
||||
|
||||
int Incremental(char *devname, struct context *c,
|
||||
int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||
struct supertype *st)
|
||||
{
|
||||
/* Add this device to an array, creating the array if necessary
|
||||
|
@ -103,6 +103,7 @@ int Incremental(char *devname, struct context *c,
|
|||
struct dev_policy *policy = NULL;
|
||||
struct map_ent target_array;
|
||||
int have_target;
|
||||
char *devname = devlist->devname;
|
||||
|
||||
struct createinfo *ci = conf_get_create_info();
|
||||
|
||||
|
@ -153,7 +154,20 @@ int Incremental(char *devname, struct context *c,
|
|||
|
||||
/* 1/ Check if device is permitted by mdadm.conf */
|
||||
|
||||
if (!conf_test_dev(devname)) {
|
||||
for (;devlist; devlist = devlist->next)
|
||||
if (conf_test_dev(devlist->devname))
|
||||
break;
|
||||
if (!devlist) {
|
||||
devlist = conf_get_devs();
|
||||
for (;devlist; devlist = devlist->next) {
|
||||
struct stat st2;
|
||||
if (stat(devlist->devname, &st2) == 0 &&
|
||||
(st2.st_mode & S_IFMT) == S_IFBLK &&
|
||||
st2.st_rdev == stb.st_rdev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!devlist) {
|
||||
if (c->verbose >= 0)
|
||||
pr_err("%s not permitted by mdadm.conf.\n",
|
||||
devname);
|
||||
|
|
12
mdadm.8.in
12
mdadm.8.in
|
@ -2676,6 +2676,7 @@ Usage:
|
|||
.RB [ \-\-run ]
|
||||
.RB [ \-\-quiet ]
|
||||
.I component-device
|
||||
.RI [ optional-aliases-for-device ]
|
||||
.HP 12
|
||||
Usage:
|
||||
.B mdadm \-\-incremental \-\-fail
|
||||
|
@ -2730,16 +2731,23 @@ That is, is it listed in a
|
|||
.B DEVICES
|
||||
line in that file. If
|
||||
.B DEVICES
|
||||
is absent then the default it to allow any device. Similar if
|
||||
is absent then the default it to allow any device. Similarly if
|
||||
.B DEVICES
|
||||
contains the special word
|
||||
.B partitions
|
||||
then any device is allowed. Otherwise the device name given to
|
||||
.I mdadm
|
||||
.IR mdadm ,
|
||||
or one of the aliases given, or an alias found in the filesystem,
|
||||
must match one of the names or patterns in a
|
||||
.B DEVICES
|
||||
line.
|
||||
|
||||
This is the only context where the aliases are used. They are
|
||||
usually provided by a
|
||||
.I udev
|
||||
rules mentioning
|
||||
.BR ${DEVLINKS} .
|
||||
|
||||
.IP +
|
||||
Does the device have a valid md superblock? If a specific metadata
|
||||
version is requested with
|
||||
|
|
16
mdadm.c
16
mdadm.c
|
@ -1553,16 +1553,16 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (devlist->next) {
|
||||
pr_err("--incremental can only handle one device.\n");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
if (devmode == 'f')
|
||||
if (devmode == 'f') {
|
||||
if (devlist->next) {
|
||||
pr_err("'--incremental --fail' can only handle one device.\n");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
rv = IncrementalRemove(devlist->devname, remove_path,
|
||||
c.verbose);
|
||||
else
|
||||
rv = Incremental(devlist->devname, &c, ss);
|
||||
} else
|
||||
rv = Incremental(devlist, &c, ss);
|
||||
break;
|
||||
case AUTODETECT:
|
||||
autodetect();
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -1235,7 +1235,7 @@ extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev
|
|||
extern int Wait(char *dev);
|
||||
extern int WaitClean(char *dev, int sock, int verbose);
|
||||
|
||||
extern int Incremental(char *devname, struct context *c,
|
||||
extern int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||
struct supertype *st);
|
||||
extern void RebuildMap(void);
|
||||
extern int IncrementalScan(struct context *c, char *devnm);
|
||||
|
|
|
@ -12,7 +12,7 @@ LABEL="md_inc"
|
|||
|
||||
# remember you can limit what gets auto/incrementally assembled by
|
||||
# mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
|
||||
ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot"
|
||||
ACTION=="add", IMPORT{program}="/sbin/mdadm --incremental --export $devnode --offroot ${DEVLINKS}"
|
||||
ACTION=="add", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
|
||||
ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
|
||||
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="/sbin/mdadm -If $name"
|
||||
|
|
Loading…
Reference in New Issue