[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