Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1
xen
xend-domain-lock.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xend-domain-lock.patch of Package xen
Index: xen-3.3.1-testing/tools/examples/domain-lock =================================================================== --- /dev/null +++ xen-3.3.1-testing/tools/examples/domain-lock @@ -0,0 +1,83 @@ +#!/bin/bash + +basedir=$(dirname "$0") + +usage() { + echo "usage: domain-lock [-l|-u] -n <vm name> -i <vm uuid> -p <physical host> path" + echo "usage: domain-lock [-s] path" + echo "" + echo "-l lock" + echo "-u unlock" + echo "-s status (default)" + echo "-n Virtual Machine name" + echo "-i Virtual Machine Id or UUID" + echo "-p Virtual Machine Server (physical host) name" + echo "path A per-VM, unique location where external lock will be managed" + exit 1 +} + +remove_lock(){ + local path=$1/lock + local name=$2 + + pid=`ps -efwww | grep vm-monitor | grep $name | awk '{print $2}'` + if [ -n "$pid" ]; then + kill $pid + rm -f $path + fi +} + +get_status(){ + local path=$1/lock + [ -f $path ] || exit 1 + + rc=`flock -xn $path /bin/true` + cat $path + exit $rc +} + +mode="status" + +while getopts ":lusn:i:p:" opt; do + case $opt in + l ) + mode="lock" + ;; + u ) + mode="unlock" + ;; + s ) + mode="status" + ;; + p ) + vm_host=$OPTARG + ;; + n ) + vm_name=$OPTARG + ;; + i ) + vm_uuid=$OPTARG + ;; + \? ) + usage + ;; + esac +done + +shift $(($OPTIND - 1)) +vm_path=$1 + +case $mode in + lock ) + [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage + $basedir/set-lock $vm_path $vm_name $vm_uuid $vm_host + ;; + unlock ) + [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage + remove_lock $vm_path $vm_name $vm_uuid $vm_host + ;; + status ) + [ -z "$vm_path" ] && usage + get_status $vm_path + ;; +esac Index: xen-3.3.1-testing/tools/examples/xend-config.sxp =================================================================== --- xen-3.3.1-testing.orig/tools/examples/xend-config.sxp +++ xen-3.3.1-testing/tools/examples/xend-config.sxp @@ -255,4 +255,46 @@ # Path where persistent domain configuration is stored. # Default is /var/lib/xend/domains/ +# #(xend-domains-path /var/lib/xend/domains) + +# Create an external lock file when domains are started. Lock +# file is placed in xend-domains-lock-path/<domain_uuid> on domain +# startup and removed when domain is stopped. By default, a lock file +# is not created. Set to yes to enable lock file creation. +# Note that external locking mechanisms are no substitute for a cluster +# environment that protects shared resources, but may be useful in +# some circumstances nonetheless. +# +#(xend-domain-lock no) + +# Path where domain lock is stored if xend-domain-lock is enabled. +# Note: This path must be accessible to all VM Servers participating +# in domain locking, e.g. by specifying a shared mount point. +# Lock is placed in <xend-domain-lock-path>/<domain-uuid>. +# Default is /var/lib/xend/domains/ +# +#(xend-domain-lock-path /var/lib/xend/domains) + +# External locking utility for acquiring/releasing domain lock. +# By default /etc/xen/scripts/domain-lock will be used if +# xend-domain-lock is set to yes. Set to path of custom +# locking utility to override the default. Synopsis: +# +# lock-util <-l | -u | -s> [-n <vm-name>] [-i <vm-id>] [-p <phy-host>] path +# +# Utility should return zero on success, non-zero on error. +# -l lock Acquire (create) lock file +# -u unlock Remove lock file +# -s status Default action. If lock file exists, print contents on +# stdout and return 0) +# -p phy-host Name of physical host (dom0) +# -n vm-name Name of domain +# -i vm-id Id or UUID of domain +# path A unique location for external lock must be specified +# +# The /etc/xen/scripts/domain-lock default utility will create +# <xend-domain-lock-path>/<vm-uuid>/lock and write <vm-name>, <vm-id>, +# and <vm-host> (if supplied) to the lock file in that order. +# +#(xend-domain-lock-utility domain-lock) Index: xen-3.3.1-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.3.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.3.1-testing/tools/python/xen/xend/XendDomainInfo.py @@ -30,11 +30,13 @@ import threading import re import copy import os +import stat +import shutil import traceback from types import StringTypes import xen.lowlevel.xc -from xen.util import asserts +from xen.util import asserts, mkdir from xen.util.blkif import parse_uname import xen.util.xsm.xsm as security from xen.util import xsconstants @@ -443,6 +445,7 @@ class XendDomainInfo: if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED): try: + self.acquire_running_lock(); XendTask.log_progress(0, 30, self._constructDomain) XendTask.log_progress(31, 60, self._initDomain) @@ -2348,6 +2351,11 @@ class XendDomainInfo: self._stateSet(DOM_STATE_HALTED) self.domid = None # Do not push into _stateSet()! + + try: + self.release_running_lock() + except: + log.exception("Failed to release domain lock.") finally: self.refresh_shutdown_lock.release() @@ -3581,6 +3589,74 @@ class XendDomainInfo: def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) + # Return name of host contained in lock file. + def get_lock_host(self, path): + fin = os.popen(xoptions.get_xend_domain_lock_utility() + \ + ' -s ' + path, 'r') + hostname = "unknown" + + try: + tokens = fin.readline().split() + for token in tokens: + item = token.split('=') + if item[0] == 'host': + hostname = item[1] + return hostname + finally: + fin.close() + + # Acquire a lock for the domain. No-op if domain locking is turned off. + def acquire_running_lock(self): + if not xoptions.get_xend_domain_lock(): + return + + log.debug("Acquiring lock for domain %s" % self.info['name_label']) + path = xoptions.get_xend_domain_lock_path() + path = os.path.join(path, self.get_uuid()) + + try: + if not os.path.exists(path): + mkdir.parents(path, stat.S_IRWXU) + except: + log.exception("%s could not be created." % path) + raise XendError("%s could not be created." % path) + + status = os.system('%s -l -p %s -n %s -i %s %s' % \ + (xoptions.get_xend_domain_lock_utility(), \ + XendNode.instance().get_name(), \ + self.info['name_label'], \ + self.info['uuid'], \ + path)) + if status != 0: + log.debug("Failed to aqcuire lock: status = %d" % status) + raise XendError("The VM is locked and appears to be running on host %s." % self.get_lock_host(path)) + + # Release lock for domain. No-op if domain locking is turned off. + def release_running_lock(self, name = None): + if not xoptions.get_xend_domain_lock(): + return + + dom_name = self.info['name_label'] + if name: + dom_name = name + log.debug("Releasing lock for domain %s" % dom_name) + + path = xoptions.get_xend_domain_lock_path() + path = os.path.join(path, self.get_uuid()) + status = os.system('%s -u -p %s -n %s -i %s %s' % \ + (xoptions.get_xend_domain_lock_utility(), \ + XendNode.instance().get_name(), \ + dom_name, \ + self.info['uuid'], \ + path)) + if status != 0: + log.exception("Failed to release lock: status = %s" % status) + try: + if len(os.listdir(path)) == 0: + shutil.rmtree(path) + except: + log.exception("Failed to remove unmanaged directory %s." % path) + def __str__(self): return '<domain id=%s name=%s memory=%s state=%s>' % \ (str(self.domid), self.info['name_label'], Index: xen-3.3.1-testing/tools/python/xen/xend/XendOptions.py =================================================================== --- xen-3.3.1-testing.orig/tools/python/xen/xend/XendOptions.py +++ xen-3.3.1-testing/tools/python/xen/xend/XendOptions.py @@ -135,6 +135,17 @@ class XendOptions: """Default rotation count of qemu-dm log file.""" qemu_dm_logrotate_count = 10 + """Default for the flag indicating whether xend should create + a lock file for domains when they are started.""" + xend_domain_lock = 'no' + + """Default domain lock storage path.""" + xend_domain_lock_path_default = '/var/lib/xend/domains' + + """Default script to acquire/release domain lock""" + xend_domain_lock_utility = osdep.scripts_dir + "/domain-lock" + + def __init__(self): self.configure() @@ -358,6 +369,24 @@ class XendOptions: return self.get_config_int("qemu-dm-logrotate-count", self.qemu_dm_logrotate_count) + def get_xend_domain_lock(self): + """Get the flag indicating whether xend should create a lock file + for domains when they are started.""" + return self.get_config_bool("xend-domain-lock", self.xend_domain_lock) + + def get_xend_domain_lock_path(self): + """ Get the path for domain lock storage + """ + return self.get_config_string("xend-domain-lock-path", self.xend_domain_lock_path_default) + + def get_xend_domain_lock_utility(self): + s = self.get_config_string('xend-domain-lock-utility') + + if s: + return os.path.join(osdep.scripts_dir, s) + else: + return self.xend_domain_lock_utility + class XendOptionsFile(XendOptions): Index: xen-3.3.1-testing/tools/examples/Makefile =================================================================== --- xen-3.3.1-testing.orig/tools/examples/Makefile +++ xen-3.3.1-testing/tools/examples/Makefile @@ -35,6 +35,7 @@ XEN_SCRIPTS += vtpm vtpm-delete XEN_SCRIPTS += xen-hotplug-cleanup XEN_SCRIPTS += external-device-migrate XEN_SCRIPTS += vscsi +XEN_SCRIPTS += domain-lock vm-monitor 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 Index: xen-3.3.1-testing/tools/python/xen/xend/XendCheckpoint.py =================================================================== --- xen-3.3.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py +++ xen-3.3.1-testing/tools/python/xen/xend/XendCheckpoint.py @@ -110,6 +110,7 @@ def save(fd, dominfo, network, live, dst dominfo.shutdown('suspend') dominfo.waitForShutdown() if line in ('suspend', 'suspended'): + dominfo.release_running_lock(domain_name) dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) log.info("Domain %d suspended.", dominfo.getDomid()) @@ -387,6 +388,7 @@ def restore(xd, fd, dominfo = None, paus if not paused: dominfo.unpause() + dominfo.acquire_running_lock() return dominfo except: dominfo.destroy() Index: xen-3.3.1-testing/tools/examples/vm-monitor =================================================================== --- /dev/null +++ xen-3.3.1-testing/tools/examples/vm-monitor @@ -0,0 +1,41 @@ +#!/bin/bash + +basedir=$(dirname "$0") +HA_TICK=2 + +monitor() { + local path=$1 + local name=$2 + local uuid=$3 + local host=$4 + local count=0 + path=$path/lock + + while : + do + echo "name=$name uuid=$uuid host=$host count=$count" > $path + count=$(($count+1)) + sleep $HA_TICK + done& +} + +create_lock() { + local path=$1/lock + local rc=0 + + [ -f $path ] || touch $path + flock -x -w $HA_TICK $path $basedir/vm-monitor $* + rc=$? + if [ $rc -eq 1 ]; then + echo `cat $path` + exit 1 + else + exit $rc + fi +} + +if [ $0 = "$basedir/set-lock" ]; then + create_lock $* +elif [ $0 = "$basedir/vm-monitor" ]; then + monitor $* +fi
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor