Bug #8408
dsl_props_set_sync_impl() does not handle nested nvlists correctly
Start date:
2017-06-17
Due date:
% Done:
100%
Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:
Description
When iterating over the input nvlist in dsl_props_set_sync_impl() when we don't preserve the nvpair name before looking up ZPROP_VALUE, so when we later go to process it nvpair_name() is always "value" instead of the actual property name.
This results in a couple of bugs in the recv code:
- received properties are not restored correctly when failing to receive an incremental send stream
- received properties are not completely replaced by the new ones when successfully receiving an incremental send stream
This was discovered on ZFS on Linux (fixed in https://github.com/zfsonlinux/zfs/commit/5f1346c29997dd4e02acf4c19c875d5484f33b1e)
Reproducer:
# misc functions function is_linux() { if [[ "$(uname)" == "Linux" ]]; then return 0 else return 1 fi } # setup POOLNAME='testpool' if is_linux; then TMPDIR='/var/tmp' mountpoint -q $TMPDIR || mount -t tmpfs tmpfs $TMPDIR zpool destroy $POOLNAME fallocate -l 65m $TMPDIR/zpool.dat zpool create $POOLNAME $TMPDIR/zpool.dat else TMPDIR='/tmp' zpool destroy $POOLNAME mkfile 65m $TMPDIR/zpool.dat zpool create $POOLNAME $TMPDIR/zpool.dat fi # send first stream, received compression is 'on' zfs create $POOLNAME/send zfs set compression=on $POOLNAME/send zfs snap $POOLNAME/send@snap1 zfs send -p $POOLNAME/send@snap1 > $TMPDIR/snap_full.dat zfs recv $POOLNAME/recv < $TMPDIR/snap_full.dat zfs get -o all compression $POOLNAME/recv # send second stream, compression is 'lz4' zfs set compression=lz4 $POOLNAME/send dd if=/dev/urandom of=/$POOLNAME/send/urandom bs=1M count=10 zfs snap $POOLNAME/send@snap2 zfs send -pI $POOLNAME/send@snap1 $POOLNAME/send@snap2 > $TMPDIR/snap_incr.dat # truncate the stream, fail to receive incremental dd if=/dev/null of=$TMPDIR/snap_incr.dat bs=1 count=1 seek=9M zfs recv -F $POOLNAME/recv < $TMPDIR/snap_incr.dat # zfs receive failed, compression should be 'on' zfs get -o all compression $POOLNAME/recv
This is the resulting properties on "testpool/recv": we have a "value" property instead of "compression"
[root@52-54-00-d3-7a-01 ~]# zdb -dddd testpool 49 Dataset mos [META], ID 0, cr_txg 4, 114K, 64 objects, rootbp DVA[0]=<0:17b2e00:200> DVA[1]=<0:17b3000:200> DVA[2]=<0:17b3200:200> [L0 DMU objset] fletcher4 lz4 LE contiguous unique triple size=800L/200P birth=498L/498P fill=64 cksum=11413d065e:672e12e9d76:13ff1f57e066a:2ac3890cc2454c Object lvl iblk dblk dsize lsize %full type 49 1 128K 512 0 512 100.00 DSL props dnode flags: USED_BYTES dnode maxblkid: 0 microzap: 512 bytes, 2 entries value$recvd = 1 $hasrecvd = 0
Updated by Electric Monk almost 3 years ago
- Status changed from New to Closed
git commit 85723e5eec42f46dbfdb4c09b9e1ed66501d1ccf
commit 85723e5eec42f46dbfdb4c09b9e1ed66501d1ccf Author: loli10K <ezomori.nozomu@gmail.com> Date: 2018-02-08T05:16:37.000Z 8408 dsl_props_set_sync_impl() does not handle nested nvlists correctly Reviewed by: Paul Dagnelie <pcd@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Approved by: Dan McDonald <danmcd@joyent.com>