]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Factor out add-disk code
authorNeilBrown <neilb@suse.de>
Thu, 18 Sep 2008 05:13:32 +0000 (15:13 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 18 Sep 2008 05:13:32 +0000 (15:13 +1000)
The variety of approaches to 'add_disk' are factored out into
a separate function, and Incremental mode benefits by being
closer to supporting the assembly of containers.

Also remove the adding-to-array-data-structure out of sysfs_add_disk
and into add_disk.

And add some tests for --incremental mode to make sure we don't break it.

Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Create.c
Incremental.c
managemon.c
mdadm.h
super-intel.c
sysfs.c
test
tests/03r0assem
tests/03r5assemV1
util.c

index 34d046d679008a11c3143b9a902b13a3589f73e6..1f41369a8512acb5bf1d18748337d184f1ba343b 100644 (file)
@@ -844,10 +844,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
 
        /* Almost ready to actually *do* something */
        if (!old_linux) {
+               struct mdinfo *sra = NULL;
                int rv;
 
 #ifndef MDASSEMBLE
-               struct mdinfo *sra = NULL;
                if (st->ss->external) {
                        char ver[100];
                        strcat(strcpy(ver, "external:"), info.text_version);
@@ -913,13 +913,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                j = chosen_drive;
 
                        if (j >= 0 /* && devices[j].uptodate */) {
-#ifndef MDASSEMBLE
-                               if (st->ss->external)
-                                       rv = sysfs_add_disk(sra, &devices[j].i);
-                               else
-#endif
-                                       rv = ioctl(mdfd, ADD_NEW_DISK,
-                                         &devices[j].i.disk);
+                               rv = add_disk(mdfd, st, sra, &devices[j].i);
+
                                if (rv) {
                                        fprintf(stderr, Name ": failed to add "
                                                        "%s to %s: %s\n",
index 48d811f21e5d27a5f6257dbe43bb2b24a370afbc..20886d119c868609e15dd52d1f8dc65c4dfb278a 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -714,11 +714,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                inf->errors = 0;
                                rv = 0;
 
-                               if (st->ss->external)
-                                       rv = sysfs_add_disk(sra, inf);
-                               else
-                                       rv = ioctl(mdfd, ADD_NEW_DISK,
-                                                  &inf->disk);
+                               rv = add_disk(mdfd, st, sra, inf);
 
                                if (rv) {
                                        fprintf(stderr,
index 6f21a63e3767aa3dae9a8e48e19d6897c9876e30..209ef98207e3a430d3ab3d9f21156809d95b0c11 100644 (file)
@@ -299,7 +299,6 @@ int Incremental(char *devname, int verbose, int runstop,
        /* - create the array */
        /* - add the device */
                mdu_array_info_t ainf;
-               mdu_disk_info_t disk;
                struct mdinfo *sra;
 
                memset(&ainf, 0, sizeof(ainf));
@@ -314,17 +313,19 @@ int Incremental(char *devname, int verbose, int runstop,
                }
                sra = sysfs_read(mdfd, devnum, GET_VERSION);
                sysfs_set_str(sra, NULL, "metadata_version", info.text_version);
-               memset(&disk, 0, sizeof(disk));
-               disk.major = major(stb.st_rdev);
-               disk.minor = minor(stb.st_rdev);
-               sysfs_free(sra);
-               if (ioctl(mdfd, ADD_NEW_DISK, &disk) != 0) {
+
+               st->ss->getinfo_super(st, &info);
+               info.disk.major = major(stb.st_rdev);
+               info.disk.minor = minor(stb.st_rdev);
+               if (add_disk(mdfd, st, sra, &info) != 0) {
                        fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
                                devname, chosen_name, strerror(errno));
                        ioctl(mdfd, STOP_ARRAY, 0);
                        close(mdfd);
+                       sysfs_free(sra);
                        return 2;
                }
+               sysfs_free(sra);
                sra = sysfs_read(mdfd, devnum, GET_DEVS);
                if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
                        /* It really should be 'none' - must be old buggy
@@ -346,7 +347,6 @@ int Incremental(char *devname, int verbose, int runstop,
        /* - add the device */
                char dn[20];
                int dfd2;
-               mdu_disk_info_t disk;
                int err;
                struct mdinfo *sra;
                struct supertype *st2;
@@ -378,17 +378,16 @@ int Incremental(char *devname, int verbose, int runstop,
                        close(mdfd);
                        return 2;
                }
-               memset(&disk, 0, sizeof(disk));
-               disk.major = major(stb.st_rdev);
-               disk.minor = minor(stb.st_rdev);
-               err = ioctl(mdfd, ADD_NEW_DISK, &disk);
+               info2.disk.major = major(stb.st_rdev);
+               info2.disk.minor = minor(stb.st_rdev);
+               err = add_disk(mdfd, st2, sra, &info2);
                if (err < 0 && errno == EBUSY) {
                        /* could be another device present with the same
                         * disk.number. Find and reject any such
                         */
                        find_reject(mdfd, st, sra, info.disk.number,
                                    info.events, verbose, chosen_name);
-                       err = ioctl(mdfd, ADD_NEW_DISK, &disk);
+                       err = add_disk(mdfd, st2, sra, &info2);
                }
                if (err < 0) {
                        fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
index 779cb237e77308a91c58f33e7ec635d05216d309..dc3ff7f2f0edd9abbc4fedb7fee827b645aad39a 100644 (file)
@@ -346,7 +346,11 @@ static void manage_member(struct mdstat_ent *mdstat,
                                struct mdinfo *newd;
                                if (sysfs_add_disk(&newa->info, d) < 0)
                                        continue;
-                               newd = newa->info.devs;
+                               newd = malloc(sizeof(*newd));
+                               *newd = *d;
+                               newd->next = newa->info.devs;
+                               newa->info.devs = newd;
+
                                newd->state_fd = sysfs_open(a->devnum,
                                                            newd->sys_name,
                                                            "state");
diff --git a/mdadm.h b/mdadm.h
index 2205e38c4268511232f10b5c886be2440062014d..b123da2dd24503ef3c2bf6830da826edc342388a 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -767,6 +767,8 @@ extern unsigned long long calc_array_size(int level, int raid_disks, int layout,
 extern int flush_metadata_updates(struct supertype *st);
 extern void append_metadata_update(struct supertype *st, void *buf, int len);
 
+extern int add_disk(int mdfd, struct supertype *st,
+                   struct mdinfo *sra, struct mdinfo *info);
 
 extern char *human_size(long long bytes);
 char *human_size_brief(long long bytes);
index bbc073028018b0acf4d67be6ade72a14a00feb07..07539ca07ed19c522704f315995f94136c63c3c5 100644 (file)
@@ -1796,7 +1796,7 @@ static int create_array(struct supertype *st)
        return 0;
 }
 
-static int add_disk(struct supertype *st)
+static int _add_disk(struct supertype *st)
 {
        struct intel_super *super = st->sb;
        size_t len;
@@ -1833,7 +1833,7 @@ static int write_init_super_imsm(struct supertype *st)
                        /* in the add disk case we are running in mdmon
                         * context, so don't close fd's
                         */
-                       return add_disk(st);
+                       return _add_disk(st);
                } else
                        rv = create_array(st);
 
diff --git a/sysfs.c b/sysfs.c
index 9ef5b394b85fa75851ce3eb776a5c5d5830af29f..fdad790f06e2d1294e5ace28ca62462949a6767e 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -456,7 +456,6 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
 {
        char dv[100];
        char nm[100];
-       struct mdinfo *sd2;
        char *dname;
        int rv;
 
@@ -482,12 +481,6 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
                rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
 //             rv |= sysfs_set_str(sra, sd, "state", "in_sync");
        }
-       if (! rv) {
-               sd2 = malloc(sizeof(*sd2));
-               *sd2 = *sd;
-               sd2->next = sra->devs;
-               sra->devs = sd2;
-       }
        return rv;
 }
 
diff --git a/test b/test
index bd8d279360d6a83aa910ab7f9276a0a66bb39931..9ceb531e7a3e3fe882f349931d75c7523655fa01 100644 (file)
--- a/test
+++ b/test
@@ -155,6 +155,7 @@ testdev() {
    dsize=$[dvsize/chunk]
    dsize=$[dsize*chunk]
    rasize=$[dsize*2*cnt]
+   if [ `/sbin/blockdev --getsize $dev` -eq 0 ]; then sleep 2 ; fi
    if [ $rasize -ne `/sbin/blockdev --getsize $dev` ]
    then
      echo "ERROR: size is wrong for $dev: $cnt * $dvsize (chunk=$chunk) = $rasize, not `/sbin/blockdev --getsize $dev`"
index 4f03d7bdc2ee0d2516c4684567d8bff5d80e88f6..55205a36f91702e62387b5e5ffea655ba655d5c7 100644 (file)
@@ -129,3 +129,10 @@ echo "  metadata=1 devices=$dev0,$dev1,$dev2" >> $conf
 mdadm --assemble --scan --config=$conf $md2 
 $tst
 mdadm -S $md2
+
+# Now use incremental assembly.
+mdadm -I --config=$conf $dev0
+mdadm -I --config=$conf $dev1
+mdadm -I --config=$conf $dev2
+$tst
+mdadm -S $md2
index 7553a4f0b9b56fab6854f57c8fbbe1ffcf6eab22..0f2c83b6ed3a159964844747f00a005ff5a1baae 100644 (file)
@@ -113,3 +113,10 @@ echo "  metadata=1.0 devices=$dev0,$dev1,$dev2" >> $conf
 mdadm --assemble --scan --config=$conf $md1
 check state U_U
 eval $tst
+
+# And now assemble with -I
+mdadm -Ss
+mdadm -I -c $conf $dev0
+mdadm -I -c $conf $dev1
+mdadm -I -c $conf $dev2
+eval $tst
diff --git a/util.c b/util.c
index 181a0a3c9193b11dc4a64a723c53436b1dd0b2f6..7469fca4111e0f0a577c4c36766d5b2333a54acc 100644 (file)
--- a/util.c
+++ b/util.c
@@ -999,6 +999,27 @@ int open_container(int fd)
        return -1;
 }
 
+int add_disk(int mdfd, struct supertype *st,
+            struct mdinfo *sra, struct mdinfo *info)
+{
+       /* Add a device to an array, in one of 2 ways. */
+       int rv;
+#ifndef MDASSEMBLE
+       if (st->ss->external) {
+               rv = sysfs_add_disk(sra, info);
+               if (! rv) {
+                       struct mdinfo *sd2;
+                       sd2 = malloc(sizeof(*sd2));
+                       *sd2 = *info;
+                       sd2->next = sra->devs;
+                       sra->devs = sd2;
+               }
+       } else
+#endif
+               rv = ioctl(mdfd, ADD_NEW_DISK, &info->disk);
+       return rv;
+}
+
 char *devnum2devname(int num)
 {
        char name[100];