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 http://www.opensolaris.org/os/licensing. 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 67log_assert "'zfs bookmark' should work only when passed valid arguments." 68log_onexit cleanup 69 70DATASET="$TESTPOOL/$TESTFS" 71DATASET_TWO="$TESTPOOL/${TESTFS}_two" 72TESTSNAP='snapshot' 73TESTSNAP2='snapshot2' 74TESTBM='bookmark' 75TESTBMCOPY='bookmark_copy' 76 77 78# Create initial snapshot 79log_must zfs snapshot "$DATASET@$TESTSNAP" 80 81# 82# Bookmark creation tests 83# 84 85# Verify we can create a bookmark specifying snapshot and bookmark full paths 86log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 87log_must eval "bkmarkexists $DATASET#$TESTBM" 88log_must zfs destroy "$DATASET#$TESTBM" 89 90# Verify we can create a bookmark specifying the snapshot name 91log_must zfs bookmark "@$TESTSNAP" "$DATASET#$TESTBM" 92log_must eval "bkmarkexists $DATASET#$TESTBM" 93log_must zfs destroy "$DATASET#$TESTBM" 94 95# Verify we can create a bookmark specifying the bookmark name 96log_must zfs bookmark "$DATASET@$TESTSNAP" "#$TESTBM" 97log_must eval "bkmarkexists $DATASET#$TESTBM" 98log_must zfs destroy "$DATASET#$TESTBM" 99 100# Verify at least a full dataset path is required and both snapshot and 101# bookmark name must be valid 102log_mustnot zfs bookmark "@$TESTSNAP" "#$TESTBM" 103log_mustnot zfs bookmark "$TESTSNAP" "#$TESTBM" 104log_mustnot zfs bookmark "@$TESTSNAP" "$TESTBM" 105log_mustnot zfs bookmark "$TESTSNAP" "$TESTBM" 106log_mustnot zfs bookmark "$TESTSNAP" "$DATASET#$TESTBM" 107log_mustnot zfs bookmark "$DATASET" "$TESTBM" 108log_mustnot zfs bookmark "$DATASET@" "$TESTBM" 109log_mustnot zfs bookmark "$DATASET" "#$TESTBM" 110log_mustnot zfs bookmark "$DATASET@" "#$TESTBM" 111log_mustnot zfs bookmark "$DATASET@$TESTSNAP" "$TESTBM" 112log_mustnot zfs bookmark "@" "#$TESTBM" 113log_mustnot zfs bookmark "@" "#" 114log_mustnot zfs bookmark "@$TESTSNAP" "#" 115log_mustnot zfs bookmark "@$TESTSNAP" "$DATASET#" 116log_mustnot zfs bookmark "@$TESTSNAP" "$DATASET" 117log_mustnot zfs bookmark "$TESTSNAP" "$DATASET#" 118log_mustnot zfs bookmark "$TESTSNAP" "$DATASET" 119log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 120 121# Verify that we can create a bookmarks on another origin filesystem 122log_must zfs clone "$DATASET@$TESTSNAP" "$DATASET_TWO" 123log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET_TWO#$TESTBM" 124log_must eval "destroy_dataset $DATASET_TWO" 125 126# Verify that we can cannot create bookmarks on a non-origin filesystem 127log_must zfs create "$DATASET_TWO" 128log_mustnot_expect "source is not an ancestor of the new bookmark's dataset" zfs bookmark "$DATASET@$TESTSNAP" "$DATASET_TWO#$TESTBM" 129log_must zfs destroy "$DATASET_TWO" 130 131# Verify that we can create bookmarks of snapshots on the pool dataset 132log_must zfs snapshot "$TESTPOOL@$TESTSNAP" 133log_must zfs bookmark "$TESTPOOL@$TESTSNAP" "$TESTPOOL#$TESTBM" 134log_must zfs destroy "$TESTPOOL#$TESTBM" 135log_must zfs destroy "$TESTPOOL@$TESTSNAP" 136 137# 138# Bookmark copying tests 139# 140 141# create the source bookmark 142log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 143 144# Verify we can copy a bookmark by specifying the source bookmark 145# and new bookmark full paths. 146log_must eval "bkmarkexists $DATASET#$TESTBM" 147log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET#$TESTBMCOPY" 148log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 149## validate destroy once (should be truly independent bookmarks) 150log_must zfs destroy "$DATASET#$TESTBM" 151log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 152log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 153log_must zfs destroy "$DATASET#$TESTBMCOPY" 154log_mustnot eval "bkmarkexists $DATASET#$TESTBMCOPY" 155log_mustnot eval "bkmarkexists $DATASET#$TESTBM" 156## recreate the source bookmark 157log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 158 159# Verify we can copy a bookmark specifying the short source name 160log_must zfs bookmark "#$TESTBM" "$DATASET#$TESTBMCOPY" 161log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 162log_must zfs destroy "$DATASET#$TESTBMCOPY" 163 164# Verify we can copy a bookmark specifying the short bookmark name 165log_must zfs bookmark "$DATASET#$TESTBM" "#$TESTBMCOPY" 166log_must eval "bkmarkexists $DATASET#$TESTBMCOPY" 167log_must zfs destroy "$DATASET#$TESTBMCOPY" 168 169# Verify two short paths are not allowed, and test empty paths 170log_mustnot zfs bookmark "#$TESTBM" "#$TESTBMCOPY" 171log_mustnot zfs bookmark "#$TESTBM" "#" 172log_mustnot zfs bookmark "#" "#$TESTBMCOPY" 173log_mustnot zfs bookmark "#" "#" 174log_mustnot zfs bookmark "#" "" 175log_mustnot zfs bookmark "" "#" 176log_mustnot zfs bookmark "" "" 177 178# Verify that we can copy bookmarks on another origin filesystem 179log_must zfs clone "$DATASET@$TESTSNAP" "$DATASET_TWO" 180log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET_TWO#$TESTBMCOPY" 181log_must zfs destroy "$DATASET_TWO" 182 183# Verify that we can cannot create bookmarks on another non-origin filesystem 184log_must zfs create "$DATASET_TWO" 185log_mustnot_expect "source is not an ancestor of the new bookmark's dataset" zfs bookmark "$DATASET#$TESTBM" "$DATASET_TWO#$TESTBMCOPY" 186log_must zfs destroy "$DATASET_TWO" 187 188# Verify that we can copy bookmarks on the pool dataset 189log_must zfs snapshot "$TESTPOOL@$TESTSNAP" 190log_must zfs bookmark "$TESTPOOL@$TESTSNAP" "$TESTPOOL#$TESTBM" 191log_must zfs bookmark "$TESTPOOL#$TESTBM" "$TESTPOOL#$TESTBMCOPY" 192log_must zfs destroy "$TESTPOOL#$TESTBM" 193log_must zfs destroy "$TESTPOOL#$TESTBMCOPY" 194log_must zfs destroy "$TESTPOOL@$TESTSNAP" 195 196# Verify that copied 'normal' bookmarks are independent of the source bookmark 197log_must zfs bookmark "$DATASET#$TESTBM" "$DATASET#$TESTBMCOPY" 198log_must zfs destroy "$DATASET#$TESTBM" 199log_must eval "zfs send $DATASET@$TESTSNAP > $TEST_BASE_DIR/zfstest_datastream.$$" 200log_must eval "destroy_dataset $TESTPOOL/$TESTFS/recv" 201log_must eval "zfs recv -o mountpoint=none $TESTPOOL/$TESTFS/recv < $TEST_BASE_DIR/zfstest_datastream.$$" 202log_must zfs snapshot "$DATASET@$TESTSNAP2" 203log_must eval "zfs send -i \#$TESTBMCOPY $DATASET@$TESTSNAP2 > $TEST_BASE_DIR/zfstest_datastream.$$" 204log_must eval "zfs recv $TESTPOOL/$TESTFS/recv < $TEST_BASE_DIR/zfstest_datastream.$$" 205# cleanup 206log_must eval "destroy_dataset $DATASET@$TESTSNAP2" 207log_must zfs destroy "$DATASET#$TESTBMCOPY" 208log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 209 210# Verify that copied redaction bookmarks are independent of the source bookmark 211## create redaction bookmark 212log_must zfs destroy "$DATASET#$TESTBM" 213log_must zfs destroy "$DATASET@$TESTSNAP" 214log_must eval "echo secret > $TESTDIR/secret" 215log_must zfs snapshot "$DATASET@$TESTSNAP" 216log_must eval "echo redacted > $TESTDIR/secret" 217log_must zfs snapshot "$DATASET@$TESTSNAP2" # TESTSNAP2 is the redaction snapshot 218log_must zfs list -t all -o name,createtxg,guid,mountpoint,written 219log_must zfs redact "$DATASET@$TESTSNAP" "$TESTBM" "$DATASET@$TESTSNAP2" 220# ensure our primitive for testing whether a bookmark is a redaction bookmark works 221log_must eval "zfs get all $DATASET#$TESTBM | grep redact_snaps" 222## copy the redaction bookmark 223log_must zfs bookmark "$DATASET#$TESTBM" "#$TESTBMCOPY" 224log_mustnot eval "zfs get all $DATASET#$TESTBMCOPY | grep redact_snaps" 225log_must eval "zfs send --redact "$TESTBMCOPY" -i $DATASET@$TESTSNAP $DATASET@$TESTSNAP2 2>&1 | head -n 100 | grep 'not a redaction bookmark'" 226# try the above again after destroying the source bookmark, preventive measure for future work 227log_must zfs destroy "$DATASET#$TESTBM" 228log_mustnot eval "zfs get all $DATASET#$TESTBMCOPY | grep redact_snaps" 229log_must eval "zfs send --redact "$TESTBMCOPY" -i $DATASET@$TESTSNAP $DATASET@$TESTSNAP2 2>&1 | head -n 100 | grep 'not a redaction bookmark'" 230## cleanup 231log_must eval "destroy_dataset $DATASET@$TESTSNAP2" 232log_must zfs destroy "$DATASET#$TESTBMCOPY" 233log_must eval "destroy_dataset $DATASET@$TESTSNAP" 234log_must zfs snapshot "$DATASET@$TESTSNAP" 235log_must zfs bookmark "$DATASET@$TESTSNAP" "$DATASET#$TESTBM" 236 237log_pass "'zfs bookmark' works as expected" 238