# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Node ID 645ef4726bce548ee348f1a9333020bd7d23826f
# Parent 58f28e00001e3015f09ad74fe6a23bb4bcae93af
[XEND] Fix missing domains on domU reboot.
Fixed regression with rebooting domU caused by the change in handling
syncing state from Xen and Xend.
Added missing implementation for XendDomainInfo.unwatchVm() which
disappeared during a merge.
Added protection for console/vnc-port reading for managed domains.
Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx>
---
tools/python/xen/xend/XendConfig.py | 2 -
tools/python/xen/xend/XendDomain.py | 46 +++++++++++++++++++++-----------
tools/python/xen/xend/XendDomainInfo.py | 20 ++++++++++---
3 files changed, 47 insertions(+), 21 deletions(-)
diff -r 58f28e00001e -r 645ef4726bce tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Nov 17 14:00:45 2006 +0000
+++ b/tools/python/xen/xend/XendConfig.py Fri Nov 17 15:53:29 2006 +0000
@@ -583,7 +583,7 @@ class XendConfig(dict):
old_state = sxp.child_value(parsed, 'state')
if old_state:
for i in range(len(CONFIG_OLD_DOM_STATES)):
- cfg[CONFIG_OLD_DOM_STATES[i]] = (old_state[i] != '-')
+ cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-')
# Xen API extra cfgs
# ------------------
diff -r 58f28e00001e -r 645ef4726bce tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Nov 17 14:00:45 2006 +0000
+++ b/tools/python/xen/xend/XendDomain.py Fri Nov 17 15:53:29 2006 +0000
@@ -33,7 +33,7 @@ from xen.xend import XendRoot, XendCheck
from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo
from xen.xend.PrettyPrint import prettyprint
from xen.xend.XendConfig import XendConfig
-from xen.xend.XendError import XendError, XendInvalidDomain
+from xen.xend.XendError import XendError, XendInvalidDomain, VmError
from xen.xend.XendLogging import log
from xen.xend.XendConstants import XS_VMROOT
from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_RUNNING
@@ -65,7 +65,6 @@ class XendDomain:
@type domains_lock: threaading.RLock
@ivar _allow_new_domains: Flag to set that allows creating of new domains.
@type _allow_new_domains: boolean
-
"""
def __init__(self):
@@ -281,9 +280,13 @@ class XendDomain:
sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
sxp_cache_file.close()
- except IOError:
- log.error("Error occurred saving configuration file to %s" %
- domain_config_dir)
+ except:
+ log.exception("Error occurred saving configuration file " +
+ "to %s" % domain_config_dir)
+ try:
+ self._managed_domain_remove(dom_uuid)
+ except:
+ pass
raise XendError("Failed to save configuration file to: %s" %
domain_config_dir)
else:
@@ -377,19 +380,33 @@ class XendDomain:
# update information for all running domains
# - like cpu_time, status, dying, etc.
running = self._running_domains()
+ running_domids = [d['domid'] for d in running if d['dying'] != 1]
+
+ # remove domains that are not running from active domain list.
+ # The list might have changed by now, because the update call may
+ # cause new domains to be added, if the domain has rebooted. We get
+ # the list again.
+ for domid, dom in self.domains.items():
+ if domid not in running_domids and domid != DOM0_ID:
+ self._remove_domain(dom, domid)
+
+ # Add domains that are not already tracked but running in Xen,
+ # and update domain state for those that are running and tracked.
for dom in running:
domid = dom['domid']
if domid in self.domains and dom['dying'] != 1:
self.domains[domid].update(dom)
-
- # remove domains that are not running from active domain list.
- # The list might have changed by now, because the update call may
- # cause new domains to be added, if the domain has rebooted. We get
- # the list again.
- running_domids = [d['domid'] for d in running if d['dying'] != 1]
- for domid, dom in self.domains.items():
- if domid not in running_domids and domid != DOM0_ID:
- self._remove_domain(dom, domid)
+ elif domid not in self.domains and dom['dying'] != 1:
+ try:
+ new_dom = XendDomainInfo.recreate(dom, False)
+ self._add_domain(new_dom)
+ except VmError:
+ log.exception("Unable to recreate domain")
+ try:
+ xc.domain_destroy(domid)
+ except:
+ log.exception("Hard destruction of domain failed: %d" %
+ domid)
def _add_domain(self, info):
@@ -409,7 +426,6 @@ class XendDomain:
@param info: XendDomainInfo of a domain to be removed.
@type info: XendDomainInfo
"""
-
if info:
if domid == None:
domid = info.getDomid()
diff -r 58f28e00001e -r 645ef4726bce tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Nov 17 14:00:45 2006 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Nov 17 15:53:29 2006 +0000
@@ -403,7 +403,7 @@ class XendDomainInfo:
self.vmWatch = None
self.shutdownWatch = None
self.shutdownStartTime = None
-
+
self.state = DOM_STATE_HALTED
self.state_updated = threading.Condition()
self.refresh_shutdown_lock = threading.Condition()
@@ -430,7 +430,7 @@ class XendDomainInfo:
initialisation if it not started.
"""
from xen.xend import XendDomain
-
+
if self.state == DOM_STATE_HALTED:
try:
self._constructDomain()
@@ -443,7 +443,6 @@ class XendDomainInfo:
# save running configuration if XendDomains believe domain is
# persistent
- #
if is_managed:
xendomains = XendDomain.instance()
xendomains.managed_config_save(self)
@@ -475,6 +474,9 @@ class XendDomainInfo:
log.debug('XendDomainInfo.shutdown')
if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
raise XendError('Domain cannot be shutdown')
+
+ if self.domid == 0:
+ raise XendError('Domain 0 cannot be shutdown')
if not reason in DOMAIN_SHUTDOWN_REASONS.values():
raise XendError('Invalid reason: %s' % reason)
@@ -920,7 +922,7 @@ class XendDomainInfo:
# the VM path now, otherwise we will end up with one
# watch for the old domain, and one for the new.
self._unwatchVm()
- elif reason in ['poweroff', 'reboot']:
+ elif reason in ('poweroff', 'reboot'):
restart_reason = reason
else:
self.destroy()
@@ -1521,6 +1523,14 @@ class XendDomainInfo:
def _unwatchVm(self):
"""Remove the watch on the VM path, if any. Idempotent. Nothrow
guarantee."""
+ try:
+ try:
+ if self.vmWatch:
+ self.vmWatch.unwatch()
+ finally:
+ self.vmWatch = None
+ except:
+ log.exception("Unwatching VM path failed.")
def testDeviceComplete(self):
""" For Block IO migration safety we must ensure that
@@ -1663,7 +1673,7 @@ class XendDomainInfo:
result = self.info.get_sxp(domain = self,
ignore_devices = ignore_store)
- if not ignore_store:
+ if not ignore_store and self.dompath:
vnc_port = self._readDom('console/vnc-port')
if vnc_port is not None:
result.append(['device',
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|