[DRBD-cvs] svn commit by phil - r3038 - in branches/drbd-8.0: .
scripts - Florian's nice Xen-DRBD script.
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Thu Aug 30 22:17:26 CEST 2007
Author: phil
Date: 2007-08-30 22:17:24 +0200 (Thu, 30 Aug 2007)
New Revision: 3038
Added:
branches/drbd-8.0/scripts/block-drbd
Modified:
branches/drbd-8.0/drbd.spec.in
branches/drbd-8.0/scripts/Makefile
Log:
Florian's nice Xen-DRBD script.
Modified: branches/drbd-8.0/drbd.spec.in
===================================================================
--- branches/drbd-8.0/drbd.spec.in 2007-08-30 19:45:14 UTC (rev 3037)
+++ branches/drbd-8.0/drbd.spec.in 2007-08-30 20:17:24 UTC (rev 3038)
@@ -122,6 +122,7 @@
/sbin/drbdmeta
/usr/lib/drbd/outdate-peer.sh
/etc/ha.d/resource.d/drbddisk
+/etc/xen/scripts/block-drbd
%defattr(644,root,root)
%config(noreplace) /etc/drbd.conf
Modified: branches/drbd-8.0/scripts/Makefile
===================================================================
--- branches/drbd-8.0/scripts/Makefile 2007-08-30 19:45:14 UTC (rev 3037)
+++ branches/drbd-8.0/scripts/Makefile 2007-08-30 20:17:24 UTC (rev 3038)
@@ -62,6 +62,8 @@
install -m 755 drbddisk $(PREFIX)/etc/ha.d/resource.d
install -d $(PREFIX)/usr/lib/drbd
install -m 755 outdate-peer.sh $(PREFIX)/usr/lib/drbd
+ mkdir -p $(PREFIX)/etc/xen/scripts
+ install -m 755 block-drbd $(PREFIX)/etc/xen/scripts
ifeq ($(DIST),suselike)
ln -sf ../etc/init.d/drbd $(PREFIX)/sbin/rcdrbd
endif
@@ -77,4 +79,5 @@
uninstall:
rm $(INITD)drbd
rm $(PREFIX)/etc/ha.d/resource.d/drbddisk
+ rm $(PREFIX)/etc/xen/scripts/block-drbd
! test -L $(PREFIX)/sbin/rcdrbd || rm $(PREFIX)/sbin/rcdrbd
Added: branches/drbd-8.0/scripts/block-drbd
===================================================================
--- branches/drbd-8.0/scripts/block-drbd 2007-08-30 19:45:14 UTC (rev 3037)
+++ branches/drbd-8.0/scripts/block-drbd 2007-08-30 20:17:24 UTC (rev 3038)
@@ -0,0 +1,278 @@
+#!/bin/bash
+#
+# A modified version of Xen's block script for use with DRBD.
+#
+# The idea is to give over the role assignment of DRBD
+# devices to this script. It will promote a DRBD device to primary
+# role when the Xen DomU gets started. During a Xen live migration
+# both DRBD devices will be primary for a short time. Other
+# than that only one side of the DRBD device pair will be
+# primary at a time.
+#
+# Syntax example for a DomU.cfg. 'r0' is the DRBD resource name.
+# disk = [ 'drbd:r0,sda1,w' ]
+#
+# Of course you have to set the "allow-two-primaries" in the
+# DRBD config.
+#
+# By Florian Haas, LINBIT Information Technologies 2007.
+#
+
+dir=$(dirname "$0")
+. "$dir/block-common.sh"
+
+##
+# canonicalise_mode mode
+#
+# Takes the given mode, which may be r, w, ro, rw, w!, or rw!, or variations
+# thereof, and canonicalises them to one of
+#
+# 'r': perform checks for a new read-only mount;
+# 'w': perform checks for a read-write mount; or
+# '!': perform no checks at all.
+#
+canonicalise_mode()
+{
+ local mode="$1"
+
+ if ! expr index "$mode" 'w' >/dev/null
+ then
+ echo 'r'
+ elif ! expr index "$mode" '!' >/dev/null
+ then
+ echo 'w'
+ else
+ echo '!'
+ fi
+}
+
+
+##
+# check_sharing device mode
+#
+# Check whether the device requested is already in use. To use the device in
+# read-only mode, it may be in use in read-only mode, but may not be in use in
+# read-write anywhere at all. To use the device in read-write mode, it must
+# not be in use anywhere at all.
+#
+# Prints one of
+#
+# 'local': the device may not be used because it is mounted in the current
+# (i.e. the privileged domain) in a way incompatible with the
+# requested mode;
+# 'guest': the device may not be used because it already mounted by a guest
+# in a way incompatible with the requested mode; or
+# 'ok': the device may be used.
+#
+check_sharing()
+{
+ local dev="$1"
+ local mode="$2"
+
+ local devmm=$(device_major_minor "$dev")
+ local file
+
+ if [ "$mode" = 'w' ]
+ then
+ toskip="^$"
+ else
+ toskip="^[^ ]* [^ ]* [^ ]* ro[, ]"
+ fi
+
+ for file in $(cat /proc/mounts | grep -v "$toskip" | cut -f 1 -d ' ')
+ do
+ if [ -e "$file" ]
+ then
+ local d=$(device_major_minor "$file")
+
+ if [ "$d" = "$devmm" ]
+ then
+ echo 'local'
+ return
+ fi
+ fi
+ done
+
+ local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE"
+ for dom in $(xenstore-list "$base_path")
+ do
+ for dev in $(xenstore-list "$base_path/$dom")
+ do
+ d=$(xenstore_read_default "$base_path/$dom/$dev/physical-device" "")
+
+ if [ "$d" = "$devmm" ]
+ then
+ if [ "$mode" = 'w' ]
+ then
+ if ! same_vm $dom
+ then
+ echo 'guest'
+ return
+ fi
+ else
+ local m=$(xenstore_read "$base_path/$dom/$dev/mode")
+ m=$(canonicalise_mode "$m")
+
+ if [ "$m" = 'w' ]
+ then
+ if ! same_vm $dom
+ then
+ echo 'guest'
+ return
+ fi
+ fi
+ fi
+ fi
+ done
+ done
+
+ echo 'ok'
+}
+
+
+same_vm()
+{
+ local otherdom="$1"
+ # Note that othervm can be MISSING here, because Xend will be racing with
+ # the hotplug scripts -- the entries in /local/domain can be removed by
+ # Xend before the hotplug scripts have removed the entry in
+ # /local/domain/0/backend/. In this case, we want to pretend that the
+ # VM is the same as FRONTEND_UUID, because that way the 'sharing' will be
+ # allowed.
+ local othervm=$(xenstore_read_default "/local/domain/$otherdom/vm" \
+ "$FRONTEND_UUID")
+
+ [ "$FRONTEND_UUID" = "$othervm" ]
+}
+
+
+##
+# check_device_sharing dev mode
+#
+# Perform the sharing check for the given physical device and mode.
+#
+check_device_sharing()
+{
+ local dev="$1"
+ local mode=$(canonicalise_mode "$2")
+ local result
+
+ if [ "x$mode" = 'x!' ]
+ then
+ return 0
+ fi
+
+ result=$(check_sharing "$dev" "$mode")
+
+ if [ "$result" != 'ok' ]
+ then
+ do_ebusy "Device $dev is mounted " "$mode" "$result"
+ fi
+}
+
+
+##
+# do_ebusy prefix mode result
+#
+# Helper function for check_device_sharing check_file_sharing, calling ebusy
+# with an error message constructed from the given prefix, mode, and result
+# from a call to check_sharing.
+#
+do_ebusy()
+{
+ local prefix="$1"
+ local mode="$2"
+ local result="$3"
+
+ if [ "$result" = 'guest' ]
+ then
+ dom='a guest '
+ when='now'
+ else
+ dom='the privileged '
+ when='by a guest'
+ fi
+
+ if [ "$mode" = 'w' ]
+ then
+ m1=''
+ m2=''
+ else
+ m1='read-write '
+ m2='read-only '
+ fi
+
+ release_lock "block"
+ ebusy \
+"${prefix}${m1}in ${dom}domain,
+and so cannot be mounted ${m2}${when}."
+}
+
+
+t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
+
+case "$command" in
+ add)
+ phys=$(xenstore_read_default "$XENBUS_PATH/physical-device" 'MISSING')
+ if [ "$phys" != 'MISSING' ]
+ then
+ # Depending upon the hotplug configuration, it is possible for this
+ # script to be called twice, so just bail.
+ exit 0
+ fi
+
+ if [ -n "$t" ]
+ then
+ p=$(xenstore_read "$XENBUS_PATH/params")
+ mode=$(xenstore_read "$XENBUS_PATH/mode")
+ fi
+
+ case $t in
+ drbd)
+ drbd_resource=$p
+ drbd_state="$(/sbin/drbdadm state $drbd_resource)"
+ drbd_lstate="${drbd_state%%/*}"
+ drbd_dev="$(/sbin/drbdadm sh-dev $drbd_resource)"
+ if [ "$drbd_lstate" != 'Primary' ]; then
+ /sbin/drbdadm primary $drbd_resource
+ fi
+ dev=$drbd_dev
+ FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
+ FRONTEND_UUID=$(xenstore_read_default \
+ "/local/domain/$FRONTEND_ID/vm" 'unknown')
+ claim_lock "block"
+ check_device_sharing "$dev" "$mode"
+ write_dev "$dev"
+ release_lock "block"
+ exit 0
+ ;;
+ "")
+ claim_lock "block"
+ success
+ release_lock "block"
+ ;;
+ esac
+ ;;
+
+ remove)
+ case $t in
+ drbd)
+ p=$(xenstore_read "$XENBUS_PATH/params")
+ drbd_resource=$p
+ drbd_state="$(/sbin/drbdadm state $drbd_resource)"
+ drbd_lstate="${drbd_state%%/*}"
+ drbd_dev="$(/sbin/drbdadm sh-dev $drbd_resource)"
+
+ if [ "$drbd_lstate" != 'Secondary' ]; then
+ /sbin/drbdadm secondary $drbd_resource
+ fi
+ exit 0
+ ;;
+
+ "")
+ exit 0
+ ;;
+ esac
+ ;;
+
+esac
Property changes on: branches/drbd-8.0/scripts/block-drbd
___________________________________________________________________
Name: svn:executable
+ *
More information about the drbd-cvs
mailing list