]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Allow --update=devicesize with --re-add
authorNeilBrown <neilb@suse.de>
Thu, 9 Dec 2010 02:06:29 +0000 (13:06 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 9 Dec 2010 02:06:29 +0000 (13:06 +1100)
This is useful with 1.1 and 1.2 metadata to update the metadata if
the device size has changed.
The same functionality can be achieved by writing to the device size
in sysfs after re-adding normally, but in some cases this might be
easier.

Signed-off-by: NeilBrown <neilb@suse.de>
Incremental.c
Manage.c
Monitor.c
mdadm.8.in
mdadm.c
mdadm.h

index 9399f5bec27f6f35356c8abe0df009f9d57e9c83..bc4531a58faff5bea2ec2334ae8b8c4815290891 100644 (file)
@@ -980,7 +980,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
                        close(dfd);
                        *dfdp = -1;
                        rv =  Manage_subdevs(chosen->sys_name, mdfd, &devlist,
-                                            -1, 0);
+                                            -1, 0, NULL);
                        close(mdfd);
                }
                if (verbose > 0) {
@@ -1549,15 +1549,16 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
                                int subfd = open_dev(memb->devnum);
                                if (subfd >= 0) {
                                        Manage_subdevs(memb->dev, subfd,
-                                                      &devlist, verbose, 0);
+                                                      &devlist, verbose, 0,
+                                                      NULL);
                                        close(subfd);
                                }
                        }
                free_mdstat(mdstat);
        } else
-               Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
+               Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL);
        devlist.disposition = 'r';
-       rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
+       rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL);
        close(mdfd);
        free_mdstat(ent);
        return rv;
index a203ec9b90062f7ca78b847cd4cfffb10ea684a8..81fa986d770c2f8ee201b61b90944c62390db624 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -325,7 +325,8 @@ int Manage_resize(char *devname, int fd, long long size, int raid_disks)
 }
 
 int Manage_subdevs(char *devname, int fd,
-                  struct mddev_dev *devlist, int verbose, int test)
+                  struct mddev_dev *devlist, int verbose, int test,
+                  char *update)
 {
        /* do something to each dev.
         * devmode can be
@@ -691,6 +692,24 @@ int Manage_subdevs(char *devname, int fd,
                                                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 = tst->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) {
index 61550ee00b83cd1dc77c5302321e2b3433d7f8ef..af701939d12a1794201607886edbaa59dca05e00 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -739,9 +739,9 @@ static int move_spare(struct state *from, struct state *to,
        sprintf(devname, "%d:%d", major(devid), minor(devid));
 
        devlist.disposition = 'r';
-       if (Manage_subdevs(from->devname, fd2, &devlist, -1, 0) == 0) {
+       if (Manage_subdevs(from->devname, fd2, &devlist, -1, 0, NULL) == 0) {
                devlist.disposition = 'a';
-               if (Manage_subdevs(to->devname, fd1, &devlist, -1, 0) == 0) {
+               if (Manage_subdevs(to->devname, fd1, &devlist, -1, 0, NULL) == 0) {
                        alert("MoveSpare", to->devname, from->devname, info);
                        /* make sure we will see newly added spare before next
                         * time through loop
@@ -752,7 +752,7 @@ static int move_spare(struct state *from, struct state *to,
                        close(fd2);
                        return 1;
                }
-               else Manage_subdevs(from->devname, fd2, &devlist, -1, 0);
+               else Manage_subdevs(from->devname, fd2, &devlist, -1, 0, NULL);
        }
        close(fd1);
        close(fd2);
index fed5b62802eaa2351f72f97e29c944f36285179f..ac87b47b6dac52fccbadac44afd500954107c72c 100644 (file)
@@ -1053,7 +1053,7 @@ will report failure if these specifiers didn't find any match.
 .BR \-a ", " \-\-add
 hot-add listed devices.
 If a device appears to have recently been part of the array
-(possibly it failed or was removed) the device is re-added as describe
+(possibly it failed or was removed) the device is re\-added as describe
 in the next point.
 If that fails or the device was never part of the array, the device is
 added as a hot-spare.
@@ -1079,6 +1079,13 @@ When used on an array that has no metadata (i.e. it was built with
 it will be assumed that bitmap-based recovery is enough to make the
 device fully consistent with the array.
 
+When
+.B \-\-re\-add
+can be accompanied by
+.BR \-\-update=devicesize .
+See the description of this option when used in Assemble mode for an
+explanation of its use.
+
 If the device name given is
 .B missing
 then mdadm will try to find any device that looks like it should be
diff --git a/mdadm.c b/mdadm.c
index dd5311d5912c7a503452b33f36aaf8d6cc70ee9e..2ffe94f7c6c7c30bdec788f1d5ec6900124bfb22 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -666,12 +666,14 @@ int main(int argc, char *argv[])
                case O(ASSEMBLE,'U'): /* update the superblock */
                case O(MISC,'U'):
                        if (update) {
-                               fprintf(stderr, Name ": Can only update one aspect of superblock, both %s and %s given.\n",
+                               fprintf(stderr, Name ": Can only update one aspect"
+                                       " of superblock, both %s and %s given.\n",
                                        update, optarg);
                                exit(2);
                        }
                        if (mode == MISC && !subarray) {
-                               fprintf(stderr, Name ": Only subarrays can be updated in misc mode\n");
+                               fprintf(stderr, Name ": Only subarrays can be"
+                                       " updated in misc mode\n");
                                exit(2);
                        }
                        update = optarg;
@@ -695,13 +697,17 @@ int main(int argc, char *argv[])
                                continue;
                        if (strcmp(update, "byteorder")==0) {
                                if (ss) {
-                                       fprintf(stderr, Name ": must not set metadata type with --update=byteorder.\n");
+                                       fprintf(stderr,
+                                               Name ": must not set metadata"
+                                               " type with --update=byteorder.\n");
                                        exit(2);
                                }
                                for(i=0; !ss && superlist[i]; i++)
-                                       ss = superlist[i]->match_metadata_desc("0.swap");
+                                       ss = superlist[i]->match_metadata_desc(
+                                               "0.swap");
                                if (!ss) {
-                                       fprintf(stderr, Name ": INTERNAL ERROR cannot find 0.swap\n");
+                                       fprintf(stderr, Name ": INTERNAL ERROR"
+                                               " cannot find 0.swap\n");
                                        exit(2);
                                }
 
@@ -723,6 +729,27 @@ int main(int argc, char *argv[])
                "     'no-bitmap'\n");
                        exit(outf == stdout ? 0 : 2);
 
+               case O(MANAGE,'U'):
+                       /* update=devicesize is allowed with --re-add */
+                       if (devmode != 'a' || re_add != 1) {
+                               fprintf(stderr, Name "--update in Manage mode only"
+                                       " allowed with --re-add.\n");
+                               exit(1);
+                       }
+                       if (update) {
+                               fprintf(stderr, Name ": Can only update one aspect"
+                                       " of superblock, both %s and %s given.\n",
+                                       update, optarg);
+                               exit(2);
+                       }
+                       update = optarg;
+                       if (strcmp(update, "devicesize") != 0) {
+                               fprintf(stderr, Name ": only 'devicesize' can be"
+                                       " updated with --re-add\n");
+                               exit(2);
+                       }
+                       continue;
+
                case O(INCREMENTAL,NoDegraded):
                        fprintf(stderr, Name ": --no-degraded is deprecated in Incremental mode\n");
                case O(ASSEMBLE,NoDegraded): /* --no-degraded */
@@ -1153,7 +1180,8 @@ int main(int argc, char *argv[])
                        rv = Manage_ro(devlist->devname, mdfd, readonly);
                if (!rv && devs_found>1)
                        rv = Manage_subdevs(devlist->devname, mdfd,
-                                           devlist->next, verbose-quiet, test);
+                                           devlist->next, verbose-quiet, test,
+                                           update);
                if (!rv && readonly < 0)
                        rv = Manage_ro(devlist->devname, mdfd, readonly);
                if (!rv && runstop)
diff --git a/mdadm.h b/mdadm.h
index 8e2c23146c33c7c6864a9e04a3defb319ae5d702..a5d94d7195ee1c2fe34b7b8748264ab28d396e33 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -959,7 +959,8 @@ extern int Manage_ro(char *devname, int fd, int readonly);
 extern int Manage_runstop(char *devname, int fd, int runstop, int quiet);
 extern int Manage_resize(char *devname, int fd, long long size, int raid_disks);
 extern int Manage_subdevs(char *devname, int fd,
-                         struct mddev_dev *devlist, int verbose, int test);
+                         struct mddev_dev *devlist, int verbose, int test,
+                         char *update);
 extern int autodetect(void);
 extern int Grow_Add_device(char *devname, int fd, char *newdev);
 extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force);