From bf4fb153a4431ad3f91c3e72eebbd661b0455ed7 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 14 Dec 2006 17:31:29 +1100 Subject: [PATCH] Fix and test --update=uuid A number of odd bugs here, but now we have a regression test as well. --- Assemble.c | 12 ++++--- ChangeLog | 1 + bitmap.c | 30 ++++++++++++++--- mdadm.h | 2 +- super1.c | 16 +++++++-- test | 12 +++++-- tests/06update-uuid | 82 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 140 insertions(+), 15 deletions(-) diff --git a/Assemble.c b/Assemble.c index 59f42390..2adf08d3 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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 { diff --git a/ChangeLog b/ChangeLog index d1e0eb03..ebd83fbc 100644 --- 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 diff --git a/bitmap.c b/bitmap.c index 81dc62b2..c905b4d3 100644 --- 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 f6350e18..318edd47 100644 --- 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); diff --git a/super1.c b/super1.c index be1a0e5b..14f9c8af 100644 --- 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 75c53d87..f0a4388f 100644 --- 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 diff --git a/tests/06update-uuid b/tests/06update-uuid index e69de29b..c23afc9f 100644 --- a/tests/06update-uuid +++ b/tests/06update-uuid @@ -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 -- 2.39.2