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);
|
free(super);
|
||||||
super = NULL;
|
super = NULL;
|
||||||
|
|
||||||
|
if (update && strcmp(update, "byteorder")==0)
|
||||||
|
st->minor_version = 90;
|
||||||
|
|
||||||
if (devcnt == 0) {
|
if (devcnt == 0) {
|
||||||
fprintf(stderr, Name ": no devices found for %s\n",
|
fprintf(stderr, Name ": no devices found for %s\n",
|
||||||
mddev);
|
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
|
Changes Prior to 2.0-devel-3 release
|
||||||
- Assorted fixes for multiple bugs...
|
- Assorted fixes for multiple bugs...
|
||||||
- Add test suite
|
- 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 sparc2.2 ,
|
||||||
.BR summaries ,
|
.BR summaries ,
|
||||||
.BR resync ,
|
.BR resync ,
|
||||||
|
.BR byteorder ,
|
||||||
or
|
or
|
||||||
.BR super-minor .
|
.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
|
to perform a "resync" pass to make sure that all redundant information
|
||||||
is correct.
|
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
|
The
|
||||||
.B summaries
|
.B summaries
|
||||||
option will correct the summaries in the superblock. That is the
|
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;
|
continue;
|
||||||
if (strcmp(update, "resync")==0)
|
if (strcmp(update, "resync")==0)
|
||||||
continue;
|
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);
|
fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2', 'super-minor', 'resync' or 'summaries' supported\n",update);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
|
||||||
|
|
40
super0.c
40
super0.c
|
@ -52,7 +52,39 @@ static unsigned long calc_sb0_csum(mdp_super_t *super)
|
||||||
return newcsum;
|
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
|
#ifndef MDASSEMBLE
|
||||||
|
|
||||||
static void examine_super0(void *sbv)
|
static void examine_super0(void *sbv)
|
||||||
{
|
{
|
||||||
mdp_super_t *sb = 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st->ss && st->minor_version == 9)
|
||||||
|
super0_swap_endian(super);
|
||||||
|
|
||||||
if (super->md_magic != MD_SB_MAGIC) {
|
if (super->md_magic != MD_SB_MAGIC) {
|
||||||
if (devname)
|
if (devname)
|
||||||
fprintf(stderr, Name ": No super block found on %s (Expected magic %08x, got %08x)\n",
|
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;
|
return st;
|
||||||
|
|
||||||
|
st->minor_version = 9; /* flag for 'byte-swapped' */
|
||||||
|
if (strcmp(arg, "0.swap")==0)
|
||||||
|
return st;
|
||||||
|
|
||||||
free(st);
|
free(st);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -743,7 +782,6 @@ int write_bitmap0(struct supertype *st, int fd, void *sbv)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct superswitch super0 = {
|
struct superswitch super0 = {
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
.examine_super = examine_super0,
|
.examine_super = examine_super0,
|
||||||
|
|
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.
|
# We test mdadm on loop-back block devices.
|
||||||
# dir for storing files should be settable by command line maybe
|
# dir for storing files should be settable by command line maybe
|
||||||
targetdir=/tmp
|
targetdir=/tmp
|
||||||
export targetdir
|
export targetdir dir
|
||||||
size=20000
|
size=20000
|
||||||
mdsize0=19904
|
mdsize0=19904
|
||||||
mdsize1=19992
|
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