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

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

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)