1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or https://opensource.org/licenses/CDDL-1.0. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 25# Copyright 2019, 2020 by Christian Schwarz. All rights reserved. 26# 27 28. $STF_SUITE/include/libtest.shlib 29 30# 31# DESCRIPTION: 32# 'zfs bookmark' should work with both full and short arguments. 33# 34# STRATEGY: 35# 1. Create initial snapshot 36# 37# 2. Verify we can create a bookmark specifying snapshot and bookmark full paths 38# 3. Verify we can create a bookmark specifying the short snapshot name 39# 4. Verify we can create a bookmark specifying the short bookmark name 40# 5. Verify at least a full dataset path is required and both snapshot and 41# bookmark name must be valid 42# 43# 6. Verify we can copy a bookmark by specifying the source bookmark and new 44# bookmark full paths. 45# 7. Verify we can copy a bookmark specifying the short source name 46# 8. Verify we can copy a bookmark specifying the short new name 47# 9. Verify two short paths are not allowed, and test empty paths 48# 10. Verify we cannot copy a bookmark if the new bookmark already exists 49# 11. Verify that copying a bookmark only works if new and source name 50# have the same dataset 51# 52 53verify_runnable "both" 54 55function cleanup 56{ 57 snapexists "$DATASET@$TESTSNAP" && \ 58 destroy_dataset "$DATASET@$TESTSNAP" 59 60 bkmarkexists "$DATASET#$TESTBM" && \ 61 destroy_dataset "$DATASET#$TESTBM" 62 63 bkmarkexists "$DATASET#$TESTBMCOPY" && \ 64 destroy_dataset "$DATASET#$TESTBMCOPY" 65 66 log_must rm -f "$TEST_BASE_DIR/zfstest_datastream.$$" 67} 68 69log_assert "'zfs bookmark' should work only when passed valid arguments." 70log_onexit cleanup 71 72DATASET="$TESTPOOL/$TESTFS" 73DATASET_TWO="$TESTPOOL/${TESTFS}_two" 74TESTSNAP='snapshot' 75TESTSNAP2='snapshot2' 76TESTBM='bookmark' 77TESTBMCOPY='bookmark_copy' 78 79 80# Create initial snapshot 81log_must zfs snapshot "$DATASET@$TESTSNAP" 82 83# 84# Bookmark creation tests 85# 86 87# Verify we can create a bookmark specifying snapshot and bookmark full paths 88log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 89log_must eval "bkmarkexists $DATASET#$TESTBM" 90log_must zfs destroy "$DATASET#$TESTBM" 91 92# Verify we can create a bookmark specifying the snapshot name 93log_must zfs bookmark "@$TESTSNAP" "$DATASET#$TESTBM" 94log_must eval "bkmarkexists $DATASET#$TESTBM" 95log_must zfs destroy "$DATASET#$TESTBM" 96 97# Verify we can create a bookmark specifying the bookmark name 98log_must zfs bookmark "$DATASET@$TESTSNAP" "#$TESTBM" 99log_must eval "bkmarkexists $DATASET#$TESTBM" 100log_must zfs destroy "$DATASET#$TESTBM" 101 102# Verify at least a full dataset path is required and both snapshot and 103# bookmark name must be valid 104log_mustnot zfs bookmark "@$TESTSNAP" "#$TESTBM" 105log_mustnot zfs bookmark "$TESTSNAP" "#$TESTBM" 106log_mustnot zfs bookmark "@$TESTSNAP" "$TESTBM" 107log_mustnot zfs bookmark "$TESTSNAP" "$TESTBM" 108log_mustnot zfs bookmark "$TESTSNAP" "$DATASET#$TESTBM" 109log_mustnot zfs bookmark "$DATASET" "$TESTBM" 110log_mustnot zfs bookmark "$DATASET@" "$TESTBM" 111log_mustnot zfs bookmark "$DATASET" "#$TESTBM" 112log_mustnot zfs bookmark "$DATASET@" "#$TESTBM" 113log_mustnot zfs bookmark "$DATASET@$TESTSNAP" "$TESTBM" 114log_mustnot zfs bookmark "@" "#$TESTBM" 115log_mustnot zfs bookmark "@" "#" 116log_mustnot zfs bookmark "@$TESTSNAP" "#" 117log_mustnot zfs bookmark "@$TESTSNAP" "$DATASET#" 118log_mustnot zfs bookmark "@$TESTSNAP" "$DATASET" 119log_mustnot zfs bookmark "$TESTSNAP" "$DATASET#" 120log_mustnot zfs bookmark "$TESTSNAP" "$DATASET" 121log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 122 123# Verify that we can create a bookmarks on another origin filesystem 124log_must zfs clone "$DATASET@$TESTSNAP" "$DATASET_TWO" 125log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET_TWO#$TESTBM" 126log_must eval "destroy_dataset $DATASET_TWO" 127 128# Verify that we can cannot create bookmarks on a non-origin filesystem 129log_must zfs create "$DATASET_TWO" 130log_mustnot_expect "source is not an ancestor of the new bookmark's dataset" zfs bookmark "$DATASET@$TESTSNAP" "$DATASET_TWO#$TESTBM" 131log_must zfs destroy "$DATASET_TWO" 132 133# Verify that we can create bookmarks of snapshots on the pool dataset 134log_must zfs snapshot "$TESTPOOL@$TESTSNAP" 135log_must zfs bookmark "$TESTPOOL@$TESTSNAP" "$TESTPOOL#$TESTBM" 136log_must zfs destroy "$TESTPOOL#$TESTBM" 137log_must zfs destroy "$TESTPOOL@$TESTSNAP" 138 139# 140# Bookmark copying tests 141# 142 143# create the source bookmark 144log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 145 146# Verify we can copy a bookmark by specifying the source bookmark 147# and new bookmark full paths. 148log_must eval "bkmarkexists $DATASET#$TESTBM" 149log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET#$TESTBMCOPY" 150log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 151## validate destroy once (should be truly independent bookmarks) 152log_must zfs destroy "$DATASET#$TESTBM" 153log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 154log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 155log_must zfs destroy "$DATASET#$TESTBMCOPY" 156log_mustnot eval "bkmarkexists $DATASET#$TESTBMCOPY" 157log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 158## recreate the source bookmark 159log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 160 161# Verify we can copy a bookmark specifying the short source name 162log_must zfs bookmark "#$TESTBM" "$DATASET#$TESTBMCOPY" 163log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 164log_must zfs destroy "$DATASET#$TESTBMCOPY" 165 166# Verify we can copy a bookmark specifying the short bookmark name 167log_must zfs bookmark "$DATASET#$TESTBM" "#$TESTBMCOPY" 168log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 169log_must zfs destroy "$DATASET#$TESTBMCOPY" 170 171# Verify two short paths are not allowed, and test empty paths 172log_mustnot zfs bookmark "#$TESTBM" "#$TESTBMCOPY" 173log_mustnot zfs bookmark "#$TESTBM" "#" 174log_mustnot zfs bookmark "#" "#$TESTBMCOPY" 175log_mustnot zfs bookmark "#" "#" 176log_mustnot zfs bookmark "#" "" 177log_mustnot zfs bookmark "" "#" 178log_mustnot zfs bookmark "" "" 179 180# Verify that we can copy bookmarks on another origin filesystem 181log_must zfs clone "$DATASET@$TESTSNAP" "$DATASET_TWO" 182log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET_TWO#$TESTBMCOPY" 183log_must zfs destroy "$DATASET_TWO" 184 185# Verify that we can cannot create bookmarks on another non-origin filesystem 186log_must zfs create "$DATASET_TWO" 187log_mustnot_expect "source is not an ancestor of the new bookmark's dataset" zfs bookmark "$DATASET#$TESTBM" "$DATASET_TWO#$TESTBMCOPY" 188log_must zfs destroy "$DATASET_TWO" 189 190# Verify that we can copy bookmarks on the pool dataset 191log_must zfs snapshot "$TESTPOOL@$TESTSNAP" 192log_must zfs bookmark "$TESTPOOL@$TESTSNAP" "$TESTPOOL#$TESTBM" 193log_must zfs bookmark "$TESTPOOL#$TESTBM" "$TESTPOOL#$TESTBMCOPY" 194log_must zfs destroy "$TESTPOOL#$TESTBM" 195log_must zfs destroy "$TESTPOOL#$TESTBMCOPY" 196log_must zfs destroy "$TESTPOOL@$TESTSNAP" 197 198# Verify that copied 'normal' bookmarks are independent of the source bookmark 199log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET#$TESTBMCOPY" 200log_must zfs destroy "$DATASET#$TESTBM" 201log_must eval "zfs send $DATASET@$TESTSNAP > $TEST_BASE_DIR/zfstest_datastream.$$" 202log_must eval "destroy_dataset $TESTPOOL/$TESTFS/recv" 203log_must eval "zfs recv -o mountpoint=none $TESTPOOL/$TESTFS/recv < $TEST_BASE_DIR/zfstest_datastream.$$" 204log_must zfs snapshot "$DATASET@$TESTSNAP2" 205log_must eval "zfs send -i \#$TESTBMCOPY $DATASET@$TESTSNAP2 > $TEST_BASE_DIR/zfstest_datastream.$$" 206log_must eval "zfs recv $TESTPOOL/$TESTFS/recv < $TEST_BASE_DIR/zfstest_datastream.$$" 207# cleanup 208log_must eval "destroy_dataset $DATASET@$TESTSNAP2" 209log_must zfs destroy "$DATASET#$TESTBMCOPY" 210log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 211 212# Verify that copied redaction bookmarks are independent of the source bookmark 213## create redaction bookmark 214log_must zfs destroy "$DATASET#$TESTBM" 215log_must zfs destroy "$DATASET@$TESTSNAP" 216log_must eval "echo secret > $TESTDIR/secret" 217log_must zfs snapshot "$DATASET@$TESTSNAP" 218log_must eval "echo redacted > $TESTDIR/secret" 219log_must zfs snapshot "$DATASET@$TESTSNAP2" # TESTSNAP2 is the redaction snapshot 220log_must zfs list -t all -o name,createtxg,guid,mountpoint,written 221log_must zfs redact "$DATASET@$TESTSNAP" "$TESTBM" "$DATASET@$TESTSNAP2" 222# ensure our primitive for testing whether a bookmark is a redaction bookmark works 223log_must eval "zfs get all $DATASET#$TESTBM | grep redact_snaps" 224## copy the redaction bookmark 225log_must zfs bookmark "$DATASET#$TESTBM" "#$TESTBMCOPY" 226log_mustnot eval "zfs get all $DATASET#$TESTBMCOPY | grep redact_snaps" 227log_must eval "zfs send --redact "$TESTBMCOPY" -i $DATASET@$TESTSNAP $DATASET@$TESTSNAP2 2>&1 | head -n 100 | grep 'not a redaction bookmark'" 228# try the above again after destroying the source bookmark, preventive measure for future work 229log_must zfs destroy "$DATASET#$TESTBM" 230log_mustnot eval "zfs get all $DATASET#$TESTBMCOPY | grep redact_snaps" 231log_must eval "zfs send --redact "$TESTBMCOPY" -i $DATASET@$TESTSNAP $DATASET@$TESTSNAP2 2>&1 | head -n 100 | grep 'not a redaction bookmark'" 232## cleanup 233log_must eval "destroy_dataset $DATASET@$TESTSNAP2" 234log_must zfs destroy "$DATASET#$TESTBMCOPY" 235log_must eval "destroy_dataset $DATASET@$TESTSNAP" 236log_must zfs snapshot "$DATASET@$TESTSNAP" 237log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 238 239log_pass "'zfs bookmark' works as expected" 240