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 slog replay correctly when TX_REMOVEs are followed by
33#	TX_CREATEs.
34#
35# STRATEGY:
36#	1. Create a file system (TESTFS) with a lot of files
37#	2. Freeze TESTFS
38#	3. Remove all files then create a lot of files
39#	4. Copy TESTFS to temporary location (TESTDIR/copy)
40#	5. Unmount filesystem
41#	   <at this stage TESTFS is empty again and unfrozen, and the
42#	   intent log contains a complete set of deltas to replay it>
43#	6. Remount TESTFS <which replays the intent log>
44#	7. Compare TESTFS against the TESTDIR/copy
45#
46
47verify_runnable "global"
48
49function cleanup_fs
50{
51	cleanup
52}
53
54log_assert "Replay of intent log succeeds."
55log_onexit cleanup_fs
56log_must setup
57
58#
59# 1. Create a file system (TESTFS) with a lot of files
60#
61log_must zpool create $TESTPOOL $VDEV log mirror $LDEV
62log_must zfs set compression=on $TESTPOOL
63log_must zfs create $TESTPOOL/$TESTFS
64
65# Prep for the test of TX_REMOVE followed by TX_CREATE
66dnsize=(legacy auto 1k 2k 4k 8k 16k)
67NFILES=200
68log_must mkdir /$TESTPOOL/$TESTFS/dir0
69log_must eval 'for i in $(seq $NFILES); do zfs set dnodesize=${dnsize[$RANDOM % ${#dnsize[@]}]} $TESTPOOL/$TESTFS; touch /$TESTPOOL/$TESTFS/dir0/file.$i; done'
70
71#
72# Reimport to reset dnode allocation pointer.
73# This is to make sure we will have TX_REMOVE and TX_CREATE on same id
74#
75log_must zpool export $TESTPOOL
76log_must zpool import -f -d $VDIR $TESTPOOL
77
78#
79# This dd command works around an issue where ZIL records aren't created
80# after freezing the pool unless a ZIL header already exists. Create a file
81# synchronously to force ZFS to write one out.
82#
83log_must dd if=/dev/zero of=/$TESTPOOL/$TESTFS/sync \
84    oflag=dsync,sync bs=1 count=1
85
86#
87# 2. Freeze TESTFS
88#
89log_must zpool freeze $TESTPOOL
90
91#
92# 3. Remove all files then create a lot of files
93#
94# TX_REMOVE followed by TX_CREATE
95log_must eval 'rm -f /$TESTPOOL/$TESTFS/dir0/*'
96log_must eval 'for i in $(seq $NFILES); do zfs set dnodesize=${dnsize[$RANDOM % ${#dnsize[@]}]} $TESTPOOL/$TESTFS; touch /$TESTPOOL/$TESTFS/dir0/file.$i; done'
97
98#
99# 4. Copy TESTFS to temporary location (TESTDIR/copy)
100#
101log_must mkdir -p $TESTDIR/copy
102log_must cp -a /$TESTPOOL/$TESTFS/* $TESTDIR/copy/
103
104#
105# 5. Unmount filesystem and export the pool
106#
107# At this stage TESTFS is empty again and frozen, the intent log contains
108# a complete set of deltas to replay.
109#
110log_must zfs unmount /$TESTPOOL/$TESTFS
111
112log_note "Verify transactions to replay:"
113log_must zdb -iv $TESTPOOL/$TESTFS
114
115log_must zpool export $TESTPOOL
116
117#
118# 6. Remount TESTFS <which replays the intent log>
119#
120# Import the pool to unfreeze it and claim log blocks.  It has to be
121# `zpool import -f` because we can't write a frozen pool's labels!
122#
123log_must zpool import -f -d $VDIR $TESTPOOL
124
125#
126# 7. Compare TESTFS against the TESTDIR/copy
127#
128log_note "Verify current block usage:"
129log_must zdb -bcv $TESTPOOL
130
131log_note "Verify number of files"
132log_must test "$(ls /$TESTPOOL/$TESTFS/dir0 | wc -l)" -eq $NFILES
133
134log_note "Verify working set diff:"
135log_must diff -r /$TESTPOOL/$TESTFS $TESTDIR/copy
136
137log_pass "Replay of intent log succeeds."
138