1#!/bin/ksh -p
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright (c) 2018 by Delphix. All rights reserved.
15#
16
17# DESCRIPTION
18# Test race conditions for livelist condensing
19
20# STRATEGY
21# These tests exercise code paths that deal with a livelist being
22# simultaneously condensed and deactivated (deleted, exported or disabled).
23# If a variable is set, the zthr will pause until it is cancelled or waited
24# and then a counter variable keeps track of whether or not the code path is
25# reached.
26
27# 1. Deletion race: repeatedly overwrite the same file to trigger condense
28# and then delete the clone.
29# 2. Disable race: Overwrite enough files to trigger condenses and disabling of
30# the livelist.
31# 3. Export race: repeatedly overwrite the same file to trigger condense and
32# then export the pool.
33
34. $STF_SUITE/include/libtest.shlib
35. $STF_SUITE/tests/functional/cli_root/zfs_destroy/zfs_destroy_common.kshlib
36
37function cleanup
38{
39	log_must zfs destroy -Rf $TESTPOOL/$TESTFS1
40	# reset the livelist sublist size to the original value
41	set_tunable64 LIVELIST_MAX_ENTRIES $ORIGINAL_MAX
42	# reset the condense tests to 0
43	set_tunable32 LIVELIST_CONDENSE_ZTHR_PAUSE 0
44	set_tunable32 LIVELIST_CONDENSE_SYNC_PAUSE 0
45	log_must zfs inherit compression $TESTPOOL
46}
47
48function delete_race
49{
50	set_tunable32 "$1" 0
51	log_must zfs clone $TESTPOOL/$TESTFS1@snap $TESTPOOL/$TESTCLONE
52	for i in {1..5}; do
53		sync_pool $TESTPOOL
54		log_must mkfile 5m /$TESTPOOL/$TESTCLONE/out
55	done
56	log_must zfs destroy $TESTPOOL/$TESTCLONE
57	sync_pool $TESTPOOL
58	[[ "1" == "$(get_tunable "$1")" ]] || \
59	    log_fail "delete/condense race test failed"
60}
61
62function export_race
63{
64	set_tunable32 "$1" 0
65	log_must zfs clone $TESTPOOL/$TESTFS1@snap $TESTPOOL/$TESTCLONE
66	for i in {1..5}; do
67		sync_pool $TESTPOOL
68		log_must mkfile 5m /$TESTPOOL/$TESTCLONE/out
69	done
70	log_must zpool export $TESTPOOL
71	log_must zpool import $TESTPOOL
72	[[ "1" == "$(get_tunable "$1")" ]] || \
73	    log_fail "export/condense race test failed"
74	log_must zfs destroy $TESTPOOL/$TESTCLONE
75}
76
77function disable_race
78{
79	set_tunable32 "$1" 0
80	log_must zfs clone $TESTPOOL/$TESTFS1@snap $TESTPOOL/$TESTCLONE
81	for i in {1..5}; do
82		sync_pool $TESTPOOL
83		log_must mkfile 5m /$TESTPOOL/$TESTCLONE/out
84	done
85	# overwrite the file shared with the origin to trigger disable
86	log_must mkfile 100m /$TESTPOOL/$TESTCLONE/atestfile
87	sync_pool $TESTPOOL
88	[[ "1" == "$(get_tunable "$1")" ]] || \
89	    log_fail "disable/condense race test failed"
90	log_must zfs destroy $TESTPOOL/$TESTCLONE
91}
92
93ORIGINAL_MAX=$(get_tunable LIVELIST_MAX_ENTRIES)
94
95log_onexit cleanup
96
97# You might think that setting compression=off for $TESTFS1 would be
98# sufficient. You would be mistaken.
99# You need compression=off for whatever the parent of $TESTFS1 is,
100# and $TESTFS1.
101log_must zfs set compression=off $TESTPOOL
102log_must zfs create $TESTPOOL/$TESTFS1
103log_must mkfile 100m /$TESTPOOL/$TESTFS1/atestfile
104sync_pool $TESTPOOL
105log_must zfs snapshot $TESTPOOL/$TESTFS1@snap
106
107# Reduce livelist size to trigger condense more easily
108set_tunable64 LIVELIST_MAX_ENTRIES 20
109
110# Test cancellation path in the zthr
111set_tunable32 LIVELIST_CONDENSE_ZTHR_PAUSE 1
112set_tunable32 LIVELIST_CONDENSE_SYNC_PAUSE 0
113disable_race LIVELIST_CONDENSE_ZTHR_CANCEL
114delete_race LIVELIST_CONDENSE_ZTHR_CANCEL
115export_race LIVELIST_CONDENSE_ZTHR_CANCEL
116
117# Test cancellation path in the synctask
118set_tunable32 LIVELIST_CONDENSE_ZTHR_PAUSE 0
119set_tunable32 LIVELIST_CONDENSE_SYNC_PAUSE 1
120disable_race LIVELIST_CONDENSE_SYNC_CANCEL
121delete_race LIVELIST_CONDENSE_SYNC_CANCEL
122
123log_pass "Clone livelist condense race conditions passed."
124