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