]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - scripts/zimport.sh
Merge branch 'issue-2094'
[FreeBSD/FreeBSD.git] / scripts / zimport.sh
1 #!/bin/sh
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 CPUS=`grep -c ^processor /proc/cpuinfo`
77 ERROR=0
78
79 usage() {
80 cat << EOF
81 USAGE:
82 zimport.sh [hvl] [-r repo] [-s src-tag] [-i pool-dir] [-p pool-tag] [-f path]
83
84 DESCRIPTION:
85         ZPOOL import verification tests
86
87 OPTIONS:
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
98 EOF
99 }
100
101 while 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
136 done
137
138 # Initialize the test suite
139 init
140 check_modules || die "ZFS modules must be unloaded"
141
142 SRC_DIR="$TEST_DIR/src"
143 SRC_DIR_SPL="$SRC_DIR/spl"
144 SRC_DIR_ZFS="$SRC_DIR/zfs"
145
146 if [ $COLOR -eq 0 ]; then
147         COLOR_GREEN=""
148         COLOR_BROWN=""
149         COLOR_RED=""
150         COLOR_RESET=""
151 fi
152
153 pass_nonewline() {
154         echo -n -e "${COLOR_GREEN}Pass${COLOR_RESET}\t\t"
155 }
156
157 skip_nonewline() {
158         echo -n -e "${COLOR_BROWN}Skip${COLOR_RESET}\t\t"
159 }
160
161 fail_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 #
175 src_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 #
211 pool_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 #
228 pool_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
237
238         # Create a file vdev RAIDZ pool.
239         FILEDIR="$POOL_DIR_PRISTINE" $ZPOOL_CREATE \
240             -c file-raidz -p $POOL_TAG -v >/dev/null || fail
241
242         # Create a pool/fs filesystem with some random contents.
243         $ZFS_CMD create $POOL_TAG/fs || fail
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
249         $ZFS_CMD clone $POOL_TAG/fs@snap $POOL_TAG/clone || fail
250         rm -Rf /$POOL_TAG/clone/* || fail
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
256         sleep 10
257         $ZPOOL_CMD export $POOL_TAG || fail
258
259         $ZFS_SH -u || fail
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.
264 if [ ! -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
269 fi
270
271 # Given the available images in the zfs-images directory substitute the
272 # list of available images for the reserved keywork 'all'.
273 for 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
282 done
283 POOL_TAGS="$NEW_TAGS"
284
285 if [ $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
294 fi
295
296 if [ ! -d $TEST_DIR ]; then
297         mkdir -p $TEST_DIR
298 fi
299
300 # Print a header for all tags which are being tested.
301 echo "--------------------- ZFS on Linux Source Versions --------------"
302 printf "%-16s" " "
303 for TAG in $SRC_TAGS; do
304         src_set_vars $TAG
305
306         if [ "$TAG" = "installed" ]; then
307                 ZFS_VERSION=`modinfo zfs | awk '/version:/ { print $2; exit }'`
308                 if [ -n "$ZFS_VERSION" ]; then
309                         printf "%-16s" $ZFS_VERSION
310                 else
311                         echo "ZFS is not installed\n"
312                         fail
313                 fi
314         else
315                 printf "%-16s" $TAG
316         fi
317 done
318 echo -e "\n-----------------------------------------------------------------"
319
320 #
321 # Attempt to generate the tarball from your local git repository, if that
322 # fails then attempt to download the tarball from Github.
323 #
324 printf "%-16s" "Clone SPL"
325 for TAG in $SRC_TAGS; do
326         src_set_vars $TAG
327
328         if [ -d $SPL_DIR ]; then
329                 skip_nonewline
330         elif  [ "$SPL_TAG" = "installed" ]; then
331                 skip_nonewline
332         else
333                 cd $SPLSRC
334
335                 if [ ! -d $SRC_DIR_SPL ]; then
336                         mkdir -p $SRC_DIR_SPL
337                 fi
338
339                 git archive --format=tar --prefix=$SPL_TAG/ $SPL_TAG \
340                     -o $SRC_DIR_SPL/$SPL_TAG.tar &>/dev/nul || \
341                     rm $SRC_DIR_SPL/$SPL_TAG.tar
342                 if [ -s $SRC_DIR_SPL/$SPL_TAG.tar ]; then
343                         tar -xf $SRC_DIR_SPL/$SPL_TAG.tar -C $SRC_DIR_SPL
344                         rm $SRC_DIR_SPL/$SPL_TAG.tar
345                         echo -n -e "${COLOR_GREEN}Local${COLOR_RESET}\t\t"
346                 else
347                         mkdir -p $SPL_DIR || fail
348                         curl -sL $SPL_URL | tar -xz -C $SPL_DIR \
349                             --strip-components=1 || fail
350                         echo -n -e "${COLOR_GREEN}Remote${COLOR_RESET}\t\t"
351                 fi
352         fi
353 done
354 printf "\n"
355
356 #
357 # Attempt to generate the tarball from your local git repository, if that
358 # fails then attempt to download the tarball from Github.
359 #
360 printf "%-16s" "Clone ZFS"
361 for TAG in $SRC_TAGS; do
362         src_set_vars $TAG
363
364         if [ -d $ZFS_DIR ]; then
365                 skip_nonewline
366         elif  [ "$ZFS_TAG" = "installed" ]; then
367                 skip_nonewline
368         else
369                 cd $SRCDIR
370
371                 if [ ! -d $SRC_DIR_ZFS ]; then
372                         mkdir -p $SRC_DIR_ZFS
373                 fi
374
375                 git archive --format=tar --prefix=$ZFS_TAG/ $ZFS_TAG \
376                     -o $SRC_DIR_ZFS/$ZFS_TAG.tar &>/dev/nul || \
377                     rm $SRC_DIR_ZFS/$ZFS_TAG.tar
378                 if [ -s $SRC_DIR_ZFS/$ZFS_TAG.tar ]; then
379                         tar -xf $SRC_DIR_ZFS/$ZFS_TAG.tar -C $SRC_DIR_ZFS
380                         rm $SRC_DIR_ZFS/$ZFS_TAG.tar
381                         echo -n -e "${COLOR_GREEN}Local${COLOR_RESET}\t\t"
382                 else
383                         mkdir -p $ZFS_DIR || fail
384                         curl -sL $ZFS_URL | tar -xz -C $ZFS_DIR \
385                             --strip-components=1 || fail
386                         echo -n -e "${COLOR_GREEN}Remote${COLOR_RESET}\t\t"
387                 fi
388         fi
389 done
390 printf "\n"
391
392 # Build the listed tags
393 printf "%-16s" "Build SPL"
394 for TAG in $SRC_TAGS; do
395         src_set_vars $TAG
396
397         if [ -f $SPL_DIR/module/spl/spl.ko ]; then
398                 skip_nonewline
399         elif  [ "$SPL_TAG" = "installed" ]; then
400                 skip_nonewline
401         else
402                 cd $SPL_DIR
403                 make distclean &>/dev/null
404                 sh ./autogen.sh &>/dev/null || fail
405                 ./configure &>/dev/null || fail
406                 make -s -j$CPUS &>/dev/null || fail
407                 pass_nonewline
408         fi
409 done
410 printf "\n"
411
412 # Build the listed tags
413 printf "%-16s" "Build ZFS"
414 for TAG in $SRC_TAGS; do
415         src_set_vars $TAG
416
417         if [ -f $ZFS_DIR/module/zfs/zfs.ko ]; then
418                 skip_nonewline
419         elif  [ "$ZFS_TAG" = "installed" ]; then
420                 skip_nonewline
421         else
422                 cd $ZFS_DIR
423                 make distclean &>/dev/null
424                 sh ./autogen.sh &>/dev/null || fail
425                 ./configure --with-spl=$SPL_DIR &>/dev/null || fail
426                 make -s -j$CPUS &>/dev/null || fail
427                 pass_nonewline
428         fi
429 done
430 printf "\n"
431 echo "-----------------------------------------------------------------"
432
433 # Either create a new pool using 'zpool create', or alternately restore an
434 # existing pool from another ZFS implementation for compatibility testing.
435 for TAG in $POOL_TAGS; do
436         pool_set_vars $TAG
437         SKIP=0
438
439         printf "%-16s" $POOL_TAG
440         rm -Rf $POOL_DIR
441         mkdir -p $POOL_DIR_PRISTINE
442
443         # Use the existing compressed image if available.
444         if [ -f $POOL_BZIP ]; then
445                 tar -xjf $POOL_BZIP -C $POOL_DIR_PRISTINE \
446                     --strip-components=1 || fail
447         # Use the installed version to create the pool.
448         elif  [ "$TAG" = "installed" ]; then
449                 pool_create $TAG
450         # A source build is available to create the pool.
451         elif [ -d $POOL_DIR_SRC ]; then
452                 pool_create $TAG
453         else
454                 SKIP=1
455         fi
456
457         # Verify 'zpool import' works for all listed source versions.
458         for TAG in $SRC_TAGS; do
459
460                 if [ $SKIP -eq 1 ]; then
461                         skip_nonewline
462                         continue
463                 fi
464
465                 src_set_vars $TAG
466                 if [ "$TAG" != "installed" ]; then
467                         cd $ZFS_DIR
468                 fi
469                 $ZFS_SH zfs="spa_config_path=$POOL_DIR_COPY"
470
471                 cp -a --sparse=always $POOL_DIR_PRISTINE $POOL_DIR_COPY || fail
472                 POOL_NAME=`$ZPOOL_CMD import -d $POOL_DIR_COPY | \
473                     awk '/pool:/ { print $2; exit 0 }'`
474
475                 $ZPOOL_CMD import -N -d $POOL_DIR_COPY $POOL_NAME &>/dev/null
476                 if [ $? -ne 0 ]; then
477                         fail_nonewline
478                         ERROR=1
479                 else
480                         $ZPOOL_CMD export $POOL_NAME || fail
481                         pass_nonewline
482                 fi
483
484                 rm -Rf $POOL_DIR_COPY
485
486                 $ZFS_SH -u || fail
487         done
488         printf "\n"
489 done
490
491 if [ ! $KEEP ]; then
492         rm -Rf $TEST_DIR
493 fi
494
495 exit $ERROR