X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;ds=sidebyside;f=mdopen.c;h=eac1c1fcb904edb426b2e7862f26df41a9106311;hb=ae2416e7b6937b9414321c5239e2ad415f7c1988;hp=a37eb9c334b709caae9dd16ae5bec059e573997a;hpb=d7ba0c55f07d24b51e6da1a5850d7164e9cf01d9;p=thirdparty%2Fmdadm.git diff --git a/mdopen.c b/mdopen.c index a37eb9c3..eac1c1fc 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" @@ -43,12 +38,12 @@ void make_parts(char *dev, int cnt) * else that of dev */ struct stat stb; - int major_num = major_num; /* quiet gcc -Os unitialized warning */ - int minor_num = minor_num; /* quiet gcc -Os unitialized warning */ - int odig = odig; /* quiet gcc -Os unitialized warning */ + int major_num; + int minor_num; + int odig; 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]; @@ -57,22 +52,27 @@ void make_parts(char *dev, int cnt) if (cnt==0) cnt=4; if (lstat(dev, &stb)!= 0) return; - if (S_ISLNK(stb.st_mode)) { + + if (S_ISBLK(stb.st_mode)) { + major_num = major(stb.st_rdev); + minor_num = minor(stb.st_rdev); + odig = -1; + } else if (S_ISLNK(stb.st_mode)) { int len = readlink(dev, orig, sizeof(orig)); if (len < 0 || len > 1000) return; orig[len] = 0; odig = isdigit(orig[len-1]); - } else if (S_ISBLK(stb.st_mode)) { - major_num = major(stb.st_rdev); - minor_num = minor(stb.st_rdev); + major_num = -1; + minor_num = -1; } else - return; + return; + name = malloc(nlen); for (i=1; i <= cnt ; i++) { struct stat stb2; snprintf(name, nlen, "%s%s%d", dev, dig?"p":"", i); if (stat(name, &stb2)==0) { - if (!S_ISBLK(stb2.st_mode)) + if (!S_ISBLK(stb2.st_mode) || !S_ISBLK(stb.st_mode)) continue; if (stb2.st_rdev == makedev(major_num, minor_num+i)) continue; @@ -97,6 +97,7 @@ void make_parts(char *dev, int cnt) if (err == 0 && stat(name, &stb2) == 0) add_dev(name, &stb2, 0, NULL); } + free(name); } @@ -161,7 +162,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) { @@ -311,7 +311,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. @@ -360,8 +363,12 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, if (lstat(chosen, &stb) == 0) { char buf[300]; + ssize_t link_len = readlink(chosen, buf, sizeof(buf)-1); + if (link_len >= 0) + buf[link_len] = '\0'; + if ((stb.st_mode & S_IFMT) != S_IFLNK || - readlink(chosen, buf, 300) <0 || + link_len < 0 || strcmp(buf, devname) != 0) { fprintf(stderr, Name ": %s exists - ignoring\n", chosen); @@ -390,6 +397,8 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, int open_mddev(char *dev, int report_errors) { int mdfd = open(dev, O_RDWR); + if (mdfd < 0 && errno == EACCES) + mdfd = open(dev, O_RDONLY); if (mdfd < 0) { if (report_errors) fprintf(stderr, Name ": error opening %s: %s\n",