summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-08-24 12:21:31 -0500
committerDavid Teigland <teigland@redhat.com>2012-08-24 12:21:31 -0500
commita444becc9744d04754a3d780df3884e71f18a84e (patch)
tree7096bf314e8632a5ae8f0ed9448b7ebb32be292b
parent52102eae4df5f2a35e75f7bb1aad0677c53d2113 (diff)
downloaddct-stuff-a444becc9744d04754a3d780df3884e71f18a84e.tar.gz
dct-stuff-a444becc9744d04754a3d780df3884e71f18a84e.tar.xz
dct-stuff-a444becc9744d04754a3d780df3884e71f18a84e.zip
sanlvm: add script
-rwxr-xr-xlvm/sanlvm390
1 files changed, 390 insertions, 0 deletions
diff --git a/lvm/sanlvm b/lvm/sanlvm
new file mode 100755
index 0000000..2fff9b7
--- /dev/null
+++ b/lvm/sanlvm
@@ -0,0 +1,390 @@
+#!/bin/bash
+
+host_id=0
+cmd=""
+vgname=""
+lvname=""
+lock_mode=""
+active_mode=""
+offset=""
+
+help() {
+ vg="\$vg"
+ host_id="\$host_id"
+ echo ""
+ echo "1. /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 " 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 ""
+ echo "3. sanlvm start"
+ echo " start lockspaces for vgs @sanlvm, created above"
+ echo " sanlock add_lockspace -s $vg:$host_id:/dev/$vg/leases:0"
+ echo ""
+ echo "4. 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 ""
+ exit 0
+}
+
+if [[ $# == 0 ]]; then
+ help
+fi
+
+arg1=$1
+
+if [[ $arg1 == "help" ]]; then
+ help
+fi
+
+if [[ $arg1 == "--ex" ]] || [[ $arg1 == "--sh" ]]; then
+ lock_mode=$arg1
+ cmd=$2
+else
+ cmd=$1
+fi
+
+# vg name is the arg preceding the first pv path arg,
+# or the last arg when no pv paths exist
+# e.g. vgcreate, vgchange, vgextend, lvcreate
+
+get_vg_name() {
+ prev=$2
+
+ for i in $args
+ do
+ first=`expr substr $i 1 1`
+ if [ "$first" == "/" ]; then
+ vgname=$prev
+ return
+ fi
+
+ prev=$i
+ done
+
+ for i in $args
+ do
+ vgname=$i
+ done
+}
+
+# lv name follows -n or --name arg
+# FIXME: this doesn't work without a space, i.e. -nfoo
+
+get_lv_name() {
+ save_next=0
+
+ for i in $args
+ do
+ if [[ $save_next == 1 ]]
+ lvname=$i
+ return
+ fi
+
+ if [[ "$i" == "-n" ]] || [[ "$i" == "--name" ]]; then
+ save_next=1
+ continue
+ fi
+ done
+}
+
+# vg name is part of an lv path, e.g. lvextend, lvremove
+# first arg containing '/'
+
+get_vg_lv_name() {
+ for i in $args
+ do
+ ind=`expr index $i /`
+ if [ "$ind" -gt 0 ]; then
+ lvname=`basename $i`
+ dir=`dirname $i`
+ vgname=`basename $dir`
+ return
+ fi
+ done
+}
+
+get_host_id() {
+ host_id=`awk '/^host_id/ { print $2 }' < /etc/sanlvm.conf`
+
+ if [[ $? -ne 0 ]]; then
+ echo no host_id found in /etc/sanlvm.conf
+ exit 1
+ 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
+ do
+ if [[ "$i" == "-ay" ]] || [[ "$i" == "-aly" ]] || [[ "$i" == "-aey" ]]; then
+ active_mode="y"
+ return
+ fi
+
+ if [[ "$i" == "-an" ]] || [[ "$i" == "-aln" ]] || [[ "$i" == "-aen" ]]; then
+ active_mode="n"
+ return
+ fi
+
+ if [[ "$i" == "-a" ]] || [[ "$i == "--available" ]]; then
+ check_next=1
+ continue
+ fi
+
+ if [[ $check_next == 1 ]]; then
+ ind=`expr index $i y`
+ if [ "$ind" -gt 0 ]; then
+ active_mode="y"
+ else
+ active_mode="n"
+ fi
+ return
+ fi
+ done
+}
+
+# get the offset value from the @sanlvm_offset_xyz tag on the lv
+
+get_lease_offset() {
+ tags=`lvs --noheadings -o lv_name,lv_tags $vgname | grep $lvname | awk '{print $2}'`
+
+ # FIXME: handle case where the lv has tags other than ours
+
+ offset=`echo $tags | cut --delimiter=_ --fields=3`
+}
+
+if [[ "$cmd" == "start" ]]; then
+ get_host_id
+
+ for vgname in `vgs @sanlvm --noheadings -o vg_name`; do
+ 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=$*
+
+ get_vg_name
+
+ lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ lvm lvcreate -n leases -L 1G $vgname
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ sanlock direct init -s $vgname:0:/dev/$vgname/leases:0
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ sanlock direct init -r $vgname:vglk:/dev/$vgname/leases:1048576
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ lvm vgchange --addtag @sanlvm $vgname
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "_lvcreate" ]]; then
+ # wrapped by vglk
+
+ shift
+
+ args=$*
+
+ get_vg_name
+ get_lv_name
+
+ # FIXME: get offset by searching leases lv for unused lease area
+ offset=2097152
+
+ # FIXME: add arg to disable activation
+ # lvcreate
+ lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ # FIXME: can remove this once lvcreate doesn't activate
+ lvm lvchange -an $vgname/$lvname
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ lvm lvchange --addtag @sanlvm_offset_$offset $vgname/$lvname
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ sanlock direct init -r $vgname:$lvname:/dev/$vgname/leases:$offset
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "lvcreate" ]]; then
+ # we need the multiple steps in _lvcreate to all be wrapped in vglk
+
+ args=$*
+
+ get_vg_name
+
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c ./sanlvm _lvcreate "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "_lvremove" ]]; then
+ # wrapped by vglk
+
+ shift
+
+ args=$*
+
+ get_vg_lv_name
+ get_lease_offset
+
+ # lvremove, this will fail if the lv is in use
+ lvm "$@"
+
+ # FIXME: release lv lease is there is one
+
+ # FIXME: clear the lease area that was used for the lv activation
+ # lease, if there was one (there was an offset tag)
+
+ exit 0
+
+elif [[ "$cmd" == "lvremove" ]]; then
+ # we need the multiple steps in _lvremove to all be wrapped in vglk
+
+ args=$*
+
+ get_vg_lv_name
+
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c ./sanlvm _lvremove "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ 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_vg_lv_name
+ get_active_mode
+ get_lease_offset
+
+ if [[ "$active_mode" == "y" ]]; then
+ # acquire lease, then activate
+
+ if [[ "$lock_mode" == "--sh" ]]; then
+ suffix=":SH"
+ elif [[ "$lock_mode" == "--ex" ]]; then
+ suffix=""
+ else
+ echo "use sanlvm --ex|sh for lv activation"
+ exit 1
+ fi
+
+ sanlock client acquire -r $vgname:$lvname:/dev/$vgname/leases:$offset$suffix -p `pidof sanlvmd`
+
+ # lvchange activate
+ lvm "$@"
+
+ elif [[ "$active_mode" == "n" ]]; then
+ # deactivate, then release lease
+
+ # lvchange deactivate
+ lvm "$@"
+
+ sanlock client release -r $vgname:$lvname:/dev/$vgname/leases:$offset -p `pidof sanlvmd`
+ else
+ # non-activation related change to lv
+ # FIXME: do we also want to take ex lv lease?
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@
+ fi
+
+ exit 0
+
+elif [[ "$cmd" == "lvextend" ]] || [[ "$cmd" == "lvreduce" ]]; then
+ args=$*
+
+ get_vg_lv_name
+
+ # FIXME: do we also want to take ex lv lease?
+
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+
+else
+ if [[ $# -lt 2 ]]; then
+ echo vg name required
+ exit 1
+ fi
+
+ args=$*
+
+ get_vg_name
+
+ sanlock command -r $vgname:vglk:/dev/$vgname/leases:1048576 -c /sbin/lvm "$@"
+
+ if [[ $? -ne 0 ]]; then
+ exit 1
+ fi
+
+ exit 0
+fi
+