ia64/xen-unstable

changeset 4671:7719c5e6954d

bitkeeper revision 1.1327.2.11 (426fb893OrpBVeRpaWJ0atIxlG4Hxw)

Add support for unix-domain sockets to consoles and the
event server.

Signed-off-by: Mike Wray <mike.wray@hp.com>
author mjw@wray-m-3.hpl.hp.com
date Wed Apr 27 16:06:43 2005 +0000 (2005-04-27)
parents 629cd2d0d581
children 6639dd8a166b 16efdf7bbd57
files tools/python/xen/util/console_client.py tools/python/xen/web/unix.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/console.py tools/python/xen/xend/server/event.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/python/xen/util/console_client.py	Wed Apr 27 14:42:44 2005 +0000
     1.2 +++ b/tools/python/xen/util/console_client.py	Wed Apr 27 16:06:43 2005 +0000
     1.3 @@ -57,9 +57,18 @@ def __send_to_sock(sock):
     1.4                      raise
     1.5      sys.exit(0)
     1.6  
     1.7 -def connect(host,port):
     1.8 -    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
     1.9 -    sock.connect((host,port))
    1.10 +def connect(host, port, path=None):
    1.11 +    # Try inet first. If 'path' is given and the error
    1.12 +    # was connection refused, try unix-domain on 'path'.
    1.13 +    try:
    1.14 +        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    1.15 +        sock.connect((host, port))
    1.16 +    except socket.error, err:
    1.17 +        if (path is None) or (err[0] != errno.ECONNREFUSED):
    1.18 +            raise
    1.19 +        # Try unix-domain.
    1.20 +        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    1.21 +        sock.connect(path)
    1.22  
    1.23      oattrs = tcgetattr(0)
    1.24      nattrs = tcgetattr(0)
    1.25 @@ -86,7 +95,14 @@ def connect(host,port):
    1.26          __send_to_sock(sock)
    1.27  
    1.28  if __name__ == '__main__':
    1.29 -    if len(sys.argv) != 3:
    1.30 -        print sys.argv[0] + " <host> <port>"
    1.31 +    argc = len(sys.argv)
    1.32 +    if argc < 3 or argc > 4:
    1.33 +        print >>sys.stderr, sys.argv[0], "<host> <port> [<path>]"
    1.34          sys.exit(1)
    1.35 -    connect(str(sys.argv[1]),int(sys.argv[2]))
    1.36 +    host = sys.argv[1]
    1.37 +    port = int(sys.argv[2])
    1.38 +    if argc > 3:
    1.39 +        path = sys.argv[3]
    1.40 +    else:
    1.41 +        path = None
    1.42 +    connect(host, port, path=path)
     2.1 --- a/tools/python/xen/web/unix.py	Wed Apr 27 14:42:44 2005 +0000
     2.2 +++ b/tools/python/xen/web/unix.py	Wed Apr 27 16:06:43 2005 +0000
     2.3 @@ -1,6 +1,7 @@
     2.4  import sys
     2.5  import socket
     2.6  import os
     2.7 +import os.path
     2.8  
     2.9  from connection import *
    2.10  from protocol import *
    2.11 @@ -15,18 +16,22 @@ class UnixListener(SocketListener):
    2.12          self.path = path
    2.13          
    2.14      def createSocket(self):
    2.15 -        try:
    2.16 -            os.unlink(self.path)
    2.17 -        except SystemExit:
    2.18 -            raise
    2.19 -        except Exception, ex:
    2.20 -            pass
    2.21 +        pathdir = os.path.dirname(self.path)
    2.22 +        if not os.path.exists(pathdir):
    2.23 +            os.makedirs(pathdir)
    2.24 +        else:
    2.25 +            try:
    2.26 +                os.unlink(self.path)
    2.27 +            except SystemExit:
    2.28 +                raise
    2.29 +            except Exception, ex:
    2.30 +                pass
    2.31          sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    2.32          sock.bind(self.path)
    2.33          return sock
    2.34  
    2.35      def acceptConnection(self, sock, protocol, addr):
    2.36 -        return UnixServerConnection(sock, protocol, addr, self)
    2.37 +        return UnixServerConnection(sock, protocol, self.path, self)
    2.38  
    2.39  class UnixClientConnection(SocketClientConnection):
    2.40  
     3.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Apr 27 14:42:44 2005 +0000
     3.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Apr 27 16:06:43 2005 +0000
     3.3 @@ -324,7 +324,7 @@ class Daemon:
     3.4              xroot = XendRoot.instance()
     3.5              log.info("Xend Daemon started")
     3.6              self.createFactories()
     3.7 -            self.listenEvent(xroot)
     3.8 +            event.listenEvent(self)
     3.9              self.listenChannels()
    3.10              servers = SrvServer.create()
    3.11              self.daemonize()
    3.12 @@ -340,11 +340,6 @@ class Daemon:
    3.13      def createFactories(self):
    3.14          self.channelF = channel.channelFactory()
    3.15  
    3.16 -    def listenEvent(self, xroot):
    3.17 -        port = xroot.get_xend_event_port()
    3.18 -        interface = xroot.get_xend_address()
    3.19 -        return event.listenEvent(self, port, interface)
    3.20 -
    3.21      def listenChannels(self):
    3.22          def virqReceived(virq):
    3.23              print 'virqReceived>', virq
     4.1 --- a/tools/python/xen/xend/server/console.py	Wed Apr 27 14:42:44 2005 +0000
     4.2 +++ b/tools/python/xen/xend/server/console.py	Wed Apr 27 16:06:43 2005 +0000
     4.3 @@ -19,7 +19,7 @@ from messages import *
     4.4  from params import *
     4.5  
     4.6  class ConsoleProtocol(protocol.Protocol):
     4.7 -    """Asynchronous handler for a console TCP socket.
     4.8 +    """Asynchronous handler for a console socket.
     4.9      """
    4.10  
    4.11      def __init__(self, console, id):
    4.12 @@ -36,10 +36,16 @@ class ConsoleProtocol(protocol.Protocol)
    4.13              self.loseConnection()
    4.14              return
    4.15          else:
    4.16 +            if len(self.addr) == 2:
    4.17 +                host = str(self.addr[0])
    4.18 +                port = str(self.addr[1])
    4.19 +            else:
    4.20 +                host = 'localhost'
    4.21 +                port = str(addr)
    4.22              log.info("Console connected %s %s %s",
    4.23 -                     self.id, str(self.addr[0]), str(self.addr[1]))
    4.24 +                     self.id, host, port)
    4.25              eserver.inject('xend.console.connect',
    4.26 -                           [self.id, self.addr[0], self.addr[1]])
    4.27 +                           [self.id, host, port])
    4.28  
    4.29      def dataReceived(self, data):
    4.30          if self.console.receiveInput(self, data):
    4.31 @@ -50,7 +56,6 @@ class ConsoleProtocol(protocol.Protocol)
    4.32          return len(data)
    4.33  
    4.34      def connectionLost(self, reason=None):
    4.35 -        print 'ConsoleProtocol>connectionLost>', reason
    4.36          log.info("Console disconnected %s %s %s",
    4.37                   str(self.id), str(self.addr[0]), str(self.addr[1]))
    4.38          eserver.inject('xend.console.disconnect',
    4.39 @@ -60,22 +65,7 @@ class ConsoleProtocol(protocol.Protocol)
    4.40      def loseConnection(self):
    4.41          self.transport.loseConnection()
    4.42  
    4.43 -class ConsoleFactory(protocol.ServerFactory):
    4.44 -    """Asynchronous handler for a console server socket.
    4.45 -    """
    4.46 -    protocol = ConsoleProtocol
    4.47 -    
    4.48 -    def __init__(self, console, id):
    4.49 -        #protocol.ServerFactory.__init__(self)
    4.50 -        self.console = console
    4.51 -        self.id = id
    4.52 -
    4.53 -    def buildProtocol(self, addr):
    4.54 -        proto = self.protocol(self.console, self.id)
    4.55 -        proto.factory = self
    4.56 -        return proto
    4.57 -
    4.58 -class ConsoleDev(Dev):
    4.59 +class ConsoleDev(Dev, protocol.ServerFactory):
    4.60      """Console device for a domain.
    4.61      Does not poll for i/o itself, but relies on the domain to post console
    4.62      output and the connected TCP sockets to post console input.
    4.63 @@ -96,7 +86,9 @@ class ConsoleDev(Dev):
    4.64          self.obuf = xu.buffer()
    4.65          self.ibuf = xu.buffer()
    4.66          self.channel = None
    4.67 -        self.listener = None
    4.68 +        self.listening = False
    4.69 +        self.unix_listener = None
    4.70 +        self.tcp_listener = None
    4.71          
    4.72          console_port = sxp.child_value(self.config, "console_port")
    4.73          if console_port is None:
    4.74 @@ -188,9 +180,15 @@ class ConsoleDev(Dev):
    4.75          try:
    4.76              self.lock.acquire()
    4.77              self.status = self.STATUS_CLOSED
    4.78 +            self.listening = False
    4.79              if self.conn:
    4.80                  self.conn.loseConnection()
    4.81 -            self.listener.stopListening()
    4.82 +            if self.tcp_listener:
    4.83 +                self.tcp_listener.stopListening()
    4.84 +                self.tcp_listener = None
    4.85 +            if self.unix_listener:
    4.86 +                self.unix_listener.stopListening()
    4.87 +                self.unix_listener = None
    4.88          finally:
    4.89              self.lock.release()
    4.90  
    4.91 @@ -201,16 +199,28 @@ class ConsoleDev(Dev):
    4.92              self.lock.acquire()
    4.93              if self.closed():
    4.94                  return
    4.95 -            if self.listener:
    4.96 +            if self.listening:
    4.97                  pass
    4.98              else:
    4.99 +                self.listening = True
   4.100                  self.status = self.STATUS_LISTENING
   4.101 -                cf = ConsoleFactory(self, self.id)
   4.102 -                interface = xroot.get_console_address()
   4.103 -                self.listener = reactor.listenTCP(self.console_port, cf, interface=interface)
   4.104 +                if xroot.get_xend_unix_server():
   4.105 +                    path = '/var/lib/xend/console-%s' % self.console_port
   4.106 +                    self.unix_listener = reactor.listenUNIX(path, self)
   4.107 +                if xroot.get_xend_http_server():
   4.108 +                    interface = xroot.get_console_address()
   4.109 +                    self.tcp_listener = reactor.listenTCP(self.console_port, self, interface=interface)
   4.110          finally:
   4.111              self.lock.release()
   4.112  
   4.113 +    def buildProtocol(self, addr):
   4.114 +        """Factory function called to create the protocol when a connection is accepted
   4.115 +        by listenTCP.
   4.116 +        """
   4.117 +        proto = ConsoleProtocol(self, self.id)
   4.118 +        proto.factory = self
   4.119 +        return proto
   4.120 +
   4.121      def connect(self, addr, conn):
   4.122          """Connect a TCP connection to the console.
   4.123          Fails if closed or already connected.
     5.1 --- a/tools/python/xen/xend/server/event.py	Wed Apr 27 14:42:44 2005 +0000
     5.2 +++ b/tools/python/xen/xend/server/event.py	Wed Apr 27 16:06:43 2005 +0000
     5.3 @@ -11,7 +11,7 @@ from xen.xend import EventServer
     5.4  eserver = EventServer.instance()
     5.5  from xen.xend.XendError import XendError
     5.6  
     5.7 -from xen.xend import XendRoot
     5.8 +from xen.xend import XendRoot; xroot = XendRoot.instance()
     5.9  
    5.10  DEBUG = 1
    5.11  
    5.12 @@ -165,7 +165,7 @@ class EventProtocol(protocol.Protocol):
    5.13  
    5.14      def op_log_stderr(self, name, v):
    5.15          mode = v[1]
    5.16 -        logging = XendRoot.instance().get_logging()
    5.17 +        logging = xroot.get_logging()
    5.18          if mode == 'on':
    5.19              logging.addLogStderr()
    5.20          else:
    5.21 @@ -181,21 +181,23 @@ class EventProtocol(protocol.Protocol):
    5.22          import controller
    5.23          controller.DEBUG = (mode == 'on')
    5.24  
    5.25 -class EventFactory(protocol.Factory):
    5.26 +class EventFactory(protocol.ServerFactory):
    5.27      """Asynchronous handler for the event server socket.
    5.28      """
    5.29 -    protocol = EventProtocol
    5.30 -    service = None
    5.31  
    5.32      def __init__(self, daemon):
    5.33 -        #protocol.Factory.__init__(self)
    5.34 +        #protocol.ServerFactory.__init__(self)
    5.35          self.daemon = daemon
    5.36  
    5.37      def buildProtocol(self, addr):
    5.38 -        proto = self.protocol(self.daemon)
    5.39 -        proto.factory = self
    5.40 -        return proto
    5.41 +        return EventProtocol(self.daemon)
    5.42  
    5.43 -def listenEvent(daemon, port, interface):
    5.44 +def listenEvent(daemon):
    5.45      factory = EventFactory(daemon)
    5.46 -    return reactor.listenTCP(port, factory, interface=interface)
    5.47 +    if xroot.get_xend_unix_server():
    5.48 +        path = '/var/lib/xend/event-socket'
    5.49 +        reactor.listenUNIX(path, factory)
    5.50 +    if xroot.get_xend_http_server():
    5.51 +        port = xroot.get_xend_event_port()
    5.52 +        interface = xroot.get_xend_address()
    5.53 +        reactor.listenTCP(port, factory, interface=interface)
     6.1 --- a/tools/python/xen/xm/create.py	Wed Apr 27 14:42:44 2005 +0000
     6.2 +++ b/tools/python/xen/xm/create.py	Wed Apr 27 16:06:43 2005 +0000
     6.3 @@ -593,7 +593,8 @@ def main(argv):
     6.4      else:
     6.5          (dom, console) = make_domain(opts, config)
     6.6          if opts.vals.console_autoconnect:
     6.7 -            console_client.connect('localhost', console)
     6.8 +            path = "/var/lib/xend/console-%s" % console
     6.9 +            console_client.connect('localhost', console, path=path)
    6.10          
    6.11  if __name__ == '__main__':
    6.12      main(sys.argv)
     7.1 --- a/tools/python/xen/xm/main.py	Wed Apr 27 14:42:44 2005 +0000
     7.2 +++ b/tools/python/xen/xm/main.py	Wed Apr 27 16:06:43 2005 +0000
     7.3 @@ -644,7 +644,8 @@ class ProgConsole(Prog):
     7.4              self.err("No console information")
     7.5          port = sxp.child_value(console, "console_port")
     7.6          from xen.util import console_client
     7.7 -        console_client.connect("localhost", int(port))
     7.8 +        path = "/var/lib/xend/console-%s" % port
     7.9 +        console_client.connect("localhost", int(port), path=path)
    7.10  
    7.11  xm.prog(ProgConsole)
    7.12