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
|