Merge branch 'master' into from-stable
authorNeilBrown <neilb@suse.de>
Thu, 7 Aug 2008 04:12:25 +0000 (14:12 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 7 Aug 2008 04:12:25 +0000 (14:12 +1000)
Conflicts:

Create.c
Manage.c

1  2 
Create.c
Grow.c
Makefile
Manage.c
Query.c
ReadMe.c
md.4
mdadm.8
mdadm.c
test

diff --cc Create.c
+++ b/Create.c
@@@ -130,42 -116,6 +130,42 @@@ int Create(struct supertype *st, char *
                        Name ": This level does not support spare devices\n");
                return 1;
        }
-               fd = open(devlist->devname, O_RDONLY, 0);
 +
 +      if (subdevs == 1 && strcmp(devlist->devname, "missing") != 0) {
 +              /* If given a single device, it might be a container, and we can
 +               * extract a device list from there
 +               */
 +              mdu_array_info_t inf;
 +              int fd;
 +
 +              memset(&inf, 0, sizeof(inf));
++              fd = open(devlist->devname, O_RDONLY);
 +              if (fd >= 0 &&
 +                  ioctl(fd, GET_ARRAY_INFO, &inf) == 0 &&
 +                  inf.raid_disks == 0) {
 +                      /* yep, looks like a container */
 +                      if (st) {
 +                              rv = st->ss->load_super(st, fd,
 +                                                      devlist->devname);
 +                              if (rv == 0)
 +                                      have_container = 1;
 +                      } else {
 +                              st = guess_super(fd);
 +                              if (st && !(rv = st->ss->
 +                                          load_super(st, fd,
 +                                                     devlist->devname)))
 +                                      have_container = 1;
 +                              else
 +                                      st = NULL;
 +                      }
 +              }
 +              if (fd >= 0)
 +                      close(fd);
 +              if (have_container) {
 +                      subdevs = 0;
 +                      devlist = NULL;
 +              }
 +      }
        if (subdevs > raiddisks+sparedisks) {
                fprintf(stderr, Name ": You have listed more devices (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
                return 1;
                        minsize = freesize;
                }
                if (runstop != 1 || verbose >= 0) {
-                       int fd = open(dname, O_RDONLY, 0);
++                      int fd = open(dname, O_RDONLY);
 +                      if (fd <0 ) {
 +                              fprintf(stderr, Name ": Cannot open %s: %s\n",
 +                                      dname, strerror(errno));
 +                              fail=1;
 +                              continue;
 +                      }
                        warn |= check_ext2(fd, dname);
                        warn |= check_reiser(fd, dname);
                        warn |= check_raid(fd, dname);
                        if (dnum == insert_point) {
                                moved_disk = dv;
                        }
 -                      info.disk.raid_disk = info.disk.number;
 -                      if (info.disk.raid_disk < raiddisks)
 -                              info.disk.state = (1<<MD_DISK_ACTIVE) |
 +                      if (dnum == insert_point ||
 +                          strcasecmp(dv->devname, "missing")==0)
 +                              continue;
 +
 +                      switch(pass) {
 +                      case 1:
 +                              *inf = info;
 +
 +                              inf->disk.number = dnum;
 +                              inf->disk.raid_disk = dnum;
 +                              if (inf->disk.raid_disk < raiddisks)
 +                                      inf->disk.state = (1<<MD_DISK_ACTIVE) |
                                                (1<<MD_DISK_SYNC);
 -                      else
 -                              info.disk.state = 0;
 -                      if (dv->writemostly)
 -                              info.disk.state |= (1<<MD_DISK_WRITEMOSTLY);
 +                              else
 +                                      inf->disk.state = 0;
 +
 +                              if (dv->writemostly)
 +                                      inf->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
 +
 +                              if (st->ss->external && st->subarray[0])
-                                       fd = open(dv->devname, O_RDWR, 0);
++                                      fd = open(dv->devname, O_RDWR);
 +                              else
-                                       fd = open(dv->devname, O_RDWR|O_EXCL,0);
++                                      fd = open(dv->devname, O_RDWR|O_EXCL);
  
 -                      if (dnum == insert_point ||
 -                          strcasecmp(dv->devname, "missing")==0) {
 -                              info.disk.major = 0;
 -                              info.disk.minor = 0;
 -                              info.disk.state = (1<<MD_DISK_FAULTY);
 -                      } else {
 -                              fd = open(dv->devname, O_RDONLY|O_EXCL);
                                if (fd < 0) {
 -                                      fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n",
 +                                      fprintf(stderr, Name ": failed to open %s "
 +                                              "after earlier success - aborting\n",
                                                dv->devname);
                                        return 1;
                                }
diff --cc Grow.c
Simple merge
diff --cc Makefile
Simple merge
diff --cc Manage.c
+++ b/Manage.c
@@@ -116,58 -111,20 +116,63 @@@ int Manage_runstop(char *devname, int f
        } else if (runstop < 0){
                struct map_ent *map = NULL;
                struct stat stb;
 -              if (ioctl(fd, STOP_ARRAY, NULL)) {
 -                      if (quiet==0) {
 -                              fprintf(stderr, Name ": fail to stop array %s: %s\n",
 +              struct mdinfo *mdi;
 +              /* If this is an mdmon managed array, just write 'inactive'
 +               * to the array state and let mdmon clear up.
 +               */
 +              mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
 +              if (mdi &&
 +                  mdi->array.level > 0 &&
 +                  mdi->text_version[0] == '/') {
 +                      char *cp;
 +
 +                      /* This is mdmon managed. */
 +                      close(fd);
 +                      if (sysfs_set_str(mdi, NULL,
 +                                        "array_state", "inactive") < 0) {
 +                              if (quiet == 0)
 +                                      fprintf(stderr, Name
 +                                              ": failed to stop array %s: %s\n",
 +                                              devname, strerror(errno));
 +                              return 1;
 +                      }
 +
 +                      /* Give monitor a chance to act */
 +                      cp = strchr(mdi->text_version+1, '/');
 +                      if (*cp)
 +                              *cp = 0;
 +                      ping_monitor(mdi->text_version+1);
 +
 +                      fd = open(devname, O_RDONLY);
 +              } else if (mdi &&
 +                         mdi->array.major_version == -1 &&
 +                         mdi->array.minor_version == -2 &&
 +                         mdi->text_version[0] != '/') {
 +                      /* container, possibly mdmon-managed.
 +                       * Make sure mdmon isn't opening it, which
 +                       * would interfere with the 'stop'
 +                       */
 +                      ping_monitor(mdi->sys_name);
 +              }
 +              if (mdi)
 +                      sysfs_free(mdi);
 +
 +              if (fd >= 0 && ioctl(fd, STOP_ARRAY, NULL)) {
-                       if (quiet == 0)
++                      if (quiet == 0) {
 +                              fprintf(stderr, Name
 +                                      ": failed to stop array %s: %s\n",
                                        devname, strerror(errno));
+                               if (errno == EBUSY)
+                                       fprintf(stderr, "Perhaps a running "
+                                               "process, mounted filesystem "
+                                               "or active volume group?\n");
+                       }
                        return 1;
                }
 +
                if (quiet <= 0)
                        fprintf(stderr, Name ": stopped %s\n", devname);
 -              if (fstat(fd, &stb) == 0) {
 +              if (fd >= 0 && fstat(fd, &stb) == 0) {
                        int devnum;
                        if (major(stb.st_rdev) == MD_MAJOR)
                                devnum = minor(stb.st_rdev);
diff --cc Query.c
Simple merge
diff --cc ReadMe.c
Simple merge
diff --cc md.4
Simple merge
diff --cc mdadm.8
Simple merge
diff --cc mdadm.c
Simple merge
diff --cc test
Simple merge