| #!/bin/ksh -p |
| # |
| # This file and its contents are supplied under the terms of the |
| # Common Development and Distribution License ("CDDL"), version 1.0. |
| # You may only use this file in accordance with the terms of version |
| # 1.0 of the CDDL. |
| # |
| # A full copy of the text of the CDDL should have accompanied this |
| # source. A copy of the CDDL is also available via the Internet at |
| # http://www.illumos.org/license/CDDL. |
| # |
| |
| # |
| # Copyright (c) 2018, 2020 by Delphix. All rights reserved. |
| # |
| |
| # DESCRIPTION |
| # Verify zfs destroy test for clones with the livelist feature |
| # enabled. |
| |
| # STRATEGY |
| # 1. One clone with an empty livelist |
| # - create the clone, check that livelist exists |
| # - delete the clone, check that livelist is eventually |
| # destroyed |
| # 2. One clone with populated livelist |
| # - create the clone, check that livelist exists |
| # - write multiple files to the clone |
| # - delete the clone, check that livelist is eventually |
| # destroyed |
| # 3. Multiple clones with empty livelists |
| # - same as 1. but with multiple clones |
| # 4. Multiple clones with populated livelists |
| # - same as 2. but with multiple clones |
| # 5. Clone of clone with populated livelists with promote |
| |
| . $STF_SUITE/include/libtest.shlib |
| . $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib |
| |
| function cleanup |
| { |
| datasetexists $TESTPOOL/$TESTFS1 && destroy_dataset $TESTPOOL/$TESTFS1 -R |
| # reset the livelist sublist size to its original value |
| set_tunable64 LIVELIST_MAX_ENTRIES $ORIGINAL_MAX |
| } |
| |
| function clone_write_file |
| { |
| log_must mkfile 1m /$TESTPOOL/$1/$2 |
| log_must zpool sync $TESTPOOL |
| } |
| |
| function test_one_empty |
| { |
| clone_dataset $TESTFS1 snap $TESTCLONE |
| |
| log_must zfs destroy $TESTPOOL/$TESTCLONE |
| check_livelist_gone |
| } |
| |
| function test_one |
| { |
| clone_dataset $TESTFS1 snap $TESTCLONE |
| |
| clone_write_file $TESTCLONE $TESTFILE0 |
| clone_write_file $TESTCLONE $TESTFILE1 |
| clone_write_file $TESTCLONE $TESTFILE2 |
| log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE0 |
| log_must rm /$TESTPOOL/$TESTCLONE/$TESTFILE2 |
| check_livelist_exists $TESTCLONE |
| |
| log_must zfs destroy $TESTPOOL/$TESTCLONE |
| check_livelist_gone |
| } |
| |
| function test_multiple_empty |
| { |
| clone_dataset $TESTFS1 snap $TESTCLONE |
| clone_dataset $TESTFS1 snap $TESTCLONE1 |
| clone_dataset $TESTFS1 snap $TESTCLONE2 |
| |
| log_must zfs destroy $TESTPOOL/$TESTCLONE |
| log_must zfs destroy $TESTPOOL/$TESTCLONE1 |
| log_must zfs destroy $TESTPOOL/$TESTCLONE2 |
| check_livelist_gone |
| } |
| |
| function test_multiple |
| { |
| clone_dataset $TESTFS1 snap $TESTCLONE |
| clone_dataset $TESTFS1 snap $TESTCLONE1 |
| clone_dataset $TESTFS1 snap $TESTCLONE2 |
| |
| clone_write_file $TESTCLONE $TESTFILE0 |
| |
| clone_write_file $TESTCLONE1 $TESTFILE0 |
| clone_write_file $TESTCLONE1 $TESTFILE1 |
| clone_write_file $TESTCLONE1 $TESTFILE2 |
| |
| clone_write_file $TESTCLONE2 $TESTFILE0 |
| log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE0 |
| clone_write_file $TESTCLONE2 $TESTFILE1 |
| log_must rm /$TESTPOOL/$TESTCLONE2/$TESTFILE1 |
| |
| check_livelist_exists $TESTCLONE |
| check_livelist_exists $TESTCLONE1 |
| check_livelist_exists $TESTCLONE2 |
| |
| log_must zfs destroy $TESTPOOL/$TESTCLONE |
| log_must zfs destroy $TESTPOOL/$TESTCLONE1 |
| log_must zfs destroy $TESTPOOL/$TESTCLONE2 |
| check_livelist_gone |
| } |
| |
| function test_promote |
| { |
| clone_dataset $TESTFS1 snap $TESTCLONE |
| |
| log_must zfs promote $TESTPOOL/$TESTCLONE |
| check_livelist_gone |
| log_must zfs destroy -R $TESTPOOL/$TESTCLONE |
| } |
| |
| function test_clone_clone_promote |
| { |
| log_must zfs create $TESTPOOL/fs |
| log_must dd if=/dev/zero of=/$TESTPOOL/fs/file bs=128k count=100 |
| log_must zfs snapshot $TESTPOOL/fs@snap |
| log_must zfs clone $TESTPOOL/fs@snap $TESTPOOL/clone |
| log_must dd if=/dev/zero of=/$TESTPOOL/clone/clonefile bs=128k count=10 |
| log_must zfs snapshot $TESTPOOL/clone@csnap |
| log_must zfs clone $TESTPOOL/clone@csnap $TESTPOOL/cloneclone |
| |
| check_livelist_exists clone |
| check_livelist_exists cloneclone |
| |
| # Promote should remove both clones' livelists |
| log_must zfs promote $TESTPOOL/cloneclone |
| check_livelist_gone |
| |
| # This destroy should not use a livelist |
| log_must zfs destroy $TESTPOOL/clone |
| log_must zdb -bcc $TESTPOOL |
| } |
| |
| ORIGINAL_MAX=$(get_tunable LIVELIST_MAX_ENTRIES) |
| |
| log_onexit cleanup |
| log_must zfs create $TESTPOOL/$TESTFS1 |
| log_must mkfile 20m /$TESTPOOL/$TESTFS1/atestfile |
| log_must zfs snapshot $TESTPOOL/$TESTFS1@snap |
| |
| # set a small livelist entry size to more easily test multiple entry livelists |
| set_tunable64 LIVELIST_MAX_ENTRIES 20 |
| |
| test_one_empty |
| test_one |
| test_multiple_empty |
| test_multiple |
| test_promote |
| test_clone_clone_promote |
| |
| log_pass "Clone with the livelist feature enabled could be destroyed," \ |
| "also could be promoted and destroyed as expected." |