ia64/xen-unstable

changeset 8144:5dd8073a4f16

Move the relocate.setupRelocation code into XendDomain, removing the mutual
dependency between those two classes.

Split the XendDomain constructor into two pieces so that XendDomainInfo can
call XendDomain.instance even during the initial startup of XendDomain.

These two together mean that there is no need for the horrendous hack using
XendRoot.get_component to pass the singleton instance of XendDomain around.
Both XendRoot.get_component and XendRoot.add_component can go.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Wed Nov 30 19:26:32 2005 +0000 (2005-11-30)
parents a12ec604308f
children b7790c2874c4
files tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/server/relocate.py
line diff
     1.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Nov 30 19:25:35 2005 +0000
     1.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Nov 30 19:26:32 2005 +0000
     1.3 @@ -24,6 +24,7 @@
     1.4  
     1.5  import logging
     1.6  import os
     1.7 +import socket
     1.8  import sys
     1.9  import threading
    1.10  
    1.11 @@ -35,7 +36,6 @@ from xen.xend import XendRoot
    1.12  from xen.xend import XendCheckpoint
    1.13  from xen.xend.XendError import XendError
    1.14  from xen.xend.XendLogging import log
    1.15 -from xen.xend.server import relocate
    1.16  from xen.xend.xenstore.xswatch import xswatch
    1.17  
    1.18  
    1.19 @@ -54,15 +54,16 @@ class XendDomain:
    1.20      ## public:
    1.21      
    1.22      def __init__(self):
    1.23 -        # Hack alert. Python does not support mutual imports, but XendDomainInfo
    1.24 -        # needs access to the XendDomain instance to look up domains. Attempting
    1.25 -        # to import XendDomain from XendDomainInfo causes unbounded recursion.
    1.26 -        # So we stuff the XendDomain instance (self) into xroot's components.
    1.27 -        xroot.add_component("xen.xend.XendDomain", self)
    1.28 -
    1.29          self.domains = {}
    1.30          self.domains_lock = threading.RLock()
    1.31  
    1.32 +
    1.33 +    # This must be called only the once, by instance() below.  It is separate
    1.34 +    # from the constructor because XendDomainInfo calls back into this class
    1.35 +    # in order to check the uniqueness of domain names.  This means that
    1.36 +    # instance() must be able to return a valid instance of this class even
    1.37 +    # during this initialisation.
    1.38 +    def init(self):
    1.39          self.domains_lock.acquire()
    1.40          try:
    1.41              self._add_domain(
    1.42 @@ -389,10 +390,15 @@ class XendDomain:
    1.43          dominfo = self.domain_lookup(domid)
    1.44  
    1.45          port = xroot.get_xend_relocation_port()
    1.46 -        sock = relocate.setupRelocation(dst, port)
    1.47 +        try:
    1.48 +            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    1.49 +            sock.connect((dst, port))
    1.50 +        except socket.error, err:
    1.51 +            raise XendError("can't connect: %s" % err[1])
    1.52  
    1.53 +        sock.send("receive\n")
    1.54          XendCheckpoint.save(sock.fileno(), dominfo, live)
    1.55 -        
    1.56 +
    1.57  
    1.58      def domain_save(self, domid, dst):
    1.59          """Start saving a domain to file.
    1.60 @@ -527,4 +533,5 @@ def instance():
    1.61          inst
    1.62      except:
    1.63          inst = XendDomain()
    1.64 +        inst.init()
    1.65      return inst
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Nov 30 19:25:35 2005 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Nov 30 19:26:32 2005 +0000
     2.3 @@ -33,14 +33,14 @@ import xen.lowlevel.xc
     2.4  from xen.util import asserts
     2.5  from xen.util.blkif import blkdev_uname_to_file
     2.6  
     2.7 -from xen.xend import image
     2.8 -from xen.xend import sxp
     2.9 -from xen.xend import XendRoot
    2.10 +import image
    2.11 +import sxp
    2.12 +import uuid
    2.13 +import XendDomain
    2.14 +import XendRoot
    2.15 +
    2.16  from xen.xend.XendBootloader import bootloader
    2.17  from xen.xend.XendError import XendError, VmError
    2.18 -from xen.xend.XendRoot import get_component
    2.19 -
    2.20 -import uuid
    2.21  
    2.22  from xen.xend.xenstore.xstransact import xstransact
    2.23  from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
    2.24 @@ -338,9 +338,8 @@ def parseConfig(config):
    2.25  
    2.26  
    2.27  def domain_by_name(name):
    2.28 -    # See comment in XendDomain constructor.
    2.29 -    xd = get_component('xen.xend.XendDomain')
    2.30 -    return xd.domain_lookup_by_name_nr(name)
    2.31 +    return XendDomain.instance().domain_lookup_by_name_nr(name)
    2.32 +
    2.33  
    2.34  def shutdown_reason(code):
    2.35      """Get a shutdown reason from a code.
    2.36 @@ -1343,8 +1342,7 @@ class XendDomainInfo:
    2.37  
    2.38              new_dom = None
    2.39              try:
    2.40 -                xd = get_component('xen.xend.XendDomain')
    2.41 -                new_dom = xd.domain_create(config)
    2.42 +                new_dom = XendDomain.instance().domain_create(config)
    2.43                  new_dom.unpause()
    2.44                  new_dom.removeVm(RESTART_IN_PROGRESS)
    2.45              except:
     3.1 --- a/tools/python/xen/xend/XendRoot.py	Wed Nov 30 19:25:35 2005 +0000
     3.2 +++ b/tools/python/xen/xend/XendRoot.py	Wed Nov 30 19:26:32 2005 +0000
     3.3 @@ -93,24 +93,6 @@ class XendRoot:
     3.4          self.configure()
     3.5  
     3.6  
     3.7 -    def add_component(self, name, val):
     3.8 -        """Add a xend component.
     3.9 -
    3.10 -        @param name: component name
    3.11 -        @param val:  component object
    3.12 -        """
    3.13 -        self.components[name] = val
    3.14 -
    3.15 -    def get_component(self, name):
    3.16 -        """Get a xend component from its name.
    3.17 -        This is used as a work-round for problems caused by mutually
    3.18 -        recursive imports.
    3.19 -
    3.20 -        @param name: component name
    3.21 -        @return: component object (or None)
    3.22 -        """
    3.23 -        return self.components.get(name)
    3.24 -
    3.25      def _logError(self, fmt, *args):
    3.26          """Logging function to log to stderr. We use this for XendRoot log
    3.27          messages because they may be logged before the logger has been
    3.28 @@ -277,21 +259,3 @@ def instance():
    3.29      except:
    3.30          inst = XendRoot()
    3.31      return inst
    3.32 -
    3.33 -def add_component(name, val):
    3.34 -    """Register a component with XendRoot.
    3.35 -    This is used to work-round import cycles.
    3.36 -
    3.37 -    @param name: component name
    3.38 -    @param val:  component value (often a module)
    3.39 -    """
    3.40 -    return instance().add_component(name, val)
    3.41 -
    3.42 -def get_component(name):
    3.43 -    """Get a component.
    3.44 -    This is used to work-round import cycles.
    3.45 -
    3.46 -    @param name: component name
    3.47 -    @return component or None
    3.48 -    """
    3.49 -    return instance().get_component(name)
     4.1 --- a/tools/python/xen/xend/server/relocate.py	Wed Nov 30 19:25:35 2005 +0000
     4.2 +++ b/tools/python/xen/xend/server/relocate.py	Wed Nov 30 19:26:32 2005 +0000
     4.3 @@ -23,16 +23,12 @@ import StringIO
     4.4  from xen.web import protocol, tcp, unix
     4.5  
     4.6  from xen.xend import sxp
     4.7 +from xen.xend import XendDomain
     4.8 +from xen.xend import XendRoot
     4.9  from xen.xend.XendError import XendError
    4.10 -from xen.xend import XendRoot
    4.11  from xen.xend.XendLogging import log
    4.12  
    4.13  
    4.14 -xroot = XendRoot.instance()
    4.15 -
    4.16 -
    4.17 -DEBUG = 0
    4.18 -
    4.19  class RelocationProtocol(protocol.Protocol):
    4.20      """Asynchronous handler for a connected relocation socket.
    4.21      """
    4.22 @@ -111,8 +107,8 @@ class RelocationProtocol(protocol.Protoc
    4.23          if self.transport:
    4.24              self.send_reply(["ready", name])
    4.25              self.transport.sock.setblocking(1)
    4.26 -            xd = xroot.get_component("xen.xend.XendDomain")
    4.27 -            xd.domain_restore_fd(self.transport.sock.fileno())
    4.28 +            XendDomain.instance().domain_restore_fd(
    4.29 +                self.transport.sock.fileno())
    4.30              self.transport.sock.setblocking(0)
    4.31          else:
    4.32              log.error(name + ": no transport")
    4.33 @@ -120,6 +116,7 @@ class RelocationProtocol(protocol.Protoc
    4.34  
    4.35  
    4.36  def listenRelocation():
    4.37 +    xroot = XendRoot.instance()
    4.38      if xroot.get_xend_unix_server():
    4.39          path = '/var/lib/xend/relocation-socket'
    4.40          unix.listenUNIX(path, RelocationProtocol)
    4.41 @@ -128,15 +125,3 @@ def listenRelocation():
    4.42          interface = xroot.get_xend_relocation_address()
    4.43          l = tcp.listenTCP(port, RelocationProtocol, interface=interface)
    4.44          l.setCloExec()
    4.45 -
    4.46 -def setupRelocation(dst, port):
    4.47 -    try:
    4.48 -        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    4.49 -        sock.connect((dst, port))
    4.50 -    except socket.error, err:
    4.51 -        raise XendError("can't connect: %s" % err[1])
    4.52 -
    4.53 -    sock.send("receive\n")
    4.54 -    print sock.recv(80)
    4.55 -
    4.56 -    return sock