]>
Commit | Line | Data |
---|---|---|
23d56208 AX |
1 | #!/bin/bash |
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, Version 1.0 only | |
7 | # (the "License"). You may not use this file except in compliance | |
8 | # with the License. | |
9 | # | |
10 | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
11 | # or http://www.opensolaris.org/os/licensing. | |
12 | # See the License for the specific language governing permissions | |
13 | # and limitations under the License. | |
14 | # | |
15 | # When distributing Covered Code, include this CDDL HEADER in each | |
16 | # file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
17 | # If applicable, add the following below this CDDL HEADER, with the | |
18 | # fields enclosed by brackets "[]" replaced with your own identifying | |
19 | # information: Portions Copyright [yyyy] [name of copyright owner] | |
20 | # | |
21 | # CDDL HEADER END | |
22 | # | |
23 | # | |
24 | # Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
25 | # Use is subject to license terms. | |
26 | # | |
27 | # Linux version | |
28 | # | |
29 | # To run just type ziltest.sh | |
30 | # | |
31 | # - creates a 200MB pool in /var/tmp/ | |
32 | # - prints information on: | |
33 | # working set files | |
34 | # ZIL records written | |
35 | # ZIL block usage | |
36 | # verification results | |
37 | # - returns status of 0 on success | |
38 | # | |
39 | ########################################################################## | |
40 | # | |
41 | # Here's how it all works: | |
42 | # | |
43 | # The general idea is to build up | |
44 | # an intent log from a bunch of diverse user commands | |
45 | # without actually committing them to the file system. | |
46 | # Then copy the file system, replay the intent | |
47 | # log and compare the file system and the copy. | |
48 | # | |
49 | # To enable this automated testing of the intent log | |
50 | # requires some but minimal support from the file system. | |
51 | # In particular, a "freeze" command is required to flush | |
52 | # the in-flight transactions; to stop the actual | |
53 | # committing of transactions; and to ensure no deltas are | |
54 | # discarded. All deltas past a freeze point are kept for | |
55 | # replay and comparison later. Here is the flow: | |
56 | # | |
57 | # create an empty file system (FS) | |
58 | # freeze FS | |
59 | # run various user commands that create files, directories and ACLs | |
60 | # copy FS to temporary location (COPY) | |
61 | # unmount filesystem | |
62 | # <at this stage FS is empty again and unfrozen, and the | |
63 | # intent log contains a complete set of deltas to replay it> | |
64 | # remount FS <which replays the intent log> | |
65 | # compare FS against the COPY | |
66 | # | |
67 | ||
68 | PATH=/usr/bin | |
69 | PATH=$PATH:/usr/sbin | |
70 | PATH=$PATH:/bin | |
71 | PATH=$PATH:/sbin | |
72 | export PATH | |
73 | ||
74 | # ==================================================================== | |
75 | # SETUP | |
76 | # ==================================================================== | |
77 | CMD=$(basename "$0") | |
78 | POOL=ziltestpool.$$ | |
79 | DEVSIZE=${DEVSIZE-200m} | |
80 | POOLDIR=/var/tmp | |
81 | POOLFILE=$POOLDIR/ziltest_poolfile.$$ | |
82 | SLOGFILE=$POOLDIR/ziltest_slog.$$ | |
83 | FS=$POOL/fs | |
84 | ROOT=/$FS | |
85 | COPY=/var/tmp/${POOL} | |
86 | KEEP=no | |
87 | ||
88 | cleanup() | |
89 | { | |
90 | zfs destroy -rf $FS | |
91 | echo "$CMD: pool I/O summary & status:" | |
92 | echo "----------------------------------------------------" | |
93 | zpool iostat $POOL | |
94 | echo | |
95 | zpool status $POOL | |
96 | echo "----------------------------------------------------" | |
97 | echo | |
98 | zpool destroy -f $POOL | |
99 | rm -rf $COPY | |
100 | rm $POOLFILE $SLOGFILE | |
101 | } | |
102 | ||
103 | bail() | |
104 | { | |
105 | test $KEEP = no && cleanup | |
106 | echo "$1" | |
107 | exit 1 | |
108 | } | |
109 | ||
110 | test $# -eq 0 || bail "usage: $CMD" | |
111 | ||
112 | # ==================================================================== | |
113 | # PREP | |
114 | # | |
115 | # Create a pool using a file based vdev | |
116 | # Create a destination for runtime copy of FS | |
117 | # Freeze transaction syncing in the pool | |
118 | # ==================================================================== | |
119 | truncate -s "$DEVSIZE" $POOLFILE || bail "can't make $POOLFILE" | |
120 | truncate -s "$DEVSIZE" $SLOGFILE || bail "can't make $SLOGFILE" | |
121 | zpool create $POOL $POOLFILE log $SLOGFILE || bail "can't create pool | |
122 | $POOL" | |
123 | zpool list $POOL | |
124 | ||
125 | zfs set compression=on $POOL || bail "can't enable compression on $POOL" | |
126 | zfs create $FS || bail "can't create $FS" | |
127 | mkdir -p $COPY || bail "can't create $COPY" | |
128 | ||
129 | # | |
130 | # This dd command works around an issue where ZIL records aren't created | |
131 | # after freezing the pool unless a ZIL header already exists. Create a file | |
132 | # synchronously to force ZFS to write one out. | |
133 | # | |
134 | dd if=/dev/zero of=$ROOT/sync conv=fdatasync,fsync bs=1 count=1 2> /dev/null | |
135 | ||
136 | zpool freeze $POOL || bail "can't freeze $POOL" | |
137 | ||
138 | # ==================================================================== | |
139 | # TESTS | |
140 | # | |
141 | # Add operations here that will add commit records to the ZIL | |
142 | # | |
143 | # Use $ROOT for all file name prefixes | |
144 | # ==================================================================== | |
145 | ||
146 | # | |
147 | # TX_CREATE | |
148 | # | |
149 | touch $ROOT/a | |
150 | ||
151 | # | |
152 | # TX_RENAME | |
153 | # | |
154 | mv $ROOT/a $ROOT/b | |
155 | ||
156 | # | |
157 | # TX_SYMLINK | |
158 | # | |
159 | touch $ROOT/c | |
160 | ln -s $ROOT/c $ROOT/d | |
161 | ||
162 | # | |
163 | # TX_LINK | |
164 | # | |
165 | touch $ROOT/e | |
166 | ln $ROOT/e $ROOT/f | |
167 | ||
168 | # | |
169 | # TX_MKDIR | |
170 | # | |
171 | mkdir $ROOT/dir_to_delete | |
172 | ||
173 | # | |
174 | # TX_RMDIR | |
175 | # | |
176 | rmdir $ROOT/dir_to_delete | |
177 | ||
178 | # | |
179 | # Create a simple validation payload | |
180 | # | |
181 | PAYLOAD=$(modinfo -F filename zfs) | |
182 | cp "$PAYLOAD" "$ROOT/payload" | |
183 | CHECKSUM_BEFORE=$(sha256sum -b "$PAYLOAD") | |
184 | ||
185 | # | |
186 | # TX_WRITE (small file with ordering) | |
187 | # | |
188 | cp /etc/mtab $ROOT/small_file | |
189 | cp /etc/profile $ROOT/small_file | |
190 | ||
191 | # | |
192 | # TX_CREATE, TX_MKDIR, TX_REMOVE, TX_RMDIR | |
193 | # | |
194 | cp -R /usr/share/dict $ROOT | |
195 | rm -rf $ROOT/dict | |
196 | ||
197 | # | |
198 | # TX_SETATTR | |
199 | # | |
200 | touch $ROOT/setattr | |
201 | chmod 567 $ROOT/setattr | |
202 | chgrp root $ROOT/setattr | |
203 | touch -cm -t 201311271200 $ROOT/setattr | |
204 | ||
205 | # | |
206 | # TX_TRUNCATE (to zero) | |
207 | # | |
208 | cp /etc/services $ROOT/truncated_file | |
209 | > $ROOT/truncated_file | |
210 | ||
211 | # | |
212 | # Write to an open but removed file | |
213 | # | |
214 | (sleep 2; date) > $ROOT/date & sleep 1; rm $ROOT/date; wait | |
215 | ||
216 | # | |
217 | # TX_WRITE (large file) | |
218 | # | |
219 | dd if=/usr/share/lib/termcap of=$ROOT/large bs=128k oflag=sync 2> /dev/null | |
220 | ||
221 | # | |
222 | # Write zeroes, which compresss to holes, in the middle of a file | |
223 | # | |
224 | dd if=$POOLFILE of=$ROOT/holes.1 bs=128k count=8 2> /dev/null | |
225 | dd if=/dev/zero of=$ROOT/holes.1 bs=128k count=2 2> /dev/null | |
226 | ||
227 | dd if=$POOLFILE of=$ROOT/holes.2 bs=128k count=8 2> /dev/null | |
228 | dd if=/dev/zero of=$ROOT/holes.2 bs=128k count=2 oseek=2 2> /dev/null | |
229 | ||
230 | dd if=$POOLFILE of=$ROOT/holes.3 bs=128k count=8 2> /dev/null | |
231 | dd if=/dev/zero of=$ROOT/holes.3 bs=128k count=2 oseek=2 conv=notrunc 2> /dev/null | |
232 | ||
233 | # | |
234 | # TX_MKXATTR | |
235 | # | |
236 | mkdir $ROOT/xattr.dir | |
237 | attr -qs fileattr -V HelloWorld $ROOT/xattr.dir | |
238 | attr -qs tmpattr -V HelloWorld $ROOT/xattr.dir | |
239 | attr -qr tmpattr $ROOT/xattr.dir | |
240 | ||
241 | touch $ROOT/xattr.file | |
242 | attr -qs fileattr -V HelloWorld $ROOT/xattr.file | |
243 | attr -qs tmpattr -V HelloWorld $ROOT/xattr.file | |
244 | attr -qr tmpattr $ROOT/xattr.file | |
245 | rm $ROOT/xattr.file | |
246 | ||
247 | ||
248 | # ==================================================================== | |
249 | # REPLAY | |
250 | # ==================================================================== | |
251 | ||
252 | KEEP=yes # keep stuff around if we fail, so we can look at it | |
253 | ||
254 | cd $ROOT | |
255 | find . | cpio -pdmu --quiet $COPY | |
256 | echo | |
257 | cd / | |
258 | ||
259 | zfs unmount $FS || bail "can't unmount $FS" | |
260 | ||
261 | echo "$CMD: transactions to replay:" | |
262 | echo "----------------------------------------------------" | |
263 | zdb -ivv $FS || bail "can't run zdb on $POOL" | |
264 | echo "----------------------------------------------------" | |
265 | echo | |
266 | ||
267 | # | |
268 | # Export and reimport the pool to unfreeze it and claim log blocks. | |
269 | # It has to be import -f because we can't write a frozen pool's labels! | |
270 | # | |
271 | zpool export $POOL || bail "can't export $POOL" | |
272 | zpool import -f -d $POOLDIR $POOL || bail "can't import $POOL" | |
273 | ||
274 | # ==================================================================== | |
275 | # VERIFY | |
276 | # ==================================================================== | |
277 | ||
278 | echo "$CMD: current block usage:" | |
279 | echo "----------------------------------------------------" | |
280 | zdb -bcv $POOL || bail "blocks were leaked!" | |
281 | echo "----------------------------------------------------" | |
282 | echo | |
283 | ||
284 | echo "$CMD: Copy of xattrs:" | |
285 | echo "----------------------------------------------------" | |
286 | attr -l $ROOT/xattr.dir || bail "can't list xattrs" | |
287 | echo "----------------------------------------------------" | |
288 | echo | |
289 | ||
290 | echo "$CMD: Results of workingset diff:" | |
291 | echo "----------------------------------------------------" | |
292 | diff -r $ROOT $COPY > /dev/null || diff -r $ROOT $COPY || bail "replay diffs!" | |
293 | ||
294 | echo "$CHECKSUM_BEFORE" | sha256sum -c || bail "payload checksums don't match" | |
295 | echo "payload checksum matched" | |
296 | echo "----------------------------------------------------" | |
297 | echo | |
298 | ||
299 | cleanup | |
300 | ||
301 | exit 0 |