1#!/bin/ksh -p
2# SPDX-License-Identifier: CDDL-1.0
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) 2017 by Delphix. All rights reserved.
16#
17
18. $STF_SUITE/tests/functional/channel_program/channel_common.kshlib
19
20#
21# DESCRIPTION:
22#       Listing zfs holds should work correctly.
23#
24
25verify_runnable "global"
26
27TESTHOLD=testhold-tag
28TESTHOLD1=$TESTHOLD-1
29TESTHOLD2=$TESTHOLD-2
30TESTHOLD3=$TESTHOLD-3
31SNAP=$TESTPOOL/$TESTFS@$TESTSNAP
32
33function cleanup
34{
35	holdexists $TESTHOLD $SNAP && log_must zfs release $TESTHOLD $SNAP
36	holdexists $TESTHOLD1 $SNAP && log_must zfs release $TESTHOLD1 $SNAP
37	holdexists $TESTHOLD2 $SNAP && log_must zfs release $TESTHOLD2 $SNAP
38	holdexists $TESTHOLD3 $SNAP && log_must zfs release $TESTHOLD3 $SNAP
39	destroy_snapshot
40}
41
42log_onexit cleanup
43
44create_snapshot
45
46# 0 holds handled correctly
47log_must_program $TESTPOOL - <<-EOF
48	n = 0
49	for s in zfs.list.holds("$SNAP") do
50		n = n + 1
51	end
52	assert(n == 0)
53	return 0
54EOF
55
56# Create a hold
57log_must zfs hold $TESTHOLD $SNAP
58
59log_must_program $TESTPOOL - <<-EOF
60	n = 0
61	for s in zfs.list.holds("$SNAP") do
62		assert(s == "$TESTHOLD")
63		n = n + 1
64	end
65	assert(n == 1)
66	return 0
67EOF
68
69log_must zfs hold $TESTHOLD1 $SNAP
70log_must zfs hold $TESTHOLD2 $SNAP
71log_must zfs hold $TESTHOLD3 $SNAP
72
73# All holds appear exactly once
74log_must_program $TESTPOOL - <<-EOF
75	a = {}
76	a["$TESTHOLD"] = false
77	a["$TESTHOLD1"] = false
78	a["$TESTHOLD2"] = false
79	a["$TESTHOLD3"] = false
80	n = 0
81	for s in zfs.list.holds("$SNAP") do
82		assert(not a[s])
83		a[s] = true
84		n = n + 1
85	end
86	assert(n == 4)
87	assert(a["$TESTHOLD"] and
88	    a["$TESTHOLD1"] and
89	    a["$TESTHOLD2"] and
90	    a["$TESTHOLD3"])
91	return 0
92EOF
93
94# Nonexistent input
95log_mustnot_program $TESTPOOL - <<-EOF
96	zfs.list.holds("$TESTPOOL/nonexistent-fs@nonexistent-snap")
97	return 0
98EOF
99log_mustnot_program $TESTPOOL - <<-EOF
100	zfs.list.holds("nonexistent-pool/$TESTFS")
101	return 0
102EOF
103
104# Can't look in a different pool than the one specified on command line
105log_mustnot_program $TESTPOOL - <<-EOF
106	zfs.list.holds("testpool2")
107	return 0
108EOF
109
110# Can't have holds on filesystems
111log_mustnot_program $TESTPOOL - <<-EOF
112	zfs.list.holds("$TESTPOOL/$TESTFS")
113	return 0
114EOF
115
116# Can't have holds on bookmarks
117log_mustnot_program $TESTPOOL - <<-EOF
118	zfs.list.holds("$TESTPOOL/$TESTFS#bookmark")
119	return 0
120EOF
121
122log_pass "Listing zfs holds should work correctly."
123