@@ -586,20 +586,31 @@ function list_file_blocks # input_file
586
586
# two are converted to decimal in the while loop. 4M is added to
587
587
# the offset to compensate for the first two labels and boot
588
588
# block. Lastly, the offset and length are printed in units of
589
- # 512b blocks for ease of use with dd.
589
+ # 512B blocks for ease of use with dd.
590
590
#
591
591
log_must zpool sync -f
592
592
typeset level path offset length
593
- zdb -ddddd $ds $objnum | awk -F: '
593
+ zdb -dddddd $ds $objnum | awk -v pad=$((4<<20)) -v bs=512 '
594
+ /^$/ { looking = 0 }
595
+ looking {
596
+ level = $2
597
+ field = 3
598
+ while (split($field, dva, ":") == 3) {
599
+ # top level vdev id
600
+ vdev = int(dva[1])
601
+ # offset + 4M label/boot pad in 512B blocks
602
+ offset = (int("0x"dva[2]) + pad) / bs
603
+ # length in 512B blocks
604
+ len = int("0x"dva[3]) / bs
605
+
606
+ print level, vdev, offset, len
607
+
608
+ ++field
609
+ }
610
+ }
594
611
/^Indirect blocks:/ { looking = 1 }
595
- /^\t\tsegment / { looking = 0 }
596
- /L[0-8]/ && looking { print }
597
- ' | sed -n 's/^.*\(L[0-9]\) *\([0-9]*\):\([0-9a-f]*\):\([0-9a-f]*\) .*$/\1 \2 \3 \4/p' | \
612
+ ' | \
598
613
while read level vdev offset length; do
599
- offset=$((16#$offset)) # Conversion from hex
600
- length=$((16#$length))
601
- offset="$(((offset + 4 * 1024 * 1024) / 512))"
602
- length="$((length / 512))"
603
614
for path in ${VDEV_MAP[$vdev][@]}; do
604
615
echo "$level $path $offset $length"
605
616
done
0 commit comments