]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Fix and test --update=uuid
authorNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:29 +0000 (17:31 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:29 +0000 (17:31 +1100)
A number of odd bugs here, but now we have a regression test as well.

Assemble.c
ChangeLog
bitmap.c
mdadm.h
super1.c
test
tests/06update-uuid

index 59f42390e36fb0b2d07c6c8ed45bf67b7291ee46..2adf08d34bb0de843d81309bf2c1937ceaac06f5 100644 (file)
@@ -136,6 +136,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        int chosen_drive;
        int change = 0;
        int inargv = 0;
+       int bitmap_done;
        int start_partial_ok = (runstop >= 0) && (force || devlist==NULL || mdfd < 0);
        unsigned int num_devs;
        mddev_dev_t tmpdev;
@@ -413,6 +414,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        }
 
        /* Ok, no bad inconsistancy, we can try updating etc */
+       bitmap_done = 0;
        for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
                char *devname = tmpdev->devname;
                struct stat stb;
@@ -469,10 +471,12 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                close(dfd);
 
                        if (strcmp(update, "uuid")==0 &&
-                           ident->bitmap_fd)
-                               if (bitmap_update_uuid(ident->bitmap_fd, info.uuid) != 0)
-                                       fprintf(stderr, Name ": Could not update uuid on %s.\n",
-                                               devname);
+                           ident->bitmap_fd >= 0 && !bitmap_done) {
+                               if (bitmap_update_uuid(ident->bitmap_fd, info.uuid, st->ss->swapuuid) != 0)
+                                       fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
+                               else
+                                       bitmap_done = 1;
+                       }
                } else
 #endif
                {
index d1e0eb03685b9030d14dcf1f743bc8042a56b963..ebd83fbc5495c58f4046530bcb30566834568115 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,7 @@ Changes Prior to this release
        much of each device is actually used, not how big they are.
     -   --wait or -W will wait for resync activity to finish on the given
        devices.
+    -   Fix some problems with --update=uuid and add a test.
 
 Changes Prior to 2.5.6 release
     -   Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled
index 81dc62b256de6393bc20ec1a387202dbf0b110a7..c905b4d3f548bd9fc72b4d8c84f8d8beb6711563 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -260,6 +260,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        bitmap_info_t *info;
        int rv = 1;
        char buf[64];
+       int swap;
 
        info = bitmap_file_read(filename, brief, &st);
        if (!info)
@@ -279,14 +280,22 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
        }
 
        rv = 0;
-       if (st && st->ss->swapuuid) {
-       printf("            UUID : %08x.%08x.%08x.%08x\n",
+       if (st)
+               swap = st->ss->swapuuid;
+       else
+#if __BYTE_ORDER == BIG_ENDIAN
+               swap = 0;
+#else
+               swap = 1;
+#endif
+       if (swap) {
+       printf("            UUID : %08x:%08x:%08x:%08x\n",
                                        swapl(*(__u32 *)(sb->uuid+0)),
                                        swapl(*(__u32 *)(sb->uuid+4)),
                                        swapl(*(__u32 *)(sb->uuid+8)),
                                        swapl(*(__u32 *)(sb->uuid+12)));
        } else {
-       printf("            UUID : %08x.%08x.%08x.%08x\n",
+       printf("            UUID : %08x:%08x:%08x:%08x\n",
                                        *(__u32 *)(sb->uuid+0),
                                        *(__u32 *)(sb->uuid+4),
                                        *(__u32 *)(sb->uuid+8),
@@ -402,7 +411,7 @@ out:
        return rv;
 }
 
-int bitmap_update_uuid(int fd, int *uuid)
+int bitmap_update_uuid(int fd, int *uuid, int swap)
 {
        struct bitmap_super_s bm;
        if (lseek(fd, 0, 0) != 0)
@@ -411,7 +420,18 @@ int bitmap_update_uuid(int fd, int *uuid)
                return 1;
        if (bm.magic != __cpu_to_le32(BITMAP_MAGIC))
                return 1;
-       memcpy(bm.uuid, uuid, 16);
+       if (swap) {
+               unsigned char *ac = (unsigned char *)bm.uuid;
+               unsigned char *bc = (unsigned char *)uuid;
+               int i;
+               for (i=0; i<16; i+= 4) {
+                       ac[i+0] = bc[i+3];
+                       ac[i+1] = bc[i+2];
+                       ac[i+2] = bc[i+1];
+                       ac[i+3] = bc[i+0];
+               }
+       } else
+               memcpy(bm.uuid, uuid, 16);
        if (lseek(fd, 0, 0) != 0)
                return 2;
        if (write(fd, &bm, sizeof(bm)) != sizeof(bm)) {
diff --git a/mdadm.h b/mdadm.h
index f6350e1870fb34c339da7acfcc37a1c8c82269d2..318edd47234b506d50d83774d9ec88cf6ff6208f 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -431,7 +431,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16],
                        unsigned long long array_size,
                        int major);
 extern int ExamineBitmap(char *filename, int brief, struct supertype *st);
-extern int bitmap_update_uuid(int fd, int *uuid);
+extern int bitmap_update_uuid(int fd, int *uuid, int swap);
 
 extern int md_get_version(int fd);
 extern int get_linux_version(void);
index be1a0e5baf9d4be2494b0f4086e5e2d478ea4aff..14f9c8af6563eab2bc6642eec1a9a96fb8e00907 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -536,11 +536,23 @@ static int update_super1(struct mdinfo *info, void *sbv, char *update,
                sb->resync_offset = 0ULL;
        }
        if (strcmp(update, "uuid") == 0) {
-               memcpy(sb->set_uuid, info->uuid, 16);
+               if (super1.swapuuid) {
+                       unsigned char *ac = (unsigned char *)sb->set_uuid;
+                       unsigned char *bc = (unsigned char *)info->uuid;
+                       int i;
+                       for (i=0; i<16; i+= 4) {
+                               ac[i+0] = bc[i+3];
+                               ac[i+1] = bc[i+2];
+                               ac[i+2] = bc[i+1];
+                               ac[i+3] = bc[i+0];
+                       }
+               } else
+                       memcpy(sb->set_uuid, info->uuid, 16);
+
                if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
                        struct bitmap_super_s *bm;
                        bm = (struct bitmap_super_s*)(sbv+1024);
-                       memcpy(bm->uuid, info->uuid, 16);
+                       memcpy(bm->uuid, sb->set_uuid, 16);
                }
        }
        if (strcmp(update, "homehost") == 0 &&
diff --git a/test b/test
index 75c53d87b794a7b60489e3e9dd42d74d1dd56ebc..f0a4388f592e5bdc0155abffd630d7c824b4c54b 100644 (file)
--- a/test
+++ b/test
@@ -66,9 +66,10 @@ fi
 # mdadm always adds --quiet, and we want to see any unexpected messages
 mdadm() {
     case $* in
-       *-C* ) $mdadm --quiet "$@" --auto=yes;;
-        * )   $mdadm --quiet "$@"
+       *-C* ) $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes;;
+        * )   $mdadm 2> $targetdir/stderr --quiet "$@"
     esac
+    cat >&2 $targetdir/stderr
 }
 
 # check various things
@@ -126,6 +127,11 @@ check() {
    esac
 }
 
+no_errors() {
+  if [ -s $targetdir/stderr ]
+  then echo Bad errors from mdadm: ; cat $targetdir/stderr; exit 2;
+  fi
+}
 # basic device test
 
 testdev() {
@@ -159,7 +165,7 @@ do
    # namespace, but cannot change it.
    if ( set -ex ; . $script )  2> $targetdir/log
    then echo "$script succeeded" 
-   else cat $targetdir/log
+   else cat $targetdir/log ; cat $targetdir/stderr
         echo "$script failed"
        exit 1
    fi
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c23afc9fcf364b12fd257aa0d9d3b14a8ea3627e 100644 (file)
@@ -0,0 +1,82 @@
+set -x
+
+# create an array, then change the uuid.
+
+mdadm -CR --assume-clean $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+mdadm -S /dev/md0
+
+# try v1 superblock
+
+mdadm -CR --assume-clean -e1 $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+mdadm -S /dev/md0
+
+
+# now if we have a bitmap, that needs updating too.
+rm -f $targetdir/bitmap
+mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+if mdadm -X $targetdir/bitmap | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 ||
+   mdadm -X $targetdir/bitmap | grep -s > /dev/null 67452301:efcdab89:98badcfe:10325476
+then : ; else
+   echo Wrong uuid; mdadm -X $targetdir/bitmap ; exit 2;
+fi
+mdadm -S /dev/md0
+
+# and bitmap for version1
+rm -f $targetdir/bitmap
+mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+# -X cannot tell which byteorder to use for the UUID, so allow both.
+if mdadm -X $targetdir/bitmap | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 ||
+   mdadm -X $targetdir/bitmap | grep -s > /dev/null 67452301:efcdab89:98badcfe:10325476
+then : ; else
+   echo Wrong uuid; mdadm -X $targetdir/bitmap ; exit 2;
+fi
+mdadm -S /dev/md0
+
+# Internal bitmaps too.
+mdadm -CR --assume-clean  -b internal $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+mdadm -X $dev0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -X $dev0; exit 2;
+}
+mdadm -S /dev/md0
+
+mdadm -CR --assume-clean -e1.2 -b internal $md0 -l5 -n3 $dev0 $dev1 $dev2
+mdadm -S /dev/md0
+mdadm -A /dev/md0 --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
+no_errors
+mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
+}
+mdadm -X $dev0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
+   echo Wrong uuid; mdadm -X $dev0; exit 2;
+}
+mdadm -S /dev/md0