1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
lvm2/test/test-utils.sh
Mike Snitzer b123a82d73 Change default alignment of pe_start to 1MB.
The new standard in the storage industry is to default alignment of data
areas to 1MB.  fdisk, parted, and mdadm have all been updated to this
default.

Update LVM to align the PV's data area start (pe_start) to 1MB.  This
provides a more useful default than the previous default of 64K (which
generally ended up being a 192K pe_start once the first metadata area
was created).

Before this patch:
# pvs -o name,vg_mda_size,pe_start
  PV         VMdaSize  1st PE
  /dev/sdd     188.00k 192.00k

After this patch:
# pvs -o name,vg_mda_size,pe_start
  PV         VMdaSize  1st PE
  /dev/sdd    1020.00k   1.00m

The heuristic for setting the default alignment for LVM data areas is:
- If the default value (1MB) is a multiple of the detected alignment
  then just use the default.
- Otherwise, use the detected value.

In practice this means we'll almost always use 1MB -- that is unless:
- the alignment was explicitly specified with --dataalignment
- or MD's full stripe width, or the {minimum,optimal}_io_size exceeds
  1MB
- or the specified/detected value is not a power-of-2
2010-08-12 04:11:48 +00:00

428 lines
9.5 KiB
Bash

# Copyright (C) 2008 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
aux() {
# use just "$@" for verbose operation
"$@" > /dev/null 2> /dev/null
#"$@"
}
STACKTRACE() {
trap - ERR;
i=0;
while FUNC=${FUNCNAME[$i]}; test "$FUNC" != "main"; do
echo "$i ${FUNC}() called from ${BASH_SOURCE[$i]}:${BASH_LINENO[$i]}"
i=$(($i + 1));
done
# Get backtraces from coredumps
if which gdb >& /dev/null; then
echo bt full > gdb_commands.txt
echo l >> gdb_commands.txt
echo quit >> gdb_commands.txt
for core in `ls core* 2>/dev/null`; do
bin=$(gdb -batch -c $core 2>&1 | grep "generated by" | \
sed -e "s,.*generated by \`\([^ ']*\).*,\1,")
gdb -batch -c $core -x gdb_commands.txt `which $bin`
done
fi
test -f debug.log && {
sed -e "s,^,## DEBUG: ,;s,$top_srcdir/\?,," < debug.log
}
}
init_udev_transaction() {
if test "$DM_UDEV_SYNCHRONISATION" = 1; then
COOKIE=$(dmsetup udevcreatecookie)
# Cookie is not generated if udev is not running!
if test -n "$COOKIE"; then
export DM_UDEV_COOKIE=$COOKIE
fi
fi
}
finish_udev_transaction() {
if test "$DM_UDEV_SYNCHRONISATION" = 1 -a -n "$DM_UDEV_COOKIE"; then
dmsetup udevreleasecookie
unset DM_UDEV_COOKIE
fi
}
prepare_clvmd() {
if test -z "$LVM_TEST_LOCKING" || test "$LVM_TEST_LOCKING" -ne 3 ; then
return 0 # not needed
fi
if pgrep clvmd ; then
echo "Cannot use fake cluster locking with real clvmd ($(pgrep clvmd)) running."
exit 200
fi
# skip if we don't have our own clvmd...
(which clvmd | grep $abs_builddir) || exit 200
trap_teardown
clvmd -Isinglenode -d 1 &
LOCAL_CLVMD="$!"
}
prepare_dmeventd() {
if pgrep dmeventd ; then
echo "Cannot test dmeventd with real dmeventd ($(pgrep clvmd)) running."
exit 200
fi
# skip if we don't have our own dmeventd...
(which dmeventd | grep $abs_builddir) || exit 200
trap_teardown
dmeventd -f &
LOCAL_DMEVENTD="$!"
}
prepare_testroot() {
OLDPWD="`pwd`"
PREFIX="LVMTEST$$"
trap_teardown
TESTDIR=$($abs_srcdir/mkdtemp ${LVM_TEST_DIR-$(pwd)} $PREFIX.XXXXXXXXXX) \
|| { echo "failed to create temporary directory in ${LVM_TEST_DIR-$(pwd)}"; exit 1; }
export LVM_SYSTEM_DIR=$TESTDIR/etc
export DM_DEV_DIR=$TESTDIR/dev
mkdir $LVM_SYSTEM_DIR $DM_DEV_DIR $DM_DEV_DIR/mapper $TESTDIR/lib
cd $TESTDIR
for i in `find $abs_top_builddir/daemons/dmeventd/plugins/ -name \*.so`; do
echo Setting up symlink from $i to $TESTDIR/lib
ln -s $i $TESTDIR/lib
done
}
teardown_devs() {
test -n "$PREFIX" && {
rm -rf $TESTDIR/dev/$PREFIX*
init_udev_transaction
while dmsetup table | grep -q ^$PREFIX; do
for s in `dmsetup info -c -o name --noheading | grep ^$PREFIX`; do
dmsetup remove $s >& /dev/null || true
done
done
finish_udev_transaction
}
# 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 [ -n "$SCSI_DEBUG_DEV" ] ; then
modprobe -r scsi_debug
else
test -n "$LOOP" && losetup -d $LOOP
test -n "$LOOPFILE" && rm -f $LOOPFILE
fi
unset devs # devs is set in prepare_devs()
unset LOOP
}
teardown() {
echo $LOOP
echo $PREFIX
test -n "$LOCAL_CLVMD" && {
kill "$LOCAL_CLVMD"
sleep .1
kill -9 "$LOCAL_CLVMD" || true
}
test -n "$LOCAL_DMEVENTD" && kill -9 "$LOCAL_DMEVENTD"
teardown_devs
test -n "$TESTDIR" && {
cd $OLDPWD
rm -rf $TESTDIR || echo BLA
}
}
trap_teardown() {
trap 'set +vx; STACKTRACE; set -vx' ERR
trap 'aux teardown' EXIT # don't forget to clean up
}
make_ioerror() {
echo 0 10000000 error | dmsetup create ioerror
ln -s $DM_DEV_DIR/mapper/ioerror $DM_DEV_DIR/ioerror
}
prepare_loop() {
size=$1
test -n "$size" || size=32
# skip if prepare_scsi_debug_dev() was used
if [ -n "$SCSI_DEBUG_DEV" -a -n "$LOOP" ]; then
return 0
fi
test -z "$LOOP"
test -n "$DM_DEV_DIR"
trap_teardown
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
LOOPFILE="$PWD/test.img"
dd if=/dev/zero of="$LOOPFILE" bs=$((1024*1024)) count=0 seek=$(($size-1))
if LOOP=`losetup -s -f "$LOOPFILE" 2>/dev/null`; then
return 0
elif LOOP=`losetup -f` && losetup $LOOP "$LOOPFILE"; then
# no -s support
return 0
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
if [ -n "$LOOP" ]; then
break
fi
done
test -n "$LOOP" # confirm or fail
return 0
fi
exit 1 # should not happen
}
# 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"
shift
local SCSI_DEBUG_PARAMS="$@"
test -n "$SCSI_DEBUG_DEV" && return 0
test -z "$LOOP"
test -n "$DM_DEV_DIR"
trap_teardown
# Skip test if awk isn't available (required for get_sd_devs_)
which awk || exit 200
# Skip test if scsi_debug module is unavailable or is already in use
modprobe --dry-run scsi_debug || exit 200
lsmod | grep -q scsi_debug && exit 200
# 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 || exit 200
sleep 2 # allow for async Linux SCSI device registration
local DEBUG_DEV=/dev/$(grep scsi_debug /sys/block/*/device/model | cut -f4 -d /)
[ -b $DEBUG_DEV ] || exit 1 # should not happen
# Create symlink to scsi_debug device in $DM_DEV_DIR
SCSI_DEBUG_DEV=$DM_DEV_DIR/$(basename $DEBUG_DEV)
# Setting $LOOP provides means for prepare_devs() override
LOOP=$SCSI_DEBUG_DEV
ln -snf $DEBUG_DEV $SCSI_DEBUG_DEV
return 0
}
cleanup_scsi_debug_dev()
{
aux teardown_devs
unset SCSI_DEBUG_DEV
unset LOOP
}
prepare_devs() {
local n="$1"
test -z "$n" && n=3
local devsize="$2"
test -z "$devsize" && devsize=34
local pvname="$3"
test -z "$pvname" && pvname="pv"
prepare_loop $(($n*$devsize))
if ! loopsz=`blockdev --getsz $LOOP 2>/dev/null`; then
loopsz=`blockdev --getsize $LOOP 2>/dev/null`
fi
local size=$(($loopsz/$n))
init_udev_transaction
for i in `seq 1 $n`; do
local name="${PREFIX}$pvname$i"
local dev="$DM_DEV_DIR/mapper/$name"
eval "dev$i=$dev"
devs="$devs $dev"
echo 0 $size linear $LOOP $((($i-1)*$size)) > $name.table
dmsetup create $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
}
disable_dev() {
init_udev_transaction
for dev in "$@"; do
# first we make the device inaccessible
echo 0 10000000 error | dmsetup load $dev
dmsetup resume $dev
# now let's try to get rid of it if it's unused
#dmsetup remove $dev
done
finish_udev_transaction
}
enable_dev() {
init_udev_transaction
for dev in "$@"; do
local name=`echo "$dev" | sed -e 's,.*/,,'`
dmsetup create $name $name.table || dmsetup load $name $name.table
dmsetup resume $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 || {
echo "Internal error: $dev not backed up, can't restore!"
exit 1
}
dd of=$dev if=$dev.backup bs=1024
done
}
prepare_pvs() {
prepare_devs "$@"
pvcreate -ff $devs
}
prepare_vg() {
vgremove -ff $vg || true
teardown_devs
prepare_pvs "$@"
vgcreate -c n $vg $devs
pvs -v
}
prepare_lvmconf() {
local filter="$1"
test -z "$filter" && \
filter='[ "a/dev\/mirror/", "a/dev\/mapper\/.*pv[0-9_]*$/", "r/.*/" ]'
locktype=
if test -n "$LVM_TEST_LOCKING"; then locktype="locking_type = $LVM_TEST_LOCKING"; fi
cat > $TESTDIR/etc/lvm.conf.new <<-EOF
$LVM_TEST_CONFIG
devices {
dir = "$DM_DEV_DIR"
scan = "$DM_DEV_DIR"
filter = $filter
cache_dir = "$TESTDIR/etc"
sysfs_scan = 0
}
log {
syslog = 0
indent = 1
level = 9
file = "$TESTDIR/debug.log"
overwrite = 1
activation = 1
}
backup {
backup = 0
archive = 0
}
global {
abort_on_internal_errors = 1
library_dir = "$TESTDIR/lib"
locking_dir = "$TESTDIR/var/lock/lvm"
$locktype
}
activation {
udev_sync = 1
udev_rules = 1
polling_interval = 0
}
EOF
# FIXME remove this workaround after mmap & truncating file problems solved
mv -f $TESTDIR/etc/lvm.conf.new $TESTDIR/etc/lvm.conf
cat $TESTDIR/etc/lvm.conf
}
prepare() {
ulimit -c unlimited
# FIXME any way to set this just for our children?
# echo 1 > /proc/sys/kernel/core_uses_pid
prepare_testroot
prepare_lvmconf
prepare_clvmd
# set up some default names
vg=${PREFIX}vg
vg1=${PREFIX}vg1
vg2=${PREFIX}vg2
lv=LV
lv1=LV1
lv2=LV2
lv3=LV3
lv4=LV4
}
LANG=C
LC_ALL=C
TZ=UTC
unset CDPATH
. ./init.sh || { echo >&2 you must run make first; exit 1; }
. ./lvm-utils.sh
set -vexE -o pipefail
aux prepare