]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Merge branch 'master' into devel-3.2
authorNeilBrown <neilb@suse.de>
Thu, 24 Mar 2011 01:00:55 +0000 (12:00 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 24 Mar 2011 01:00:55 +0000 (12:00 +1100)
Conflicts:
Incremental.c
Manage.c
ReadMe.c
inventory
mdadm.8.in
mdadm.spec
mdassemble.8
mdmon.8

1  2 
Manage.c
inventory

diff --combined Manage.c
index 0a966a861ccb5f323e1d2d10eefdee593f890984,3502175dad27d8328eea83d574b4878a9b18a8aa..b7aceaa52be187179ec7cff4ba0d7d9b78482e94
+++ b/Manage.c
@@@ -56,6 -56,7 +56,6 @@@ int Manage_ro(char *devname, int fd, in
        mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
        if (mdi &&
            mdi->array.major_version == -1 &&
 -          mdi->array.level > 0 &&
            is_subarray(mdi->text_version)) {
                char vers[64];
                strcpy(vers, "external:");
@@@ -87,8 -88,6 +87,8 @@@
                        if (*cp)
                                *cp = 0;
                        ping_monitor(vers+10);
 +                      if (mdi->array.level <= 0)
 +                              sysfs_set_str(mdi, NULL, "array_state", "active");
                }
                return 0;
        }
@@@ -224,9 -223,7 +224,9 @@@ int Manage_runstop(char *devname, int f
                                close(fd);
                        fprintf(stderr,
                                Name ": Cannot get exclusive access to %s:"
 -                              " possibly it is still in use.\n",
 +                              "Perhaps a running "
 +                              "process, mounted filesystem "
 +                              "or active volume group?\n",
                                devname);
                        return 1;
                }
                if (mdi &&
                    mdi->array.level > 0 &&
                    is_subarray(mdi->text_version)) {
 +                      int err;
                        /* 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));
 +
 +                      count = 25;
 +                      while (count &&
 +                             (err = sysfs_set_str(mdi, NULL,
 +                                                  "array_state",
 +                                                  "inactive")) < 0
 +                             && errno == EBUSY) {
 +                              usleep(200000);
 +                              count--;
 +                      }
 +                      if (err && !quiet) {
 +                              fprintf(stderr, Name
 +                                      ": failed to stop array %s: %s\n",
 +                                      devname, strerror(errno));
                                return 1;
                        }
  
                 * which blocks STOP_ARRAY is probably a transient use,
                 * so it is reasonable to retry for a while - 5 seconds.
                 */
-               count = 25;
+               count = 25; err = 0;
                while (count && fd >= 0
                       && (err = ioctl(fd, STOP_ARRAY, NULL)) < 0
                       && errno == EBUSY) {
@@@ -370,8 -358,7 +370,8 @@@ int Manage_resize(char *devname, int fd
  }
  
  int Manage_subdevs(char *devname, int fd,
 -                 mddev_dev_t devlist, int verbose, int test)
 +                 struct mddev_dev *devlist, int verbose, int test,
 +                 char *update)
  {
        /* do something to each dev.
         * devmode can be
         * For 'f' and 'r', the device can also be a kernel-internal
         * name such as 'sdb'.
         */
 -      mddev_dev_t add_devlist = NULL;
 +      struct mddev_dev *add_devlist = NULL;
        mdu_array_info_t array;
        mdu_disk_info_t disc;
        unsigned long long array_size;
 -      mddev_dev_t dv, next = NULL;
 +      struct mddev_dev *dv, *next = NULL;
        struct stat stb;
        int j, jnext = 0;
        int tfd = -1;
        struct supertype *st, *tst;
 +      char *subarray = NULL;
        int duuid[4];
        int ouuid[4];
        int lfd = -1;
        if (array_size <= 0)
                array_size = array.size * 2;
  
 -      tst = super_by_fd(fd);
 +      tst = super_by_fd(fd, &subarray);
        if (!tst) {
                fprintf(stderr, Name ": unsupport array - version %d.%d\n",
                        array.major_version, array.minor_version);
                        return 1;
                case 'a':
                        /* add the device */
 -                      if (tst->subarray[0]) {
 +                      if (subarray) {
                                fprintf(stderr, Name ": Cannot add disks to a"
                                        " \'member\' array, perform this"
                                        " operation on the parent container\n");
                                if (tst->sb)
                                        /* already loaded */;
                                else if (tst->ss->external) {
 -                                      tst->ss->load_super(tst, fd, NULL);
 +                                      tst->ss->load_container(tst, fd, NULL);
                                } else for (j = 0; j < tst->max_devs; j++) {
                                        char *dev;
                                        int dfd;
                                /* FIXME this is a bad test to be using */
                                if (!tst->sb) {
                                        close(tfd);
 -                                      fprintf(stderr, Name ": cannot find valid superblock in this array - HELP\n");
 +                                      fprintf(stderr, Name ": cannot load array metadata from %s\n", devname);
                                        return 1;
                                }
  
                                        ;
                                else if (st->sb) {
                                        struct mdinfo mdi;
 -                                      st->ss->getinfo_super(st, &mdi);
 +                                      st->ss->getinfo_super(st, &mdi, NULL);
                                        st->ss->uuid_from_super(st, ouuid);
                                        if ((mdi.disk.state & (1<<MD_DISK_ACTIVE)) &&
                                            !(mdi.disk.state & (1<<MD_DISK_FAULTY)) &&
                                                remove_partitions(tfd);
                                                close(tfd);
                                                tfd = -1;
 +                                              if (update) {
 +                                                      int rv = -1;
 +                                                      tfd = dev_open(dv->devname, O_RDWR);
 +
 +                                                      if (tfd >= 0)
 +                                                              rv = st->ss->update_super(
 +                                                                      st, NULL, update,
 +                                                                      devname, verbose, 0, NULL);
 +                                                      if (rv == 0)
 +                                                              rv = st->ss->store_super(st, tfd);
 +                                                      close(tfd);
 +                                                      tfd = -1;
 +                                                      if (rv != 0) {
 +                                                              fprintf(stderr, Name ": failed to update"
 +                                                                      " superblock during re-add\n");
 +                                                              return 1;
 +                                                      }
 +                                              }
                                                /* don't even try if disk is marked as faulty */
                                                errno = 0;
                                                if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
                                        skip_re_add:
                                                re_add_failed = 1;
                                        }
 +                                      st->ss->free_super(st);
                                }
                                if (add_dev != dv->devname) {
                                        if (verbose > 0)
                                        close(dfd);
                                        return 1;
                                }
 -                              /* write_init_super will close 'dfd' */
 -                              if (tst->ss->write_init_super(tst))
 +                              if (tst->ss->write_init_super(tst)) {
 +                                      close(dfd);
                                        return 1;
 +                              }
                        } else if (dv->re_add) {
                                /*  this had better be raid1.
                                 * As we are "--re-add"ing we must find a spare slot
                        if (dv->writemostly == 1)
                                disc.state |= (1 << MD_DISK_WRITEMOSTLY);
                        if (tst->ss->external) {
 -                              /* add a disk to an external metadata container
 -                               * only if mdmon is around to see it
 -                               */
 +                              /* add a disk
 +                               * to an external metadata container */
                                struct mdinfo new_mdi;
                                struct mdinfo *sra;
                                int container_fd;
                                        fprintf(stderr, Name ": add failed for %s:"
                                                " could not get exclusive access to container\n",
                                                dv->devname);
 -                                      return 1;
 -                              }
 -
 -                              if (!mdmon_running(devnum)) {
 -                                      fprintf(stderr, Name ": add failed for %s: mdmon not running\n",
 -                                              dv->devname);
 -                                      close(container_fd);
 +                                      tst->ss->free_super(tst);
                                        return 1;
                                }
  
                                dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
 +                              if (mdmon_running(tst->container_dev))
 +                                      tst->update_tail = &tst->updates;
                                if (tst->ss->add_to_super(tst, &disc, dfd,
                                                          dv->devname)) {
                                        close(dfd);
                                        close(container_fd);
                                        return 1;
                                }
 -                              close(dfd);
 +                              if (tst->update_tail)
 +                                      flush_metadata_updates(tst);
 +                              else
 +                                      tst->ss->sync_metadata(tst);
  
                                sra = sysfs_read(container_fd, -1, 0);
                                if (!sra) {
                                        fprintf(stderr, Name ": add failed for %s: sysfs_read failed\n",
                                                dv->devname);
                                        close(container_fd);
 +                                      tst->ss->free_super(tst);
                                        return 1;
                                }
                                sra->array.level = LEVEL_CONTAINER;
                                /* Need to set data_offset and component_size */
 -                              tst->ss->getinfo_super(tst, &new_mdi);
 +                              tst->ss->getinfo_super(tst, &new_mdi, NULL);
                                new_mdi.disk.major = disc.major;
                                new_mdi.disk.minor = disc.minor;
                                new_mdi.recovery_start = 0;
 +                              /* Make sure fds are closed as they are O_EXCL which
 +                               * would block add_disk */
 +                              tst->ss->free_super(tst);
                                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);
 +                                      sysfs_free(sra);
                                        return 1;
                                }
 -                              ping_monitor(devnum2devname(devnum));
 +                              ping_monitor_by_id(devnum);
                                sysfs_free(sra);
                                close(container_fd);
 -                      } else if (ioctl(fd, ADD_NEW_DISK, &disc)) {
 -                              fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
 -                                      dv->devname, j, strerror(errno));
 -                              return 1;
 +                      } else {
 +                              tst->ss->free_super(tst);
 +                              if (ioctl(fd, ADD_NEW_DISK, &disc)) {
 +                                      fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
 +                                              dv->devname, j, strerror(errno));
 +                                      return 1;
 +                              }
                        }
                        if (verbose >= 0)
                                fprintf(stderr, Name ": added %s\n", dv->devname);
  
                case 'r':
                        /* hot remove */
 -                      if (tst->subarray[0]) {
 +                      if (subarray) {
                                fprintf(stderr, Name ": Cannot remove disks from a"
                                        " \'member\' array, perform this"
                                        " operation on the parent container\n");
@@@ -1112,14 -1072,22 +1112,14 @@@ int autodetect(void
        return rv;
  }
  
 -int Update_subarray(char *dev, char *subarray, char *update, mddev_ident_t ident, int quiet)
 +int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet)
  {
        struct supertype supertype, *st = &supertype;
        int fd, rv = 2;
  
        memset(st, 0, sizeof(*st));
 -      if (snprintf(st->subarray, sizeof(st->subarray), "%s", subarray) >=
 -          (signed)sizeof(st->subarray)) {
 -              if (!quiet)
 -                      fprintf(stderr,
 -                              Name ": Input overflow for subarray '%s' > %zu bytes\n",
 -                              subarray, sizeof(st->subarray) - 1);
 -              return 2;
 -      }
  
 -      fd = open_subarray(dev, st, quiet);
 +      fd = open_subarray(dev, subarray, st, quiet);
        if (fd < 0)
                return 2;
  
        if (mdmon_running(st->devnum))
                st->update_tail = &st->updates;
  
 -      rv = st->ss->update_subarray(st, update, ident);
 +      rv = st->ss->update_subarray(st, subarray, update, ident);
  
        if (rv) {
                if (!quiet)
  
        return rv;
  }
 +
 +/* Move spare from one array to another
 + * If adding to destination array fails
 + * add back to original array
 + * Returns 1 on success, 0 on failure */
 +int move_spare(char *from_devname, char *to_devname, dev_t devid)
 +{
 +      struct mddev_dev devlist;
 +      char devname[20];
 +
 +      /* try to remove and add */
 +      int fd1 = open(to_devname, O_RDONLY);
 +      int fd2 = open(from_devname, O_RDONLY);
 +
 +      if (fd1 < 0 || fd2 < 0) {
 +              if (fd1>=0) close(fd1);
 +              if (fd2>=0) close(fd2);
 +              return 0;
 +      }
 +
 +      devlist.next = NULL;
 +      devlist.used = 0;
 +      devlist.re_add = 0;
 +      devlist.writemostly = 0;
 +      devlist.devname = devname;
 +      sprintf(devname, "%d:%d", major(devid), minor(devid));
 +
 +      devlist.disposition = 'r';
 +      if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL) == 0) {
 +              devlist.disposition = 'a';
 +              if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL) == 0) {
 +                      /* make sure manager is aware of changes */
 +                      ping_manager(to_devname);
 +                      ping_manager(from_devname);
 +                      close(fd1);
 +                      close(fd2);
 +                      return 1;
 +              }
 +              else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL);
 +      }
 +      close(fd1);
 +      close(fd2);
 +      return 0;
 +}
  #endif
diff --combined inventory
index d960099840ab91f71cf573f7a5d9af0c49870b13,d05eb3c354319e2217ef5254ae882143e47a96ca..d630f7a4284beb2168f89bf5d5faae4c82814cba
+++ b/inventory
@@@ -8,7 -8,7 +8,8 @@@ ANNOUNCE-3.1.
  ANNOUNCE-3.1.2
  ANNOUNCE-3.1.3
  ANNOUNCE-3.1.4
+ ANNOUNCE-3.1.5
 +ANNOUNCE-3.2
  Assemble.c
  bitmap.c
  bitmap.h
@@@ -23,7 -23,6 +24,7 @@@ Detail.
  dlink.c
  dlink.h
  Examine.c
 +external-reshape-design.txt
  .gitignore
  Grow.c
  Incremental.c
@@@ -52,7 -51,6 +53,7 @@@ mdassemble.
  mdassemble.c
  mdmon.8
  mdmon.c
 +mdmon-design.txt
  mdmon.h
  mdopen.c
  md_p.h
@@@ -65,10 -63,8 +66,10 @@@ monitor.
  Monitor.c
  msg.c
  msg.h
 +part.h
  platform-intel.c
  platform-intel.h
 +policy.c
  probe_roms.c
  probe_roms.h
  pwgr.c
@@@ -83,9 -79,7 +84,9 @@@ sha1.
  super0.c
  super1.c
  super-ddf.c
 +super-gpt.c
  super-intel.c
 +super-mbr.c
  swap_super.c
  sysfs.c
  test
@@@ -142,48 -136,12 +143,48 @@@ tests/08imsm-overla
  tests/09imsm-assemble
  tests/09imsm-create-fail-rebuild
  tests/10ddf-create
 +tests/11spare-migration
 +tests/12imsm-r0_2d-grow-r0_3d
 +tests/12imsm-r0_2d-grow-r0_4d
 +tests/12imsm-r0_2d-grow-r0_5d
 +tests/12imsm-r0_3d-grow-r0_4d
 +tests/12imsm-r5_3d-grow-r5_4d
 +tests/12imsm-r5_3d-grow-r5_5d
 +tests/13imsm-r0_r0_2d-grow-r0_r0_4d
 +tests/13imsm-r0_r0_2d-grow-r0_r0_5d
 +tests/13imsm-r0_r0_3d-grow-r0_r0_4d
 +tests/13imsm-r0_r5_3d-grow-r0_r5_4d
 +tests/13imsm-r0_r5_3d-grow-r0_r5_5d
 +tests/13imsm-r5_r0_3d-grow-r5_r0_4d
 +tests/13imsm-r5_r0_3d-grow-r5_r0_5d
 +tests/14imsm-r0_3d_no_spares-migrate-r5_3d
 +tests/14imsm-r0_3d-r5_3d-migrate-r5_4d-r5_4d
 +tests/14imsm-r0_r0_2d-takeover-r10_4d
 +tests/14imsm-r10_4d-grow-r10_5d
 +tests/14imsm-r10_r5_4d-takeover-r0_2d
 +tests/14imsm-r1_2d-grow-r1_3d
 +tests/14imsm-r1_2d-takeover-r0_2d
 +tests/14imsm-r5_3d-grow-r5_5d-no-spares
 +tests/14imsm-r5_3d-migrate-r4_3d
 +tests/15imsm-r0_3d_64k-migrate-r0_3d_256k
 +tests/15imsm-r5_3d_4k-migrate-r5_3d_256k
 +tests/15imsm-r5_3d_64k-migrate-r5_3d_256k
 +tests/15imsm-r5_6d_4k-migrate-r5_6d_256k
 +tests/15imsm-r5_r0_3d_64k-migrate-r5_r0_3d_256k
 +tests/16imsm-r0_3d-migrate-r5_4d
 +tests/16imsm-r0_5d-migrate-r5_6d
 +tests/16imsm-r5_3d-migrate-r0_3d
 +tests/16imsm-r5_5d-migrate-r0_5d
 +tests/18imsm-1d-takeover-r0_1d
 +tests/18imsm-1d-takeover-r1_2d
 +tests/18imsm-r0_2d-takeover-r10_4d
 +tests/18imsm-r10_4d-takeover-r0_2d
  tests/check
 -tests/env-08imsm-overlap
 -tests/env-09imsm-assemble
 -tests/env-09imsm-create-fail-rebuild
 +tests/env-imsm-template
 +tests/imsm-grow-template
  tests/testdev
  tests/ToTest
 +tests/utils
  TODO
  udev-md-raid.rules
  util.c