Support fixing of byte-swapped superblocks.
Good for moving between little-endian and big-endian. Still needs documentation. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
parent
8068890f11
commit
586ed40547
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
13
mdadm.8
13
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
|
||||
|
|
14
mdadm.c
14
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);
|
||||
|
||||
|
|
40
super0.c
40
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
|
||||
|
|
2
test
2
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue