X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Manage.c;h=3aa09bcba241caba52b989abd6804de9e65a056e;hp=f2b32662ede7d1dd69de30e654cebf158beab08e;hb=aae5a11207cf6da1682e6a76e116a19e21473f03;hpb=6c40598f598874d1d4c2c4d0da0c2a9b873d768d diff --git a/Manage.c b/Manage.c index f2b32662..3aa09bcb 100644 --- a/Manage.c +++ b/Manage.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" @@ -446,11 +441,15 @@ int Manage_subdevs(char *devname, int fd, } else { j = 0; - if (stat(dv->devname, &stb)) { + tfd = dev_open(dv->devname, O_RDONLY); + if (tfd < 0 || fstat(tfd, &stb) != 0) { fprintf(stderr, Name ": cannot find %s: %s\n", dv->devname, strerror(errno)); + if (tfd >= 0) + close(tfd); return 1; } + close(tfd); if ((stb.st_mode & S_IFMT) != S_IFBLK) { fprintf(stderr, Name ": %s is not a " "block device.\n", @@ -472,7 +471,7 @@ int Manage_subdevs(char *devname, int fd, return 1; } /* Make sure it isn't in use (in 2.6 or later) */ - tfd = open(dv->devname, O_RDONLY|O_EXCL|O_DIRECT); + tfd = dev_open(dv->devname, O_RDONLY|O_EXCL|O_DIRECT); if (tfd < 0) { fprintf(stderr, Name ": Cannot open %s: %s\n", dv->devname, strerror(errno)); @@ -588,6 +587,11 @@ int Manage_subdevs(char *devname, int fd, fprintf(stderr, Name ": re-added %s\n", dv->devname); continue; } + if (errno == ENOMEM || errno == EROFS) { + fprintf(stderr, Name ": add new device failed for %s: %s\n", + dv->devname, strerror(errno)); + return 1; + } /* fall back on normal-add */ } } @@ -623,7 +627,7 @@ int Manage_subdevs(char *devname, int fd, int dfd; if (dv->writemostly == 1) disc.state |= 1 << MD_DISK_WRITEMOSTLY; - dfd = open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); + dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); if (tst->ss->add_to_super(tst, &disc, dfd, dv->devname)) { close(dfd); @@ -702,7 +706,7 @@ int Manage_subdevs(char *devname, int fd, tst->ss->getinfo_super(tst, &new_mdi); new_mdi.disk.major = disc.major; new_mdi.disk.minor = disc.minor; - if (sysfs_add_disk(sra, &new_mdi) != 0) { + if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { fprintf(stderr, Name ": add new device to external metadata" " failed for %s\n", dv->devname); close(container_fd); @@ -746,7 +750,14 @@ int Manage_subdevs(char *devname, int fd, " to container - odd\n"); return 1; } - if (!sysfs_unique_holder(dnum, stb.st_rdev)) { + /* in the detached case it is not possible to + * check if we are the unique holder, so just + * rely on the 'detached' checks + */ + if (strcmp(dv->devname, "detached") == 0 || + sysfs_unique_holder(dnum, stb.st_rdev)) + /* pass */; + else { fprintf(stderr, Name ": %s is %s, cannot remove.\n", dnprintable,