ia64/xen-unstable

changeset 1582:fdcfd59a93e8

bitkeeper revision 1.1010.1.7 (40dc2667VP5fW6QI61kdgU_iNS2Pnw)

Tidy up console destruction on domain exit.
author mjw@wray-m-3.hpl.hp.com
date Fri Jun 25 13:19:35 2004 +0000 (2004-06-25)
parents e27e8d79cc6a
children 07af9a3715e2
files tools/xenmgr/lib/EventServer.py tools/xenmgr/lib/XendConsole.py tools/xenmgr/lib/XendDomain.py tools/xenmgr/lib/server/SrvConsoleDir.py tools/xenmgr/lib/server/SrvConsoleServer.py tools/xenmgr/lib/server/SrvDomainDir.py tools/xenmgr/lib/server/channel.py tools/xenmgr/lib/server/console.py tools/xenmgr/lib/server/controller.py
line diff
     1.1 --- a/tools/xenmgr/lib/EventServer.py	Fri Jun 25 10:34:19 2004 +0000
     1.2 +++ b/tools/xenmgr/lib/EventServer.py	Fri Jun 25 13:19:35 2004 +0000
     1.3 @@ -4,6 +4,8 @@
     1.4  """
     1.5  import string
     1.6  
     1.7 +from twisted.internet import reactor
     1.8 +
     1.9  # subscribe a.b.c h: map a.b.c -> h
    1.10  # subscribe a.b.* h: map a.b.* -> h
    1.11  # subscribe a.b.? h: map a.b.? -> h
    1.12 @@ -73,7 +75,7 @@ class EventServer:
    1.13          """
    1.14          if event == None:
    1.15              self.handlers.clear()
    1.16 -        else:
    1.17 +        elif event in self.handlers:
    1.18              del self.handlers[event]
    1.19          
    1.20      def unsubscribe(self, event, handler):
    1.21 @@ -88,21 +90,29 @@ class EventServer:
    1.22          if handler in hl:
    1.23              hl.remove(handler)
    1.24  
    1.25 -    def inject(self, event, val):
    1.26 -        """Inject an event. Handlers for it are called if runing, otherwise
    1.27 +    def inject(self, event, val, async=1):
    1.28 +        """Inject an event. Handlers for it are called if running, otherwise
    1.29          it is queued.
    1.30  
    1.31          event	event type
    1.32          val	event value
    1.33          """
    1.34          if self.run:
    1.35 -            #print ">event", event, val
    1.36 -            self.call_event_handlers(event, event, val)
    1.37 -            self.call_query_handlers(event, val)
    1.38 -            self.call_star_handlers(event, val)
    1.39 +            if async:
    1.40 +                reactor.callLater(0, self.call_handlers, event, val)
    1.41 +            else:
    1.42 +                self.notify_handlers(event, val)
    1.43          else:
    1.44              self.queue.append( (event, val) )
    1.45  
    1.46 +    def call_handlers(self, event, val):
    1.47 +        """Internal method to call event handlers.
    1.48 +        """
    1.49 +        #print ">event", event, val
    1.50 +        self.call_event_handlers(event, event, val)
    1.51 +        self.call_query_handlers(event, val)
    1.52 +        self.call_star_handlers(event, val)
    1.53 +
    1.54      def call_event_handlers(self, key, event, val):
    1.55          """Call the handlers for an event.
    1.56          It is safe for handlers to subscribe or unsubscribe.
     2.1 --- a/tools/xenmgr/lib/XendConsole.py	Fri Jun 25 10:34:19 2004 +0000
     2.2 +++ b/tools/xenmgr/lib/XendConsole.py	Fri Jun 25 13:19:35 2004 +0000
     2.3 @@ -21,10 +21,10 @@ class XendConsoleInfo:
     2.4  
     2.5      def __init__(self, console, dom1, port1, dom2, port2, conn=None):
     2.6          self.console = console
     2.7 -        self.dom1  = dom1
     2.8 -        self.port1 = port1
     2.9 -        self.dom2  = dom2
    2.10 -        self.port2 = port2
    2.11 +        self.dom1  = int(dom1)
    2.12 +        self.port1 = int(port1)
    2.13 +        self.dom2  = int(dom2)
    2.14 +        self.port2 = int(port2)
    2.15          self.conn  = conn
    2.16          #self.id = "%d.%d-%d.%d" % (self.dom1, self.port1, self.dom2, self.port2)
    2.17          self.id = str(port1)
    2.18 @@ -81,6 +81,7 @@ class XendConsole:
    2.19              print 'XendConsole> rebooted: removing all console info'
    2.20              self.rm_all()
    2.21          eserver.subscribe('xend.domain.died', self.onDomainDied)
    2.22 +        eserver.subscribe('xend.domain.destroy', self.onDomainDied)
    2.23  
    2.24      def rm_all(self):
    2.25          """Remove all console info. Used after reboot.
    2.26 @@ -104,11 +105,15 @@ class XendConsole:
    2.27                  self._delete_console(c.id)
    2.28  
    2.29      def onDomainDied(self, event, val):
    2.30 -        print 'onDomainDied', "dom=", dom,
    2.31          dom = int(val)
    2.32 +        #print 'XendConsole>onDomainDied', 'event', event, "dom=", dom
    2.33          for c in self.consoles():
    2.34 -            print 'onDomainDied', "dom=", dom, "dom1=", c.dom1, "dom2=", c.dom2
    2.35 +            #print 'onDomainDied', "dom=", dom, "dom1=", c.dom1, "dom2=", c.dom2
    2.36              if (c.dom1 == dom) or (c.dom2 == dom):
    2.37 +                'XendConsole>onDomainDied', 'delete console dom=', dom
    2.38 +                ctrl = xcd.get_domain_console(dom)
    2.39 +                if ctrl:
    2.40 +                    ctrl.close()
    2.41                  self._delete_console(c.id)
    2.42  
    2.43      def sync(self):
     3.1 --- a/tools/xenmgr/lib/XendDomain.py	Fri Jun 25 10:34:19 2004 +0000
     3.2 +++ b/tools/xenmgr/lib/XendDomain.py	Fri Jun 25 13:19:35 2004 +0000
     3.3 @@ -79,11 +79,10 @@ class XendDomain:
     3.4                  self._delete_domain(domid)
     3.5          deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
     3.6          def cbok(val):
     3.7 -            print "doms:"
     3.8 -            for d in self.domain.values(): print 'dom', d
     3.9 -            print "refresh..."
    3.10 +            #print "doms:"
    3.11 +            #for d in self.domain.values(): print 'dom', d
    3.12              self.refresh()
    3.13 -            print "doms:"
    3.14 +            print "XendDomain>initial_refresh> doms:"
    3.15              for d in self.domain.values(): print 'dom', d
    3.16          deferred.addCallback(cbok)
    3.17  
    3.18 @@ -148,11 +147,14 @@ class XendDomain:
    3.19              self.db.delete(id)
    3.20  
    3.21      def reap(self):
    3.22 -        print 'reap>'
    3.23 +        """Go through the domains looking for ones that have crashed or stopped.
    3.24 +        Tidy them up.
    3.25 +        """
    3.26 +        print 'XendDomain>reap>'
    3.27          domlist = xc.domain_getinfo()
    3.28          casualties = []
    3.29          for d in domlist:
    3.30 -            print 'dom', d
    3.31 +            #print 'dom', d
    3.32              dead = 0
    3.33              dead = dead or (d['crashed'] or d['shutdown'])
    3.34              dead = dead or (d['dying'] and
    3.35 @@ -161,12 +163,12 @@ class XendDomain:
    3.36                  casualties.append(d)
    3.37          for d in casualties:
    3.38              id = str(d['dom'])
    3.39 -            print 'died> id=', id, d
    3.40 +            print 'XendDomain>reap> died id=', id, d
    3.41              dominfo = self.domain.get(id)
    3.42              if not dominfo: continue
    3.43              dominfo.died()
    3.44              self.domain_destroy(id, refresh=0)
    3.45 -        print 'reap<'
    3.46 +        print 'XendDomain>reap<'
    3.47  
    3.48      def refresh(self):
    3.49          """Refresh domain list from Xen.
    3.50 @@ -203,6 +205,8 @@ class XendDomain:
    3.51              try:
    3.52                  self._delete_domain(id)
    3.53              except:
    3.54 +                print 'refresh_domain: error'
    3.55 +                raise
    3.56                  pass
    3.57          else:
    3.58              d = self.domain.get(id)
     4.1 --- a/tools/xenmgr/lib/server/SrvConsoleDir.py	Fri Jun 25 10:34:19 2004 +0000
     4.2 +++ b/tools/xenmgr/lib/server/SrvConsoleDir.py	Fri Jun 25 13:19:35 2004 +0000
     4.3 @@ -18,7 +18,8 @@ class SrvConsoleDir(SrvDir):
     4.4          try:
     4.5              info = self.xconsole.console_get(x)
     4.6              val = SrvConsole(info)
     4.7 -        except KeyError:
     4.8 +        except KeyError, ex:
     4.9 +            print 'SrvConsoleDir>', ex
    4.10              pass
    4.11          return val
    4.12  
     5.1 --- a/tools/xenmgr/lib/server/SrvConsoleServer.py	Fri Jun 25 10:34:19 2004 +0000
     5.2 +++ b/tools/xenmgr/lib/server/SrvConsoleServer.py	Fri Jun 25 13:19:35 2004 +0000
     5.3 @@ -378,7 +378,10 @@ class EventProtocol(protocol.Protocol):
     5.4          return ['ok']
     5.5  
     5.6      def op_info(self, name, req):
     5.7 -        val = self.daemon.consoles()
     5.8 +        val = ['info']
     5.9 +        val += self.daemon.consoles()
    5.10 +        val += self.daemon.blkifs()
    5.11 +        val += self.daemon.netifs()
    5.12          return val
    5.13  
    5.14      def op_sys_subscribe(self, name, v):
    5.15 @@ -603,6 +606,9 @@ class Daemon:
    5.16          d = self.blkifCF.createInstance(dom, recreate=recreate)
    5.17          return d
    5.18  
    5.19 +    def blkifs(self):
    5.20 +        return [ x.sxpr() for x in self.blkifCF.getInstances() ]
    5.21 +
    5.22      def blkif_get(self, dom):
    5.23          return self.blkifCF.getInstanceByDom(dom)
    5.24  
    5.25 @@ -637,6 +643,9 @@ class Daemon:
    5.26          """
    5.27          return self.netifCF.createInstance(dom, recreate=recreate)
    5.28  
    5.29 +    def netifs(self):
    5.30 +        return [ x.sxpr() for x in self.netifCF.getInstances() ]
    5.31 +
    5.32      def netif_get(self, dom):
    5.33          return self.netifCF.getInstanceByDom(dom)
    5.34  
    5.35 @@ -677,8 +686,7 @@ class Daemon:
    5.36          console = self.get_console(id)
    5.37          if not console:
    5.38              raise ValueError('Invalid console id')
    5.39 -        if console.conn:
    5.40 -            console.conn.loseConnection()
    5.41 +        console.disconnect()
    5.42  
    5.43      def domain_shutdown(self, dom, reason):
    5.44          """Shutdown a domain.
     6.1 --- a/tools/xenmgr/lib/server/SrvDomainDir.py	Fri Jun 25 10:34:19 2004 +0000
     6.2 +++ b/tools/xenmgr/lib/server/SrvDomainDir.py	Fri Jun 25 13:19:35 2004 +0000
     6.3 @@ -24,7 +24,8 @@ class SrvDomainDir(SrvDir):
     6.4          try:
     6.5              dom = self.xd.domain_get(x)
     6.6              val = SrvDomain(dom)
     6.7 -        except KeyError:
     6.8 +        except KeyError, ex:
     6.9 +            print 'SrvDomainDir>', ex
    6.10              pass
    6.11          return val
    6.12  
    6.13 @@ -46,7 +47,7 @@ class SrvDomainDir(SrvDir):
    6.14              config = pin.get_val()
    6.15              ok = 1
    6.16          except Exception, ex:
    6.17 -            print ex
    6.18 +            print 'op_create>', ex
    6.19          if not ok:
    6.20              req.setResponseCode(http.BAD_REQUEST, "Invalid configuration")
    6.21              return "Invalid configuration"
     7.1 --- a/tools/xenmgr/lib/server/channel.py	Fri Jun 25 10:34:19 2004 +0000
     7.2 +++ b/tools/xenmgr/lib/server/channel.py	Fri Jun 25 13:19:35 2004 +0000
     7.3 @@ -49,6 +49,7 @@ class ChannelFactory:
     7.4          """Get the channel for the given domain.
     7.5          Construct if necessary.
     7.6          """
     7.7 +        dom = int(dom)
     7.8          for chan in self.channels.values():
     7.9              if not isinstance(chan, Channel): continue
    7.10              if chan.dom == dom:
    7.11 @@ -199,7 +200,7 @@ class Channel(BaseChannel):
    7.12          """
    7.13          BaseChannel.__init__(self, factory)
    7.14          # Domain.
    7.15 -        self.dom = dom
    7.16 +        self.dom = int(dom)
    7.17          # Domain port (object).
    7.18          self.port = self.factory.createPort(dom)
    7.19          # Channel port (int).
    7.20 @@ -210,6 +211,7 @@ class Channel(BaseChannel):
    7.21          self.devs_by_type = {}
    7.22          # Output queue.
    7.23          self.queue = []
    7.24 +        self.closed = 0
    7.25  
    7.26      def getLocalPort(self):
    7.27          """Get the local port.
    7.28 @@ -225,11 +227,12 @@ class Channel(BaseChannel):
    7.29          """Close the channel. Calls lostChannel() on all its devices and
    7.30          channelClosed() on the factory.
    7.31          """
    7.32 +        self.closed = 1
    7.33          for d in self.devs:
    7.34              d.lostChannel()
    7.35          self.factory.channelClosed(self)
    7.36 -        del self.devs
    7.37 -        del self.devs_by_type
    7.38 +        self.devs = []
    7.39 +        self.devs_by_type = {}
    7.40  
    7.41      def registerDevice(self, types, dev):
    7.42          """Register a device controller.
    7.43 @@ -237,20 +240,21 @@ class Channel(BaseChannel):
    7.44          @param types message types the controller handles
    7.45          @param dev   device controller
    7.46          """
    7.47 +        if self.closed: return
    7.48          self.devs.append(dev)
    7.49          for ty in types:
    7.50              self.devs_by_type[ty] = dev
    7.51  
    7.52 -    def unregisterDevice(self, dev):
    7.53 +    def deregisterDevice(self, dev):
    7.54          """Remove the registration for a device controller.
    7.55  
    7.56          @param dev device controller
    7.57          """
    7.58 -        self.devs.remove(dev)
    7.59 -        types = [ ty for (ty, d) in self.devs_by_type.items()
    7.60 -                  if d == dev ]
    7.61 +        if dev in self.devs:
    7.62 +            self.devs.remove(dev)
    7.63 +        types = [ ty for (ty, d) in self.devs_by_type.items() if d == dev ]
    7.64          for ty in types:
    7.65 -            del devs_by_type[ty]
    7.66 +            del self.devs_by_type[ty]
    7.67  
    7.68      def getDevice(self, type):
    7.69          """Get the device controller handling a message type.
     8.1 --- a/tools/xenmgr/lib/server/console.py	Fri Jun 25 10:34:19 2004 +0000
     8.2 +++ b/tools/xenmgr/lib/server/console.py	Fri Jun 25 13:19:35 2004 +0000
     8.3 @@ -103,7 +103,7 @@ class ConsoleController(controller.Contr
     8.4      """
     8.5  
     8.6      def __init__(self, factory, dom, console_port):
     8.7 -        #print 'ConsoleController> dom=', dom
     8.8 +        #print 'ConsoleController> dom=', dom, type(dom)
     8.9          controller.Controller.__init__(self, factory, dom)
    8.10          self.majorTypes = [ CMSG_CONSOLE ]
    8.11          self.status = "new"
    8.12 @@ -120,6 +120,7 @@ class ConsoleController(controller.Contr
    8.13  
    8.14      def sxpr(self):
    8.15          val =['console',
    8.16 +              ['status',       self.status ],
    8.17                ['id',           self.idx ],
    8.18                ['domain',       self.dom ],
    8.19                ['local_port',   self.channel.getLocalPort() ],
    8.20 @@ -139,10 +140,17 @@ class ConsoleController(controller.Contr
    8.21          return self.status == 'connected'
    8.22  
    8.23      def close(self):
    8.24 -        self.status = "closed"
    8.25 -        self.listener.stopListening()
    8.26 -        self.deregisterChannel()
    8.27 -        self.lostChannel()
    8.28 +        try:
    8.29 +            #print 'ConsoleController> close dom=', self.dom
    8.30 +            self.status = "closed"
    8.31 +            if self.conn:
    8.32 +                self.conn.loseConnection()
    8.33 +            self.listener.stopListening()
    8.34 +            self.deregisterChannel()
    8.35 +            self.lostChannel()
    8.36 +        except Exception, ex:
    8.37 +            print 'ConsoleController>close>', ex
    8.38 +            raise
    8.39  
    8.40      def listen(self):
    8.41          """Listen for TCP connections to the console port..
    8.42 @@ -166,6 +174,8 @@ class ConsoleController(controller.Contr
    8.43          return 0
    8.44  
    8.45      def disconnect(self):
    8.46 +        if self.conn:
    8.47 +            self.conn.loseConnection()
    8.48          self.addr = None
    8.49          self.conn = None
    8.50          self.listen()
     9.1 --- a/tools/xenmgr/lib/server/controller.py	Fri Jun 25 10:34:19 2004 +0000
     9.2 +++ b/tools/xenmgr/lib/server/controller.py	Fri Jun 25 13:19:35 2004 +0000
     9.3 @@ -36,14 +36,14 @@ class CtrlMsgRcvr:
     9.4          pass
     9.5      
     9.6      def registerChannel(self):
     9.7 -        print 'CtrlMsgRcvr>registerChannel>', self
     9.8 +        #print 'CtrlMsgRcvr>registerChannel>', self
     9.9          self.channel = self.channelFactory.domChannel(self.dom)
    9.10          self.idx = self.channel.getIndex()
    9.11          if self.majorTypes:
    9.12              self.channel.registerDevice(self.majorTypes, self)
    9.13          
    9.14      def deregisterChannel(self):
    9.15 -        print 'CtrlMsgRcvr>deregisterChannel>', self
    9.16 +        #print 'CtrlMsgRcvr>deregisterChannel>', self
    9.17          if self.channel:
    9.18              self.channel.deregisterDevice(self)
    9.19              del self.channel
    9.20 @@ -92,13 +92,16 @@ class ControllerFactory(CtrlMsgRcvr):
    9.21          return None
    9.22  
    9.23      def delInstance(self, instance):
    9.24 +        #print 'ControllerFactory>delInstance>', instance.idx
    9.25          if instance.idx in self.instances:
    9.26 +            #print 'ControllerFactory>delInstance> remove', instance.idx
    9.27              del self.instances[instance.idx]
    9.28  
    9.29      def createInstance(self, dom, recreate=0):
    9.30          raise NotImplementedError()
    9.31  
    9.32      def instanceClosed(self, instance):
    9.33 +        #print 'ControllerFactory>instanceClosed>', instance.idx, instance
    9.34          self.delInstance(instance)
    9.35  
    9.36      def addDeferred(self):
    9.37 @@ -126,7 +129,7 @@ class Controller(CtrlMsgRcvr):
    9.38      def __init__(self, factory, dom):
    9.39          CtrlMsgRcvr.__init__(self)
    9.40          self.factory = factory
    9.41 -        self.dom = dom
    9.42 +        self.dom = int(dom)
    9.43          self.channel = None
    9.44          self.idx = None
    9.45  
    9.46 @@ -135,6 +138,7 @@ class Controller(CtrlMsgRcvr):
    9.47          self.lostChannel()
    9.48  
    9.49      def lostChannel(self):
    9.50 +        #print 'Controller>lostChannel>', self, self.factory
    9.51          self.factory.instanceClosed(self)
    9.52  
    9.53  class Dev: