create_mddev: add support for /dev/md_XXX non-numeric names.

With the 'devnm' infrastructure fixed, it is quite easy to support
names like "md_home" for md arrays.
The currently defaults to "off" and can be enabled in mdadm.conf with
  CREATE names=yes
This is incase other tools get confused by the new names.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2013-05-15 11:03:25 +10:00
parent 83785d301f
commit eca944fa9c
6 changed files with 94 additions and 33 deletions

View File

@ -687,6 +687,7 @@ int Create(struct supertype *st, char *mddev,
/* base name on mddev */
/* /dev/md0 -> 0
* /dev/md_d0 -> d0
* /dev/md_foo -> foo
* /dev/md/1 -> 1
* /dev/md/d1 -> d1
* /dev/md/home -> home
@ -696,9 +697,8 @@ int Create(struct supertype *st, char *mddev,
name = strrchr(mddev, '/');
if (name) {
name++;
if (strncmp(name, "md_d", 4)==0 &&
strlen(name) > 4 &&
isdigit(name[4]) &&
if (strncmp(name, "md_", 3)==0 &&
strlen(name) > 3 &&
(name-mddev) == 5 /* /dev/ */)
name += 3;
else if (strncmp(name, "md", 2)==0 &&

View File

@ -219,6 +219,7 @@ struct mddev_dev *load_containers(void)
struct createinfo createinfo = {
.autof = 2, /* by default, create devices with standard names */
.symlinks = 1,
.names = 0, /* By default, stick with numbered md devices. */
#ifdef DEBIAN
.gid = 6, /* disk */
.mode = 0660,
@ -334,6 +335,10 @@ static void createline(char *line)
createinfo.symlinks = 1;
else if (strncasecmp(w, "symlinks=no", 11) == 0)
createinfo.symlinks = 0;
else if (strncasecmp(w, "names=yes", 12) == 0)
createinfo.names = 1;
else if (strncasecmp(w, "names=no", 11) == 0)
createinfo.names = 0;
else {
pr_err("unrecognised word on CREATE line: %s\n",
w);

View File

@ -2957,19 +2957,33 @@ exists or is listed in the config file.
The standard names for non-partitioned arrays (the only sort of md
array available in 2.4 and earlier) are of the form
.IP
/dev/mdNN
.RB /dev/md NN
.PP
where NN is a number.
The standard names for partitionable arrays (as available from 2.6
onwards) are of the form
onwards) are of the form:
.IP
/dev/md_dNN
.RB /dev/md_d NN
.PP
Partition numbers should be indicated by added "pMM" to these, thus "/dev/md/d1p2".
Partition numbers should be indicated by adding "pMM" to these, thus "/dev/md/d1p2".
.PP
From kernel version, 2.6.28 the "non-partitioned array" can actually
be partitioned. So the "md_dNN" names are no longer needed, and
partitions such as "/dev/mdNNpXX" are possible.
From kernel version 2.6.28 the "non-partitioned array" can actually
be partitioned. So the "md_d\fBNN\fP"
names are no longer needed, and
partitions such as "/dev/md\fBNN\fPp\fBXX\fp"
are possible.
.PP
From kernel version 2.6.29 standard names can be non-numeric following
the form:
.IP
.RB /dev/md_ XXX
.PP
where
.B XXX
is any string. These names are supported by
.I mdadm
since version 3.3 provided they are enabled in
.IR mdadm.conf .
.SH NOTE
.I mdadm

View File

@ -148,7 +148,7 @@ created as /dev/mdX, then the minor number X is stored.
The value is a comma separated list of device names or device name
patterns.
Only devices with names which match one entry in the list will be used
to assemble the array. Note that the devices
to assemble the array. Note that the devices
listed there must also be listed on a DEVICE line.
.TP
.B level=
@ -339,6 +339,32 @@ or
Give
.B symlinks=no
to suppress this symlink creation.
.TP
.B names=yes
Since Linux 2.6.29 it has been possible to create
.B md
devices with a name like
.B md_home
rather than just a number, like
.BR md3 .
.I mdadm
will use the numeric alternative by default as other tools that interact
with md arrays may expect only numbers.
If
.B names=yes
is given in
.I mdadm.conf
then
.I mdadm
will use a name when appropriate.
If
.B names=no
is given, then non-numeric
.I md
device names will not be used even if the default changes in a future
release of
.IR mdadm .
.RE
.TP
@ -437,7 +463,7 @@ The known metadata types are
.TP
.B POLICY
This is used to specify what automatic behavior is allowed on devices
This is used to specify what automatic behavior is allowed on devices
newly appearing in the system and provides a way of marking spares that can
be moved to other arrays as well as the migration domains.
.I Domain
@ -475,7 +501,7 @@ file glob matching anything from
.B /dev/disk/by-path
.TP
.B type=
either
either
.B disk
or
.BR part .

View File

@ -257,6 +257,7 @@ struct createinfo {
int autof;
int mode;
int symlinks;
int names;
struct supertype *supertype;
};

View File

@ -126,7 +126,7 @@ void make_parts(char *dev, int cnt)
*
* If udev is configured, we create a temporary device, open it, and
* unlink it.
* If not, we create the /dev/mdXX device, and is name is usable,
* If not, we create the /dev/mdXX device, and if name is usable,
* /dev/md/name
* In any case we return /dev/md/name or (if that isn't available)
* /dev/mdXX in 'chosen'.
@ -260,25 +260,6 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
}
}
if (num < 0) {
/* need to choose a free number. */
char *_devnm = find_free_devnm(use_mdp);
if (devnm == NULL) {
pr_err("No avail md devices - aborting\n");
return -1;
}
strcpy(devnm, _devnm);
} else {
sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
if (mddev_busy(devnm)) {
pr_err("%s is already in use.\n",
dev);
return -1;
}
}
sprintf(devname, "/dev/%s", devnm);
if (cname[0] == 0 && name) {
/* Need to find a name if we can
* We don't completely trust 'name'. Truncate to
@ -323,6 +304,40 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
}
}
devnm[0] = 0;
if (num < 0 && cname && ci->names) {
int fd;
int n = -1;
sprintf(devnm, "md_%s", cname);
fd = open("/sys/module/md_mod/parameters/new_array", O_WRONLY);
if (fd >= 0) {
n = write(fd, devnm, strlen(devnm));
close(fd);
}
if (n < 0)
devnm[0] = 0;
}
if (devnm[0])
;
else if (num < 0) {
/* need to choose a free number. */
char *_devnm = find_free_devnm(use_mdp);
if (devnm == NULL) {
pr_err("No avail md devices - aborting\n");
return -1;
}
strcpy(devnm, _devnm);
} else {
sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
if (mddev_busy(devnm)) {
pr_err("%s is already in use.\n",
dev);
return -1;
}
}
sprintf(devname, "/dev/%s", devnm);
if (dev && dev[0] == '/')
strcpy(chosen, dev);
else if (cname[0] == 0)