summaryrefslogtreecommitdiffstats
path: root/os-plugins/plugins/xen/files/xen.examples/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'os-plugins/plugins/xen/files/xen.examples/scripts')
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/blktap93
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block398
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/block-common.sh117
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block-iscsi78
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block-nbd34
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block-npiv77
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-common.sh238
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-vport79
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/domain-lock83
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/external-device-migrate98
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/locking.sh98
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/logging.sh22
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/network-bridge380
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/network-nat125
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/network-route27
l---------os-plugins/plugins/xen/files/xen.examples/scripts/set-lock1
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vif-bridge100
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/vif-common.sh158
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vif-nat192
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vif-route56
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vm-monitor41
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vscsi22
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vtpm22
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-common.sh448
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/vtpm-delete18
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-hotplug-common.sh35
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-impl208
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-migration.sh19
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-cleanup36
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-common.sh93
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/xen-network-common.sh118
-rw-r--r--os-plugins/plugins/xen/files/xen.examples/scripts/xen-script-common.sh44
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/xend-relocation.sh159
-rwxr-xr-xos-plugins/plugins/xen/files/xen.examples/scripts/xmclone.sh793
34 files changed, 4510 insertions, 0 deletions
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/blktap b/os-plugins/plugins/xen/files/xen.examples/scripts/blktap
new file mode 100755
index 00000000..01a0f6c6
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/blktap
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+# Copyright (c) 2005, XenSource Ltd.
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+. "$dir/block-common.sh"
+
+findCommand "$@"
+
+##
+# check_blktap_sharing file mode
+#
+# Perform the sharing check for the given blktap and mode.
+#
+check_blktap_sharing()
+{
+ local file="$1"
+ local mode="$2"
+
+ 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
+ params=$(xenstore_read "$base_path/$dom/$dev/params" | cut -d: -f2)
+ if [ "$file" = "$params" ]
+ 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'
+}
+
+
+t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING')
+if [ -n "$t" ]
+then
+ p=$(xenstore_read "$XENBUS_PATH/params")
+ # if we have a ':', chew from head including :
+ if echo $p | grep -q \:
+ then
+ p=${p#*:}
+ fi
+fi
+# some versions of readlink cannot be passed a regular file
+if [ -L "$p" ]; then
+ file=$(readlink -f "$p") || fatal "$p link does not exist."
+else
+ file="$p"
+fi
+
+if [ "$command" = 'add' ]
+then
+ [ -e "$file" ] || { fatal $file does not exist; }
+
+ FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
+ FRONTEND_UUID=$(xenstore_read "/local/domain/$FRONTEND_ID/vm")
+ mode=$(xenstore_read "$XENBUS_PATH/mode")
+ mode=$(canonicalise_mode "$mode")
+
+ if [ "$mode" != '!' ]
+ then
+ result=$(check_blktap_sharing "$file" "$mode")
+ [ "$result" = 'ok' ] || ebusy "$file already in use by other domain"
+ fi
+
+ success
+fi
+
+exit 0
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block b/os-plugins/plugins/xen/files/xen.examples/scripts/block
new file mode 100755
index 00000000..cf579ed4
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block
@@ -0,0 +1,398 @@
+#!/bin/bash
+
+dir=$(dirname "$0")
+. "$dir/block-common.sh"
+
+expand_dev() {
+ local dev
+ case $1 in
+ /*)
+ dev=$1
+ ;;
+ *)
+ dev=/dev/$1
+ ;;
+ esac
+ echo -n $dev
+}
+
+
+##
+# 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'
+}
+
+
+##
+# 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
+}
+
+
+##
+# check_device_sharing file dev mode
+#
+# Perform the sharing check for the given file mounted through the given
+# loopback interface, in the given mode.
+#
+check_file_sharing()
+{
+ local file="$1"
+ local dev="$2"
+ local mode="$3"
+
+ result=$(check_sharing "$dev" "$mode")
+
+ if [ "$result" != 'ok' ]
+ then
+ do_ebusy "File $file is loopback-mounted through $dev,
+which 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
+ FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
+ FRONTEND_UUID=$(xenstore_read_default \
+ "/local/domain/$FRONTEND_ID/vm" 'unknown')
+
+ case $t in
+ phy)
+ dev=$(expand_dev $p)
+
+ if [ -L "$dev" ]
+ then
+ dev=$(readlink -f "$dev") || fatal "$dev link does not exist."
+ fi
+ test -e "$dev" || fatal "$dev does not exist."
+ test -b "$dev" || fatal "$dev is not a block device."
+
+ claim_lock "block"
+ check_device_sharing "$dev" "$mode"
+ write_dev "$dev"
+ release_lock "block"
+ exit 0
+ ;;
+
+ file)
+ lo_flags=""
+ [ "${mode/S}" = "$mode" ] || lo_flags="-y"
+ # Canonicalise the file, for sharing check comparison, and the mode
+ # for ease of use here.
+ file=$(readlink -f "$p") || fatal "$p does not exist."
+ test -f "$file" || fatal "$file does not exist."
+ mode=$(canonicalise_mode "$mode")
+ [ "$mode" = "r" ] && lo_flags="$lo_flags -r"
+
+ claim_lock "block"
+
+ if [ "$mode" = 'w' ] && ! stat "$file" -c %A | grep -q w
+ then
+ release_lock "block"
+ ebusy \
+"File $file is read-only, and so I will not
+mount it read-write in a guest domain."
+ fi
+
+ losetup_failure=1
+ for do_losetup in 1 2 3
+ do
+ loopdev=''
+ for dev in /dev/loop*
+ do
+ if [ ! -b "$dev" ]
+ then
+ continue
+ fi
+
+ f=$(losetup "$dev" 2>/dev/null) || f=''
+
+ if [ "$f" ]
+ then
+ # $dev is in use. Check sharing.
+ if [ "x$mode" = 'x!' ]
+ then
+ continue
+ fi
+
+ f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
+
+ # $f is the filename, as read from losetup, but the loopback
+ # driver truncates filenames at 64 characters, so we need to go
+ # trawling through the store if it's longer than that. Truncation
+ # is indicated by an asterisk at the end of the filename.
+ if expr index "$f" '*' >/dev/null
+ then
+ found=""
+ for dom in $(xenstore-list "$XENBUS_BASE_PATH")
+ do
+ for domdev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
+ do
+ d=$(xenstore_read_default \
+ "$XENBUS_BASE_PATH/$dom/$domdev/node" "")
+ if [ "$d" = "$dev" ]
+ then
+ f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
+ found=1
+ break 2
+ fi
+ done
+ done
+
+ if [ ! "$found" ]
+ then
+ # This loopback device is in use by someone else, so skip it.
+ log debug "Loopback sharing check skips device $dev."
+ continue
+ fi
+ fi
+
+ # Canonicalise the filename for the comparison.
+
+ # I have seen this readlink fails because the filename given by
+ # losetup is only the basename. This cannot happen when the loop
+ # device is set up through this script, because file is
+ # canonicalised above, but it may happen when loop devices are set
+ # up some other way. This readlink may also conceivably fail if
+ # the file backing this loop device has been removed.
+
+ # For maximum safety, in the case that $f does not resolve, we
+ # assume that $file and $f are in the same directory.
+
+ # If you create a loopback filesystem, remove it and continue to
+ # run on it, and then create another file with the same name, then
+ # this check will block that -- don't do that.
+
+ # If you create loop devices through some other mechanism, use
+ # relative filenames, and then use the same filename through this
+ # script, then this check will block that -- don't do that either.
+
+ f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
+
+
+ if [ "$f" = "$file" ]
+ then
+ check_file_sharing "$file" "$dev" "$mode"
+ fi
+ else
+ # $dev is not in use, so we'll remember it for use later; we want
+ # to finish the sharing check first.
+
+ if [ "$loopdev" = '' ]
+ then
+ loopdev="$dev"
+ fi
+ fi
+ done
+
+ if [ "$loopdev" = '' ]
+ then
+ release_lock "block"
+ fatal 'Failed to find an unused loop device'
+ fi
+
+ losetup $lo_flags "$loopdev" "$file" && losetup_failure="" && break
+ done
+
+ if [ "$losetup_failure" ]
+ then
+ fatal 'losetup $lo_flags $loopdev $file'
+ fi
+
+ xenstore_write "$XENBUS_PATH/node" "$loopdev"
+ write_dev "$loopdev"
+ release_lock "block"
+ exit 0
+ ;;
+
+ "")
+ claim_lock "block"
+ success
+ release_lock "block"
+ ;;
+ esac
+ ;;
+
+ remove)
+ case $t in
+ phy)
+ exit 0
+ ;;
+
+ file)
+ node=$(xenstore_read "$XENBUS_PATH/node")
+
+ #In case the loopback is temporarily blocked, retry the losetup -d.
+ for i in 1 2 3 4 5
+ do
+ if losetup -d "$node"
+ then
+ exit 0
+ fi
+ sleep 1
+ done
+ log err "losetup -d $node failed."
+ exit 1
+ ;;
+
+ "")
+ exit 0
+ ;;
+ esac
+ ;;
+
+esac
+
+# If we've reached here, $t is neither phy nor file, so fire a helper script.
+[ -x /etc/xen/scripts/block-"$t" ] && \
+ /etc/xen/scripts/block-"$t" "$command" $node
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/block-common.sh
new file mode 100644
index 00000000..efedbf50
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-common.sh
@@ -0,0 +1,117 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+findCommand "$@"
+
+if [ "$command" != "add" ] &&
+ [ "$command" != "remove" ]
+then
+ log err "Invalid command: $command"
+ exit 1
+fi
+
+
+XENBUS_PATH="${XENBUS_PATH:?}"
+
+
+ebusy()
+{
+ xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
+ "$XENBUS_PATH/hotplug-status" busy
+ log err "$@"
+ exit 1
+}
+
+
+##
+# Print the given device's major and minor numbers, written in hex and
+# separated by a colon.
+device_major_minor()
+{
+ stat -L -c %t:%T "$1"
+}
+
+
+##
+# Write physical-device = MM,mm to the store, where MM and mm are the major
+# and minor numbers of device respectively.
+#
+# @param device The device from which major and minor numbers are read, which
+# will be written into the store.
+#
+write_dev() {
+ local mm
+
+ mm=$(device_major_minor "$1")
+
+ if [ -z $mm ]
+ then
+ fatal "Backend device does not exist"
+ fi
+
+ xenstore_write "$XENBUS_PATH/physical-device" "$mm"
+
+ success
+}
+
+
+##
+# 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
+}
+
+
+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")
+ local target=$(xenstore_read_default "/local/domain/$FRONTEND_ID/target" \
+ "-1")
+ [ "$FRONTEND_UUID" = "$othervm" -o "$target" = "$otherdom" ]
+}
+
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-iscsi b/os-plugins/plugins/xen/files/xen.examples/scripts/block-iscsi
new file mode 100755
index 00000000..f473a0a9
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-iscsi
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# Usage: block-iscsi [add tgtname | remove dev]
+#
+# This assumes you're running a correctly configured
+# iscsi target (server) at the other end!
+# Note that we assume that the passwords for discovery (if needed)
+# are in /etc/iscsid.conf
+# and the node session passwords (if required) in the
+# open-iscsi database below /var/lib/open-iscsi/node.db
+#
+# (c) Kurt Garloff <kurt@garloff.de>, 2006-09-04, GNU GPL
+# Contributors: Jim Fehlig <jfehlig@novell.com>
+# Stefan de Konink <skinkie@xs4all.nl>
+
+dir=$(dirname "$0")
+. "$dir/block-common.sh"
+
+# echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node"
+
+find_sdev()
+{
+ unset dev
+ for session in /sys/class/iscsi_session/session*; do
+ if [ "$1" = "`cat $session/targetname`" ]; then
+ dev=`basename $session/device/target*/*:0:*/block*/*`
+ return
+ fi
+ done
+}
+
+find_sdev_rev()
+{
+ unset tgt
+ for session in /sys/class/iscsi_session/session*; do
+ dev=`basename $session/device/target*/*:0:*/block*/*`
+ if [ "$dev" = "$1" ]; then
+ tgt=`cat $session/targetname`
+ return
+ fi
+ done
+}
+
+case "$command" in
+ add)
+ # load modules and start iscsid
+ /etc/init.d/open-iscsi status >/dev/null 2>&1 ||
+ { /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; }
+ # list of targets on node
+ /sbin/iscsiadm -m discovery | sed "s/ .*//g" | while read line; do /sbin/iscsiadm -m discovery -t sendtargets -p $line; done >/dev/null
+ par=`xenstore-read $XENBUS_PATH/params` || true
+ TGTID=`echo $par | sed "s/\/\///g"`
+ while read rec uuid; do
+ if [ "$uuid" = "$TGTID" ]; then
+ find_sdev $TGTID
+ if [ -z "$dev" ]; then
+ /sbin/iscsiadm -m node -T $uuid -p $rec --login || exit 2
+ sleep 4
+ find_sdev $TGTID
+ fi
+ xenstore-write $XENBUS_PATH/node /dev/$dev
+ write_dev /dev/$dev
+ exit 0
+ fi
+ done < <(/sbin/iscsiadm -m node)
+ exit 1
+ ;;
+
+ remove)
+ node=`xenstore-read $XENBUS_PATH/node` || true
+ dev=$node; dev=${dev#/dev/}
+ find_sdev_rev $dev
+ if [ -x /sbin/blockdev -a -n "$node" ]; then blockdev --flushbufs "$node"; fi
+ test -z "$tgt" && exit 2
+ /sbin/iscsiadm -m node -T $tgt --logout
+ exit 1
+ ;;
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-nbd b/os-plugins/plugins/xen/files/xen.examples/scripts/block-nbd
new file mode 100755
index 00000000..d4571152
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-nbd
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Usage: block-nbd [bind server ctl_port |unbind node]
+#
+# The node argument to unbind is the name of the device node we are to
+# unbind.
+#
+# This assumes you're running a correctly configured server at the other end!
+
+dir=$(dirname "$0")
+. "$dir/block-common.sh"
+
+#set -x
+par=`xenstore-read $XENBUS_PATH/params` || true
+#echo $par
+
+case "$command" in
+ add)
+ modprobe nbd
+ for dev in /dev/nbd*; do
+ if nbd-client $par $dev; then
+ xenstore-write $XENBUS_PATH/node $dev
+ write_dev $dev
+ exit 0
+ fi
+ done
+ exit 1
+ ;;
+ remove)
+ node=`xenstore-read $XENBUS_PATH/node` || true
+ nbd-client -d $node
+ exit 0
+ ;;
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv
new file mode 100755
index 00000000..19719dab
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+# Usage: block-npiv [add npiv | remove dev]
+
+dir=$(dirname "$0")
+. "$dir/block-npiv-common.sh"
+. "$dir/block-common.sh"
+
+#set -x
+#command=$1
+
+case "$command" in
+ add)
+ # Params is one big arg, with fields separated by hyphens:
+ # FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN#
+ # arg 2 - Fabric Name
+ # arg 3 - VPORT's WWPN
+ # arg 4 - VPORT's WWNN
+ # arg 5 - Target's WWPN
+ # arg 6 - LUN # on Target
+ # no wwn contains a leading 0x - it is a 16 character hex value
+ # You may want to optionally pick a specific adapter ?
+ par=`xenstore-read $XENBUS_PATH/params` || true
+ #par=$2
+ NPIVARGS=$par;
+ LUN=${NPIVARGS##*-*-*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $LUN = $NPIVARGS ; then exit 1; fi
+ TGTWWPN=${NPIVARGS##*-*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $TGTWWPN = $NPIVARGS ; then exit 1; fi
+ VPORTWWNN=${NPIVARGS##*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $VPORTWWNN = $NPIVARGS ; then exit 1; fi
+ VPORTWWPN=${NPIVARGS##*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $VPORTWWPN = $NPIVARGS ; then exit 1; fi
+ FABRICNM=$NPIVARGS
+
+ # Ensure we compare everything using lower-case hex characters
+ TGTWWPN=`echo $TGTWWPN | tr A-Z a-z`
+ VPORTWWPN=`echo $VPORTWWPN | tr A-Z a-z`
+ VPORTWWNN=`echo $VPORTWWNN | tr A-Z a-z`
+ FABRICNM=`echo $FABRICNM | tr A-Z a-z`
+
+ find_vhost $VPORTWWPN
+ if test -z "$vhost" ; then
+ create_vport $FABRICNM $VPORTWWPN $VPORTWWNN
+ if [ $? -ne 0 ] ; then exit 2; fi
+ sleep 8
+ find_vhost $VPORTWWPN
+ if test -z "$vhost" ; then exit 3; fi
+ fi
+ find_sdev $vhost $TGTWWPN $LUN
+ if test -z "$dev"; then
+ echo "- - -" > /sys/class/scsi_host/$vhost/scan
+ sleep 2
+ find_sdev $vhost $TGTWWPN $LUN
+ fi
+ if test ! -z "$dev"; then
+ xenstore-write $XENBUS_PATH/node /dev/$dev
+ write_dev /dev/$dev
+ exit 0
+ fi
+
+ exit 4
+ ;;
+
+ remove)
+ node=`xenstore-read $XENBUS_PATH/node` || true
+ #node=$2
+ dev=$node; dev=${dev#/dev/}
+ # this is really screwy. the first delete of a lun will
+ # terminate the entire vport (all luns)
+ find_vhost_from_dev $dev
+ if test -z "$vhost" ; then exit 5; fi
+ flush_nodes_on_vhost $vhost
+ delete_vhost $vhost
+ exit 0
+ ;;
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-common.sh
new file mode 100755
index 00000000..dcf71036
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-common.sh
@@ -0,0 +1,238 @@
+
+
+# Look for the NPIV vport with the WWPN
+# $1 contains the WWPN (assumes it does not contain a leading "0x")
+find_vhost()
+{
+ unset vhost
+
+ # look in upstream locations
+ for fchost in /sys/class/fc_vports/* ; do
+ if test -e $fchost/port_name ; then
+ wwpn=`cat $fchost/port_name | sed -e s/^0x//`
+ if test $wwpn = $1 ; then
+ # Note: makes the assumption the vport will always have an scsi_host child
+ vhost=`ls -d $fchost/device/host*`
+ vhost=`basename $vhost`
+ return
+ fi
+ fi
+ done
+
+ # look in vendor-specific locations
+
+ # Emulex - just looks like another scsi_host - so look at fc_hosts...
+ for fchost in /sys/class/fc_host/* ; do
+ if test -e $fchost/port_name ; then
+ wwpn=`cat $fchost/port_name | sed -e s/^0x//`
+ if test $wwpn = $1 ; then
+ # Note: makes the assumption the vport will always have an scsi_host child
+ vhost=`basename $fchost`
+ return
+ fi
+ fi
+ done
+}
+
+
+# Create a NPIV vport on the fabric w/ FABRICNM, with WWPN,WWNN
+# $1 contains FABRICNM
+# $2 contains the VPORT WWPN
+# $3 contains the VPORT WWNN
+# (assumes no name contains a leading "0x")
+create_vport()
+{
+ # find a base adapter with npiv support that is on the right fabric
+
+ # Look via upstream interfaces
+ for fchost in /sys/class/fc_host/* ; do
+ if test -e $fchost/vport_create ; then
+ # is the link up, w/ NPIV support ?
+ pstate=`cat $fchost/port_state`
+ ptype=`cat $fchost/port_type | cut -c 1-5`
+ fname=`cat $fchost/fabric_name | sed -e s/^0x//`
+ if [ $pstate = "Online" -a $ptype = "NPort" -a $fname = $1 ] ; then
+ vmax=`cat $fchost/max_npiv_vports`
+ vinuse=`cat $fchost/npiv_vports_inuse`
+ avail=`expr $vmax - $vinuse`
+ if [ $avail -gt 0 ] ; then
+ # create the vport
+ echo $2":"$3 > $fchost/vport_create
+ if [ $? -eq 0 ] ; then
+ return 0
+ fi
+ # failed - so we'll just look for the next adapter
+ fi
+ fi
+ fi
+ done
+
+ # Look in vendor-specific locations
+
+ # Emulex: interfaces mirror upstream, but are under adapter scsi_host
+ for shost in /sys/class/scsi_host/* ; do
+ if [ -e $shost/vport_create ] ; then
+ fchost=`ls -d $shost/device/fc_host*`
+ # is the link up, w/ NPIV support ?
+ pstate=`cat $fchost/port_state`
+ ptype=`cat $fchost/port_type | cut -c 1-5`
+ fname=`cat $fchost/fabric_name | sed -e s/^0x//`
+ if [ $pstate = "Online" -a $ptype = "NPort" -a $fname = $1 ] ; then
+ vmax=`cat $shost/max_npiv_vports`
+ vinuse=`cat $shost/npiv_vports_inuse`
+ avail=`expr $vmax - $vinuse`
+ if [ $avail -gt 0 ] ; then
+ # create the vport
+ echo $2":"$3 > $shost/vport_create
+ if [ $? -eq 0 ] ; then
+ return 0
+ fi
+ # failed - so we'll just look for the next adapter
+ fi
+ fi
+ fi
+ done
+
+ return 1
+}
+
+
+# Look for the LUN on the indicated scsi_host (which is an NPIV vport)
+# $1 is the scsi_host name (normalized to simply the hostX name)
+# $2 is the WWPN of the tgt port the lun is on
+# Note: this implies we don't support a multipath'd lun, or we
+# are explicitly identifying a "path"
+# $3 is the LUN number of the scsi device
+find_sdev()
+{
+ unset dev
+ hostno=${1/*host/}
+ for sdev in /sys/class/scsi_device/${hostno}:*:$3 ; do
+ if test -e $sdev/device/../fc_trans*/target${hostno}*/port_name ; then
+ tgtwwpn=`cat $sdev/device/../fc_trans*/target${hostno}*/port_name | sed -e s/^0x//`
+ if test $tgtwwpn = $2 ; then
+ if test -e $sdev/device/block* ; then
+ dev=`ls $sdev/device/block*`
+ dev=${dev##*/}
+ return
+ fi
+ fi
+ fi
+ done
+}
+
+
+# Look for the NPIV vhost based on a scsi "sdX" name
+# $1 is the "sdX" name
+find_vhost_from_dev()
+{
+ unset vhost
+ hostno=`readlink /sys/block/$1/device`
+ hostno=${hostno##*/}
+ hostno=${hostno%%:*}
+ if test -z "$hostno" ; then return; fi
+ vhost="host"$hostno
+}
+
+
+# We're about to terminate a vhost based on a scsi device
+# Flush all nodes on that vhost as they are about to go away
+# $1 is the vhost
+flush_nodes_on_vhost()
+{
+ if test ! -x /sbin/blockdev ; then return; fi
+ hostno=${1/*host/}
+ for sdev in /sys/class/scsi_device/${hostno}:* ; do
+ if test -e $sdev/device/block* ; then
+ dev=`ls $sdev/device/block*`
+ dev="/dev/"$dev
+ if test -n "$dev"; then
+ blockdev --flushbufs $dev
+ fi
+ fi
+ done
+}
+
+
+# Terminate a NPIV vhost
+# $1 is vhost
+delete_vhost()
+{
+ # use upstream interface
+ for vport in /sys/class/fc_vports/* ; do
+ if test -e $vport/device/$1 ; then
+ if test -e $vport/vport_delete ; then
+ echo "1" > $vport/vport_delete
+ if test $? -ne 0 ; then exit 6; fi
+ sleep 4
+ return
+ fi
+ fi
+ done
+
+ # use vendor specific interface
+
+ # Emulex
+ if test -e /sys/class/fc_host/$1/device/../scsi_host*/lpfc_drvr_version ; then
+ shost=`ls -1d /sys/class/fc_host/$1/device/../scsi_host* | sed s/.*scsi_host://`
+ vportwwpn=`cat /sys/class/fc_host/$1/port_name | sed s/^0x//`
+ vportwwnn=`cat /sys/class/fc_host/$1/node_name | sed s/^0x//`
+ echo "$vportwwpn:$vportwwnn" > /sys/class/scsi_host/$shost/vport_delete
+ if test $? -ne 0 ; then exit 6; fi
+ sleep 4
+ return
+ fi
+
+ # Qlogic
+ if test -e /sys/class/fc_host/$1/device/../scsi_host*/driver_version ; then
+ shost=`ls -1d /sys/class/fc_host/$1/device/../scsi_host* | sed s/.*scsi_host://`
+ vportwwpn=`cat /sys/class/fc_host/$1/port_name | sed s/^0x//`
+ vportwwnn=`cat /sys/class/fc_host/$1/node_name | sed s/^0x//`
+ echo "$vportwwpn:$vportwwnn" > /sys/class/scsi_host/$shost/vport_delete
+ if test $? -ne 0 ; then exit 6; fi
+ sleep 4
+ return
+ fi
+
+ exit 6
+}
+
+
+vport_status()
+{
+ # Look via upstream interfaces
+ for fchost in /sys/class/fc_host/* ; do
+ if test -e $fchost/vport_create ; then
+ vport_status_display $fchost $fchost
+ fi
+ done
+
+ # Look in vendor-specific locations
+
+ # Emulex: interfaces mirror upstream, but are under adapter scsi_host
+ for shost in /sys/class/scsi_host/* ; do
+ if [ -e $shost/vport_create ] ; then
+ fchost=`ls -d $shost/device/fc_host*`
+ vport_status_display $fchost $shost
+ fi
+ done
+
+ return 0
+}
+
+
+vport_status_display()
+{
+ echo
+ echo "fc_host: " $2
+ echo "port_state: " `cat $1/port_state`
+ echo "port_type: " `cat $1/port_type`
+ echo "fabric_name: " `cat $1/fabric_name`
+ echo "max_npiv_vports: " `cat $2/max_npiv_vports`
+ echo "npiv_vports_inuse: " `cat $2/npiv_vports_inuse`
+ echo "modeldesc: " `cat $2/modeldesc`
+ echo "speed: " `cat $1/speed`
+
+ return 0
+}
+
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-vport b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-vport
new file mode 100755
index 00000000..91185f74
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/block-npiv-vport
@@ -0,0 +1,79 @@
+#!/bin/bash
+
+# Usage: block-npiv-vport [create npivargs | delete vportwwpn | status]
+
+dir=$(dirname "$0")
+. "$dir/block-npiv-common.sh"
+
+#set -x
+command=$1
+params=$2
+
+case "$command" in
+ create)
+ # Params is one big arg, with fields separated by hyphens:
+ # FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN#
+ # arg 2 - Fabric Name
+ # arg 3 - VPORT's WWPN
+ # arg 4 - VPORT's WWNN
+ # arg 5 - Target's WWPN
+ # arg 6 - LUN # on Target
+ # no wwn contains a leading 0x - it is a 16 character hex value
+ # You may want to optionally pick a specific adapter ?
+ NPIVARGS=$params;
+ LUN=${NPIVARGS##*-*-*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $LUN = $NPIVARGS ; then exit 1; fi
+ TGTWWPN=${NPIVARGS##*-*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $TGTWWPN = $NPIVARGS ; then exit 1; fi
+ VPORTWWNN=${NPIVARGS##*-*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $VPORTWWNN = $NPIVARGS ; then exit 1; fi
+ VPORTWWPN=${NPIVARGS##*-}; NPIVARGS=${NPIVARGS%-*}
+ if test $VPORTWWPN = $NPIVARGS ; then exit 1; fi
+ FABRICNM=$NPIVARGS
+
+ # Ensure we compare everything using lower-case hex characters
+ TGTWWPN=`echo $TGTWWPN | tr A-Z a-z`
+ VPORTWWPN=`echo $VPORTWWPN | tr A-Z a-z`
+ VPORTWWNN=`echo $VPORTWWNN | tr A-Z a-z`
+ FABRICNM=`echo $FABRICNM | tr A-Z a-z`
+
+ find_vhost $VPORTWWPN
+ if test -z "$vhost" ; then
+ create_vport $FABRICNM $VPORTWWPN $VPORTWWNN
+ if [ $? -ne 0 ] ; then exit 2; fi
+ sleep 8
+ find_vhost $VPORTWWPN
+ if test -z "$vhost" ; then exit 3; fi
+ fi
+
+ exit 0
+ ;;
+
+ delete)
+ # Params is VPORT's WWPN
+ # no wwn contains a leading 0x - it is a 16 character hex value
+ VPORTWWPN=$params
+
+ # Ensure we compare everything using lower-case hex characters
+ VPORTWWPN=`echo $VPORTWWPN | tr A-Z a-z`
+
+ find_vhost $VPORTWWPN
+ if test -z "$vhost" ; then exit 4; fi
+ delete_vhost $vhost
+
+ exit 0
+ ;;
+
+ status)
+ vport_status
+
+ exit 0
+ ;;
+
+ *)
+ echo "Usage: block-npiv-vport [create npivargs | delete vportwwpn | status]"
+
+ exit 1
+ ;;
+esac
+
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/domain-lock b/os-plugins/plugins/xen/files/xen.examples/scripts/domain-lock
new file mode 100755
index 00000000..268d0058
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/domain-lock
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+basedir=$(dirname "$0")
+
+usage() {
+ echo "usage: domain-lock [-l|-u] -n <vm name> -i <vm uuid> -p <physical host> path"
+ echo "usage: domain-lock [-s] path"
+ echo ""
+ echo "-l lock"
+ echo "-u unlock"
+ echo "-s status (default)"
+ echo "-n Virtual Machine name"
+ echo "-i Virtual Machine Id or UUID"
+ echo "-p Virtual Machine Server (physical host) name"
+ echo "path A per-VM, unique location where external lock will be managed"
+ exit 1
+}
+
+remove_lock(){
+ local path=$1/lock
+ local name=$2
+
+ pid=`ps -efwww | grep vm-monitor | grep $name | awk '{print $2}'`
+ if [ -n "$pid" ]; then
+ kill $pid
+ rm -f $path
+ fi
+}
+
+get_status(){
+ local path=$1/lock
+ [ -f $path ] || exit 1
+
+ rc=`flock -xn $path /bin/true`
+ cat $path
+ exit $rc
+}
+
+mode="status"
+
+while getopts ":lusn:i:p:" opt; do
+ case $opt in
+ l )
+ mode="lock"
+ ;;
+ u )
+ mode="unlock"
+ ;;
+ s )
+ mode="status"
+ ;;
+ p )
+ vm_host=$OPTARG
+ ;;
+ n )
+ vm_name=$OPTARG
+ ;;
+ i )
+ vm_uuid=$OPTARG
+ ;;
+ \? )
+ usage
+ ;;
+ esac
+done
+
+shift $(($OPTIND - 1))
+vm_path=$1
+
+case $mode in
+ lock )
+ [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage
+ $basedir/set-lock $vm_path $vm_name $vm_uuid $vm_host
+ ;;
+ unlock )
+ [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage
+ remove_lock $vm_path $vm_name $vm_uuid $vm_host
+ ;;
+ status )
+ [ -z "$vm_path" ] && usage
+ get_status $vm_path
+ ;;
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/external-device-migrate b/os-plugins/plugins/xen/files/xen.examples/scripts/external-device-migrate
new file mode 100755
index 00000000..a4113483
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/external-device-migrate
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# Copyright (c) 2005 IBM Corporation
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+set -x
+
+# This script is called by XenD for migration of external devices
+# It does not handle the migration of those devices itself, but
+# passes the requests on to further applications
+# It handles the low-level command line parsing and some of the
+# synchronization
+
+dir=$(dirname "$0")
+. "$dir/logging.sh"
+
+
+function ext_dev_migrate_usage() {
+cat <<EOF
+Pass the following command line parameters to the script:
+
+-step <n> : n-th migration step
+-host <host> : the destination host
+-domname <domain name> : name of the domain that is migrating
+-type <device type> : the type of device that is migrating
+-subtype <dev. subtype>: the subtype of the device
+-recover : indicates recovery request; an error
+ occurred during migration
+-help : display this help screen
+EOF
+}
+
+# Parse the command line paramters. The following parameters must be
+# passed as the first ones in the sequence:
+# -step [required]
+# -host [required]
+# -domname [required]
+# -type [required]
+# -subtype [optional]
+# -recover [optional]
+# The remaining ones will be passed to the called function.
+function evaluate_params()
+{
+ local step host domname typ recover filename func stype
+ stype=""
+ while [ $# -ge 1 ]; do
+ case "$1" in
+ -step) step=$2; shift; shift;;
+ -host) host=$2; shift; shift;;
+ -domname) domname=$2; shift; shift;;
+ -type) typ=$2; shift; shift;;
+ -subtype) stype=$2; shift; shift;;
+ -recover) recover=1; shift;;
+ -help) ext_dev_migrate_usage; exit 0;;
+ *) break;;
+ esac
+ done
+
+ if [ "$step" = "" -o \
+ "$host" = "" -o \
+ "$typ" = "" -o \
+ "$domname" = "" ]; then
+ echo "Error: Parameter(s) missing (-step/-host/-type/-domname)" 1>&2
+ echo "" 1>&2
+ echo "$0 -help for usage." 1>&2
+ exit 1
+ fi
+
+ filename="$dir/$typ$stype-migration.sh"
+ if [ ! -r $filename ]; then
+ echo "Error: Could not find script '$filename'"
+ return
+ fi
+ . "$filename"
+
+ if [ "$recover" = "1" ]; then
+ func="$typ"_recover
+ eval $func $host $domname $step $*
+ else
+ func="$typ"_migration_step
+ eval $func $host $domname $step $*
+ fi
+}
+
+evaluate_params "$@"
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/locking.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/locking.sh
new file mode 100644
index 00000000..6ff58e7e
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/locking.sh
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+#
+# Serialisation
+#
+
+LOCK_SLEEPTIME=1
+LOCK_SPINNING_RETRIES=5
+LOCK_RETRIES=100
+LOCK_BASEDIR=/var/run/xen-hotplug
+
+
+claim_lock()
+{
+ local lockdir="$LOCK_BASEDIR/$1"
+ mkdir -p "$LOCK_BASEDIR"
+ _claim_lock "$lockdir"
+}
+
+
+release_lock()
+{
+ _release_lock "$LOCK_BASEDIR/$1"
+}
+
+
+_claim_lock()
+{
+ local lockdir="$1"
+ local owner=$(_lock_owner "$lockdir")
+ local retries=0
+
+ while [ $retries -lt $LOCK_RETRIES ]
+ do
+ mkdir "$lockdir" 2>/dev/null && trap "release_lock $1; sigerr" ERR &&
+ _update_lock_info "$lockdir" && return
+
+ local new_owner=$(_lock_owner "$lockdir")
+ if [ "$new_owner" != "$owner" ]
+ then
+ owner="$new_owner"
+ retries=0
+ fi
+
+ if [ $retries -gt $LOCK_SPINNING_RETRIES ]
+ then
+ sleep $LOCK_SLEEPTIME
+ else
+ sleep 0
+ fi
+ retries=$(($retries + 1))
+ done
+ _steal_lock "$lockdir"
+}
+
+
+_release_lock()
+{
+ trap sigerr ERR
+ rm -rf "$1" 2>/dev/null || true
+}
+
+
+_steal_lock()
+{
+ local lockdir="$1"
+ local owner=$(cat "$lockdir/owner" 2>/dev/null || echo "unknown")
+ log err "Forced to steal lock on $lockdir from $owner!"
+ _release_lock "$lockdir"
+ _claim_lock "$lockdir"
+}
+
+
+_lock_owner()
+{
+ cat "$1/owner" 2>/dev/null || echo "unknown"
+}
+
+
+_update_lock_info()
+{
+ echo "$$: $0" >"$1/owner"
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/logging.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/logging.sh
new file mode 100644
index 00000000..c1bc699c
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/logging.sh
@@ -0,0 +1,22 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+log() {
+ local level="$1"
+ shift
+ logger -p "daemon.$level" -- "$0:" "$@" || echo "$0 $@" >&2
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/network-bridge b/os-plugins/plugins/xen/files/xen.examples/scripts/network-bridge
new file mode 100755
index 00000000..ade0ce33
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/network-bridge
@@ -0,0 +1,380 @@
+#!/bin/bash
+#============================================================================
+# Default Xen network start/stop script.
+# Xend calls a network script when it starts.
+# The script name to use is defined in /etc/xen/xend-config.sxp
+# in the network-script field.
+#
+# This script creates a bridge (default ${netdev}), adds a device
+# (defaults to the device on the default gateway route) to it, copies
+# the IP addresses from the device to the bridge and adjusts the routes
+# accordingly.
+#
+# If all goes well, this should ensure that networking stays up.
+# However, some configurations are upset by this, especially
+# NFS roots. If the bridged setup does not meet your needs,
+# configure a different script, for example using routing instead.
+#
+# Usage:
+#
+# network-bridge (start|stop|status) {VAR=VAL}*
+#
+# Vars:
+#
+# bridge The bridge to use (default ${netdev}).
+# netdev The interface to add to the bridge (default gateway device).
+# antispoof Whether to use iptables to prevent spoofing (default no).
+#
+# Internal Vars:
+# pdev="p${netdev}"
+# tdev=tmpbridge
+#
+# start:
+# Creates the bridge as tdev
+# Copies the IP and MAC addresses from pdev to bridge
+# Renames netdev to be pdev
+# Renames tdev to bridge
+# Enslaves pdev to bridge
+#
+# stop:
+# Removes pdev from the bridge
+# Transfers addresses, routes from bridge to pdev
+# Renames bridge to tdev
+# Renames pdev to netdev
+# Deletes tdev
+#
+# status:
+# Print addresses, interfaces, routes
+#
+#============================================================================
+
+
+dir=$(dirname "$0")
+. "$dir/xen-script-common.sh"
+. "$dir/xen-network-common.sh"
+
+findCommand "$@"
+evalVariables "$@"
+
+is_network_root () {
+ local rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' /etc/mtab)
+ local rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/mtab)
+
+ [[ "$rootfs" =~ "^nfs" ]] || [[ "$rootopts" =~ "_netdev" ]] && has_nfsroot=1 || has_nfsroot=0
+ if [ $has_nfsroot -eq 1 ]; then
+ local bparms=$(cat /proc/cmdline)
+ for p in $bparms; do
+ local ipaddr=$(echo $p | awk /nfsroot=/'{ print substr($1,9,index($1,":")-9) }')
+ if [ "$ipaddr" != "" ]; then
+ local nfsdev=$(ip route get $ipaddr | awk /$ipaddr/'{ print $3 }')
+ [[ "$nfsdev" == "$netdev" ]] && return 0 || return 1
+ fi
+ done
+ fi
+ return 1
+}
+
+find_alt_device () {
+ local interf=$1
+ local prefix=${interf%[[:digit:]]}
+ local ifs=$(ip link show | grep " $prefix" |\
+ gawk '{ printf ("%s",substr($2,1,length($2)-1)) }' |\
+ sed s/$interf//)
+ echo "$ifs"
+}
+
+netdev=${netdev:-$(ip route list 0.0.0.0/0 | \
+ sed 's/.*dev \([a-z]\+[0-9]\+\).*$/\1/')}
+if is_network_root ; then
+ altdevs=$(find_alt_device $netdev)
+ for netdev in $altdevs; do break; done
+ if [ -z "$netdev" ]; then
+ [ -x /usr/bin/logger ] && /usr/bin/logger "network-bridge: bridging not supported on network root; not starting"
+ exit
+ fi
+fi
+netdev=${netdev:-eth0}
+bridge=${bridge:-${netdev}}
+antispoof=${antispoof:-no}
+
+pdev="p${netdev}"
+tdev=tmpbridge
+
+get_ip_info() {
+ addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
+ gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
+}
+
+do_ifup() {
+ if [ $1 != "${netdev}" ] || ! ifup $1 ; then
+ if [ -n "$addr_pfx" ] ; then
+ # use the info from get_ip_info()
+ ip addr flush $1
+ ip addr add ${addr_pfx} dev $1
+ ip link set dev $1 up
+ [ -n "$gateway" ] && ip route add default via ${gateway}
+ fi
+ fi
+}
+
+# Usage: transfer_addrs src dst
+# Copy all IP addresses (including aliases) from device $src to device $dst.
+transfer_addrs () {
+ local src=$1
+ local dst=$2
+ # Don't bother if $dst already has IP addresses.
+ if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then
+ return
+ fi
+ # Address lines start with 'inet' and have the device in them.
+ # Replace 'inet' with 'ip addr add' and change the device name $src
+ # to 'dev $src'.
+ ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
+s/inet/ip addr add/
+s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
+s/${src}/dev ${dst} label ${dst}/
+s/secondary//
+" | sh -e
+ # Remove automatic routes on destination device
+ ip route list | sed -ne "
+/dev ${dst}\( \|$\)/ {
+ s/^/ip route del /
+ p
+}" | sh -e
+}
+
+# Usage: transfer_routes src dst
+# Get all IP routes to device $src, delete them, and
+# add the same routes to device $dst.
+# The original routes have to be deleted, otherwise adding them
+# for $dst fails (duplicate routes).
+transfer_routes () {
+ local src=$1
+ local dst=$2
+ # List all routes and grep the ones with $src in.
+ # Stick 'ip route del' on the front to delete.
+ # Change $src to $dst and use 'ip route add' to add.
+ ip route list | sed -ne "
+/dev ${src}\( \|$\)/ {
+ h
+ s/^/ip route del /
+ P
+ g
+ s/${src}/${dst}/
+ s/^/ip route add /
+ P
+ d
+}" | sh -e
+}
+
+
+##
+# link_exists interface
+#
+# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
+#
+link_exists()
+{
+ if ip link show "$1" >/dev/null 2>/dev/null
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Set the default forwarding policy for $dev to drop.
+# Allow forwarding to the bridge.
+antispoofing () {
+ iptables -P FORWARD DROP
+ iptables -F FORWARD
+ iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
+}
+
+find_active_vlans() {
+ local netdev=$1
+ local vlan
+ local vlans
+ vlans=""
+ for vifcfg in /etc/sysconfig/network/ifcfg-vlan* ; do
+ vlan=${vifcfg/*\/ifcfg-}
+ if [ "$vlan" = "vlan*" ]; then
+ continue
+ fi
+ . $vifcfg
+ etherdevice="$ETHERDEVICE"
+ if [ -x /sbin/getcfg-interface ]; then
+ etherdevice=$(/sbin/getcfg-interface "$ETHERDEVICE")
+ fi
+ if [ "$ETHERDEVICE" = "$netdev" ] || [ "$etherdevice" = "$netdev" ] ; then
+ link_exists "$vlan" && vlans="$vlans $vlan"
+ fi
+ done
+ echo "$vlans"
+}
+
+# Usage: show_status dev bridge
+# Print ifconfig and routes.
+show_status () {
+ local dev=$1
+ local bridge=$2
+
+ echo '============================================================'
+ ip addr show ${dev}
+ ip addr show ${bridge}
+ echo ' '
+ brctl show ${bridge}
+ echo ' '
+ ip route list
+ echo ' '
+ route -n
+ echo '============================================================'
+}
+
+op_start () {
+ if [ "${bridge}" = "null" ] ; then
+ return
+ fi
+
+ if link_exists "$pdev"; then
+ # The device is already up.
+ return
+ fi
+
+ local bonded=""
+ [ -e /sys/class/net/${netdev}/bonding ] && bonded="yes"
+
+ vlans=$(find_active_vlans "${netdev}")
+ for vlan in $vlans ; do ifdown $vlan ; done
+
+ create_bridge ${tdev}
+
+ # Record creation of bridge in /dev/shm/sysconfig/xenbridges so other
+ # tools, e.g. yast2 lan, know that Xen bridging is active.
+ [ -d /dev/shm/sysconfig/xenbridges ] || mkdir /dev/shm/sysconfig/xenbridges
+ touch /dev/shm/sysconfig/xenbridges/${bridge}
+
+ preiftransfer ${netdev}
+ transfer_addrs ${netdev} ${tdev}
+ # Remember slaves for bonding interface.
+ if [ -e /sys/class/net/${netdev}/bonding/slaves ]; then
+ slaves=`cat /sys/class/net/${netdev}/bonding/slaves`
+ fi
+ # Remember the IP details for do_ifup.
+ get_ip_info ${netdev}
+ if ! ifdown ${netdev}; then
+ ip link set ${netdev} down
+ ip addr flush ${netdev}
+ fi
+
+ if [ "x${bonded}" = "xyes" ]
+ then
+ ip link set ${tdev} name ${bridge}
+ ln -sf /etc/sysconfig/network/ifcfg-${netdev} /etc/sysconfig/network/ifcfg-${pdev}
+ ifup ${pdev}
+ local gw=`ip route show dev ${pdev} | fgrep default | sed 's/default via //'`
+ ip addr flush ${pdev}
+ rm -f /etc/sysconfig/network/ifcfg-${pdev}
+ brctl addif ${bridge} ${pdev}
+ ip link set ${bridge} up
+ [ -n "$gw" ] && ip route add default via ${gw}
+ else
+ ip link set ${netdev} name ${pdev}
+ ip link set ${tdev} name ${bridge}
+
+ setup_bridge_port ${pdev}
+
+ # Restore slaves
+ if [ -n "${slaves}" ]; then
+ ip link set ${pdev} up
+ ifenslave ${pdev} ${slaves}
+ fi
+ add_to_bridge2 ${bridge} ${pdev}
+ do_ifup ${bridge}
+ fi
+
+ for vlan in $vlans ; do ifup $vlan ; done
+
+ if [ ${antispoof} = 'yes' ] ; then
+ antispoofing
+ fi
+}
+
+op_stop () {
+ if [ "${bridge}" = "null" ]; then
+ return
+ fi
+ if ! link_exists "$bridge"; then
+ return
+ fi
+
+ vlans=$(find_active_vlans "${netdev}")
+ for vlan in $vlans ; do ifdown $vlan ; done
+
+ transfer_addrs ${bridge} ${pdev}
+ if ! ifdown ${bridge}; then
+ get_ip_info ${bridge}
+ ip link set ${pdev} down
+ ip addr flush ${bridge}
+
+ brctl delif ${bridge} ${pdev}
+ ip link set ${bridge} down
+
+ ip link set ${bridge} name ${tdev}
+ brctl delbr ${tdev}
+ fi
+ ip link set ${pdev} down
+ ip link set ${pdev} name ${netdev}
+ do_ifup ${netdev}
+
+ # Remove record of bridge from /dev/shm/sysconfig/xenbridges ...
+ rm -f /dev/shm/sysconfig/xenbridges/${bridge}
+ # ... and directory itself if empty
+ if [ -z "$(ls -A /dev/shm/sysconfig/xenbridges 2>/dev/null)" ]; then
+ rmdir /dev/shm/sysconfig/xenbridges
+ fi
+
+ for vlan in $vlans ; do ifup $vlan ; done
+}
+
+# adds $dev to $bridge but waits for $dev to be in running state first
+add_to_bridge2() {
+ local bridge=$1
+ local dev=$2
+ local maxtries=10
+
+ echo -n "Waiting for ${dev} to negotiate link."
+ ip link set ${dev} up
+ for i in `seq ${maxtries}` ; do
+ if ifconfig ${dev} | grep -q RUNNING ; then
+ break
+ else
+ echo -n '.'
+ sleep 1
+ fi
+ done
+
+ if [ ${i} -eq ${maxtries} ] ; then echo -n '(link isnt in running state)' ; fi
+ echo
+
+ add_to_bridge ${bridge} ${dev}
+}
+
+case "$command" in
+ start)
+ op_start
+ ;;
+
+ stop)
+ op_stop
+ ;;
+
+ status)
+ show_status ${netdev} ${bridge}
+ ;;
+
+ *)
+ echo "Unknown command: $command" >&2
+ echo 'Valid commands are: start, stop, status' >&2
+ exit 1
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/network-nat b/os-plugins/plugins/xen/files/xen.examples/scripts/network-nat
new file mode 100755
index 00000000..e20c0d03
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/network-nat
@@ -0,0 +1,125 @@
+#!/bin/bash
+#============================================================================
+# Default Xen network start/stop script when using NAT.
+# Xend calls a network script when it starts.
+# The script name to use is defined in /etc/xen/xend-config.sxp
+# in the network-script field.
+#
+# Usage:
+#
+# network-nat (start|stop|status) {VAR=VAL}*
+#
+# Vars:
+#
+# netdev The gateway interface (default eth0).
+# antispoof Whether to use iptables to prevent spoofing (default no).
+# dhcp Whether to alter the local DHCP configuration (default no).
+#
+#============================================================================
+
+dir=$(dirname "$0")
+. "$dir/xen-script-common.sh"
+. "$dir/xen-network-common.sh"
+
+findCommand "$@"
+evalVariables "$@"
+
+netdev=${netdev:-eth0}
+# antispoofing not yet implemented
+antispoof=${antispoof:-no}
+
+# turn on dhcp feature by default if dhcpd is installed
+if [ -f /etc/dhcpd.conf ]
+then
+ dhcp=${dhcp:-yes}
+else
+ dhcp=${dhcp:-no}
+fi
+
+
+if [ "$dhcp" != 'no' ]
+then
+ dhcpd_conf_file=$(find_dhcpd_conf_file)
+ dhcpd_init_file=$(find_dhcpd_init_file)
+ if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ]
+ then
+ echo 'Failed to find dhcpd configuration or init file.' >&2
+ exit 1
+ fi
+fi
+
+domain_name=`cat /etc/resolv.conf | grep -v "#" | grep -E 'search|domain' -i | tail -n 1 | awk '{ print $2 }'`
+nameserver=`cat /etc/resolv.conf | grep -v "#" | grep "nameserver" -i -m 1 | awk '{ print $2 }'`
+
+function dhcp_start()
+{
+ if ! grep -q "subnet 10.0.0.0" "$dhcpd_conf_file"
+ then
+ echo >>"$dhcpd_conf_file" "subnet 10.0.0.0 netmask 255.255.0.0 {\
+ option domain-name \"$domain_name\";\
+ option domain-name-servers $nameserver; }"
+ fi
+
+ "$dhcpd_init_file" restart
+}
+
+
+function dhcp_stop()
+{
+ local tmpfile=$(mktemp)
+ grep -v "subnet 10.0.0.0" "$dhcpd_conf_file" >"$tmpfile"
+ if diff "$tmpfile" "$dhcpd_conf_file" >&/dev/null
+ then
+ rm "$tmpfile"
+ else
+ mv "$tmpfile" "$dhcpd_conf_file"
+ fi
+
+ "$dhcpd_init_file" restart
+}
+
+
+op_start() {
+ echo 1 >/proc/sys/net/ipv4/ip_forward
+ iptables -t nat -A POSTROUTING -o ${netdev} -j MASQUERADE
+ iptables -P FORWARD ACCEPT
+ [ "$dhcp" != 'no' ] && dhcp_start
+}
+
+
+op_stop() {
+ [ "$dhcp" != 'no' ] && dhcp_stop
+ iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
+ iptables -P FORWARD DROP
+}
+
+
+show_status() {
+ echo '============================================================'
+ ifconfig
+ echo ' '
+ ip route list
+ echo ' '
+ route -n
+ echo '============================================================'
+
+}
+
+case "$command" in
+ start)
+ op_start
+ ;;
+
+ stop)
+ op_stop
+ ;;
+
+ status)
+ show_status
+ ;;
+
+ *)
+ echo "Unknown command: $command" >&2
+ echo 'Valid commands are: start, stop, status' >&2
+ exit 1
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/network-route b/os-plugins/plugins/xen/files/xen.examples/scripts/network-route
new file mode 100755
index 00000000..4416316e
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/network-route
@@ -0,0 +1,27 @@
+#!/bin/bash
+#============================================================================
+# Default Xen network start/stop script.
+# Xend calls a network script when it starts.
+# The script name to use is defined in /etc/xen/xend-config.sxp
+# in the network-script field.
+#
+# Usage:
+#
+# network-route (start|stop|status) {VAR=VAL}*
+#
+# Vars:
+#
+# netdev The gateway interface (default eth0).
+# antispoof Whether to use iptables to prevent spoofing (default yes).
+#
+#============================================================================
+
+dir=$(dirname "$0")
+. "$dir/xen-script-common.sh"
+
+evalVariables "$@"
+
+netdev=${netdev:-eth0}
+
+echo 1 >/proc/sys/net/ipv4/ip_forward
+echo 1 >/proc/sys/net/ipv4/conf/${netdev}/proxy_arp
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/set-lock b/os-plugins/plugins/xen/files/xen.examples/scripts/set-lock
new file mode 120000
index 00000000..8bd35731
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/set-lock
@@ -0,0 +1 @@
+vm-monitor \ No newline at end of file
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vif-bridge b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-bridge
new file mode 100755
index 00000000..1b698d70
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-bridge
@@ -0,0 +1,100 @@
+#!/bin/bash
+#============================================================================
+# /etc/xen/vif-bridge
+#
+# Script for configuring a vif in bridged mode.
+# The hotplugging system will call this script if it is specified either in
+# the device configuration given to Xend, or the default Xend configuration
+# in /etc/xen/xend-config.sxp. If the script is specified in neither of those
+# places, then this script is the default.
+#
+# Usage:
+# vif-bridge (add|remove|online|offline)
+#
+# Environment vars:
+# vif vif interface name (required).
+# XENBUS_PATH path to this device's details in the XenStore (required).
+#
+# Read from the store:
+# bridge bridge to add the vif to (optional). Defaults to searching for the
+# bridge itself.
+# ip list of IP networks for the vif, space-separated (optional).
+#
+# up:
+# Enslaves the vif interface to the bridge and adds iptables rules
+# for its ip addresses (if any).
+#
+# down:
+# Removes the vif interface from the bridge and removes the iptables
+# rules for its ip addresses (if any).
+#============================================================================
+
+dir=$(dirname "$0")
+. "$dir/vif-common.sh"
+
+bridge=${bridge:-}
+bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")
+
+if [ -z "$bridge" ]
+then
+ bridge=$(brctl show | cut -d "
+" -f 2 | cut -f 1)
+
+ if [ -z "$bridge" ]
+ then
+ fatal "Could not find bridge, and none was specified"
+ fi
+else
+ #
+ # Old style bridge setup with netloop, used to have a bridge name
+ # of xenbrX, enslaving pethX and vif0.X, and then configuring
+ # eth0.
+ #
+ # New style bridge setup does not use netloop, so the bridge name
+ # is ethX and the physical device is enslaved pethX
+ #
+ # So if...
+ #
+ # - User asks for xenbrX
+ # - AND xenbrX doesn't exist
+ # - AND there is a ethX device which is a bridge
+ #
+ # ..then we translate xenbrX to ethX
+ #
+ # This lets old config files work without modification
+ #
+ if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
+ then
+ if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
+ then
+ bridge="eth${bridge#xenbr}"
+ fi
+ fi
+fi
+
+RET=0
+ip link show $bridge 1>/dev/null 2>&1 || RET=1
+if [ "$RET" -eq 1 ]
+then
+ fatal "Could not find bridge device $bridge"
+fi
+
+case "$command" in
+ online)
+ setup_bridge_port "$vif"
+ add_to_bridge "$bridge" "$vif"
+ ;;
+
+ offline)
+ do_without_error brctl delif "$bridge" "$vif"
+ do_without_error ifconfig "$vif" down
+ ;;
+esac
+
+handle_iptable
+
+log debug "Successful vif-bridge $command for $vif, bridge $bridge."
+if [ "$command" == "online" ]
+then
+ success
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vif-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-common.sh
new file mode 100644
index 00000000..fe483f9d
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-common.sh
@@ -0,0 +1,158 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+. "$dir/xen-network-common.sh"
+
+findCommand "$@"
+
+if [ "$command" != "online" ] &&
+ [ "$command" != "offline" ] &&
+ [ "$command" != "add" ] &&
+ [ "$command" != "remove" ]
+then
+ log err "Invalid command: $command"
+ exit 1
+fi
+
+case "$command" in
+ add | remove)
+ exit 0
+ ;;
+esac
+
+
+# Parameters may be read from the environment, the command line arguments, and
+# the store, with overriding in that order. The environment is given by the
+# driver, the command line is given by the Xend global configuration, and
+# store details are given by the per-domain or per-device configuration.
+
+evalVariables "$@"
+
+ip=${ip:-}
+ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip")
+
+# Check presence of compulsory args.
+XENBUS_PATH="${XENBUS_PATH:?}"
+vif="${vif:?}"
+
+
+vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "")
+if [ "$vifname" ]
+then
+ if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null
+ then
+ do_or_die ip link set "$vif" name "$vifname"
+ fi
+ vif="$vifname"
+fi
+
+
+frob_iptable()
+{
+ if [ "$command" == "online" ]
+ then
+ local c="-I"
+ else
+ local c="-D"
+ fi
+
+ iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT \
+ 2>/dev/null &&
+ iptables "$c" FORWARD -m state --state RELATED,ESTABLISHED -m physdev \
+ --physdev-out "$vif" -j ACCEPT 2>/dev/null
+
+ if [ "$command" == "online" ] && [ $? ]
+ then
+ log err "iptables setup failed. This may affect guest networking."
+ fi
+}
+
+
+##
+# Add or remove the appropriate entries in the iptables. With antispoofing
+# turned on, we have to explicitly allow packets to the interface, regardless
+# of the ip setting. If ip is set, then we additionally restrict the packets
+# to those coming from the specified networks, though we allow DHCP requests
+# as well.
+#
+handle_iptable()
+{
+ # Check for a working iptables installation. Checking for the iptables
+ # binary is not sufficient, because the user may not have the appropriate
+ # modules installed. If iptables is not working, then there's no need to do
+ # anything with it, so we can just return.
+ if ! iptables -L -n >&/dev/null
+ then
+ return
+ fi
+
+ claim_lock "iptables"
+
+ if [ "$ip" != "" ]
+ then
+ local addr
+ for addr in $ip
+ do
+ frob_iptable -s "$addr"
+ done
+
+ # Always allow the domain to talk to a DHCP server.
+ frob_iptable -p udp --sport 68 --dport 67
+ else
+ # No IP addresses have been specified, so allow anything.
+ frob_iptable
+ fi
+
+ release_lock "iptables"
+}
+
+
+##
+# ip_of interface
+#
+# Print the IP address currently in use at the given interface, or nothing if
+# the interface is not up.
+#
+ip_of()
+{
+ ip addr show "$1" | awk "/^.*inet.*$1\$/{print \$2}" | sed -n '1 s,/.*,,p'
+}
+
+
+##
+# dom0_ip
+#
+# Print the IP address of the interface in dom0 through which we are routing.
+# This is the IP address on the interface specified as "netdev" as a parameter
+# to these scripts, or eth0 by default. This function will call fatal if no
+# such interface could be found.
+#
+dom0_ip()
+{
+ local nd=${netdev:-eth0}
+ local result=$(ip_of "$nd")
+ if [ -z "$result" ]
+ then
+ fatal
+"$netdev is not up. Bring it up or specify another interface with " \
+"netdev=<if> as a parameter to $0."
+ fi
+ echo "$result"
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vif-nat b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-nat
new file mode 100755
index 00000000..75bdf5c4
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-nat
@@ -0,0 +1,192 @@
+#!/bin/bash
+#============================================================================
+# /etc/xen/vif-nat
+#
+# Script for configuring a vif in routed-nat mode.
+# The hotplugging system will call this script if it is specified either in
+# the device configuration given to Xend, or the default Xend configuration
+# in /etc/xen/xend-config.sxp. If the script is specified in neither of those
+# places, then vif-bridge is the default.
+#
+# Usage:
+# vif-nat (add|remove|online|offline)
+#
+# Environment vars:
+# vif vif interface name (required).
+# XENBUS_PATH path to this device's details in the XenStore (required).
+#
+# Parameters:
+# dhcp Whether to alter the local DHCP configuration to include this
+# new host (default no).
+#
+# Read from the store:
+# ip list of IP networks for the vif, space-separated (default given in
+# this script).
+#============================================================================
+
+
+dir=$(dirname "$0")
+. "$dir/vif-common.sh"
+
+# turn on dhcp feature by default if dhcpd is installed
+if [ -f /etc/dhcpd.conf ]
+then
+ dhcp=${dhcp:-yes}
+else
+ dhcp=${dhcp:-no}
+fi
+
+if [ "$dhcp" != 'no' ]
+then
+ dhcpd_conf_file=$(find_dhcpd_conf_file)
+ dhcpd_init_file=$(find_dhcpd_init_file)
+ dhcpd_arg_file=$(find_dhcpd_arg_file)
+ if [ -z "$dhcpd_conf_file" ] || [ -z "$dhcpd_init_file" ] || [ -z "$dhcpd_arg_file" ]
+ then
+ echo 'Failed to find dhcpd configuration or init or args file.' >&2
+ exit 1
+ fi
+fi
+
+
+domid=$(xenstore_read "$XENBUS_PATH/frontend-id")
+vifid=$(xenstore_read "$XENBUS_PATH/handle")
+vifid=$(( $vifid + 1 ))
+
+
+ip_from_dom()
+{
+ local domid1=$(( $domid / 256 ))
+ local domid2=$(( $domid % 256 ))
+
+ echo "10.$domid1.$domid2.$vifid/16"
+}
+
+
+routing_ip()
+{
+ echo $(echo $1 | awk -F. '{print $1"."$2"."$3"."$4 + 127}')
+}
+
+
+dotted_quad()
+{
+ echo\
+ $(( ($1 & 0xFF000000) >> 24))\
+.$(( ($1 & 0x00FF0000) >> 16))\
+.$(( ($1 & 0x0000FF00) >> 8 ))\
+.$(( $1 & 0x000000FF ))
+}
+
+
+if [ "$ip" = "" ]
+then
+ ip=$(ip_from_dom)
+fi
+
+router_ip=$(routing_ip "$ip")
+
+# Split the given IP/bits pair.
+vif_ip=`echo ${ip} | awk -F/ '{print $1}'`
+
+hostname=$(xenstore_read "$XENBUS_PATH/domain" | tr -- '_.:/+' '-----')
+if [ "$vifid" != "1" ]
+then
+ hostname="$hostname-$vifid"
+fi
+
+dhcparg_remove_entry()
+{
+ local tmpfile=$(mktemp)
+ sed -e "s/$vif //" "$dhcpd_arg_file" >"$tmpfile"
+ if diff "$tmpfile" "$dhcpd_arg_file" >/dev/null
+ then
+ rm "$tmpfile"
+ else
+ mv "$tmpfile" "$dhcpd_arg_file"
+ fi
+}
+
+dhcparg_add_entry()
+{
+ dhcparg_remove_entry
+ local tmpfile=$(mktemp)
+ # handle Red Hat, SUSE, and Debian styles, with or without quotes
+ sed -e 's/^DHCPDARGS="*\([^"]*\)"*/DHCPDARGS="\1'"$vif "'"/' \
+ "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
+ sed -e 's/^DHCPD_INTERFACE="*\([^"]*\)"*/DHCPD_INTERFACE="\1'"$vif "'"/' \
+ "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
+ sed -e 's/^INTERFACES="*\([^"]*\)"*/INTERFACES="\1'"$vif "'"/' \
+ "$dhcpd_arg_file" >"$tmpfile" && mv "$tmpfile" "$dhcpd_arg_file"
+ rm -f "$tmpfile"
+}
+
+dhcp_remove_entry()
+{
+ local tmpfile=$(mktemp)
+ grep -v "host $hostname" "$dhcpd_conf_file" >"$tmpfile"
+ if diff "$tmpfile" "$dhcpd_conf_file" >/dev/null
+ then
+ rm "$tmpfile"
+ else
+ mv "$tmpfile" "$dhcpd_conf_file"
+ fi
+ dhcparg_remove_entry
+}
+
+
+dhcp_up()
+{
+ claim_lock "vif-nat-dhcp"
+ dhcp_remove_entry
+ mac=$(xenstore_read "$XENBUS_PATH/mac")
+ echo >>"$dhcpd_conf_file" \
+"host $hostname { hardware ethernet $mac; fixed-address $vif_ip; option routers $router_ip; option host-name \"$hostname\"; }"
+ dhcparg_add_entry
+ release_lock "vif-nat-dhcp"
+ "$dhcpd_init_file" restart || true
+}
+
+
+dhcp_down()
+{
+ claim_lock "vif-nat-dhcp"
+ dhcp_remove_entry
+ release_lock "vif-nat-dhcp"
+ "$dhcpd_init_file" restart || true # We need to ignore failure because
+ # ISC dhcpd 3 borks if there is nothing
+ # for it to do, which is the case if
+ # the outgoing interface is not
+ # configured to offer leases and there
+ # are no vifs.
+}
+
+
+case "$command" in
+ online)
+ if ip route | grep -q "dev $vif"
+ then
+ log debug "$vif already up"
+ exit 0
+ fi
+
+ do_or_die ip link set "$vif" up arp on
+ do_or_die ip addr add "$router_ip" dev "$vif"
+ do_or_die ip route add "$vif_ip" dev "$vif" src "$router_ip"
+ echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
+ [ "$dhcp" != 'no' ] && dhcp_up
+ ;;
+ offline)
+ [ "$dhcp" != 'no' ] && dhcp_down
+ do_without_error ifconfig "$vif" down
+ ;;
+esac
+
+
+handle_iptable
+
+log debug "Successful vif-nat $command for $vif."
+if [ "$command" = "online" ]
+then
+ success
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vif-route b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-route
new file mode 100755
index 00000000..f5fd88ed
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vif-route
@@ -0,0 +1,56 @@
+#!/bin/bash
+#============================================================================
+# /etc/xen/vif-route
+#
+# Script for configuring a vif in routed mode.
+# The hotplugging system will call this script if it is specified either in
+# the device configuration given to Xend, or the default Xend configuration
+# in /etc/xen/xend-config.sxp. If the script is specified in neither of those
+# places, then vif-bridge is the default.
+#
+# Usage:
+# vif-route (add|remove|online|offline)
+#
+# Environment vars:
+# vif vif interface name (required).
+# XENBUS_PATH path to this device's details in the XenStore (required).
+#
+# Read from the store:
+# ip list of IP networks for the vif, space-separated (default given in
+# this script).
+#============================================================================
+
+dir=$(dirname "$0")
+. "$dir/vif-common.sh"
+
+main_ip=$(dom0_ip)
+
+case "$command" in
+ online)
+ ifconfig ${vif} ${main_ip} netmask 255.255.255.255 up
+ echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp
+ ipcmd='add'
+ cmdprefix=''
+ ;;
+ offline)
+ do_without_error ifdown ${vif}
+ ipcmd='del'
+ cmdprefix='do_without_error'
+ ;;
+esac
+
+if [ "${ip}" ] ; then
+ # If we've been given a list of IP addresses, then add routes from dom0 to
+ # the guest using those addresses.
+ for addr in ${ip} ; do
+ ${cmdprefix} ip route ${ipcmd} ${addr} dev ${vif} src ${main_ip}
+ done
+fi
+
+handle_iptable
+
+log debug "Successful vif-route $command for $vif."
+if [ "$command" = "online" ]
+then
+ success
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vm-monitor b/os-plugins/plugins/xen/files/xen.examples/scripts/vm-monitor
new file mode 100755
index 00000000..1c9a1791
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vm-monitor
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+basedir=$(dirname "$0")
+HA_TICK=2
+
+monitor() {
+ local path=$1
+ local name=$2
+ local uuid=$3
+ local host=$4
+ local count=0
+ path=$path/lock
+
+ while :
+ do
+ echo "name=$name uuid=$uuid host=$host count=$count" > $path
+ count=$(($count+1))
+ sleep $HA_TICK
+ done&
+}
+
+create_lock() {
+ local path=$1/lock
+ local rc=0
+
+ [ -f $path ] || touch $path
+ flock -x -w $HA_TICK $path $basedir/vm-monitor $*
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ echo `cat $path`
+ exit 1
+ else
+ exit $rc
+ fi
+}
+
+if [ $0 = "$basedir/set-lock" ]; then
+ create_lock $*
+elif [ $0 = "$basedir/vm-monitor" ]; then
+ monitor $*
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vscsi b/os-plugins/plugins/xen/files/xen.examples/scripts/vscsi
new file mode 100755
index 00000000..5ac26147
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vscsi
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Copyright (c) 2007, FUJITSU Limited
+# Based on the block scripts code.
+#
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+findCommand "$@"
+
+case "$command" in
+ add)
+ success
+ ;;
+ remove)
+ # TODO
+ exit 0
+ ;;
+esac
+
+exit 0
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm
new file mode 100755
index 00000000..38a4532f
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+dir=$(dirname "$0")
+. "$dir/vtpm-hotplug-common.sh"
+
+vtpm_fatal_error=0
+
+case "$command" in
+ add)
+ vtpm_create_instance
+ ;;
+ remove)
+ vtpm_remove_instance
+ ;;
+esac
+
+if [ $vtpm_fatal_error -eq 0 ]; then
+ log debug "Successful vTPM operation '$command'."
+ success
+else
+ fatal "Error while executing vTPM operation '$command'."
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-common.sh
new file mode 100644
index 00000000..a45868ee
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-common.sh
@@ -0,0 +1,448 @@
+#
+# Copyright (c) 2005 IBM Corporation
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+dir=$(dirname "$0")
+. "$dir/logging.sh"
+. "$dir/locking.sh"
+
+VTPMDB="/var/vtpm/vtpm.db"
+
+#In the vtpm-impl file some commands should be defined:
+# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
+if [ -r "$dir/vtpm-impl.alt" ]; then
+ . "$dir/vtpm-impl.alt"
+elif [ -r "$dir/vtpm-impl" ]; then
+ . "$dir/vtpm-impl"
+else
+ function vtpm_create () {
+ true
+ }
+ function vtpm_setup() {
+ true
+ }
+ function vtpm_start() {
+ true
+ }
+ function vtpm_suspend() {
+ true
+ }
+ function vtpm_resume() {
+ true
+ }
+ function vtpm_delete() {
+ true
+ }
+ function vtpm_migrate() {
+ echo "Error: vTPM migration accross machines not implemented."
+ }
+ function vtpm_migrate_local() {
+ echo "Error: local vTPM migration not supported"
+ }
+ function vtpm_migrate_recover() {
+ true
+ }
+fi
+
+
+#Find the instance number for the vtpm given the name of the domain
+# Parameters
+# - vmname : the name of the vm
+# Return value
+# Returns '0' if instance number could not be found, otherwise
+# it returns the instance number in the variable 'instance'
+function vtpmdb_find_instance () {
+ local vmname ret instance
+ vmname=$1
+ ret=0
+
+ instance=$(cat $VTPMDB | \
+ awk -vvmname=$vmname \
+ '{ \
+ if ( 1 != index($1,"#")) { \
+ if ( $1 == vmname ) { \
+ print $2; \
+ exit; \
+ } \
+ } \
+ }')
+ if [ "$instance" != "" ]; then
+ ret=$instance
+ fi
+ echo "$ret"
+}
+
+
+# Check whether a particular instance number is still available
+# returns "0" if it is not available, "1" otherwise.
+function vtpmdb_is_free_instancenum () {
+ local instance instances avail i
+ instance=$1
+ avail=1
+ #Allowed instance number range: 1-255
+ if [ $instance -eq 0 -o $instance -gt 255 ]; then
+ avail=0
+ else
+ instances=$(cat $VTPMDB | \
+ gawk \
+ '{ \
+ if (1 != index($1,"#")) { \
+ printf("%s ",$2); \
+ } \
+ }')
+ for i in $instances; do
+ if [ $i -eq $instance ]; then
+ avail=0
+ break
+ fi
+ done
+ fi
+ echo "$avail"
+}
+
+
+# Get an available instance number given the database
+# Returns an unused instance number
+function vtpmdb_get_free_instancenum () {
+ local ctr instances don found
+ instances=$(cat $VTPMDB | \
+ gawk \
+ '{ \
+ if (1 != index($1,"#")) { \
+ printf("%s ",$2); \
+ } \
+ }')
+ ctr=1
+ don=0
+ while [ $don -eq 0 ]; do
+ found=0
+ for i in $instances; do
+ if [ $i -eq $ctr ]; then
+ found=1;
+ break;
+ fi
+ done
+
+ if [ $found -eq 0 ]; then
+ don=1
+ break
+ fi
+ let ctr=ctr+1
+ done
+ echo "$ctr"
+}
+
+
+# Add a domain name and instance number to the DB file
+function vtpmdb_add_instance () {
+ local res vmname inst
+ vmname=$1
+ inst=$2
+
+ if [ ! -f $VTPMDB ]; then
+ echo "#Database for VM to vTPM association" > $VTPMDB
+ echo "#1st column: domain name" >> $VTPMDB
+ echo "#2nd column: TPM instance number" >> $VTPMDB
+ fi
+ res=$(vtpmdb_validate_entry $vmname $inst)
+ if [ $res -eq 0 ]; then
+ echo "$vmname $inst" >> $VTPMDB
+ fi
+}
+
+
+#Validate whether an entry is the same as passed to this
+#function
+function vtpmdb_validate_entry () {
+ local res rc vmname inst
+ rc=0
+ vmname=$1
+ inst=$2
+
+ res=$(cat $VTPMDB | \
+ gawk -vvmname=$vmname \
+ -vinst=$inst \
+ '{ \
+ if ( 1 == index($1,"#")) {\
+ } else \
+ if ( $1 == vmname && \
+ $2 == inst) { \
+ printf("1"); \
+ exit; \
+ } else \
+ if ( $1 == vmname || \
+ $2 == inst) { \
+ printf("2"); \
+ exit; \
+ } \
+ }')
+
+ if [ "$res" == "1" ]; then
+ rc=1
+ elif [ "$res" == "2" ]; then
+ rc=2
+ fi
+ echo "$rc"
+}
+
+
+#Remove an entry from the vTPM database given its domain name
+#and instance number
+function vtpmdb_remove_entry () {
+ local vmname instance VTPMDB_TMP
+ vmname=$1
+ instance=$2
+ VTPMDB_TMP="$VTPMDB".tmp
+
+ $(cat $VTPMDB | \
+ gawk -vvmname=$vmname \
+ '{ \
+ if ( $1 != vmname ) { \
+ print $0; \
+ } \
+ '} > $VTPMDB_TMP)
+ if [ -e $VTPMDB_TMP ]; then
+ mv -f $VTPMDB_TMP $VTPMDB
+ vtpm_delete $instance
+ else
+ log err "Error creating temporary file '$VTPMDB_TMP'."
+ fi
+}
+
+
+# Find the reason for the creation of this device:
+# Returns 'resume' or 'create'
+function vtpm_get_create_reason () {
+ local resume
+ resume=$(xenstore_read $XENBUS_PATH/resume)
+ if [ "$resume" == "True" ]; then
+ echo "resume"
+ else
+ echo "create"
+ fi
+}
+
+
+#Create a vTPM instance
+# If no entry in the TPM database is found, the instance is
+# created and an entry added to the database.
+function vtpm_create_instance () {
+ local res instance domname reason uuid
+ uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
+ reason=$(vtpm_get_create_reason)
+
+ claim_lock vtpmdb
+
+ instance="0"
+
+ if [ "$uuid" != "" ]; then
+ instance=$(vtpmdb_find_instance $uuid)
+ fi
+ if [ "$instance" == "0" ]; then
+ domname=$(xenstore_read "$XENBUS_PATH"/domain)
+ instance=$(vtpmdb_find_instance $domname)
+ fi
+
+ if [ "$instance" == "0" -a "$reason" != "create" ]; then
+ release_lock vtpmdb
+ return
+ fi
+
+ if [ "$instance" == "0" ]; then
+ #Try to give the preferred instance to the domain
+ instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
+ if [ "$instance" != "" ]; then
+ res=$(vtpmdb_is_free_instancenum $instance)
+ if [ $res -eq 0 ]; then
+ instance=$(vtpmdb_get_free_instancenum)
+ fi
+ else
+ instance=$(vtpmdb_get_free_instancenum)
+ fi
+
+ vtpm_create $instance
+
+ if [ $vtpm_fatal_error -eq 0 ]; then
+ if [ "$uuid" != "" ]; then
+ vtpmdb_add_instance $uuid $instance
+ else
+ vtpmdb_add_instance $domname $instance
+ fi
+ fi
+ else
+ if [ "$reason" == "resume" ]; then
+ vtpm_resume $instance
+ else
+ vtpm_start $instance
+ fi
+ fi
+
+ release_lock vtpmdb
+
+ xenstore_write $XENBUS_PATH/instance $instance
+}
+
+
+#Remove an instance when a VM is terminating or suspending.
+#Since it is assumed that the VM will appear again, the
+#entry is kept in the VTPMDB file.
+function vtpm_remove_instance () {
+ local instance reason domname uuid
+ #Stop script execution quietly if path does not exist (anymore)
+ xenstore-exists "$XENBUS_PATH"/domain
+ uuid=$(xenstore_read "$XENBUS_PATH"/uuid)
+
+ claim_lock vtpmdb
+
+ instance="0"
+
+ if [ "$uuid" != "" ]; then
+ instance=$(vtpmdb_find_instance $uuid)
+ fi
+
+ if [ "$instance" == "0" ]; then
+ domname=$(xenstore_read "$XENBUS_PATH"/domain)
+ instance=$(vtpmdb_find_instance $domname)
+ fi
+
+ if [ "$instance" != "0" ]; then
+ vtpm_suspend $instance
+ fi
+
+ release_lock vtpmdb
+}
+
+
+#Remove an entry in the VTPMDB file given the domain's name
+#1st parameter: The name of the domain
+function vtpm_delete_instance () {
+ local instance
+
+ claim_lock vtpmdb
+
+ instance=$(vtpmdb_find_instance $1)
+ if [ "$instance" != "0" ]; then
+ vtpmdb_remove_entry $1 $instance
+ fi
+
+ release_lock vtpmdb
+}
+
+# Determine whether the given address is local to this machine
+# Return values:
+# "-1" : the given machine name is invalid
+# "0" : this is not an address of this machine
+# "1" : this is an address local to this machine
+function vtpm_isLocalAddress() {
+ local addr res
+ addr=$(ping $1 -c 1 | \
+ gawk '{ print substr($3,2,length($3)-2); exit }')
+ if [ "$addr" == "" ]; then
+ echo "-1"
+ return
+ fi
+ res=$(ifconfig | grep "inet addr" | \
+ gawk -vaddr=$addr \
+ '{ \
+ if ( addr == substr($2, 6)) {\
+ print "1"; \
+ } \
+ }' \
+ )
+ if [ "$res" == "" ]; then
+ echo "0"
+ return
+ fi
+ echo "1"
+}
+
+# Perform a migration step. This function differentiates between migration
+# to the local host or to a remote machine.
+# Parameters:
+# 1st: destination host to migrate to
+# 2nd: name of the domain to migrate
+# 3rd: the migration step to perform
+function vtpm_migration_step() {
+ local res=$(vtpm_isLocalAddress $1)
+ if [ "$res" == "0" ]; then
+ vtpm_migrate $1 $2 $3
+ else
+ vtpm_migrate_local
+ fi
+}
+
+# Recover from migration due to an error. This function differentiates
+# between migration to the local host or to a remote machine.
+# Parameters:
+# 1st: destination host the migration was going to
+# 2nd: name of the domain that was to be migrated
+# 3rd: the last successful migration step that was done
+function vtpm_recover() {
+ local res
+ res=$(vtpm_isLocalAddress $1)
+ if [ "$res" == "0" ]; then
+ vtpm_migrate_recover $1 $2 $3
+ fi
+}
+
+
+#Determine the domain id given a domain's name.
+#1st parameter: name of the domain
+#return value: domain id or -1 if domain id could not be determined
+function vtpm_domid_from_name () {
+ local id name ids
+ ids=$(xenstore-list /local/domain)
+ for id in $ids; do
+ name=$(xenstore-read /local/domain/$id/name)
+ if [ "$name" == "$1" ]; then
+ echo "$id"
+ return
+ fi
+ done
+ echo "-1"
+}
+
+#Determine the virtual TPM's instance number using the domain ID.
+#1st parm: domain ID
+function vtpm_uuid_by_domid() {
+ echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
+}
+
+
+# Determine the vTPM's UUID by the name of the VM
+function vtpm_uuid_from_vmname() {
+ local domid=$(vtpm_domid_from_name $1)
+ if [ "$domid" != "-1" ]; then
+ echo $(vtpm_uuid_by_domid $domid)
+ return
+ fi
+ echo ""
+}
+
+#Add a virtual TPM instance number and its associated domain name
+#to the VTPMDB file and activate usage of this virtual TPM instance
+#by writing the instance number into the xenstore
+#1st parm: name of virtual machine
+#2nd parm: instance of associated virtual TPM
+function vtpm_add_and_activate() {
+ local domid=$(vtpm_domid_from_name $1)
+ local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
+ if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
+ vtpmdb_add_instance $vtpm_uuid $2
+ xenstore-write backend/vtpm/$domid/0/instance $2
+ fi
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-delete b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-delete
new file mode 100755
index 00000000..b75b95bf
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-delete
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# This scripts must be called the following way:
+# vtpm-delete <vtpm uuid>
+# or
+# vtpm-delete --vmname <vm name>
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
+
+if [ "$1" == "--vmname" ]; then
+ vtpm_uuid=$(vtpm_uuid_from_vmname $2)
+ if [ "$vtpm_uuid" != "" ];then
+ vtpm_delete_instance $vtpm_uuid
+ fi
+else
+ vtpm_delete_instance $1
+fi
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-hotplug-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-hotplug-common.sh
new file mode 100644
index 00000000..9fd35e74
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-hotplug-common.sh
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2005 IBM Corporation
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+findCommand "$@"
+if [ "$command" != "online" ] &&
+ [ "$command" != "offline" ] &&
+ [ "$command" != "add" ] &&
+ [ "$command" != "remove" ]
+then
+ log err "Invalid command: $command"
+ exit 1
+fi
+
+
+XENBUS_PATH="${XENBUS_PATH:?}"
+
+. "$dir/vtpm-common.sh"
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-impl b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-impl
new file mode 100644
index 00000000..4f9a1fd8
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-impl
@@ -0,0 +1,208 @@
+#!/bin/bash
+# ===================================================================
+#
+# Copyright (c) 2005, Intel Corp.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+# | SRC | TAG | CMD SIZE | ORD |mtype|strt
+TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\x01\\x00\\x00\\x01\\x01\\x01
+TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x11\\x01\\x00\\x00\\x01\\x01\\x02
+TPM_CMD_CLOS=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x02
+TPM_CMD_DELE=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x0e\\x01\\x00\\x00\\x03
+
+TPM_TYPE_PVM=\\x01
+TPM_TYPE_HVM=\\x02
+
+TPM_SUCCESS=00000000
+
+TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
+RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo
+
+VTPM_MIG=/usr/bin/vtpm_migrator
+
+# -------------------- Helpers for binary streams -----------
+
+function str_to_hex32() {
+ printf "%0.8x" $1
+}
+
+function hex32_to_bin() {
+ local inst=$(str_to_hex32 $1);
+
+ local n1=`echo $inst | sed 's/\(..\)....../\\\\x\1/'`
+ local n2=`echo $inst | sed 's/..\(..\)..../\\\\x\1/'`
+ local n3=`echo $inst | sed 's/....\(..\)../\\\\x\1/'`
+ local n4=`echo $inst | sed 's/......\(..\)/\\\\x\1/'`
+
+ echo "$n1$n2$n3$n4"
+}
+
+function vtpm_manager_cmd() {
+ local cmd=$1;
+ local inst=$2;
+ local inst_bin=$(hex32_to_bin $inst);
+
+ claim_lock vtpm_mgr
+
+ #send cmd to vtpm_manager
+ printf "$cmd$inst_bin" > $TX_VTPM_MANAGER
+
+ #recv response
+ set +e
+ local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null | xxd -ps`
+ set -e
+
+ release_lock vtpm_mgr
+
+ #return whether the command was successful
+ if [ $resp_hex -ne $TPM_SUCCESS ]; then
+ vtpm_fatal_error=1
+ false
+ else
+ true
+ fi
+}
+
+# Helper to get vm type to pass to vtpm_manager open/resume
+function vtpm_get_type() {
+ local inst=$(xenstore_read $XENBUS_PATH/frontend-id)
+ local vm=$(xenstore_read /local/domain/$inst/vm)
+ if [ "$vm" != "" ]; then
+ local ostype=$(xenstore-read $vm/image/ostype)
+ if [ "$ostype" == "hvm" ]; then
+ echo $TPM_TYPE_HVM;
+ else
+ echo $TPM_TYPE_PVM;
+ fi
+ fi
+}
+
+# ------------------ Command handlers -----------------
+
+# Create new vtpm instance & set it up for use
+function vtpm_create () {
+ # Creation is handled implicitly by the manager on first setup
+ # so just set it up for use
+ $(vtpm_start $1)
+}
+
+# Setup vtpm instance for use.
+function vtpm_start() {
+ local vmtype=$(vtpm_get_type);
+ $(vtpm_manager_cmd $TPM_CMD_OPEN$vmtype $1)
+}
+
+function vtpm_resume() {
+ local vmtype=$(vtpm_get_type);
+ $(vtpm_manager_cmd $TPM_CMD_RESM$vmtype $1)
+}
+
+# Reset the vtpm AKA clear PCRs
+function vtpm_reset() {
+ #not used by current implemenation
+ true
+}
+
+# Shutdown the vtpm while the vm is down
+# This could be a suspend of shutdown
+# we cannot distinquish, so save the state
+# and decide on startup if we should keep is
+function vtpm_suspend() {
+ $(vtpm_manager_cmd $TPM_CMD_CLOS $1)
+}
+
+
+function vtpm_delete() {
+ local inst=$1
+ if $(vtpm_manager_cmd $TPM_CMD_DELE $inst); then
+ rm -f /var/vtpm/vtpm_dm_$1.data
+ true
+ else
+ vtpm_fatal_error=1
+ false
+ fi
+}
+
+# Perform a migration step. This function differentiates between migration
+# to the local host or to a remote machine.
+# Parameters:
+# 1st: destination host to migrate to
+# 2nd: name of the domain to migrate
+# 3rd: the migration step to perform
+function vtpm_migrate() {
+ local instance res
+
+ instance=$(vtpmdb_find_instance $2)
+ if [ "$instance" == "" ]; then
+ log err "VTPM Migratoin failed. Unable to translation of domain name"
+ echo "Error: VTPM Migration failed while looking up instance number"
+ fi
+
+ case "$3" in
+ 0)
+ #Incicate migration supported
+ echo "0"
+ ;;
+
+ 1)
+ # Get Public Key from Destination
+ # Call vtpm_manager's migration part 1
+ claim_lock vtpm_mgr
+ $VTPM_MIG $1 $2 $instance $3
+ release_lock vtpm_mgr
+ ;;
+
+ 2)
+ # Call manager's migration step 2 and send result to destination
+ # If successful remove from db
+ claim_lock vtpm_mgr
+ $VTPM_MIG $1 $2 $instance $3
+ release_lock vtpm_mgr
+ ;;
+
+ 3)
+ if `ps x | grep "$VTPM_MIG $1"`; then
+ log err "VTPM Migration failed to complete."
+ echo "Error: VTPM Migration failed to complete."
+ fi
+ ;;
+ esac
+
+}
+
+
+function vtpm_migrate_recover() {
+ echo "Error: Recovery not supported yet"
+}
+
+function vtpm_migrate_local() {
+ echo "Error: local vTPM migration not supported"
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-migration.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-migration.sh
new file mode 100644
index 00000000..7e38ae26
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/vtpm-migration.sh
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2005 IBM Corporation
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+dir=$(dirname "$0")
+. "$dir/vtpm-common.sh"
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-cleanup b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-cleanup
new file mode 100755
index 00000000..706359d0
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-cleanup
@@ -0,0 +1,36 @@
+#! /bin/bash
+
+dir=$(dirname "$0")
+. "$dir/xen-hotplug-common.sh"
+
+# Claim the lock protecting /etc/xen/scripts/block. This stops a race whereby
+# paths in the store would disappear underneath that script as it attempted to
+# read from the store checking for device sharing.
+# Any other scripts that do similar things will have to have their lock
+# claimed too.
+# This is pretty horrible, but there's not really a nicer way of solving this.
+claim_lock "block"
+
+# split backend/DEVCLASS/VMID/DEVID on slashes
+path_array=( ${XENBUS_PATH//\// } )
+# get /vm/UUID path
+vm=$(xenstore_read_default "/local/domain/${path_array[2]}/vm" "")
+# construct /vm/UUID/device/DEVCLASS/DEVID
+if [ "$vm" != "" ]; then
+ vm_dev="$vm/device/${path_array[1]}/${path_array[3]}"
+else
+ vm_dev=
+fi
+
+# remove device frontend store entries
+xenstore-rm -t \
+ $(xenstore-read "$XENBUS_PATH/frontend" 2>/dev/null) 2>/dev/null || true
+
+# remove device backend store entries
+xenstore-rm -t "$XENBUS_PATH" 2>/dev/null || true
+xenstore-rm -t "error/$XENBUS_PATH" 2>/dev/null || true
+
+# remove device path from /vm/UUID
+[ "$vm_dev" != "" ] && xenstore-rm -t "$vm_dev" 2>/dev/null || true
+
+release_lock "block"
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-common.sh
new file mode 100644
index 00000000..980a6270
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-hotplug-common.sh
@@ -0,0 +1,93 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+
+dir=$(dirname "$0")
+. "$dir/logging.sh"
+. "$dir/xen-script-common.sh"
+. "$dir/locking.sh"
+
+exec 2>>/var/log/xen/xen-hotplug.log
+
+export PATH="/sbin:/bin:/usr/bin:/usr/sbin:$PATH"
+export LANG="POSIX"
+unset $(set | grep ^LC_ | cut -d= -f1)
+
+fatal() {
+ xenstore_write "$XENBUS_PATH/hotplug-error" "$*" \
+ "$XENBUS_PATH/hotplug-status" error
+ log err "$@"
+ exit 1
+}
+
+success() {
+ # Tell DevController that backend is "connected"
+ xenstore_write "$XENBUS_PATH/hotplug-status" connected
+}
+
+do_or_die() {
+ "$@" || fatal "$@ failed"
+}
+
+do_without_error() {
+ "$@" 2>/dev/null || log debug "$@ failed"
+}
+
+sigerr() {
+ fatal "$0 failed; error detected."
+}
+
+trap sigerr ERR
+
+
+##
+# xenstore_read <path>+
+#
+# Read each of the given paths, returning each result on a separate line, or
+# exit this script if any of the paths is missing.
+#
+xenstore_read() {
+ local v=$(xenstore-read "$@" || true)
+ [ "$v" != "" ] || fatal "xenstore-read $@ failed."
+ echo "$v"
+}
+
+
+##
+# xenstore_read_default <path> <default>
+#
+# Read the given path, returning the value there or the given default if the
+# path is not present.
+#
+xenstore_read_default() {
+ xenstore-read "$1" 2>/dev/null || echo "$2"
+}
+
+
+##
+# xenstore_write (<path> <value>)+
+#
+# Write each of the key/value pairs to the store, and exit this script if any
+# such writing fails.
+#
+xenstore_write() {
+ log debug "Writing $@ to xenstore."
+ xenstore-write "$@" || fatal "Writing $@ to xenstore failed."
+}
+
+
+log debug "$@" "XENBUS_PATH=$XENBUS_PATH"
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xen-network-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-network-common.sh
new file mode 100644
index 00000000..7014333d
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-network-common.sh
@@ -0,0 +1,118 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+
+# Gentoo doesn't have ifup/ifdown, so we define appropriate alternatives.
+
+# Other platforms just use ifup / ifdown directly.
+
+##
+# preiftransfer
+#
+# @param $1 The current name for the physical device, which is also the name
+# that the virtual device will take once the physical device has
+# been renamed.
+
+if ! which ifup >/dev/null 2>/dev/null
+then
+ preiftransfer()
+ {
+ true
+ }
+ ifup()
+ {
+ false
+ }
+ ifdown()
+ {
+ false
+ }
+else
+ preiftransfer()
+ {
+ true
+ }
+fi
+
+
+first_file()
+{
+ t="$1"
+ shift
+ for file in $@
+ do
+ if [ "$t" "$file" ]
+ then
+ echo "$file"
+ return
+ fi
+ done
+}
+
+find_dhcpd_conf_file()
+{
+ first_file -f /etc/dhcp3/dhcpd.conf /etc/dhcpd.conf
+}
+
+
+find_dhcpd_init_file()
+{
+ first_file -x /etc/init.d/{dhcp3-server,dhcp,dhcpd}
+}
+
+find_dhcpd_arg_file()
+{
+ first_file -f /etc/sysconfig/dhcpd /etc/defaults/dhcp /etc/default/dhcp3-server
+}
+
+# configure interfaces which act as pure bridge ports:
+setup_bridge_port() {
+ local dev="$1"
+
+ # take interface down ...
+ ip link set ${dev} down
+
+ # ... and configure it
+ ip addr flush ${dev}
+}
+
+# Usage: create_bridge bridge
+create_bridge () {
+ local bridge=$1
+
+ # Don't create the bridge if it already exists.
+ if [ ! -e "/sys/class/net/${bridge}/bridge" ]; then
+ brctl addbr ${bridge}
+ brctl stp ${bridge} off
+ brctl setfd ${bridge} 0
+ fi
+}
+
+# Usage: add_to_bridge bridge dev
+add_to_bridge () {
+ local bridge=$1
+ local dev=$2
+
+ # Don't add $dev to $bridge if it's already on a bridge.
+ if [ -e "/sys/class/net/${bridge}/brif/${dev}" ]; then
+ ip link set ${dev} up || true
+ return
+ fi
+ brctl addif ${bridge} ${dev}
+ ip link set ${dev} up
+}
+
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xen-script-common.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-script-common.sh
new file mode 100644
index 00000000..f6841acf
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xen-script-common.sh
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005 XenSource Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+
+set -e
+
+
+evalVariables()
+{
+ for arg in "$@"
+ do
+ if expr 'index' "$arg" '=' '>' '1' >/dev/null
+ then
+ eval "$arg"
+ fi
+ done
+}
+
+
+findCommand()
+{
+ for arg in "$@"
+ do
+ if ! expr 'index' "$arg" '=' >/dev/null
+ then
+ command="$arg"
+ return
+ fi
+ done
+}
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xend-relocation.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/xend-relocation.sh
new file mode 100755
index 00000000..1f1cd061
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xend-relocation.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+#============================================================================
+# xend-relocation
+#
+# Version = 1.0.3
+# Date = 2007-09-14
+#
+# Maintainer(s) = Ron Terry - ron (at) pronetworkconsulting (dot) com
+#
+# The latest version can be found at:
+#
+# http://pronetworkconsulting.com/linux/scripts/xend-relocation.html
+#
+# Description:
+#
+# This script is used to enable or disable the VM relocation (migration)
+# feature of xend. It can be used to manage the local instance of xend
+# or both the local instance and instances of xend on the other machines
+# to/from which VMs can be relocated.
+# To manage the instances of xend on other machines this script communicates
+# using ssh so it is recomended that if you use this feature you
+# pre-distribute ssh keys between the servers.
+#
+# Depends on:
+#
+# Can use: /etc/sysconfig/xend
+#
+# Usage: xend-relocation (start|stop|status)
+# or
+# xend-relocation (on|off|status)
+#
+# Vars:
+#
+# XEN_CONFIG_FILE
+#
+# RELOCATION_NODELIST
+#
+# MANAGE_ALL_RELOCATION_NODES
+#
+# XEN_RELOCATION_PORT
+#
+#============================================================================
+
+#### Read config files and set variables ##################################
+
+# If you source the /etc/sysconfig/xend file comment out the variables
+# being set in this script.
+
+. /etc/sysconfig/xend
+
+XEN_CONFIG_FILE="/etc/xen/xend-config.sxp"
+
+#### Script Functions #####################################################
+
+usage(){
+ echo ""
+ echo "Usage: xend-relocation {start|stop|status}"
+ echo " or"
+ echo " xend-relocation {on|off|status}"
+ echo ""
+}
+
+relocate_on() {
+ for NODE in $RELOCATION_NODELIST
+ do
+ case $NODE in
+ any)
+ SSHCMD=""
+ RELOCATION_NODELIST=""
+ ;;
+ *)
+ if [ "$MANAGE_ALL_RELOCATION_NODES" = "true" ]
+ then
+ SSHCMD="ssh root@$NODE "
+ else
+ SSHCMD=""
+ fi
+ ;;
+ esac
+
+ $SSHCMD sed -i "s/^#(xend-relocation-server yes)/(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^#(xend-relocation-server no)/(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^#(xend-relocation-port [^)]*)/(xend-relocation-port $XEN_RELOCATION_PORT)/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^(xend-relocation-hosts-allow \(.*\)/###(xend-relocation-hosts-allow \1/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^#(xend-relocation-hosts-allow .*/(xend-relocation-hosts-allow \'$RELOCATION_NODELIST')/g" $XEN_CONFIG_FILE
+ $SSHCMD rcxend restart
+
+ if [ "$NODE" = "any" ] || [ "$MANAGE_ALL_RELOCATION_NODES" = "false" ]
+ then
+ exit 0
+ fi
+ done
+}
+
+relocate_off() {
+ for NODE in $RELOCATION_NODELIST
+ do
+ case $NODE in
+ any)
+ SSHCMD=""
+ RELOCATION_NODELIST=""
+ ;;
+ *)
+ SSHCMD="ssh root@$NODE "
+ ;;
+ esac
+
+ $SSHCMD sed -i "s/^(xend-relocation-server yes)/#(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^(xend-relocation-port [^)]*)/#(xend-relocation-port $XEN_RELOCATION_PORT)/g" $XEN_CONFIG_FILE
+ $SSHCMD sed -i "s/^(xend-relocation-hosts-allow .*/#(xend-relocation-hosts-allow \'$RELOCATION_NODELIST')/g" $XEN_CONFIG_FILE
+ $SSHCMD rcxend restart
+
+ if [ "$NODE" = "any" ] || [ "$MANAGE_ALL_RELOCATION_NODES" = "false" ]
+ then
+ exit 0
+ fi
+ done
+}
+
+relocate_status() {
+ if grep -q "^(xend-relocation-server .*yes)" $XEN_CONFIG_FILE
+ then
+ ENABLED="yes"
+ elif egrep -q "(^\(xend-relocation-server .*no\)|^#\(xend-relocation-server .*no\)|^#\(xend-relocation-server .*yes\))" $XEN_CONFIG_FILE
+ then
+ ENABLED="no"
+ fi
+
+ echo ""
+ echo "Xend Relocation Server Enabled: $ENABLED"
+ echo ""
+}
+
+#### Script Body ##########################################################
+
+case $1 in
+ on|ON|On|start)
+ case $ENABLE_RELOCATION in
+ true)
+ relocate_on
+ ;;
+ false)
+ ;;
+ esac
+ exit 0
+ ;;
+ off|OFF|Off|stop)
+ relocate_off
+ exit 0
+ ;;
+ status|STATUS|Status)
+ relocate_status
+ exit 0
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+esac
diff --git a/os-plugins/plugins/xen/files/xen.examples/scripts/xmclone.sh b/os-plugins/plugins/xen/files/xen.examples/scripts/xmclone.sh
new file mode 100755
index 00000000..fd31249b
--- /dev/null
+++ b/os-plugins/plugins/xen/files/xen.examples/scripts/xmclone.sh
@@ -0,0 +1,793 @@
+#! /bin/bash
+
+# Script to clone Xen Dom-Us.
+# Based on XenClone by Glen Davis; rewritten by Bob Brandt.
+# Further extended and restructured by Manfred Hollstein.
+# Copyright (C) 2007 Manfred Hollstein, SUSE / Novell Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA.
+
+#
+# Defaults
+#
+VERSION=0.4.5
+XEN_CONFIGS=/etc/xen/vm/
+XEN_BASE=/var/lib/xen/images/
+SOURCE=
+DESTINATION=
+DUPLICATE=0
+HOSTNAME=
+IP=
+MAC=
+PART=2
+DOMU_IS_FILE_BASED=
+DOMU_ROOTDEV=
+FORCE=no
+
+
+#
+# Subroutines used in this script
+#
+
+# Display the usage information for this script
+function usage ()
+{
+ cat << EOF
+Usage: ${0##*/} [-h|--help] [-v|--version] [--force] [-c dir] [-b dir] [-d]
+ [-n hostname] [-i address] [-m address]
+ [-p number-of-root-partition-within-domU]
+ [-t target-device]
+ SourcedomU NewdomU
+
+Clones a domU, and gives a new Host name, MAC address and possibly IP address.
+Once finished the new domU should boot without any additional configuration.
+Currently works with single NIC, and basic bridge setup. Tested with cloning
+a SLES10 install created from the SLES10 YaST Xen module.
+
+ -h, --help Display this help message.
+ -v, --version Display the version of this program.
+ --force Silently overwrite files when destination already exists.
+ -c Xen configuration directory which defaults to:
+ $XEN_CONFIGS
+ -b Xen image base directory which defaults to:
+ $XEN_BASE
+ -d Duplicate only, do not modify attributes.
+ -n Hostname to be used, if not specified the NewdomU name
+ will be used.
+ -i IP address to be used, if not specified the IP address
+ will not be changed.
+ -m MAC address to be used, if not specified a psuedo-random
+ address will be used based on the ip address with the
+ format: 00:16:3e:BB:CC:DD
+ Where BB,CC,DD are the Hex octals of the IP address.
+ -p This script assumes that the second partition on any
+ writable disk of the domU to be cloned holds the root
+ file system in which attributes have to be changed.
+ If this is not the case for you, you can specify the
+ partition number using this flag.
+ -t If the SourcedomU uses a block device for its root/
+ boot directory, you need to specify the new block
+ device for NewdomU.
+
+From XENSource Networking WIKI (http://wiki.xensource.com/xenwiki/XenNetworking)
+Virtualised network interfaces in domains are given Ethernet MAC addresses. When
+choosing MAC addresses to use, ensure you choose a unicast address. That is, one
+with the low bit of the first octet set to zero. For example, an address
+starting aa: is OK but ab: is not.
+It is best to keep to the range of addresses declared to be "locally assigned"
+(rather than allocated globally to hardware vendors). These have the second
+lowest bit set to one in the first octet. For example, aa: is OK, a8: isn't.
+
+Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.
+EOF
+}
+
+# Display the version information for this script
+function version ()
+{
+ cat << EOF
+${0##*/} (Xen VM clone utility) $VERSION
+${0##*/} comes with ABSOLUTELY NO WARRANTY.
+This is free software, and you are welcome to redistribute it under the terms
+of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
+
+Written by Manfred Hollstein, based on work by Glen Davis and Bob Brandt.
+EOF
+}
+
+# Find/Replace text within a file
+function replace ()
+{
+ sed -i -e "s!$1!$2!g" "$3"
+}
+
+#
+# Find the first entry that names a writable image or device, assuming
+# the Dom-U is going to boot from it:
+#
+function get_first_writable_image ()
+{
+ local i
+
+ for i in $@
+ do
+ case $i in
+ # Match the first entry like "'phy:/dev/md0,xvda,w',"
+ *",w'," )
+ # Strip off the leading "'" character:
+ i="${i#*\'}"
+ # Strip off the final trailing "',"
+ echo "${i%*\',}"
+ return
+ ;;
+ esac
+ done
+}
+
+#
+# Extract just the protocol and the file/device name part from a disk entry:
+#
+function extract_proto_and_filename ()
+{
+ echo "$1" | cut -d, -f1
+}
+
+
+#
+# Make sure this script is run by the superuser root
+#
+if [ `id -u` -ne 0 ]
+then
+ echo "You must be root to run this script!" >&2
+ exit 1
+fi
+
+
+#
+# Process the parameters
+#
+# Must look for double -- arguments before calling getopts
+#
+if [ "$1" = "--version" ]
+then
+ version
+ exit 0
+fi
+if [ "$1" = "--help" ]
+then
+ usage
+ exit 0
+fi
+if [ "$1" = "--force" ]
+then
+ FORCE=yes
+ shift
+fi
+while getopts ":b:c:dhi:m:n:p:t:v" opt
+do
+ case $opt in
+ b )
+ XEN_BASE=$OPTARG
+ ;;
+ c )
+ XEN_CONFIGS=$OPTARG
+ ;;
+ d )
+ DUPLICATE=1
+ ;;
+ h )
+ usage
+ exit 1
+ ;;
+ i )
+ IP=$OPTARG
+ ;;
+ m )
+ MAC=$OPTARG
+ ;;
+ n )
+ HOSTNAME=$OPTARG
+ ;;
+ p )
+ PART=$OPTARG
+ ;;
+ t )
+ DOMU_ROOTDEV=$OPTARG
+ ;;
+ v )
+ version
+ exit 0
+ ;;
+ esac
+done
+shift $(($OPTIND-1))
+
+if [ $# -ne 2 ]
+then
+ echo "Illegal number of arguments passed!" >&2
+ echo "" >&2
+ usage
+ exit 1
+fi
+
+SOURCE=$1
+DESTINATION=$2
+
+
+#
+# Verify the Source and Destination parameters
+#
+# The source and destination should be relative directory names without
+# trailing /'s. If the source does have a full path, use that path as the
+# value for XEN_BASE. Otherwise remove all but the last part of the path
+# for both source and destination
+#
+SOURCEDIR=${SOURCE%/*}
+SOURCEBASE=${SOURCE##*/}
+if [ "$SOURCEDIR" != "$SOURCEBASE" ]
+then
+ XEN_BASE=$SOURCEDIR"/"
+ SOURCE=$SOURCEBASE
+fi
+SOURCE=${SOURCE##*/}
+DESTINATION=${DESTINATION##*/}
+
+
+#
+# Verify the Xen Config and Source parameters
+#
+# Verify the validity of each argument, ask the user if there is a problem
+while [ ! -d "$XEN_CONFIGS" ]
+do
+ cat << EOF >&2
+$XEN_CONFIGS either does not exist or is not a directory.
+Please enter a valid directory.
+EOF
+ read -e -p "Xen Configuration Directory? " XEN_CONFIGS
+done
+while [ ! -d "$XEN_BASE" ]
+do
+ cat << EOF >&2
+$XEN_BASE either does not exist or is not a directory.
+Please enter a valid directory.
+EOF
+ read -e -p "Xen Image Base Directory? " XEN_BASE
+done
+
+#
+# Directories should have a / after them
+#
+[ "$XEN_CONFIGS" != "" ] && XEN_CONFIGS="${XEN_CONFIGS%/}/"
+[ "$XEN_BASE" != "" ] && XEN_BASE="${XEN_BASE%/}/"
+
+
+#
+# Verify that actual image and configuration file exist
+#
+while :
+do
+ if [ ! -f "$XEN_CONFIGS$SOURCE" ]
+ then
+ echo "The $XEN_CONFIGS$SOURCE file does not exist." >&2
+ echo "Please select a valid file." >&2
+ FILES=
+ for FILE in `ls $XEN_CONFIGS`
+ do
+ # If the entry is a file
+ [ -f "$XEN_CONFIGS$FILE" ] &&
+ FILES="$FILES $XEN_CONFIGS$FILE"
+ done
+ if [ -z "$FILES" ]
+ then
+ echo "There are no suitable files beneath $XEN_CONFIGS" >&2
+ exit 1
+ fi
+ echo "Files beneath $XEN_CONFIGS"
+ select FILE in $FILES
+ do
+ if [ -f "$FILE" ]
+ then
+ SOURCE=${FILE##*/}
+ break
+ fi
+ echo "Invalid Selection." >&2
+ done
+ else
+ #
+ # Figure out what type of image we're using:
+ #
+ BOOTENTRY=$(get_first_writable_image $(sed -n -e 's,^disk[ ]*=[ ]*\[\(.*\)\],\1,p' "$XEN_CONFIGS$SOURCE"))
+ case "$BOOTENTRY" in
+ phy:* )
+ DOMU_IS_FILE_BASED=no
+ ;;
+ file:* | \
+ tap:aio:* )
+ DOMU_IS_FILE_BASED=yes
+ ;;
+ * )
+ echo "Don't know how to deal with the boot protocol/device you appear to be using: $BOOTENTRY" >&2
+ echo "These are the ones this script supports: \"phy:*\", \"file:*\", \"tap:aio:*\"" >&2
+ exit 1
+ ;;
+ esac
+ fi
+
+
+ if [ ${DOMU_IS_FILE_BASED} = yes ]
+ then
+ if [ ! -d "$XEN_BASE$SOURCE" ]
+ then
+ echo "The directory $XEN_BASE$SOURCE is invalid." >&2
+ echo "Please select another one." >&2
+ FILES=
+ for FILE in `ls $XEN_BASE`
+ do
+ # If the entry is a directory and
+ # it is not empty
+ [ -d "$XEN_BASE$FILE" ] &&
+ [ "`ls $XEN_BASE$FILE`" != "" ] &&
+ FILES="$FILES $XEN_BASE$FILE"
+ done
+ if [ -z "$FILES" ]
+ then
+ echo "There are no suitable directories beneath $XEN_BASE" >&2
+ exit 1
+ fi
+ echo "Directories beneath $XEN_BASE"
+ select FILE in $FILES
+ do
+ if [ -d "$FILE" ]
+ then
+ SOURCE=${FILE##*/}
+ break
+ fi
+ echo "Invalid Selection." >&2
+ done
+ continue
+ fi
+ break
+
+ else # DomU is using some block device
+ while [ ! -b "${DOMU_ROOTDEV}" ] || [ ! -w "${DOMU_ROOTDEV}" ]
+ do
+ read -e -p "You need to specify a valid block device for the new target DomU: " DOMU_ROOTDEV
+ done
+ break
+
+ fi
+done
+BOOTIMAGE="$(echo $BOOTENTRY | awk -F : '{ print $NF }' | sed -e 's:,[^,]*,[^,]*$::')"
+
+
+#
+# Verify that the destination location does not already have an image or
+# config file
+#
+while [ -z "$DESTINATION" ]
+do
+ echo "You have not specified a Destination." >&2
+ read -e -p "New Destination? " DESTINATION
+done
+while :
+do
+ if [ -f "$XEN_CONFIGS$DESTINATION" ] && [ $FORCE = no ]
+ then
+ echo "The target configuration file $XEN_CONFIGS$DESTINATION already exists!" >&2
+ read -e -p "Please select a new Destination? " DESTINATION
+ fi
+ if [ ${DOMU_IS_FILE_BASED} = yes ]
+ then
+ if [ -d "$XEN_BASE$DESTINATION" ] && [ $FORCE = no ]
+ then
+ echo "The target image location $XEN_BASE$DESTINATION already exists!" >&2
+ read -p "Please select a new Destination? " DESTINATION
+ continue
+ fi
+ fi
+ break
+done
+
+
+#
+# Verify the network parameters (if Duplicate Only was not selected)
+#
+if [ $DUPLICATE -eq 0 ]
+then
+ if [ -z "$HOSTNAME" ]
+ then
+ echo "You have not entered a host name. If you wish to, enter one now." >&2
+ read -p "New host name? (Default: $DESTINATION) " HOSTNAME
+ fi
+ [ -z "$HOSTNAME" ] && HOSTNAME=$DESTINATION
+
+ if [ -z "$IP" ]
+ then
+ echo "You have not specified an IP Address. If you wish to change the IP address, enter one now."
+ read -p "New IP Address? " IP
+ fi
+ while [ -n "$IP" ] && [ "${IP/*.*.*.*/ok}" != "ok" ]
+ do
+ echo "The IP Address you specified is invalid. If you wish, enter a new one now."
+ read -p "New IP Address? " IP
+ [ -z "$IP" ] && break
+ done
+
+ if [ -z "$MASK" ]
+ then
+ echo "You have not specified a network mask in bits. Please enter one now. Default is 24 "
+ read -p "Network mask? " MASK
+ fi
+ while [ -n "$MASK" ] && [ "${MASK/**/ok}" != "ok" ]
+ do
+ echo "The Network mask you specified is invalid. If you wish, enter a new one now."
+ read -p "Network mask? " MASK
+ [ -z "$MASK" ] && MASK=24
+ done
+
+ if [ -z "$MAC" ]
+ then
+ newMAC=""
+ newMACtext="(format 01:23:45:67:89:AB)"
+ # If the IP Address is specified and the MAC isn't, generate one.
+ if [ -n "$IP" ]
+ then
+ octal1=${IP%%.*}
+ IP=${IP#*.}
+ octal2=${IP%%.*}
+ IP=${IP#*.}
+ octal3=${IP%%.*}
+ octal4=${IP#*.}
+ IP="$octal1.$octal2.$octal3.$octal4"
+ octal1="00"`echo $octal1 16 o p | dc | tr '[:upper:]' '[:lower:]'`
+ octal2="00"`echo $octal2 16 o p | dc | tr '[:upper:]' '[:lower:]'`
+ octal3="00"`echo $octal3 16 o p | dc | tr '[:upper:]' '[:lower:]'`
+ octal4="00"`echo $octal4 16 o p | dc | tr '[:upper:]' '[:lower:]'`
+ newMAC="00:16:3e:"${octal2:(-2)}":"${octal3:(-2)}":"${octal4:(-2)}
+ newMACtext="(default $newMAC)"
+ fi
+ echo "You have not specified a MAC Address. If you wish to change the MAC address, enter one now."
+ read -p "New MAC Address? $newMACtext " MAC
+ [ -z "$MAC" ] && MAC=$newMAC
+ fi
+
+ while [ "$MAC" != "" ] && [ "${MAC/[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]/ok}" != "ok" ]
+ do
+ echo "The MAC Address you specified is invalid. If you wish, enter a new one now."
+ read -p "New MAC Address? (format 01:23:45:67:89:AB) " MAC
+ [ -z "$MAC" ] && break
+ done
+else
+ HOSTNAME=
+ IP=
+ MASK=
+ MAC=
+fi
+
+
+#
+# Make sure that the source VM is not running
+#
+xmid=`xm domid "$SOURCE" 2>/dev/null`
+if [ $? -eq 0 ] && [ -n "$xmid" ] && [ -z "${xmid//[[:digit:]]/}" ]
+then
+ echo "domU $SOURCE is currently running on Xen, please shutdown before cloning." >&2
+ echo "The command \"xm shutdown $xmid -w\" will shutdown the domU" >&2
+ exit 1
+fi
+
+
+#
+# Copy the Xen Config file
+#
+SOURCECONFIG="$XEN_CONFIGS$SOURCE"
+DESTCONFIG="$XEN_CONFIGS$DESTINATION"
+echo "Copying Configuration files"
+if ! cp -fv "$SOURCECONFIG" "$DESTCONFIG"
+then
+ echo "The Config file $SOURCECONFIG could not be copied to $DESTCONFIG" >&2
+ exit 1
+fi
+
+
+#
+# Edit newly copied configuration file
+#
+echo "Editing config file ($DESTCONFIG), correcting the new domU Name."
+if ! replace "$SOURCE" "$DESTINATION" "$DESTCONFIG"
+then
+ echo "Unable to change the domU name in $DESTCONFIG from $SOURCE to $DESTINATION" >&2
+ exit 1
+fi
+
+if [ $DUPLICATE -eq 0 ]
+then
+ oldUUID=`grep "^uuid[ ]*=.*$" $DESTCONFIG`
+ if [ x"${oldUUID}" = x ]
+ then
+ echo 'uuid="'`uuidgen`'"' >> $DESTCONFIG
+ else
+ sed -i -e 's,^uuid[ ]*=.*$,uuid="'`uuidgen`'",' $DESTCONFIG
+ fi
+fi
+
+if [ $DUPLICATE -eq 0 ] && [ -n "$MAC" ]
+then
+ # Get the vif line in the config file
+ oldMAC=`grep "vif[ ]*=[ ]*" $DESTCONFIG`
+ # extract everything between the square brackets
+ oldMAC=${oldMAC#*[}
+ oldMAC=${oldMAC%*]}
+ # using the single quotes as delimiters, get the second field
+ # (this script can only deal with one adapter!)
+ oldMAC=`echo "$oldMAC" | cut -f2 -d\'`
+ # remove the mac= from the beginning
+ oldMAC=${oldMAC#mac=*}
+
+ if ! replace "$oldMAC" "$MAC" "$DESTCONFIG"
+ then
+ echo "Unable to change the MAC address in $DESTCONFIG from ($oldMAC) to ($MAC)" >&2
+ exit 1
+ fi
+fi
+
+
+#
+# Create and Copy image directory
+#
+
+if [ $DOMU_IS_FILE_BASED = yes ]
+then
+ SOURCEXEN="$XEN_BASE$SOURCE/"
+ DESTXEN="$XEN_BASE$DESTINATION/"
+ echo "Creating the new image directory $DESTXEN"
+ if ! mkdir -pv --mode=755 "$DESTXEN"
+ then
+ echo "Unable to create the directory $DESTXEN" >&2
+ exit 1
+ fi
+ echo "Copying complete image. (This may take a few minutes!)"
+
+ tar -C $SOURCEXEN -cSf - --exclude=lost+found `cd $SOURCEXEN; echo *` \
+ | tar -C $DESTXEN -xvBSpf -
+ if [ $? -ne 0 ]
+ then
+ echo "Unable to copy the images from $SOURCEXEN to $DESTXEN" >&2
+ exit 1
+ fi
+else # Deal with block devices
+ if [ $DUPLICATE -eq 0 ]
+ then
+ echo "Editing config file ($DESTCONFIG), correcting the new domU root device name."
+ if ! replace ":$BOOTIMAGE," ":$DOMU_ROOTDEV," "$DESTCONFIG"
+ then
+ echo "Unable to change the domU root device name in $DESTCONFIG from $BOOTIMAGE to $DOMU_ROOTDEV" >&2
+ exit 1
+ fi
+ fi
+ echo "Copying from source block device ($BOOTIMAGE) to the new target device ($DOMU_ROOTDEV)"
+ echo "(This may take a few minutes!)"
+ if ! dd if=$BOOTIMAGE of=$DOMU_ROOTDEV bs=4K
+ then
+ echo "Failed to copy from $BOOTIMAGE to $DOMU_ROOTDEV" >&2
+ exit 1
+ fi
+fi
+
+
+#
+# The rest of the script only applies if we are actually making changes within
+# the image
+#
+if [ $DUPLICATE -eq 0 ]
+then
+ #
+ # Create a temporary directory name
+ #
+ tmpdir=$(mktemp -d)
+ if [ $? -ne 0 ]
+ then
+ echo "Unable to create temporary directory $tmpdir." >&2
+ exit 1
+ fi
+
+ if [ $DOMU_IS_FILE_BASED = yes ]
+ then
+ set -- $(echo $DESTXEN*)
+ else
+ set -- $(echo $DOMU_ROOTDEV)
+ fi
+
+ for DISKIMAGE
+ do
+ # Silently ignore any directories (lost+found comes to mind):
+ [ -d $DISKIMAGE ] && continue
+
+ #
+ # Mount the newly copied image file
+ #
+ loopdev=''
+ for dev in /dev/loop*
+ do
+ if [ ! -b "$dev" ]
+ then
+ continue
+ fi
+
+ status=$(losetup "$dev" 2>/dev/null) || status=''
+
+ if [ ! "$status" ]
+ then
+ status=$(losetup $dev "$DISKIMAGE")
+ if [ ! "$status" ]
+ then
+ kpartx -a $dev
+ loopdev=$dev
+ break
+ fi
+ fi
+ done
+ if [ ! "$loopdev" ]
+ then
+ echo "No loopback devices available." >&2
+ exit 1
+ fi
+
+ echo -n "Trying to mount partition $PART of $DISKIMAGE ... "
+ mapperdev=$(echo "$loopdev" | sed -e 's/dev\//dev\/mapper\//g')p$PART
+ status=$(mount -o rw $mapperdev "$tmpdir")
+ if [ "$status" ]
+ then
+ kpartx -d $loopdev
+ losetup -d $loopdev
+ continue
+ fi
+ echo "succeeded."
+
+ pushd "$tmpdir" > /dev/null
+
+ #
+ # Find out if we are looking at SLE10
+ #
+ SLE10=
+ if [ -f etc/SuSE-release ]
+ then
+ OSVER=`cat etc/SuSE-release | sed -n 1p | awk -F'(' '{ print $1 }' | sed 's/ $//g'`
+ if [ "$OSVER" == "openSUSE 10" -o \
+ "$OSVER" == "SUSE Linux Enterprise Server 10" -o \
+ "$OSVER" == "SUSE Linux Enterprise Desktop 10" ]
+ then
+ SLE10=1
+ fi
+ fi
+
+ #
+ # Change the Network Configuration in the mounted image file
+ #
+ if [ -n "$MAC" ]
+ then
+ if [ -d etc/sysconfig/network/ ]
+ then
+ echo "Changing the Network configuration in the newly copied image."
+ pushd "etc/sysconfig/network/" > /dev/null
+ # Find the ifcfg-ethMACADDRESS file in the
+ # newly copied image
+ ETH0=`ls | grep ifcfg-eth | cut -f1`
+ if [ -z "$ETH0" ]
+ then
+ echo "Unable to find ethernet file in image file" 2>&1
+ cd /tmp; umount "$tmpdir"; rmdir "$tmpdir"
+ kpartx -d $loopdev
+ losetup -d $loopdev
+ exit 1
+ fi
+ if [ "$SLE10" ]
+ then
+ mv -f "$ETH0" ifcfg-eth-id-$MAC
+ else
+ sed -i -e "s,^LLADDR=.*$,LLADDR=\'$MAC\'," \
+ ifcfg-eth0
+ fi
+ popd > /dev/null
+ fi
+
+ if [ -d etc/udev/rules.d/ ]
+ then
+ # The 30-net_persistent_names.rules or 70-persistent-net.rules
+ # file controls which interface to use.
+ # By removing the SUBSYSTEM== lines, we force
+ # the system to recreate it.
+ pushd "etc/udev/rules.d/" > /dev/null
+ if [ "$SLE10" ]
+ then
+ sed -i -e "/SUBSYSTEM==/d" \
+ 30-net_persistent_names.rules
+ else
+ sed -i -e "/SUBSYSTEM==/d" \
+ 70-persistent-net.rules
+ fi
+ popd > /dev/null
+ fi
+ fi
+
+ #
+ # Change the IP Address in the mounted image file
+ #
+ if [ -n "$IP" ]
+ then
+ if [ -d etc/sysconfig/network/ ]
+ then
+ echo "Modify the IP Address of the new domU."
+
+ pushd "etc/sysconfig/network/" > /dev/null
+ if [ "$SLE10" ]
+ then
+ sed -i -e "s,^IPADDR=.*$,IPADDR=$IP," \
+ ifcfg-eth-id-$MAC
+ else
+ sed -i -e "s,^IPADDR=.*$,IPADDR=$IP/$MASK," \
+ ifcfg-eth0
+ fi
+ popd > /dev/null
+ fi
+ fi
+
+ #
+ # Change the HOSTNAME and hosts files in the mounted image file
+ #
+ if [ -n "$HOSTNAME" ]
+ then
+ if [ -d "etc/" ]
+ then
+ echo "Changing HOSTNAME file to $HOSTNAME."
+
+ pushd "etc/" > /dev/null
+ # using the period as a delimiter, select the
+ # first entry for the hostname
+ oldHOSTNAME=`cut -f1 -d\. HOSTNAME`
+ if ! replace "$oldHOSTNAME" "$HOSTNAME" "HOSTNAME"
+ then
+ echo "Unable to change the HOSTNAME from $oldHOSTNAME to $HOSTNAME" >&2
+ cd /tmp; umount "$tmpdir"; rmdir "$tmpdir"
+ kpartx -d $loopdev
+ losetup -d $loopdev
+ exit 1
+ fi
+ FQDN=`cat HOSTNAME`
+
+ # Add entries for the new domU to /etc/hosts,
+ # if it doesn't already include them:
+ if ! egrep -q "[[:space:]]$FQDN[^[:alnum:]]" \
+ hosts
+ then
+ echo "Changing hosts file."
+ echo -e "$IP\t$FQDN $HOSTNAME" >> hosts
+ fi
+ popd > /dev/null
+ fi
+ fi
+
+ popd > /dev/null
+ umount "$tmpdir"
+ kpartx -d $loopdev
+ losetup -d $loopdev
+ done
+
+ rmdir "$tmpdir"
+fi
+
+echo "Clone is complete. domU $DESTCONFIG is ready to start!"
+exit 0