mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
283 lines
6.3 KiB
Bash
283 lines
6.3 KiB
Bash
#!/usr/bin/env bash
|
|
# Copyright (C) 2010-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
|
|
|
|
# check.sh: assert various things about volumes
|
|
|
|
# USAGE:
|
|
# check linear VG LV
|
|
# check lv_on VG LV PV
|
|
|
|
# check mirror VG LV [LOGDEV|core]
|
|
# check mirror_nonredundant VG LV
|
|
# check mirror_legs VG LV N
|
|
# check mirror_images_on VG LV DEV [DEV...]
|
|
|
|
# ...
|
|
|
|
test -z "$BASH" || set -e -o pipefail
|
|
|
|
die() {
|
|
echo "$@" >&2
|
|
return 1
|
|
}
|
|
|
|
lvl() {
|
|
lvs -a --noheadings "$@"
|
|
}
|
|
|
|
lvdevices() {
|
|
get lv_devices "$@"
|
|
}
|
|
|
|
mirror_images_redundant() {
|
|
local vg=$1
|
|
local lv=$vg/$2
|
|
lvs -a $vg -o+devices
|
|
for i in $(lvdevices $lv); do
|
|
echo "# $i:"
|
|
lvdevices $vg/$i | sort | uniq
|
|
done > check.tmp.all
|
|
|
|
(grep -v ^# check.tmp.all || true) | sort | uniq -d > check.tmp
|
|
|
|
test $(cat check.tmp | wc -l) -eq 0 || \
|
|
die "mirror images of $lv expected redundant, but are not:" \
|
|
$(cat check.tmp.all)
|
|
}
|
|
|
|
lv_on() {
|
|
local lv=$1/$2
|
|
(lvdevices $lv | grep -F "$3") || \
|
|
die "LV $lv expected on $3 but is not:" \
|
|
$(lvdevices $lv)
|
|
test $(lvdevices $lv | grep -vF "$3" | wc -l) -eq 0 || \
|
|
die "LV $lv contains unexpected devices:" \
|
|
$(lvdevices $lv)
|
|
}
|
|
|
|
mirror_images_on() {
|
|
local vg=$1
|
|
local lv=$2
|
|
shift 2
|
|
for i in $(lvdevices $lv); do
|
|
lv_on $vg $lv $1
|
|
shift
|
|
done
|
|
}
|
|
|
|
mirror_log_on() {
|
|
local vg=$1
|
|
local lv=$2
|
|
local where=$3
|
|
if test "$where" = "core"; then
|
|
get lv_field $vg/$lv mirror_log | not grep mlog
|
|
else
|
|
lv_on $vg ${lv}_mlog "$where"
|
|
fi
|
|
}
|
|
|
|
lv_is_contiguous() {
|
|
local lv=$1/$2
|
|
test $(lvl --segments $lv | wc -l) -eq 1 || \
|
|
die "LV $lv expected to be contiguous, but is not:" \
|
|
$(lvl --segments $lv)
|
|
}
|
|
|
|
lv_is_clung() {
|
|
local lv=$1/$2
|
|
test $(lvdevices $lv | sort | uniq | wc -l) -eq 1 || \
|
|
die "LV $lv expected to be clung, but is not:" \
|
|
$(lvdevices $lv | sort | uniq)
|
|
}
|
|
|
|
mirror_images_contiguous() {
|
|
for i in $(lvdevices $1/$2); do
|
|
lv_is_contiguous $1 $i
|
|
done
|
|
}
|
|
|
|
mirror_images_clung() {
|
|
for i in $(lvdevices $1/$2); do
|
|
lv_is_clung $1 $i
|
|
done
|
|
}
|
|
|
|
mirror() {
|
|
mirror_nonredundant "$@"
|
|
mirror_images_redundant $1 $2
|
|
}
|
|
|
|
mirror_nonredundant() {
|
|
local lv=$1/$2
|
|
local attr=$(get lv_field $lv attr)
|
|
(echo "$attr" | grep "^......m..$" >/dev/null) || {
|
|
if (echo "$attr" | grep "^o........$" >/dev/null) &&
|
|
lvs -a | fgrep "[${2}_mimage" >/dev/null; then
|
|
echo "TEST WARNING: $lv is a snapshot origin and looks like a mirror,"
|
|
echo "assuming it is actually a mirror"
|
|
else
|
|
die "$lv expected a mirror, but is not:" \
|
|
$(lvs $lv)
|
|
fi
|
|
}
|
|
test -z "$3" || mirror_log_on $1 $2 "$3"
|
|
}
|
|
|
|
mirror_legs() {
|
|
local expect=$3
|
|
test "$expect" -eq $(lvdevices $1/$2 | wc -w)
|
|
}
|
|
|
|
mirror_no_temporaries() {
|
|
local vg=$1
|
|
local lv=$2
|
|
(lvl -o name $vg | grep $lv | not grep "tmp") || \
|
|
die "$lv has temporary mirror images unexpectedly:" \
|
|
$(lvl $vg | grep $lv)
|
|
}
|
|
|
|
linear() {
|
|
local lv=$1/$2
|
|
test $(get lv_field $lv stripes -a) -eq 1 || \
|
|
die "$lv expected linear, but is not:" \
|
|
$(lvl $lv -o+devices)
|
|
}
|
|
|
|
# in_sync <VG> <LV>
|
|
# Works for "mirror" and "raid*"
|
|
in_sync() {
|
|
local a
|
|
local b
|
|
local idx
|
|
local type
|
|
local lvm_name="$1/$2"
|
|
local dm_name=$(echo $lvm_name | sed s:-:--: | sed s:/:-:)
|
|
|
|
if ! a=(`dmsetup status $dm_name`); then
|
|
die "Unable to get sync status of $1"
|
|
elif [ ${a[2]} = "snapshot-origin" ]; then
|
|
if ! a=(`dmsetup status ${dm_name}-real`); then
|
|
die "Unable to get sync status of $1"
|
|
fi
|
|
fi
|
|
|
|
if [ ${a[2]} = "raid" ]; then
|
|
# 6th argument is the sync ratio for RAID
|
|
idx=6
|
|
type=${a[3]}
|
|
elif [ ${a[2]} = "mirror" ]; then
|
|
# 4th Arg tells us how far to the sync ratio
|
|
idx=$((${a[3]} + 4))
|
|
type=${a[2]}
|
|
else
|
|
die "Unable to get sync ratio for target type '${a[2]}'"
|
|
fi
|
|
|
|
b=( $(echo ${a[$idx]} | sed s:/:' ':) )
|
|
|
|
if [ ${b[0]} != ${b[1]} ]; then
|
|
echo "$lvm_name ($type) is not in-sync"
|
|
return 1
|
|
fi
|
|
|
|
if [[ ${a[$(($idx - 1))]} =~ a ]]; then
|
|
die "$lvm_name in-sync, but 'a' characters in health status"
|
|
fi
|
|
|
|
echo "$lvm_name ($type) is in-sync"
|
|
return 0
|
|
}
|
|
|
|
active() {
|
|
local lv=$1/$2
|
|
(get lv_field $lv attr | grep "^....a....$" >/dev/null) || \
|
|
die "$lv expected active, but lvs says it's not:" \
|
|
$(lvl $lv -o+devices)
|
|
dmsetup info $1-$2 >/dev/null ||
|
|
die "$lv expected active, lvs thinks it is but there are no mappings!"
|
|
}
|
|
|
|
inactive() {
|
|
local lv=$1/$2
|
|
(get lv_field $lv attr | grep "^....[-isd]....$" >/dev/null) || \
|
|
die "$lv expected inactive, but lvs says it's not:" \
|
|
$(lvl $lv -o+devices)
|
|
not dmsetup info $1-$2 2>/dev/null || \
|
|
die "$lv expected inactive, lvs thinks it is but there are mappings!"
|
|
}
|
|
|
|
# Check for list of LVs from given VG
|
|
lv_exists() {
|
|
local vg=$1
|
|
local lv=
|
|
while [ $# -gt 1 ]; do
|
|
shift
|
|
lv="$lv $vg/$1"
|
|
done
|
|
lvl $lv &>/dev/null || \
|
|
die "$lv expected to exist but does not"
|
|
}
|
|
|
|
pv_field() {
|
|
local actual=$(get pv_field "$1" "$2" "${@:4}")
|
|
test "$actual" = "$3" || \
|
|
die "pv_field: PV=\"$1\", field=\"$2\", actual=\"$actual\", expected=\"$3\""
|
|
}
|
|
|
|
vg_field() {
|
|
local actual=$(get vg_field $1 "$2" "${@:4}")
|
|
test "$actual" = "$3" || \
|
|
die "vg_field: vg=$1, field=\"$2\", actual=\"$actual\", expected=\"$3\""
|
|
}
|
|
|
|
lv_field() {
|
|
local actual=$(get lv_field $1 "$2" "${@:4}")
|
|
test "$actual" = "$3" || \
|
|
die "lv_field: lv=$lv, field=\"$2\", actual=\"$actual\", expected=\"$3\""
|
|
}
|
|
|
|
compare_fields() {
|
|
local cmd1=$1
|
|
local obj1=$2
|
|
local field1=$3
|
|
local cmd2=$4
|
|
local obj2=$5
|
|
local field2=$6
|
|
local val1=$($cmd1 --noheadings -o "$field1" "$obj1")
|
|
local val2=$($cmd2 --noheadings -o "$field2" "$obj2")
|
|
test "$val1" = "$val2" || \
|
|
die "compare_fields $obj1($field1): $val1 $obj2($field2): $val2"
|
|
}
|
|
|
|
compare_vg_field() {
|
|
local vg1=$1
|
|
local vg2=$2
|
|
local field=$3
|
|
local val1=$(vgs --noheadings -o "$field" $vg1)
|
|
local val2=$(vgs --noheadings -o "$field" $vg2)
|
|
test "$val1" = "$val2" || \
|
|
die "compare_vg_field: $vg1: $val1, $vg2: $val2"
|
|
}
|
|
|
|
pvlv_counts() {
|
|
local local_vg=$1
|
|
local num_pvs=$2
|
|
local num_lvs=$3
|
|
local num_snaps=$4
|
|
lvs -o+devices $local_vg
|
|
vg_field $local_vg pv_count $num_pvs
|
|
vg_field $local_vg lv_count $num_lvs
|
|
vg_field $local_vg snap_count $num_snaps
|
|
}
|
|
|
|
unset LVM_VALGRIND
|
|
"$@"
|