Fix assembling of array with spares when verion-1 superblock is used.
As spared don't have a position in the raid array with verion-1 superblocks, we need to handle them a bit differently. Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
parent
265e0f1731
commit
308e1801ba
|
@ -119,6 +119,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
||||||
struct mdinfo info;
|
struct mdinfo info;
|
||||||
struct mddev_ident_s ident2;
|
struct mddev_ident_s ident2;
|
||||||
char *avail;
|
char *avail;
|
||||||
|
int nextspare = 0;
|
||||||
|
|
||||||
vers = md_get_version(mdfd);
|
vers = md_get_version(mdfd);
|
||||||
if (vers <= 0) {
|
if (vers <= 0) {
|
||||||
|
@ -320,6 +321,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
|
||||||
i = devcnt;
|
i = devcnt;
|
||||||
else
|
else
|
||||||
i = devices[devcnt].raid_disk;
|
i = devices[devcnt].raid_disk;
|
||||||
|
if (i+1 == 0) {
|
||||||
|
if (nextspare < info.array.raid_disks)
|
||||||
|
nextspare = info.array.raid_disks;
|
||||||
|
i = nextspare++;
|
||||||
|
}
|
||||||
if (i < 10000) {
|
if (i < 10000) {
|
||||||
if (i >= bestcnt) {
|
if (i >= bestcnt) {
|
||||||
unsigned int newbestcnt = i+10;
|
unsigned int newbestcnt = i+10;
|
||||||
|
|
|
@ -4,6 +4,9 @@ Changes Prior to this release
|
||||||
depending on which devices are present, and so will correctly
|
depending on which devices are present, and so will correctly
|
||||||
handle "--assemble --force" if multiple devices have failed.
|
handle "--assemble --force" if multiple devices have failed.
|
||||||
- Report raid10 layout in --examine output.
|
- Report raid10 layout in --examine output.
|
||||||
|
- Fix assembling of arrays that use the version-1 superblock and
|
||||||
|
have spares. Previously the spares would be ignored.
|
||||||
|
- Fix bug so that multiple drives can be re-added at once.
|
||||||
|
|
||||||
Changes Prior to 2.0
|
Changes Prior to 2.0
|
||||||
- Support assembling from byte-swapped superblocks
|
- Support assembling from byte-swapped superblocks
|
||||||
|
|
2
Manage.c
2
Manage.c
|
@ -288,7 +288,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
|
if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
|
||||||
if (verbose >= 0)
|
if (verbose >= 0)
|
||||||
fprintf(stderr, Name ": re-added %s\n", dv->devname);
|
fprintf(stderr, Name ": re-added %s\n", dv->devname);
|
||||||
return 0;
|
continue;
|
||||||
}
|
}
|
||||||
/* fall back on normal-add */
|
/* fall back on normal-add */
|
||||||
}
|
}
|
||||||
|
|
2
makedist
2
makedist
|
@ -61,7 +61,7 @@ else
|
||||||
echo $target/$base does not exist.
|
echo $target/$base does not exist.
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
( cd .. ; ln -s mdadm mdadm-$version ; tar chf - --exclude="TAGS" --exclude='*,v' --exclude='*~' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz
|
( cd .. ; ln -s mdadm.v2 mdadm-$version ; tar chf - --exclude="TAGS" --exclude='*,v' --exclude='*~' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz
|
||||||
mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - )
|
mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - )
|
||||||
mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - )
|
mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - )
|
||||||
diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new
|
diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new
|
||||||
|
|
9
test
9
test
|
@ -60,12 +60,19 @@ path1=$dev7
|
||||||
|
|
||||||
# mdadm always adds --quiet, and we want to see any unexpected messages
|
# mdadm always adds --quiet, and we want to see any unexpected messages
|
||||||
mdadm() {
|
mdadm() {
|
||||||
$mdadm 2>&1 --quiet "$@"
|
$mdadm --quiet "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# check various things
|
# check various things
|
||||||
check() {
|
check() {
|
||||||
case $1 in
|
case $1 in
|
||||||
|
spares )
|
||||||
|
spares=`tr '] ' '\012\012' < /proc/mdstat | grep -c '(S)' || exit 0`
|
||||||
|
if [ $spares -ne $2 ]
|
||||||
|
then
|
||||||
|
echo >&2 "ERROR expected $2 spares, found $spares"; exit 1;
|
||||||
|
fi
|
||||||
|
;;
|
||||||
raid* | linear )
|
raid* | linear )
|
||||||
grep -s "active $1 " /proc/mdstat > /dev/null || {
|
grep -s "active $1 " /proc/mdstat > /dev/null || {
|
||||||
echo >&2 "ERROR active $1 not found" ; cat /proc/mdstat ; exit 1;}
|
echo >&2 "ERROR active $1 not found" ; cat /proc/mdstat ; exit 1;}
|
||||||
|
|
|
@ -1,109 +1,116 @@
|
||||||
|
|
||||||
# create a v-1 raid5 array and assemble in various ways
|
# create a v-1 raid5 array and assemble in various ways
|
||||||
|
|
||||||
mdadm -CR -e1 --name one $md1 -l5 -n3 $dev0 $dev1 $dev2
|
mdadm -CR -e1 --name one $md1 -l5 -n3 -x2 $dev0 $dev1 $dev2 $dev3 $dev4
|
||||||
tst="check raid5 ;testdev $md1 2 $mdsize1 64 ; mdadm -S $md1"
|
tst="check raid5 ;testdev $md1 2 $mdsize1 64 ; mdadm -S $md1"
|
||||||
uuid=`mdadm -Db $md1 | sed 's/.*UUID=//'`
|
uuid=`mdadm -Db $md1 | sed 's/.*UUID=//'`
|
||||||
check wait
|
check wait
|
||||||
|
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm -A $md1 $dev0 $dev1 $dev2
|
mdadm -A $md1 $dev0 $dev1 $dev2
|
||||||
|
mdadm $md1 --add $dev3 $dev4
|
||||||
|
check spares 2
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm -A $md1 -u $uuid $devlist
|
mdadm -A $md1 -u $uuid $devlist
|
||||||
|
check spares 2
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm -A $md1 --name one $devlist
|
mdadm -A $md1 --name one $devlist
|
||||||
|
check spares 2
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
|
|
||||||
conf=$targetdir/mdadm.conf
|
conf=$targetdir/mdadm.conf
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 UUID=$uuid
|
echo array $md1 UUID=$uuid
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf $md1
|
mdadm -As -c $conf $md1
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 name=one
|
echo array $md1 name=one
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf
|
mdadm -As -c $conf
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 devices=$dev0,$dev1,$dev2
|
echo array $md1 devices=$dev0,$dev1,$dev2,$dev3,$dev4
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf
|
mdadm -As -c $conf
|
||||||
|
|
||||||
echo "DEVICE $devlist" > $conf
|
echo "DEVICE $devlist" > $conf
|
||||||
mdadm -Db $md1 >> $conf
|
mdadm -Db $md1 >> $conf
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm --assemble --scan --config=$conf $md1
|
mdadm --assemble --scan --config=$conf $md1
|
||||||
eval $tst
|
eval $tst
|
||||||
|
echo PING >&2
|
||||||
|
|
||||||
echo " metadata=1.0 devices=$dev0,$dev1,$dev2" >> $conf
|
echo " metadata=1.0 devices=$dev0,$dev1,$dev2,$dev3,$dev4" >> $conf
|
||||||
mdadm --assemble --scan --config=$conf $md1
|
mdadm --assemble --scan --config=$conf $md1
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
### Now with a missing device
|
### Now with a missing device
|
||||||
|
|
||||||
mdadm -AR $md1 $dev0 $dev2 #
|
mdadm -AR $md1 $dev0 $dev2 $dev3 $dev4 #
|
||||||
|
check state U_U
|
||||||
|
check spares 1
|
||||||
|
eval $tst
|
||||||
|
|
||||||
|
mdadm -A $md1 -u $uuid $devlist
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm -A $md1 -u $uuid $devlist
|
mdadm -A $md1 --name=one $devlist
|
||||||
check state U_U
|
|
||||||
eval $tst
|
|
||||||
|
|
||||||
mdadm -A $md1 --name=one $devlist
|
|
||||||
check state U_U
|
check state U_U
|
||||||
|
check spares 1
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
|
|
||||||
conf=$targetdir/mdadm.conf
|
conf=$targetdir/mdadm.conf
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 UUID=$uuid
|
echo array $md1 UUID=$uuid
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf $md1
|
mdadm -As -c $conf $md1
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 name=one
|
echo array $md1 name=one
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf
|
mdadm -As -c $conf
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
{
|
{
|
||||||
echo DEVICE $devlist
|
echo DEVICE $devlist
|
||||||
echo array $md1 devices=$dev0,$dev1,$dev2
|
echo array $md1 devices=$dev0,$dev1,$dev2
|
||||||
} > $conf
|
} > $conf
|
||||||
|
|
||||||
mdadm -As -c $conf
|
mdadm -As -c $conf
|
||||||
|
|
||||||
echo "DEVICE $devlist" > $conf
|
echo "DEVICE $devlist" > $conf
|
||||||
mdadm -Db $md1 >> $conf
|
mdadm -Db $md1 >> $conf
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
mdadm --assemble --scan --config=$conf $md1
|
mdadm --assemble --scan --config=$conf $md1
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
||||||
echo " metadata=1.0 devices=$dev0,$dev1,$dev2" >> $conf
|
echo " metadata=1.0 devices=$dev0,$dev1,$dev2" >> $conf
|
||||||
mdadm --assemble --scan --config=$conf $md1
|
mdadm --assemble --scan --config=$conf $md1
|
||||||
check state U_U
|
check state U_U
|
||||||
eval $tst
|
eval $tst
|
||||||
|
|
Loading…
Reference in New Issue