Good for moving between little-endian and big-endian.
Still needs documentation.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
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);
+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
.BR sparc2.2 ,
.BR summaries ,
.BR resync ,
+.BR byteorder ,
or
.BR super-minor .
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
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);
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;
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",
)
return st;
+ st->minor_version = 9; /* flag for 'byte-swapped' */
+ if (strcmp(arg, "0.swap")==0)
+ return st;
+
free(st);
return NULL;
}
return rv;
}
-
struct superswitch super0 = {
#ifndef MDASSEMBLE
# 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
--- /dev/null
+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
+
+
+