aboutsummaryrefslogtreecommitdiffstats
path: root/tests/zfs-tests
diff options
context:
space:
mode:
authorRyan Moeller <[email protected]>2020-10-29 21:43:38 +0000
committerBrian Behlendorf <[email protected]>2020-11-11 11:01:42 -0800
commit97f5cfea77edb9c49ca0b0880a5c183af51a0ca2 (patch)
tree24cf3a633b84cfe5a87f37c2db22087ac9aa1321 /tests/zfs-tests
parent5ecbea67ebe98fa98904024378d09d5511a727ae (diff)
ZTS: Output all block copies in list_file_blocks
The second part of list_file_blocks transforms the object description output by zdb -ddddd $ds $objnum into a stream of lines of the form "level path offset length" for the indirect blocks in the given file. The current code only works for the first copy of L0 blocks. L1 and L2 indirect blocks have more than one copy on disk. Add one more -d to the zdb command so we get all block copies and rewrite the transformation to match more than L0 and output all DVAs. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ryan Moeller <[email protected]> Closes #11141
Diffstat (limited to 'tests/zfs-tests')
-rw-r--r--tests/zfs-tests/include/blkdev.shlib37
1 files changed, 27 insertions, 10 deletions
diff --git a/tests/zfs-tests/include/blkdev.shlib b/tests/zfs-tests/include/blkdev.shlib
index 9522baebd..3f29d4f59 100644
--- a/tests/zfs-tests/include/blkdev.shlib
+++ b/tests/zfs-tests/include/blkdev.shlib
@@ -586,20 +586,37 @@ function list_file_blocks # input_file
# two are converted to decimal in the while loop. 4M is added to
# the offset to compensate for the first two labels and boot
# block. Lastly, the offset and length are printed in units of
- # 512b blocks for ease of use with dd.
+ # 512B blocks for ease of use with dd.
#
+ typeset level vdev path offset length
+ if awk -n '' 2>/dev/null; then
+ # gawk needs -n to decode hex
+ AWK='awk -n'
+ else
+ AWK='awk'
+ fi
log_must zpool sync -f
- typeset level path offset length
- zdb -ddddd $ds $objnum | awk -F: '
+ zdb -dddddd $ds $objnum | $AWK -v pad=$((4<<20)) -v bs=512 '
+ /^$/ { looking = 0 }
+ looking {
+ level = $2
+ field = 3
+ while (split($field, dva, ":") == 3) {
+ # top level vdev id
+ vdev = int(dva[1])
+ # offset + 4M label/boot pad in 512B blocks
+ offset = (int("0x"dva[2]) + pad) / bs
+ # length in 512B blocks
+ len = int("0x"dva[3]) / bs
+
+ print level, vdev, offset, len
+
+ ++field
+ }
+ }
/^Indirect blocks:/ { looking = 1 }
- /^\t\tsegment / { looking = 0 }
- /L[0-8]/ && looking { print }
- ' | sed -n 's/^.*\(L[0-9]\) *\([0-9]*\):\([0-9a-f]*\):\([0-9a-f]*\) .*$/\1 \2 \3 \4/p' | \
+ ' | \
while read level vdev offset length; do
- offset=$((16#$offset)) # Conversion from hex
- length=$((16#$length))
- offset="$(((offset + 4 * 1024 * 1024) / 512))"
- length="$((length / 512))"
for path in ${VDEV_MAP[$vdev][@]}; do
echo "$level $path $offset $length"
done