ZTS: Fix create-o_ashift test case
The function that fills the uberblock ring buffer on every device label has been reworked to avoid occasional failures caused by a race condition that prevents 'zpool sync' from writing some uberblock sequentially: this happens when the pool sync ioctl dispatch code calls txg_wait_synced() while we're already waiting for a TXG to sync. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #6924 Closes #6977
This commit is contained in:
parent
bbffb59efc
commit
c30e34faa1
|
@ -2788,10 +2788,6 @@ dump_label(const char *dev)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, BLKFLSBUF) != 0)
|
|
||||||
(void) printf("failed to invalidate cache '%s' : %s\n", path,
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
if (fstat64_blk(fd, &statbuf) != 0) {
|
if (fstat64_blk(fd, &statbuf) != 0) {
|
||||||
(void) printf("failed to stat '%s': %s\n", path,
|
(void) printf("failed to stat '%s': %s\n", path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
@ -2799,6 +2795,10 @@ dump_label(const char *dev)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (S_ISBLK(statbuf.st_mode) && ioctl(fd, BLKFLSBUF) != 0)
|
||||||
|
(void) printf("failed to invalidate cache '%s' : %s\n", path,
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
avl_create(&config_tree, cksum_record_compare,
|
avl_create(&config_tree, cksum_record_compare,
|
||||||
sizeof (cksum_record_t), offsetof(cksum_record_t, link));
|
sizeof (cksum_record_t), offsetof(cksum_record_t, link));
|
||||||
avl_create(&uberblock_tree, cksum_record_compare,
|
avl_create(&uberblock_tree, cksum_record_compare,
|
||||||
|
|
|
@ -42,54 +42,47 @@
|
||||||
|
|
||||||
verify_runnable "global"
|
verify_runnable "global"
|
||||||
|
|
||||||
# See issue: https://github.com/zfsonlinux/zfs/issues/6924
|
|
||||||
if is_linux; then
|
|
||||||
log_unsupported "Test case occasionally fails"
|
|
||||||
fi
|
|
||||||
|
|
||||||
function cleanup
|
function cleanup
|
||||||
{
|
{
|
||||||
poolexists $TESTPOOL && destroy_pool $TESTPOOL
|
destroy_pool $TESTPOOL
|
||||||
log_must rm -f $disk
|
log_must rm -f $disk
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Commit the specified number of TXGs to the provided pool
|
# Fill the uberblock ring in every <device> label: we do this by committing
|
||||||
# We use 'zpool sync' here because we can't force it via sync(1) like on illumos
|
# TXGs to the provided <pool> until every slot contains a valid uberblock.
|
||||||
# $1 pool name
|
# NOTE: We use 'zpool sync' here because we can't force it via sync(1) like on
|
||||||
# $2 number of txg syncs
|
# illumos
|
||||||
#
|
#
|
||||||
function txg_sync
|
function write_device_uberblocks # <device> <pool>
|
||||||
{
|
{
|
||||||
typeset pool=$1
|
typeset device=$1
|
||||||
typeset -i count=$2
|
typeset pool=$2
|
||||||
typeset -i i=0;
|
|
||||||
|
|
||||||
while [ $i -lt $count ]
|
while [ "$(zdb -quuul $device | grep -c 'invalid')" -ne 0 ]
|
||||||
do
|
do
|
||||||
log_must sync_pool $pool true
|
sync_pool $pool true
|
||||||
((i = i + 1))
|
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Verify device $1 labels contains $2 valid uberblocks in every label
|
# Verify every label on <device> contains <count> (valid) uberblocks
|
||||||
# $1 device
|
|
||||||
# $2 uberblocks count
|
|
||||||
#
|
#
|
||||||
function verify_device_uberblocks
|
function verify_device_uberblocks # <device> <count>
|
||||||
{
|
{
|
||||||
typeset device=$1
|
typeset device=$1
|
||||||
typeset ubcount=$2
|
typeset ubcount=$2
|
||||||
|
|
||||||
zdb -quuul $device | egrep '^(\s+)?Uberblock' |
|
zdb -quuul $device | egrep '^(\s+)?Uberblock' |
|
||||||
egrep -v 'invalid$' | awk \
|
awk -v ubcount=$ubcount 'BEGIN { count=0 } { uberblocks[$0]++; }
|
||||||
-v ubcount=$ubcount '{ uberblocks[$0]++; }
|
END {
|
||||||
END { for (i in uberblocks) {
|
for (i in uberblocks) {
|
||||||
count++;
|
if (i ~ /invalid/) { continue; }
|
||||||
if (uberblocks[i] != 4) { exit 1; }
|
if (uberblocks[i] != 4) { exit 1; }
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
if (count != ubcount) { exit 1; } }'
|
if (count != ubcount) { exit 1; }
|
||||||
|
}'
|
||||||
|
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
@ -115,8 +108,7 @@ do
|
||||||
log_fail "Pool was created without setting ashift value to "\
|
log_fail "Pool was created without setting ashift value to "\
|
||||||
"$ashift (current = $pprop)"
|
"$ashift (current = $pprop)"
|
||||||
fi
|
fi
|
||||||
# force 128 txg sync to fill the uberblock ring
|
write_device_uberblocks $disk $TESTPOOL
|
||||||
txg_sync $TESTPOOL 128
|
|
||||||
verify_device_uberblocks $disk ${ubcount[$i]}
|
verify_device_uberblocks $disk ${ubcount[$i]}
|
||||||
if [[ $? -ne 0 ]]
|
if [[ $? -ne 0 ]]
|
||||||
then
|
then
|
||||||
|
|
Loading…
Reference in New Issue