summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-12-03 14:01:24 +1100
committerNeilBrown <neilb@suse.de>2013-12-03 14:01:24 +1100
commitb11fe74db0d764c3a245d95bc3651be9bbd59463 (patch)
tree8da452583d18057e67f65462a2e5dec2f4f3dee8
parent169ffac7ad7748c8586fd1d68b7a417d71133140 (diff)
downloadmdadm-b11fe74db0d764c3a245d95bc3651be9bbd59463.tar.gz
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>
-rw-r--r--Incremental.c18
-rw-r--r--mdadm.8.in12
-rw-r--r--mdadm.c16
-rw-r--r--mdadm.h2
-rw-r--r--udev-md-raid-assembly.rules2
5 files changed, 36 insertions, 14 deletions
diff --git a/Incremental.c b/Incremental.c
index 0703dea..f548bad 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -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);
diff --git a/mdadm.8.in b/mdadm.8.in
index f49822e..edbedc4 100644
--- a/mdadm.8.in
+++ b/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
diff --git a/mdadm.c b/mdadm.c
index 359e9f9..f6f5b53 100644
--- a/mdadm.c
+++ b/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();
diff --git a/mdadm.h b/mdadm.h
index c38fdfb..69facaf 100644
--- a/mdadm.h
+++ b/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);
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index 72bbed4..a668e16 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -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"