1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-28 20:25:52 +03:00
lvm2/test/lib/aux.sh
2012-03-16 19:08:09 +00:00

505 lines
13 KiB
Bash

#!/bin/bash
# Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. lib/utils
run_valgrind() {
# Execute script which may use $TESTNAME for creating individal
# log files for each execute command
exec "${VALGRIND:-valg}" "$@"
}
prepare_clvmd() {
test "${LVM_TEST_LOCKING:-0}" -ne 3 && return # not needed
if pgrep clvmd ; then
echo "Cannot use fake cluster locking with real clvmd ($(pgrep clvmd)) running."
skip
fi
# skip if we don't have our own clvmd...
(which clvmd 2>/dev/null | grep "$abs_builddir") || skip
# skip if we singlenode is not compiled in
(clvmd --help 2>&1 | grep "Available cluster managers" | grep "singlenode") || skip
# lvmconf "activation/monitoring = 1"
local run_valgrind=
test -z "$LVM_VALGRIND_CLVMD" || run_valgrind="run_valgrind"
$run_valgrind lib/clvmd -Isinglenode -d 1 -f &
local local_clvmd=$!
sleep .3
# extra sleep for slow valgrind
test -z "$LVM_VALGRIND_CLVMD" || sleep 5
# check that it is really running now
ps $local_clvmd || die
echo $local_clvmd > LOCAL_CLVMD
}
prepare_dmeventd() {
if pgrep dmeventd ; then
echo "Cannot test dmeventd with real dmeventd ($(pgrep dmeventd)) running."
skip
fi
# skip if we don't have our own dmeventd...
(which dmeventd 2>/dev/null | grep "$abs_builddir") || skip
lvmconf "activation/monitoring = 1"
dmeventd -f "$@" &
echo $! > LOCAL_DMEVENTD
# FIXME wait for pipe in /var/run instead
sleep 1
}
prepare_lvmetad() {
# skip if we don't have our own lvmetad...
(which lvmetad 2>/dev/null | grep "$abs_builddir") || skip
lvmconf "global/use_lvmetad = 1"
lvmconf "devices/md_component_detection = 0"
echo "preparing lvmetad..."
lvmetad -f "$@" -s "$TESTDIR/lvmetad.socket" &
echo $! > LOCAL_LVMETAD
sleep 1
}
notify_lvmetad() {
if test -e LOCAL_LVMETAD; then
pvscan --cache "$@" || true
fi
}
teardown_devs() {
vgremove -ff $vg $vg1 $vg2 $vg3 $vg4 &>/dev/null || rm -f debug.log
# Delete any remaining dm/udev semaphores
teardown_udev_cookies
test -z "$PREFIX" || {
rm -rf "$TESTDIR/dev/$PREFIX"*
# Try unmount opened devices first
for s in $(dmsetup info -c -o open,name --sort -open --noheading | grep "$PREFIX"); do
test "${s%%:*}" -gt 0 || break
umount -fl "$DM_DEV_DIR/mapper/${s#[0..9]*:}" &>/dev/null || true
done
# Remove devices, start with closed (sorted by open count)
init_udev_transaction
for s in $(dmsetup info -c -o name --sort open --noheading | grep "$PREFIX"); do
dmsetup remove "$s" &>/dev/null || true
done
finish_udev_transaction
udev_wait
# Brute force, and without udev transaction
while dmsetup table | grep -q "$PREFIX"; do
for s in $(dmsetup info -c -o name --sort open --noheading | grep "$PREFIX"); do
umount -fl "$DM_DEV_DIR/mapper/$s" &>/dev/null || true
dmsetup remove -f "$s" &>/dev/null || true
done
udev_wait
done
}
# NOTE: SCSI_DEBUG_DEV test must come before the LOOP test because
# prepare_scsi_debug_dev() also sets LOOP to short-circuit prepare_loop()
if test -f SCSI_DEBUG_DEV; then
modprobe -r scsi_debug
else
test ! -f LOOP || losetup -d $(cat LOOP)
test ! -f LOOPFILE || rm -f $(cat LOOPFILE)
fi
rm -f DEVICES # devs is set in prepare_devs()
rm -f LOOP
# Attempt to remove any loop devices that failed to get torn down if earlier tests aborted
test -z "$COMMON_PREFIX" || {
# Resume any linears to be sure we do not deadlock
STRAY_DEVS=$(dmsetup table | sed 's/:.*//' | grep "$COMMON_PREFIX" | cut -d' ' -f 1)
for dm in $STRAY_DEVS ; do
# FIXME: only those really suspended
echo "dmsetup resume \"$dm\""
dmsetup resume "$dm" || true
done
STRAY_MOUNTS=$(mount | grep "$COMMON_PREFIX" | cut -d' ' -f1)
if test -n "$STRAY_MOUNTS"; then
echo "Removing stray mounted devices containing $COMMON_PREFIX:"
mount | grep "$COMMON_PREFIX"
umount -fl "$STRAY_MOUNTS" || true
udev_wait
fi
init_udev_transaction
NUM_REMAINING_DEVS=999
while NUM_DEVS=$(dmsetup table | grep "^$COMMON_PREFIX" | wc -l) && \
test $NUM_DEVS -lt $NUM_REMAINING_DEVS -a $NUM_DEVS -ne 0; do
echo "Removing $NUM_DEVS stray mapped devices with names beginning with $COMMON_PREFIX:"
STRAY_DEVS=$(dmsetup table | sed 's/:.*//' | grep "$COMMON_PREFIX" | cut -d' ' -f 1)
dmsetup info -c | grep "^$COMMON_PREFIX"
for dm in $STRAY_DEVS ; do
echo "dmsetup remove -f \"$dm\""
dmsetup remove -f "$dm" || true
done
NUM_REMAINING_DEVS=$NUM_DEVS
done
finish_udev_transaction
udev_wait
STRAY_LOOPS=$(losetup -a | grep "$COMMON_PREFIX" | cut -d: -f1)
if test -n "$STRAY_LOOPS"; then
echo "Removing stray loop devices containing $COMMON_PREFIX:"
losetup -a | grep "$COMMON_PREFIX"
losetup -d "$STRAY_LOOPS" || true
fi
}
}
teardown() {
echo -n "## teardown..."
test -f LOCAL_CLVMD && {
kill -INT "$(cat LOCAL_CLVMD)"
test -z "$LVM_VALGRIND_CLVMD" || sleep 1
sleep .1
kill -9 "$(cat LOCAL_CLVMD)" &>/dev/null || true
}
echo -n .
test -f LOCAL_DMEVENTD && kill -9 $(cat LOCAL_DMEVENTD) || true
test -f LOCAL_LVMETAD && kill -9 $(cat LOCAL_LVMETAD) || true
echo -n .
test -d "$DM_DEV_DIR/mapper" && teardown_devs
echo -n .
test -n "$TESTDIR" && {
cd "$TESTOLDPWD"
rm -rf "$TESTDIR" || echo BLA
}
echo "ok"
test -n "$RUNNING_DMEVENTD" || not pgrep dmeventd &>/dev/null
}
make_ioerror() {
echo 0 10000000 error | dmsetup create -u TEST-ioerror ioerror
ln -s "$DM_DEV_DIR/mapper/ioerror" "$DM_DEV_DIR/ioerror"
}
prepare_loop() {
local size=${1=32}
echo -n "## preparing loop device..."
# skip if prepare_scsi_debug_dev() was used
if test -f SCSI_DEBUG_DEV -a -f LOOP ; then
echo "(skipped)"
return 0
fi
test ! -e LOOP
test -n "$DM_DEV_DIR"
for i in 0 1 2 3 4 5 6 7; do
test -e "$DM_DEV_DIR/loop$i" || mknod "$DM_DEV_DIR/loop$i" b 7 $i
done
echo -n .
local LOOPFILE="$PWD/test.img"
dd if=/dev/zero of="$LOOPFILE" bs=$((1024*1024)) count=0 seek=$(($size-1)) 2> /dev/null
if LOOP=$(losetup -s -f "$LOOPFILE" 2>/dev/null); then
:
elif LOOP=$(losetup -f) && losetup "$LOOP" "$LOOPFILE"; then
# no -s support
:
else
# no -f support
# Iterate through $DM_DEV_DIR/loop{,/}{0,1,2,3,4,5,6,7}
for slash in '' /; do
for i in 0 1 2 3 4 5 6 7; do
local dev="$DM_DEV_DIR/loop$slash$i"
! losetup "$dev" >/dev/null 2>&1 || continue
# got a free
losetup "$dev" "$LOOPFILE"
LOOP=$dev
break
done
test -z "$LOOP" || break
done
fi
test -n "$LOOP" # confirm or fail
echo "$LOOP" > LOOP
echo "ok ($LOOP)"
}
# A drop-in replacement for prepare_loop() that uses scsi_debug to create
# a ramdisk-based SCSI device upon which all LVM devices will be created
# - scripts must take care not to use a DEV_SIZE that will enduce OOM-killer
prepare_scsi_debug_dev() {
local DEV_SIZE=$1
local SCSI_DEBUG_PARAMS=${@:2}
test -f "SCSI_DEBUG_DEV" && return 0
test -z "$LOOP"
test -n "$DM_DEV_DIR"
# Skip test if awk isn't available (required for get_sd_devs_)
which awk || skip
# Skip test if scsi_debug module is unavailable or is already in use
modprobe --dry-run scsi_debug || skip
lsmod | grep -q scsi_debug && skip
# Create the scsi_debug device and determine the new scsi device's name
# NOTE: it will _never_ make sense to pass num_tgts param;
# last param wins.. so num_tgts=1 is imposed
modprobe scsi_debug dev_size_mb=$DEV_SIZE $SCSI_DEBUG_PARAMS num_tgts=1 || skip
sleep 2 # allow for async Linux SCSI device registration
local DEBUG_DEV="/dev/$(grep -H scsi_debug /sys/block/*/device/model | cut -f4 -d /)"
test -b "$DEBUG_DEV" || return 1 # should not happen
# Create symlink to scsi_debug device in $DM_DEV_DIR
SCSI_DEBUG_DEV="$DM_DEV_DIR/$(basename $DEBUG_DEV)"
echo "$SCSI_DEBUG_DEV" > SCSI_DEBUG_DEV
echo "$SCSI_DEBUG_DEV" > LOOP
# Setting $LOOP provides means for prepare_devs() override
test "$LVM_TEST_DEVDIR" != "/dev" && ln -snf "$DEBUG_DEV" "$SCSI_DEBUG_DEV"
}
cleanup_scsi_debug_dev() {
teardown_devs
rm -f SCSI_DEBUG_DEV LOOP
}
prepare_devs() {
local n=${1:-3}
local devsize=${2:-34}
local pvname=${3:-pv}
prepare_loop $(($n*$devsize))
echo -n "## preparing $n devices..."
if ! loopsz=$(blockdev --getsz "$LOOP" 2>/dev/null); then
loopsz=$(blockdev --getsize "$LOOP" 2>/dev/null)
fi
local size=$(($loopsz/$n))
devs=
init_udev_transaction
for i in $(seq 1 $n); do
local name="${PREFIX}$pvname$i"
local dev="$DM_DEV_DIR/mapper/$name"
devs="$devs $dev"
echo 0 $size linear "$LOOP" $((($i-1)*$size)) > "$name.table"
dmsetup create -u "TEST-$name" "$name" "$name.table"
done
finish_udev_transaction
#for i in `seq 1 $n`; do
# local name="${PREFIX}$pvname$i"
# dmsetup info -c $name
#done
#for i in `seq 1 $n`; do
# local name="${PREFIX}$pvname$i"
# dmsetup table $name
#done
echo $devs > DEVICES
echo "ok"
}
disable_dev() {
init_udev_transaction
for dev in "$@"; do
maj=$(($(stat --printf=0x%t "$dev")))
min=$(($(stat --printf=0x%T "$dev")))
echo "Disabling device $dev ($maj:$min)"
dmsetup remove -f "$dev" || true
notify_lvmetad --major "$maj" --minor "$min"
done
finish_udev_transaction
}
enable_dev() {
init_udev_transaction
for dev in "$@"; do
local name=$(echo "$dev" | sed -e 's,.*/,,')
dmsetup create -u "TEST-$name" "$name" "$name.table" || \
dmsetup load "$name" "$name.table"
# using device name (since device path does not exists yes with udev)
dmsetup resume "$name"
notify_lvmetad "$dev"
done
finish_udev_transaction
}
backup_dev() {
for dev in "$@"; do
dd if="$dev" of="$dev.backup" bs=1024
done
}
restore_dev() {
for dev in "$@"; do
test -e "$dev.backup" || \
die "Internal error: $dev not backed up, can't restore!"
dd of="$dev" if="$dev.backup" bs=1024
done
}
prepare_pvs() {
prepare_devs "$@"
pvcreate -ff $devs
}
prepare_vg() {
teardown_devs
prepare_pvs "$@"
vgcreate -c n $vg $devs
}
lvmconf() {
LVM_TEST_LOCKING=${LVM_TEST_LOCKING:-1}
if test "$DM_DEV_DIR" = "/dev"; then
LVM_VERIFY_UDEV=${LVM_VERIFY_UDEV:-0}
else
LVM_VERIFY_UDEV=${LVM_VERIFY_UDEV:-1}
fi
test -f CONFIG_VALUES || {
cat > CONFIG_VALUES <<-EOF
devices/dir = "$DM_DEV_DIR"
devices/scan = "$DM_DEV_DIR"
devices/filter = [ "a/dev\\\\/mirror/", "a/dev\\\\/mapper\\\\/.*pv[0-9_]*$/", "r/.*/" ]
devices/cache_dir = "$TESTDIR/etc"
devices/sysfs_scan = 0
devices/default_data_alignment = 1
devices/md_component_detection = 0
log/syslog = 0
log/indent = 1
log/level = 9
log/file = "$TESTDIR/debug.log"
log/overwrite = 1
log/activation = 1
log/verbose = 0
activation/retry_deactivation = 1
backup/backup = 0
backup/archive = 0
global/abort_on_internal_errors = 1
global/detect_internal_vg_cache_corruption = 1
global/library_dir = "$TESTDIR/lib"
global/locking_dir = "$TESTDIR/var/lock/lvm"
global/locking_type=$LVM_TEST_LOCKING
global/si_unit_consistency = 1
global/fallback_to_local_locking = 0
activation/checks = 1
activation/udev_sync = 1
activation/udev_rules = 1
activation/verify_udev_operations = $LVM_VERIFY_UDEV
activation/polling_interval = 0
activation/snapshot_autoextend_percent = 50
activation/snapshot_autoextend_threshold = 50
activation/monitoring = 0
EOF
}
for v in "$@"; do
echo "$v" >> CONFIG_VALUES
done
rm -f CONFIG
for s in $(cat CONFIG_VALUES | cut -f1 -d/ | sort | uniq); do
echo "$s {" >> CONFIG
for k in $(grep ^$s/ CONFIG_VALUES | cut -f1 -d= | sed -e 's, *$,,' | sort | uniq); do
grep "^$k" CONFIG_VALUES | tail -n 1 | sed -e "s,^$s/, ," >> CONFIG
done
echo "}" >> CONFIG
echo >> CONFIG
done
mv -f CONFIG $TESTDIR/etc/lvm.conf
}
apitest() {
t=$1
shift
test -x "$abs_top_builddir/test/api/$t.t" || skip
"$abs_top_builddir/test/api/$t.t" "$@" && rm -f debug.log
}
api() {
test -x "$abs_top_builddir/test/api/wrapper" || skip
"$abs_top_builddir/test/api/wrapper" "$@" && rm -f debug.log
}
udev_wait() {
pgrep udev >/dev/null || return 0
which udevadm >/dev/null || return 0
if test -n "$1" ; then
udevadm settle --exit-if-exists=$1
else
udevadm settle --timeout=15
fi
}
#
# Check wheter kernel [dm module] target exist
# at least in expected version
#
# [dm-]target-name major minor revision
#
# i.e. dm_target_at_least dm-thin-pool 1 0
target_at_least()
{
case "$1" in
dm-*) modprobe "$1" ;;
esac
version=$(dmsetup targets 2>/dev/null | grep "${1##dm-} " 2>/dev/null)
version=${version##* v}
shift
major=$(echo "$version" | cut -d. -f1)
minor=$(echo "$version" | cut -d. -f2)
revision=$(echo "$version" | cut -d. -f3)
test -z "$1" && return 0
test -n "$major" || return 1
test "$major" -gt "$1" && return 0
test "$major" -eq "$1" || return 1
test -z "$2" && return 0
test -n "$minor" || return 1
test "$minor" -gt "$2" && return 0
test "$minor" -eq "$2" || return 1
test -z "$4" && return 0
test -n "$revision" || return 1
test "$revision" -eq "$3" || return 1
}
test -f DEVICES && devs=$(cat DEVICES)
test -f LOOP && LOOP=$(cat LOOP)
unset LVM_VALGRIND
"$@"