summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-08-29 16:47:58 -0500
committerDavid Teigland <teigland@redhat.com>2012-08-29 16:47:58 -0500
commit52a93f9d621deabac7d0d686c527771317d2ded9 (patch)
tree5f323cfb64db527927150e06f0b986ed2125fa76
parentc5e56956ea89a06644f17c24eb105e4273294c89 (diff)
downloaddct-stuff-52a93f9d621deabac7d0d686c527771317d2ded9.tar.gz
dct-stuff-52a93f9d621deabac7d0d686c527771317d2ded9.tar.xz
dct-stuff-52a93f9d621deabac7d0d686c527771317d2ded9.zip
sanlvm: update
Signed-off-by: David Teigland <teigland@redhat.com>
-rwxr-xr-xlvm/sanlvm271
1 files changed, 206 insertions, 65 deletions
diff --git a/lvm/sanlvm b/lvm/sanlvm
index 511fc57..4594db9 100755
--- a/lvm/sanlvm
+++ b/lvm/sanlvm
@@ -2,6 +2,7 @@
host_id=0
cmd=
+glpath=
vgname=
lvname=
lock_mode=
@@ -9,38 +10,76 @@ active_mode=
no_active=
offset=
+# sanlvmd is only needed when sanlvm is used with lv
+# activation leases. When sanlvm is only used to
+# serialize vg metadata changes, it's not needed.
+#
+# sanlvmd is a process that sanlock views as owning the lv
+# activation leases. When a vg disappears/fails, sanlock
+# will notify the owner of the leases in that vg; in this
+# case, it sends SIGTERM to sanlvmd. When sanlvmd gets
+# this SIGTERM, it knows that its leases will be disappearing
+# soon, and that another host would be able to acquire them.
+# So, it needs to force the local host to stop using the
+# lv's it has locked, since they won't be locked much longer.
+#
+# To do this, it could:
+# - forcibly deactivate the sanlvm lvs in the failed vgs
+# - suspend the lv's in the failed vgs
+# - or suspend lv's, replace with the error target and resume
+# and once done, it can release the leases on those lvs.
+#
+# (If the sanlock watchdog is enabled, it will fire to reset
+# the host if sanlvmd is not able to release the leases
+# before another host could acquire them.)
+#
+# If the lv's are suspended, sanlvmd could monitor and wait
+# for the vg to reappear. When it does, it could reacquire
+# the leases for the suspended lv's and then resume the lv's.
+# (Unless the leases have been acquired by another host since
+# they were released, in which case they cannot be reacquired
+# by the oringal host, and the lv's will not be resumed.)
+
help() {
vg="\$vg"
host_id="\$host_id"
echo ""
- echo "1. /etc/sanlvm.conf"
+ echo "/etc/sanlvm.conf"
echo " must contain unique host_id definition from 1 to 2000, e.g."
echo " host_id 1"
echo ""
- echo "2. sanlvm vgcreate [options] $vg <devs>"
+ echo "sanlvm vgcreate [options] $vg <devs>"
echo " create vg, unprotected by sanlock,"
echo " create and initialize storage in $vg for sanlock to use"
- echo " vgcreate [options] $vg <devs>"
- echo " lvcreate -n leases -L 1G $vg"
- echo " sanlock direct init -s $vg:0:/dev/$vg/leases:0"
- echo " sanlock direct init -r $vg:vglk:/dev/$vg/leases:1048576"
- echo " vgchange --addtag @sanlvm $vg"
+ echo " . vgcreate [options] $vg <devs>"
+ echo " . lvcreate -n leases -L 1G $vg"
+ echo " . sanlock direct init -s $vg:0:/dev/$vg/leases:0"
+ echo " . sanlock direct init -r $vg:vglk:/dev/$vg/leases:1048576"
+ echo " . vgchange --addtag @sanlvm $vg"
echo ""
- echo "3. sanlvm start"
+ echo "sanlvm start"
echo " start lockspaces for vgs @sanlvm, created above"
- echo " sanlock add_lockspace -s $vg:$host_id:/dev/$vg/leases:0"
+ echo " . sanlock add_lockspace -s $vg:$host_id:/dev/$vg/leases:0"
echo ""
- echo "4. sanlvm <lvmcmd> ..."
+ echo "sanlvm <lvmcmd> ..."
echo " lvm commands within $vg are serialized by sanlock"
- echo " sanlock command -r $vg:vglk:/dev/$vg/leases:1048576 -c /sbin/lvm <lvmcmd> ..."
+ echo " . sanlock command -r $vg:vglk:/dev/$vg/leases:1048576 -c /sbin/lvm <lvmcmd> ..."
echo ""
-
- echo "sanlvm vgcreate [options] $vg <devs>"
- echo "sanlvm start"
echo "sanlvm [--na] lvcreate ..."
- echo "sanlvm lvextend|lvreduce|lvremove ..."
+ echo " create an lv with or without (--na) an associated lv"
+ echo " activation lease. without an activation lease, the"
+ echo " the activation state among hosts is ignored."
+ echo ""
echo "sanlvm --sh|ex lvchange -ay ..."
+ echo " acquire a shared or exclusive lease, then activate the lv."
+ echo " an exclusive lease prevents more than one host from activating"
+ echo " the lv at once, a shared lease allows multiple hosts to"
+ echo " activate the lv at once, and prevents any from activating"
+ echo " it exclusively."
+ echo ""
echo "sanlvm lvchange -an ..."
+ echo " deactivate the lv, then release its lease"
+ echo ""
exit 0
}
@@ -71,7 +110,7 @@ fi
get_vg_name() {
prev=$2
- for i in $args
+ for i in $get_args
do
first=`expr substr $i 1 1`
if [[ "$first" == "/" ]]; then
@@ -82,7 +121,7 @@ get_vg_name() {
prev=$i
done
- for i in $args
+ for i in $get_args
do
vgname=$i
done
@@ -94,7 +133,7 @@ get_vg_name() {
get_lv_name() {
save_next=0
- for i in $args
+ for i in $get_args
do
if [[ $save_next == 1 ]]; then
lvname=$i
@@ -112,7 +151,7 @@ get_lv_name() {
# first arg containing '/'
get_vg_lv_name() {
- for i in $args
+ for i in $get_args
do
ind=`expr index $i /`
if [ $ind -gt 0 ]; then
@@ -133,12 +172,20 @@ get_host_id() {
fi
}
+get_global_lease() {
+ glpath=`awk '/^global_lease_path/ { print $2 }' < /etc/sanlvm.conf`
+
+ if [[ $? -ne 0 ]]; then
+ echo "no global_lease_path found in /etc/sanlvm.conf"
+ fi
+}
+
# search lvchange args for -a, ---available
# if there's a "y" anywhere after the option, then active_mode="y"
# if there's a "n" anywhere after the option, then active_mode="n"
get_active_mode() {
- for i in $args
+ for i in $get_args
do
if [[ "$i" == "-ay" ]] || [[ "$i" == "-aly" ]] || [[ "$i" == "-aey" ]]; then
active_mode="y"
@@ -181,21 +228,54 @@ get_lease_offset() {
offset=`echo $tags | cut --delimiter=_ --fields=3`
}
-if [[ "$cmd" == "start" ]]; then
+if [[ "$cmd" == "global_init" ]]; then
+ get_global_lease
+
+ if [[ "$glpath" == "" ]]; then
+ exit 1
+ fi
+
+ sanlock direct init -s sanlvm_global:0:$glpath:0
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ sanlock direct init -r sanlvm_global:lease:$glpath:1048576
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "start" ]]; then
+ get_global_lease
get_host_id
+ if [[ "$glpath" != "" ]]; then
+ lvm lvchange -a y $glpath
+ sanlock add_lockspace -s sanlvm_global:$host_id:$glpath:0
+ fi
+
for vgname in `vgs @sanlvm --noheadings -o vg_name`; do
+ # FIXME: do something to prevent sanlvm lv's from
+ # automatically being activated by the system at
+ # startup; then this vgchange -an is not needed.
+ vgchange -an $vgname
+
lvm lvchange -a y /dev/$vgname/leases
echo adding lockspace $vgname, this may take minutes...
sanlock add_lockspace -s $vgname:$host_id:/dev/$vgname/leases:0
done
exit 0
-fi
-if [[ "$cmd" == "vgcreate" ]]; then
- args=$*
+elif [[ "$cmd" == "vgcreate" ]]; then
+ # FIXME: wrap this function in sanlvm_global:lease
+
+ get_args=$*
get_vg_name
lvm "$@"
@@ -230,20 +310,94 @@ if [[ "$cmd" == "vgcreate" ]]; then
exit 0
+elif [[ "$cmd" == "vgextend" ]]; then
+
+ get_args=$*
+ get_vg_name
+ get_glpath
+
+ # FIXME: take both global lease and vglk, e.g.
+ # sanlock command -r sanlvm_global:lease:$glpath:1048576 -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@"
+
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "vgremove" ]]; then
+
+
+ get_args=$*
+ get_vg_name
+ get_glpath
+
+ # It doesn't work to hold the vglk around vgremove, because
+ # the vglk requires the leases lv to be open, which causes
+ # the vgremove to fail. This is similar to the reason we can't
+ # hold the vglk around vgcreate: the leases area for vglk doesn't
+ # exist yet because it's inside the vg being created.
+
+ # FIXME: we could do the lvremoves automatically,
+ # but it looks messy
+
+ found=0
+
+ for lvname in `lvs $vgname --noheadings -o lv_name`; do
+ if [[ "$lvname" != "leases" ]]; then
+ echo "run sanlvm lvremove $vgname/$lvname before vgremove"
+ found=1
+ fi
+ done
+
+ if [[ $found -eq 1 ]]; then
+ exit 1
+ fi
+
+ # FIXME: wrap vgremove in sanlvm_global:lease
+
+ lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "vgchange" ]]; then
+
+ # FIXME: catch variations of vgchange -ay / -an
+ # and either prohibit (require sanlvm lvchange), or
+ # translate into sanlvm lvchange here.
+
+ lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
elif [[ "$cmd" == "_lvcreate" ]]; then
# wrapped by vglk
-
shift
- args=$*
-
+ get_args=$*
get_vg_name
get_lv_name
- # FIXME: get offset by searching leases lv for unused lease area
- offset=2097152
+ offset=`sanlock direct next_free /dev/$vgname/leases`
+
+ if [[ $? -ne 0 ]]; then
+ echo "no space for new lease on /dev/$vgname/leases"
+ exit 1
+ fi
+
+ # FIXME: if we use recent lvcreate arg to disable activation,
+ # on creation, then we can remove the lvchange -an that follows.
- # FIXME: use recent lvcreate arg to disable activation
# lvcreate
lvm "$@"
@@ -251,7 +405,6 @@ elif [[ "$cmd" == "_lvcreate" ]]; then
exit 1
fi
- # FIXME: can remove this once lvcreate doesn't activate
lvm lvchange -an $vgname/$lvname
if [[ $? -ne 0 ]]; then
@@ -275,8 +428,7 @@ elif [[ "$cmd" == "_lvcreate" ]]; then
elif [[ "$cmd" == "lvcreate" ]]; then
# we need the multiple steps in _lvcreate to all be wrapped in vglk
- args=$*
-
+ get_args=$*
get_vg_name
if [[ "$no_active" == "--na" ]]; then
@@ -295,17 +447,13 @@ elif [[ "$cmd" == "lvcreate" ]]; then
elif [[ "$cmd" == "_lvremove" ]]; then
# wrapped by vglk
-
shift
- args=$*
-
vgname=$SANLVM_VGNAME
lvname=$SANLVM_LVNAME
offset=$SANLVM_OFFSET
- # refuse to remove the lv if the local
- # host has the lv activated
+ # refuse to remove the lv if the local host has the lv activated
status=`sanlock client status | grep "r $vgname:$lvname"`
@@ -314,9 +462,8 @@ elif [[ "$cmd" == "_lvremove" ]]; then
exit 1
fi
- # acquire ex activation lock on the lv so
- # we know that no hosts have it active
- # FIXME: I don't think sanlock client acquire success/fail exit codes are always correct
+ # acquire ex activation lock on the lv so we know that no hosts have it active
+ # FIXME: I don't think sanlock acquire success/fail exit codes are always correct
sanlock client acquire -r $vgname:$lvname:/dev/$vgname/leases:$offset -p `pidof sanlvmd`
@@ -336,8 +483,8 @@ elif [[ "$cmd" == "_lvremove" ]]; then
exit 0
elif [[ "$cmd" == "lvremove" ]]; then
- args=$*
+ get_args=$*
get_vg_lv_name
get_lease_offset
@@ -357,18 +504,15 @@ elif [[ "$cmd" == "lvremove" ]]; then
exit 0
-elif [[ "$cmd" == "_lvextend" ]] || [[ "$cmd" == "_lvreduce" ]]; then
+elif [[ "$cmd" == "_lvextend" ]] || [[ "$cmd" == "_lvreduce" ]] || [[ "$cmd" == "_lvconvert" ]] || [[ "$cmd" == "_lvresize" ]]; then
# wrapped by vglk
-
shift
- args=$*
-
vgname=$SANLVM_VGNAME
lvname=$SANLVM_LVNAME
offset=$SANLVM_OFFSET
- # refuse to extend/reduce the lv if the local
+ # refuse to extend/reduce/convert the lv if the local
# host has the lv activated
# FIXME: allow extend of active lv, not reduce
@@ -389,7 +533,7 @@ elif [[ "$cmd" == "_lvextend" ]] || [[ "$cmd" == "_lvreduce" ]]; then
exit 1
fi
- # lvextend/lvreduce
+ # lvextend/lvreduce/lvconvert
lvm "$@"
sanlock client release -r $vgname:$lvname:/dev/$vgname/leases:$offset -p `pidof sanlvmd`
@@ -397,9 +541,9 @@ elif [[ "$cmd" == "_lvextend" ]] || [[ "$cmd" == "_lvreduce" ]]; then
exit 0;
-elif [[ "$cmd" == "lvextend" ]] || [[ "$cmd" == "lvreduce" ]]; then
- args=$*
+elif [[ "$cmd" == "lvextend" ]] || [[ "$cmd" == "lvreduce" ]] || [[ "$cmd" == "lvconvert" ]] || [[ "$cmd" == "lvresize" ]]; then
+ get_args=$*
get_vg_lv_name
get_lease_offset
@@ -420,15 +564,8 @@ elif [[ "$cmd" == "lvextend" ]] || [[ "$cmd" == "lvreduce" ]]; then
exit 0
elif [[ "$cmd" == "lvchange" ]]; then
- # sanlvmd is a process that sanlock views as owning the lv
- # activation leases. sanlvmd should restrict sigkill, and
- # on sigterm from sanlock, it should try to forcibly deactivate
- # the sanlvm lvs, or suspend the lv's or suspend lv's, replace
- # with the error target and resume.
- # (what about handling different vg lockspaces separately?)
-
- args=$*
+ get_args=$*
get_vg_lv_name
get_active_mode
get_lease_offset
@@ -439,7 +576,6 @@ elif [[ "$cmd" == "lvchange" ]]; then
fi
if [[ "$active_mode" == "y" ]]; then
- # acquire lease, then activate
if [[ "$lock_mode" == "--sh" ]]; then
suffix=":SH"
@@ -457,10 +593,9 @@ elif [[ "$cmd" == "lvchange" ]]; then
lvm "$@"
elif [[ "$active_mode" == "n" ]]; then
- # deactivate, then release lease
- # lock mode is not used for lvchange -an, and shouldn't be
- # provided, but ignore it if it is
+ # lock mode is not used for lvchange -an,
+ # ignore it if one was provided
if [[ "$lock_mode" != "" ]]; then
shift
@@ -474,7 +609,6 @@ elif [[ "$cmd" == "lvchange" ]]; then
# non-activation related change to lv
# I don't know of any lv changes that would require either
# vglk or the lv lock
- # sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@
echo "no locks needed for this command"
lvm "$@"
@@ -482,14 +616,21 @@ elif [[ "$cmd" == "lvchange" ]]; then
exit 0
+elif [[ "$cmd" == "vgmerge" ]] || [[ "$cmd" == "vgsplit" ]] || [[ "$cmd" == "vgrename" ]] || [[ "$cmd" == "lvrename" ]]; then
+
+ # FIXME: the vg commands could be implemented by combining
+ # a global lease and vglk's
+
+ echo "command not supported with sanlvm"
+ exit 1
+
else
if [[ $# -lt 2 ]]; then
echo vg name required
exit 1
fi
- args=$*
-
+ get_args=$*
get_vg_name
sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@"