X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=mdopen.c;h=21baf5da8bb5532e2eff3f494598758f2624e7c6;hb=df65ac70ca82fb57bac603ac00d39698cb545164;hp=26da33e3e11bb74d7e1c1498c0b7562e5b291c33;hpb=e10a79c344d3e93612b359b526aae47ad02fb446;p=thirdparty%2Fmdadm.git diff --git a/mdopen.c b/mdopen.c index 26da33e3..21baf5da 100644 --- a/mdopen.c +++ b/mdopen.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2006 Neil Brown + * Copyright (C) 2001-2009 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Neil Brown - * Email: - * Paper: Neil Brown - * School of Computer Science and Engineering - * The University of New South Wales - * Sydney, 2052 - * Australia + * Email: */ #include "mdadm.h" @@ -48,14 +43,16 @@ void make_parts(char *dev, int cnt) int odig = odig; /* quiet gcc -Os unitialized warning */ int i; int nlen = strlen(dev) + 20; - char *name = malloc(nlen); + char *name; int dig = isdigit(dev[strlen(dev)-1]); char orig[1024]; char sym[1024]; + int err; if (cnt==0) cnt=4; if (lstat(dev, &stb)!= 0) return; + if (S_ISLNK(stb.st_mode)) { int len = readlink(dev, orig, sizeof(orig)); if (len < 0 || len > 1000) @@ -67,6 +64,7 @@ void make_parts(char *dev, int cnt) minor_num = minor(stb.st_rdev); } else return; + name = malloc(nlen); for (i=1; i <= cnt ; i++) { struct stat stb2; snprintf(name, nlen, "%s%s%d", dev, dig?"p":"", i); @@ -87,13 +85,16 @@ void make_parts(char *dev, int cnt) perror("chown"); if (chmod(name, stb2.st_mode & 07777)) perror("chmod"); + err = 0; } else { snprintf(sym, sizeof(sym), "%s%s%d", orig, odig?"p":"", i); - symlink(sym, name); + err = symlink(sym, name); } - stat(name, &stb2); - add_dev(name, &stb2, 0, NULL); + + if (err == 0 && stat(name, &stb2) == 0) + add_dev(name, &stb2, 0, NULL); } + free(name); } @@ -158,7 +159,6 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, if (dev) { - if (strncmp(dev, "/dev/md/", 8) == 0) { strcpy(cname, dev+8); } else if (strncmp(dev, "/dev/", 5) == 0) { @@ -235,11 +235,19 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, use_mdp = 0; } if (num < 0 && trustworthy == LOCAL && name) { - /* if name is numeric, use that for num + /* if name is numeric, possibly prefixed by + * 'md' or '/dev/md', use that for num * if it is not already in use */ char *ep; - num = strtoul(name, &ep, 10); - if (ep == name || *ep) + char *n2 = name; + if (strncmp(n2, "/dev/", 5) == 0) + n2 += 5; + if (strncmp(n2, "md", 2) == 0) + n2 += 2; + if (*n2 == '/') + n2++; + num = strtoul(n2, &ep, 10); + if (ep == n2 || *ep) num = -1; else if (mddev_busy(use_mdp ? (-1-num) : num)) num = -1; @@ -288,7 +296,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, } cnlen = strlen(cname); while (conflict) { - if (trustworthy == METADATA) + if (trustworthy == METADATA && !isdigit(cname[cnlen-1])) sprintf(cname+cnlen, "%d", unum); else /* add _%d to FOREIGN array that don't @@ -300,7 +308,10 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, conflict = 0; } } - if (cname[0] == 0) + + if (dev && dev[0] == '/') + strcpy(chosen, dev); + else if (cname[0] == 0) strcpy(chosen, devname); /* We have a device number and name. @@ -356,8 +367,9 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, chosen); strcpy(chosen, devname); } - } else - symlink(devname, chosen); + } else if (symlink(devname, chosen) != 0) + fprintf(stderr, Name ": failed to create %s: %s\n", + chosen, strerror(errno)); if (use_mdp && strcmp(chosen, devname) != 0) make_parts(chosen, parts); }