[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |