]> git.proxmox.com Git - mirror_zfs-debian.git/blame - scripts/zimport.sh
Merge tag 'upstream/0.7.2'
[mirror_zfs-debian.git] / scripts / zimport.sh
CommitLineData
ea04106b
AX
1#!/bin/bash
2#
3# Verify that an assortment of known good reference pools can be imported
4# using different versions of the ZoL code.
5#
6# By default references pools for the major ZFS implementation will be
7# checked against the most recent ZoL tags and the master development branch.
8# Alternate tags or branches may be verified with the '-s <src-tag> option.
9# Passing the keyword "installed" will instruct the script to test whatever
10# version is installed.
11#
12# Preferentially a reference pool is used for all tests. However, if one
13# does not exist and the pool-tag matches one of the src-tags then a new
14# reference pool will be created using binaries from that source build.
15# This is particularly useful when you need to test your changes before
16# opening a pull request. The keyword 'all' can be used as short hand
17# refer to all available reference pools.
18#
19# New reference pools may be added by placing a bzip2 compressed tarball
20# of the pool in the scripts/zfs-images directory and then passing
21# the -p <pool-tag> option. To increase the test coverage reference pools
22# should be collected for all the major ZFS implementations. Having these
23# pools easily available is also helpful to the developers.
24#
25# Care should be taken to run these tests with a kernel supported by all
26# the listed tags. Otherwise build failure will cause false positives.
27#
28#
29# EXAMPLES:
30#
31# The following example will verify the zfs-0.6.2 tag, the master branch,
32# and the installed zfs version can correctly import the listed pools.
33# Note there is no reference pool available for master and installed but
34# because binaries are available one is automatically constructed. The
35# working directory is also preserved between runs (-k) preventing the
36# need to rebuild from source for multiple runs.
37#
38# zimport.sh -k -f /var/tmp/zimport \
39# -s "zfs-0.6.2 master installed" \
40# -p "zevo-1.1.1 zol-0.6.2 zol-0.6.2-173 master installed"
41#
42# --------------------- ZFS on Linux Source Versions --------------
43# zfs-0.6.2 master 0.6.2-175_g36eb554
44# -----------------------------------------------------------------
45# Clone SPL Local Local Skip
46# Clone ZFS Local Local Skip
47# Build SPL Pass Pass Skip
48# Build ZFS Pass Pass Skip
49# -----------------------------------------------------------------
50# zevo-1.1.1 Pass Pass Pass
51# zol-0.6.2 Pass Pass Pass
52# zol-0.6.2-173 Fail Pass Pass
53# master Pass Pass Pass
54# installed Pass Pass Pass
55#
56basedir="$(dirname $0)"
57
58SCRIPT_COMMON=common.sh
59if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
60. "${basedir}/${SCRIPT_COMMON}"
61else
62echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
63fi
64
65PROG=zimport.sh
66
67SRC_TAGS="zfs-0.6.1 zfs-0.6.2 master"
68POOL_TAGS="all master"
69TEST_DIR=`mktemp -u -d -p /var/tmp zimport.XXXXXXXX`
70KEEP=0
71VERBOSE=0
72COLOR=1
73REPO="https://github.com/zfsonlinux"
74IMAGES_DIR="$SCRIPTDIR/zfs-images/"
75IMAGES_TAR="https://github.com/zfsonlinux/zfs-images/tarball/master"
ea04106b
AX
76ERROR=0
77
cae5b340
AX
78CONFIG_LOG="configure.log"
79CONFIG_OPTIONS=${CONFIG_OPTIONS:-""}
80MAKE_LOG="make.log"
81MAKE_OPTIONS=${MAKE_OPTIONS:-"-s -j$(nproc)"}
82
ea04106b
AX
83usage() {
84cat << EOF
85USAGE:
86zimport.sh [hvl] [-r repo] [-s src-tag] [-i pool-dir] [-p pool-tag] [-f path]
87
88DESCRIPTION:
89 ZPOOL import verification tests
90
91OPTIONS:
92 -h Show this message
93 -v Verbose
94 -c No color
95 -k Keep temporary directory
96 -r <repo> Source repository ($REPO)
97 -s <src-tag>... Verify ZoL versions with the listed tags
98 -i <pool-dir> Pool image directory
99 -p <pool-tag>... Verify pools created with the listed tags
100 -f <path> Temporary directory to use
101
102EOF
103}
104
105while getopts 'hvckr:s:i:p:f:?' OPTION; do
106 case $OPTION in
107 h)
108 usage
109 exit 1
110 ;;
111 v)
112 VERBOSE=1
113 ;;
114 c)
115 COLOR=0
116 ;;
117 k)
118 KEEP=1
119 ;;
120 r)
121 REPO="$OPTARG"
122 ;;
123 s)
124 SRC_TAGS="$OPTARG"
125 ;;
126 i)
127 IMAGES_DIR="$OPTARG"
128 ;;
129 p)
130 POOL_TAGS="$OPTARG"
131 ;;
132 f)
133 TEST_DIR="$OPTARG"
134 ;;
135 ?)
136 usage
137 exit
138 ;;
139 esac
140done
141
142# Initialize the test suite
143init
144check_modules || die "ZFS modules must be unloaded"
145
146SRC_DIR="$TEST_DIR/src"
147SRC_DIR_SPL="$SRC_DIR/spl"
148SRC_DIR_ZFS="$SRC_DIR/zfs"
149
150if [ $COLOR -eq 0 ]; then
151 COLOR_GREEN=""
152 COLOR_BROWN=""
153 COLOR_RED=""
154 COLOR_RESET=""
155fi
156
157pass_nonewline() {
158 echo -n -e "${COLOR_GREEN}Pass${COLOR_RESET}\t\t"
159}
160
161skip_nonewline() {
162 echo -n -e "${COLOR_BROWN}Skip${COLOR_RESET}\t\t"
163}
164
165fail_nonewline() {
166 echo -n -e "${COLOR_RED}Fail${COLOR_RESET}\t\t"
167}
168
169#
170# Set several helper variables which are derived from a source tag.
171#
172# SPL_TAG - The tag zfs-x.y.z is translated to spl-x.y.z.
173# SPL_DIR - The spl directory name.
174# SPL_URL - The spl github URL to fetch the tarball.
175# ZFS_TAG - The passed zfs-x.y.z tag
176# ZFS_DIR - The zfs directory name
177# ZFS_URL - The zfs github URL to fetch the tarball
178#
179src_set_vars() {
180 local TAG=$1
181
182 SPL_TAG=`echo $TAG | sed -e 's/zfs/spl/'`
183 SPL_DIR=$SRC_DIR_SPL/$SPL_TAG
184 SPL_URL=$REPO/spl/tarball/$SPL_TAG
185
186 ZFS_TAG=$TAG
187 ZFS_DIR=$SRC_DIR_ZFS/$ZFS_TAG
188 ZFS_URL=$REPO/zfs/tarball/$ZFS_TAG
189
190 if [ "$TAG" = "installed" ]; then
191 ZPOOL_CMD=`which zpool`
192 ZFS_CMD=`which zfs`
193 ZFS_SH="/usr/share/zfs/zfs.sh"
194 ZPOOL_CREATE="/usr/share/zfs/zpool-create.sh"
195 else
196 ZPOOL_CMD="./cmd/zpool/zpool"
197 ZFS_CMD="./cmd/zfs/zfs"
198 ZFS_SH="./scripts/zfs.sh"
199 ZPOOL_CREATE="./scripts/zpool-create.sh"
200 fi
201}
202
203#
204# Set several helper variables which are derived from a pool name such
205# as zol-0.6.x, zevo-1.1.1, etc. These refer to example pools from various
206# ZFS implementations which are used to verify compatibility.
207#
208# POOL_TAG - The example pools name in scripts/zfs-images/.
209# POOL_BZIP - The full path to the example bzip2 compressed pool.
210# POOL_DIR - The top level test path for this pool.
211# POOL_DIR_PRISTINE - The directory containing a pristine version of the pool.
212# POOL_DIR_COPY - The directory containing a working copy of the pool.
213# POOL_DIR_SRC - Location of a source build if it exists for this pool.
214#
215pool_set_vars() {
216 local TAG=$1
217
218 POOL_TAG=$TAG
219 POOL_BZIP=$IMAGES_DIR/$POOL_TAG.tar.bz2
220 POOL_DIR=$TEST_DIR/pools/$POOL_TAG
221 POOL_DIR_PRISTINE=$POOL_DIR/pristine
222 POOL_DIR_COPY=$POOL_DIR/copy
223 POOL_DIR_SRC=`echo -n "$SRC_DIR_ZFS/"; \
224 echo "$POOL_TAG" | sed -e 's/zol/zfs/'`
225}
226
227#
228# Construct a non-trivial pool given a specific version of the source. More
229# interesting pools provide better test coverage so this function should
230# extended as needed to create more realistic pools.
231#
232pool_create() {
233 pool_set_vars $1
234 src_set_vars $1
235
236 if [ "$POOL_TAG" != "installed" ]; then
237 cd $POOL_DIR_SRC
238 fi
239
240 $ZFS_SH zfs="spa_config_path=$POOL_DIR_PRISTINE" || fail 1
241
242 # Create a file vdev RAIDZ pool.
243 FILEDIR="$POOL_DIR_PRISTINE" $ZPOOL_CREATE \
244 -c file-raidz -p $POOL_TAG -v -x >/dev/null || fail 2
245
246 # Create a pool/fs filesystem with some random contents.
247 $ZFS_CMD create $POOL_TAG/fs || fail 3
248 populate /$POOL_TAG/fs/ 10 100
249
250 # Snapshot that filesystem, clone it, remove the files/dirs,
251 # replace them with new files/dirs.
252 $ZFS_CMD snap $POOL_TAG/fs@snap || fail 4
253 $ZFS_CMD clone $POOL_TAG/fs@snap $POOL_TAG/clone || fail 5
254 rm -Rf /$POOL_TAG/clone/* || fail 6
255 populate /$POOL_TAG/clone/ 10 100
256
257 # Scrub the pool, delay slightly, then export it. It is now
258 # somewhat interesting for testing purposes.
259 $ZPOOL_CMD scrub $POOL_TAG || fail 7
260 sleep 10
261 $ZPOOL_CMD export $POOL_TAG || fail 8
262
263 $ZFS_SH -u || fail 9
264}
265
266# If the zfs-images directory doesn't exist fetch a copy from Github then
267# cache it in the $TEST_DIR and update $IMAGES_DIR.
268if [ ! -d $IMAGES_DIR ]; then
269 IMAGES_DIR="$TEST_DIR/zfs-images"
270 mkdir -p $IMAGES_DIR
271 curl -sL $IMAGES_TAR | \
272 tar -xz -C $IMAGES_DIR --strip-components=1 || fail 10
273fi
274
275# Given the available images in the zfs-images directory substitute the
cae5b340 276# list of available images for the reserved keyword 'all'.
ea04106b
AX
277for TAG in $POOL_TAGS; do
278
279 if [ "$TAG" = "all" ]; then
280 ALL_TAGS=`ls $IMAGES_DIR | grep "tar.bz2" | \
281 sed 's/.tar.bz2//' | tr '\n' ' '`
282 NEW_TAGS="$NEW_TAGS $ALL_TAGS"
283 else
284 NEW_TAGS="$NEW_TAGS $TAG"
285 fi
286done
287POOL_TAGS="$NEW_TAGS"
288
289if [ $VERBOSE -ne 0 ]; then
290 echo "---------------------------- Options ----------------------------"
291 echo "VERBOSE=$VERBOSE"
292 echo "KEEP=$KEEP"
293 echo "REPO=$REPO"
294 echo "SRC_TAGS="$SRC_TAGS""
295 echo "POOL_TAGS="$POOL_TAGS""
296 echo "PATH=$TEST_DIR"
297 echo
298fi
299
300if [ ! -d $TEST_DIR ]; then
301 mkdir -p $TEST_DIR
302fi
303
304if [ ! -d $SRC_DIR ]; then
305 mkdir -p $SRC_DIR
306fi
307
308# Print a header for all tags which are being tested.
309echo "--------------------- ZFS on Linux Source Versions --------------"
310printf "%-16s" " "
311for TAG in $SRC_TAGS; do
312 src_set_vars $TAG
313
314 if [ "$TAG" = "installed" ]; then
315 ZFS_VERSION=`modinfo zfs | awk '/version:/ { print $2; exit }'`
316 if [ -n "$ZFS_VERSION" ]; then
317 printf "%-16s" $ZFS_VERSION
318 else
319 echo "ZFS is not installed\n"
320 fail
321 fi
322 else
323 printf "%-16s" $TAG
324 fi
325done
326echo -e "\n-----------------------------------------------------------------"
327
328#
329# Attempt to generate the tarball from your local git repository, if that
330# fails then attempt to download the tarball from Github.
331#
332printf "%-16s" "Clone SPL"
333for TAG in $SRC_TAGS; do
334 src_set_vars $TAG
335
336 if [ -d $SPL_DIR ]; then
337 skip_nonewline
338 elif [ "$SPL_TAG" = "installed" ]; then
339 skip_nonewline
340 else
341 cd $SRC_DIR
342
343 if [ ! -d $SRC_DIR_SPL ]; then
344 mkdir -p $SRC_DIR_SPL
345 fi
346
347 git archive --format=tar --prefix=$SPL_TAG/ $SPL_TAG \
348 -o $SRC_DIR_SPL/$SPL_TAG.tar &>/dev/nul || \
349 rm $SRC_DIR_SPL/$SPL_TAG.tar
350 if [ -s $SRC_DIR_SPL/$SPL_TAG.tar ]; then
351 tar -xf $SRC_DIR_SPL/$SPL_TAG.tar -C $SRC_DIR_SPL
352 rm $SRC_DIR_SPL/$SPL_TAG.tar
353 echo -n -e "${COLOR_GREEN}Local${COLOR_RESET}\t\t"
354 else
355 mkdir -p $SPL_DIR || fail 1
356 curl -sL $SPL_URL | tar -xz -C $SPL_DIR \
357 --strip-components=1 || fail 2
358 echo -n -e "${COLOR_GREEN}Remote${COLOR_RESET}\t\t"
359 fi
360 fi
361done
362printf "\n"
363
364#
365# Attempt to generate the tarball from your local git repository, if that
366# fails then attempt to download the tarball from Github.
367#
368printf "%-16s" "Clone ZFS"
369for TAG in $SRC_TAGS; do
370 src_set_vars $TAG
371
372 if [ -d $ZFS_DIR ]; then
373 skip_nonewline
374 elif [ "$ZFS_TAG" = "installed" ]; then
375 skip_nonewline
376 else
377 cd $SRC_DIR
378
379 if [ ! -d $SRC_DIR_ZFS ]; then
380 mkdir -p $SRC_DIR_ZFS
381 fi
382
383 git archive --format=tar --prefix=$ZFS_TAG/ $ZFS_TAG \
384 -o $SRC_DIR_ZFS/$ZFS_TAG.tar &>/dev/nul || \
385 rm $SRC_DIR_ZFS/$ZFS_TAG.tar
386 if [ -s $SRC_DIR_ZFS/$ZFS_TAG.tar ]; then
387 tar -xf $SRC_DIR_ZFS/$ZFS_TAG.tar -C $SRC_DIR_ZFS
388 rm $SRC_DIR_ZFS/$ZFS_TAG.tar
389 echo -n -e "${COLOR_GREEN}Local${COLOR_RESET}\t\t"
390 else
391 mkdir -p $ZFS_DIR || fail 1
392 curl -sL $ZFS_URL | tar -xz -C $ZFS_DIR \
393 --strip-components=1 || fail 2
394 echo -n -e "${COLOR_GREEN}Remote${COLOR_RESET}\t\t"
395 fi
396 fi
397done
398printf "\n"
399
400# Build the listed tags
401printf "%-16s" "Build SPL"
402for TAG in $SRC_TAGS; do
403 src_set_vars $TAG
404
405 if [ -f $SPL_DIR/module/spl/spl.ko ]; then
406 skip_nonewline
407 elif [ "$SPL_TAG" = "installed" ]; then
408 skip_nonewline
409 else
410 cd $SPL_DIR
411 make distclean &>/dev/null
cae5b340
AX
412 ./autogen.sh >>$CONFIG_LOG 2>&1 || fail 1
413 ./configure $CONFIG_OPTIONS >>$CONFIG_LOG 2>&1 || fail 2
414 make ${MAKE_OPTIONS} >>$MAKE_LOG 2>&1 || fail 3
ea04106b
AX
415 pass_nonewline
416 fi
417done
418printf "\n"
419
420# Build the listed tags
421printf "%-16s" "Build ZFS"
422for TAG in $SRC_TAGS; do
423 src_set_vars $TAG
424
425 if [ -f $ZFS_DIR/module/zfs/zfs.ko ]; then
426 skip_nonewline
427 elif [ "$ZFS_TAG" = "installed" ]; then
428 skip_nonewline
429 else
430 cd $ZFS_DIR
431 make distclean &>/dev/null
cae5b340
AX
432 ./autogen.sh >>$CONFIG_LOG 2>&1 || fail 1
433 ./configure --with-spl=$SPL_DIR $CONFIG_OPTIONS \
434 >>$CONFIG_LOG 2>&1 || fail 2
435 make ${MAKE_OPTIONS} >>$MAKE_LOG 2>&1 || fail 3
ea04106b
AX
436 pass_nonewline
437 fi
438done
439printf "\n"
440echo "-----------------------------------------------------------------"
441
442# Either create a new pool using 'zpool create', or alternately restore an
443# existing pool from another ZFS implementation for compatibility testing.
444for TAG in $POOL_TAGS; do
445 pool_set_vars $TAG
446 SKIP=0
447
448 printf "%-16s" $POOL_TAG
449 rm -Rf $POOL_DIR
450 mkdir -p $POOL_DIR_PRISTINE
451
452 # Use the existing compressed image if available.
453 if [ -f $POOL_BZIP ]; then
454 tar -xjf $POOL_BZIP -C $POOL_DIR_PRISTINE \
455 --strip-components=1 || fail 1
456 # Use the installed version to create the pool.
457 elif [ "$TAG" = "installed" ]; then
458 pool_create $TAG
459 # A source build is available to create the pool.
460 elif [ -d $POOL_DIR_SRC ]; then
461 pool_create $TAG
462 else
463 SKIP=1
464 fi
465
466 # Verify 'zpool import' works for all listed source versions.
467 for TAG in $SRC_TAGS; do
468
469 if [ $SKIP -eq 1 ]; then
470 skip_nonewline
471 continue
472 fi
473
474 src_set_vars $TAG
475 if [ "$TAG" != "installed" ]; then
476 cd $ZFS_DIR
477 fi
478 $ZFS_SH zfs="spa_config_path=$POOL_DIR_COPY"
479
480 cp -a --sparse=always $POOL_DIR_PRISTINE \
481 $POOL_DIR_COPY || fail 2
482 POOL_NAME=`$ZPOOL_CMD import -d $POOL_DIR_COPY | \
483 awk '/pool:/ { print $2; exit 0 }'`
484
485 $ZPOOL_CMD import -N -d $POOL_DIR_COPY $POOL_NAME &>/dev/null
486 if [ $? -ne 0 ]; then
487 fail_nonewline
488 ERROR=1
489 else
490 $ZPOOL_CMD export $POOL_NAME || fail 3
491 pass_nonewline
492 fi
493
494 rm -Rf $POOL_DIR_COPY
495
496 $ZFS_SH -u || fail 4
497 done
498 printf "\n"
499done
500
501if [ ! $KEEP ]; then
502 rm -Rf $TEST_DIR
503fi
504
505exit $ERROR