[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merge
ChangeSet 1.1396, 2005/05/03 09:08:47+01:00, xenbk@xxxxxxxxxxxxxxxxxx Merge XendDomain.py | 462 ++++++++++++++++++++++++++++++---------------------------- XendRoot.py | 52 +++++- 2 files changed, 291 insertions(+), 223 deletions(-) diff -Nru a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py 2005-05-13 16:06:15 -04:00 +++ b/tools/python/xen/xend/XendDomain.py 2005-05-13 16:06:15 -04:00 @@ -6,30 +6,68 @@ """ import sys import traceback - -from twisted.internet import defer -#defer.Deferred.debug = 1 -from twisted.internet import reactor +import time import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() import sxp -import XendRoot -xroot = XendRoot.instance() +import XendRoot; xroot = XendRoot.instance() import XendDB import XendDomainInfo import XendMigrate -import EventServer +import EventServer; eserver = EventServer.instance() from XendError import XendError from XendLogging import log +from scheduler import Scheduler -from xen.xend.server import SrvDaemon -xend = SrvDaemon.instance() +from xen.xend.server import channel -eserver = EventServer.instance() __all__ = [ "XendDomain" ] + +SHUTDOWN_TIMEOUT = 30 + +class DomainShutdown: + """A pending domain shutdown. The domain is asked to shut down, + if it has not terminated or rebooted when the timeout expires it + is destroyed. + """ + + def __init__(self, dominfo, reason, key, timeout=None): + if timeout is None: + timeout = SHUTDOWN_TIMEOUT + self.start = time.time() + self.timeout = timeout + self.dominfo = dominfo + self.last_restart_time = dominfo.restart_time + self.last_restart_count = dominfo.restart_count + self.reason = reason + self.key = key + + def getDomain(self): + return self.dominfo.id + + def getDomainName(self): + return self.dominfo.name + + def getReason(self): + return self.reason + + def getTimeout(self): + return self.timeout + + def isTerminated(self): + return self.dominfo.is_terminated() + + def isRestarted(self): + return (self.dominfo.restart_count > self.last_restart_count) + + def isShutdown(self): + return self.isTerminated() or self.isRestarted() + + def isExpired(self): + return (time.time() - self.start) > self.timeout class XendDomain: """Index of all domains. Singleton. @@ -46,8 +84,11 @@ restarts_by_id = {} restarts_by_name = {} + """Table of pending domain shutdowns, indexed by domain id.""" + shutdowns_by_id = {} + """Table of delayed calls.""" - schedule = {} + scheduler = Scheduler() def __init__(self): # Hack alert. Python does not support mutual imports, but XendDomainInfo @@ -67,7 +108,8 @@ def onVirq(self, event, val): """Event handler for virq. """ - self.reap() + print 'onVirq>', val + self.refresh_schedule(delay=0) def schedule_later(self, _delay, _name, _fn, *args): """Schedule a function to be called later (if not already scheduled). @@ -77,34 +119,16 @@ @param _fn: function @param args: arguments """ - if self.schedule.get(_name): return - self.schedule[_name] = reactor.callLater(_delay, _fn, *args) + self.scheduler.later(_delay, _name, _fn, args) def schedule_cancel(self, name): """Cancel a scheduled function call. @param name: schedule name to cancel """ - callid = self.schedule.get(name) - if not callid: - return - if callid.active(): - callid.cancel() - del self.schedule[name] + self.scheduler.cancel(name) - def reap_schedule(self, delay=0): - """Schedule reap to be called later. - - @param delay: delay in seconds - """ - self.schedule_later(delay, 'reap', self.reap) - - def reap_cancel(self): - """Cancel any scheduled reap. - """ - self.schedule_cancel('reap') - - def refresh_schedule(self, delay=0): + def refresh_schedule(self, delay=1): """Schedule refresh to be called later. @param delay: delay in seconds @@ -116,7 +140,7 @@ """ self.schedule_cancel('refresh') - def domain_restarts_schedule(self, delay=0): + def domain_restarts_schedule(self, delay=1): """Schedule domain_restarts to be called later. @param delay: delay in seconds @@ -132,30 +156,46 @@ """Remove all domain info. Used after reboot. """ for (k, v) in self.domain_db.items(): - self._delete_domain(k, notify=0) - - def initial_refresh(self): - """Refresh initial domain info from domain_db. - """ - - def cb_all_ok(val): - self.refresh() + self._delete_domain(k, notify=False) + def xen_domains(self): + """Get table of domains indexed by id from xc. + """ domlist = xc.domain_getinfo() doms = {} for d in domlist: domid = str(d['dom']) doms[domid] = d - dlist = [] + return doms + + def xen_domain(self, dom): + """Get info about a single domain from xc. + Returns None if not found. + """ + dom = int(dom) + dominfo = xc.domain_getinfo(dom, 1) + if dominfo == [] or dominfo[0]['dom'] != dom: + dominfo = None + else: + dominfo = dominfo[0] + return dominfo + + def initial_refresh(self): + """Refresh initial domain info from domain_db. + """ + doms = self.xen_domains() for config in self.domain_db.values(): domid = str(sxp.child_value(config, 'id')) if domid in doms: - d_dom = self._new_domain(config, doms[domid]) - dlist.append(d_dom) + try: + self._new_domain(config, doms[domid]) + self.update_domain(domid) + except Exception, ex: + log.exception("Error recreating domain info: id=%s", domid) + self._delete_domain(domid) else: self._delete_domain(domid) - d_all = defer.DeferredList(dlist, fireOnOneErrback=1) - d_all.addCallback(cb_all_ok) + self.refresh() def sync(self): """Sync domain db to disk. @@ -177,35 +217,45 @@ @param savedinfo: saved info from the db @param info: domain info from xen - @return: deferred + @return: domain """ - def cbok(dominfo): - self.domain_by_id[dominfo.id] = dominfo - self.domain_by_name[dominfo.name] = dominfo - if dominfo.restart_pending(): - self.domain_restart_add(dominfo) - - deferred = XendDomainInfo.vm_recreate(savedinfo, info) - deferred.addCallback(cbok) - return deferred + dominfo = XendDomainInfo.vm_recreate(savedinfo, info) + self.domain_by_id[dominfo.id] = dominfo + self.domain_by_name[dominfo.name] = dominfo + if dominfo.restart_pending(): + self.domain_restart_add(dominfo) + return dominfo - def _add_domain(self, info, notify=1): + def _add_domain(self, info, notify=True): """Add a domain entry to the tables. @param info: domain info object @param notify: send a domain created event if true """ + # Remove entries under the wrong id. + for i, d in self.domain_by_id.items(): + if i != d.id: + del self.domain_by_id[i] + if i in self.domain_db: + del self.domain_db[i] + self.db.delete(i) + # Remove entries under the wrong name. _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |