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 2007 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28. $STF_SUITE/tests/functional/slog/slog.kshlib 29 30# 31# DESCRIPTION: 32# Verify slogs are replayed correctly. This test is a direct 33# adaptation of the ziltest.sh script for the ZFS Test Suite. 34# 35# The general idea is to build up an intent log from a bunch of 36# diverse user commands without actually committing them to the 37# file system. Then copy the file system, replay the intent 38# log and compare the file system and the copy. 39# 40# To enable this automated testing of the intent log some minimal 41# support is required of the file system. In particular, a 42# "freeze" command is required to flush the in-flight transactions; 43# to stop the actual committing of transactions; and to ensure no 44# deltas are discarded. All deltas past a freeze point are kept 45# for replay and comparison later. Here is the flow: 46# 47# STRATEGY: 48# 1. Create an empty file system (TESTFS) 49# 2. Freeze TESTFS 50# 3. Run various user commands that create files, directories and ACLs 51# 4. Copy TESTFS to temporary location (TESTDIR/copy) 52# 5. Unmount filesystem 53# <at this stage TESTFS is empty again and unfrozen, and the 54# intent log contains a complete set of deltas to replay it> 55# 6. Remount TESTFS <which replays the intent log> 56# 7. Compare TESTFS against the TESTDIR/copy 57# 58 59verify_runnable "global" 60 61log_assert "Replay of intent log succeeds." 62log_onexit cleanup 63log_must setup 64 65# 66# 1. Create an empty file system (TESTFS) 67# 68log_must zpool create $TESTPOOL $VDEV log mirror $LDEV 69log_must zfs set compression=on $TESTPOOL 70log_must zfs create $TESTPOOL/$TESTFS 71 72# 73# This dd command works around an issue where ZIL records aren't created 74# after freezing the pool unless a ZIL header already exists. Create a file 75# synchronously to force ZFS to write one out. 76# 77log_must dd if=/dev/zero of=/$TESTPOOL/$TESTFS/sync \ 78 conv=fdatasync,fsync bs=1 count=1 79 80# 81# 2. Freeze TESTFS 82# 83log_must zpool freeze $TESTPOOL 84 85# 86# 3. Run various user commands that create files, directories and ACLs 87# 88 89# TX_CREATE 90log_must touch /$TESTPOOL/$TESTFS/a 91 92# TX_RENAME 93log_must mv /$TESTPOOL/$TESTFS/a /$TESTPOOL/$TESTFS/b 94 95# TX_SYMLINK 96log_must touch /$TESTPOOL/$TESTFS/c 97log_must ln -s /$TESTPOOL/$TESTFS/c /$TESTPOOL/$TESTFS/d 98 99# TX_LINK 100log_must touch /$TESTPOOL/$TESTFS/e 101log_must ln /$TESTPOOL/$TESTFS/e /$TESTPOOL/$TESTFS/f 102 103# TX_MKDIR 104log_must mkdir /$TESTPOOL/$TESTFS/dir_to_delete 105 106# TX_RMDIR 107log_must rmdir /$TESTPOOL/$TESTFS/dir_to_delete 108 109# Create a simple validation payload 110log_must mkdir -p $TESTDIR 111log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/payload \ 112 oflag=sync bs=1k count=8 113typeset checksum=$(sha256digest /$TESTPOOL/$TESTFS/payload) 114 115# TX_WRITE (small file with ordering) 116log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/small_file \ 117 oflag=sync bs=1k count=1 118log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/small_file \ 119 oflag=sync bs=512 count=1 120 121# TX_CREATE, TX_MKDIR, TX_REMOVE, TX_RMDIR 122log_must cp -R /usr/share/dict /$TESTPOOL/$TESTFS 123log_must rm -rf /$TESTPOOL/$TESTFS/dict 124 125# TX_SETATTR 126log_must touch /$TESTPOOL/$TESTFS/setattr 127log_must chmod 567 /$TESTPOOL/$TESTFS/setattr 128if is_freebsd; then 129 log_must chgrp wheel /$TESTPOOL/$TESTFS/setattr 130else 131 log_must chgrp root /$TESTPOOL/$TESTFS/setattr 132fi 133log_must touch -cm -t 201311271200 /$TESTPOOL/$TESTFS/setattr 134 135# TX_TRUNCATE (to zero) 136log_must mkfile 4k /$TESTPOOL/$TESTFS/truncated_file 137log_must truncate -s 0 /$TESTPOOL/$TESTFS/truncated_file 138 139# TX_WRITE (large file) 140log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/large \ 141 oflag=sync bs=128k count=64 142 143# Write zeros, which compress to holes, in the middle of a file 144log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/holes.1 \ 145 oflag=sync bs=128k count=8 146log_must dd if=/dev/zero of=/$TESTPOOL/$TESTFS/holes.1 \ 147 oflag=sync bs=128k count=2 148 149log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/holes.2 \ 150 oflag=sync bs=128k count=8 151log_must dd if=/dev/zero of=/$TESTPOOL/$TESTFS/holes.2 \ 152 oflag=sync bs=128k count=2 seek=2 153 154log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/holes.3 \ 155 oflag=sync bs=128k count=8 156log_must dd if=/dev/zero of=/$TESTPOOL/$TESTFS/holes.3 \ 157 oflag=sync bs=128k count=2 seek=2 conv=notrunc 158 159# TX_MKXATTR 160log_must mkdir /$TESTPOOL/$TESTFS/xattr.dir 161log_must touch /$TESTPOOL/$TESTFS/xattr.file 162log_must set_xattr fileattr HelloWorld /$TESTPOOL/$TESTFS/xattr.dir 163log_must set_xattr tmpattr HelloWorld /$TESTPOOL/$TESTFS/xattr.dir 164log_must rm_xattr fileattr /$TESTPOOL/$TESTFS/xattr.dir 165 166log_must set_xattr fileattr HelloWorld /$TESTPOOL/$TESTFS/xattr.file 167log_must set_xattr tmpattr HelloWorld /$TESTPOOL/$TESTFS/xattr.file 168log_must rm_xattr tmpattr /$TESTPOOL/$TESTFS/xattr.file 169 170# TX_WRITE, TX_LINK, TX_REMOVE 171# Make sure TX_REMOVE won't affect TX_WRITE if file is not destroyed 172log_must dd if=/dev/urandom of=/$TESTPOOL/$TESTFS/link_and_unlink \ 173 oflag=sync bs=128k count=8 174log_must ln /$TESTPOOL/$TESTFS/link_and_unlink \ 175 /$TESTPOOL/$TESTFS/link_and_unlink.link 176log_must rm /$TESTPOOL/$TESTFS/link_and_unlink.link 177 178# 179# 4. Copy TESTFS to temporary location (TESTDIR/copy) 180# 181log_must mkdir -p $TESTDIR/copy 182log_must cp -a /$TESTPOOL/$TESTFS/* $TESTDIR/copy/ 183 184# 185# 5. Unmount filesystem and export the pool 186# 187# At this stage TESTFS is empty again and frozen, the intent log contains 188# a complete set of deltas to replay. 189# 190log_must zfs unmount /$TESTPOOL/$TESTFS 191 192log_note "Verify transactions to replay:" 193log_must zdb -iv $TESTPOOL/$TESTFS 194 195log_must zpool export $TESTPOOL 196 197# 198# 6. Remount TESTFS <which replays the intent log> 199# 200# Import the pool to unfreeze it and claim log blocks. It has to be 201# `zpool import -f` because we can't write a frozen pool's labels! 202# 203log_must zpool import -f -d $VDIR $TESTPOOL 204 205# 206# 7. Compare TESTFS against the TESTDIR/copy 207# 208log_note "Verify current block usage:" 209log_must zdb -bcv $TESTPOOL 210 211log_note "Verify copy of xattrs:" 212log_must ls_xattr /$TESTPOOL/$TESTFS/xattr.dir 213log_must ls_xattr /$TESTPOOL/$TESTFS/xattr.file 214 215log_note "Verify working set diff:" 216log_must diff -r /$TESTPOOL/$TESTFS $TESTDIR/copy 217 218log_note "Verify file checksum:" 219typeset checksum1=$(sha256digest /$TESTPOOL/$TESTFS/payload) 220[[ "$checksum1" == "$checksum" ]] || \ 221 log_fail "checksum mismatch ($checksum1 != $checksum)" 222 223log_pass "Replay of intent log succeeds." 224