]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - mdopen.c
2 * mdadm - manage Linux "md" devices aka RAID arrays.
4 * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Email: <neilb@suse.de>
30 void make_parts(char *dev
, int cnt
)
32 /* make 'cnt' partition devices for 'dev'
33 * If dev is a device name we use the
34 * major/minor from dev and add 1..cnt
35 * If it is a symlink, we make similar symlinks.
36 * If dev ends with a digit, we add "p%d" else "%d"
37 * If the name exists, we use it's owner/mode,
45 int nlen
= strlen(dev
) + 20;
47 int dig
= isdigit(dev
[strlen(dev
)-1]);
54 if (lstat(dev
, &stb
)!= 0)
57 if (S_ISBLK(stb
.st_mode
)) {
58 major_num
= major(stb
.st_rdev
);
59 minor_num
= minor(stb
.st_rdev
);
61 } else if (S_ISLNK(stb
.st_mode
)) {
64 len
= readlink(dev
, orig
, sizeof(orig
));
65 if (len
< 0 || len
>= (int)sizeof(orig
))
68 odig
= isdigit(orig
[len
-1]);
74 for (i
= 1; i
<= cnt
; i
++) {
76 snprintf(name
, nlen
, "%s%s%d", dev
, dig
?"p":"", i
);
77 if (stat(name
, &stb2
) == 0) {
78 if (!S_ISBLK(stb2
.st_mode
) || !S_ISBLK(stb
.st_mode
))
80 if (stb2
.st_rdev
== makedev(major_num
, minor_num
+i
))
86 if (S_ISBLK(stb
.st_mode
)) {
87 if (mknod(name
, S_IFBLK
| 0600,
88 makedev(major_num
, minor_num
+i
)))
90 if (chown(name
, stb2
.st_uid
, stb2
.st_gid
))
92 if (chmod(name
, stb2
.st_mode
& 07777))
96 snprintf(sym
, sizeof(sym
), "%s%s%d", orig
, odig
?"p":"", i
);
97 err
= symlink(sym
, name
);
100 if (err
== 0 && stat(name
, &stb2
) == 0)
101 add_dev(name
, &stb2
, 0, NULL
);
106 int create_named_array(char *devnm
)
110 static const char new_array_file
[] = {
111 "/sys/module/md_mod/parameters/new_array"
114 fd
= open(new_array_file
, O_WRONLY
);
115 if (fd
< 0 && errno
== ENOENT
) {
116 if (system("modprobe md_mod") == 0)
117 fd
= open(new_array_file
, O_WRONLY
);
120 n
= write(fd
, devnm
, strlen(devnm
));
123 if (fd
< 0 || n
!= (int)strlen(devnm
)) {
124 pr_err("Fail to create %s when using %s, fallback to creation via node\n",
125 devnm
, new_array_file
);
133 * We need a new md device to assemble/build/create an array.
134 * 'dev' is a name given us by the user (command line or mdadm.conf)
135 * It might start with /dev or /dev/md any might end with a digit
137 * If it starts with just /dev, it must be /dev/mdX or /dev/md_dX
138 * If it ends with a digit string, then it must be as above, or
139 * 'trustworthy' must be 'METADATA' and the 'dev' must be
140 * /dev/md/'name'NN or 'name'NN
141 * If it doesn't end with a digit string, it must be /dev/md/'name'
142 * or 'name' or must be NULL.
143 * If the digit string is present, it gives the minor number to use
144 * If not, we choose a high, unused minor number.
145 * If the 'dev' is a standard name, it devices whether 'md' or 'mdp'.
146 * else if the name is 'd[0-9]+' then we use mdp
147 * else if trustworthy is 'METADATA' we use md
148 * else the choice depends on 'autof'.
149 * If name is NULL it is assumed to match whatever dev provides.
150 * If both name and dev are NULL, we choose a name 'mdXX' or 'mdpXX'
152 * If 'name' is given, and 'trustworthy' is 'foreign' and name is not
153 * supported by 'dev', we add a "_%d" suffix based on the minor number
156 * If udev is configured, we create a temporary device, open it, and
158 * If not, we create the /dev/mdXX device, and if name is usable,
160 * In any case we return /dev/md/name or (if that isn't available)
161 * /dev/mdXX in 'chosen'.
163 * When we create devices, we use uid/gid/umask from config file.
166 int create_mddev(char *dev
, char *name
, int autof
, int trustworthy
,
167 char *chosen
, int block_udev
)
173 struct createinfo
*ci
= conf_get_create_info();
180 if (!udev_is_available())
192 strcpy(chosen
, DEV_MD_DIR
);
193 cname
= chosen
+ strlen(chosen
);
196 if (strncmp(dev
, DEV_MD_DIR
, DEV_MD_DIR_LEN
) == 0) {
197 snprintf(cname
, MD_NAME_MAX
, "%s", dev
+ DEV_MD_DIR_LEN
);
198 } else if (strncmp(dev
, "/dev/", 5) == 0) {
199 char *e
= dev
+ strlen(dev
);
200 while (e
> dev
&& isdigit(e
[-1]))
203 num
= strtoul(e
, NULL
, 10);
204 snprintf(cname
, MD_NAME_MAX
, "%s", dev
+ 5);
205 cname
[e
-(dev
+5)] = 0;
206 /* name *must* be mdXX or md_dXX in this context */
208 (strcmp(cname
, "md") != 0 && strcmp(cname
, "md_d") != 0)) {
209 pr_err("%s is an invalid name for an md device. Try /dev/md/%s\n",
213 if (strcmp(cname
, "md") == 0)
217 /* recreate name: /dev/md/0 or /dev/md/d0 */
218 sprintf(cname
, "%s%d", use_mdp
?"d":"", num
);
222 /* 'cname' must not contain a slash, and may not be
225 if (strchr(cname
, '/') != NULL
) {
226 pr_err("%s is an invalid name for an md device.\n", dev
);
230 pr_err("%s is an invalid name for an md device (empty!).\n", dev
);
234 /* If cname is 'N' or 'dN', we get dev number
242 num
= strtoul(sp
, &ep
, 10);
245 if (ep
== sp
|| *ep
|| num
< 0)
247 else if (cname
[0] == 'd')
254 /* Now determine device number */
255 /* named 'METADATA' cannot use 'mdp'. */
256 if (name
&& name
[0] == 0)
258 if (name
&& trustworthy
== METADATA
&& use_mdp
== 1) {
259 pr_err("%s is not allowed for a %s container. Consider /dev/md%d.\n", dev
, name
, num
);
262 if (name
&& trustworthy
== METADATA
)
265 if (autof
== 4 || autof
== 6)
270 if (num
< 0 && trustworthy
== LOCAL
&& name
) {
271 /* if name is numeric, possibly prefixed by
272 * 'md' or '/dev/md', use that for num
273 * if it is not already in use */
276 if (strncmp(n2
, "/dev/", 5) == 0)
278 if (strncmp(n2
, "md", 2) == 0)
282 num
= strtoul(n2
, &ep
, 10);
286 sprintf(devnm
, "md%s%d", use_mdp
? "_d":"", num
);
287 if (mddev_busy(devnm
))
292 if (cname
[0] == 0 && name
) {
293 /* Need to find a name if we can
294 * We don't completely trust 'name'. Truncate to
295 * reasonable length and remove '/'
298 struct map_ent
*map
= NULL
;
302 strncpy(cname
, name
, 200);
304 for (cp
= cname
; *cp
; cp
++)
315 if (trustworthy
== LOCAL
||
316 (trustworthy
== FOREIGN
&& strchr(cname
, ':') != NULL
)) {
317 /* Only need suffix if there is a conflict */
318 if (map_by_name(&map
, cname
) == NULL
)
321 cnlen
= strlen(cname
);
323 if (trustworthy
== METADATA
&& !isdigit(cname
[cnlen
-1]))
324 sprintf(cname
+cnlen
, "%d", unum
);
326 /* add _%d to FOREIGN array that don't
329 sprintf(cname
+cnlen
, "_%d", unum
);
331 if (map_by_name(&map
, cname
) == NULL
)
337 if (num
< 0 && cname
&& ci
->names
) {
338 sprintf(devnm
, "md_%s", cname
);
341 if (!create_named_array(devnm
)) {
347 sprintf(devnm
, "md%d", num
);
350 if (!create_named_array(devnm
)) {
357 /* need to choose a free number. */
358 char *_devnm
= find_free_devnm(use_mdp
);
359 if (_devnm
== NULL
) {
360 pr_err("No avail md devices - aborting\n");
363 strcpy(devnm
, _devnm
);
365 sprintf(devnm
, "%s%d", use_mdp
?"md_d":"md", num
);
366 if (mddev_busy(devnm
)) {
367 pr_err("%s is already in use.\n",
374 create_named_array(devnm
);
377 sprintf(devname
, "/dev/%s", devnm
);
379 if (dev
&& dev
[0] == '/')
381 else if (cname
[0] == 0)
382 strcpy(chosen
, devname
);
384 /* We have a device number and name.
385 * If we cannot detect udev, we need to make
386 * devices and links ourselves.
388 if (!udev_is_available()) {
389 /* Make sure 'devname' exists and 'chosen' is a symlink to it */
390 if (lstat(devname
, &stb
) == 0) {
391 /* Must be the correct device, else error */
392 if ((stb
.st_mode
&S_IFMT
) != S_IFBLK
||
393 stb
.st_rdev
!= devnm2devid(devnm
)) {
394 pr_err("%s exists but looks wrong, please fix\n",
399 if (mknod(devname
, S_IFBLK
|0600,
400 devnm2devid(devnm
)) != 0) {
401 pr_err("failed to create %s\n",
405 if (chown(devname
, ci
->uid
, ci
->gid
))
407 if (chmod(devname
, ci
->mode
))
410 add_dev(devname
, &stb
, 0, NULL
);
413 make_parts(devname
, parts
);
415 if (strcmp(chosen
, devname
) != 0) {
416 if (mkdir(DEV_NUM_PREF
, 0700) == 0) {
417 if (chown(DEV_NUM_PREF
, ci
->uid
, ci
->gid
))
418 perror("chown " DEV_NUM_PREF
);
419 if (chmod(DEV_NUM_PREF
, ci
->mode
| ((ci
->mode
>> 2) & 0111)))
420 perror("chmod " DEV_NUM_PREF
);
423 if (dev
&& strcmp(chosen
, dev
) == 0)
424 /* We know we are allowed to use this name */
427 if (lstat(chosen
, &stb
) == 0) {
429 ssize_t link_len
= readlink(chosen
, buf
, sizeof(buf
)-1);
431 buf
[link_len
] = '\0';
433 if ((stb
.st_mode
& S_IFMT
) != S_IFLNK
||
435 strcmp(buf
, devname
) != 0) {
436 pr_err("%s exists - ignoring\n",
438 strcpy(chosen
, devname
);
440 } else if (symlink(devname
, chosen
) != 0)
441 pr_err("failed to create %s: %s\n",
442 chosen
, strerror(errno
));
443 if (use_mdp
&& strcmp(chosen
, devname
) != 0)
444 make_parts(chosen
, parts
);
447 mdfd
= open_dev_excl(devnm
);
449 pr_err("unexpected failure opening %s\n",
454 /* Open this and check that it is an md device.
455 * On success, return filedescriptor.
456 * On failure, return -1 if it doesn't exist,
457 * or -2 if it exists but is not an md device.
459 int open_mddev(char *dev
, int report_errors
)
461 int mdfd
= open(dev
, O_RDONLY
);
465 pr_err("error opening %s: %s\n",
466 dev
, strerror(errno
));
470 if (md_array_valid(mdfd
) == 0) {
473 pr_err("%s does not appear to be an md device\n", dev
);
481 * is_mddev() - check that file name passed is an md device.
482 * @dev: file name that has to be checked.
483 * Return: 1 if file passed is an md device, 0 if not.
485 int is_mddev(char *dev
)
487 int fd
= open_mddev(dev
, 1);
497 char *find_free_devnm(int use_partitions
)
499 static char devnm
[32];
501 for (devnum
= 127; devnum
!= 128;
502 devnum
= devnum
? devnum
-1 : (1<<9)-1) {
505 sprintf(devnm
, "md_d%d", devnum
);
507 sprintf(devnm
, "md%d", devnum
);
508 if (mddev_busy(devnm
))
510 if (!conf_name_is_free(devnm
))
512 if (!udev_is_available()) {
513 /* make sure it is new to /dev too, at least as a
515 dev_t devid
= devnm2devid(devnm
);
517 char *dn
= map_dev(major(devid
),
519 if (dn
&& ! is_standard(dn
, NULL
))