2019-03-07 17:58:38 +03:00
|
|
|
#!/usr/bin/env bash
|
2009-06-22 20:29:05 +04:00
|
|
|
#
|
|
|
|
# Copyright (C) 2009 Red Hat, Inc.
|
|
|
|
# Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2009-07-16 21:26:54 +04:00
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-06-22 20:29:05 +04:00
|
|
|
#
|
|
|
|
|
2019-03-07 17:58:39 +03:00
|
|
|
SED=
|
|
|
|
for sed in sed gsed; do
|
|
|
|
($sed --version | grep 'GNU sed') > /dev/null 2>&1
|
|
|
|
if [ "$?" -eq 0 ]; then
|
|
|
|
SED=$sed
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
if [ -z "$SED" ]; then
|
|
|
|
echo "$0: GNU sed not found"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
dd()
|
|
|
|
{
|
|
|
|
if [ "$HOSTOS" == "Linux" ]
|
2013-09-04 15:16:04 +04:00
|
|
|
then
|
|
|
|
command dd --help | grep noxfer > /dev/null 2>&1
|
|
|
|
|
|
|
|
if [ "$?" -eq 0 ]
|
|
|
|
then
|
|
|
|
command dd status=noxfer $@
|
|
|
|
else
|
|
|
|
command dd $@
|
|
|
|
fi
|
2009-06-22 20:29:05 +04:00
|
|
|
else
|
2013-09-04 15:16:04 +04:00
|
|
|
command dd $@
|
2009-06-22 20:29:05 +04:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2013-08-06 11:44:49 +04:00
|
|
|
# poke_file 'test.img' 512 '\xff\xfe'
|
|
|
|
poke_file()
|
|
|
|
{
|
|
|
|
printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
|
|
|
|
}
|
2020-03-24 20:27:56 +03:00
|
|
|
|
|
|
|
# poke_file_le $img_filename $offset $byte_width $value
|
|
|
|
# Example: poke_file_le "$TEST_IMG" 512 2 65534
|
|
|
|
poke_file_le()
|
|
|
|
{
|
|
|
|
local img=$1 ofs=$2 len=$3 val=$4 str=''
|
|
|
|
|
|
|
|
while ((len--)); do
|
|
|
|
str+=$(printf '\\x%02x' $((val & 0xff)))
|
|
|
|
val=$((val >> 8))
|
|
|
|
done
|
|
|
|
|
|
|
|
poke_file "$img" "$ofs" "$str"
|
|
|
|
}
|
|
|
|
|
|
|
|
# poke_file_be $img_filename $offset $byte_width $value
|
|
|
|
# Example: poke_file_be "$TEST_IMG" 512 2 65279
|
|
|
|
poke_file_be()
|
|
|
|
{
|
|
|
|
local img=$1 ofs=$2 len=$3 val=$4
|
|
|
|
local str=$(printf "%0$((len * 2))x\n" $val | sed 's/\(..\)/\\x\1/g')
|
|
|
|
|
|
|
|
poke_file "$img" "$ofs" "$str"
|
|
|
|
}
|
2013-08-06 11:44:49 +04:00
|
|
|
|
2019-10-11 18:28:13 +03:00
|
|
|
# peek_file_le 'test.img' 512 2 => 65534
|
|
|
|
peek_file_le()
|
|
|
|
{
|
2020-02-26 15:54:24 +03:00
|
|
|
local val=0 shift=0 byte
|
|
|
|
|
|
|
|
# coreutils' od --endian is not portable, so manually assemble bytes.
|
|
|
|
for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do
|
|
|
|
val=$(( val | (byte << shift) ))
|
|
|
|
shift=$((shift + 8))
|
|
|
|
done
|
|
|
|
printf %llu $val
|
2019-10-11 18:28:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
# peek_file_be 'test.img' 512 2 => 65279
|
|
|
|
peek_file_be()
|
|
|
|
{
|
2020-02-26 15:54:24 +03:00
|
|
|
local val=0 byte
|
|
|
|
|
|
|
|
# coreutils' od --endian is not portable, so manually assemble bytes.
|
|
|
|
for byte in $(od -j"$2" -N"$3" -An -v -tu1 "$1"); do
|
|
|
|
val=$(( (val << 8) | byte ))
|
|
|
|
done
|
|
|
|
printf %llu $val
|
2019-10-11 18:28:13 +03:00
|
|
|
}
|
|
|
|
|
2020-02-26 15:54:24 +03:00
|
|
|
# peek_file_raw 'test.img' 512 2 => '\xff\xfe'. Do not use if the raw data
|
|
|
|
# is likely to contain \0 or trailing \n.
|
2019-10-11 18:28:13 +03:00
|
|
|
peek_file_raw()
|
|
|
|
{
|
|
|
|
dd if="$1" bs=1 skip="$2" count="$3" status=none
|
|
|
|
}
|
|
|
|
|
2021-02-04 15:48:33 +03:00
|
|
|
config=common.config
|
|
|
|
test -f $config || config=../common.config
|
|
|
|
if ! test -f $config
|
|
|
|
then
|
|
|
|
echo "$0: failed to find common.config"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if ! . $config
|
2017-09-12 17:44:55 +03:00
|
|
|
then
|
2017-09-12 17:44:58 +03:00
|
|
|
echo "$0: failed to source common.config"
|
2017-09-12 17:44:55 +03:00
|
|
|
exit 1
|
2009-06-22 20:29:05 +04:00
|
|
|
fi
|
|
|
|
|
2019-09-04 12:11:19 +03:00
|
|
|
# Set the variables to the empty string to turn Valgrind off
|
|
|
|
# for specific processes, e.g.
|
|
|
|
# $ VALGRIND_QEMU_IO= ./check -qcow2 -valgrind 015
|
|
|
|
|
|
|
|
: ${VALGRIND_QEMU_VM=$VALGRIND_QEMU}
|
|
|
|
: ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU}
|
|
|
|
: ${VALGRIND_QEMU_IO=$VALGRIND_QEMU}
|
|
|
|
: ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU}
|
2020-10-27 22:05:57 +03:00
|
|
|
: ${VALGRIND_QSD=$VALGRIND_QEMU}
|
2019-09-04 12:11:19 +03:00
|
|
|
|
|
|
|
# The Valgrind own parameters may be set with
|
|
|
|
# its environment variable VALGRIND_OPTS, e.g.
|
|
|
|
# $ VALGRIND_OPTS="--leak-check=yes" ./check -qcow2 -valgrind 015
|
|
|
|
|
|
|
|
_qemu_proc_exec()
|
|
|
|
{
|
|
|
|
local VALGRIND_LOGFILE="$1"
|
|
|
|
shift
|
2019-09-04 12:11:20 +03:00
|
|
|
if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
|
2019-09-04 12:11:19 +03:00
|
|
|
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$@"
|
|
|
|
else
|
|
|
|
exec "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
_qemu_proc_valgrind_log()
|
|
|
|
{
|
|
|
|
local VALGRIND_LOGFILE="$1"
|
|
|
|
local RETVAL="$2"
|
2019-09-04 12:11:20 +03:00
|
|
|
if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
|
2019-09-04 12:11:19 +03:00
|
|
|
if [ $RETVAL == 99 ]; then
|
|
|
|
cat "${VALGRIND_LOGFILE}"
|
|
|
|
fi
|
|
|
|
rm -f "${VALGRIND_LOGFILE}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-09-12 17:44:54 +03:00
|
|
|
_qemu_wrapper()
|
|
|
|
{
|
2019-09-04 12:11:19 +03:00
|
|
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
2017-09-12 17:44:54 +03:00
|
|
|
(
|
|
|
|
if [ -n "${QEMU_NEED_PID}" ]; then
|
|
|
|
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
|
|
|
|
fi
|
2021-08-09 12:01:06 +03:00
|
|
|
|
|
|
|
GDB=""
|
|
|
|
if [ -n "${GDB_OPTIONS}" ]; then
|
|
|
|
GDB="gdbserver ${GDB_OPTIONS}"
|
|
|
|
fi
|
|
|
|
|
2019-09-04 12:11:19 +03:00
|
|
|
VALGRIND_QEMU="${VALGRIND_QEMU_VM}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
2021-08-09 12:01:06 +03:00
|
|
|
$GDB "$QEMU_PROG" $QEMU_OPTIONS "$@"
|
2017-09-12 17:44:54 +03:00
|
|
|
)
|
2019-09-04 12:11:19 +03:00
|
|
|
RETVAL=$?
|
|
|
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
|
|
|
return $RETVAL
|
2017-09-12 17:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
_qemu_img_wrapper()
|
|
|
|
{
|
2019-09-04 12:11:19 +03:00
|
|
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
|
|
|
(
|
|
|
|
VALGRIND_QEMU="${VALGRIND_QEMU_IMG}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
|
|
|
"$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@"
|
|
|
|
)
|
|
|
|
RETVAL=$?
|
|
|
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
|
|
|
return $RETVAL
|
2017-09-12 17:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
_qemu_io_wrapper()
|
|
|
|
{
|
|
|
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
|
|
|
local QEMU_IO_ARGS="$QEMU_IO_OPTIONS"
|
|
|
|
if [ "$IMGOPTSSYNTAX" = "true" ]; then
|
|
|
|
QEMU_IO_ARGS="--image-opts $QEMU_IO_ARGS"
|
|
|
|
if [ -n "$IMGKEYSECRET" ]; then
|
|
|
|
QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
(
|
2019-09-04 12:11:19 +03:00
|
|
|
VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
|
|
|
"$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
|
2017-09-12 17:44:54 +03:00
|
|
|
)
|
|
|
|
RETVAL=$?
|
2019-09-04 12:11:19 +03:00
|
|
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
|
|
|
return $RETVAL
|
2017-09-12 17:44:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
_qemu_nbd_wrapper()
|
|
|
|
{
|
2019-09-04 12:11:19 +03:00
|
|
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
|
|
|
(
|
|
|
|
VALGRIND_QEMU="${VALGRIND_QEMU_NBD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
|
|
|
"$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
|
|
|
|
$QEMU_NBD_OPTIONS "$@"
|
|
|
|
)
|
|
|
|
RETVAL=$?
|
|
|
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
|
|
|
return $RETVAL
|
2017-09-12 17:44:54 +03:00
|
|
|
}
|
|
|
|
|
2020-10-27 22:05:57 +03:00
|
|
|
_qemu_storage_daemon_wrapper()
|
|
|
|
{
|
|
|
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
|
|
|
(
|
|
|
|
if [ -n "${QSD_NEED_PID}" ]; then
|
|
|
|
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-storage-daemon.pid"
|
|
|
|
fi
|
|
|
|
VALGRIND_QEMU="${VALGRIND_QSD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
|
|
|
"$QSD_PROG" $QSD_OPTIONS "$@"
|
|
|
|
)
|
|
|
|
RETVAL=$?
|
|
|
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
|
|
|
return $RETVAL
|
|
|
|
}
|
|
|
|
|
2019-09-04 12:11:20 +03:00
|
|
|
# Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141
|
|
|
|
# Until valgrind 3.16+ is ubiquitous, we must work around a hang in
|
|
|
|
# valgrind when issuing sigkill. Disable valgrind for this invocation.
|
|
|
|
_NO_VALGRIND()
|
|
|
|
{
|
|
|
|
NO_VALGRIND="y" "$@"
|
|
|
|
}
|
|
|
|
|
2017-09-12 17:44:54 +03:00
|
|
|
export QEMU=_qemu_wrapper
|
|
|
|
export QEMU_IMG=_qemu_img_wrapper
|
|
|
|
export QEMU_IO=_qemu_io_wrapper
|
|
|
|
export QEMU_NBD=_qemu_nbd_wrapper
|
2020-10-27 22:05:57 +03:00
|
|
|
export QSD=_qemu_storage_daemon_wrapper
|
2017-09-12 17:44:54 +03:00
|
|
|
|
2016-05-10 19:11:27 +03:00
|
|
|
if [ "$IMGOPTSSYNTAX" = "true" ]; then
|
|
|
|
DRIVER="driver=$IMGFMT"
|
2017-09-12 17:44:56 +03:00
|
|
|
QEMU_IMG_EXTRA_ARGS="--image-opts $QEMU_IMG_EXTRA_ARGS"
|
|
|
|
if [ -n "$IMGKEYSECRET" ]; then
|
|
|
|
QEMU_IMG_EXTRA_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IMG_EXTRA_ARGS"
|
|
|
|
fi
|
2016-05-10 19:11:29 +03:00
|
|
|
if [ "$IMGFMT" = "luks" ]; then
|
|
|
|
DRIVER="$DRIVER,key-secret=keysec0"
|
|
|
|
fi
|
2016-05-10 19:11:27 +03:00
|
|
|
if [ "$IMGPROTO" = "file" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
|
|
|
TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT"
|
|
|
|
elif [ "$IMGPROTO" = "nbd" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
2019-12-18 13:48:55 +03:00
|
|
|
TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix"
|
|
|
|
TEST_IMG="$TEST_IMG,file.path=$SOCK_DIR/nbd"
|
2020-10-27 22:05:58 +03:00
|
|
|
elif [ "$IMGPROTO" = "fuse" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
|
|
|
TEST_IMG="$DRIVER,file.filename=$SOCK_DIR/fuse-t.$IMGFMT"
|
2016-05-10 19:11:27 +03:00
|
|
|
elif [ "$IMGPROTO" = "ssh" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
|
|
|
TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE"
|
|
|
|
elif [ "$IMGPROTO" = "nfs" ]; then
|
|
|
|
TEST_DIR="$DRIVER,file.driver=nfs,file.filename=nfs://127.0.0.1/$TEST_DIR"
|
2016-10-27 14:16:56 +03:00
|
|
|
TEST_IMG=$TEST_DIR/t.$IMGFMT
|
2016-05-10 19:11:27 +03:00
|
|
|
else
|
|
|
|
TEST_IMG="$DRIVER,file.driver=$IMGPROTO,file.filename=$TEST_DIR/t.$IMGFMT"
|
|
|
|
fi
|
2011-01-17 20:01:17 +03:00
|
|
|
else
|
2017-09-12 17:44:56 +03:00
|
|
|
QEMU_IMG_EXTRA_ARGS=
|
2016-05-10 19:11:27 +03:00
|
|
|
if [ "$IMGPROTO" = "file" ]; then
|
|
|
|
TEST_IMG=$TEST_DIR/t.$IMGFMT
|
|
|
|
elif [ "$IMGPROTO" = "nbd" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
2019-11-15 00:34:13 +03:00
|
|
|
TEST_IMG="nbd+unix:///?socket=$SOCK_DIR/nbd"
|
2020-10-27 22:05:58 +03:00
|
|
|
elif [ "$IMGPROTO" = "fuse" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
|
|
|
TEST_IMG="$SOCK_DIR/fuse-t.$IMGFMT"
|
2016-05-10 19:11:27 +03:00
|
|
|
elif [ "$IMGPROTO" = "ssh" ]; then
|
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
2019-02-25 22:08:27 +03:00
|
|
|
REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR"
|
2016-05-10 19:11:27 +03:00
|
|
|
TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
|
|
|
|
elif [ "$IMGPROTO" = "nfs" ]; then
|
2018-05-17 18:26:14 +03:00
|
|
|
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
|
2018-05-17 19:33:52 +03:00
|
|
|
REMOTE_TEST_DIR="nfs://127.0.0.1$TEST_DIR"
|
2018-05-17 18:26:14 +03:00
|
|
|
TEST_IMG="nfs://127.0.0.1$TEST_IMG_FILE"
|
2016-05-10 19:11:27 +03:00
|
|
|
else
|
|
|
|
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
|
|
|
|
fi
|
2011-01-17 20:01:17 +03:00
|
|
|
fi
|
iotests: Let _make_test_img guess $TEST_IMG_FILE
When most iotests want to create a test image that is named differently
from the default $TEST_IMG, they do something like this:
TEST_IMG="$TEST_IMG.base" _make_test_img $options
This works fine with the "file" protocol, but not so much for anything
else: _make_test_img tries to create an image under $TEST_IMG_FILE
first, and only under $TEST_IMG if the former is not set; and on
everything but "file", $TEST_IMG_FILE is set.
There are two ways we can fix this: First, we could make all tests
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
(e.g. with something like _set_test_img_suffix $suffix that would affect
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
pretty clean solution, and this is maybe what we should have done from
the start.
But it would also require changes to most existing bash tests. So the
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
points to the original value. If so, it is possible that the caller has
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
most protocols) derive the corresponding $TEST_IMG_FILE value from
$TEST_IMG value and thus work around what technically is the caller
misbehaving.
This second solution is less clean, but it is robust against people
keeping their old habit of adjusting TEST_IMG only, and requires much
less changes. So this patch implements it.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2020-10-27 22:05:54 +03:00
|
|
|
ORIG_TEST_IMG_FILE=$TEST_IMG_FILE
|
2017-07-27 16:13:20 +03:00
|
|
|
ORIG_TEST_IMG="$TEST_IMG"
|
2009-06-22 20:29:05 +04:00
|
|
|
|
2020-10-27 22:05:58 +03:00
|
|
|
FUSE_PIDS=()
|
|
|
|
FUSE_EXPORTS=()
|
|
|
|
|
2017-09-12 17:44:56 +03:00
|
|
|
if [ -z "$TEST_DIR" ]; then
|
2018-11-16 23:33:03 +03:00
|
|
|
TEST_DIR=$PWD/scratch
|
2017-09-12 17:44:56 +03:00
|
|
|
fi
|
|
|
|
|
|
|
|
QEMU_TEST_DIR="${TEST_DIR}"
|
|
|
|
|
|
|
|
if [ ! -e "$TEST_DIR" ]; then
|
|
|
|
mkdir "$TEST_DIR"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -d "$TEST_DIR" ]; then
|
2018-10-04 19:18:46 +03:00
|
|
|
echo "common.rc: Error: \$TEST_DIR ($TEST_DIR) is not a directory"
|
2017-09-12 17:44:56 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2018-05-17 19:33:52 +03:00
|
|
|
if [ -z "$REMOTE_TEST_DIR" ]; then
|
|
|
|
REMOTE_TEST_DIR="$TEST_DIR"
|
|
|
|
fi
|
|
|
|
|
2017-09-12 17:44:56 +03:00
|
|
|
if [ ! -d "$SAMPLE_IMG_DIR" ]; then
|
2018-10-04 19:18:46 +03:00
|
|
|
echo "common.rc: Error: \$SAMPLE_IMG_DIR ($SAMPLE_IMG_DIR) is not a directory"
|
2017-09-12 17:44:56 +03:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2013-09-25 16:12:20 +04:00
|
|
|
_use_sample_img()
|
|
|
|
{
|
|
|
|
SAMPLE_IMG_FILE="${1%\.bz2}"
|
|
|
|
TEST_IMG="$TEST_DIR/$SAMPLE_IMG_FILE"
|
|
|
|
bzcat "$SAMPLE_IMG_DIR/$1" > "$TEST_IMG"
|
|
|
|
if [ $? -ne 0 ]
|
|
|
|
then
|
|
|
|
echo "_use_sample_img error, cannot extract '$SAMPLE_IMG_DIR/$1'"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2018-07-11 09:40:46 +03:00
|
|
|
_stop_nbd_server()
|
|
|
|
{
|
|
|
|
if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then
|
|
|
|
local QEMU_NBD_PID
|
|
|
|
read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid"
|
|
|
|
kill ${QEMU_NBD_PID}
|
2019-11-15 00:34:13 +03:00
|
|
|
rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid" "$SOCK_DIR/nbd"
|
2018-07-11 09:40:46 +03:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-11-07 19:37:08 +03:00
|
|
|
# Gets the data_file value from IMGOPTS and replaces the '$TEST_IMG'
|
|
|
|
# pattern by '$1'
|
|
|
|
# Caution: The replacement is done with sed, so $1 must be escaped
|
|
|
|
# properly. (The delimiter is '#'.)
|
|
|
|
_get_data_file()
|
|
|
|
{
|
|
|
|
if ! echo "$IMGOPTS" | grep -q 'data_file='; then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$IMGOPTS" | sed -e 's/.*data_file=\([^,]*\).*/\1/' \
|
|
|
|
| sed -e "s#\\\$TEST_IMG#$1#"
|
|
|
|
}
|
|
|
|
|
iotests: Let _make_test_img guess $TEST_IMG_FILE
When most iotests want to create a test image that is named differently
from the default $TEST_IMG, they do something like this:
TEST_IMG="$TEST_IMG.base" _make_test_img $options
This works fine with the "file" protocol, but not so much for anything
else: _make_test_img tries to create an image under $TEST_IMG_FILE
first, and only under $TEST_IMG if the former is not set; and on
everything but "file", $TEST_IMG_FILE is set.
There are two ways we can fix this: First, we could make all tests
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
(e.g. with something like _set_test_img_suffix $suffix that would affect
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
pretty clean solution, and this is maybe what we should have done from
the start.
But it would also require changes to most existing bash tests. So the
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
points to the original value. If so, it is possible that the caller has
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
most protocols) derive the corresponding $TEST_IMG_FILE value from
$TEST_IMG value and thus work around what technically is the caller
misbehaving.
This second solution is less clean, but it is robust against people
keeping their old habit of adjusting TEST_IMG only, and requires much
less changes. So this patch implements it.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2020-10-27 22:05:54 +03:00
|
|
|
# Translate a $TEST_IMG to its corresponding $TEST_IMG_FILE for
|
|
|
|
# different protocols
|
|
|
|
_test_img_to_test_img_file()
|
|
|
|
{
|
|
|
|
case "$IMGPROTO" in
|
|
|
|
file)
|
|
|
|
echo "$1"
|
|
|
|
;;
|
|
|
|
|
2020-10-27 22:05:58 +03:00
|
|
|
fuse)
|
|
|
|
echo "$1" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#"
|
|
|
|
;;
|
|
|
|
|
iotests: Let _make_test_img guess $TEST_IMG_FILE
When most iotests want to create a test image that is named differently
from the default $TEST_IMG, they do something like this:
TEST_IMG="$TEST_IMG.base" _make_test_img $options
This works fine with the "file" protocol, but not so much for anything
else: _make_test_img tries to create an image under $TEST_IMG_FILE
first, and only under $TEST_IMG if the former is not set; and on
everything but "file", $TEST_IMG_FILE is set.
There are two ways we can fix this: First, we could make all tests
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
(e.g. with something like _set_test_img_suffix $suffix that would affect
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
pretty clean solution, and this is maybe what we should have done from
the start.
But it would also require changes to most existing bash tests. So the
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
points to the original value. If so, it is possible that the caller has
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
most protocols) derive the corresponding $TEST_IMG_FILE value from
$TEST_IMG value and thus work around what technically is the caller
misbehaving.
This second solution is less clean, but it is robust against people
keeping their old habit of adjusting TEST_IMG only, and requires much
less changes. So this patch implements it.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2020-10-27 22:05:54 +03:00
|
|
|
nfs)
|
|
|
|
echo "$1" | sed -e "s#nfs://127.0.0.1##"
|
|
|
|
;;
|
|
|
|
|
|
|
|
ssh)
|
|
|
|
echo "$1" | \
|
|
|
|
sed -e "s#ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?##"
|
|
|
|
;;
|
|
|
|
|
|
|
|
*)
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
_make_test_img()
|
|
|
|
{
|
|
|
|
# extra qemu-img options can be added by tests
|
|
|
|
# at least one argument (the image size) needs to be added
|
2012-03-14 22:57:23 +04:00
|
|
|
local extra_img_options=""
|
2012-03-27 15:45:14 +04:00
|
|
|
local optstr=""
|
2012-11-02 17:01:23 +04:00
|
|
|
local img_name=""
|
2013-10-31 19:57:37 +04:00
|
|
|
local use_backing=0
|
|
|
|
local backing_file=""
|
2016-05-10 19:11:28 +03:00
|
|
|
local object_options=""
|
2019-11-07 19:36:55 +03:00
|
|
|
local opts_param=false
|
2019-11-07 19:36:54 +03:00
|
|
|
local misc_params=()
|
2012-11-02 17:01:23 +04:00
|
|
|
|
2020-10-27 22:05:58 +03:00
|
|
|
if [[ $IMGPROTO == fuse && $TEST_IMG == $SOCK_DIR/fuse-* ]]; then
|
|
|
|
# The caller may be trying to overwrite an existing image
|
|
|
|
_rm_test_img "$TEST_IMG"
|
|
|
|
fi
|
|
|
|
|
iotests: Let _make_test_img guess $TEST_IMG_FILE
When most iotests want to create a test image that is named differently
from the default $TEST_IMG, they do something like this:
TEST_IMG="$TEST_IMG.base" _make_test_img $options
This works fine with the "file" protocol, but not so much for anything
else: _make_test_img tries to create an image under $TEST_IMG_FILE
first, and only under $TEST_IMG if the former is not set; and on
everything but "file", $TEST_IMG_FILE is set.
There are two ways we can fix this: First, we could make all tests
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
(e.g. with something like _set_test_img_suffix $suffix that would affect
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
pretty clean solution, and this is maybe what we should have done from
the start.
But it would also require changes to most existing bash tests. So the
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
points to the original value. If so, it is possible that the caller has
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
most protocols) derive the corresponding $TEST_IMG_FILE value from
$TEST_IMG value and thus work around what technically is the caller
misbehaving.
This second solution is less clean, but it is robust against people
keeping their old habit of adjusting TEST_IMG only, and requires much
less changes. So this patch implements it.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2020-10-27 22:05:54 +03:00
|
|
|
if [ -z "$TEST_IMG_FILE" ]; then
|
2012-11-02 17:01:23 +04:00
|
|
|
img_name=$TEST_IMG
|
iotests: Let _make_test_img guess $TEST_IMG_FILE
When most iotests want to create a test image that is named differently
from the default $TEST_IMG, they do something like this:
TEST_IMG="$TEST_IMG.base" _make_test_img $options
This works fine with the "file" protocol, but not so much for anything
else: _make_test_img tries to create an image under $TEST_IMG_FILE
first, and only under $TEST_IMG if the former is not set; and on
everything but "file", $TEST_IMG_FILE is set.
There are two ways we can fix this: First, we could make all tests
adjust not only TEST_IMG, but also TEST_IMG_FILE if that is present
(e.g. with something like _set_test_img_suffix $suffix that would affect
not only TEST_IMG but also TEST_IMG_FILE, if necessary). This is a
pretty clean solution, and this is maybe what we should have done from
the start.
But it would also require changes to most existing bash tests. So the
alternative is this: Let _make_test_img see whether $TEST_IMG_FILE still
points to the original value. If so, it is possible that the caller has
adjusted $TEST_IMG but not $TEST_IMG_FILE. In such a case, we can (for
most protocols) derive the corresponding $TEST_IMG_FILE value from
$TEST_IMG value and thus work around what technically is the caller
misbehaving.
This second solution is less clean, but it is robust against people
keeping their old habit of adjusting TEST_IMG only, and requires much
less changes. So this patch implements it.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201027190600.192171-15-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2020-10-27 22:05:54 +03:00
|
|
|
elif [ "$IMGOPTSSYNTAX" != "true" -a \
|
|
|
|
"$TEST_IMG_FILE" = "$ORIG_TEST_IMG_FILE" ]; then
|
|
|
|
# Handle cases of tests only updating TEST_IMG, but not TEST_IMG_FILE
|
|
|
|
img_name=$(_test_img_to_test_img_file "$TEST_IMG")
|
|
|
|
if [ "$?" != 0 ]; then
|
|
|
|
img_name=$TEST_IMG_FILE
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# $TEST_IMG_FILE is not the default value, so it definitely has been
|
|
|
|
# modified by the test
|
|
|
|
img_name=$TEST_IMG_FILE
|
2012-11-02 17:01:23 +04:00
|
|
|
fi
|
2012-03-27 15:45:14 +04:00
|
|
|
|
|
|
|
if [ -n "$IMGOPTS" ]; then
|
2019-11-07 19:37:08 +03:00
|
|
|
imgopts_expanded=$(echo "$IMGOPTS" | sed -e "s#\\\$TEST_IMG#$img_name#")
|
|
|
|
optstr=$(_optstr_add "$optstr" "$imgopts_expanded")
|
2012-03-27 15:45:14 +04:00
|
|
|
fi
|
2016-05-10 19:11:28 +03:00
|
|
|
if [ -n "$IMGKEYSECRET" ]; then
|
|
|
|
object_options="--object secret,id=keysec0,data=$IMGKEYSECRET"
|
|
|
|
optstr=$(_optstr_add "$optstr" "key-secret=keysec0")
|
|
|
|
fi
|
2009-06-22 20:29:05 +04:00
|
|
|
|
2019-11-07 19:36:54 +03:00
|
|
|
for param; do
|
|
|
|
if [ "$use_backing" = "1" -a -z "$backing_file" ]; then
|
|
|
|
backing_file=$param
|
|
|
|
continue
|
2019-11-07 19:36:55 +03:00
|
|
|
elif $opts_param; then
|
|
|
|
optstr=$(_optstr_add "$optstr" "$param")
|
|
|
|
opts_param=false
|
|
|
|
continue
|
2019-11-07 19:36:54 +03:00
|
|
|
fi
|
|
|
|
|
|
|
|
case "$param" in
|
|
|
|
-b)
|
|
|
|
use_backing=1
|
|
|
|
;;
|
|
|
|
|
2019-11-07 19:36:55 +03:00
|
|
|
-o)
|
|
|
|
opts_param=true
|
|
|
|
;;
|
|
|
|
|
|
|
|
--no-opts)
|
|
|
|
optstr=""
|
|
|
|
;;
|
|
|
|
|
2019-11-07 19:36:54 +03:00
|
|
|
*)
|
|
|
|
misc_params=("${misc_params[@]}" "$param")
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2010-10-31 23:10:20 +03:00
|
|
|
if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then
|
2012-03-27 15:45:14 +04:00
|
|
|
optstr=$(_optstr_add "$optstr" "cluster_size=$CLUSTER_SIZE")
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$optstr" ]; then
|
|
|
|
extra_img_options="-o $optstr $extra_img_options"
|
2009-10-01 21:29:59 +04:00
|
|
|
fi
|
|
|
|
|
2018-07-11 09:40:46 +03:00
|
|
|
if [ $IMGPROTO = "nbd" ]; then
|
|
|
|
_stop_nbd_server
|
|
|
|
fi
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# XXX(hch): have global image options?
|
2013-10-31 19:57:37 +04:00
|
|
|
(
|
|
|
|
if [ $use_backing = 1 ]; then
|
2019-11-07 19:36:54 +03:00
|
|
|
$QEMU_IMG create $object_options -f $IMGFMT $extra_img_options -b "$backing_file" "$img_name" "${misc_params[@]}" 2>&1
|
2013-10-31 19:57:37 +04:00
|
|
|
else
|
2019-11-07 19:36:54 +03:00
|
|
|
$QEMU_IMG create $object_options -f $IMGFMT $extra_img_options "$img_name" "${misc_params[@]}" 2>&1
|
2013-10-31 19:57:37 +04:00
|
|
|
fi
|
2014-08-19 21:28:58 +04:00
|
|
|
) | _filter_img_create
|
2012-11-02 17:01:23 +04:00
|
|
|
|
2019-11-15 00:34:13 +03:00
|
|
|
# Start an NBD server on the image file, which is what we'll be talking to.
|
|
|
|
# Once NBD gains resize support, we may also want to use -f raw at the
|
|
|
|
# server and interpret format over NBD, but for now, the format is
|
|
|
|
# interpreted at the server and raw data sent over NBD.
|
2012-11-02 17:01:23 +04:00
|
|
|
if [ $IMGPROTO = "nbd" ]; then
|
2017-04-26 17:14:07 +03:00
|
|
|
# Pass a sufficiently high number to -e that should be enough for all
|
|
|
|
# tests
|
2019-11-15 00:34:13 +03:00
|
|
|
eval "$QEMU_NBD -v -t -k '$SOCK_DIR/nbd' -f $IMGFMT -e 42 -x '' $TEST_IMG_FILE >/dev/null &"
|
2012-11-02 17:01:23 +04:00
|
|
|
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
|
|
|
|
fi
|
2020-10-27 22:05:58 +03:00
|
|
|
|
|
|
|
if [ $IMGPROTO = "fuse" -a -f "$img_name" ]; then
|
|
|
|
local export_mp
|
|
|
|
local pid
|
|
|
|
local pidfile
|
|
|
|
local timeout
|
|
|
|
|
|
|
|
export_mp=$(echo "$img_name" | sed -e "s#$TEST_DIR/#$SOCK_DIR/fuse-#")
|
|
|
|
if ! echo "$export_mp" | grep -q "^$SOCK_DIR"; then
|
|
|
|
echo 'Cannot use FUSE exports with images outside of TEST_DIR' >&2
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
touch "$export_mp"
|
|
|
|
rm -f "$SOCK_DIR/fuse-output"
|
|
|
|
|
|
|
|
# Usually, users would export formatted nodes. But we present fuse as a
|
|
|
|
# protocol-level driver here, so we have to leave the format to the
|
|
|
|
# client.
|
export/fuse: Add allow-other option
Without the allow_other mount option, no user (not even root) but the
one who started qemu/the storage daemon can access the export. Allow
users to configure the export such that such accesses are possible.
While allow_other is probably what users want, we cannot make it an
unconditional default, because passing it is only possible (for non-root
users) if the global fuse.conf configuration file allows it. Thus, the
default is an 'auto' mode, in which we first try with allow_other, and
then fall back to without.
FuseExport.allow_other reports whether allow_other was actually used as
a mount option or not. Currently, this information is not used, but a
future patch will let this field decide whether e.g. an export's UID and
GID can be changed through chmod.
One notable thing about 'auto' mode is that libfuse may print error
messages directly to stderr, and so may fusermount (which it executes).
Our export code cannot really filter or hide them. Therefore, if 'auto'
fails its first attempt and has to fall back, fusermount will print an
error message that mounting with allow_other failed.
This behavior necessitates a change to iotest 308, namely we need to
filter out this error message (because if the first attempt at mounting
with allow_other succeeds, there will be no such message).
Furthermore, common.rc's _make_test_img should use allow-other=off for
FUSE exports, because iotests generally do not need to access images
from other users, so allow-other=on or allow-other=auto have no
advantage. OTOH, allow-other=on will not work on systems where
user_allow_other is disabled, and with allow-other=auto, we get said
error message that we would need to filter out again. Just disabling
allow-other is simplest.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210625142317.271673-3-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-06-25 17:23:13 +03:00
|
|
|
# Switch off allow-other, because in general we do not need it for
|
|
|
|
# iotests. The default allow-other=auto has the downside of printing a
|
|
|
|
# fusermount error on its first attempt if allow_other is not
|
|
|
|
# permissible, which we would need to filter.
|
2020-10-27 22:05:58 +03:00
|
|
|
QSD_NEED_PID=y $QSD \
|
|
|
|
--blockdev file,node-name=export-node,filename=$img_name,discard=unmap \
|
export/fuse: Add allow-other option
Without the allow_other mount option, no user (not even root) but the
one who started qemu/the storage daemon can access the export. Allow
users to configure the export such that such accesses are possible.
While allow_other is probably what users want, we cannot make it an
unconditional default, because passing it is only possible (for non-root
users) if the global fuse.conf configuration file allows it. Thus, the
default is an 'auto' mode, in which we first try with allow_other, and
then fall back to without.
FuseExport.allow_other reports whether allow_other was actually used as
a mount option or not. Currently, this information is not used, but a
future patch will let this field decide whether e.g. an export's UID and
GID can be changed through chmod.
One notable thing about 'auto' mode is that libfuse may print error
messages directly to stderr, and so may fusermount (which it executes).
Our export code cannot really filter or hide them. Therefore, if 'auto'
fails its first attempt and has to fall back, fusermount will print an
error message that mounting with allow_other failed.
This behavior necessitates a change to iotest 308, namely we need to
filter out this error message (because if the first attempt at mounting
with allow_other succeeds, there will be no such message).
Furthermore, common.rc's _make_test_img should use allow-other=off for
FUSE exports, because iotests generally do not need to access images
from other users, so allow-other=on or allow-other=auto have no
advantage. OTOH, allow-other=on will not work on systems where
user_allow_other is disabled, and with allow-other=auto, we get said
error message that we would need to filter out again. Just disabling
allow-other is simplest.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210625142317.271673-3-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-06-25 17:23:13 +03:00
|
|
|
--export fuse,id=fuse-export,node-name=export-node,mountpoint="$export_mp",writable=on,growable=on,allow-other=off \
|
2020-10-27 22:05:58 +03:00
|
|
|
&
|
|
|
|
|
|
|
|
pidfile="$QEMU_TEST_DIR/qemu-storage-daemon.pid"
|
|
|
|
|
|
|
|
# Wait for the PID file
|
|
|
|
while [ ! -f "$pidfile" ]; do
|
|
|
|
sleep 0.5
|
|
|
|
done
|
|
|
|
|
|
|
|
pid=$(cat "$pidfile")
|
|
|
|
rm -f "$pidfile"
|
|
|
|
|
|
|
|
FUSE_PIDS+=($pid)
|
|
|
|
FUSE_EXPORTS+=("$export_mp")
|
|
|
|
fi
|
2009-06-22 20:29:05 +04:00
|
|
|
}
|
|
|
|
|
2013-11-26 10:40:34 +04:00
|
|
|
_rm_test_img()
|
|
|
|
{
|
|
|
|
local img=$1
|
2020-10-27 22:05:58 +03:00
|
|
|
|
|
|
|
if [[ $IMGPROTO == fuse && $img == $SOCK_DIR/fuse-* ]]; then
|
|
|
|
# Drop a FUSE export
|
|
|
|
local df_output
|
|
|
|
local i
|
|
|
|
local image_file
|
|
|
|
local index=''
|
|
|
|
local timeout
|
|
|
|
|
|
|
|
for i in "${!FUSE_EXPORTS[@]}"; do
|
|
|
|
if [ "${FUSE_EXPORTS[i]}" = "$img" ]; then
|
|
|
|
index=$i
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ -z "$index" ]; then
|
|
|
|
# Probably gone already
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
kill "${FUSE_PIDS[index]}"
|
|
|
|
|
|
|
|
# Wait until the mount is gone
|
|
|
|
timeout=10 # *0.5 s
|
|
|
|
while true; do
|
|
|
|
# Will show the mount point; if the mount is still there,
|
|
|
|
# it will be $img.
|
|
|
|
df_output=$(df "$img" 2>/dev/null)
|
|
|
|
|
|
|
|
# But df may also show an error ("Transpoint endpoint not
|
|
|
|
# connected"), so retry in such cases
|
|
|
|
if [ -n "$df_output" ]; then
|
|
|
|
if ! echo "$df_output" | grep -q "$img"; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
sleep 0.5
|
|
|
|
|
|
|
|
timeout=$((timeout - 1))
|
|
|
|
if [ "$timeout" = 0 ]; then
|
|
|
|
echo 'Failed to take down FUSE export' >&2
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
rm -f "$img"
|
|
|
|
|
|
|
|
unset "FUSE_PIDS[$index]"
|
|
|
|
unset "FUSE_EXPORTS[$index]"
|
|
|
|
|
|
|
|
image_file=$(echo "$img" | sed -e "s#$SOCK_DIR/fuse-#$TEST_DIR/#")
|
|
|
|
_rm_test_img "$image_file"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2013-11-26 10:40:34 +04:00
|
|
|
if [ "$IMGFMT" = "vmdk" ]; then
|
|
|
|
# Remove all the extents for vmdk
|
2014-04-11 00:47:39 +04:00
|
|
|
"$QEMU_IMG" info "$img" 2>/dev/null | grep 'filename:' | cut -f 2 -d: \
|
2013-11-26 10:40:34 +04:00
|
|
|
| xargs -I {} rm -f "{}"
|
2019-11-07 19:37:08 +03:00
|
|
|
elif [ "$IMGFMT" = "qcow2" ]; then
|
|
|
|
# Remove external data file
|
|
|
|
if data_file=$(_get_data_file "$img"); then
|
|
|
|
rm -f "$data_file"
|
|
|
|
fi
|
2013-11-26 10:40:34 +04:00
|
|
|
fi
|
2014-04-11 00:47:39 +04:00
|
|
|
rm -f "$img"
|
2013-11-26 10:40:34 +04:00
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
_cleanup_test_img()
|
|
|
|
{
|
2011-01-17 20:01:17 +03:00
|
|
|
case "$IMGPROTO" in
|
|
|
|
|
2012-11-02 17:01:23 +04:00
|
|
|
nbd)
|
2018-07-11 09:40:46 +03:00
|
|
|
_stop_nbd_server
|
2013-09-25 16:12:22 +04:00
|
|
|
rm -f "$TEST_IMG_FILE"
|
2012-11-02 17:01:23 +04:00
|
|
|
;;
|
2017-04-04 06:48:09 +03:00
|
|
|
|
2020-10-27 22:05:58 +03:00
|
|
|
fuse)
|
|
|
|
local mp
|
|
|
|
|
|
|
|
for mp in "${FUSE_EXPORTS[@]}"; do
|
|
|
|
_rm_test_img "$mp"
|
|
|
|
done
|
|
|
|
|
|
|
|
FUSE_PIDS=()
|
|
|
|
FUSE_EXPORTS=()
|
|
|
|
;;
|
|
|
|
|
2011-01-17 20:01:17 +03:00
|
|
|
file)
|
2013-11-26 10:40:34 +04:00
|
|
|
_rm_test_img "$TEST_DIR/t.$IMGFMT"
|
|
|
|
_rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
|
|
|
|
_rm_test_img "$TEST_DIR/t.$IMGFMT.base"
|
2013-09-25 16:12:20 +04:00
|
|
|
if [ -n "$SAMPLE_IMG_FILE" ]
|
|
|
|
then
|
|
|
|
rm -f "$TEST_DIR/$SAMPLE_IMG_FILE"
|
2017-07-27 16:13:20 +03:00
|
|
|
SAMPLE_IMG_FILE=
|
|
|
|
TEST_IMG="$ORIG_TEST_IMG"
|
2013-09-25 16:12:20 +04:00
|
|
|
fi
|
2011-01-17 20:01:17 +03:00
|
|
|
;;
|
|
|
|
|
|
|
|
rbd)
|
2014-01-09 00:05:38 +04:00
|
|
|
rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null
|
2011-01-17 20:01:17 +03:00
|
|
|
;;
|
|
|
|
|
|
|
|
esac
|
2009-06-22 20:29:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
_check_test_img()
|
|
|
|
{
|
2016-05-10 19:11:27 +03:00
|
|
|
(
|
|
|
|
if [ "$IMGOPTSSYNTAX" = "true" ]; then
|
|
|
|
$QEMU_IMG check $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1
|
|
|
|
else
|
|
|
|
$QEMU_IMG check "$@" -f $IMGFMT "$TEST_IMG" 2>&1
|
|
|
|
fi
|
2016-08-10 05:43:12 +03:00
|
|
|
) | _filter_testdir | _filter_qemu_img_check
|
2019-09-16 20:53:20 +03:00
|
|
|
|
|
|
|
# return real qemu_img check status, to analyze in
|
|
|
|
# _check_test_img_ignore_leaks
|
|
|
|
return ${PIPESTATUS[0]}
|
|
|
|
}
|
|
|
|
|
|
|
|
_check_test_img_ignore_leaks()
|
|
|
|
{
|
|
|
|
out=$(_check_test_img "$@")
|
|
|
|
status=$?
|
|
|
|
if [ $status = 3 ]; then
|
|
|
|
# This must correspond to success output in dump_human_image_check()
|
|
|
|
echo "No errors were found on the image."
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
echo "$out"
|
|
|
|
return $status
|
2009-06-22 20:29:05 +04:00
|
|
|
}
|
|
|
|
|
2012-10-17 16:02:32 +04:00
|
|
|
_img_info()
|
|
|
|
{
|
2014-11-27 17:03:53 +03:00
|
|
|
if [[ "$1" == "--format-specific" ]]; then
|
|
|
|
local format_specific=1
|
|
|
|
shift
|
|
|
|
else
|
|
|
|
local format_specific=0
|
|
|
|
fi
|
|
|
|
|
qemu-iotests: Discard specific info in _img_info
In _img_info, filter out additional information specific to the image
format provided by qemu-img info, since tests designed for multiple
image formats would produce different outputs for every image format
otherwise.
In a human-readable dump, that new information will always be last for
each "image information block" (multiple blocks are emitted when
inspecting the backing file chain). Every block is separated by an empty
line. Therefore, in this case, everything starting with the line "Format
specific information:" up to that empty line (or EOF, if it is the last
block) has to be stripped.
The JSON dump will always emit pretty JSON data. Therefore, the opening
and closing braces of every object will be on lines which are indented
by exactly the same amount, and all lines in between will have more
indentation. Thus, in this case, everything starting with a line
matching the regular expression /^ *"format-specific": {/ until /^ *},?/
has to be stripped, where the number of spaces at the beginning of the
respective lines is equal.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2013-10-09 12:46:19 +04:00
|
|
|
discard=0
|
|
|
|
regex_json_spec_start='^ *"format-specific": \{'
|
2018-03-02 20:38:14 +03:00
|
|
|
$QEMU_IMG info $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 | \
|
2018-05-17 19:33:52 +03:00
|
|
|
sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
|
|
|
|
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
|
2012-10-17 16:02:32 +04:00
|
|
|
-e "s#$TEST_DIR#TEST_DIR#g" \
|
2020-10-27 22:05:58 +03:00
|
|
|
-e "s#$SOCK_DIR/fuse-#TEST_DIR/#g" \
|
2012-10-17 16:02:32 +04:00
|
|
|
-e "s#$IMGFMT#IMGFMT#g" \
|
|
|
|
-e "/^disk size:/ D" \
|
qemu-iotests: Discard specific info in _img_info
In _img_info, filter out additional information specific to the image
format provided by qemu-img info, since tests designed for multiple
image formats would produce different outputs for every image format
otherwise.
In a human-readable dump, that new information will always be last for
each "image information block" (multiple blocks are emitted when
inspecting the backing file chain). Every block is separated by an empty
line. Therefore, in this case, everything starting with the line "Format
specific information:" up to that empty line (or EOF, if it is the last
block) has to be stripped.
The JSON dump will always emit pretty JSON data. Therefore, the opening
and closing braces of every object will be on lines which are indented
by exactly the same amount, and all lines in between will have more
indentation. Thus, in this case, everything starting with a line
matching the regular expression /^ *"format-specific": {/ until /^ *},?/
has to be stripped, where the number of spaces at the beginning of the
respective lines is equal.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2013-10-09 12:46:19 +04:00
|
|
|
-e "/actual-size/ D" | \
|
2017-11-23 05:08:20 +03:00
|
|
|
while IFS='' read -r line; do
|
2014-11-27 17:03:53 +03:00
|
|
|
if [[ $format_specific == 1 ]]; then
|
|
|
|
discard=0
|
|
|
|
elif [[ $line == "Format specific information:" ]]; then
|
qemu-iotests: Discard specific info in _img_info
In _img_info, filter out additional information specific to the image
format provided by qemu-img info, since tests designed for multiple
image formats would produce different outputs for every image format
otherwise.
In a human-readable dump, that new information will always be last for
each "image information block" (multiple blocks are emitted when
inspecting the backing file chain). Every block is separated by an empty
line. Therefore, in this case, everything starting with the line "Format
specific information:" up to that empty line (or EOF, if it is the last
block) has to be stripped.
The JSON dump will always emit pretty JSON data. Therefore, the opening
and closing braces of every object will be on lines which are indented
by exactly the same amount, and all lines in between will have more
indentation. Thus, in this case, everything starting with a line
matching the regular expression /^ *"format-specific": {/ until /^ *},?/
has to be stripped, where the number of spaces at the beginning of the
respective lines is equal.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2013-10-09 12:46:19 +04:00
|
|
|
discard=1
|
|
|
|
elif [[ $line =~ $regex_json_spec_start ]]; then
|
|
|
|
discard=2
|
|
|
|
regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
|
|
|
|
fi
|
|
|
|
if [[ $discard == 0 ]]; then
|
|
|
|
echo "$line"
|
|
|
|
elif [[ $discard == 1 && ! $line ]]; then
|
|
|
|
echo
|
|
|
|
discard=0
|
|
|
|
elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
|
|
|
|
discard=0
|
|
|
|
fi
|
|
|
|
done
|
2012-10-17 16:02:32 +04:00
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# bail out, setting up .notrun file
|
|
|
|
#
|
|
|
|
_notrun()
|
|
|
|
{
|
2014-05-25 01:24:55 +04:00
|
|
|
echo "$*" >"$OUTPUT_DIR/$seq.notrun"
|
2009-06-22 20:29:05 +04:00
|
|
|
echo "$seq not run: $*"
|
|
|
|
status=0
|
|
|
|
exit
|
|
|
|
}
|
|
|
|
|
2019-09-04 12:11:21 +03:00
|
|
|
# bail out, setting up .casenotrun file
|
|
|
|
# The function _casenotrun() is used as a notifier. It is the
|
|
|
|
# caller's responsibility to make skipped a particular test.
|
|
|
|
#
|
|
|
|
_casenotrun()
|
|
|
|
{
|
|
|
|
echo " [case not run] $*" >>"$OUTPUT_DIR/$seq.casenotrun"
|
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# just plain bail out
|
|
|
|
#
|
|
|
|
_fail()
|
|
|
|
{
|
2014-05-25 01:24:55 +04:00
|
|
|
echo "$*" | tee -a "$OUTPUT_DIR/$seq.full"
|
2009-06-22 20:29:05 +04:00
|
|
|
echo "(see $seq.full for details)"
|
|
|
|
status=1
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# tests whether $IMGFMT is one of the supported image formats for a test
|
|
|
|
#
|
|
|
|
_supported_fmt()
|
|
|
|
{
|
2014-03-26 16:05:23 +04:00
|
|
|
# "generic" is suitable for most image formats. For some formats it doesn't
|
|
|
|
# work, however (most notably read-only formats), so they can opt out by
|
|
|
|
# setting IMGFMT_GENERIC to false.
|
2009-06-22 20:29:05 +04:00
|
|
|
for f; do
|
2013-09-27 16:48:15 +04:00
|
|
|
if [ "$f" = "$IMGFMT" -o "$f" = "generic" -a "$IMGFMT_GENERIC" = "true" ]; then
|
2020-06-25 15:55:35 +03:00
|
|
|
if [ "$IMGFMT" = "luks" ]; then
|
|
|
|
_require_working_luks
|
|
|
|
fi
|
2013-09-04 15:16:04 +04:00
|
|
|
return
|
|
|
|
fi
|
2009-06-22 20:29:05 +04:00
|
|
|
done
|
|
|
|
|
|
|
|
_notrun "not suitable for this image format: $IMGFMT"
|
|
|
|
}
|
|
|
|
|
2017-02-01 03:31:19 +03:00
|
|
|
# tests whether $IMGFMT is one of the unsupported image format for a test
|
|
|
|
#
|
|
|
|
_unsupported_fmt()
|
|
|
|
{
|
|
|
|
for f; do
|
|
|
|
if [ "$f" = "$IMGFMT" ]; then
|
|
|
|
_notrun "not suitable for this image format: $IMGFMT"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2011-01-17 20:01:17 +03:00
|
|
|
# tests whether $IMGPROTO is one of the supported image protocols for a test
|
|
|
|
#
|
|
|
|
_supported_proto()
|
|
|
|
{
|
|
|
|
for f; do
|
2013-09-04 15:16:04 +04:00
|
|
|
if [ "$f" = "$IMGPROTO" -o "$f" = "generic" ]; then
|
|
|
|
return
|
|
|
|
fi
|
2011-01-17 20:01:17 +03:00
|
|
|
done
|
|
|
|
|
|
|
|
_notrun "not suitable for this image protocol: $IMGPROTO"
|
|
|
|
}
|
|
|
|
|
2017-02-14 19:21:17 +03:00
|
|
|
# tests whether $IMGPROTO is specified as an unsupported image protocol for a test
|
|
|
|
#
|
|
|
|
_unsupported_proto()
|
|
|
|
{
|
|
|
|
for f; do
|
|
|
|
if [ "$f" = "$IMGPROTO" ]; then
|
|
|
|
_notrun "not suitable for this image protocol: $IMGPROTO"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# tests whether the host OS is one of the supported OSes for a test
|
|
|
|
#
|
|
|
|
_supported_os()
|
|
|
|
{
|
|
|
|
for h
|
|
|
|
do
|
2013-09-04 15:16:04 +04:00
|
|
|
if [ "$h" = "$HOSTOS" ]
|
|
|
|
then
|
|
|
|
return
|
|
|
|
fi
|
2009-06-22 20:29:05 +04:00
|
|
|
done
|
|
|
|
|
|
|
|
_notrun "not suitable for this OS: $HOSTOS"
|
|
|
|
}
|
|
|
|
|
2013-12-04 05:07:00 +04:00
|
|
|
_supported_cache_modes()
|
2012-08-09 16:05:57 +04:00
|
|
|
{
|
2013-12-04 05:07:00 +04:00
|
|
|
for mode; do
|
|
|
|
if [ "$mode" = "$CACHEMODE" ]; then
|
|
|
|
return
|
|
|
|
fi
|
2012-08-09 16:05:57 +04:00
|
|
|
done
|
2013-12-04 05:07:00 +04:00
|
|
|
_notrun "not suitable for cache mode: $CACHEMODE"
|
|
|
|
}
|
|
|
|
|
2020-04-30 15:47:06 +03:00
|
|
|
# Check whether the filesystem supports O_DIRECT
|
|
|
|
_check_o_direct()
|
|
|
|
{
|
2020-12-18 21:20:12 +03:00
|
|
|
testfile="$TEST_DIR"/_check_o_direct
|
|
|
|
$QEMU_IMG create -f raw "$testfile" 1M > /dev/null
|
|
|
|
out=$($QEMU_IO -f raw -t none -c quit "$testfile" 2>&1)
|
|
|
|
rm -f "$testfile"
|
2020-04-30 15:47:06 +03:00
|
|
|
|
|
|
|
[[ "$out" != *"O_DIRECT"* ]]
|
|
|
|
}
|
|
|
|
|
|
|
|
_require_o_direct()
|
|
|
|
{
|
|
|
|
if ! _check_o_direct; then
|
|
|
|
_notrun "file system on $TEST_DIR does not support O_DIRECT"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
_check_cache_mode()
|
|
|
|
{
|
|
|
|
if [ $CACHEMODE == "none" ] || [ $CACHEMODE == "directsync" ]; then
|
|
|
|
_require_o_direct
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
_check_cache_mode
|
|
|
|
|
|
|
|
# $1 - cache mode to use by default
|
|
|
|
# $2 - (optional) cache mode to use by default if O_DIRECT is not supported
|
2013-12-04 05:07:00 +04:00
|
|
|
_default_cache_mode()
|
|
|
|
{
|
|
|
|
if $CACHEMODE_IS_DEFAULT; then
|
2020-04-30 15:47:06 +03:00
|
|
|
if [ -z "$2" ] || _check_o_direct; then
|
|
|
|
CACHEMODE="$1"
|
|
|
|
else
|
|
|
|
CACHEMODE="$2"
|
|
|
|
fi
|
|
|
|
QEMU_IO="$QEMU_IO --cache $CACHEMODE"
|
|
|
|
_check_cache_mode
|
2013-12-04 05:07:00 +04:00
|
|
|
return
|
|
|
|
fi
|
2012-08-09 16:05:57 +04:00
|
|
|
}
|
2020-01-20 17:18:57 +03:00
|
|
|
_supported_aio_modes()
|
|
|
|
{
|
|
|
|
for mode; do
|
|
|
|
if [ "$mode" = "$AIOMODE" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
_notrun "not suitable for aio mode: $AIOMODE"
|
|
|
|
}
|
|
|
|
_default_aio_mode()
|
|
|
|
{
|
|
|
|
AIOMODE="$1"
|
|
|
|
QEMU_IO="$QEMU_IO --aio $1"
|
|
|
|
}
|
2012-08-09 16:05:57 +04:00
|
|
|
|
2013-11-26 10:40:32 +04:00
|
|
|
_unsupported_imgopts()
|
|
|
|
{
|
|
|
|
for bad_opt
|
|
|
|
do
|
2021-02-10 12:51:28 +03:00
|
|
|
# Add a space so tests can match for whitespace that marks the
|
|
|
|
# end of an option (\b or \> are not portable)
|
|
|
|
if echo "$IMGOPTS " | grep -q 2>/dev/null "$bad_opt"
|
2013-11-26 10:40:32 +04:00
|
|
|
then
|
|
|
|
_notrun "not suitable for image option: $bad_opt"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2020-06-25 15:55:32 +03:00
|
|
|
# Caution: Overwrites $TEST_DIR/t.luks
|
|
|
|
_require_working_luks()
|
|
|
|
{
|
|
|
|
file="$TEST_DIR/t.luks"
|
|
|
|
|
|
|
|
output=$(
|
|
|
|
$QEMU_IMG create -f luks \
|
|
|
|
--object secret,id=sec0,data=hunter0 \
|
|
|
|
-o key-secret=sec0 \
|
|
|
|
-o iter-time=10 \
|
|
|
|
"$file" \
|
|
|
|
1M \
|
|
|
|
2>&1
|
|
|
|
)
|
|
|
|
status=$?
|
|
|
|
|
|
|
|
IMGFMT='luks' _rm_test_img "$file"
|
|
|
|
|
|
|
|
if [ $status != 0 ]; then
|
|
|
|
reason=$(echo "$output" | grep "$file:" | $SED -e "s#.*$file: *##")
|
|
|
|
if [ -z "$reason" ]; then
|
|
|
|
reason="Failed to create a LUKS image"
|
|
|
|
fi
|
|
|
|
_notrun "$reason"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# this test requires that a specified command (executable) exists
|
|
|
|
#
|
|
|
|
_require_command()
|
|
|
|
{
|
2015-09-02 21:52:27 +03:00
|
|
|
if [ "$1" = "QEMU" ]; then
|
|
|
|
c=$QEMU_PROG
|
|
|
|
elif [ "$1" = "QEMU_IMG" ]; then
|
|
|
|
c=$QEMU_IMG_PROG
|
|
|
|
elif [ "$1" = "QEMU_IO" ]; then
|
|
|
|
c=$QEMU_IO_PROG
|
|
|
|
elif [ "$1" = "QEMU_NBD" ]; then
|
|
|
|
c=$QEMU_NBD_PROG
|
|
|
|
else
|
|
|
|
eval c=\$$1
|
|
|
|
fi
|
2013-12-04 13:10:56 +04:00
|
|
|
[ -x "$c" ] || _notrun "$1 utility required, skipped this test"
|
2009-06-22 20:29:05 +04:00
|
|
|
}
|
|
|
|
|
2019-08-23 16:35:52 +03:00
|
|
|
# Check that a set of drivers has been whitelisted in the QEMU binary
|
|
|
|
#
|
|
|
|
_require_drivers()
|
|
|
|
{
|
|
|
|
available=$($QEMU -drive format=help | \
|
|
|
|
sed -e '/Supported formats:/!d' -e 's/Supported formats://')
|
|
|
|
for driver
|
|
|
|
do
|
|
|
|
if ! echo "$available" | grep -q " $driver\( \|$\)"; then
|
|
|
|
_notrun "$driver not available"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2019-12-02 13:16:29 +03:00
|
|
|
# Check that we have a file system that allows huge (but very sparse) files
|
|
|
|
#
|
|
|
|
_require_large_file()
|
|
|
|
{
|
|
|
|
if ! truncate --size="$1" "$TEST_IMG"; then
|
|
|
|
_notrun "file system on $TEST_DIR does not support large enough files"
|
|
|
|
fi
|
|
|
|
rm "$TEST_IMG"
|
|
|
|
}
|
|
|
|
|
2020-01-21 12:52:03 +03:00
|
|
|
# Check that a set of devices is available in the QEMU binary
|
|
|
|
#
|
|
|
|
_require_devices()
|
|
|
|
{
|
|
|
|
available=$($QEMU -M none -device help | \
|
|
|
|
grep ^name | sed -e 's/^name "//' -e 's/".*$//')
|
|
|
|
for device
|
|
|
|
do
|
|
|
|
if ! echo "$available" | grep -q "$device" ; then
|
|
|
|
_notrun "$device not available"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2021-03-23 19:53:07 +03:00
|
|
|
_require_one_device_of()
|
|
|
|
{
|
|
|
|
available=$($QEMU -M none -device help | \
|
|
|
|
grep ^name | sed -e 's/^name "//' -e 's/".*$//')
|
|
|
|
for device
|
|
|
|
do
|
|
|
|
if echo "$available" | grep -q "$device" ; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
_notrun "$* not available"
|
|
|
|
}
|
|
|
|
|
2009-06-22 20:29:05 +04:00
|
|
|
# make sure this script returns success
|
2015-01-04 04:53:48 +03:00
|
|
|
true
|