1#!/bin/ksh 2 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright (c) 2019 by Datto, Inc. All rights reserved. 16# 17 18. $STF_SUITE/include/libtest.shlib 19 20# 21# Description: 22# zdb -R pool <DVA>:d will display the correct data and length 23# 24# Strategy: 25# 1. Create a pool, set compression to lzjb 26# 2. Write some identifiable data to a file 27# 3. Run zdb -ddddddbbbbbb against the file 28# 4. Record the DVA, lsize, and psize of L0 block 0 29# 5. Run zdb -R with :d flag and match the data 30# 6. Run zdb -R with :dr flags and match the lsize/psize 31# 7. Run zdb -R with :dr flags and match the lsize 32# 8. Run zdb -R with :dr flags and match the psize 33# 34 35 36function cleanup 37{ 38 datasetexists $TESTPOOL && destroy_pool $TESTPOOL 39} 40 41log_assert "Verify zdb -R :d flag (decompress) works as expected" 42log_onexit cleanup 43init_data=$TESTDIR/file1 44write_count=256 45blksize=4096 46pattern="_match__pattern_" 47verify_runnable "global" 48verify_disk_count "$DISKS" 2 49 50default_mirror_setup_noexit $DISKS 51log_must zfs set recordsize=$blksize $TESTPOOL/$TESTFS 52log_must zfs set compression=lzjb $TESTPOOL/$TESTFS 53 54# 16 chars 256 times = 4k = block size 55typeset four_k="" 56for i in {1..$write_count} 57do 58 four_k=$four_k$pattern 59done 60 61# write the 4k block 256 times 62for i in {1..$write_count} 63do 64 echo $four_k >> $init_data 65done 66 67sync_pool $TESTPOOL true 68 69# get object number of file 70listing=$(ls -i $init_data) 71set -A array $listing 72obj=${array[0]} 73log_note "file $init_data has object number $obj" 74 75output=$(zdb -ddddddbbbbbb $TESTPOOL/$TESTFS $obj 2> /dev/null \ 76 |grep -m 1 "L0 DVA") 77dva=$(sed -Ene 's/^.+DVA\[0\]=<([^>]+)>.*$/\1/p' <<< "$output") 78log_note "block 0 of $init_data has a DVA of $dva" 79 80# use the length reported by zdb -ddddddbbbbbb 81size_str=$(sed -Ene 's/^.+ size=([^ ]+) .*$/\1/p' <<< "$output") 82log_note "block size $size_str" 83 84IFS=: read -r vdev offset _ <<< "$dva" 85output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:d) 86echo $output | grep -q $pattern || log_fail "zdb -R :d failed to decompress the data properly" 87 88output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:dr) 89echo $output | grep -q $four_k || log_fail "zdb -R :dr failed to decompress the data properly" 90 91output=$(zdb -R $TESTPOOL $vdev:$offset:$size_str:dr) 92result=${#output} 93(( $result != $blksize)) && log_fail \ 94"zdb -R failed to decompress the data to the length (${#output} != $size_str)" 95 96# decompress using lsize 97IFS=/ read -r lsize psize _ <<< "$size_str" 98output=$(zdb -R $TESTPOOL $vdev:$offset:$lsize:dr) 99result=${#output} 100(( $result != $blksize)) && log_fail \ 101"zdb -R failed to decompress the data (length ${#output} != $blksize)" 102 103# Specifying psize will decompress successfully , but not always to full 104# lsize since zdb has to guess lsize incrementally. 105output=$(zdb -R $TESTPOOL $vdev:$offset:$psize:dr) 106result=${#output} 107# convert psize to decimal 108psize_orig=$psize 109psize=${psize%?} 110psize=$((16#$psize)) 111(( $result < $psize)) && log_fail \ 112"zdb -R failed to decompress the data with psize $psize_orig\ 113 (length ${#output} < $psize)" 114 115log_pass "zdb -R :d flag (decompress) works as expected" 116