]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support fixing of byte-swapped superblocks.
authorNeil Brown <neilb@suse.de>
Tue, 9 Aug 2005 04:25:27 +0000 (04:25 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 9 Aug 2005 04:25:27 +0000 (04:25 +0000)
Good for moving between little-endian and big-endian.
Still needs documentation.

Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Assemble.c
ChangeLog
mdadm.8
mdadm.c
super0.c
test
tests/06r5swap [new file with mode: 0644]

index 20183ae12c3bdbe3653f0c1f2494e0c74dc49a2f..739db51203f316f5164e85d83b4ff819a1f3b033 100644 (file)
@@ -334,6 +334,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                free(super);
        super = NULL;
 
+       if (update && strcmp(update, "byteorder")==0)
+               st->minor_version = 90;
+
        if (devcnt == 0) {
                fprintf(stderr, Name ": no devices found for %s\n",
                        mddev);
index c70bda1e5233affba972b088d4792ae6875f37b8..2cb01c17c89ebeebed5e086eddc4d92569e8fd4b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Changes Prior to this release
+    -   Support assembling from byte-swapped superblocks
+       metadata type "0.swap" and --update=byteorder
+
 Changes Prior to 2.0-devel-3 release
     -   Assorted fixes for multiple bugs...
     -   Add test suite
diff --git a/mdadm.8 b/mdadm.8
index b0ac74ae478fffd5e25c781585928fd3b6b9a950..1ecdac29130080495e3ba8c8a38c4cdb1af47da7 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -525,6 +525,7 @@ argument given to this flag can be one of
 .BR sparc2.2 ,
 .BR summaries ,
 .BR resync ,
+.BR byteorder ,
 or
 .BR super-minor .
 
@@ -555,6 +556,18 @@ copies for raid1) may be incorrect.  This will cause the raid system
 to perform a "resync" pass to make sure that all redundant information
 is correct.
 
+The
+.B byteorder
+option allows arrays to be moved between machines with different
+byte-order.
+When assembling such an array for the first time after a move, giving 
+.B "--update=byteorder"
+will cause
+.I mdadm
+to expect superblocks to have their byteorder reversed, and will
+correct that order before assembling the array.  This is only valid
+with original (Verion 0.90) superblocks.
+
 The
 .B summaries
 option will correct the summaries in the superblock. That is the
diff --git a/mdadm.c b/mdadm.c
index 45c59b379d251fcb01a4e67469bdb172dc35fb3c..2b2b9be7043df8e8707c7a6e293d062a09b952c6 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -547,6 +547,20 @@ int main(int argc, char *argv[])
                                continue;
                        if (strcmp(update, "resync")==0)
                                continue;
+                       if (strcmp(update, "byteorder")==0) {
+                               if (ss) {
+                                       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");
+                               if (!ss) {
+                                       fprintf(stderr, Name ": INTERNAL ERROR cannot find 0.swap\n");
+                                       exit(2);
+                               }
+
+                               continue;
+                       }
                        fprintf(stderr, Name ": '--update %s' invalid.  Only 'sparc2.2', 'super-minor', 'resync' or 'summaries' supported\n",update);
                        exit(2);
 
index 7ff5ff427cab070f3d88f9c4a89caf346c82cc32..7a306b524f12637c002b57444b95e470120c32ee 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -52,7 +52,39 @@ static unsigned long calc_sb0_csum(mdp_super_t *super)
        return newcsum;
 }
 
+
+void super0_swap_endian(struct mdp_superblock_s *sb)
+{
+       /* as super0 superblocks are host-endian, it is sometimes
+        * useful to be able to swap the endianness 
+        * as (almost) everything is u32's we byte-swap every 4byte
+        * number.
+        * We then also have to swap the events_hi and events_lo
+        */
+       char *sbc = (char *)sb;
+       __u32 t32;
+       int i;
+
+       for (i=0; i < MD_SB_BYTES ; i+=4) {
+               char t = sbc[i];
+               sbc[i] = sbc[i+3];
+               sbc[i+3] = t;
+               t=sbc[i+1];
+               sbc[i+1]=sbc[i+2];
+               sbc[i+2]=t;
+       }
+       t32 = sb->events_hi;
+       sb->events_hi = sb->events_lo;
+       sb->events_lo = t32;
+
+       t32 = sb->cp_events_hi;
+       sb->cp_events_hi = sb->cp_events_lo;
+       sb->cp_events_lo = t32;
+
+}      
+
 #ifndef MDASSEMBLE
+
 static void examine_super0(void *sbv)
 {
        mdp_super_t *sb = sbv;
@@ -572,6 +604,9 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
                return 1;
        }
 
+       if (st->ss && st->minor_version == 9)
+               super0_swap_endian(super);
+
        if (super->md_magic != MD_SB_MAGIC) {
                if (devname)
                        fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n",
@@ -611,6 +646,10 @@ static struct supertype *match_metadata_desc0(char *arg)
                )
                return st;
 
+       st->minor_version = 9; /* flag for 'byte-swapped' */
+       if (strcmp(arg, "0.swap")==0)
+               return st;
+
        free(st);
        return NULL;
 }
@@ -742,7 +781,6 @@ int write_bitmap0(struct supertype *st, int fd, void *sbv)
 
        return rv;
 }
-       
 
 struct superswitch super0 = {
 #ifndef MDASSEMBLE
diff --git a/test b/test
index ea1851c314bec5b75e7375b6de665b08f9346c0e..3e7990925e0c0df29816ded9dbefaa8261ca2f16 100644 (file)
--- a/test
+++ b/test
@@ -28,7 +28,7 @@ export md0=/dev/md0 md1=/dev/md1 md2=/dev/md2
 # We test mdadm on loop-back block devices.
 # dir for storing files should be settable by command line maybe
 targetdir=/tmp
-export targetdir
+export targetdir dir
 size=20000
 mdsize0=19904
 mdsize1=19992
diff --git a/tests/06r5swap b/tests/06r5swap
new file mode 100644 (file)
index 0000000..01f4718
--- /dev/null
@@ -0,0 +1,22 @@
+set -e
+
+# make a raid5 array, byte swap the superblocks, then assemble...
+
+$mdadm -CR $md0 -l5 -n4 $dev0 $dev1 $dev2 $dev3
+sleep 4
+$mdadm -S $md0
+
+$mdadm -E --metadata=0 $dev1 | grep -v Events > $targetdir/d1
+for d in $dev0 $dev1 $dev2 $dev3
+do $dir/swap_super $d
+done
+$mdadm -E --metadata=0.swap  $dev1 | grep -v Events > $targetdir/d1s
+diff -u $targetdir/d1 $targetdir/d1s
+
+$mdadm --assemble --update=byteorder $md0 $dev0 $dev1 $dev2 $dev3
+sleep 3
+cat /proc/mdstat
+exit 1
+
+
+