xref: /openbmc/qemu/tests/qemu-iotests/common.rc (revision 80adf54e)
1#!/bin/bash
2#
3# Copyright (C) 2009 Red Hat, Inc.
4# Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19
20dd()
21{
22   if [ "$HOSTOS" == "Linux" ]
23   then
24        command dd --help | grep noxfer > /dev/null 2>&1
25
26        if [ "$?" -eq 0 ]
27            then
28                command dd status=noxfer $@
29            else
30                command dd $@
31            fi
32   else
33        command dd $@
34   fi
35}
36
37# poke_file 'test.img' 512 '\xff\xfe'
38poke_file()
39{
40    printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
41}
42
43# we need common.config
44if [ "$iam" != "check" ]
45then
46    if ! . ./common.config
47        then
48        echo "$iam: failed to source common.config"
49        exit 1
50    fi
51fi
52
53# make sure we have a standard umask
54umask 022
55
56if [ "$IMGOPTSSYNTAX" = "true" ]; then
57    DRIVER="driver=$IMGFMT"
58    if [ "$IMGFMT" = "luks" ]; then
59        DRIVER="$DRIVER,key-secret=keysec0"
60    fi
61    if [ "$IMGPROTO" = "file" ]; then
62        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
63        TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT"
64    elif [ "$IMGPROTO" = "nbd" ]; then
65        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
66        TEST_IMG="$DRIVER,file.driver=nbd,file.host=127.0.0.1,file.port=10810"
67    elif [ "$IMGPROTO" = "ssh" ]; then
68        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
69        TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE"
70    elif [ "$IMGPROTO" = "nfs" ]; then
71        TEST_DIR="$DRIVER,file.driver=nfs,file.filename=nfs://127.0.0.1/$TEST_DIR"
72        TEST_IMG=$TEST_DIR/t.$IMGFMT
73    else
74        TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT"
75    fi
76else
77    if [ "$IMGPROTO" = "file" ]; then
78        TEST_IMG=$TEST_DIR/t.$IMGFMT
79    elif [ "$IMGPROTO" = "nbd" ]; then
80        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
81        TEST_IMG="nbd:127.0.0.1:10810"
82    elif [ "$IMGPROTO" = "ssh" ]; then
83        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
84        TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
85    elif [ "$IMGPROTO" = "nfs" ]; then
86        TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
87        TEST_IMG=$TEST_DIR/t.$IMGFMT
88    elif [ "$IMGPROTO" = "vxhs" ]; then
89        TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
90        TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT"
91    else
92        TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
93    fi
94fi
95ORIG_TEST_IMG="$TEST_IMG"
96
97_optstr_add()
98{
99    if [ -n "$1" ]; then
100        echo "$1,$2"
101    else
102        echo "$2"
103    fi
104}
105
106_set_default_imgopts()
107{
108    if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
109        IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
110    fi
111    if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
112        IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
113    fi
114}
115
116_use_sample_img()
117{
118    SAMPLE_IMG_FILE="${1%\.bz2}"
119    TEST_IMG="$TEST_DIR/$SAMPLE_IMG_FILE"
120    bzcat "$SAMPLE_IMG_DIR/$1" > "$TEST_IMG"
121    if [ $? -ne 0 ]
122    then
123        echo "_use_sample_img error, cannot extract '$SAMPLE_IMG_DIR/$1'"
124        exit 1
125    fi
126}
127
128_make_test_img()
129{
130    # extra qemu-img options can be added by tests
131    # at least one argument (the image size) needs to be added
132    local extra_img_options=""
133    local image_size=$*
134    local optstr=""
135    local img_name=""
136    local use_backing=0
137    local backing_file=""
138    local object_options=""
139
140    if [ -n "$TEST_IMG_FILE" ]; then
141        img_name=$TEST_IMG_FILE
142    else
143        img_name=$TEST_IMG
144    fi
145
146    if [ -n "$IMGOPTS" ]; then
147        optstr=$(_optstr_add "$optstr" "$IMGOPTS")
148    fi
149    if [ -n "$IMGKEYSECRET" ]; then
150        object_options="--object secret,id=keysec0,data=$IMGKEYSECRET"
151        optstr=$(_optstr_add "$optstr" "key-secret=keysec0")
152    fi
153
154    if [ "$1" = "-b" ]; then
155        use_backing=1
156        backing_file=$2
157        image_size=$3
158    fi
159    if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then
160        optstr=$(_optstr_add "$optstr" "cluster_size=$CLUSTER_SIZE")
161    fi
162
163    if [ -n "$optstr" ]; then
164        extra_img_options="-o $optstr $extra_img_options"
165    fi
166
167    # XXX(hch): have global image options?
168    (
169     if [ $use_backing = 1 ]; then
170        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" $image_size 2>&1
171     else
172        $QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" $image_size 2>&1
173     fi
174    ) | _filter_img_create
175
176    # Start an NBD server on the image file, which is what we'll be talking to
177    if [ $IMGPROTO = "nbd" ]; then
178        # Pass a sufficiently high number to -e that should be enough for all
179        # tests
180        eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT -e 42  $TEST_IMG_FILE >/dev/null &"
181        sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
182    fi
183
184    # Start QNIO server on image directory for vxhs protocol
185    if [ $IMGPROTO = "vxhs" ]; then
186        eval "$QEMU_VXHS -d  $TEST_DIR > /dev/null &"
187        sleep 1 # Wait for server to come up.
188    fi
189}
190
191_rm_test_img()
192{
193    local img=$1
194    if [ "$IMGFMT" = "vmdk" ]; then
195        # Remove all the extents for vmdk
196        "$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
197            | xargs -I {} rm -f "{}"
198    fi
199    rm -f "$img"
200}
201
202_cleanup_test_img()
203{
204    case "$IMGPROTO" in
205
206        nbd)
207            if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then
208                local QEMU_NBD_PID
209                read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid"
210                kill ${QEMU_NBD_PID}
211                rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid"
212            fi
213            rm -f "$TEST_IMG_FILE"
214            ;;
215        vxhs)
216            if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then
217                local QEMU_VXHS_PID
218                read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid"
219                kill ${QEMU_VXHS_PID} >/dev/null 2>&1
220                rm -f "${TEST_DIR}/qemu-vxhs.pid"
221            fi
222            rm -f "$TEST_IMG_FILE"
223            ;;
224
225        file)
226            _rm_test_img "$TEST_DIR/t.$IMGFMT"
227            _rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
228            _rm_test_img "$TEST_DIR/t.$IMGFMT.base"
229            if [ -n "$SAMPLE_IMG_FILE" ]
230            then
231                rm -f "$TEST_DIR/$SAMPLE_IMG_FILE"
232                SAMPLE_IMG_FILE=
233                TEST_IMG="$ORIG_TEST_IMG"
234            fi
235            ;;
236
237        rbd)
238            rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null
239            ;;
240
241        sheepdog)
242            collie vdi delete "$TEST_DIR/t.$IMGFMT"
243            ;;
244
245    esac
246}
247
248_check_test_img()
249{
250    (
251        if [ "$IMGOPTSSYNTAX" = "true" ]; then
252            $QEMU_IMG check $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1
253        else
254            $QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1
255        fi
256    ) | _filter_testdir | _filter_qemu_img_check
257}
258
259_img_info()
260{
261    if [[ "$1" == "--format-specific" ]]; then
262        local format_specific=1
263        shift
264    else
265        local format_specific=0
266    fi
267
268    discard=0
269    regex_json_spec_start='^ *"format-specific": \{'
270    $QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \
271        sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
272            -e "s#$TEST_DIR#TEST_DIR#g" \
273            -e "s#$IMGFMT#IMGFMT#g" \
274            -e "/^disk size:/ D" \
275            -e "/actual-size/ D" | \
276        while IFS='' read line; do
277            if [[ $format_specific == 1 ]]; then
278                discard=0
279            elif [[ $line == "Format specific information:" ]]; then
280                discard=1
281            elif [[ $line =~ $regex_json_spec_start ]]; then
282                discard=2
283                regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
284            fi
285            if [[ $discard == 0 ]]; then
286                echo "$line"
287            elif [[ $discard == 1 && ! $line ]]; then
288                echo
289                discard=0
290            elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
291                discard=0
292            fi
293        done
294}
295
296_get_pids_by_name()
297{
298    if [ $# -ne 1 ]
299    then
300        echo "Usage: _get_pids_by_name process-name" 1>&2
301        exit 1
302    fi
303
304    # Algorithm ... all ps(1) variants have a time of the form MM:SS or
305    # HH:MM:SS before the psargs field, use this as the search anchor.
306    #
307    # Matches with $1 (process-name) occur if the first psarg is $1
308    # or ends in /$1 ... the matching uses sed's regular expressions,
309    # so passing a regex into $1 will work.
310
311    ps $PS_ALL_FLAGS \
312    | sed -n \
313        -e 's/$/ /' \
314        -e 's/[         ][         ]*/ /g' \
315        -e 's/^ //' \
316        -e 's/^[^ ]* //' \
317        -e "/[0-9]:[0-9][0-9]  *[^ ]*\/$1 /s/ .*//p" \
318        -e "/[0-9]:[0-9][0-9]  *$1 /s/ .*//p"
319}
320
321# fqdn for localhost
322#
323_get_fqdn()
324{
325    host=`hostname`
326    $NSLOOKUP_PROG $host | $AWK_PROG '{ if ($1 == "Name:") print $2 }'
327}
328
329# check if run as root
330#
331_need_to_be_root()
332{
333    id=`id | $SED_PROG -e 's/(.*//' -e 's/.*=//'`
334    if [ "$id" -ne 0 ]
335    then
336        echo "Arrgh ... you need to be root (not uid=$id) to run this test"
337        exit 1
338    fi
339}
340
341# bail out, setting up .notrun file
342#
343_notrun()
344{
345    echo "$*" >"$OUTPUT_DIR/$seq.notrun"
346    echo "$seq not run: $*"
347    status=0
348    exit
349}
350
351# just plain bail out
352#
353_fail()
354{
355    echo "$*" | tee -a "$OUTPUT_DIR/$seq.full"
356    echo "(see $seq.full for details)"
357    status=1
358    exit 1
359}
360
361# tests whether $IMGFMT is one of the supported image formats for a test
362#
363_supported_fmt()
364{
365    # "generic" is suitable for most image formats. For some formats it doesn't
366    # work, however (most notably read-only formats), so they can opt out by
367    # setting IMGFMT_GENERIC to false.
368    for f; do
369        if [ "$f" = "$IMGFMT" -o "$f" = "generic" -a "$IMGFMT_GENERIC" = "true" ]; then
370            return
371        fi
372    done
373
374    _notrun "not suitable for this image format: $IMGFMT"
375}
376
377# tests whether $IMGFMT is one of the unsupported image format for a test
378#
379_unsupported_fmt()
380{
381    for f; do
382        if [ "$f" = "$IMGFMT" ]; then
383            _notrun "not suitable for this image format: $IMGFMT"
384        fi
385    done
386}
387
388# tests whether $IMGPROTO is one of the supported image protocols for a test
389#
390_supported_proto()
391{
392    for f; do
393        if [ "$f" = "$IMGPROTO" -o "$f" = "generic" ]; then
394            return
395        fi
396    done
397
398    _notrun "not suitable for this image protocol: $IMGPROTO"
399}
400
401# tests whether $IMGPROTO is specified as an unsupported image protocol for a test
402#
403_unsupported_proto()
404{
405    for f; do
406        if [ "$f" = "$IMGPROTO" ]; then
407            _notrun "not suitable for this image protocol: $IMGPROTO"
408            return
409        fi
410    done
411}
412
413# tests whether the host OS is one of the supported OSes for a test
414#
415_supported_os()
416{
417    for h
418    do
419        if [ "$h" = "$HOSTOS" ]
420        then
421            return
422        fi
423    done
424
425    _notrun "not suitable for this OS: $HOSTOS"
426}
427
428_supported_cache_modes()
429{
430    for mode; do
431        if [ "$mode" = "$CACHEMODE" ]; then
432            return
433        fi
434    done
435    _notrun "not suitable for cache mode: $CACHEMODE"
436}
437
438_default_cache_mode()
439{
440    if $CACHEMODE_IS_DEFAULT; then
441        CACHEMODE="$1"
442        QEMU_IO="$QEMU_IO --cache $1"
443        return
444    fi
445}
446
447_unsupported_imgopts()
448{
449    for bad_opt
450    do
451        if echo "$IMGOPTS" | grep -q 2>/dev/null "$bad_opt"
452        then
453            _notrun "not suitable for image option: $bad_opt"
454        fi
455    done
456}
457
458# this test requires that a specified command (executable) exists
459#
460_require_command()
461{
462    if [ "$1" = "QEMU" ]; then
463        c=$QEMU_PROG
464    elif [ "$1" = "QEMU_IMG" ]; then
465        c=$QEMU_IMG_PROG
466    elif [ "$1" = "QEMU_IO" ]; then
467        c=$QEMU_IO_PROG
468    elif [ "$1" = "QEMU_NBD" ]; then
469        c=$QEMU_NBD_PROG
470    else
471        eval c=\$$1
472    fi
473    [ -x "$c" ] || _notrun "$1 utility required, skipped this test"
474}
475
476_full_imgfmt_details()
477{
478    if [ -n "$IMGOPTS" ]; then
479        echo "$IMGFMT ($IMGOPTS)"
480    else
481        echo "$IMGFMT"
482    fi
483}
484
485_full_platform_details()
486{
487    os=`uname -s`
488    host=`hostname -s`
489    kernel=`uname -r`
490    platform=`uname -m`
491    echo "$os/$platform $host $kernel"
492}
493
494_link_out_file()
495{
496   if [ -z "$1" ]; then
497      echo Error must pass \$seq.
498      exit
499   fi
500   rm -f $1
501   if [ "`uname`" == "IRIX64" ] || [ "`uname`" == "IRIX" ]; then
502      ln -s $1.irix $1
503   elif [ "`uname`" == "Linux" ]; then
504      ln -s $1.linux $1
505   else
506      echo Error test $seq does not run on the operating system: `uname`
507      exit
508   fi
509}
510
511_die()
512{
513        echo $@
514        exit 1
515}
516
517# make sure this script returns success
518true
519