summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c12
-rw-r--r--ChangeLog1
-rw-r--r--bitmap.c30
-rw-r--r--mdadm.h2
-rw-r--r--super1.c16
-rw-r--r--test12
-rw-r--r--tests/06update-uuid82
7 files changed, 140 insertions, 15 deletions
diff --git a/Assemble.c b/Assemble.c
index 59f4239..2adf08d 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 d1e0eb0..ebd83fb 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 81dc62b..c905b4d 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 f6350e1..318edd4 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 be1a0e5..14f9c8a 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 75c53d8..f0a4388 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 e69de29..c23afc9 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