]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - scripts/zimport.sh
Fix zpool_scrub_* test cases
[FreeBSD/FreeBSD.git] / scripts / zimport.sh
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 #
56 basedir="$(dirname $0)"
57
58 SCRIPT_COMMON=common.sh
59 if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
60 . "${basedir}/${SCRIPT_COMMON}"
61 else
62 echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
63 fi
64
65 PROG=zimport.sh
66
67 SRC_TAGS="zfs-0.6.1 zfs-0.6.2 master"
68 POOL_TAGS="all master"
69 TEST_DIR=`mktemp -u -d -p /var/tmp zimport.XXXXXXXX`
70 KEEP=0
71 VERBOSE=0
72 COLOR=1
73 REPO="https://github.com/zfsonlinux"
74 IMAGES_DIR="$SCRIPTDIR/zfs-images/"
75 IMAGES_TAR="https://github.com/zfsonlinux/zfs-images/tarball/master"
76 ERROR=0
77
78 CONFIG_LOG="configure.log"
79 CONFIG_OPTIONS=${CONFIG_OPTIONS:-""}
80 MAKE_LOG="make.log"
81 MAKE_OPTIONS=${MAKE_OPTIONS:-"-s -j$(nproc)"}
82
83 usage() {
84 cat << EOF
85 USAGE:
86 zimport.sh [hvl] [-r repo] [-s src-tag] [-i pool-dir] [-p pool-tag] [-f path]
87
88 DESCRIPTION:
89         ZPOOL import verification tests
90
91 OPTIONS:
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
102 EOF
103 }
104
105 while 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
140 done
141
142 # Initialize the test suite
143 init
144 check_modules || die "ZFS modules must be unloaded"
145
146 SRC_DIR="$TEST_DIR/src"
147 SRC_DIR_SPL="$SRC_DIR/spl"
148 SRC_DIR_ZFS="$SRC_DIR/zfs"
149
150 if [ $COLOR -eq 0 ]; then
151         COLOR_GREEN=""
152         COLOR_BROWN=""
153         COLOR_RED=""
154         COLOR_RESET=""
155 fi
156
157 pass_nonewline() {
158         echo -n -e "${COLOR_GREEN}Pass${COLOR_RESET}\t\t"
159 }
160
161 skip_nonewline() {
162         echo -n -e "${COLOR_BROWN}Skip${COLOR_RESET}\t\t"
163 }
164
165 fail_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 #
179 src_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 #
215 pool_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 #
232 pool_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.
268 if [ ! -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
273 fi
274
275 # Given the available images in the zfs-images directory substitute the
276 # list of available images for the reserved keywork 'all'.
277 for 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
286 done
287 POOL_TAGS="$NEW_TAGS"
288
289 if [ $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
298 fi
299
300 if [ ! -d $TEST_DIR ]; then
301         mkdir -p $TEST_DIR
302 fi
303
304 if [ ! -d $SRC_DIR ]; then
305         mkdir -p $SRC_DIR
306 fi
307
308 # Print a header for all tags which are being tested.
309 echo "--------------------- ZFS on Linux Source Versions --------------"
310 printf "%-16s" " "
311 for 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
325 done
326 echo -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 #
332 printf "%-16s" "Clone SPL"
333 for 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
361 done
362 printf "\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 #
368 printf "%-16s" "Clone ZFS"
369 for 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
397 done
398 printf "\n"
399
400 # Build the listed tags
401 printf "%-16s" "Build SPL"
402 for 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
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
415                 pass_nonewline
416         fi
417 done
418 printf "\n"
419
420 # Build the listed tags
421 printf "%-16s" "Build ZFS"
422 for 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
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
436                 pass_nonewline
437         fi
438 done
439 printf "\n"
440 echo "-----------------------------------------------------------------"
441
442 # Either create a new pool using 'zpool create', or alternately restore an
443 # existing pool from another ZFS implementation for compatibility testing.
444 for 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"
499 done
500
501 if [ ! $KEEP ]; then
502         rm -Rf $TEST_DIR
503 fi
504
505 exit $ERROR