# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1227590484 -32400
# Node ID 436816898c87fb6e86fff510ddce2df10afa4454
# Parent 7ef733b961c8786029e399c3f878f1e67a6af780
# Parent e7c421510be96f456cd367d125d86f939d27d253
merge with xen-unstable.hg
---
tools/examples/blktap | 93 --
tools/examples/block | 381 --------
tools/examples/block-common.sh | 116 --
tools/examples/block-enbd | 27
tools/examples/block-nbd | 27
tools/examples/external-device-migrate | 91 --
tools/examples/init.d/sysconfig.xendomains | 137 ---
tools/examples/init.d/xend | 66 -
tools/examples/init.d/xendomains | 531 ------------
tools/examples/locking.sh | 98 --
tools/examples/logging.sh | 22
tools/examples/network-bridge | 310 -------
tools/examples/network-nat | 119 --
tools/examples/network-route | 27
tools/examples/vif-bridge | 100 --
tools/examples/vif-common.sh | 151 ---
tools/examples/vif-nat | 192 ----
tools/examples/vif-route | 56 -
tools/examples/vscsi | 22
tools/examples/vtpm | 22
tools/examples/vtpm-common.sh | 448 ----------
tools/examples/vtpm-delete | 18
tools/examples/vtpm-hotplug-common.sh | 35
tools/examples/vtpm-impl | 208 ----
tools/examples/vtpm-migration.sh | 19
tools/examples/xen-backend.agent | 39
tools/examples/xen-backend.rules | 9
tools/examples/xen-hotplug-cleanup | 22
tools/examples/xen-hotplug-common.sh | 93 --
tools/examples/xen-network-common.sh | 118 --
tools/examples/xen-script-common.sh | 44
xen/arch/x86/mm/page-guest32.h | 100 --
xen/include/asm-x86/pirq.h | 11
extras/mini-os/include/posix/net/if.h | 85 +
extras/mini-os/lib/sys.c | 7
tools/Makefile | 1
tools/examples/Makefile | 58 -
tools/firmware/hvmloader/config.h | 1
tools/firmware/hvmloader/hvmloader.c | 198 +++-
tools/firmware/rombios/rombios.c | 23
tools/hotplug/Linux/Makefile | 97 ++
tools/hotplug/Linux/blktap | 93 ++
tools/hotplug/Linux/block | 381 ++++++++
tools/hotplug/Linux/block-common.sh | 116 ++
tools/hotplug/Linux/block-enbd | 27
tools/hotplug/Linux/block-nbd | 27
tools/hotplug/Linux/external-device-migrate | 98 ++
tools/hotplug/Linux/init.d/sysconfig.xendomains | 137 +++
tools/hotplug/Linux/init.d/xend | 66 +
tools/hotplug/Linux/init.d/xendomains | 531 ++++++++++++
tools/hotplug/Linux/locking.sh | 98 ++
tools/hotplug/Linux/logging.sh | 22
tools/hotplug/Linux/network-bridge | 310 +++++++
tools/hotplug/Linux/network-nat | 119 ++
tools/hotplug/Linux/network-route | 27
tools/hotplug/Linux/vif-bridge | 100 ++
tools/hotplug/Linux/vif-common.sh | 151 +++
tools/hotplug/Linux/vif-nat | 192 ++++
tools/hotplug/Linux/vif-route | 56 +
tools/hotplug/Linux/vscsi | 22
tools/hotplug/Linux/vtpm | 22
tools/hotplug/Linux/vtpm-common.sh | 448 ++++++++++
tools/hotplug/Linux/vtpm-delete | 18
tools/hotplug/Linux/vtpm-hotplug-common.sh | 35
tools/hotplug/Linux/vtpm-impl | 208 ++++
tools/hotplug/Linux/vtpm-migration.sh | 19
tools/hotplug/Linux/xen-backend.agent | 39
tools/hotplug/Linux/xen-backend.rules | 9
tools/hotplug/Linux/xen-hotplug-cleanup | 22
tools/hotplug/Linux/xen-hotplug-common.sh | 93 ++
tools/hotplug/Linux/xen-network-common.sh | 118 ++
tools/hotplug/Linux/xen-script-common.sh | 44
tools/hotplug/Makefile | 9
tools/hotplug/NetBSD/Makefile | 41
tools/hotplug/NetBSD/block-nbsd | 88 +
tools/hotplug/NetBSD/qemu-ifup-nbsd | 3
tools/hotplug/NetBSD/vif-bridge-nbsd | 35
tools/hotplug/NetBSD/vif-ip-nbsd | 33
tools/hotplug/common/Makefile | 37
tools/libxc/xc_cpufeature.h | 1
tools/libxc/xc_cpuid_x86.c | 3
tools/misc/xenpm.c | 2
tools/python/xen/util/rwlock.py | 137 +++
tools/python/xen/xend/XendAPI.py | 2
tools/python/xen/xend/XendConfig.py | 2
tools/python/xen/xend/XendDomain.py | 29
tools/python/xen/xend/XendDomainInfo.py | 230 ++---
tools/python/xen/xend/osdep.py | 29
tools/python/xen/xend/server/pciif.py | 47 -
tools/python/xen/xm/create.py | 5
unmodified_drivers/linux-2.6/balloon/Kbuild | 5
unmodified_drivers/linux-2.6/mkbuildtree | 1
unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c | 4
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c | 4
xen/Rules.mk | 3
xen/arch/x86/Makefile | 1
xen/arch/x86/acpi/boot.c | 4
xen/arch/x86/acpi/power.c | 39
xen/arch/x86/copy_page.S | 66 +
xen/arch/x86/cpu/common.c | 9
xen/arch/x86/cpu/mcheck/p4.c | 2
xen/arch/x86/domain.c | 47 -
xen/arch/x86/domain_build.c | 39
xen/arch/x86/domctl.c | 13
xen/arch/x86/hpet.c | 19
xen/arch/x86/hvm/hvm.c | 43
xen/arch/x86/hvm/mtrr.c | 16
xen/arch/x86/hvm/svm/svm.c | 24
xen/arch/x86/hvm/vioapic.c | 4
xen/arch/x86/hvm/vlapic.c | 42
xen/arch/x86/hvm/vmsi.c | 2
xen/arch/x86/hvm/vmx/intr.c | 4
xen/arch/x86/hvm/vmx/realmode.c | 23
xen/arch/x86/hvm/vmx/vmcs.c | 5
xen/arch/x86/hvm/vmx/vmx.c | 91 +-
xen/arch/x86/hvm/vmx/vpmu_core2.c | 2
xen/arch/x86/i8259.c | 2
xen/arch/x86/io_apic.c | 24
xen/arch/x86/irq.c | 55 -
xen/arch/x86/mm.c | 100 +-
xen/arch/x86/mm/Makefile | 6
xen/arch/x86/mm/guest_walk.c | 260 +++++
xen/arch/x86/mm/hap/guest_walk.c | 181 +---
xen/arch/x86/mm/hap/private.h | 34
xen/arch/x86/mm/p2m.c | 2
xen/arch/x86/mm/shadow/multi.c | 401 +--------
xen/arch/x86/mm/shadow/types.h | 203 ----
xen/arch/x86/msi.c | 55 -
xen/arch/x86/setup.c | 8
xen/arch/x86/smpboot.c | 17
xen/arch/x86/time.c | 138 ++-
xen/arch/x86/traps.c | 11
xen/arch/x86/x86_32/mm.c | 24
xen/arch/x86/x86_64/mm.c | 19
xen/common/kernel.c | 3
xen/drivers/passthrough/io.c | 4
xen/drivers/passthrough/pci.c | 6
xen/drivers/passthrough/vtd/dmar.c | 4
xen/drivers/passthrough/vtd/ia64/vtd.c | 5
xen/drivers/passthrough/vtd/intremap.c | 33
xen/drivers/passthrough/vtd/iommu.c | 36
xen/drivers/passthrough/vtd/qinval.c | 2
xen/drivers/passthrough/vtd/vtd.h | 2
xen/drivers/passthrough/vtd/x86/vtd.c | 11
xen/include/asm-ia64/hvm/irq.h | 2
xen/include/asm-ia64/linux/asm/irq.h | 1
xen/include/asm-x86/acpi.h | 3
xen/include/asm-x86/config.h | 6
xen/include/asm-x86/cpufeature.h | 1
xen/include/asm-x86/domain.h | 3
xen/include/asm-x86/guest_pt.h | 291 ++++++
xen/include/asm-x86/hpet.h | 4
xen/include/asm-x86/hvm/irq.h | 1
xen/include/asm-x86/hvm/vlapic.h | 3
xen/include/asm-x86/hvm/vmx/vmx.h | 6
xen/include/asm-x86/irq.h | 2
xen/include/asm-x86/mach-default/irq_vectors.h | 4
xen/include/asm-x86/mm.h | 1
xen/include/asm-x86/msi.h | 8
xen/include/asm-x86/page.h | 6
xen/include/asm-x86/perfc_defn.h | 2
xen/include/asm-x86/x86_32/page.h | 2
xen/include/asm-x86/x86_64/page.h | 2
xen/include/public/features.h | 6
xen/include/public/grant_table.h | 9
xen/include/public/io/pciif.h | 35
xen/include/public/kexec.h | 21
xen/include/xen/hvm/irq.h | 2
xen/include/xen/hypercall.h | 6
xen/include/xen/iommu.h | 4
xen/include/xen/irq.h | 11
xen/include/xen/kexec.h | 21
172 files changed, 6061 insertions(+), 5163 deletions(-)
diff -r 7ef733b961c8 -r 436816898c87 extras/mini-os/include/posix/net/if.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/posix/net/if.h Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,85 @@
+/*
+ * This code is mostly taken from NetBSD net/if.h
+ * Changes: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
+ *
+ ******************************************************************************
+ *
+ * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by William Studenmund and Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ */
+
+#ifndef _NET_IF_H_
+#define _NET_IF_H_
+
+/*
+ * Length of interface external name, including terminating '\0'.
+ * Note: this is the same size as a generic device's external name.
+ */
+#define IF_NAMESIZE 16
+
+struct if_nameindex {
+ unsigned int if_index; /* 1, 2, ... */
+ char *if_name; /* null terminated name: "le0", ... */
+};
+
+unsigned int if_nametoindex(const char *);
+char * if_indextoname(unsigned int, char *);
+struct if_nameindex * if_nameindex(void);
+void if_freenameindex(struct if_nameindex *);
+
+#endif /* !_NET_IF_H_ */
+
diff -r 7ef733b961c8 -r 436816898c87 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c Tue Nov 18 10:55:51 2008 +0100
+++ b/extras/mini-os/lib/sys.c Tue Nov 25 14:21:24 2008 +0900
@@ -34,6 +34,7 @@
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <net/if.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
@@ -1324,6 +1325,12 @@ unsupported_function(int, tcgetattr, 0);
unsupported_function(int, tcgetattr, 0);
unsupported_function(int, poll, -1);
+/* net/if.h */
+unsupported_function_log(unsigned int, if_nametoindex, -1);
+unsupported_function_log(char *, if_indextoname, (char *) NULL);
+unsupported_function_log(struct if_nameindex *, if_nameindex, (struct
if_nameindex *) NULL);
+unsupported_function_crash(if_freenameindex);
+
/* Linuxish abi for the Caml runtime, don't support */
unsupported_function_log(struct dirent *, readdir64, NULL);
unsupported_function_log(int, getrusage, -1);
diff -r 7ef733b961c8 -r 436816898c87 tools/Makefile
--- a/tools/Makefile Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -9,6 +9,7 @@ SUBDIRS-y += xenstore
SUBDIRS-y += xenstore
SUBDIRS-y += misc
SUBDIRS-y += examples
+SUBDIRS-y += hotplug
SUBDIRS-y += xentrace
SUBDIRS-$(CONFIG_XCUTILS) += xcutils
SUBDIRS-$(CONFIG_X86) += firmware
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/Makefile
--- a/tools/examples/Makefile Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/examples/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -24,41 +24,6 @@ XEN_CONFIGS += xend-pci-quirks.sxp
XEN_CONFIGS += xend-pci-quirks.sxp
XEN_CONFIGS += xend-pci-permissive.sxp
-# Xen script dir and scripts to go there.
-XEN_SCRIPT_DIR = /etc/xen/scripts
-XEN_SCRIPTS = network-bridge vif-bridge
-XEN_SCRIPTS += network-route vif-route
-XEN_SCRIPTS += network-nat vif-nat
-XEN_SCRIPTS += block
-XEN_SCRIPTS += block-enbd block-nbd
-XEN_SCRIPTS += blktap
-XEN_SCRIPTS += vtpm vtpm-delete
-XEN_SCRIPTS += xen-hotplug-cleanup
-XEN_SCRIPTS += external-device-migrate
-XEN_SCRIPTS += vscsi
-XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
-XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
-XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
-XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
-
-XEN_HOTPLUG_DIR = /etc/hotplug
-XEN_HOTPLUG_SCRIPTS = xen-backend.agent
-
-UDEV_RULES_DIR = /etc/udev
-UDEV_RULES = xen-backend.rules
-
-DI = $(if $(DISTDIR),$(shell readlink -f $(DISTDIR)),)
-DE = $(if $(DESTDIR),$(shell readlink -f $(DESTDIR)),)
-ifeq ($(findstring $(DI),$(DE)),$(DI))
-HOTPLUGS=install-hotplug install-udev
-else
-ifeq ($(shell [ -x /usr/bin/udevinfo ] && [ `/usr/bin/udevinfo -V | sed -e
's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/'` -ge 059 ] && echo 1),1)
-HOTPLUGS=install-udev
-else
-HOTPLUGS=install-hotplug
-endif
-endif
-
.PHONY: all
all:
@@ -66,7 +31,7 @@ build:
build:
.PHONY: install
-install: all install-readmes install-initd install-configs install-scripts
$(HOTPLUGS)
+install: all install-readmes install-configs $(HOTPLUGS)
.PHONY: install-readmes
install-readmes:
@@ -77,14 +42,6 @@ install-readmes:
$(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \
done
-.PHONY: install-initd
-install-initd:
- [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
- [ -d $(DESTDIR)/etc/sysconfig ] || $(INSTALL_DIR)
$(DESTDIR)/etc/sysconfig
- $(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
- $(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
- $(INSTALL_PROG) $(XENDOMAINS_SYSCONFIG)
$(DESTDIR)/etc/sysconfig/xendomains
-
.PHONY: install-configs
install-configs: $(XEN_CONFIGS)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
@@ -94,19 +51,6 @@ install-configs: $(XEN_CONFIGS)
set -e; for i in $(XEN_CONFIGS); \
do [ -e $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \
$(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \
- done
-
-.PHONY: install-scripts
-install-scripts:
- [ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \
- $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
- set -e; for i in $(XEN_SCRIPTS); \
- do \
- $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
- done
- set -e; for i in $(XEN_SCRIPT_DATA); \
- do \
- $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
done
.PHONY: install-hotplug
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/blktap
--- a/tools/examples/blktap Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/block
--- a/tools/examples/block Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-#!/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
-
- case $t in
- phy)
- dev=$(expand_dev $p)
- FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
- FRONTEND_UUID=$(xenstore_read_default \
- "/local/domain/$FRONTEND_ID/vm" 'unknown')
-
- 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)
- # 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")
-
- 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
-
- 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
-
- if LANG=C losetup -h 2>&1 | grep read-only >/dev/null
- then
- roflag="-$mode"; roflag="${roflag#-w}"; roflag="${roflag#-!}"
- else
- roflag=''
- fi
- do_or_die losetup $roflag "$loopdev" "$file"
- 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")
- losetup -d "$node"
- exit 0
- ;;
-
- "")
- 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/block-common.sh
--- a/tools/examples/block-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-#
-# 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")
-
- [ "$FRONTEND_UUID" = "$othervm" ]
-}
-
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/block-enbd
--- a/tools/examples/block-enbd Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# Usage: block-enbd [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"
-
-case "$command" in
- add)
- for dev in /dev/nd*; do
- if nbd-client $2:$3 $dev; then
- write_dev $dev
- exit 0
- fi
- done
- exit 1
- ;;
- remove)
- nbd-client -d $2
- exit 0
- ;;
-esac
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/block-nbd
--- a/tools/examples/block-nbd Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-# 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"
-
-case "$command" in
- add)
- for dev in /dev/nbd*; do
- if nbd-client $2 $3 $dev; then
- write_dev $dev
- exit 0
- fi
- done
- exit 1
- ;;
- remove)
- nbd-client -d $2
- exit 0
- ;;
-esac
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/external-device-migrate
--- a/tools/examples/external-device-migrate Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/init.d/sysconfig.xendomains
--- a/tools/examples/init.d/sysconfig.xendomains Tue Nov 18 10:55:51
2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-## Path: System/xen
-## Description: xen domain start/stop on boot
-## Type: string
-## Default:
-#
-# The xendomains script can send SysRq requests to domains on shutdown.
-# If you don't want to MIGRATE, SAVE, or SHUTDOWN, this may be a possibility
-# to do a quick and dirty shutdown ("s e i u o") or at least sync the disks
-# of the domains ("s").
-#
-XENDOMAINS_SYSRQ=""
-
-## Type: integer
-## Default: 100000
-#
-# If XENDOMAINS_SYSRQ is set, this variable determines how long to wait
-# (in microseconds) after each SysRq, so the domain has a chance to react.
-# If you want to a quick'n'dirty shutdown via SysRq, you may want to set
-# it to a relatively high value (1200000).
-#
-XENDOMAINS_USLEEP=100000
-
-## Type: integer
-## Default: 5000000
-#
-# When creating a guest domain, it is sensible to allow a little time for it
-# to get started before creating another domain or proceeding through the
-# boot process. Without this, the booting guests will thrash the disk as they
-# start up. This timeout (in microseconds) specifies the delay after guest
-# domain creation.
-#
-XENDOMAINS_CREATE_USLEEP=5000000
-
-## Type: string
-## Default: ""
-#
-# Set this to a non-empty string if you want to migrate virtual machines
-# on shutdown. The string will be passed to the xm migrate DOMID command
-# as is: It should contain the target IP address of the physical machine
-# to migrate to and optionally parameters like --live. Leave empty if
-# you don't want to try virtual machine relocation on shutdown.
-# If migration succeeds, neither SAVE nor SHUTDOWN will be executed for
-# that domain.
-#
-XENDOMAINS_MIGRATE=""
-
-## Type: string
-## Default: /var/lib/xen/save
-#
-# Directory to save running domains to when the system (dom0) is
-# shut down. Will also be used to restore domains from if # XENDOMAINS_RESTORE
-# is set (see below). Leave empty to disable domain saving on shutdown
-# (e.g. because you rather shut domains down).
-# If domain saving does succeed, SHUTDOWN will not be executed.
-#
-XENDOMAINS_SAVE=/var/lib/xen/save
-
-## Type: string
-## Default: "--halt --wait"
-#
-# If neither MIGRATE nor SAVE were enabled or if they failed, you can
-# try to shut down a domain by sending it a shutdown request. To do this,
-# set this to "--halt --wait". Omit the "--wait" flag to avoid waiting
-# for the domain to be really down. Leave empty to skip domain shutdown.
-#
-XENDOMAINS_SHUTDOWN="--halt --wait"
-
-## Type: string
-## Default: "--all --halt --wait"
-#
-# After we have gone over all virtual machines (resp. all automatically
-# started ones, see XENDOMAINS_AUTO_ONLY below) in a loop and sent SysRq,
-# migrated, saved and/or shutdown according to the settings above, we
-# might want to shutdown the virtual machines that are still running
-# for some reason or another. To do this, set this variable to
-# "--all --halt --wait", it will be passed to xm shutdown.
-# Leave it empty not to do anything special here.
-# (Note: This will hit all virtual machines, even if XENDOMAINS_AUTO_ONLY
-# is set.)
-#
-XENDOMAINS_SHUTDOWN_ALL="--all --halt --wait"
-
-## Type: boolean
-## Default: true
-#
-# This variable determines whether saved domains from XENDOMAINS_SAVE
-# will be restored on system startup.
-#
-XENDOMAINS_RESTORE=true
-
-## Type: string
-## Default: /etc/xen/auto
-#
-# This variable sets the directory where domains configurations
-# are stored that should be started on system startup automatically.
-# Leave empty if you don't want to start domains automatically
-# (or just don't place any xen domain config files in that dir).
-# Note that the script tries to be clever if both RESTORE and AUTO are
-# set: It will first restore saved domains and then only start domains
-# in AUTO which are not running yet.
-# Note that the name matching is somewhat fuzzy.
-#
-XENDOMAINS_AUTO=/etc/xen/auto
-
-## Type: boolean
-## Default: false
-#
-# If this variable is set to "true", only the domains started via config
-# files in XENDOMAINS_AUTO will be treated according to XENDOMAINS_SYSRQ,
-# XENDOMAINS_MIGRATE, XENDOMAINS_SAVE, XENDMAINS_SHUTDOWN; otherwise
-# all running domains will be.
-# Note that the name matching is somewhat fuzzy.
-#
-XENDOMAINS_AUTO_ONLY=false
-
-## Type: integer
-## Default: 300
-#
-# On xendomains stop, a number of xm commands (xm migrate, save, shutdown,
-# shutdown --all) may be executed. In the worst case, these commands may
-# stall forever, which will prevent a successful shutdown of the machine.
-# If this variable is non-zero, the script will set up a watchdog timer
-# for every of these xm commands and time it out after the number of seconds
-# specified by this variable.
-# Note that SHUTDOWN_ALL will not be called if no virtual machines or only
-# zombies are still running, so you don't need to enable this timeout just
-# for the zombie case.
-# The setting should be large enough to make sure that migrate/save/shutdown
-# can succeed. If you do live migrations, keep in mind that live migration
-# of a 1GB machine over Gigabit ethernet may actually take something like
-# 100s (assuming that live migration uses 10% of the network # bandwidth).
-# Depending on the virtual machine, a shutdown may also require a significant
-# amount of time. So better setup this variable to a huge number and hope the
-# watchdog never fires.
-#
-XENDOMAINS_STOP_MAXWAIT=300
-
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/init.d/xend
--- a/tools/examples/init.d/xend Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#!/bin/bash
-#
-# xend Script to start and stop the Xen control daemon.
-#
-# Author: Keir Fraser <keir.fraser@xxxxxxxxxxxx>
-#
-# chkconfig: 2345 98 01
-# description: Starts and stops the Xen control daemon.
-### BEGIN INIT INFO
-# Provides: xend
-# Required-Start: $syslog $remote_fs
-# Should-Start:
-# Required-Stop: $syslog $remote_fs
-# Should-Stop:
-# Default-Start: 3 4 5
-# Default-Stop: 0 1 2 6
-# Default-Enabled: yes
-# Short-Description: Start/stop xend
-# Description: Starts and stops the Xen control daemon.
-### END INIT INFO
-
-if ! grep -q "control_d" /proc/xen/capabilities ; then
- exit 0
-fi
-
-# Wait for Xend to be up
-function await_daemons_up
-{
- i=1
- rets=10
- xend status
- while [ $? -ne 0 -a $i -lt $rets ]; do
- sleep 1
- echo -n .
- i=$(($i + 1))
- xend status
- done
-}
-
-case "$1" in
- start)
- xend start
- await_daemons_up
- ;;
- stop)
- xend stop
- ;;
- status)
- xend status
- ;;
- reload)
- xend reload
- ;;
- restart|force-reload)
- xend restart
- await_daemons_up
- ;;
- *)
- # do not advertise unreasonable commands that there is no reason
- # to use with this device
- echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
- exit 1
-esac
-
-exit $?
-
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/init.d/xendomains
--- a/tools/examples/init.d/xendomains Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,531 +0,0 @@
-#!/bin/bash
-#
-# /etc/init.d/xendomains
-# Start / stop domains automatically when domain 0 boots / shuts down.
-#
-# chkconfig: 345 99 00
-# description: Start / stop Xen domains.
-#
-# This script offers fairly basic functionality. It should work on Redhat
-# but also on LSB-compliant SuSE releases and on Debian with the LSB package
-# installed. (LSB is the Linux Standard Base)
-#
-# Based on the example in the "Designing High Quality Integrated Linux
-# Applications HOWTO" by Avi Alkalay
-# <http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/>
-#
-### BEGIN INIT INFO
-# Provides: xendomains
-# Required-Start: $syslog $remote_fs xend
-# Should-Start:
-# Required-Stop: $syslog $remote_fs xend
-# Should-Stop:
-# Default-Start: 3 4 5
-# Default-Stop: 0 1 2 6
-# Default-Enabled: yes
-# Short-Description: Start/stop secondary xen domains
-# Description: Start / stop domains automatically when domain 0
-# boots / shuts down.
-### END INIT INFO
-
-# Correct exit code would probably be 5, but it's enough
-# if xend complains if we're not running as privileged domain
-if ! [ -e /proc/xen/privcmd ]; then
- exit 0
-fi
-
-LOCKFILE=/var/lock/subsys/xendomains
-XENDOM_CONFIG=/etc/sysconfig/xendomains
-
-test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
- if [ "$1" = "stop" ]; then exit 0;
- else exit 6; fi; }
-
-. $XENDOM_CONFIG
-
-# Use the SUSE rc_ init script functions;
-# emulate them on LSB, RH and other systems
-if test -e /etc/rc.status; then
- # SUSE rc script library
- . /etc/rc.status
-else
- _cmd=$1
- declare -a _SMSG
- if test "${_cmd}" = "status"; then
- _SMSG=(running dead dead unused unknown)
- _RC_UNUSED=3
- else
- _SMSG=(done failed failed missed failed skipped unused failed failed)
- _RC_UNUSED=6
- fi
- if test -e /etc/init.d/functions; then
- # REDHAT
- . /etc/init.d/functions
- echo_rc()
- {
- #echo -n " [${_SMSG[${_RC_RV}]}] "
- if test ${_RC_RV} = 0; then
- success " [${_SMSG[${_RC_RV}]}] "
- else
- failure " [${_SMSG[${_RC_RV}]}] "
- fi
- }
- elif test -e /lib/lsb/init-functions; then
- # LSB
- . /lib/lsb/init-functions
- if alias log_success_msg >/dev/null 2>/dev/null; then
- echo_rc()
- {
- echo " [${_SMSG[${_RC_RV}]}] "
- }
- else
- echo_rc()
- {
- if test ${_RC_RV} = 0; then
- log_success_msg " [${_SMSG[${_RC_RV}]}] "
- else
- log_failure_msg " [${_SMSG[${_RC_RV}]}] "
- fi
- }
- fi
- else
- # emulate it
- echo_rc()
- {
- echo " [${_SMSG[${_RC_RV}]}] "
- }
- fi
- rc_reset() { _RC_RV=0; }
- rc_failed()
- {
- if test -z "$1"; then
- _RC_RV=1;
- elif test "$1" != "0"; then
- _RC_RV=$1;
- fi
- return ${_RC_RV}
- }
- rc_check()
- {
- return rc_failed $?
- }
- rc_status()
- {
- rc_failed $?
- if test "$1" = "-r"; then _RC_RV=0; shift; fi
- if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
- if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed
3; shift; fi
- if test "$1" = "-v"; then echo_rc; shift; fi
- if test "$1" = "-r"; then _RC_RV=0; shift; fi
- return ${_RC_RV}
- }
- rc_exit() { exit ${_RC_RV}; }
- rc_active()
- {
- if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi
- if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi
- return 1
- }
-fi
-
-if ! which usleep >&/dev/null
-then
- usleep()
- {
- if [ -n "$1" ]
- then
- sleep $(( $1 / 1000000 ))
- fi
- }
-fi
-
-# Reset status of this service
-rc_reset
-
-##
-# Returns 0 (success) if the given parameter names a directory, and that
-# directory is not empty.
-#
-contains_something()
-{
- if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
- then
- return 0
- else
- return 1
- fi
-}
-
-# read name from xen config file
-rdname()
-{
- NM=$(xm create --quiet --dryrun --defconfig "$1" |
- sed -n 's/^.*(name \(.*\))$/\1/p')
-}
-
-rdnames()
-{
- NAMES=
- if ! contains_something "$XENDOMAINS_AUTO"
- then
- return
- fi
- for dom in $XENDOMAINS_AUTO/*; do
- rdname $dom
- if test -z $NAMES; then
- NAMES=$NM;
- else
- NAMES="$NAMES|$NM"
- fi
- done
-}
-
-parseln()
-{
- if [[ "$1" =~ "\(domain" ]]; then
- name=;id=
- else if [[ "$1" =~ "\(name" ]]; then
- name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/')
- else if [[ "$1" =~ "\(domid" ]]; then
- id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/')
- fi; fi; fi
-
- [ -n "$name" -a -n "$id" ] && return 0 || return 1
-}
-
-is_running()
-{
- rdname $1
- RC=1
- name=;id=
- while read LN; do
- parseln "$LN" || continue
- if test $id = 0; then continue; fi
- case $name in
- ($NM)
- RC=0
- ;;
- esac
- done < <(xm list -l | grep '(\(domain\|domid\|name\)')
- return $RC
-}
-
-start()
-{
- if [ -f $LOCKFILE ]; then
- echo -n "xendomains already running (lockfile exists)"
- return;
- fi
-
- saved_domains=" "
- if [ "$XENDOMAINS_RESTORE" = "true" ] &&
- contains_something "$XENDOMAINS_SAVE"
- then
- mkdir -p $(dirname "$LOCKFILE")
- touch $LOCKFILE
- echo -n "Restoring Xen domains:"
- saved_domains=`ls $XENDOMAINS_SAVE`
- for dom in $XENDOMAINS_SAVE/*; do
- if [ -f $dom ] ; then
- HEADER=`head -c 16 $dom | head -n 1 2> /dev/null`
- if [ $HEADER = "LinuxGuestRecord" ]; then
- echo -n " ${dom##*/}"
- xm restore $dom
- if [ $? -ne 0 ]; then
- rc_failed $?
- echo -n '!'
- else
- # mv $dom ${dom%/*}/.${dom##*/}
- rm $dom
- fi
- fi
- fi
- done
- echo .
- fi
-
- if contains_something "$XENDOMAINS_AUTO"
- then
- touch $LOCKFILE
- echo -n "Starting auto Xen domains:"
- # We expect config scripts for auto starting domains to be in
- # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
-
- # Create all domains with config files in XENDOMAINS_AUTO.
- # TODO: We should record which domain name belongs
- # so we have the option to selectively shut down / migrate later
- # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
- # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
- # restore correctly it requires administrative attention.
- for dom in $XENDOMAINS_AUTO/*; do
- echo -n " ${dom##*/}"
- shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
- echo $saved_domains | grep -w $shortdom > /dev/null
- if [ $? -eq 0 ] || is_running $dom; then
- echo -n "(skip)"
- else
- xm create --quiet --defconfig $dom
- if [ $? -ne 0 ]; then
- rc_failed $?
- echo -n '!'
- else
- usleep $XENDOMAINS_CREATE_USLEEP
- fi
- fi
- done
- fi
-}
-
-all_zombies()
-{
- name=;id=
- while read LN; do
- parseln "$LN" || continue
- if test $id = 0; then continue; fi
- if test "$state" != "-b---d" -a "$state" != "-----d"; then
- return 1;
- fi
- done < <(xm list -l | grep '(\(domain\|domid\|name\)')
- return 0
-}
-
-# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
-# if it has not exited by that time kill it, so the init script will
-# succeed within a finite amount of time; if $2 is nonnull, it will
-# kill the command as well as soon as no domain (except for zombies)
-# are left (used for shutdown --all).
-watchdog_xm()
-{
- if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0";
then
- exit
- fi
- usleep 20000
- for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
- # exit if xm save/migrate/shutdown is finished
- PSAX=`ps axlw | grep "xm $1" | grep -v grep`
- if test -z "$PSAX"; then exit; fi
- echo -n "."; sleep 1
- # go to kill immediately if there's only zombies left
- if all_zombies && test -n "$2"; then break; fi
- done
- sleep 1
- read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
- # kill xm $1
- kill $PSPID >/dev/null 2>&1
-}
-
-stop()
-{
- # Collect list of domains to shut down
- if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
- rdnames
- fi
- echo -n "Shutting down Xen domains:"
- name=;id=
- while read LN; do
- parseln "$LN" || continue
- if test $id = 0; then continue; fi
- echo -n " $name"
- if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
- eval "
- case \"\$name\" in
- ($NAMES)
- # nothing
- ;;
- (*)
- echo -n '(skip)'
- continue
- ;;
- esac
- "
- fi
- # XENDOMAINS_SYSRQ chould be something like just "s"
- # or "s e i u" or even "s e s i u o"
- # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
- if test -n "$XENDOMAINS_SYSRQ"; then
- for sysrq in $XENDOMAINS_SYSRQ; do
- echo -n "(SR-$sysrq)"
- xm sysrq $id $sysrq
- if test $? -ne 0; then
- rc_failed $?
- echo -n '!'
- fi
- # usleep just ignores empty arg
- usleep $XENDOMAINS_USLEEP
- done
- fi
- if test "$state" = "-b---d" -o "$state" = "-----d"; then
- echo -n "(zomb)"
- continue
- fi
- if test -n "$XENDOMAINS_MIGRATE"; then
- echo -n "(migr)"
- watchdog_xm migrate &
- WDOG_PID=$!
- xm migrate $id $XENDOMAINS_MIGRATE
- if test $? -ne 0; then
- rc_failed $?
- echo -n '!'
- kill $WDOG_PID >/dev/null 2>&1
- else
- kill $WDOG_PID >/dev/null 2>&1
- continue
- fi
- fi
- if test -n "$XENDOMAINS_SAVE"; then
- echo -n "(save)"
- watchdog_xm save &
- WDOG_PID=$!
- mkdir -p "$XENDOMAINS_SAVE"
- xm save $id $XENDOMAINS_SAVE/$name
- if test $? -ne 0; then
- rc_failed $?
- echo -n '!'
- kill $WDOG_PID >/dev/null 2>&1
- else
- kill $WDOG_PID >/dev/null 2>&1
- continue
- fi
- fi
- if test -n "$XENDOMAINS_SHUTDOWN"; then
- # XENDOMAINS_SHUTDOWN should be "--halt --wait"
- echo -n "(shut)"
- watchdog_xm shutdown &
- WDOG_PID=$!
- xm shutdown $id $XENDOMAINS_SHUTDOWN
- if test $? -ne 0; then
- rc_failed $?
- echo -n '!'
- fi
- kill $WDOG_PID >/dev/null 2>&1
- fi
- done < <(xm list -l | grep '(\(domain\|domid\|name\)')
-
- # NB. this shuts down ALL Xen domains (politely), not just the ones in
- # AUTODIR/*
- # This is because it's easier to do ;-) but arguably if this script is run
- # on system shutdown then it's also the right thing to do.
- if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
- # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
- echo -n " SHUTDOWN_ALL "
- watchdog_xm shutdown 1 &
- WDOG_PID=$!
- xm shutdown $XENDOMAINS_SHUTDOWN_ALL
- if test $? -ne 0; then
- rc_failed $?
- echo -n '!'
- fi
- kill $WDOG_PID >/dev/null 2>&1
- fi
-
- # Unconditionally delete lock file
- rm -f $LOCKFILE
-}
-
-check_domain_up()
-{
- name=;id=
- while read LN; do
- parseln "$LN" || continue
- if test $id = 0; then continue; fi
- case $name in
- ($1)
- return 0
- ;;
- esac
- done < <(xm list -l | grep '(\(domain\|domid\|name\)')
- return 1
-}
-
-check_all_auto_domains_up()
-{
- if ! contains_something "$XENDOMAINS_AUTO"
- then
- return 0
- fi
- missing=
- for nm in $XENDOMAINS_AUTO/*; do
- rdname $nm
- found=0
- if check_domain_up "$NM"; then
- echo -n " $name"
- else
- missing="$missing $NM"
- fi
- done
- if test -n "$missing"; then
- echo -n " MISS AUTO:$missing"
- return 1
- fi
- return 0
-}
-
-check_all_saved_domains_up()
-{
- if ! contains_something "$XENDOMAINS_SAVE"
- then
- return 0
- fi
- missing=`/bin/ls $XENDOMAINS_SAVE`
- echo -n " MISS SAVED: " $missing
- return 1
-}
-
-# This does NOT necessarily restart all running domains: instead it
-# stops all running domains and then boots all the domains specified in
-# AUTODIR. If other domains have been started manually then they will
-# not get restarted.
-# Commented out to avoid confusion!
-
-restart()
-{
- stop
- start
-}
-
-reload()
-{
- restart
-}
-
-
-case "$1" in
- start)
- start
- rc_status
- if test -f $LOCKFILE; then rc_status -v; fi
- ;;
-
- stop)
- stop
- rc_status -v
- ;;
-
- restart)
- restart
- ;;
- reload)
- reload
- ;;
-
- status)
- echo -n "Checking for xendomains:"
- if test ! -f $LOCKFILE; then
- rc_failed 3
- else
- check_all_auto_domains_up
- rc_status
- check_all_saved_domains_up
- rc_status
- fi
- rc_status -v
- ;;
-
- *)
- echo "Usage: $0 {start|stop|restart|reload|status}"
- rc_failed 3
- rc_status -v
- ;;
-esac
-
-rc_exit
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/locking.sh
--- a/tools/examples/locking.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/logging.sh
--- a/tools/examples/logging.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/network-bridge
--- a/tools/examples/network-bridge Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-#!/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 ! 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
-}
-
-# 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
-
- create_bridge ${tdev}
-
- preiftransfer ${netdev}
- transfer_addrs ${netdev} ${tdev}
- if ! ifdown ${netdev}; then
- # If ifdown fails, remember the IP details.
- get_ip_info ${netdev}
- ip link set ${netdev} down
- ip addr flush ${netdev}
- fi
- ip link set ${netdev} name ${pdev}
- ip link set ${tdev} name ${bridge}
-
- setup_bridge_port ${pdev}
-
- add_to_bridge2 ${bridge} ${pdev}
- do_ifup ${bridge}
-
- if [ ${antispoof} = 'yes' ] ; then
- antispoofing
- fi
-}
-
-op_stop () {
- if [ "${bridge}" = "null" ]; then
- return
- fi
- if ! link_exists "$bridge"; then
- return
- fi
-
- transfer_addrs ${bridge} ${pdev}
- if ! ifdown ${bridge}; then
- get_ip_info ${bridge}
- fi
- ip link set ${pdev} down
- ip addr flush ${bridge}
-
- brctl delif ${bridge} ${pdev}
- ip link set ${bridge} down
-
- ip link set ${bridge} name ${tdev}
- ip link set ${pdev} name ${netdev}
- do_ifup ${netdev}
-
- brctl delbr ${tdev}
-}
-
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/network-nat
--- a/tools/examples/network-nat Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-#!/bin/bash -x
-#============================================================================
-# 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
-
-
-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 {}"
- 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
- [ "$dhcp" != 'no' ] && dhcp_start
-}
-
-
-op_stop() {
- [ "$dhcp" != 'no' ] && dhcp_stop
- iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
-}
-
-
-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 -r 7ef733b961c8 -r 436816898c87 tools/examples/network-route
--- a/tools/examples/network-route Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/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:-eth${vifnum}}
-
-echo 1 >/proc/sys/net/ipv4/ip_forward
-echo 1 >/proc/sys/net/ipv4/conf/${netdev}/proxy_arp
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/vif-bridge
--- a/tools/examples/vif-bridge Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vif-common.sh
--- a/tools/examples/vif-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-#
-# 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="-A"
- else
- local c="-D"
- fi
-
- iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT \
- 2>/dev/null ||
- [ "$c" == "-D" ] ||
- log err \
- "iptables $c FORWARD -m physdev --physdev-in $vif $@ -j ACCEPT failed.
-If you are using iptables, this may affect networking for guest domains."
-}
-
-
-##
-# 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
-
- 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
-}
-
-
-##
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vif-nat
--- a/tools/examples/vif-nat Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vif-route
--- a/tools/examples/vif-route Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vscsi
--- a/tools/examples/vscsi Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm
--- a/tools/examples/vtpm Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,448 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm-delete
--- a/tools/examples/vtpm-delete Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm-hotplug-common.sh
--- a/tools/examples/vtpm-hotplug-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm-impl
--- a/tools/examples/vtpm-impl Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-#!/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 -r 7ef733b961c8 -r 436816898c87 tools/examples/vtpm-migration.sh
--- a/tools/examples/vtpm-migration.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#! /bin/bash
-
-PATH=/etc/xen/scripts:$PATH
-
-. /etc/xen/scripts/locking.sh
-
-claim_lock xenbus_hotplug_global
-
-case "$XENBUS_TYPE" in
- tap)
- /etc/xen/scripts/blktap "$ACTION"
- ;;
- vbd)
- /etc/xen/scripts/block "$ACTION"
- ;;
- vtpm)
- /etc/xen/scripts/vtpm "$ACTION"
- ;;
- vif)
- [ -n "$script" ] && $script "$ACTION"
- ;;
- vscsi)
- /etc/xen/scripts/vscsi "$ACTION"
- ;;
-esac
-
-case "$ACTION" in
- add)
- ;;
- remove)
- /etc/xen/scripts/xen-hotplug-cleanup
- ;;
- online)
- ;;
- offline)
- ;;
-esac
-
-release_lock xenbus_hotplug_global
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap
$env{ACTION}"
-SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block
$env{ACTION}"
-SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm
$env{ACTION}"
-SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script}
online"
-SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline",
RUN+="$env{script} offline"
-SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi
$env{ACTION}"
-SUBSYSTEM=="xen-backend", ACTION=="remove",
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
-KERNEL=="evtchn", NAME="xen/%k"
-KERNEL=="blktap[0-9]*", NAME="xen/%k"
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-hotplug-cleanup
--- a/tools/examples/xen-hotplug-cleanup Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#! /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"
-
-# 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
-
-release_lock "block"
diff -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-hotplug-common.sh
--- a/tools/examples/xen-hotplug-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-network-common.sh
--- a/tools/examples/xen-network-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/examples/xen-script-common.sh
--- a/tools/examples/xen-script-common.sh Tue Nov 18 10:55:51 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#
-# 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 -r 7ef733b961c8 -r 436816898c87 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/firmware/hvmloader/config.h Tue Nov 25 14:21:24 2008 +0900
@@ -23,7 +23,6 @@
/* Memory map. */
#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
-#define ETHERBOOT_PHYSICAL_ADDRESS 0x000D0000
#define SMBIOS_PHYSICAL_ADDRESS 0x000E9000
#define SMBIOS_MAXIMUM_SIZE 0x00001000
#define ACPI_PHYSICAL_ADDRESS 0x000EA000
diff -r 7ef733b961c8 -r 436816898c87 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c Tue Nov 25 14:21:24 2008 +0900
@@ -322,60 +322,56 @@ static void pci_setup(void)
}
/*
- * Scan the PCI bus for the first NIC supported by etherboot, and copy
- * the corresponding rom data to *copy_rom_dest. Returns the length of the
- * selected rom, or 0 if no NIC found.
+ * Scan the list of Option ROMs at @roms for one which supports
+ * PCI (@vendor_id, @device_id) found at slot @devfn. If one is found,
+ * copy it to @dest and return its size rounded up to a multiple 2kB. This
+ * function will not copy ROMs beyond address 0xE0000.
*/
-static int scan_etherboot_nic(void *copy_rom_dest)
+#define round_option_rom(x) (((x) + 2047) & ~2047)
+static int scan_option_rom(
+ uint8_t devfn, uint16_t vendor_id, uint16_t device_id,
+ void *roms, uint32_t dest)
{
struct option_rom_header *rom;
struct option_rom_pnp_header *pnph;
struct option_rom_pci_header *pcih;
- uint32_t devfn;
- uint16_t class, vendor_id, device_id;
uint8_t csum;
int i;
- for ( devfn = 0; devfn < 128; devfn++ )
- {
- class = pci_readw(devfn, PCI_CLASS_DEVICE);
- vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
- device_id = pci_readw(devfn, PCI_DEVICE_ID);
-
- if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
- continue;
-
- /* We're only interested in NICs. */
- if ( class != 0x0200 )
- continue;
-
- rom = (struct option_rom_header *)etherboot;
- for ( ; ; )
- {
- /* Invalid signature means we're out of option ROMs. */
- if ( strncmp((char *)rom->signature, "\x55\xaa", 2) ||
- (rom->rom_size == 0) )
- break;
-
- /* Invalid checksum means we're out of option ROMs. */
- csum = 0;
- for ( i = 0; i < (rom->rom_size * 512); i++ )
- csum += ((uint8_t *)rom)[i];
- if ( csum != 0 )
- break;
-
- /* Check the PCI PnP header (if any) for a match. */
- pcih = (struct option_rom_pci_header *)
- ((char *)rom + rom->pci_header_offset);
- if ( (rom->pci_header_offset != 0) &&
- !strncmp((char *)pcih->signature, "PCIR", 4) &&
- (pcih->vendor_id == vendor_id) &&
- (pcih->device_id == device_id) )
- goto found;
-
- rom = (struct option_rom_header *)
- ((char *)rom + rom->rom_size * 512);
- }
+ static uint32_t orom_ids[64];
+ static int nr_roms;
+
+ /* Avoid duplicate ROMs. */
+ for ( i = 0; i < nr_roms; i++ )
+ if ( orom_ids[i] == (vendor_id | ((uint32_t)device_id << 16)) )
+ return 0;
+
+ rom = roms;
+ for ( ; ; )
+ {
+ /* Invalid signature means we're out of option ROMs. */
+ if ( strncmp((char *)rom->signature, "\x55\xaa", 2) ||
+ (rom->rom_size == 0) )
+ break;
+
+ /* Invalid checksum means we're out of option ROMs. */
+ csum = 0;
+ for ( i = 0; i < (rom->rom_size * 512); i++ )
+ csum += ((uint8_t *)rom)[i];
+ if ( csum != 0 )
+ break;
+
+ /* Check the PCI PnP header (if any) for a match. */
+ pcih = (struct option_rom_pci_header *)
+ ((char *)rom + rom->pci_header_offset);
+ if ( (rom->pci_header_offset != 0) &&
+ !strncmp((char *)pcih->signature, "PCIR", 4) &&
+ (pcih->vendor_id == vendor_id) &&
+ (pcih->device_id == device_id) )
+ goto found;
+
+ rom = (struct option_rom_header *)
+ ((char *)rom + rom->rom_size * 512);
}
return 0;
@@ -392,15 +388,96 @@ static int scan_etherboot_nic(void *copy
((char *)rom + pnph->next_header_offset))
: ((struct option_rom_pnp_header *)NULL));
- printf("Loading PXE ROM ...\n");
+ printf("Loading PCI Option ROM ...\n");
if ( (pnph != NULL) && (pnph->manufacturer_name_offset != 0) )
printf(" - Manufacturer: %s\n",
(char *)rom + pnph->manufacturer_name_offset);
if ( (pnph != NULL) && (pnph->product_name_offset != 0) )
printf(" - Product name: %s\n",
(char *)rom + pnph->product_name_offset);
- memcpy(copy_rom_dest, rom, rom->rom_size * 512);
- return rom->rom_size * 512;
+
+ if ( (dest + rom->rom_size * 512 + 1) > 0xe0000u )
+ {
+ printf("Option ROM size %x exceeds available space\n",
+ rom->rom_size * 512);
+ return 0;
+ }
+
+ orom_ids[nr_roms++] = vendor_id | ((uint32_t)device_id << 16);
+ memcpy((void *)dest, rom, rom->rom_size * 512);
+ *(uint8_t *)(dest + rom->rom_size * 512) = devfn;
+ return round_option_rom(rom->rom_size * 512 + 1);
+}
+
+/*
+ * Scan the PCI bus for the first NIC supported by etherboot, and copy
+ * the corresponding rom data to *copy_rom_dest. Returns the length of the
+ * selected rom, or 0 if no NIC found.
+ */
+static int scan_etherboot_nic(uint32_t copy_rom_dest)
+{
+ uint8_t devfn;
+ uint16_t class, vendor_id, device_id;
+
+ for ( devfn = 0; devfn < 128; devfn++ )
+ {
+ class = pci_readw(devfn, PCI_CLASS_DEVICE);
+ vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
+ device_id = pci_readw(devfn, PCI_DEVICE_ID);
+
+ /* We're only interested in NICs. */
+ if ( (vendor_id != 0xffff) &&
+ (device_id != 0xffff) &&
+ (class == 0x0200) )
+ return scan_option_rom(
+ devfn, vendor_id, device_id, etherboot, copy_rom_dest);
+ }
+
+ return 0;
+}
+
+/*
+ * Scan the PCI bus for the devices that have an option ROM, and copy
+ * the corresponding rom data to rom_phys_addr.
+ */
+static int pci_load_option_roms(uint32_t rom_base_addr)
+{
+ uint32_t option_rom_addr, rom_phys_addr = rom_base_addr;
+ uint16_t vendor_id, device_id;
+ uint8_t devfn, class;
+
+ for ( devfn = 0; devfn < 128; devfn++ )
+ {
+ class = pci_readb(devfn, PCI_CLASS_DEVICE + 1);
+ vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
+ device_id = pci_readw(devfn, PCI_DEVICE_ID);
+
+ if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
+ continue;
+
+ /*
+ * Currently only scan options from mass storage devices and serial
+ * bus controller (Fibre Channel included).
+ */
+ if ( (class != 0x1) && (class != 0xc) )
+ continue;
+
+ option_rom_addr = pci_readl(devfn, PCI_ROM_ADDRESS);
+ if ( !option_rom_addr )
+ continue;
+
+ /* Ensure Expansion Bar is enabled before copying */
+ pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr | 0x1);
+
+ rom_phys_addr += scan_option_rom(
+ devfn, vendor_id, device_id,
+ (void *)(option_rom_addr & ~2047), rom_phys_addr);
+
+ /* Restore the default original value of Expansion Bar */
+ pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr);
+ }
+
+ return rom_phys_addr - rom_base_addr;
}
/* Replace possibly erroneous memory-size CMOS fields with correct values. */
@@ -461,8 +538,9 @@ static uint16_t init_xen_platform_io_bas
int main(void)
{
- int vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
- uint32_t vga_ram = 0;
+ int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0;
+ int rombios_sz, smbios_sz;
+ uint32_t etherboot_phys_addr, option_rom_phys_addr, vga_ram = 0;
uint16_t xen_pfiob;
printf("HVM Loader\n");
@@ -497,13 +575,13 @@ int main(void)
printf("Loading Cirrus VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_cirrusvga, sizeof(vgabios_cirrusvga));
- vgabios_sz = sizeof(vgabios_cirrusvga);
+ vgabios_sz = round_option_rom(sizeof(vgabios_cirrusvga));
break;
case VGA_std:
printf("Loading Standard VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
vgabios_stdvga, sizeof(vgabios_stdvga));
- vgabios_sz = sizeof(vgabios_stdvga);
+ vgabios_sz = round_option_rom(sizeof(vgabios_stdvga));
break;
default:
printf("No emulated VGA adaptor ...\n");
@@ -516,7 +594,11 @@ int main(void)
printf("VGA RAM at %08x\n", vga_ram);
}
- etherboot_sz = scan_etherboot_nic((void*)ETHERBOOT_PHYSICAL_ADDRESS);
+ etherboot_phys_addr = VGABIOS_PHYSICAL_ADDRESS + vgabios_sz;
+ etherboot_sz = scan_etherboot_nic(etherboot_phys_addr);
+
+ option_rom_phys_addr = etherboot_phys_addr + etherboot_sz;
+ option_rom_sz = pci_load_option_roms(option_rom_phys_addr);
if ( get_acpi_enabled() )
{
@@ -533,8 +615,12 @@ int main(void)
VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1);
if ( etherboot_sz )
printf(" %05x-%05x: Etherboot ROM\n",
- ETHERBOOT_PHYSICAL_ADDRESS,
- ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1);
+ etherboot_phys_addr,
+ etherboot_phys_addr + etherboot_sz - 1);
+ if ( option_rom_sz )
+ printf(" %05x-%05x: PCI Option ROMs\n",
+ option_rom_phys_addr,
+ option_rom_phys_addr + option_rom_sz - 1);
if ( smbios_sz )
printf(" %05x-%05x: SMBIOS tables\n",
SMBIOS_PHYSICAL_ADDRESS,
diff -r 7ef733b961c8 -r 436816898c87 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/firmware/rombios/rombios.c Tue Nov 25 14:21:24 2008 +0900
@@ -9677,19 +9677,34 @@ block_count_rounded:
pop ds
pop ax
#endif
- xor bx, bx ;; Restore DS back to 0000:
- mov ds, bx
push ax ;; Save AX
push di ;; Save DI
;; Push addr of ROM entry point
push cx ;; Push seg
push #0x0003 ;; Push offset
+ ;; Get the BDF into ax before invoking the option ROM
+ mov bl, [2]
+ mov al, bl
+ shr al, #7
+ cmp al, #1
+ jne fetch_bdf
+ mov ax, ds ;; Increment the DS since rom size larger than an segment
+ add ax, #0x1000
+ mov ds, ax
+fetch_bdf:
+ shl bx, #9
+ xor ax, ax
+ mov al, [bx]
+
;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.
;; That should stop it grabbing INT 19h; we will use its BEV instead.
- mov ax, #0xf000
- mov es, ax
+ mov bx, #0xf000
+ mov es, bx
lea di, pnp_string
+
+ xor bx, bx ;; Restore DS back to 0000:
+ mov ds, bx
mov bp, sp ;; Call ROM init routine using seg:off on stack
db 0xff ;; call_far ss:[bp+0]
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,97 @@
+XEN_ROOT = ../../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Init scripts.
+XEND_INITD = init.d/xend
+XENDOMAINS_INITD = init.d/xendomains
+XENDOMAINS_SYSCONFIG = init.d/sysconfig.xendomains
+
+# Xen configuration dir and configs to go there.
+XEN_CONFIG_DIR = /etc/xen
+
+# Xen script dir and scripts to go there.
+XEN_SCRIPT_DIR = /etc/xen/scripts
+XEN_SCRIPTS = network-bridge vif-bridge
+XEN_SCRIPTS += network-route vif-route
+XEN_SCRIPTS += network-nat vif-nat
+XEN_SCRIPTS += block
+XEN_SCRIPTS += block-enbd block-nbd
+XEN_SCRIPTS += blktap
+XEN_SCRIPTS += vtpm vtpm-delete
+XEN_SCRIPTS += xen-hotplug-cleanup
+XEN_SCRIPTS += external-device-migrate
+XEN_SCRIPTS += vscsi
+XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
+XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
+XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
+XEN_SCRIPT_DATA += vtpm-migration.sh vtpm-impl
+
+XEN_HOTPLUG_DIR = /etc/hotplug
+XEN_HOTPLUG_SCRIPTS = xen-backend.agent
+
+UDEV_RULES_DIR = /etc/udev
+UDEV_RULES = xen-backend.rules
+
+DI = $(if $(DISTDIR),$(shell readlink -f $(DISTDIR)),)
+DE = $(if $(DESTDIR),$(shell readlink -f $(DESTDIR)),)
+ifeq ($(findstring $(DI),$(DE)),$(DI))
+HOTPLUGS=install-hotplug install-udev
+else
+ifeq ($(shell [ -x /usr/bin/udevinfo ] && [ `/usr/bin/udevinfo -V | sed -e
's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/'` -ge 059 ] && echo 1),1)
+HOTPLUGS=install-udev
+else
+HOTPLUGS=install-hotplug
+endif
+endif
+
+.PHONY: all
+all:
+
+.PHONY: build
+build:
+
+.PHONY: install
+install: all install-initd install-scripts $(HOTPLUGS)
+
+.PHONY: install-initd
+install-initd:
+ [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
+ [ -d $(DESTDIR)/etc/sysconfig ] || $(INSTALL_DIR)
$(DESTDIR)/etc/sysconfig
+ $(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
+ $(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
+ $(INSTALL_PROG) $(XENDOMAINS_SYSCONFIG)
$(DESTDIR)/etc/sysconfig/xendomains
+
+.PHONY: install-scripts
+install-scripts:
+ [ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \
+ $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
+ set -e; for i in $(XEN_SCRIPTS); \
+ do \
+ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+ set -e; for i in $(XEN_SCRIPT_DATA); \
+ do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+
+.PHONY: install-hotplug
+install-hotplug:
+ [ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \
+ $(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR)
+ set -e; for i in $(XEN_HOTPLUG_SCRIPTS); \
+ do \
+ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_HOTPLUG_DIR); \
+ done
+
+.PHONY: install-udev
+install-udev:
+ [ -d $(DESTDIR)$(UDEV_RULES_DIR) ] || \
+ $(INSTALL_DIR) $(DESTDIR)$(UDEV_RULES_DIR)/rules.d
+ set -e; for i in $(UDEV_RULES); \
+ do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(UDEV_RULES_DIR); \
+ ln -sf ../$$i $(DESTDIR)$(UDEV_RULES_DIR)/rules.d; \
+ done
+
+.PHONY: clean
+clean:
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/blktap
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/blktap Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/block
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/block Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,381 @@
+#!/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
+
+ case $t in
+ phy)
+ dev=$(expand_dev $p)
+ FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
+ FRONTEND_UUID=$(xenstore_read_default \
+ "/local/domain/$FRONTEND_ID/vm" 'unknown')
+
+ 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)
+ # 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")
+
+ 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
+
+ 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
+
+ if LANG=C losetup -h 2>&1 | grep read-only >/dev/null
+ then
+ roflag="-$mode"; roflag="${roflag#-w}"; roflag="${roflag#-!}"
+ else
+ roflag=''
+ fi
+ do_or_die losetup $roflag "$loopdev" "$file"
+ 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")
+ losetup -d "$node"
+ exit 0
+ ;;
+
+ "")
+ 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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/block-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/block-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,116 @@
+#
+# 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")
+
+ [ "$FRONTEND_UUID" = "$othervm" ]
+}
+
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/block-enbd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/block-enbd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Usage: block-enbd [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"
+
+case "$command" in
+ add)
+ for dev in /dev/nd*; do
+ if nbd-client $2:$3 $dev; then
+ write_dev $dev
+ exit 0
+ fi
+ done
+ exit 1
+ ;;
+ remove)
+ nbd-client -d $2
+ exit 0
+ ;;
+esac
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/block-nbd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/block-nbd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# 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"
+
+case "$command" in
+ add)
+ for dev in /dev/nbd*; do
+ if nbd-client $2 $3 $dev; then
+ write_dev $dev
+ exit 0
+ fi
+ done
+ exit 1
+ ;;
+ remove)
+ nbd-client -d $2
+ exit 0
+ ;;
+esac
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/external-device-migrate
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/external-device-migrate Tue Nov 25 14:21:24
2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87
tools/hotplug/Linux/init.d/sysconfig.xendomains
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/init.d/sysconfig.xendomains Tue Nov 25 14:21:24
2008 +0900
@@ -0,0 +1,137 @@
+## Path: System/xen
+## Description: xen domain start/stop on boot
+## Type: string
+## Default:
+#
+# The xendomains script can send SysRq requests to domains on shutdown.
+# If you don't want to MIGRATE, SAVE, or SHUTDOWN, this may be a possibility
+# to do a quick and dirty shutdown ("s e i u o") or at least sync the disks
+# of the domains ("s").
+#
+XENDOMAINS_SYSRQ=""
+
+## Type: integer
+## Default: 100000
+#
+# If XENDOMAINS_SYSRQ is set, this variable determines how long to wait
+# (in microseconds) after each SysRq, so the domain has a chance to react.
+# If you want to a quick'n'dirty shutdown via SysRq, you may want to set
+# it to a relatively high value (1200000).
+#
+XENDOMAINS_USLEEP=100000
+
+## Type: integer
+## Default: 5000000
+#
+# When creating a guest domain, it is sensible to allow a little time for it
+# to get started before creating another domain or proceeding through the
+# boot process. Without this, the booting guests will thrash the disk as they
+# start up. This timeout (in microseconds) specifies the delay after guest
+# domain creation.
+#
+XENDOMAINS_CREATE_USLEEP=5000000
+
+## Type: string
+## Default: ""
+#
+# Set this to a non-empty string if you want to migrate virtual machines
+# on shutdown. The string will be passed to the xm migrate DOMID command
+# as is: It should contain the target IP address of the physical machine
+# to migrate to and optionally parameters like --live. Leave empty if
+# you don't want to try virtual machine relocation on shutdown.
+# If migration succeeds, neither SAVE nor SHUTDOWN will be executed for
+# that domain.
+#
+XENDOMAINS_MIGRATE=""
+
+## Type: string
+## Default: /var/lib/xen/save
+#
+# Directory to save running domains to when the system (dom0) is
+# shut down. Will also be used to restore domains from if # XENDOMAINS_RESTORE
+# is set (see below). Leave empty to disable domain saving on shutdown
+# (e.g. because you rather shut domains down).
+# If domain saving does succeed, SHUTDOWN will not be executed.
+#
+XENDOMAINS_SAVE=/var/lib/xen/save
+
+## Type: string
+## Default: "--halt --wait"
+#
+# If neither MIGRATE nor SAVE were enabled or if they failed, you can
+# try to shut down a domain by sending it a shutdown request. To do this,
+# set this to "--halt --wait". Omit the "--wait" flag to avoid waiting
+# for the domain to be really down. Leave empty to skip domain shutdown.
+#
+XENDOMAINS_SHUTDOWN="--halt --wait"
+
+## Type: string
+## Default: "--all --halt --wait"
+#
+# After we have gone over all virtual machines (resp. all automatically
+# started ones, see XENDOMAINS_AUTO_ONLY below) in a loop and sent SysRq,
+# migrated, saved and/or shutdown according to the settings above, we
+# might want to shutdown the virtual machines that are still running
+# for some reason or another. To do this, set this variable to
+# "--all --halt --wait", it will be passed to xm shutdown.
+# Leave it empty not to do anything special here.
+# (Note: This will hit all virtual machines, even if XENDOMAINS_AUTO_ONLY
+# is set.)
+#
+XENDOMAINS_SHUTDOWN_ALL="--all --halt --wait"
+
+## Type: boolean
+## Default: true
+#
+# This variable determines whether saved domains from XENDOMAINS_SAVE
+# will be restored on system startup.
+#
+XENDOMAINS_RESTORE=true
+
+## Type: string
+## Default: /etc/xen/auto
+#
+# This variable sets the directory where domains configurations
+# are stored that should be started on system startup automatically.
+# Leave empty if you don't want to start domains automatically
+# (or just don't place any xen domain config files in that dir).
+# Note that the script tries to be clever if both RESTORE and AUTO are
+# set: It will first restore saved domains and then only start domains
+# in AUTO which are not running yet.
+# Note that the name matching is somewhat fuzzy.
+#
+XENDOMAINS_AUTO=/etc/xen/auto
+
+## Type: boolean
+## Default: false
+#
+# If this variable is set to "true", only the domains started via config
+# files in XENDOMAINS_AUTO will be treated according to XENDOMAINS_SYSRQ,
+# XENDOMAINS_MIGRATE, XENDOMAINS_SAVE, XENDMAINS_SHUTDOWN; otherwise
+# all running domains will be.
+# Note that the name matching is somewhat fuzzy.
+#
+XENDOMAINS_AUTO_ONLY=false
+
+## Type: integer
+## Default: 300
+#
+# On xendomains stop, a number of xm commands (xm migrate, save, shutdown,
+# shutdown --all) may be executed. In the worst case, these commands may
+# stall forever, which will prevent a successful shutdown of the machine.
+# If this variable is non-zero, the script will set up a watchdog timer
+# for every of these xm commands and time it out after the number of seconds
+# specified by this variable.
+# Note that SHUTDOWN_ALL will not be called if no virtual machines or only
+# zombies are still running, so you don't need to enable this timeout just
+# for the zombie case.
+# The setting should be large enough to make sure that migrate/save/shutdown
+# can succeed. If you do live migrations, keep in mind that live migration
+# of a 1GB machine over Gigabit ethernet may actually take something like
+# 100s (assuming that live migration uses 10% of the network # bandwidth).
+# Depending on the virtual machine, a shutdown may also require a significant
+# amount of time. So better setup this variable to a huge number and hope the
+# watchdog never fires.
+#
+XENDOMAINS_STOP_MAXWAIT=300
+
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/init.d/xend
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/init.d/xend Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# xend Script to start and stop the Xen control daemon.
+#
+# Author: Keir Fraser <keir.fraser@xxxxxxxxxxxx>
+#
+# chkconfig: 2345 98 01
+# description: Starts and stops the Xen control daemon.
+### BEGIN INIT INFO
+# Provides: xend
+# Required-Start: $syslog $remote_fs
+# Should-Start:
+# Required-Stop: $syslog $remote_fs
+# Should-Stop:
+# Default-Start: 3 4 5
+# Default-Stop: 0 1 2 6
+# Default-Enabled: yes
+# Short-Description: Start/stop xend
+# Description: Starts and stops the Xen control daemon.
+### END INIT INFO
+
+if ! grep -q "control_d" /proc/xen/capabilities ; then
+ exit 0
+fi
+
+# Wait for Xend to be up
+function await_daemons_up
+{
+ i=1
+ rets=10
+ xend status
+ while [ $? -ne 0 -a $i -lt $rets ]; do
+ sleep 1
+ echo -n .
+ i=$(($i + 1))
+ xend status
+ done
+}
+
+case "$1" in
+ start)
+ xend start
+ await_daemons_up
+ ;;
+ stop)
+ xend stop
+ ;;
+ status)
+ xend status
+ ;;
+ reload)
+ xend reload
+ ;;
+ restart|force-reload)
+ xend restart
+ await_daemons_up
+ ;;
+ *)
+ # do not advertise unreasonable commands that there is no reason
+ # to use with this device
+ echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
+ exit 1
+esac
+
+exit $?
+
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/init.d/xendomains
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/init.d/xendomains Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,531 @@
+#!/bin/bash
+#
+# /etc/init.d/xendomains
+# Start / stop domains automatically when domain 0 boots / shuts down.
+#
+# chkconfig: 345 99 00
+# description: Start / stop Xen domains.
+#
+# This script offers fairly basic functionality. It should work on Redhat
+# but also on LSB-compliant SuSE releases and on Debian with the LSB package
+# installed. (LSB is the Linux Standard Base)
+#
+# Based on the example in the "Designing High Quality Integrated Linux
+# Applications HOWTO" by Avi Alkalay
+# <http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/>
+#
+### BEGIN INIT INFO
+# Provides: xendomains
+# Required-Start: $syslog $remote_fs xend
+# Should-Start:
+# Required-Stop: $syslog $remote_fs xend
+# Should-Stop:
+# Default-Start: 3 4 5
+# Default-Stop: 0 1 2 6
+# Default-Enabled: yes
+# Short-Description: Start/stop secondary xen domains
+# Description: Start / stop domains automatically when domain 0
+# boots / shuts down.
+### END INIT INFO
+
+# Correct exit code would probably be 5, but it's enough
+# if xend complains if we're not running as privileged domain
+if ! [ -e /proc/xen/privcmd ]; then
+ exit 0
+fi
+
+LOCKFILE=/var/lock/subsys/xendomains
+XENDOM_CONFIG=/etc/sysconfig/xendomains
+
+test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
+ if [ "$1" = "stop" ]; then exit 0;
+ else exit 6; fi; }
+
+. $XENDOM_CONFIG
+
+# Use the SUSE rc_ init script functions;
+# emulate them on LSB, RH and other systems
+if test -e /etc/rc.status; then
+ # SUSE rc script library
+ . /etc/rc.status
+else
+ _cmd=$1
+ declare -a _SMSG
+ if test "${_cmd}" = "status"; then
+ _SMSG=(running dead dead unused unknown)
+ _RC_UNUSED=3
+ else
+ _SMSG=(done failed failed missed failed skipped unused failed failed)
+ _RC_UNUSED=6
+ fi
+ if test -e /etc/init.d/functions; then
+ # REDHAT
+ . /etc/init.d/functions
+ echo_rc()
+ {
+ #echo -n " [${_SMSG[${_RC_RV}]}] "
+ if test ${_RC_RV} = 0; then
+ success " [${_SMSG[${_RC_RV}]}] "
+ else
+ failure " [${_SMSG[${_RC_RV}]}] "
+ fi
+ }
+ elif test -e /lib/lsb/init-functions; then
+ # LSB
+ . /lib/lsb/init-functions
+ if alias log_success_msg >/dev/null 2>/dev/null; then
+ echo_rc()
+ {
+ echo " [${_SMSG[${_RC_RV}]}] "
+ }
+ else
+ echo_rc()
+ {
+ if test ${_RC_RV} = 0; then
+ log_success_msg " [${_SMSG[${_RC_RV}]}] "
+ else
+ log_failure_msg " [${_SMSG[${_RC_RV}]}] "
+ fi
+ }
+ fi
+ else
+ # emulate it
+ echo_rc()
+ {
+ echo " [${_SMSG[${_RC_RV}]}] "
+ }
+ fi
+ rc_reset() { _RC_RV=0; }
+ rc_failed()
+ {
+ if test -z "$1"; then
+ _RC_RV=1;
+ elif test "$1" != "0"; then
+ _RC_RV=$1;
+ fi
+ return ${_RC_RV}
+ }
+ rc_check()
+ {
+ return rc_failed $?
+ }
+ rc_status()
+ {
+ rc_failed $?
+ if test "$1" = "-r"; then _RC_RV=0; shift; fi
+ if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
+ if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed
3; shift; fi
+ if test "$1" = "-v"; then echo_rc; shift; fi
+ if test "$1" = "-r"; then _RC_RV=0; shift; fi
+ return ${_RC_RV}
+ }
+ rc_exit() { exit ${_RC_RV}; }
+ rc_active()
+ {
+ if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi
+ if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi
+ return 1
+ }
+fi
+
+if ! which usleep >&/dev/null
+then
+ usleep()
+ {
+ if [ -n "$1" ]
+ then
+ sleep $(( $1 / 1000000 ))
+ fi
+ }
+fi
+
+# Reset status of this service
+rc_reset
+
+##
+# Returns 0 (success) if the given parameter names a directory, and that
+# directory is not empty.
+#
+contains_something()
+{
+ if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
+ then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# read name from xen config file
+rdname()
+{
+ NM=$(xm create --quiet --dryrun --defconfig "$1" |
+ sed -n 's/^.*(name \(.*\))$/\1/p')
+}
+
+rdnames()
+{
+ NAMES=
+ if ! contains_something "$XENDOMAINS_AUTO"
+ then
+ return
+ fi
+ for dom in $XENDOMAINS_AUTO/*; do
+ rdname $dom
+ if test -z $NAMES; then
+ NAMES=$NM;
+ else
+ NAMES="$NAMES|$NM"
+ fi
+ done
+}
+
+parseln()
+{
+ if [[ "$1" =~ "\(domain" ]]; then
+ name=;id=
+ else if [[ "$1" =~ "\(name" ]]; then
+ name=$(echo $1 | sed -e 's/^.*(name \(.*\))$/\1/')
+ else if [[ "$1" =~ "\(domid" ]]; then
+ id=$(echo $1 | sed -e 's/^.*(domid \(.*\))$/\1/')
+ fi; fi; fi
+
+ [ -n "$name" -a -n "$id" ] && return 0 || return 1
+}
+
+is_running()
+{
+ rdname $1
+ RC=1
+ name=;id=
+ while read LN; do
+ parseln "$LN" || continue
+ if test $id = 0; then continue; fi
+ case $name in
+ ($NM)
+ RC=0
+ ;;
+ esac
+ done < <(xm list -l | grep '(\(domain\|domid\|name\)')
+ return $RC
+}
+
+start()
+{
+ if [ -f $LOCKFILE ]; then
+ echo -n "xendomains already running (lockfile exists)"
+ return;
+ fi
+
+ saved_domains=" "
+ if [ "$XENDOMAINS_RESTORE" = "true" ] &&
+ contains_something "$XENDOMAINS_SAVE"
+ then
+ mkdir -p $(dirname "$LOCKFILE")
+ touch $LOCKFILE
+ echo -n "Restoring Xen domains:"
+ saved_domains=`ls $XENDOMAINS_SAVE`
+ for dom in $XENDOMAINS_SAVE/*; do
+ if [ -f $dom ] ; then
+ HEADER=`head -c 16 $dom | head -n 1 2> /dev/null`
+ if [ $HEADER = "LinuxGuestRecord" ]; then
+ echo -n " ${dom##*/}"
+ xm restore $dom
+ if [ $? -ne 0 ]; then
+ rc_failed $?
+ echo -n '!'
+ else
+ # mv $dom ${dom%/*}/.${dom##*/}
+ rm $dom
+ fi
+ fi
+ fi
+ done
+ echo .
+ fi
+
+ if contains_something "$XENDOMAINS_AUTO"
+ then
+ touch $LOCKFILE
+ echo -n "Starting auto Xen domains:"
+ # We expect config scripts for auto starting domains to be in
+ # XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
+
+ # Create all domains with config files in XENDOMAINS_AUTO.
+ # TODO: We should record which domain name belongs
+ # so we have the option to selectively shut down / migrate later
+ # If a domain statefile from $XENDOMAINS_SAVE matches a domain name
+ # in $XENDOMAINS_AUTO, do not try to start that domain; if it didn't
+ # restore correctly it requires administrative attention.
+ for dom in $XENDOMAINS_AUTO/*; do
+ echo -n " ${dom##*/}"
+ shortdom=$(echo $dom | sed -n 's/^.*\/\(.*\)$/\1/p')
+ echo $saved_domains | grep -w $shortdom > /dev/null
+ if [ $? -eq 0 ] || is_running $dom; then
+ echo -n "(skip)"
+ else
+ xm create --quiet --defconfig $dom
+ if [ $? -ne 0 ]; then
+ rc_failed $?
+ echo -n '!'
+ else
+ usleep $XENDOMAINS_CREATE_USLEEP
+ fi
+ fi
+ done
+ fi
+}
+
+all_zombies()
+{
+ name=;id=
+ while read LN; do
+ parseln "$LN" || continue
+ if test $id = 0; then continue; fi
+ if test "$state" != "-b---d" -a "$state" != "-----d"; then
+ return 1;
+ fi
+ done < <(xm list -l | grep '(\(domain\|domid\|name\)')
+ return 0
+}
+
+# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
+# if it has not exited by that time kill it, so the init script will
+# succeed within a finite amount of time; if $2 is nonnull, it will
+# kill the command as well as soon as no domain (except for zombies)
+# are left (used for shutdown --all).
+watchdog_xm()
+{
+ if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0";
then
+ exit
+ fi
+ usleep 20000
+ for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
+ # exit if xm save/migrate/shutdown is finished
+ PSAX=`ps axlw | grep "xm $1" | grep -v grep`
+ if test -z "$PSAX"; then exit; fi
+ echo -n "."; sleep 1
+ # go to kill immediately if there's only zombies left
+ if all_zombies && test -n "$2"; then break; fi
+ done
+ sleep 1
+ read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
+ # kill xm $1
+ kill $PSPID >/dev/null 2>&1
+}
+
+stop()
+{
+ # Collect list of domains to shut down
+ if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
+ rdnames
+ fi
+ echo -n "Shutting down Xen domains:"
+ name=;id=
+ while read LN; do
+ parseln "$LN" || continue
+ if test $id = 0; then continue; fi
+ echo -n " $name"
+ if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
+ eval "
+ case \"\$name\" in
+ ($NAMES)
+ # nothing
+ ;;
+ (*)
+ echo -n '(skip)'
+ continue
+ ;;
+ esac
+ "
+ fi
+ # XENDOMAINS_SYSRQ chould be something like just "s"
+ # or "s e i u" or even "s e s i u o"
+ # for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
+ if test -n "$XENDOMAINS_SYSRQ"; then
+ for sysrq in $XENDOMAINS_SYSRQ; do
+ echo -n "(SR-$sysrq)"
+ xm sysrq $id $sysrq
+ if test $? -ne 0; then
+ rc_failed $?
+ echo -n '!'
+ fi
+ # usleep just ignores empty arg
+ usleep $XENDOMAINS_USLEEP
+ done
+ fi
+ if test "$state" = "-b---d" -o "$state" = "-----d"; then
+ echo -n "(zomb)"
+ continue
+ fi
+ if test -n "$XENDOMAINS_MIGRATE"; then
+ echo -n "(migr)"
+ watchdog_xm migrate &
+ WDOG_PID=$!
+ xm migrate $id $XENDOMAINS_MIGRATE
+ if test $? -ne 0; then
+ rc_failed $?
+ echo -n '!'
+ kill $WDOG_PID >/dev/null 2>&1
+ else
+ kill $WDOG_PID >/dev/null 2>&1
+ continue
+ fi
+ fi
+ if test -n "$XENDOMAINS_SAVE"; then
+ echo -n "(save)"
+ watchdog_xm save &
+ WDOG_PID=$!
+ mkdir -p "$XENDOMAINS_SAVE"
+ xm save $id $XENDOMAINS_SAVE/$name
+ if test $? -ne 0; then
+ rc_failed $?
+ echo -n '!'
+ kill $WDOG_PID >/dev/null 2>&1
+ else
+ kill $WDOG_PID >/dev/null 2>&1
+ continue
+ fi
+ fi
+ if test -n "$XENDOMAINS_SHUTDOWN"; then
+ # XENDOMAINS_SHUTDOWN should be "--halt --wait"
+ echo -n "(shut)"
+ watchdog_xm shutdown &
+ WDOG_PID=$!
+ xm shutdown $id $XENDOMAINS_SHUTDOWN
+ if test $? -ne 0; then
+ rc_failed $?
+ echo -n '!'
+ fi
+ kill $WDOG_PID >/dev/null 2>&1
+ fi
+ done < <(xm list -l | grep '(\(domain\|domid\|name\)')
+
+ # NB. this shuts down ALL Xen domains (politely), not just the ones in
+ # AUTODIR/*
+ # This is because it's easier to do ;-) but arguably if this script is run
+ # on system shutdown then it's also the right thing to do.
+ if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
+ # XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
+ echo -n " SHUTDOWN_ALL "
+ watchdog_xm shutdown 1 &
+ WDOG_PID=$!
+ xm shutdown $XENDOMAINS_SHUTDOWN_ALL
+ if test $? -ne 0; then
+ rc_failed $?
+ echo -n '!'
+ fi
+ kill $WDOG_PID >/dev/null 2>&1
+ fi
+
+ # Unconditionally delete lock file
+ rm -f $LOCKFILE
+}
+
+check_domain_up()
+{
+ name=;id=
+ while read LN; do
+ parseln "$LN" || continue
+ if test $id = 0; then continue; fi
+ case $name in
+ ($1)
+ return 0
+ ;;
+ esac
+ done < <(xm list -l | grep '(\(domain\|domid\|name\)')
+ return 1
+}
+
+check_all_auto_domains_up()
+{
+ if ! contains_something "$XENDOMAINS_AUTO"
+ then
+ return 0
+ fi
+ missing=
+ for nm in $XENDOMAINS_AUTO/*; do
+ rdname $nm
+ found=0
+ if check_domain_up "$NM"; then
+ echo -n " $name"
+ else
+ missing="$missing $NM"
+ fi
+ done
+ if test -n "$missing"; then
+ echo -n " MISS AUTO:$missing"
+ return 1
+ fi
+ return 0
+}
+
+check_all_saved_domains_up()
+{
+ if ! contains_something "$XENDOMAINS_SAVE"
+ then
+ return 0
+ fi
+ missing=`/bin/ls $XENDOMAINS_SAVE`
+ echo -n " MISS SAVED: " $missing
+ return 1
+}
+
+# This does NOT necessarily restart all running domains: instead it
+# stops all running domains and then boots all the domains specified in
+# AUTODIR. If other domains have been started manually then they will
+# not get restarted.
+# Commented out to avoid confusion!
+
+restart()
+{
+ stop
+ start
+}
+
+reload()
+{
+ restart
+}
+
+
+case "$1" in
+ start)
+ start
+ rc_status
+ if test -f $LOCKFILE; then rc_status -v; fi
+ ;;
+
+ stop)
+ stop
+ rc_status -v
+ ;;
+
+ restart)
+ restart
+ ;;
+ reload)
+ reload
+ ;;
+
+ status)
+ echo -n "Checking for xendomains:"
+ if test ! -f $LOCKFILE; then
+ rc_failed 3
+ else
+ check_all_auto_domains_up
+ rc_status
+ check_all_saved_domains_up
+ rc_status
+ fi
+ rc_status -v
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|restart|reload|status}"
+ rc_failed 3
+ rc_status -v
+ ;;
+esac
+
+rc_exit
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/locking.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/locking.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/logging.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/logging.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/network-bridge
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/network-bridge Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,310 @@
+#!/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 ! 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
+}
+
+# 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
+
+ create_bridge ${tdev}
+
+ preiftransfer ${netdev}
+ transfer_addrs ${netdev} ${tdev}
+ if ! ifdown ${netdev}; then
+ # If ifdown fails, remember the IP details.
+ get_ip_info ${netdev}
+ ip link set ${netdev} down
+ ip addr flush ${netdev}
+ fi
+ ip link set ${netdev} name ${pdev}
+ ip link set ${tdev} name ${bridge}
+
+ setup_bridge_port ${pdev}
+
+ add_to_bridge2 ${bridge} ${pdev}
+ do_ifup ${bridge}
+
+ if [ ${antispoof} = 'yes' ] ; then
+ antispoofing
+ fi
+}
+
+op_stop () {
+ if [ "${bridge}" = "null" ]; then
+ return
+ fi
+ if ! link_exists "$bridge"; then
+ return
+ fi
+
+ transfer_addrs ${bridge} ${pdev}
+ if ! ifdown ${bridge}; then
+ get_ip_info ${bridge}
+ fi
+ ip link set ${pdev} down
+ ip addr flush ${bridge}
+
+ brctl delif ${bridge} ${pdev}
+ ip link set ${bridge} down
+
+ ip link set ${bridge} name ${tdev}
+ ip link set ${pdev} name ${netdev}
+ do_ifup ${netdev}
+
+ brctl delbr ${tdev}
+}
+
+# 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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/network-nat
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/network-nat Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,119 @@
+#!/bin/bash -x
+#============================================================================
+# 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
+
+
+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 {}"
+ 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
+ [ "$dhcp" != 'no' ] && dhcp_start
+}
+
+
+op_stop() {
+ [ "$dhcp" != 'no' ] && dhcp_stop
+ iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
+}
+
+
+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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/network-route
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/network-route Tue Nov 25 14:21:24 2008 +0900
@@ -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:-eth${vifnum}}
+
+echo 1 >/proc/sys/net/ipv4/ip_forward
+echo 1 >/proc/sys/net/ipv4/conf/${netdev}/proxy_arp
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vif-bridge
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vif-bridge Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vif-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vif-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,151 @@
+#
+# 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="-A"
+ else
+ local c="-D"
+ fi
+
+ iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT \
+ 2>/dev/null ||
+ [ "$c" == "-D" ] ||
+ log err \
+ "iptables $c FORWARD -m physdev --physdev-in $vif $@ -j ACCEPT failed.
+If you are using iptables, this may affect networking for guest domains."
+}
+
+
+##
+# 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
+
+ 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
+}
+
+
+##
+# 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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vif-nat
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vif-nat Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vif-route
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vif-route Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vscsi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vscsi Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm-delete
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm-delete Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm-hotplug-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm-hotplug-common.sh Tue Nov 25 14:21:24
2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm-impl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm-impl Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/vtpm-migration.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/vtpm-migration.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-backend.agent
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-backend.agent Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,39 @@
+#! /bin/bash
+
+PATH=/etc/xen/scripts:$PATH
+
+. /etc/xen/scripts/locking.sh
+
+claim_lock xenbus_hotplug_global
+
+case "$XENBUS_TYPE" in
+ tap)
+ /etc/xen/scripts/blktap "$ACTION"
+ ;;
+ vbd)
+ /etc/xen/scripts/block "$ACTION"
+ ;;
+ vtpm)
+ /etc/xen/scripts/vtpm "$ACTION"
+ ;;
+ vif)
+ [ -n "$script" ] && $script "$ACTION"
+ ;;
+ vscsi)
+ /etc/xen/scripts/vscsi "$ACTION"
+ ;;
+esac
+
+case "$ACTION" in
+ add)
+ ;;
+ remove)
+ /etc/xen/scripts/xen-hotplug-cleanup
+ ;;
+ online)
+ ;;
+ offline)
+ ;;
+esac
+
+release_lock xenbus_hotplug_global
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-backend.rules
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-backend.rules Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,9 @@
+SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap
$env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block
$env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm
$env{ACTION}"
+SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script}
online"
+SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="offline",
RUN+="$env{script} offline"
+SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi
$env{ACTION}"
+SUBSYSTEM=="xen-backend", ACTION=="remove",
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
+KERNEL=="evtchn", NAME="xen/%k"
+KERNEL=="blktap[0-9]*", NAME="xen/%k"
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-hotplug-cleanup
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-hotplug-cleanup Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,22 @@
+#! /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"
+
+# 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
+
+release_lock "block"
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-hotplug-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-hotplug-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-network-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-network-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Linux/xen-script-common.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Linux/xen-script-common.sh Tue Nov 25 14:21:24 2008 +0900
@@ -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 -r 7ef733b961c8 -r 436816898c87 tools/hotplug/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,9 @@
+XEN_ROOT = ../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+SUBDIRS-y := common
+SUBDIRS-$(CONFIG_NetBSD) += NetBSD
+SUBDIRS-$(CONFIG_Linux) += Linux
+
+.PHONY: all clean install
+all clean install: %: subdirs-%
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/NetBSD/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,41 @@
+XEN_ROOT = ../../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+# Xen configuration dir and configs to go there.
+XEN_CONFIG_DIR = $(PREFIX)/etc/xen
+
+# Xen script dir and scripts to go there.
+XEN_SCRIPT_DIR = $(PREFIX)/etc/xen/scripts
+XEN_SCRIPTS =
+XEN_SCRIPTS += block-nbsd
+XEN_SCRIPTS += hvm-nbsd
+XEN_SCRIPTS += netbsd1-nbsd
+XEN_SCRIPTS += qemu-ifup-nbsd
+XEN_SCRIPTS += vif-bridge-nbsd
+XEN_SCRIPTS += vif-ip-nbsd
+
+XEN_SCRIPT_DATA =
+
+.PHONY: all
+all:
+
+.PHONY: build
+build:
+
+.PHONY: install
+install: all install-scripts
+
+.PHONY: install-scripts
+install-scripts:
+ $(INSTALL_DATA_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
+ set -e; for i in $(XEN_SCRIPTS); \
+ do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+ set -e; for i in $(XEN_SCRIPT_DATA); \
+ do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+
+.PHONY: clean
+clean:
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/NetBSD/block-nbsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/block-nbsd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,88 @@
+#!/bin/sh -e
+
+# $NetBSD: block-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: block xsdir_backend_path state
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+error() {
+ echo "$@" >&2
+ xenstore_write $xpath/hotplug-status error
+ exit 1
+}
+
+
+xpath=$1
+xstatus=$2
+xtype=$(xenstore-read "$xpath/type")
+xparams=$(xenstore-read "$xpath/params")
+
+case $xstatus in
+6)
+ # device removed
+ case $xtype in
+ file)
+ vnd=$(xenstore-read "$xpath/vnd" || echo none)
+ if [ $vnd != none ]; then
+ vnconfig -u $vnd
+ fi
+ ;;
+ phy)
+ ;;
+ *)
+ echo "unknown type $xtype" >&2
+ ;;
+ esac
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ case $xtype in
+ file)
+ # Store the list of available vnd(4) devices in
+ #``available_disks'', and mark them as ``free''.
+ list=`ls -1 /dev/vnd[0-9]*d | sed "s,/dev/vnd,,;s,d,," | sort
-n`
+ for i in $list; do
+ disk="vnd$i"
+ available_disks="$available_disks $disk"
+ eval $disk=free
+ done
+ # Mark the used vnd(4) devices as ``used''.
+ for disk in `sysctl hw.disknames`; do
+ case $disk in
+ vnd[0-9]*) eval $disk=used ;;
+ esac
+ done
+ # Configure the first free vnd(4) device.
+ for disk in $available_disks; do
+ eval status=\$$disk
+ if [ "$status" = "free" ] && \
+ vnconfig /dev/${disk}d $xparams >/dev/null; then
+ device=/dev/${disk}d
+ echo vnconfig /dev/${disk}d $xparams
+ break
+ fi
+ done
+ if [ x$device = x ] ; then
+ error "no available vnd device"
+ fi
+ echo xenstore-write $xpath/vnd $device
+ xenstore-write $xpath/vnd $device
+ ;;
+ phy)
+ device=$xparams
+ ;;
+ esac
+ physical_device=$(stat -f '%r' "$device")
+ echo xenstore-write $xpath/physical-device $physical_device
+ xenstore-write $xpath/physical-device $physical_device
+ echo xenstore-write $xpath/hotplug-status connected
+ xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/NetBSD/qemu-ifup-nbsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/qemu-ifup-nbsd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,3 @@
+#!/bin/sh
+ifconfig $1 up
+exec /sbin/brconfig $2 add $1
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/NetBSD/vif-bridge-nbsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/vif-bridge-nbsd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,35 @@
+#!/bin/sh -e
+
+# $NetBSD: vif-bridge-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: vif-bridge xsdir_backend_path state
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+xpath=$1
+xstatus=$2
+
+case $xstatus in
+6)
+ # device removed
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ xbridge=$(xenstore-read "$xpath/bridge")
+ xfid=$(xenstore-read "$xpath/frontend-id")
+ xhandle=$(xenstore-read "$xpath/handle")
+ iface=xvif$xfid.$xhandle
+ echo ifconfig $iface up
+ ifconfig $iface up
+ brconfig $xbridge add $iface
+ echo brconfig $xbridge add $iface
+ xenstore-write $xpath/hotplug-status connected
+ echo xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/NetBSD/vif-ip-nbsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/NetBSD/vif-ip-nbsd Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+
+# $NetBSD: vif-ip-nbsd,v 1.1.1.1 2008/08/07 20:26:57 cegger Exp $
+# Called by xenbackendd
+# Usage: vif-ip xsdir_backend_path state
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+export PATH
+
+xpath=$1
+xstatus=$2
+
+case $xstatus in
+6)
+ # device removed
+ xenstore-rm $xpath
+ exit 0
+ ;;
+2)
+ xip=$(xenstore-read "$xpath/ip")
+ xfid=$(xenstore-read "$xpath/frontend-id")
+ xhandle=$(xenstore-read "$xpath/handle")
+ iface=xvif$xfid.$xhandle
+ echo ifconfig $iface $xip up
+ ifconfig $iface $xip up
+ xenstore-write $xpath/hotplug-status connected
+ echo xenstore-write $xpath/hotplug-status connected
+ exit 0
+ ;;
+*)
+ exit 0
+ ;;
+esac
diff -r 7ef733b961c8 -r 436816898c87 tools/hotplug/common/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/hotplug/common/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,37 @@
+XEN_ROOT = ../../../
+include $(XEN_ROOT)/tools/Rules.mk
+
+# OS-independent hotplug scripts go in this directory
+
+# Xen configuration dir and configs to go there.
+XEN_CONFIG_DIR = /etc/xen
+
+# Xen script dir and scripts to go there.
+XEN_SCRIPT_DIR = /etc/xen/scripts
+XEN_SCRIPTS =
+XEN_SCRIPT_DATA =
+
+.PHONY: all
+all:
+
+.PHONY: build
+build:
+
+.PHONY: install
+install: all install-scripts
+
+.PHONY: install-scripts
+install-scripts:
+ [ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \
+ $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
+ set -e; for i in $(XEN_SCRIPTS); \
+ do \
+ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+ set -e; for i in $(XEN_SCRIPT_DATA); \
+ do \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
+ done
+
+.PHONY: clean
+clean:
diff -r 7ef733b961c8 -r 436816898c87 tools/libxc/xc_cpufeature.h
--- a/tools/libxc/xc_cpufeature.h Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/libxc/xc_cpufeature.h Tue Nov 25 14:21:24 2008 +0900
@@ -83,6 +83,7 @@
#define X86_FEATURE_SSE4_1 (4*32+19) /* Streaming SIMD Extensions 4.1 */
#define X86_FEATURE_SSE4_2 (4*32+20) /* Streaming SIMD Extensions 4.2 */
#define X86_FEATURE_POPCNT (4*32+23) /* POPCNT instruction */
+#define X86_FEATURE_HYPERVISOR (4*32+31) /* Running under some hypervisor */
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
diff -r 7ef733b961c8 -r 436816898c87 tools/libxc/xc_cpuid_x86.c
--- a/tools/libxc/xc_cpuid_x86.c Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/libxc/xc_cpuid_x86.c Tue Nov 25 14:21:24 2008 +0900
@@ -193,6 +193,8 @@ static void xc_cpuid_hvm_policy(
bitmaskof(X86_FEATURE_SSE4_1) |
bitmaskof(X86_FEATURE_SSE4_2) |
bitmaskof(X86_FEATURE_POPCNT));
+
+ regs[2] |= bitmaskof(X86_FEATURE_HYPERVISOR);
regs[3] &= (bitmaskof(X86_FEATURE_FPU) |
bitmaskof(X86_FEATURE_VME) |
@@ -309,6 +311,7 @@ static void xc_cpuid_pv_policy(
clear_bit(X86_FEATURE_XTPR, regs[2]);
clear_bit(X86_FEATURE_PDCM, regs[2]);
clear_bit(X86_FEATURE_DCA, regs[2]);
+ set_bit(X86_FEATURE_HYPERVISOR, regs[2]);
break;
case 0x80000001:
if ( !guest_64bit )
diff -r 7ef733b961c8 -r 436816898c87 tools/misc/xenpm.c
--- a/tools/misc/xenpm.c Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/misc/xenpm.c Tue Nov 25 14:21:24 2008 +0900
@@ -170,7 +170,7 @@ int main(int argc, char **argv)
if ( !pxstat->pt )
{
fprintf(stderr, "failed to malloc for P-states table\n");
- free(pxstat->pt);
+ free(pxstat->trans_pt);
break;
}
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/util/rwlock.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/util/rwlock.py Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,137 @@
+""" Reader-writer lock implementation based on a condition variable """
+
+#============================================================================
+# 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
+#============================================================================
+# Copyright (C) 2008 International Business Machines Corp.
+# Author: Stefan Berger <stefanb@xxxxxxxxxx>
+#============================================================================
+
+from threading import Condition
+
+class RWLock:
+
+ RWLOCK_STATE_WRITER = -1
+ RWLOCK_STATE_UNUSED = 0
+
+ def __init__(self):
+ self.__condition = Condition()
+ self.__state = RWLock.RWLOCK_STATE_UNUSED
+ self.__blocked_writers = 0
+
+ def acquire_reader(self):
+ self.__condition.acquire()
+ while True:
+ if self.__state == RWLock.RWLOCK_STATE_WRITER:
+ self.__condition.wait()
+ else:
+ break
+ self.__state += 1
+ self.__condition.release()
+
+ def acquire_writer(self):
+ self.__condition.acquire()
+ self.__acquire_writer(RWLock.RWLOCK_STATE_UNUSED)
+ self.__condition.release()
+
+ def __acquire_writer(self, wait_for_state):
+ while True:
+ if self.__state == wait_for_state:
+ self.__state = RWLock.RWLOCK_STATE_WRITER
+ break
+ else:
+ self.__blocked_writers += 1
+ self.__condition.wait()
+ self.__blocked_writers -= 1
+
+ def release(self):
+ self.__condition.acquire()
+ if self.__state == RWLock.RWLOCK_STATE_WRITER:
+ self.__state = RWLock.RWLOCK_STATE_UNUSED
+ elif self.__state == RWLock.RWLOCK_STATE_UNUSED:
+ assert False, 'Lock not in use.'
+ else:
+ self.__state -= 1
+ self.__condition.notifyAll()
+ self.__condition.release()
+
+
+if __name__ == '__main__':
+ from threading import Thread
+ from time import sleep
+
+ rwlock = RWLock()
+
+ class Base(Thread):
+ def __init__(self, name, timeout):
+ self.name = name
+ self.timeout = timeout
+ Thread.__init__(self)
+
+ class Reader(Base):
+ def __init__(self, name = 'Reader', timeout = 10):
+ Base.__init__(self, name, timeout)
+
+ def run(self):
+ print '%s begin' % self.name
+ rwlock.acquire_reader()
+ print '%s acquired' % self.name
+ sleep(self.timeout)
+ rwlock.release()
+ print '%s end' % self.name
+
+ class ReaderTwice(Base):
+ def __init__(self, name = 'Reader', timeout = 10):
+ Base.__init__(self, name, timeout)
+
+ def run(self):
+ print '%s begin' % self.name
+ rwlock.acquire_reader()
+ print '%s acquired once' % self.name
+ sleep(self.timeout)
+ rwlock.acquire_reader()
+ print '%s acquired twice' % self.name
+ sleep(self.timeout)
+ rwlock.release()
+ rwlock.release()
+ print '%s end' % self.name
+
+ class Writer(Base):
+ def __init__(self, name = 'Writer', timeout = 10):
+ Base.__init__(self, name, timeout)
+
+ def run(self):
+ print '%s begin' % self.name
+ rwlock.acquire_writer()
+ print '%s acquired' % self.name
+ sleep(self.timeout)
+ rwlock.release()
+ print '%s end' % self.name
+
+ def run_test(threadlist, msg):
+ print msg
+ for t in threadlist:
+ t.start()
+ sleep(1)
+ for t in threads:
+ t.join()
+ print 'Done\n\n'
+
+ threads = []
+ threads.append( Reader('R1', 4) )
+ threads.append( Reader('R2', 4) )
+ threads.append( Writer('W1', 4) )
+ threads.append( Reader('R3', 4) )
+ run_test(threads,
+ 'Test: readers may bypass blocked writers')
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/XendAPI.py Tue Nov 25 14:21:24 2008 +0900
@@ -431,7 +431,7 @@ def valid_object(class_name):
lambda *args, **kwargs: \
_check_ref(lambda r: \
XendAPIStore.get(r, class_name) is not None,
- 'PIF', func, *args, **kwargs)
+ class_name, func, *args, **kwargs)
# -----------------------------
# Bridge to Legacy XM API calls
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/XendConfig.py Tue Nov 25 14:21:24 2008 +0900
@@ -1032,8 +1032,6 @@ class XendConfig(dict):
sxpr.append([name, s])
for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
- if legacy in ('cpus'): # skip this
- continue
if self.has_key(xenapi) and self[xenapi] not in (None, []):
if type(self[xenapi]) == bool:
# convert booleans to ints before making an sxp item
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/XendDomain.py Tue Nov 25 14:21:24 2008 +0900
@@ -50,7 +50,7 @@ from xen.xend.XendAPIConstants import *
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
-from xen.util import mkdir
+from xen.util import mkdir, rwlock
from xen.xend import uuid
xc = xen.lowlevel.xc.xc()
@@ -92,6 +92,8 @@ class XendDomain:
self.domains = {}
self.managed_domains = {}
self.domains_lock = threading.RLock()
+
+ self.policy_lock = rwlock.RWLock()
# xen api instance vars
# TODO: nothing uses this at the moment
@@ -1139,16 +1141,21 @@ class XendDomain:
"""
try:
- return XendCheckpoint.restore(self, fd, paused=paused,
relocating=relocating)
- except XendError, e:
- log.exception("Restore failed")
- raise
- except:
- # I don't really want to log this exception here, but the error
- # handling in the relocation-socket handling code (relocate.py) is
- # poor, so we need to log this for debugging.
- log.exception("Restore failed")
- raise XendError("Restore failed")
+ self.policy_lock.acquire_reader()
+
+ try:
+ return XendCheckpoint.restore(self, fd, paused=paused,
relocating=relocating)
+ except XendError, e:
+ log.exception("Restore failed")
+ raise
+ except:
+ # I don't really want to log this exception here, but the error
+ # handling in the relocation-socket handling code
(relocate.py) is
+ # poor, so we need to log this for debugging.
+ log.exception("Restore failed")
+ raise XendError("Restore failed")
+ finally:
+ self.policy_lock.release()
def domain_unpause(self, domid):
"""Unpause domain execution.
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Tue Nov 25 14:21:24 2008 +0900
@@ -479,6 +479,14 @@ class XendDomainInfo:
if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED):
try:
self._constructDomain()
+
+ try:
+ self._setCPUAffinity()
+ except:
+ # usually a CPU we want to set affinity to does not exist
+ # we just ignore it so that the domain can still be
restored
+ log.warn("Cannot restore CPU affinity")
+
self._storeVmDetails()
self._createChannels()
self._createDevices()
@@ -2166,6 +2174,64 @@ class XendDomainInfo:
raise XendError(str(exn))
+ def _setCPUAffinity(self):
+ """ Repin domain vcpus if a restricted cpus list is provided
+ """
+
+ def has_cpus():
+ if self.info['cpus'] is not None:
+ for c in self.info['cpus']:
+ if c:
+ return True
+ return False
+
+ if has_cpus():
+ for v in range(0, self.info['VCPUs_max']):
+ if self.info['cpus'][v]:
+ xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v])
+ else:
+ def find_relaxed_node(node_list):
+ import sys
+ nr_nodes = info['nr_nodes']
+ if node_list is None:
+ node_list = range(0, nr_nodes)
+ nodeload = [0]
+ nodeload = nodeload * nr_nodes
+ from xen.xend import XendDomain
+ doms = XendDomain.instance().list('all')
+ for dom in filter (lambda d: d.domid != self.domid, doms):
+ cpuinfo = dom.getVCPUInfo()
+ for vcpu in sxp.children(cpuinfo, 'vcpu'):
+ if sxp.child_value(vcpu, 'online') == 0: continue
+ cpumap = list(sxp.child_value(vcpu,'cpumap'))
+ for i in range(0, nr_nodes):
+ node_cpumask = info['node_to_cpu'][i]
+ for j in node_cpumask:
+ if j in cpumap:
+ nodeload[i] += 1
+ break
+ for i in range(0, nr_nodes):
+ if len(info['node_to_cpu'][i]) > 0 and i in node_list:
+ nodeload[i] = int(nodeload[i] * 16 /
len(info['node_to_cpu'][i]))
+ else:
+ nodeload[i] = sys.maxint
+ index = nodeload.index( min(nodeload) )
+ return index
+
+ info = xc.physinfo()
+ if info['nr_nodes'] > 1:
+ node_memory_list = info['node_to_memory']
+ needmem =
self.image.getRequiredAvailableMemory(self.info['memory_dynamic_max']) / 1024
+ candidate_node_list = []
+ for i in range(0, info['nr_nodes']):
+ if node_memory_list[i] >= needmem and
len(info['node_to_cpu'][i]) > 0:
+ candidate_node_list.append(i)
+ index = find_relaxed_node(candidate_node_list)
+ cpumask = info['node_to_cpu'][index]
+ for v in range(0, self.info['VCPUs_max']):
+ xc.vcpu_setaffinity(self.domid, v, cpumask)
+
+
def _initDomain(self):
log.debug('XendDomainInfo.initDomain: %s %s',
self.domid,
@@ -2185,58 +2251,7 @@ class XendDomainInfo:
# repin domain vcpus if a restricted cpus list is provided
# this is done prior to memory allocation to aide in memory
# distribution for NUMA systems.
- def has_cpus():
- if self.info['cpus'] is not None:
- for c in self.info['cpus']:
- if c:
- return True
- return False
-
- if has_cpus():
- for v in range(0, self.info['VCPUs_max']):
- if self.info['cpus'][v]:
- xc.vcpu_setaffinity(self.domid, v,
self.info['cpus'][v])
- else:
- def find_relaxed_node(node_list):
- import sys
- nr_nodes = info['nr_nodes']
- if node_list is None:
- node_list = range(0, nr_nodes)
- nodeload = [0]
- nodeload = nodeload * nr_nodes
- from xen.xend import XendDomain
- doms = XendDomain.instance().list('all')
- for dom in filter (lambda d: d.domid != self.domid, doms):
- cpuinfo = dom.getVCPUInfo()
- for vcpu in sxp.children(cpuinfo, 'vcpu'):
- if sxp.child_value(vcpu, 'online') == 0: continue
- cpumap = list(sxp.child_value(vcpu,'cpumap'))
- for i in range(0, nr_nodes):
- node_cpumask = info['node_to_cpu'][i]
- for j in node_cpumask:
- if j in cpumap:
- nodeload[i] += 1
- break
- for i in range(0, nr_nodes):
- if len(info['node_to_cpu'][i]) > 0 and i in node_list:
- nodeload[i] = int(nodeload[i] * 16 /
len(info['node_to_cpu'][i]))
- else:
- nodeload[i] = sys.maxint
- index = nodeload.index( min(nodeload) )
- return index
-
- info = xc.physinfo()
- if info['nr_nodes'] > 1:
- node_memory_list = info['node_to_memory']
- needmem =
self.image.getRequiredAvailableMemory(self.info['memory_dynamic_max']) / 1024
- candidate_node_list = []
- for i in range(0, info['nr_nodes']):
- if node_memory_list[i] >= needmem and
len(info['node_to_cpu'][i]) > 0:
- candidate_node_list.append(i)
- index = find_relaxed_node(candidate_node_list)
- cpumask = info['node_to_cpu'][index]
- for v in range(0, self.info['VCPUs_max']):
- xc.vcpu_setaffinity(self.domid, v, cpumask)
+ self._setCPUAffinity()
# Use architecture- and image-specific calculations to determine
# the various headrooms necessary, given the raw configured
@@ -3011,64 +3026,69 @@ class XendDomainInfo:
if not xspol:
xspol = poladmin.get_policy_by_name(policy)
- if state in [ DOM_STATE_RUNNING, DOM_STATE_PAUSED ]:
- #if domain is running or paused try to relabel in hypervisor
- if not xspol:
- return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
-
- if typ != xspol.get_type_name() or \
- policy != xspol.get_name():
- return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
-
- if typ == xsconstants.ACM_POLICY_ID:
- new_ssidref = xspol.vmlabel_to_ssidref(label)
- if new_ssidref == xsconstants.INVALID_SSIDREF:
+ try:
+ xen.xend.XendDomain.instance().policy_lock.acquire_writer()
+
+ if state in [ DOM_STATE_RUNNING, DOM_STATE_PAUSED ]:
+ #if domain is running or paused try to relabel in hypervisor
+ if not xspol:
+ return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
+
+ if typ != xspol.get_type_name() or \
+ policy != xspol.get_name():
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
- # Check that all used resources are accessible under the
- # new label
- if not is_policy_update and \
- not security.resources_compatible_with_vmlabel(xspol,
- self, label):
- return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
-
- #Check label against expected one. Can only do this
- # if the policy hasn't changed underneath in the meantime
- if xspol_old == None:
- old_label = self.get_security_label()
- if old_label != old_seclab:
- log.info("old_label != old_seclab: %s != %s" %
- (old_label, old_seclab))
+ if typ == xsconstants.ACM_POLICY_ID:
+ new_ssidref = xspol.vmlabel_to_ssidref(label)
+ if new_ssidref == xsconstants.INVALID_SSIDREF:
return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
- # relabel domain in the hypervisor
- rc, errors = security.relabel_domains([[domid, new_ssidref]])
- log.info("rc from relabeling in HV: %d" % rc)
- else:
- return (-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED, "", "", 0)
-
- if rc == 0:
- # HALTED, RUNNING or PAUSED
- if domid == 0:
- if xspol:
+ # Check that all used resources are accessible under the
+ # new label
+ if not is_policy_update and \
+ not security.resources_compatible_with_vmlabel(xspol,
+ self, label):
+ return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
+
+ #Check label against expected one. Can only do this
+ # if the policy hasn't changed underneath in the meantime
+ if xspol_old == None:
+ old_label = self.get_security_label()
+ if old_label != old_seclab:
+ log.info("old_label != old_seclab: %s != %s" %
+ (old_label, old_seclab))
+ return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
+
+ # relabel domain in the hypervisor
+ rc, errors = security.relabel_domains([[domid,
new_ssidref]])
+ log.info("rc from relabeling in HV: %d" % rc)
+ else:
+ return (-xsconstants.XSERR_POLICY_TYPE_UNSUPPORTED, "",
"", 0)
+
+ if rc == 0:
+ # HALTED, RUNNING or PAUSED
+ if domid == 0:
+ if xspol:
+ self.info['security_label'] = seclab
+ ssidref = poladmin.set_domain0_bootlabel(xspol, label)
+ else:
+ return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "",
0)
+ else:
+ if self.info.has_key('security_label'):
+ old_label = self.info['security_label']
+ # Check label against expected one, unless wildcard
+ if old_label != old_seclab:
+ return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
+
self.info['security_label'] = seclab
- ssidref = poladmin.set_domain0_bootlabel(xspol, label)
- else:
- return (-xsconstants.XSERR_POLICY_NOT_LOADED, "", "", 0)
- else:
- if self.info.has_key('security_label'):
- old_label = self.info['security_label']
- # Check label against expected one, unless wildcard
- if old_label != old_seclab:
- return (-xsconstants.XSERR_BAD_LABEL, "", "", 0)
-
- self.info['security_label'] = seclab
-
- try:
- xen.xend.XendDomain.instance().managed_config_save(self)
- except:
- pass
- return (rc, errors, old_label, new_ssidref)
+
+ try:
+
xen.xend.XendDomain.instance().managed_config_save(self)
+ except:
+ pass
+ return (rc, errors, old_label, new_ssidref)
+ finally:
+ xen.xend.XendDomain.instance().policy_lock.release()
def get_on_shutdown(self):
after_shutdown = self.info.get('actions_after_shutdown')
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/osdep.py
--- a/tools/python/xen/xend/osdep.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/osdep.py Tue Nov 25 14:21:24 2008 +0900
@@ -38,7 +38,10 @@ _vif_script = {
"SunOS": "vif-vnic"
}
-def _linux_balloon_stat(label):
+PROC_XEN_BALLOON = '/proc/xen/balloon'
+SYSFS_XEN_MEMORY = '/sys/devices/system/xen_memory/xen_memory0'
+
+def _linux_balloon_stat_proc(label):
"""Returns the value for the named label, or None if an error occurs."""
xend2linux_labels = { 'current' : 'Current allocation',
@@ -47,7 +50,6 @@ def _linux_balloon_stat(label):
'high-balloon' : 'High-mem balloon',
'limit' : 'Xen hard limit' }
- PROC_XEN_BALLOON = '/proc/xen/balloon'
f = file(PROC_XEN_BALLOON, 'r')
try:
for line in f:
@@ -61,6 +63,29 @@ def _linux_balloon_stat(label):
return None
finally:
f.close()
+
+def _linux_balloon_stat_sysfs(label):
+ sysfiles = { 'target' : 'target_kb',
+ 'current' : 'info/current_kb',
+ 'low-balloon' : 'info/low_kb',
+ 'high-balloon' : 'info/high_kb',
+ 'limit' : 'info/hard_limit_kb' }
+
+ name = os.path.join(SYSFS_XEN_MEMORY, sysfiles[label])
+ f = file(name, 'r')
+
+ val = f.read().strip()
+ if val.isdigit():
+ return int(val)
+ return None
+
+def _linux_balloon_stat(label):
+ if os.access(PROC_XEN_BALLOON, os.F_OK):
+ return _linux_balloon_stat_proc(label)
+ elif os.access(SYSFS_XEN_MEMORY, os.F_OK):
+ return _linux_balloon_stat_sysfs(label)
+
+ return None
def _solaris_balloon_stat(label):
"""Returns the value for the named label, or None if an error occurs."""
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xend/server/pciif.py Tue Nov 25 14:21:24 2008 +0900
@@ -35,6 +35,8 @@ import re
import re
from xen.xend.server.pciquirk import *
+from xen.xend.xenstore.xstransact import xstransact
+from xen.xend.xenstore.xswatch import xswatch
xc = xen.lowlevel.xc.xc()
@@ -58,6 +60,7 @@ class PciController(DevController):
class PciController(DevController):
def __init__(self, vm):
+ self.aerStateWatch = None
DevController.__init__(self, vm)
@@ -333,12 +336,6 @@ class PciController(DevController):
if rc<0:
raise VmError(('pci: failed to configure I/O memory on device
'+
'%s - errno=%d')%(dev.name,rc))
- rc = xc.physdev_map_pirq(domid = fe_domid,
- index = dev.irq,
- pirq = dev.irq)
- if rc < 0:
- raise VmError(('pci: failed to map irq on device '+
- '%s - errno=%d')%(dev.name,rc))
if dev.msix:
for (start, size) in dev.msix_iomem:
@@ -353,6 +350,12 @@ class PciController(DevController):
if rc<0:
raise VmError(('pci: failed to remove msi-x iomem'))
+ rc = xc.physdev_map_pirq(domid = fe_domid,
+ index = dev.irq,
+ pirq = dev.irq)
+ if rc < 0:
+ raise VmError(('pci: failed to map irq on device '+
+ '%s - errno=%d')%(dev.name,rc))
if dev.irq>0:
log.debug('pci: enabling irq %d'%dev.irq)
rc = xc.domain_irq_permission(domid = fe_domid, pirq = dev.irq,
@@ -431,8 +434,22 @@ class PciController(DevController):
for (domain, bus, slot, func) in pci_dev_list:
self.setupOneDevice(domain, bus, slot, func)
-
+ wPath = '/local/domain/0/backend/pci/%u/0/aerState' % (self.getDomid())
+ self.aerStatePath = xswatch(wPath, self._handleAerStateWatch)
+ log.debug('pci: register aer watch %s', wPath)
return
+
+ def _handleAerStateWatch(self, _):
+ log.debug('XendDomainInfo.handleAerStateWatch')
+ if self.getDomid() == 0:
+ raise XendError('Domain 0 cannot be shutdown')
+ readPath = '/local/domain/0/backend/pci/%u/0/aerState' %
(self.getDomid())
+ action = xstransact.Read(readPath)
+ if action and action=='aerfail':
+ log.debug('shutdown domain because of aer handle error')
+ self.vm.shutdown('poweroff')
+ return True
+
def cleanupOneDevice(self, domain, bus, slot, func):
""" Detach I/O resources for device from frontend domain
@@ -545,6 +562,22 @@ class PciController(DevController):
return new_num_devs
+ def destroyDevice(self, devid, force):
+ DevController.destroyDevice(self, devid, True)
+ log.debug('pci: unregister aer watch')
+ self.unwatchAerState
+
+ def unwatchAerState(self):
+ """Remove the watch on the domain's aerState node, if any."""
+ try:
+ try:
+ if self.aerStateWatch:
+ self.aerStateWatch.unwatch()
+ finally:
+ self.aerStateWatch = None
+ except:
+ log.exception("Unwatching aerState failed.")
+
def waitForBackend(self,devid):
return (0, "ok - no hotplug")
diff -r 7ef733b961c8 -r 436816898c87 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Tue Nov 18 10:55:51 2008 +0100
+++ b/tools/python/xen/xm/create.py Tue Nov 25 14:21:24 2008 +0900
@@ -1202,8 +1202,9 @@ def make_domain(opts, config):
except:
server.xend.domain.destroy(dom)
err("Failed to unpause domain %s" % dom)
- opts.info("Started domain %s" % (dom))
- return int(sxp.child_value(dominfo, 'domid'))
+ domid = int(sxp.child_value(dominfo, 'domid'))
+ opts.info("Started domain %s (id=%d)" % (dom, domid))
+ return domid
def get_xauthority():
diff -r 7ef733b961c8 -r 436816898c87 unmodified_drivers/linux-2.6/balloon/Kbuild
--- a/unmodified_drivers/linux-2.6/balloon/Kbuild Tue Nov 18 10:55:51
2008 +0100
+++ b/unmodified_drivers/linux-2.6/balloon/Kbuild Tue Nov 25 14:21:24
2008 +0900
@@ -4,6 +4,5 @@ obj-m = xen-balloon.o
EXTRA_CFLAGS += -I$(M)/platform-pci
-xen-balloon-objs =
-xen-balloon-objs += balloon.o
-xen-balloon-objs += sysfs.o
+xen-balloon-y := balloon.o sysfs.o
+xen-balloon-$(CONFIG_XEN_SCRUB_PAGES) += scrub.o
diff -r 7ef733b961c8 -r 436816898c87 unmodified_drivers/linux-2.6/mkbuildtree
--- a/unmodified_drivers/linux-2.6/mkbuildtree Tue Nov 18 10:55:51 2008 +0100
+++ b/unmodified_drivers/linux-2.6/mkbuildtree Tue Nov 25 14:21:24 2008 +0900
@@ -53,6 +53,7 @@ i[34567]86|x86_64)
ln -sf ${XL}/include/asm-x86/mach-xen/asm/synch_bitops*.h include/asm
ln -sf ${XL}/include/asm-x86/mach-xen/asm/maddr*.h include/asm
ln -sf ${XL}/include/asm-x86/mach-xen/asm/gnttab_dma.h include/asm
+ ln -sf ${XL}/arch/x86/lib/scrub.c balloon
else
if [ $uname = x86_64 ]; then
mkdir -p include/asm-i386
diff -r 7ef733b961c8 -r 436816898c87
unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
--- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c Tue Nov
18 10:55:51 2008 +0100
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c Tue Nov
25 14:21:24 2008 +0900
@@ -34,7 +34,11 @@ static void ap_suspend(void *_info)
atomic_dec(&info->nr_spinning);
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
#define initiate_ap_suspend(i) smp_call_function(ap_suspend, i, 0, 0)
+#else
+#define initiate_ap_suspend(i) smp_call_function(ap_suspend, i, 0)
+#endif
#else /* !defined(CONFIG_SMP) */
diff -r 7ef733b961c8 -r 436816898c87
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Tue Nov
18 10:55:51 2008 +0100
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c Tue Nov
25 14:21:24 2008 +0900
@@ -14,7 +14,11 @@ EXPORT_SYMBOL(system_state);
void ctrl_alt_del(void)
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
kill_proc(1, SIGINT, 1); /* interrupt init */
+#else
+ kill_cad_pid(SIGINT, 1);
+#endif
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
diff -r 7ef733b961c8 -r 436816898c87 xen/Rules.mk
--- a/xen/Rules.mk Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/Rules.mk Tue Nov 25 14:21:24 2008 +0900
@@ -69,6 +69,9 @@ ifneq ($(max_phys_cpus),)
ifneq ($(max_phys_cpus),)
CFLAGS-y += -DMAX_PHYS_CPUS=$(max_phys_cpus)
endif
+ifneq ($(max_phys_irqs),)
+CFLAGS-y += -DMAX_PHYS_IRQS=$(max_phys_irqs)
+endif
AFLAGS-y += -D__ASSEMBLY__
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/Makefile Tue Nov 25 14:21:24 2008 +0900
@@ -11,6 +11,7 @@ obj-y += apic.o
obj-y += apic.o
obj-y += bitops.o
obj-y += clear_page.o
+obj-y += copy_page.o
obj-y += compat.o
obj-y += delay.o
obj-y += dmi_scan.o
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/acpi/boot.c
--- a/xen/arch/x86/acpi/boot.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/acpi/boot.c Tue Nov 25 14:21:24 2008 +0900
@@ -601,7 +601,7 @@ static int __init acpi_parse_madt_ioapic
count =
acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
- NR_IRQ_VECTORS);
+ MAX_IRQ_SOURCES);
if (count < 0) {
printk(KERN_ERR PREFIX
"Error parsing interrupt source overrides entry\n");
@@ -623,7 +623,7 @@ static int __init acpi_parse_madt_ioapic
count =
acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
- NR_IRQ_VECTORS);
+ MAX_IRQ_SOURCES);
if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/acpi/power.c
--- a/xen/arch/x86/acpi/power.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/acpi/power.c Tue Nov 25 14:21:24 2008 +0900
@@ -30,6 +30,8 @@
#include <acpi/cpufreq/cpufreq.h>
+uint32_t system_reset_counter = 1;
+
static char opt_acpi_sleep[20];
string_param("acpi_sleep", opt_acpi_sleep);
@@ -75,19 +77,47 @@ static void freeze_domains(void)
static void freeze_domains(void)
{
struct domain *d;
-
+ struct vcpu *v;
+
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
- if ( d->domain_id != 0 )
+ {
+ switch ( d->domain_id )
+ {
+ case 0:
+ for_each_vcpu ( d, v )
+ if ( v != current )
+ vcpu_pause(v);
+ break;
+ default:
domain_pause(d);
+ break;
+ }
+ }
+ rcu_read_unlock(&domlist_read_lock);
}
static void thaw_domains(void)
{
struct domain *d;
-
+ struct vcpu *v;
+
+ rcu_read_lock(&domlist_read_lock);
for_each_domain ( d )
- if ( d->domain_id != 0 )
+ {
+ switch ( d->domain_id )
+ {
+ case 0:
+ for_each_vcpu ( d, v )
+ if ( v != current )
+ vcpu_unpause(v);
+ break;
+ default:
domain_unpause(d);
+ break;
+ }
+ }
+ rcu_read_unlock(&domlist_read_lock);
}
static void acpi_sleep_prepare(u32 state)
@@ -163,6 +193,7 @@ static int enter_state(u32 state)
{
case ACPI_STATE_S3:
do_suspend_lowlevel();
+ system_reset_counter++;
break;
case ACPI_STATE_S5:
acpi_enter_sleep_state(ACPI_STATE_S5);
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/copy_page.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/copy_page.S Tue Nov 25 14:21:24 2008 +0900
@@ -0,0 +1,66 @@
+#include <xen/config.h>
+#include <asm/page.h>
+
+#ifdef __i386__
+#define src_reg %esi
+#define dst_reg %edi
+#define WORD_SIZE 4
+#define tmp1_reg %eax
+#define tmp2_reg %edx
+#define tmp3_reg %ebx
+#define tmp4_reg %ebp
+#else
+#define src_reg %rsi
+#define dst_reg %rdi
+#define WORD_SIZE 8
+#define tmp1_reg %r8
+#define tmp2_reg %r9
+#define tmp3_reg %r10
+#define tmp4_reg %r11
+#endif
+
+ENTRY(copy_page_sse2)
+#ifdef __i386__
+ push %ebx
+ push %ebp
+ push %esi
+ push %edi
+ mov 6*4(%esp), src_reg
+ mov 5*4(%esp), dst_reg
+#endif
+ mov $PAGE_SIZE/(4*WORD_SIZE)-3, %ecx
+
+ prefetchnta 2*4*WORD_SIZE(src_reg)
+ mov (src_reg), tmp1_reg
+ mov WORD_SIZE(src_reg), tmp2_reg
+ mov 2*WORD_SIZE(src_reg), tmp3_reg
+ mov 3*WORD_SIZE(src_reg), tmp4_reg
+
+0: prefetchnta 3*4*WORD_SIZE(src_reg)
+1: add $4*WORD_SIZE, src_reg
+ movnti tmp1_reg, (dst_reg)
+ mov (src_reg), tmp1_reg
+ dec %ecx
+ movnti tmp2_reg, WORD_SIZE(dst_reg)
+ mov WORD_SIZE(src_reg), tmp2_reg
+ movnti tmp3_reg, 2*WORD_SIZE(dst_reg)
+ mov 2*WORD_SIZE(src_reg), tmp3_reg
+ movnti tmp4_reg, 3*WORD_SIZE(dst_reg)
+ lea 4*WORD_SIZE(dst_reg), dst_reg
+ mov 3*WORD_SIZE(src_reg), tmp4_reg
+ jg 0b
+ jpe 1b
+
+ movnti tmp1_reg, (dst_reg)
+ movnti tmp2_reg, WORD_SIZE(dst_reg)
+ movnti tmp3_reg, 2*WORD_SIZE(dst_reg)
+ movnti tmp4_reg, 3*WORD_SIZE(dst_reg)
+
+#ifdef __i386__
+ pop %edi
+ pop %esi
+ pop %ebp
+ pop %ebx
+#endif
+ sfence
+ ret
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/cpu/common.c Tue Nov 25 14:21:24 2008 +0900
@@ -564,7 +564,10 @@ void __cpuinit cpu_init(void)
{
int cpu = smp_processor_id();
struct tss_struct *t = &init_tss[cpu];
- char gdt_load[10];
+ struct desc_ptr gdt_desc = {
+ .base = (unsigned long)(this_cpu(gdt_table) -
FIRST_RESERVED_GDT_ENTRY),
+ .limit = LAST_RESERVED_GDT_BYTE
+ };
if (cpu_test_and_set(cpu, cpu_initialized)) {
printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
@@ -578,9 +581,7 @@ void __cpuinit cpu_init(void)
/* Install correct page table. */
write_ptbase(current);
- *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE;
- *(unsigned long *)(&gdt_load[2]) = GDT_VIRT_START(current);
- asm volatile ( "lgdt %0" : "=m" (gdt_load) );
+ asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
/* No nested task. */
asm volatile ("pushf ; andw $0xbfff,(%"__OP"sp) ; popf" );
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/cpu/mcheck/p4.c
--- a/xen/arch/x86/cpu/mcheck/p4.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/cpu/mcheck/p4.c Tue Nov 25 14:21:24 2008 +0900
@@ -51,7 +51,7 @@ static void intel_thermal_interrupt(stru
ack_APIC_irq();
- if (NOW() > next[cpu])
+ if (NOW() < next[cpu])
return;
next[cpu] = NOW() + MILLISECS(5000);
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/domain.c Tue Nov 25 14:21:24 2008 +0900
@@ -184,7 +184,8 @@ static int setup_compat_l4(struct vcpu *
/* This page needs to look like a pagetable so that it can be shadowed */
pg->u.inuse.type_info = PGT_l4_page_table|PGT_validated|1;
- l4tab = copy_page(page_to_virt(pg), idle_pg_table);
+ l4tab = page_to_virt(pg);
+ copy_page(l4tab, idle_pg_table);
l4tab[0] = l4e_empty();
l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] =
l4e_from_page(pg, __PAGE_HYPERVISOR);
@@ -310,12 +311,7 @@ int vcpu_initialise(struct vcpu *v)
if ( is_idle_domain(d) )
{
v->arch.schedule_tail = continue_idle_domain;
- if ( v->vcpu_id )
- v->arch.cr3 = d->vcpu[0]->arch.cr3;
- else if ( !*idle_vcpu )
- v->arch.cr3 = __pa(idle_pg_table);
- else if ( !(v->arch.cr3 = clone_idle_pagetable(v)) )
- return -ENOMEM;
+ v->arch.cr3 = __pa(idle_pg_table);
}
v->arch.guest_context.ctrlreg[4] =
@@ -1172,14 +1168,18 @@ static void paravirt_ctxt_switch_to(stru
}
}
+static inline int need_full_gdt(struct vcpu *v)
+{
+ return (!is_hvm_vcpu(v) && !is_idle_vcpu(v));
+}
+
static void __context_switch(void)
{
struct cpu_user_regs *stack_regs = guest_cpu_user_regs();
- unsigned int i, cpu = smp_processor_id();
+ unsigned int cpu = smp_processor_id();
struct vcpu *p = per_cpu(curr_vcpu, cpu);
struct vcpu *n = current;
struct desc_struct *gdt;
- struct page_info *page;
struct desc_ptr gdt_desc;
ASSERT(p != n);
@@ -1208,16 +1208,19 @@ static void __context_switch(void)
gdt = !is_pv_32on64_vcpu(n) ? per_cpu(gdt_table, cpu) :
per_cpu(compat_gdt_table, cpu);
- page = virt_to_page(gdt);
- for (i = 0; i < NR_RESERVED_GDT_PAGES; ++i)
- {
- l1e_write(n->domain->arch.mm_perdomain_pt +
- (n->vcpu_id << GDT_LDT_VCPU_SHIFT) +
- FIRST_RESERVED_GDT_PAGE + i,
- l1e_from_page(page + i, __PAGE_HYPERVISOR));
- }
-
- if ( p->vcpu_id != n->vcpu_id )
+ if ( need_full_gdt(n) )
+ {
+ struct page_info *page = virt_to_page(gdt);
+ unsigned int i;
+ for ( i = 0; i < NR_RESERVED_GDT_PAGES; i++ )
+ l1e_write(n->domain->arch.mm_perdomain_pt +
+ (n->vcpu_id << GDT_LDT_VCPU_SHIFT) +
+ FIRST_RESERVED_GDT_PAGE + i,
+ l1e_from_page(page + i, __PAGE_HYPERVISOR));
+ }
+
+ if ( need_full_gdt(p) &&
+ ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(n)) )
{
gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
gdt_desc.base = (unsigned long)(gdt - FIRST_RESERVED_GDT_ENTRY);
@@ -1226,8 +1229,10 @@ static void __context_switch(void)
write_ptbase(n);
- if ( p->vcpu_id != n->vcpu_id )
- {
+ if ( need_full_gdt(n) &&
+ ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(p)) )
+ {
+ gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
gdt_desc.base = GDT_VIRT_START(n);
asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
}
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/domain_build.c Tue Nov 25 14:21:24 2008 +0900
@@ -194,30 +194,6 @@ static void __init process_dom0_ioports_
}
}
-/* We run on dom0's page tables for the final part of the build process. */
-static void dom0_pt_enter(struct vcpu *v)
-{
- struct desc_ptr gdt_desc = {
- .limit = LAST_RESERVED_GDT_BYTE,
- .base = (unsigned long)(this_cpu(gdt_table) - FIRST_RESERVED_GDT_ENTRY)
- };
-
- asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
- write_ptbase(v);
-}
-
-/* Return to idle domain's page tables. */
-static void dom0_pt_exit(void)
-{
- struct desc_ptr gdt_desc = {
- .limit = LAST_RESERVED_GDT_BYTE,
- .base = GDT_VIRT_START(current)
- };
-
- write_ptbase(current);
- asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
-}
-
int __init construct_dom0(
struct domain *d,
unsigned long _image_start, unsigned long image_len,
@@ -479,8 +455,9 @@ int __init construct_dom0(
/* WARNING: The new domain must have its 'processor' field filled in! */
l3start = l3tab = (l3_pgentry_t *)mpt_alloc; mpt_alloc += PAGE_SIZE;
l2start = l2tab = (l2_pgentry_t *)mpt_alloc; mpt_alloc += 4*PAGE_SIZE;
- memcpy(l2tab, idle_pg_table_l2, 4*PAGE_SIZE);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < L3_PAGETABLE_ENTRIES; i++) {
+ copy_page(l2tab + i * L2_PAGETABLE_ENTRIES,
+ idle_pg_table_l2 + i * L2_PAGETABLE_ENTRIES);
l3tab[i] = l3e_from_paddr((u32)l2tab + i*PAGE_SIZE, L3_PROT);
l2tab[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT)+i] =
l2e_from_paddr((u32)l2tab + i*PAGE_SIZE, __PAGE_HYPERVISOR);
@@ -729,7 +706,8 @@ int __init construct_dom0(
else
update_cr3(v);
- dom0_pt_enter(v);
+ /* We run on dom0's page tables for the final part of the build process. */
+ write_ptbase(v);
/* Copy the OS image and free temporary buffer. */
elf.dest = (void*)vkern_start;
@@ -741,11 +719,11 @@ int __init construct_dom0(
(parms.virt_hypercall >= v_end) )
{
write_ptbase(current);
- local_irq_enable();
printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
return -1;
}
- hypercall_page_initialise(d, (void *)(unsigned
long)parms.virt_hypercall);
+ hypercall_page_initialise(
+ d, (void *)(unsigned long)parms.virt_hypercall);
}
/* Copy the initial ramdisk. */
@@ -826,7 +804,8 @@ int __init construct_dom0(
xlat_start_info(si, XLAT_start_info_console_dom0);
#endif
- dom0_pt_exit();
+ /* Return to idle domain's page tables. */
+ write_ptbase(current);
#if defined(__i386__)
/* Destroy low mappings - they were only for our convenience. */
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/domctl.c Tue Nov 25 14:21:24 2008 +0900
@@ -1074,11 +1074,24 @@ void arch_get_info_guest(struct vcpu *v,
if ( is_hvm_vcpu(v) )
{
+ struct segment_register sreg;
memset(c.nat->ctrlreg, 0, sizeof(c.nat->ctrlreg));
c.nat->ctrlreg[0] = v->arch.hvm_vcpu.guest_cr[0];
c.nat->ctrlreg[2] = v->arch.hvm_vcpu.guest_cr[2];
c.nat->ctrlreg[3] = v->arch.hvm_vcpu.guest_cr[3];
c.nat->ctrlreg[4] = v->arch.hvm_vcpu.guest_cr[4];
+ hvm_get_segment_register(v, x86_seg_cs, &sreg);
+ c.nat->user_regs.cs = sreg.sel;
+ hvm_get_segment_register(v, x86_seg_ss, &sreg);
+ c.nat->user_regs.ss = sreg.sel;
+ hvm_get_segment_register(v, x86_seg_ds, &sreg);
+ c.nat->user_regs.ds = sreg.sel;
+ hvm_get_segment_register(v, x86_seg_es, &sreg);
+ c.nat->user_regs.es = sreg.sel;
+ hvm_get_segment_register(v, x86_seg_fs, &sreg);
+ c.nat->user_regs.fs = sreg.sel;
+ hvm_get_segment_register(v, x86_seg_gs, &sreg);
+ c.nat->user_regs.gs = sreg.sel;
}
else
{
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/hpet.c Tue Nov 25 14:21:24 2008 +0900
@@ -265,23 +265,20 @@ u64 hpet_setup(void)
u64 hpet_setup(void)
{
static u64 hpet_rate;
- static int initialised;
+ static u32 system_reset_latch;
u32 hpet_id, hpet_period, cfg;
int i;
- if ( initialised )
+ if ( system_reset_latch == system_reset_counter )
return hpet_rate;
- initialised = 1;
-
- if ( hpet_address == 0 )
- return 0;
+ system_reset_latch = system_reset_counter;
set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
hpet_id = hpet_read32(HPET_ID);
- if ( hpet_id == 0 )
- {
- printk("BAD HPET vendor id.\n");
+ if ( (hpet_id & HPET_ID_REV) == 0 )
+ {
+ printk("BAD HPET revision id.\n");
return 0;
}
@@ -299,9 +296,9 @@ u64 hpet_setup(void)
for ( i = 0; i <= ((hpet_id >> 8) & 31); i++ )
{
- cfg = hpet_read32(HPET_T0_CFG + i*0x20);
+ cfg = hpet_read32(HPET_Tn_CFG(i));
cfg &= ~HPET_TN_ENABLE;
- hpet_write32(cfg & ~HPET_TN_ENABLE, HPET_T0_CFG);
+ hpet_write32(cfg, HPET_Tn_CFG(i));
}
cfg = hpet_read32(HPET_CFG);
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/hvm/hvm.c Tue Nov 25 14:21:24 2008 +0900
@@ -1884,6 +1884,25 @@ static long hvm_memory_op(int cmd, XEN_G
return rc;
}
+static long hvm_vcpu_op(
+ int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
+{
+ long rc;
+
+ switch ( cmd )
+ {
+ case VCPUOP_register_runstate_memory_area:
+ case VCPUOP_get_runstate_info:
+ rc = do_vcpu_op(cmd, vcpuid, arg);
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
+}
+
typedef unsigned long hvm_hypercall_t(
unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
@@ -1895,6 +1914,7 @@ static hvm_hypercall_t *hvm_hypercall32_
static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = {
[ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,
[ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
+ [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,
HYPERCALL(xen_version),
HYPERCALL(event_channel_op),
HYPERCALL(sched_op),
@@ -1911,9 +1931,29 @@ static long hvm_memory_op_compat32(int c
return rc;
}
+static long hvm_vcpu_op_compat32(
+ int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
+{
+ long rc;
+
+ switch ( cmd )
+ {
+ case VCPUOP_register_runstate_memory_area:
+ case VCPUOP_get_runstate_info:
+ rc = compat_vcpu_op(cmd, vcpuid, arg);
+ break;
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
+}
+
static hvm_hypercall_t *hvm_hypercall64_table[NR_hypercalls] = {
[ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,
[ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
+ [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,
HYPERCALL(xen_version),
HYPERCALL(event_channel_op),
HYPERCALL(sched_op),
@@ -1923,6 +1963,7 @@ static hvm_hypercall_t *hvm_hypercall32_
static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = {
[ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op_compat32,
[ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,
+ [ __HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op_compat32,
HYPERCALL(xen_version),
HYPERCALL(event_channel_op),
HYPERCALL(sched_op),
@@ -2081,7 +2122,7 @@ static int hvmop_set_pci_intx_level(
void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip)
{
- struct domain *d = current->domain;
+ struct domain *d = v->domain;
struct vcpu_guest_context *ctxt;
struct segment_register reg;
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/hvm/mtrr.c
--- a/xen/arch/x86/hvm/mtrr.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/hvm/mtrr.c Tue Nov 25 14:21:24 2008 +0900
@@ -392,12 +392,16 @@ uint32_t get_pat_flags(struct vcpu *v,
*/
if ( pat_entry_value == INVALID_MEM_TYPE )
{
- gdprintk(XENLOG_WARNING,
- "Conflict occurs for a given guest l1e flags:%x "
- "at %"PRIx64" (the effective mm type:%d), "
- "because the host mtrr type is:%d\n",
- gl1e_flags, (uint64_t)gpaddr, guest_eff_mm_type,
- shadow_mtrr_type);
+ struct domain *d = v->domain;
+ p2m_type_t p2mt;
+ gfn_to_mfn(d, paddr_to_pfn(gpaddr), &p2mt);
+ if (p2m_is_ram(p2mt))
+ gdprintk(XENLOG_WARNING,
+ "Conflict occurs for a given guest l1e flags:%x "
+ "at %"PRIx64" (the effective mm type:%d), "
+ "because the host mtrr type is:%d\n",
+ gl1e_flags, (uint64_t)gpaddr, guest_eff_mm_type,
+ shadow_mtrr_type);
pat_entry_value = PAT_TYPE_UNCACHABLE;
}
/* 4. Get the pte flags */
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Tue Nov 25 14:21:24 2008 +0900
@@ -739,6 +739,23 @@ static void svm_inject_exception(
struct vmcb_struct *vmcb = curr->arch.hvm_svm.vmcb;
eventinj_t event = vmcb->eventinj;
+ switch ( trapnr )
+ {
+ case TRAP_debug:
+ if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
+ {
+ __restore_debug_registers(curr);
+ vmcb->dr6 |= 0x4000;
+ }
+ case TRAP_int3:
+ if ( curr->domain->debugger_attached )
+ {
+ /* Debug/Int3: Trap to debugger. */
+ domain_pause_for_debugger();
+ return;
+ }
+ }
+
if ( unlikely(event.fields.v) &&
(event.fields.type == X86_EVENTTYPE_HW_EXCEPTION) )
{
@@ -764,13 +781,6 @@ static void svm_inject_exception(
else
{
HVMTRACE_2D(INJ_EXC, trapnr, errcode);
- }
-
- if ( (trapnr == TRAP_debug) &&
- (guest_cpu_user_regs()->eflags & X86_EFLAGS_TF) )
- {
- __restore_debug_registers(curr);
- vmcb->dr6 |= 0x4000;
}
}
diff -r 7ef733b961c8 -r 436816898c87 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Tue Nov 18 10:55:51 2008 +0100
+++ b/xen/arch/x86/hvm/vioapic.c Tue Nov 25 14:21:24 2008 +0900
@@ -344,8 +344,8 @@ static void vioapic_deliver(struct hvm_h
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|