ia64/xen-unstable

changeset 6025:0ee061e5b8a8

The attached patch removes all of the console handling code from Xend
and changes xm to simply exec /usr/libexec/xen/xc_console.

I've done a pretty good amount of testing and this seems to clear up all
of the Xend console issues in bugzilla.

This is a pretty big change to Xend though with a lot of deleted code so
I'd appreciate if people more familiar with the Xend codebase could look
through it critically.

In addition to the patch, the following files are no longer used:

tools/python/xen/util/console_client.py
tools/python/xen/xend/XendConsole.py
tools/python/xen/xend/server/SrvConsole.py
tools/python/xen/xend/server/SrvConsoleDir.py
tools/python/xen/xend/server/console.py

Regards,

Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Aug 04 09:00:16 2005 +0000 (2005-08-04)
parents 25b8b05ad991
children d25da0ddd9d5
files tools/Makefile tools/misc/xend tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvRoot.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/event.py tools/python/xen/xend/server/messages.py tools/python/xen/xm/create.py tools/python/xen/xm/main.py
line diff
     1.1 --- a/tools/Makefile	Thu Aug 04 08:58:18 2005 +0000
     1.2 +++ b/tools/Makefile	Thu Aug 04 09:00:16 2005 +0000
     1.3 @@ -13,7 +13,7 @@ SUBDIRS += xcutils
     1.4  #SUBDIRS += pygrub
     1.5  SUBDIRS += firmware
     1.6  SUBDIRS += security
     1.7 -#SUBDIRS += consoled
     1.8 +SUBDIRS += consoled
     1.9  
    1.10  .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
    1.11  
     2.1 --- a/tools/misc/xend	Thu Aug 04 08:58:18 2005 +0000
     2.2 +++ b/tools/misc/xend	Thu Aug 04 09:00:16 2005 +0000
     2.3 @@ -130,6 +130,8 @@ def main():
     2.4          return status >> 8
     2.5      elif sys.argv[1] == 'start':
     2.6          start_xcs()
     2.7 +        if os.fork() == 0:
     2.8 +            os.execvp('/usr/sbin/consoled', ['/usr/sbin/consoled']);
     2.9          return daemon.start()
    2.10      elif sys.argv[1] == 'trace_start':
    2.11          start_xcs()
     3.1 --- a/tools/python/xen/util/console_client.py	Thu Aug 04 08:58:18 2005 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,108 +0,0 @@
     3.4 -#!/usr/bin/env python
     3.5 -
     3.6 -##############################################
     3.7 -# Console client for Xen guest OSes
     3.8 -# Copyright (c) 2004, K A Fraser
     3.9 -##############################################
    3.10 -
    3.11 -import errno, os, signal, socket, struct, sys
    3.12 -
    3.13 -from termios import *
    3.14 -# Indexes into termios.tcgetattr() list.
    3.15 -IFLAG  = 0
    3.16 -OFLAG  = 1
    3.17 -CFLAG  = 2
    3.18 -LFLAG  = 3
    3.19 -ISPEED = 4
    3.20 -OSPEED = 5
    3.21 -CC     = 6
    3.22 -
    3.23 -def __child_death(signum, frame):
    3.24 -    global stop
    3.25 -    stop = True
    3.26 -
    3.27 -def __recv_from_sock(sock):
    3.28 -    global stop
    3.29 -    stop = False
    3.30 -    while not stop:
    3.31 -        try:
    3.32 -            data = sock.recv(1024)
    3.33 -        except socket.error, error:
    3.34 -            if error[0] != errno.EINTR:
    3.35 -                raise
    3.36 -        else:
    3.37 -            try:
    3.38 -                os.write(1, data)
    3.39 -            except os.error, error:
    3.40 -                if error[0] != errno.EINTR:
    3.41 -                    raise
    3.42 -    os.wait()
    3.43 -
    3.44 -def __send_to_sock(sock):
    3.45 -    while 1:
    3.46 -        try:
    3.47 -            data = os.read(0,1024)
    3.48 -        except os.error, error:
    3.49 -            if error[0] != errno.EINTR:
    3.50 -                raise
    3.51 -        else:
    3.52 -            if ord(data[0]) == ord(']')-64:
    3.53 -                break
    3.54 -            try:
    3.55 -                sock.send(data)
    3.56 -            except socket.error, error:
    3.57 -                if error[0] == errno.EPIPE:
    3.58 -                    sys.exit(0)
    3.59 -                if error[0] != errno.EINTR:
    3.60 -                    raise
    3.61 -    sys.exit(0)
    3.62 -
    3.63 -def connect(host, port, path=None):
    3.64 -    # Try inet first. If 'path' is given and the error
    3.65 -    # was connection refused, try unix-domain on 'path'.
    3.66 -    try:
    3.67 -        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    3.68 -        sock.connect((host, port))
    3.69 -    except socket.error, err:
    3.70 -        if (path is None) or (err[0] != errno.ECONNREFUSED):
    3.71 -            raise
    3.72 -        # Try unix-domain.
    3.73 -        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    3.74 -        sock.connect(path)
    3.75 -
    3.76 -    oattrs = tcgetattr(0)
    3.77 -    nattrs = tcgetattr(0)
    3.78 -    nattrs[IFLAG] = nattrs[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
    3.79 -    nattrs[OFLAG] = nattrs[OFLAG] & ~(OPOST)
    3.80 -    nattrs[CFLAG] = nattrs[CFLAG] & ~(CSIZE | PARENB)
    3.81 -    nattrs[CFLAG] = nattrs[CFLAG] | CS8
    3.82 -    nattrs[LFLAG] = nattrs[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
    3.83 -    nattrs[CC][VMIN] = 1
    3.84 -    nattrs[CC][VTIME] = 0
    3.85 -
    3.86 -    if os.fork():
    3.87 -        signal.signal(signal.SIGCHLD, __child_death)
    3.88 -        print "************ REMOTE CONSOLE: CTRL-] TO QUIT ********"
    3.89 -        tcsetattr(0, TCSAFLUSH, nattrs)
    3.90 -        try:
    3.91 -            __recv_from_sock(sock)
    3.92 -        finally:
    3.93 -            tcsetattr(0, TCSAFLUSH, oattrs)
    3.94 -            print
    3.95 -            print "************ REMOTE CONSOLE EXITED *****************"
    3.96 -    else:
    3.97 -        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
    3.98 -        __send_to_sock(sock)
    3.99 -
   3.100 -if __name__ == '__main__':
   3.101 -    argc = len(sys.argv)
   3.102 -    if argc < 3 or argc > 4:
   3.103 -        print >>sys.stderr, sys.argv[0], "<host> <port> [<path>]"
   3.104 -        sys.exit(1)
   3.105 -    host = sys.argv[1]
   3.106 -    port = int(sys.argv[2])
   3.107 -    if argc > 3:
   3.108 -        path = sys.argv[3]
   3.109 -    else:
   3.110 -        path = None
   3.111 -    connect(host, port, path=path)
     4.1 --- a/tools/python/xen/xend/XendClient.py	Thu Aug 04 08:58:18 2005 +0000
     4.2 +++ b/tools/python/xen/xend/XendClient.py	Thu Aug 04 09:00:16 2005 +0000
     4.3 @@ -5,9 +5,7 @@ Callable as a script - see main().
     4.4  Supports inet or unix connection to xend.
     4.5  
     4.6  This API is the 'control-plane' for xend.
     4.7 -The 'data-plane' is done separately. For example, consoles
     4.8 -are accessed via sockets on xend, but the list of consoles
     4.9 -is accessible via this API.
    4.10 +The 'data-plane' is done separately.
    4.11  """
    4.12  import os
    4.13  import sys
    4.14 @@ -146,9 +144,6 @@ class Xend:
    4.15      def domainurl(self, id=''):
    4.16          return self.url.relative('domain/' + str(id))
    4.17  
    4.18 -    def consoleurl(self, id=''):
    4.19 -        return self.url.relative('console/' + str(id))
    4.20 -
    4.21      def deviceurl(self, id=''):
    4.22          return self.url.relative('device/' + str(id))
    4.23  
    4.24 @@ -318,16 +313,6 @@ class Xend:
    4.25                                'idx'     : idx,
    4.26                                'config'  : fileof(config) })
    4.27  
    4.28 -    def xend_consoles(self):
    4.29 -        return self.xendGet(self.consoleurl())
    4.30 -
    4.31 -    def xend_console(self, id):
    4.32 -        return self.xendGet(self.consoleurl(id))
    4.33 -
    4.34 -    def xend_console_disconnect(self, id):
    4.35 -        return self.xendPost(self.consoleurl(id),
    4.36 -                             {'op'      : 'disconnect'})
    4.37 -
    4.38      def xend_vnets(self):
    4.39          return self.xendGet(self.vneturl())
    4.40  
     5.1 --- a/tools/python/xen/xend/XendConsole.py	Thu Aug 04 08:58:18 2005 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,44 +0,0 @@
     5.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     5.5 -
     5.6 -import XendRoot; xroot = XendRoot.instance()
     5.7 -from XendError import XendError
     5.8 -
     5.9 -class XendConsole:
    5.10 -
    5.11 -    def  __init__(self):
    5.12 -        pass
    5.13 -
    5.14 -    def console_ls(self):
    5.15 -        return [ c.console_port for c in self.consoles() ]
    5.16 -
    5.17 -    def consoles(self):
    5.18 -        l = []
    5.19 -        xd = XendRoot.get_component('xen.xend.XendDomain')
    5.20 -        for vm in xd.list():
    5.21 -            ctrl = vm.getDeviceController("console", error=False)
    5.22 -            if (not ctrl): continue
    5.23 -            console = ctrl.getDevice(0)
    5.24 -            if (not console): continue
    5.25 -            l.append(console)
    5.26 -        return l
    5.27 -    
    5.28 -    def console_get(self, id):
    5.29 -        id = int(id)
    5.30 -        for c in self.consoles():
    5.31 -            if c.console_port == id:
    5.32 -                return c
    5.33 -        return None
    5.34 -
    5.35 -    def console_disconnect(self, id):
    5.36 -        console = self.console_get(id)
    5.37 -        if not console:
    5.38 -            raise XendError('Invalid console id')
    5.39 -        console.disconnect()
    5.40 -
    5.41 -def instance():
    5.42 -    global inst
    5.43 -    try:
    5.44 -        inst
    5.45 -    except:
    5.46 -        inst = XendConsole()
    5.47 -    return inst
     6.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Aug 04 08:58:18 2005 +0000
     6.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Aug 04 09:00:16 2005 +0000
     6.3 @@ -268,7 +268,6 @@ class XendDomainInfo:
     6.4          self.restart_time = None
     6.5          self.restart_count = 0
     6.6          
     6.7 -        self.console_port = None
     6.8          self.vcpus = 1
     6.9          self.bootloader = None
    6.10  
    6.11 @@ -344,9 +343,6 @@ class XendDomainInfo:
    6.12          s += " name=" + self.name
    6.13          s += " memory=" + str(self.memory)
    6.14          s += " ssidref=" + str(self.ssidref)
    6.15 -        console = self.getConsole()
    6.16 -        if console:
    6.17 -            s += " console=" + str(console.console_port)
    6.18          s += ">"
    6.19          return s
    6.20  
    6.21 @@ -443,9 +439,6 @@ class XendDomainInfo:
    6.22              sxpr.append(self.store_channel.sxpr())
    6.23          if self.store_mfn:
    6.24              sxpr.append(['store_mfn', self.store_mfn])
    6.25 -        console = self.getConsole()
    6.26 -        if console:
    6.27 -            sxpr.append(console.sxpr())
    6.28  
    6.29          if self.restart_count:
    6.30              sxpr.append(['restart_count', self.restart_count])
    6.31 @@ -519,7 +512,6 @@ class XendDomainInfo:
    6.32  
    6.33              # Create domain devices.
    6.34              self.configure_backends()
    6.35 -            self.configure_console()
    6.36              self.configure_restart()
    6.37              self.construct_image()
    6.38              self.configure()
    6.39 @@ -785,17 +777,6 @@ class XendDomainInfo:
    6.40          """
    6.41          self.bootloader = sxp.child_value(self.config, "bootloader")
    6.42  
    6.43 -    def configure_console(self):
    6.44 -        """Configure the vm console port.
    6.45 -        """
    6.46 -        x = sxp.child_value(self.config, 'console')
    6.47 -        if x:
    6.48 -            try:
    6.49 -                port = int(x)
    6.50 -            except:
    6.51 -                raise VmError('invalid console:' + str(x))
    6.52 -            self.console_port = port
    6.53 -
    6.54      def configure_restart(self):
    6.55          """Configure the vm restart mode.
    6.56          """
    6.57 @@ -855,7 +836,7 @@ class XendDomainInfo:
    6.58  
    6.59      def restart(self):
    6.60          """Restart the domain after it has exited.
    6.61 -        Reuses the domain id and console port.
    6.62 +        Reuses the domain id
    6.63  
    6.64          """
    6.65          try:
    6.66 @@ -910,25 +891,9 @@ class XendDomainInfo:
    6.67  
    6.68          """
    6.69          self.configure_fields()
    6.70 -        self.create_console()
    6.71          self.create_devices()
    6.72          self.create_blkif()
    6.73  
    6.74 -    def create_console(self):
    6.75 -        console = self.getConsole()
    6.76 -        if not console:
    6.77 -            config = ['console']
    6.78 -            if self.console_port:
    6.79 -                config.append(['console_port', self.console_port])
    6.80 -            console = self.createDevice('console', config)
    6.81 -        return console
    6.82 -
    6.83 -    def getConsole(self):
    6.84 -        console_ctrl = self.getDeviceController("console", error=False)
    6.85 -        if console_ctrl:
    6.86 -            return console_ctrl.getDevice(0)
    6.87 -        return None
    6.88 -
    6.89      def create_blkif(self):
    6.90          """Create the block device interface (blkif) for the vm.
    6.91          The vm needs a blkif even if it doesn't have any disks
    6.92 @@ -1048,7 +1013,6 @@ add_config_handler('memory',     vm_fiel
    6.93  add_config_handler('ssidref',    vm_field_ignore)
    6.94  add_config_handler('cpu',        vm_field_ignore)
    6.95  add_config_handler('cpu_weight', vm_field_ignore)
    6.96 -add_config_handler('console',    vm_field_ignore)
    6.97  add_config_handler('restart',    vm_field_ignore)
    6.98  add_config_handler('image',      vm_field_ignore)
    6.99  add_config_handler('device',     vm_field_ignore)
   6.100 @@ -1062,9 +1026,6 @@ add_config_handler('maxmem',     vm_fiel
   6.101  #============================================================================
   6.102  # Register device controllers and their device config types.
   6.103  
   6.104 -from server import console
   6.105 -controller.addDevControllerClass("console", console.ConsoleController)
   6.106 -
   6.107  from server import blkif
   6.108  controller.addDevControllerClass("vbd", blkif.BlkifController)
   6.109  add_device_handler("vbd", "vbd")
     7.1 --- a/tools/python/xen/xend/XendRoot.py	Thu Aug 04 08:58:18 2005 +0000
     7.2 +++ b/tools/python/xen/xend/XendRoot.py	Thu Aug 04 09:00:16 2005 +0000
     7.3 @@ -70,12 +70,6 @@ class XendRoot:
     7.4      """Default path the unix-domain server listens at."""
     7.5      xend_unix_path_default = '/var/lib/xend/xend-socket'
     7.6  
     7.7 -    """Default interface address xend listens at for consoles."""
     7.8 -    console_address_default   = 'localhost'
     7.9 -
    7.10 -    """Default port xend serves consoles at. """
    7.11 -    console_port_base_default = '9600'
    7.12 -
    7.13      dom0_min_mem_default = '0'
    7.14  
    7.15      dom0_cpus_default = '0'
    7.16 @@ -302,19 +296,6 @@ class XendRoot:
    7.17          """
    7.18          return self.get_config_value("xend-unix-path", self.xend_unix_path_default)
    7.19  
    7.20 -    def get_console_address(self):
    7.21 -        """Get the address xend listens at for its console ports.
    7.22 -        This defaults to 'localhost', allowing only the localhost to connect
    7.23 -        to the console ports.  Setting this to the empty string, allows all
    7.24 -        hosts to connect.
    7.25 -        """
    7.26 -        return self.get_config_value('console-address', self.console_address_default)
    7.27 -
    7.28 -    def get_console_port_base(self):
    7.29 -        """Get the base port number used to generate console ports for domains.
    7.30 -        """
    7.31 -        return self.get_config_int('console-port-base', self.console_port_base_default)
    7.32 -
    7.33      def get_block_script(self, type):
    7.34          return self.get_config_value('block-%s' % type, '')
    7.35  
     8.1 --- a/tools/python/xen/xend/server/SrvConsole.py	Thu Aug 04 08:58:18 2005 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,41 +0,0 @@
     8.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     8.5 -
     8.6 -from xen.xend import sxp
     8.7 -from xen.xend import XendConsole
     8.8 -from xen.web.SrvDir import SrvDir
     8.9 -
    8.10 -class SrvConsole(SrvDir):
    8.11 -    """An individual console.
    8.12 -    """
    8.13 -
    8.14 -    def __init__(self, info):
    8.15 -        SrvDir.__init__(self)
    8.16 -        self.info = info
    8.17 -        self.xc = XendConsole.instance()
    8.18 -
    8.19 -    def op_disconnect(self, op, req):
    8.20 -        val = self.xc.console_disconnect(self.info.console_port)
    8.21 -        return val
    8.22 -
    8.23 -    def render_POST(self, req):
    8.24 -        return self.perform(req)
    8.25 -        
    8.26 -    def render_GET(self, req):
    8.27 -        if self.use_sxp(req):
    8.28 -            req.setHeader("Content-Type", sxp.mime_type)
    8.29 -            sxp.show(self.info.sxpr(), out=req)
    8.30 -        else:
    8.31 -            req.write('<html><head></head><body>')
    8.32 -            self.print_path(req)
    8.33 -            #self.ls()
    8.34 -            req.write('<p>%s</p>' % self.info)
    8.35 -            req.write('<p><a href="%s">Connect to domain %d</a></p>'
    8.36 -                      % (self.info.uri(), self.info.id))
    8.37 -            self.form(req)
    8.38 -            req.write('</body></html>')
    8.39 -
    8.40 -    def form(self, req):
    8.41 -        req.write('<form method="post" action="%s">' % req.prePathURL())
    8.42 -        if self.info.connected():
    8.43 -            req.write('<input type="submit" name="op" value="disconnect">')
    8.44 -        req.write('</form>')
     9.1 --- a/tools/python/xen/xend/server/SrvConsoleDir.py	Thu Aug 04 08:58:18 2005 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,59 +0,0 @@
     9.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
     9.5 -
     9.6 -from xen.web.SrvDir import SrvDir
     9.7 -from SrvConsole import SrvConsole
     9.8 -from xen.xend import XendConsole
     9.9 -from xen.xend import sxp
    9.10 -
    9.11 -class SrvConsoleDir(SrvDir):
    9.12 -    """Console directory.
    9.13 -    """
    9.14 -
    9.15 -    def __init__(self):
    9.16 -        SrvDir.__init__(self)
    9.17 -        self.xconsole = XendConsole.instance()
    9.18 -
    9.19 -    def console(self, x):
    9.20 -        val = None
    9.21 -        try:
    9.22 -            info = self.xconsole.console_get(x)
    9.23 -            val = SrvConsole(info)
    9.24 -        except KeyError, ex:
    9.25 -            print 'SrvConsoleDir>', ex
    9.26 -            pass
    9.27 -        return val
    9.28 -
    9.29 -    def get(self, x):
    9.30 -        v = SrvDir.get(self, x)
    9.31 -        if v is not None:
    9.32 -            return v
    9.33 -        v = self.console(x)
    9.34 -        return v
    9.35 -
    9.36 -    def render_GET(self, req):
    9.37 -        if self.use_sxp(req):
    9.38 -            req.setHeader("Content-Type", sxp.mime_type)
    9.39 -            self.ls_console(req, 1)
    9.40 -        else:
    9.41 -            req.write("<html><head></head><body>")
    9.42 -            self.print_path(req)
    9.43 -            self.ls(req)
    9.44 -            self.ls_console(req)
    9.45 -            #self.form(req.wfile)
    9.46 -            req.write("</body></html>")
    9.47 -
    9.48 -    def ls_console(self, req, use_sxp=0):
    9.49 -        url = req.prePathURL()
    9.50 -        if not url.endswith('/'):
    9.51 -            url += '/'
    9.52 -        if use_sxp:
    9.53 -            consoles = self.xconsole.console_ls()
    9.54 -            sxp.show(consoles, out=req)
    9.55 -        else:
    9.56 -            consoles = self.xconsole.consoles()
    9.57 -            consoles.sort(lambda x, y: cmp(x.console_port, y.console_port))
    9.58 -            req.write('<ul>')
    9.59 -            for c in consoles:
    9.60 -                cid = str(c.console_port)
    9.61 -                req.write('<li><a href="%s%s"> %s</a></li>' % (url, cid, cid))
    9.62 -            req.write('</ul>')
    10.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Thu Aug 04 08:58:18 2005 +0000
    10.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Thu Aug 04 09:00:16 2005 +0000
    10.3 @@ -4,7 +4,6 @@ from xen.web import http
    10.4  
    10.5  from xen.xend import sxp
    10.6  from xen.xend import XendDomain
    10.7 -from xen.xend import XendConsole
    10.8  from xen.xend import PrettyPrint
    10.9  from xen.xend.Args import FormFn
   10.10  
   10.11 @@ -18,7 +17,6 @@ class SrvDomain(SrvDir):
   10.12          SrvDir.__init__(self)
   10.13          self.dom = dom
   10.14          self.xd = XendDomain.instance()
   10.15 -        self.xconsole = XendConsole.instance()
   10.16  
   10.17      def op_configure(self, op, req):
   10.18          """Configure an existing domain.
   10.19 @@ -208,14 +206,6 @@ class SrvDomain(SrvDir):
   10.20              self.print_path(req)
   10.21              #self.ls()
   10.22              req.write('<p>%s</p>' % self.dom)
   10.23 -            if self.dom.console:
   10.24 -                cinfo = self.dom.console
   10.25 -                cid = str(cinfo.console_port)
   10.26 -                #todo: Local xref: need to know server prefix.
   10.27 -                req.write('<p><a href="/xend/console/%s">Console %s</a></p>'
   10.28 -                          % (cid, cid))
   10.29 -                req.write('<p><a href="%s">Connect to console</a></p>'
   10.30 -                          % cinfo.uri())
   10.31              if self.dom.config:
   10.32                  req.write("<code><pre>")
   10.33                  PrettyPrint.prettyprint(self.dom.config, out=req)
    11.1 --- a/tools/python/xen/xend/server/SrvRoot.py	Thu Aug 04 08:58:18 2005 +0000
    11.2 +++ b/tools/python/xen/xend/server/SrvRoot.py	Thu Aug 04 09:00:16 2005 +0000
    11.3 @@ -15,7 +15,6 @@ class SrvRoot(SrvDir):
    11.4      subdirs = [
    11.5          ('node',    'SrvNode'       ),
    11.6          ('domain',  'SrvDomainDir'  ),
    11.7 -        ('console', 'SrvConsoleDir' ),
    11.8          ('vnet',    'SrvVnetDir'    ),
    11.9          ]
   11.10  
    12.1 --- a/tools/python/xen/xend/server/SrvServer.py	Thu Aug 04 08:58:18 2005 +0000
    12.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Thu Aug 04 09:00:16 2005 +0000
    12.3 @@ -1,7 +1,7 @@
    12.4  #!/usr/bin/python
    12.5  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    12.6  
    12.7 -"""Example xend HTTP and console server.
    12.8 +"""Example xend HTTP
    12.9  
   12.10     Can be accessed from a browser or from a program.
   12.11     Do 'python SrvServer.py' to run the server.
    13.1 --- a/tools/python/xen/xend/server/console.py	Thu Aug 04 08:58:18 2005 +0000
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,391 +0,0 @@
    13.4 -# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    13.5 -
    13.6 -import socket
    13.7 -import threading
    13.8 -from errno import EAGAIN, EINTR, EWOULDBLOCK
    13.9 -    
   13.10 -from xen.web import reactor, protocol
   13.11 -
   13.12 -from xen.lowlevel import xu
   13.13 -
   13.14 -from xen.xend.XendError import XendError
   13.15 -from xen.xend import EventServer; eserver = EventServer.instance()
   13.16 -from xen.xend.XendLogging import log
   13.17 -from xen.xend import XendRoot; xroot = XendRoot.instance()
   13.18 -from xen.xend import sxp
   13.19 -from xen.xend.xenstore import DBVar
   13.20 -
   13.21 -from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
   13.22 -from xen.xend.server.messages import *
   13.23 -from xen.xend.server.params import *
   13.24 -
   13.25 -class ConsoleProtocol(protocol.Protocol):
   13.26 -    """Asynchronous handler for a console socket.
   13.27 -    """
   13.28 -
   13.29 -    def __init__(self, console, id):
   13.30 -        self.console = console
   13.31 -        self.id = id
   13.32 -        self.addr = None
   13.33 -
   13.34 -    def connectionMade(self, addr=None):
   13.35 -        peer = self.transport.getPeer()
   13.36 -        self.addr = addr
   13.37 -        if self.console.connect(self.addr, self):
   13.38 -            self.transport.write("Cannot connect to console %d on domain %d\n"
   13.39 -                                 % (self.id, self.console.getDomain()))
   13.40 -            self.loseConnection()
   13.41 -            return
   13.42 -        else:
   13.43 -            if len(self.addr) == 2:
   13.44 -                host = str(self.addr[0])
   13.45 -                port = str(self.addr[1])
   13.46 -            else:
   13.47 -                host = 'localhost'
   13.48 -                port = str(addr)
   13.49 -            log.info("Console connected %s %s %s",
   13.50 -                     self.id, host, port)
   13.51 -            eserver.inject('xend.console.connect',
   13.52 -                           [self.id, host, port])
   13.53 -
   13.54 -    def dataReceived(self, data):
   13.55 -        if self.console.receiveInput(self, data):
   13.56 -            self.loseConnection()
   13.57 -
   13.58 -    def write(self, data):
   13.59 -        self.transport.write(data)
   13.60 -        return len(data)
   13.61 -
   13.62 -    def connectionLost(self, reason=None):
   13.63 -        log.info("Console disconnected %s %s %s",
   13.64 -                 str(self.id), str(self.addr[0]), str(self.addr[1]))
   13.65 -        eserver.inject('xend.console.disconnect',
   13.66 -                       [self.id, self.addr[0], self.addr[1]])
   13.67 -        self.console.disconnect(conn=self)
   13.68 -
   13.69 -    def loseConnection(self):
   13.70 -        self.transport.loseConnection()
   13.71 -
   13.72 -class ConsoleDev(Dev, protocol.ServerFactory):
   13.73 -    """Console device for a domain.
   13.74 -    Does not poll for i/o itself, but relies on the domain to post console
   13.75 -    output and the connected TCP sockets to post console input.
   13.76 -    """
   13.77 -
   13.78 -    STATUS_NEW       = 'new'
   13.79 -    STATUS_CLOSED    = 'closed'
   13.80 -    STATUS_CONNECTED = 'connected'
   13.81 -    STATUS_LISTENING = 'listening'
   13.82 -
   13.83 -    __exports__ = Dev.__exports__ + [
   13.84 -        DBVar('status',       ty='str'),
   13.85 -        #DBVar('listening',    ty='str'),
   13.86 -        DBVar('console_port', ty='int'),
   13.87 -        ]
   13.88 -
   13.89 -    def __init__(self, controller, id, config, recreate=False):
   13.90 -        Dev.__init__(self, controller, id, config)
   13.91 -        self.lock = threading.RLock()
   13.92 -        self.status = self.STATUS_NEW
   13.93 -        self.addr = None
   13.94 -        self.conn = None
   13.95 -        self.console_port = None
   13.96 -        self.obuf = xu.buffer()
   13.97 -        self.ibuf = xu.buffer()
   13.98 -        self.channel = None
   13.99 -        self.listening = False
  13.100 -        self.unix_listener = None
  13.101 -        self.tcp_listener = None
  13.102 -        
  13.103 -        console_port = sxp.child_value(self.config, "console_port")
  13.104 -        if console_port is None:
  13.105 -            console_port = xroot.get_console_port_base() + self.getDomain()
  13.106 -        self.checkConsolePort(console_port)
  13.107 -        self.console_port = console_port
  13.108 -        
  13.109 -        log.info("Created console id=%d domain=%d port=%d",
  13.110 -                 self.id, self.getDomain(), self.console_port)
  13.111 -        eserver.inject('xend.console.create',
  13.112 -                       [self.id, self.getDomain(), self.console_port])
  13.113 -
  13.114 -    def init(self, recreate=False, reboot=False):
  13.115 -        try:
  13.116 -            self.lock.acquire()
  13.117 -            self.destroyed = False
  13.118 -            self.channel = self.getChannel()
  13.119 -            self.listen()
  13.120 -        finally:
  13.121 -            self.lock.release()
  13.122 -
  13.123 -    def checkConsolePort(self, console_port):
  13.124 -        """Check that a console port is not in use by another console.
  13.125 -        """
  13.126 -        xd = XendRoot.get_component('xen.xend.XendDomain')
  13.127 -        for vm in xd.list():
  13.128 -            ctrl = vm.getDeviceController(self.getType(), error=False)
  13.129 -            if (not ctrl): continue
  13.130 -            ctrl.checkConsolePort(console_port)
  13.131 -    
  13.132 -    def sxpr(self):
  13.133 -        try:
  13.134 -            self.lock.acquire()
  13.135 -            val = ['console',
  13.136 -                   ['status', self.status ],
  13.137 -                   ['id',     self.id    ],
  13.138 -                   ['domain', self.getDomain() ] ]
  13.139 -            val.append(['local_port',   self.getLocalPort()  ])
  13.140 -            val.append(['remote_port',  self.getRemotePort() ])
  13.141 -            val.append(['console_port', self.console_port    ])
  13.142 -            if self.addr:
  13.143 -                val.append(['connected', self.addr[0], self.addr[1]])
  13.144 -        finally:
  13.145 -            self.lock.release()
  13.146 -        return val
  13.147 -
  13.148 -    def getLocalPort(self):
  13.149 -        try:
  13.150 -            self.lock.acquire()
  13.151 -            if self.channel:
  13.152 -                return self.channel.getLocalPort()
  13.153 -            else:
  13.154 -                return 0
  13.155 -        finally:
  13.156 -            self.lock.release()
  13.157 -
  13.158 -    def getRemotePort(self):
  13.159 -        try:
  13.160 -            self.lock.acquire()
  13.161 -            if self.channel:
  13.162 -                return self.channel.getRemotePort()
  13.163 -            else:
  13.164 -                return 0
  13.165 -        finally:
  13.166 -            self.lock.release()
  13.167 -
  13.168 -    def uri(self):
  13.169 -        """Get the uri to use to connect to the console.
  13.170 -        This will be a telnet: uri.
  13.171 -
  13.172 -        return uri
  13.173 -        """
  13.174 -        host = socket.gethostname()
  13.175 -        return "telnet://%s:%d" % (host, self.console_port)
  13.176 -
  13.177 -    def closed(self):
  13.178 -        return self.status == self.STATUS_CLOSED
  13.179 -
  13.180 -    def connected(self):
  13.181 -        return self.status == self.STATUS_CONNECTED
  13.182 -
  13.183 -    def destroy(self, change=False, reboot=False):
  13.184 -        """Close the console.
  13.185 -        """
  13.186 -        if reboot:
  13.187 -            return
  13.188 -        try:
  13.189 -            self.lock.acquire()
  13.190 -            self.status = self.STATUS_CLOSED
  13.191 -            self.listening = False
  13.192 -            if self.conn:
  13.193 -                self.conn.loseConnection()
  13.194 -            if self.tcp_listener:
  13.195 -                self.tcp_listener.stopListening()
  13.196 -                self.tcp_listener = None
  13.197 -            if self.unix_listener:
  13.198 -                self.unix_listener.stopListening()
  13.199 -                self.unix_listener = None
  13.200 -        finally:
  13.201 -            self.lock.release()
  13.202 -
  13.203 -    def listen(self):
  13.204 -        """Listen for TCP connections to the console port..
  13.205 -        """
  13.206 -        try:
  13.207 -            self.lock.acquire()
  13.208 -            if self.closed():
  13.209 -                return
  13.210 -            if self.listening:
  13.211 -                pass
  13.212 -            else:
  13.213 -                self.listening = True
  13.214 -                self.status = self.STATUS_LISTENING
  13.215 -                if xroot.get_xend_unix_server():
  13.216 -                    path = '/var/lib/xend/console-%s' % self.console_port
  13.217 -                    self.unix_listener = reactor.listenUNIX(path, self)
  13.218 -                if xroot.get_xend_http_server():
  13.219 -                    interface = xroot.get_console_address()
  13.220 -                    self.tcp_listener = reactor.listenTCP(
  13.221 -                        self.console_port, self, interface=interface)
  13.222 -        finally:
  13.223 -            self.lock.release()
  13.224 -
  13.225 -    def buildProtocol(self, addr):
  13.226 -        """Factory function called to create the protocol when a connection is accepted
  13.227 -        by listenTCP.
  13.228 -        """
  13.229 -        proto = ConsoleProtocol(self, self.id)
  13.230 -        proto.factory = self
  13.231 -        return proto
  13.232 -
  13.233 -    def connect(self, addr, conn):
  13.234 -        """Connect a TCP connection to the console.
  13.235 -        Fails if closed or already connected.
  13.236 -
  13.237 -        addr peer address
  13.238 -        conn connection
  13.239 -
  13.240 -        returns 0 if ok, negative otherwise
  13.241 -        """
  13.242 -        try:
  13.243 -            self.lock.acquire()
  13.244 -            if self.closed():
  13.245 -                return -1
  13.246 -            if self.connected():
  13.247 -                return -1
  13.248 -            self.addr = addr
  13.249 -            self.conn = conn
  13.250 -            self.status = self.STATUS_CONNECTED
  13.251 -            self.writeOutput()
  13.252 -        finally:
  13.253 -            self.lock.release()
  13.254 -        return 0
  13.255 -
  13.256 -    def disconnect(self, conn=None):
  13.257 -        """Disconnect the TCP connection to the console.
  13.258 -        """
  13.259 -        try:
  13.260 -            self.lock.acquire()
  13.261 -            if conn and conn != self.conn: return
  13.262 -            if self.conn:
  13.263 -                self.conn.loseConnection()
  13.264 -            self.addr = None
  13.265 -            self.conn = None
  13.266 -            self.status = self.STATUS_LISTENING
  13.267 -            self.listen()
  13.268 -        finally:
  13.269 -            self.lock.release()
  13.270 -
  13.271 -    def receiveOutput(self, msg):
  13.272 -        """Receive output console data from the console channel.
  13.273 -
  13.274 -        msg     console message
  13.275 -        type    major message type
  13.276 -        subtype minor message typ
  13.277 -        """
  13.278 -        # Treat the obuf as a ring buffer.
  13.279 -        try:
  13.280 -            self.lock.acquire()
  13.281 -            data = msg.get_payload()
  13.282 -            data_n = len(data)
  13.283 -            if self.obuf.space() < data_n:
  13.284 -                self.obuf.discard(data_n)
  13.285 -            if self.obuf.space() < data_n:
  13.286 -                data = data[-self.obuf.space():]
  13.287 -            self.obuf.write(data)
  13.288 -            self.writeOutput()
  13.289 -        finally:
  13.290 -            self.lock.release()
  13.291 -        
  13.292 -    def writeOutput(self):
  13.293 -        """Handle buffered output from the console device.
  13.294 -        Sends it to the connected TCP connection (if any).
  13.295 -        """
  13.296 -        try:
  13.297 -            self.lock.acquire()
  13.298 -            if self.closed():
  13.299 -                return -1
  13.300 -            writes = 0
  13.301 -            while self.conn and (writes < 100) and (not self.obuf.empty()):
  13.302 -                try:
  13.303 -                    writes += 1
  13.304 -                    bytes = self.conn.write(self.obuf.peek())
  13.305 -                    if bytes > 0:
  13.306 -                        self.obuf.discard(bytes)
  13.307 -                except socket.error, err:
  13.308 -                    if err.args[0] in (EWOULDBLOCK, EAGAIN, EINTR):
  13.309 -                        pass
  13.310 -                    else:
  13.311 -                        self.disconnect()
  13.312 -                        break
  13.313 -                        
  13.314 -        finally:
  13.315 -            self.lock.release()
  13.316 -        return 0
  13.317 -    
  13.318 -    def receiveInput(self, conn, data):
  13.319 -        """Receive console input from a TCP connection.  Ignores the
  13.320 -        input if the calling connection (conn) is not the one
  13.321 -        connected to the console (self.conn).
  13.322 -
  13.323 -        conn connection
  13.324 -        data input data
  13.325 -        """
  13.326 -        try:
  13.327 -            self.lock.acquire()
  13.328 -            if self.closed(): return -1
  13.329 -            if conn != self.conn: return 0
  13.330 -            self.ibuf.write(data)
  13.331 -            self.writeInput()
  13.332 -        finally:
  13.333 -            self.lock.release()
  13.334 -        return 0
  13.335 -
  13.336 -    def writeInput(self):
  13.337 -        """Write pending console input to the console channel.
  13.338 -        Writes as much to the channel as it can.
  13.339 -        """
  13.340 -        try:
  13.341 -            self.lock.acquire()
  13.342 -            while self.channel and not self.ibuf.empty():
  13.343 -                msg = xu.message(CMSG_CONSOLE, 0, 0)
  13.344 -                msg.append_payload(self.ibuf.read(msg.MAX_PAYLOAD))
  13.345 -                self.channel.writeRequest(msg)
  13.346 -        finally:
  13.347 -            self.lock.release()
  13.348 -
  13.349 -class ConsoleController(DevController):
  13.350 -    """Device controller for all the consoles for a domain.
  13.351 -    """
  13.352 -
  13.353 -    def __init__(self, vm, recreate=False):
  13.354 -        DevController.__init__(self, vm, recreate=recreate)
  13.355 -        self.rcvr = None
  13.356 -
  13.357 -    def initController(self, recreate=False, reboot=False):
  13.358 -        self.destroyed = False
  13.359 -        self.rcvr = CtrlMsgRcvr(self.getChannel())
  13.360 -        self.rcvr.addHandler(CMSG_CONSOLE,
  13.361 -                             0,
  13.362 -                             self.receiveOutput)
  13.363 -        self.rcvr.registerChannel()
  13.364 -        if reboot:
  13.365 -            self.rebootDevices()
  13.366 -
  13.367 -    def destroyController(self, reboot=False):
  13.368 -        self.destroyed = True
  13.369 -        self.destroyDevices(reboot=reboot)
  13.370 -        self.rcvr.deregisterChannel()
  13.371 -
  13.372 -    def newDevice(self, id, config, recreate=False):
  13.373 -        return ConsoleDev(self, id, config, recreate=recreate)
  13.374 -
  13.375 -    def checkConsolePort(self, console_port):
  13.376 -        """Check that a console port is not in use by a console.
  13.377 -        """
  13.378 -        for c in self.getDevices():
  13.379 -            if c.console_port == console_port:
  13.380 -                raise XendError('console port in use: ' + str(console_port))
  13.381 -
  13.382 -    def receiveOutput(self, msg):
  13.383 -        """Handle a control request.
  13.384 -        The CMSG_CONSOLE messages just contain data, and no console id,
  13.385 -        so just send to console 0 (if there is one).
  13.386 -
  13.387 -        todo: extend CMSG_CONSOLE to support more than one console?
  13.388 -        """
  13.389 -        console = self.getDevice(0)
  13.390 -        if console:
  13.391 -            console.receiveOutput(msg)
  13.392 -        else:
  13.393 -            log.warning('no console: domain %d', self.getDomain())
  13.394 -
    14.1 --- a/tools/python/xen/xend/server/event.py	Thu Aug 04 08:58:18 2005 +0000
    14.2 +++ b/tools/python/xen/xend/server/event.py	Thu Aug 04 09:00:16 2005 +0000
    14.3 @@ -128,16 +128,8 @@ class EventProtocol(protocol.Protocol):
    14.4      def op_pretty(self, name, req):
    14.5          self.pretty = 1
    14.6  
    14.7 -    def op_console_disconnect(self, name, req):
    14.8 -        id = sxp.child_value(req, 'id')
    14.9 -        if not id:
   14.10 -            raise XendError('Missing console id')
   14.11 -        id = int(id)
   14.12 -        self.daemon.console_disconnect(id)
   14.13 -
   14.14      def op_info(self, name, req):
   14.15          val = ['info']
   14.16 -        #val += self.daemon.consoles()
   14.17          #val += self.daemon.blkifs()
   14.18          #val += self.daemon.netifs()
   14.19          #val += self.daemon.usbifs()
    15.1 --- a/tools/python/xen/xend/server/messages.py	Thu Aug 04 08:58:18 2005 +0000
    15.2 +++ b/tools/python/xen/xend/server/messages.py	Thu Aug 04 09:00:16 2005 +0000
    15.3 @@ -18,16 +18,6 @@ See below.
    15.4  msg_formats = {}
    15.5  
    15.6  #============================================================================
    15.7 -# Console message types.
    15.8 -#============================================================================
    15.9 -
   15.10 -CMSG_CONSOLE  = 0
   15.11 -
   15.12 -console_formats = { 'console_data': (CMSG_CONSOLE, 0) }
   15.13 -
   15.14 -msg_formats.update(console_formats)
   15.15 -
   15.16 -#============================================================================
   15.17  # Block interface message types.
   15.18  #============================================================================
   15.19  
    16.1 --- a/tools/python/xen/xm/create.py	Thu Aug 04 08:58:18 2005 +0000
    16.2 +++ b/tools/python/xen/xm/create.py	Thu Aug 04 09:00:16 2005 +0000
    16.3 @@ -7,6 +7,7 @@ import random
    16.4  import string
    16.5  import sys
    16.6  import socket
    16.7 +import commands
    16.8  
    16.9  import xen.lowlevel.xc
   16.10  
   16.11 @@ -17,8 +18,6 @@ from xen.xend.XendBootloader import boot
   16.12  from xen.xend import XendRoot; xroot = XendRoot.instance()
   16.13  from xen.util import blkif
   16.14  
   16.15 -from xen.util import console_client
   16.16 -
   16.17  from xen.xm.opts import *
   16.18  
   16.19  gopts = Opts(use="""[options] [vars]
   16.20 @@ -145,10 +144,6 @@ gopts.var('cpu_weight', val='WEIGHT',
   16.21            use="""Set the new domain's cpu weight.
   16.22            WEIGHT is a float that controls the domain's share of the cpu.""")
   16.23  
   16.24 -gopts.var('console', val='PORT',
   16.25 -          fn=set_int, default=None,
   16.26 -          use="Console port to use. Default is 9600 + domain id.")
   16.27 -
   16.28  gopts.var('restart', val='onreboot|always|never',
   16.29            fn=set_value, default=None,
   16.30            use="""Whether the domain should be restarted on exit.
   16.31 @@ -471,8 +466,6 @@ def make_config(opts, vals):
   16.32          config.append(['backend', ['netif']])
   16.33      if vals.restart:
   16.34          config.append(['restart', vals.restart])
   16.35 -    if vals.console:
   16.36 -        config.append(['console', vals.console])
   16.37  
   16.38      if vals.bootloader:
   16.39          run_bootloader(opts, config, vals)
   16.40 @@ -620,8 +613,8 @@ def make_domain(opts, config):
   16.41  
   16.42      @param opts:   options
   16.43      @param config: configuration
   16.44 -    @return: domain id, console port
   16.45 -    @rtype:  (int, int)
   16.46 +    @return: domain id
   16.47 +    @rtype:  int
   16.48      """
   16.49  
   16.50      try:
   16.51 @@ -634,19 +627,13 @@ def make_domain(opts, config):
   16.52          opts.err(str(ex))
   16.53  
   16.54      dom = sxp.child_value(dominfo, 'name')
   16.55 -    console_info = sxp.child(dominfo, 'console')
   16.56 -    if console_info:
   16.57 -        console_port = int(sxp.child_value(console_info, 'console_port'))
   16.58 -    else:
   16.59 -        console_port = None
   16.60  
   16.61      if not opts.vals.paused:
   16.62          if server.xend_domain_unpause(dom) < 0:
   16.63              server.xend_domain_destroy(dom)
   16.64              opts.err("Failed to unpause domain %s" % dom)
   16.65 -    opts.info("Started domain %s, console on port %d"
   16.66 -              % (dom, console_port))
   16.67 -    return (dom, console_port)
   16.68 +    opts.info("Started domain %s" % (dom))
   16.69 +    return int(sxp.child_value(dominfo, 'id'))
   16.70  
   16.71  def get_dom0_alloc():
   16.72      """Return current allocation memory of dom0 (in MB). Return 0 on error"""
   16.73 @@ -709,10 +696,10 @@ def main(argv):
   16.74          if dom0_min_mem != 0:
   16.75              balloon_out(dom0_min_mem, opts)
   16.76  
   16.77 -        (dom, console) = make_domain(opts, config)
   16.78 +        dom = make_domain(opts, config)
   16.79          if opts.vals.console_autoconnect:
   16.80 -            path = "/var/lib/xend/console-%s" % console
   16.81 -            console_client.connect('localhost', console, path=path)
   16.82 +            cmd = "/usr/libexec/xen/xc_console %d" % dom
   16.83 +            os.execvp('/usr/libexec/xen/xc_console', cmd.split())
   16.84          
   16.85  if __name__ == '__main__':
   16.86      main(sys.argv)
    17.1 --- a/tools/python/xen/xm/main.py	Thu Aug 04 08:58:18 2005 +0000
    17.2 +++ b/tools/python/xen/xm/main.py	Thu Aug 04 09:00:16 2005 +0000
    17.3 @@ -4,6 +4,7 @@
    17.4  import os
    17.5  import os.path
    17.6  import sys
    17.7 +import commands
    17.8  from getopt import getopt
    17.9  import socket
   17.10  import warnings
   17.11 @@ -390,7 +391,7 @@ class ProgList(Prog):
   17.12              self.brief_list(doms)
   17.13  
   17.14      def brief_list(self, doms):
   17.15 -        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console'
   17.16 +        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
   17.17          for dom in doms:
   17.18              info = server.xend_domain(dom)
   17.19              d = {}
   17.20 @@ -401,19 +402,14 @@ class ProgList(Prog):
   17.21              d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
   17.22              d['state'] = sxp.child_value(info, 'state', '??')
   17.23              d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
   17.24 -            console = sxp.child(info, 'console')
   17.25 -            if console:
   17.26 -                d['port'] = sxp.child_value(console, 'console_port')
   17.27 -            else:
   17.28 -                d['port'] = ''
   17.29              if d['vcpus'] > 1:
   17.30                  d['cpu'] = '-'
   17.31              if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
   17.32                  d['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '0')) & 0xffff
   17.33                  d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff
   17.34 -                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s    s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
   17.35 +                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
   17.36              else:
   17.37 -                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s" % d)
   17.38 +                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f" % d)
   17.39  
   17.40      def show_vcpus(self, doms):
   17.41          print 'Name              Id  VCPU  CPU  CPUMAP'
   17.42 @@ -699,29 +695,6 @@ class ProgInfo(Prog):
   17.43  
   17.44  xm.prog(ProgInfo)
   17.45  
   17.46 -class ProgConsoles(Prog):
   17.47 -    group = 'console'
   17.48 -    name = "consoles"
   17.49 -    info = """Get information about domain consoles."""
   17.50 -
   17.51 -    def main(self, args):
   17.52 -        l = server.xend_consoles()
   17.53 -        print "Dom Port  Id Connection"
   17.54 -        for x in l:
   17.55 -            info = server.xend_console(x)
   17.56 -            d = {}
   17.57 -            d['dom'] = sxp.child(info, 'domain', '?')[1]
   17.58 -            d['port'] = sxp.child_value(info, 'console_port', '?')
   17.59 -            d['id'] = sxp.child_value(info, 'id', '?')
   17.60 -            connected = sxp.child(info, 'connected')
   17.61 -            if connected:
   17.62 -                d['conn'] = '%s:%s' % (connected[1], connected[2])
   17.63 -            else:
   17.64 -                d['conn'] = ''
   17.65 -            print "%(dom)3s %(port)4s %(id)3s %(conn)s" % d
   17.66 -
   17.67 -xm.prog(ProgConsoles)
   17.68 -
   17.69  class ProgConsole(Prog):
   17.70      group = 'console'
   17.71      name = "console"
   17.72 @@ -735,13 +708,9 @@ class ProgConsole(Prog):
   17.73          if len(args) < 2: self.err("%s: Missing domain" % args[0])
   17.74          dom = args[1]
   17.75          info = server.xend_domain(dom)
   17.76 -        console = sxp.child(info, "console")
   17.77 -        if not console:
   17.78 -            self.err("No console information")
   17.79 -        port = sxp.child_value(console, "console_port")
   17.80 -        from xen.util import console_client
   17.81 -        path = "/var/lib/xend/console-%s" % port
   17.82 -        console_client.connect("localhost", int(port), path=path)
   17.83 +        domid = int(sxp.child_value(info, 'id', '-1'))
   17.84 +        cmd = "/usr/libexec/xen/xc_console %d" % domid
   17.85 +        os.execvp('/usr/libexec/xen/xc_console', cmd.split())
   17.86  
   17.87  xm.prog(ProgConsole)
   17.88