[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.