diff --git a/tools/Makefile b/tools/Makefile index 2c668a59b9..629294e776 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -13,7 +13,7 @@ SUBDIRS += xcutils #SUBDIRS += pygrub SUBDIRS += firmware SUBDIRS += security -#SUBDIRS += consoled +SUBDIRS += consoled .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff --git a/tools/misc/xend b/tools/misc/xend index 06f5e660ec..706c838428 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -130,6 +130,8 @@ def main(): return status >> 8 elif sys.argv[1] == 'start': start_xcs() + if os.fork() == 0: + os.execvp('/usr/sbin/consoled', ['/usr/sbin/consoled']); return daemon.start() elif sys.argv[1] == 'trace_start': start_xcs() diff --git a/tools/python/xen/util/console_client.py b/tools/python/xen/util/console_client.py deleted file mode 100644 index c0acacfad3..0000000000 --- a/tools/python/xen/util/console_client.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python - -############################################## -# Console client for Xen guest OSes -# Copyright (c) 2004, K A Fraser -############################################## - -import errno, os, signal, socket, struct, sys - -from termios import * -# Indexes into termios.tcgetattr() list. -IFLAG = 0 -OFLAG = 1 -CFLAG = 2 -LFLAG = 3 -ISPEED = 4 -OSPEED = 5 -CC = 6 - -def __child_death(signum, frame): - global stop - stop = True - -def __recv_from_sock(sock): - global stop - stop = False - while not stop: - try: - data = sock.recv(1024) - except socket.error, error: - if error[0] != errno.EINTR: - raise - else: - try: - os.write(1, data) - except os.error, error: - if error[0] != errno.EINTR: - raise - os.wait() - -def __send_to_sock(sock): - while 1: - try: - data = os.read(0,1024) - except os.error, error: - if error[0] != errno.EINTR: - raise - else: - if ord(data[0]) == ord(']')-64: - break - try: - sock.send(data) - except socket.error, error: - if error[0] == errno.EPIPE: - sys.exit(0) - if error[0] != errno.EINTR: - raise - sys.exit(0) - -def connect(host, port, path=None): - # Try inet first. If 'path' is given and the error - # was connection refused, try unix-domain on 'path'. - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((host, port)) - except socket.error, err: - if (path is None) or (err[0] != errno.ECONNREFUSED): - raise - # Try unix-domain. - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(path) - - oattrs = tcgetattr(0) - nattrs = tcgetattr(0) - nattrs[IFLAG] = nattrs[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) - nattrs[OFLAG] = nattrs[OFLAG] & ~(OPOST) - nattrs[CFLAG] = nattrs[CFLAG] & ~(CSIZE | PARENB) - nattrs[CFLAG] = nattrs[CFLAG] | CS8 - nattrs[LFLAG] = nattrs[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG) - nattrs[CC][VMIN] = 1 - nattrs[CC][VTIME] = 0 - - if os.fork(): - signal.signal(signal.SIGCHLD, __child_death) - print "************ REMOTE CONSOLE: CTRL-] TO QUIT ********" - tcsetattr(0, TCSAFLUSH, nattrs) - try: - __recv_from_sock(sock) - finally: - tcsetattr(0, TCSAFLUSH, oattrs) - print - print "************ REMOTE CONSOLE EXITED *****************" - else: - signal.signal(signal.SIGPIPE, signal.SIG_IGN) - __send_to_sock(sock) - -if __name__ == '__main__': - argc = len(sys.argv) - if argc < 3 or argc > 4: - print >>sys.stderr, sys.argv[0], " []" - sys.exit(1) - host = sys.argv[1] - port = int(sys.argv[2]) - if argc > 3: - path = sys.argv[3] - else: - path = None - connect(host, port, path=path) diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 24812f4abb..868836c30f 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -5,9 +5,7 @@ Callable as a script - see main(). Supports inet or unix connection to xend. This API is the 'control-plane' for xend. -The 'data-plane' is done separately. For example, consoles -are accessed via sockets on xend, but the list of consoles -is accessible via this API. +The 'data-plane' is done separately. """ import os import sys @@ -146,9 +144,6 @@ class Xend: def domainurl(self, id=''): return self.url.relative('domain/' + str(id)) - def consoleurl(self, id=''): - return self.url.relative('console/' + str(id)) - def deviceurl(self, id=''): return self.url.relative('device/' + str(id)) @@ -318,16 +313,6 @@ class Xend: 'idx' : idx, 'config' : fileof(config) }) - def xend_consoles(self): - return self.xendGet(self.consoleurl()) - - def xend_console(self, id): - return self.xendGet(self.consoleurl(id)) - - def xend_console_disconnect(self, id): - return self.xendPost(self.consoleurl(id), - {'op' : 'disconnect'}) - def xend_vnets(self): return self.xendGet(self.vneturl()) diff --git a/tools/python/xen/xend/XendConsole.py b/tools/python/xen/xend/XendConsole.py deleted file mode 100644 index 7a04f5ddde..0000000000 --- a/tools/python/xen/xend/XendConsole.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) 2004 Mike Wray - -import XendRoot; xroot = XendRoot.instance() -from XendError import XendError - -class XendConsole: - - def __init__(self): - pass - - def console_ls(self): - return [ c.console_port for c in self.consoles() ] - - def consoles(self): - l = [] - xd = XendRoot.get_component('xen.xend.XendDomain') - for vm in xd.list(): - ctrl = vm.getDeviceController("console", error=False) - if (not ctrl): continue - console = ctrl.getDevice(0) - if (not console): continue - l.append(console) - return l - - def console_get(self, id): - id = int(id) - for c in self.consoles(): - if c.console_port == id: - return c - return None - - def console_disconnect(self, id): - console = self.console_get(id) - if not console: - raise XendError('Invalid console id') - console.disconnect() - -def instance(): - global inst - try: - inst - except: - inst = XendConsole() - return inst diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index f846bb72de..3e016b681f 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -268,7 +268,6 @@ class XendDomainInfo: self.restart_time = None self.restart_count = 0 - self.console_port = None self.vcpus = 1 self.bootloader = None @@ -344,9 +343,6 @@ class XendDomainInfo: s += " name=" + self.name s += " memory=" + str(self.memory) s += " ssidref=" + str(self.ssidref) - console = self.getConsole() - if console: - s += " console=" + str(console.console_port) s += ">" return s @@ -443,9 +439,6 @@ class XendDomainInfo: sxpr.append(self.store_channel.sxpr()) if self.store_mfn: sxpr.append(['store_mfn', self.store_mfn]) - console = self.getConsole() - if console: - sxpr.append(console.sxpr()) if self.restart_count: sxpr.append(['restart_count', self.restart_count]) @@ -519,7 +512,6 @@ class XendDomainInfo: # Create domain devices. self.configure_backends() - self.configure_console() self.configure_restart() self.construct_image() self.configure() @@ -785,17 +777,6 @@ class XendDomainInfo: """ self.bootloader = sxp.child_value(self.config, "bootloader") - def configure_console(self): - """Configure the vm console port. - """ - x = sxp.child_value(self.config, 'console') - if x: - try: - port = int(x) - except: - raise VmError('invalid console:' + str(x)) - self.console_port = port - def configure_restart(self): """Configure the vm restart mode. """ @@ -855,7 +836,7 @@ class XendDomainInfo: def restart(self): """Restart the domain after it has exited. - Reuses the domain id and console port. + Reuses the domain id """ try: @@ -910,25 +891,9 @@ class XendDomainInfo: """ self.configure_fields() - self.create_console() self.create_devices() self.create_blkif() - def create_console(self): - console = self.getConsole() - if not console: - config = ['console'] - if self.console_port: - config.append(['console_port', self.console_port]) - console = self.createDevice('console', config) - return console - - def getConsole(self): - console_ctrl = self.getDeviceController("console", error=False) - if console_ctrl: - return console_ctrl.getDevice(0) - return None - def create_blkif(self): """Create the block device interface (blkif) for the vm. The vm needs a blkif even if it doesn't have any disks @@ -1048,7 +1013,6 @@ add_config_handler('memory', vm_field_ignore) add_config_handler('ssidref', vm_field_ignore) add_config_handler('cpu', vm_field_ignore) add_config_handler('cpu_weight', vm_field_ignore) -add_config_handler('console', vm_field_ignore) add_config_handler('restart', vm_field_ignore) add_config_handler('image', vm_field_ignore) add_config_handler('device', vm_field_ignore) @@ -1062,9 +1026,6 @@ add_config_handler('maxmem', vm_field_maxmem) #============================================================================ # Register device controllers and their device config types. -from server import console -controller.addDevControllerClass("console", console.ConsoleController) - from server import blkif controller.addDevControllerClass("vbd", blkif.BlkifController) add_device_handler("vbd", "vbd") diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index 3d3767f9ba..57d5fe6848 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -70,12 +70,6 @@ class XendRoot: """Default path the unix-domain server listens at.""" xend_unix_path_default = '/var/lib/xend/xend-socket' - """Default interface address xend listens at for consoles.""" - console_address_default = 'localhost' - - """Default port xend serves consoles at. """ - console_port_base_default = '9600' - dom0_min_mem_default = '0' dom0_cpus_default = '0' @@ -302,19 +296,6 @@ class XendRoot: """ return self.get_config_value("xend-unix-path", self.xend_unix_path_default) - def get_console_address(self): - """Get the address xend listens at for its console ports. - This defaults to 'localhost', allowing only the localhost to connect - to the console ports. Setting this to the empty string, allows all - hosts to connect. - """ - return self.get_config_value('console-address', self.console_address_default) - - def get_console_port_base(self): - """Get the base port number used to generate console ports for domains. - """ - return self.get_config_int('console-port-base', self.console_port_base_default) - def get_block_script(self, type): return self.get_config_value('block-%s' % type, '') diff --git a/tools/python/xen/xend/server/SrvConsole.py b/tools/python/xen/xend/server/SrvConsole.py deleted file mode 100644 index f147f2810b..0000000000 --- a/tools/python/xen/xend/server/SrvConsole.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2004 Mike Wray - -from xen.xend import sxp -from xen.xend import XendConsole -from xen.web.SrvDir import SrvDir - -class SrvConsole(SrvDir): - """An individual console. - """ - - def __init__(self, info): - SrvDir.__init__(self) - self.info = info - self.xc = XendConsole.instance() - - def op_disconnect(self, op, req): - val = self.xc.console_disconnect(self.info.console_port) - return val - - def render_POST(self, req): - return self.perform(req) - - def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - sxp.show(self.info.sxpr(), out=req) - else: - req.write('') - self.print_path(req) - #self.ls() - req.write('

%s

' % self.info) - req.write('

Connect to domain %d

' - % (self.info.uri(), self.info.id)) - self.form(req) - req.write('') - - def form(self, req): - req.write('
' % req.prePathURL()) - if self.info.connected(): - req.write('') - req.write('
') diff --git a/tools/python/xen/xend/server/SrvConsoleDir.py b/tools/python/xen/xend/server/SrvConsoleDir.py deleted file mode 100644 index 5c15eebb0f..0000000000 --- a/tools/python/xen/xend/server/SrvConsoleDir.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2004 Mike Wray - -from xen.web.SrvDir import SrvDir -from SrvConsole import SrvConsole -from xen.xend import XendConsole -from xen.xend import sxp - -class SrvConsoleDir(SrvDir): - """Console directory. - """ - - def __init__(self): - SrvDir.__init__(self) - self.xconsole = XendConsole.instance() - - def console(self, x): - val = None - try: - info = self.xconsole.console_get(x) - val = SrvConsole(info) - except KeyError, ex: - print 'SrvConsoleDir>', ex - pass - return val - - def get(self, x): - v = SrvDir.get(self, x) - if v is not None: - return v - v = self.console(x) - return v - - def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - self.ls_console(req, 1) - else: - req.write("") - self.print_path(req) - self.ls(req) - self.ls_console(req) - #self.form(req.wfile) - req.write("") - - def ls_console(self, req, use_sxp=0): - url = req.prePathURL() - if not url.endswith('/'): - url += '/' - if use_sxp: - consoles = self.xconsole.console_ls() - sxp.show(consoles, out=req) - else: - consoles = self.xconsole.consoles() - consoles.sort(lambda x, y: cmp(x.console_port, y.console_port)) - req.write('
    ') - for c in consoles: - cid = str(c.console_port) - req.write('
  • %s
  • ' % (url, cid, cid)) - req.write('
') diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index fc8fd4420b..6e51e69518 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -4,7 +4,6 @@ from xen.web import http from xen.xend import sxp from xen.xend import XendDomain -from xen.xend import XendConsole from xen.xend import PrettyPrint from xen.xend.Args import FormFn @@ -18,7 +17,6 @@ class SrvDomain(SrvDir): SrvDir.__init__(self) self.dom = dom self.xd = XendDomain.instance() - self.xconsole = XendConsole.instance() def op_configure(self, op, req): """Configure an existing domain. @@ -208,14 +206,6 @@ class SrvDomain(SrvDir): self.print_path(req) #self.ls() req.write('

%s

' % self.dom) - if self.dom.console: - cinfo = self.dom.console - cid = str(cinfo.console_port) - #todo: Local xref: need to know server prefix. - req.write('

Console %s

' - % (cid, cid)) - req.write('

Connect to console

' - % cinfo.uri()) if self.dom.config: req.write("
")
                 PrettyPrint.prettyprint(self.dom.config, out=req)
diff --git a/tools/python/xen/xend/server/SrvRoot.py b/tools/python/xen/xend/server/SrvRoot.py
index 84ef008118..3c92f5d692 100644
--- a/tools/python/xen/xend/server/SrvRoot.py
+++ b/tools/python/xen/xend/server/SrvRoot.py
@@ -15,7 +15,6 @@ class SrvRoot(SrvDir):
     subdirs = [
         ('node',    'SrvNode'       ),
         ('domain',  'SrvDomainDir'  ),
-        ('console', 'SrvConsoleDir' ),
         ('vnet',    'SrvVnetDir'    ),
         ]
 
diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py
index 1816c1c56d..2c87e104de 100644
--- a/tools/python/xen/xend/server/SrvServer.py
+++ b/tools/python/xen/xend/server/SrvServer.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # Copyright (C) 2004 Mike Wray 
 
-"""Example xend HTTP and console server.
+"""Example xend HTTP
 
    Can be accessed from a browser or from a program.
    Do 'python SrvServer.py' to run the server.
diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py
deleted file mode 100755
index e0aa04a37a..0000000000
--- a/tools/python/xen/xend/server/console.py
+++ /dev/null
@@ -1,391 +0,0 @@
-# Copyright (C) 2004 Mike Wray 
-
-import socket
-import threading
-from errno import EAGAIN, EINTR, EWOULDBLOCK
-    
-from xen.web import reactor, protocol
-
-from xen.lowlevel import xu
-
-from xen.xend.XendError import XendError
-from xen.xend import EventServer; eserver = EventServer.instance()
-from xen.xend.XendLogging import log
-from xen.xend import XendRoot; xroot = XendRoot.instance()
-from xen.xend import sxp
-from xen.xend.xenstore import DBVar
-
-from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
-from xen.xend.server.messages import *
-from xen.xend.server.params import *
-
-class ConsoleProtocol(protocol.Protocol):
-    """Asynchronous handler for a console socket.
-    """
-
-    def __init__(self, console, id):
-        self.console = console
-        self.id = id
-        self.addr = None
-
-    def connectionMade(self, addr=None):
-        peer = self.transport.getPeer()
-        self.addr = addr
-        if self.console.connect(self.addr, self):
-            self.transport.write("Cannot connect to console %d on domain %d\n"
-                                 % (self.id, self.console.getDomain()))
-            self.loseConnection()
-            return
-        else:
-            if len(self.addr) == 2:
-                host = str(self.addr[0])
-                port = str(self.addr[1])
-            else:
-                host = 'localhost'
-                port = str(addr)
-            log.info("Console connected %s %s %s",
-                     self.id, host, port)
-            eserver.inject('xend.console.connect',
-                           [self.id, host, port])
-
-    def dataReceived(self, data):
-        if self.console.receiveInput(self, data):
-            self.loseConnection()
-
-    def write(self, data):
-        self.transport.write(data)
-        return len(data)
-
-    def connectionLost(self, reason=None):
-        log.info("Console disconnected %s %s %s",
-                 str(self.id), str(self.addr[0]), str(self.addr[1]))
-        eserver.inject('xend.console.disconnect',
-                       [self.id, self.addr[0], self.addr[1]])
-        self.console.disconnect(conn=self)
-
-    def loseConnection(self):
-        self.transport.loseConnection()
-
-class ConsoleDev(Dev, protocol.ServerFactory):
-    """Console device for a domain.
-    Does not poll for i/o itself, but relies on the domain to post console
-    output and the connected TCP sockets to post console input.
-    """
-
-    STATUS_NEW       = 'new'
-    STATUS_CLOSED    = 'closed'
-    STATUS_CONNECTED = 'connected'
-    STATUS_LISTENING = 'listening'
-
-    __exports__ = Dev.__exports__ + [
-        DBVar('status',       ty='str'),
-        #DBVar('listening',    ty='str'),
-        DBVar('console_port', ty='int'),
-        ]
-
-    def __init__(self, controller, id, config, recreate=False):
-        Dev.__init__(self, controller, id, config)
-        self.lock = threading.RLock()
-        self.status = self.STATUS_NEW
-        self.addr = None
-        self.conn = None
-        self.console_port = None
-        self.obuf = xu.buffer()
-        self.ibuf = xu.buffer()
-        self.channel = None
-        self.listening = False
-        self.unix_listener = None
-        self.tcp_listener = None
-        
-        console_port = sxp.child_value(self.config, "console_port")
-        if console_port is None:
-            console_port = xroot.get_console_port_base() + self.getDomain()
-        self.checkConsolePort(console_port)
-        self.console_port = console_port
-        
-        log.info("Created console id=%d domain=%d port=%d",
-                 self.id, self.getDomain(), self.console_port)
-        eserver.inject('xend.console.create',
-                       [self.id, self.getDomain(), self.console_port])
-
-    def init(self, recreate=False, reboot=False):
-        try:
-            self.lock.acquire()
-            self.destroyed = False
-            self.channel = self.getChannel()
-            self.listen()
-        finally:
-            self.lock.release()
-
-    def checkConsolePort(self, console_port):
-        """Check that a console port is not in use by another console.
-        """
-        xd = XendRoot.get_component('xen.xend.XendDomain')
-        for vm in xd.list():
-            ctrl = vm.getDeviceController(self.getType(), error=False)
-            if (not ctrl): continue
-            ctrl.checkConsolePort(console_port)
-    
-    def sxpr(self):
-        try:
-            self.lock.acquire()
-            val = ['console',
-                   ['status', self.status ],
-                   ['id',     self.id    ],
-                   ['domain', self.getDomain() ] ]
-            val.append(['local_port',   self.getLocalPort()  ])
-            val.append(['remote_port',  self.getRemotePort() ])
-            val.append(['console_port', self.console_port    ])
-            if self.addr:
-                val.append(['connected', self.addr[0], self.addr[1]])
-        finally:
-            self.lock.release()
-        return val
-
-    def getLocalPort(self):
-        try:
-            self.lock.acquire()
-            if self.channel:
-                return self.channel.getLocalPort()
-            else:
-                return 0
-        finally:
-            self.lock.release()
-
-    def getRemotePort(self):
-        try:
-            self.lock.acquire()
-            if self.channel:
-                return self.channel.getRemotePort()
-            else:
-                return 0
-        finally:
-            self.lock.release()
-
-    def uri(self):
-        """Get the uri to use to connect to the console.
-        This will be a telnet: uri.
-
-        return uri
-        """
-        host = socket.gethostname()
-        return "telnet://%s:%d" % (host, self.console_port)
-
-    def closed(self):
-        return self.status == self.STATUS_CLOSED
-
-    def connected(self):
-        return self.status == self.STATUS_CONNECTED
-
-    def destroy(self, change=False, reboot=False):
-        """Close the console.
-        """
-        if reboot:
-            return
-        try:
-            self.lock.acquire()
-            self.status = self.STATUS_CLOSED
-            self.listening = False
-            if self.conn:
-                self.conn.loseConnection()
-            if self.tcp_listener:
-                self.tcp_listener.stopListening()
-                self.tcp_listener = None
-            if self.unix_listener:
-                self.unix_listener.stopListening()
-                self.unix_listener = None
-        finally:
-            self.lock.release()
-
-    def listen(self):
-        """Listen for TCP connections to the console port..
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return
-            if self.listening:
-                pass
-            else:
-                self.listening = True
-                self.status = self.STATUS_LISTENING
-                if xroot.get_xend_unix_server():
-                    path = '/var/lib/xend/console-%s' % self.console_port
-                    self.unix_listener = reactor.listenUNIX(path, self)
-                if xroot.get_xend_http_server():
-                    interface = xroot.get_console_address()
-                    self.tcp_listener = reactor.listenTCP(
-                        self.console_port, self, interface=interface)
-        finally:
-            self.lock.release()
-
-    def buildProtocol(self, addr):
-        """Factory function called to create the protocol when a connection is accepted
-        by listenTCP.
-        """
-        proto = ConsoleProtocol(self, self.id)
-        proto.factory = self
-        return proto
-
-    def connect(self, addr, conn):
-        """Connect a TCP connection to the console.
-        Fails if closed or already connected.
-
-        addr peer address
-        conn connection
-
-        returns 0 if ok, negative otherwise
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return -1
-            if self.connected():
-                return -1
-            self.addr = addr
-            self.conn = conn
-            self.status = self.STATUS_CONNECTED
-            self.writeOutput()
-        finally:
-            self.lock.release()
-        return 0
-
-    def disconnect(self, conn=None):
-        """Disconnect the TCP connection to the console.
-        """
-        try:
-            self.lock.acquire()
-            if conn and conn != self.conn: return
-            if self.conn:
-                self.conn.loseConnection()
-            self.addr = None
-            self.conn = None
-            self.status = self.STATUS_LISTENING
-            self.listen()
-        finally:
-            self.lock.release()
-
-    def receiveOutput(self, msg):
-        """Receive output console data from the console channel.
-
-        msg     console message
-        type    major message type
-        subtype minor message typ
-        """
-        # Treat the obuf as a ring buffer.
-        try:
-            self.lock.acquire()
-            data = msg.get_payload()
-            data_n = len(data)
-            if self.obuf.space() < data_n:
-                self.obuf.discard(data_n)
-            if self.obuf.space() < data_n:
-                data = data[-self.obuf.space():]
-            self.obuf.write(data)
-            self.writeOutput()
-        finally:
-            self.lock.release()
-        
-    def writeOutput(self):
-        """Handle buffered output from the console device.
-        Sends it to the connected TCP connection (if any).
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return -1
-            writes = 0
-            while self.conn and (writes < 100) and (not self.obuf.empty()):
-                try:
-                    writes += 1
-                    bytes = self.conn.write(self.obuf.peek())
-                    if bytes > 0:
-                        self.obuf.discard(bytes)
-                except socket.error, err:
-                    if err.args[0] in (EWOULDBLOCK, EAGAIN, EINTR):
-                        pass
-                    else:
-                        self.disconnect()
-                        break
-                        
-        finally:
-            self.lock.release()
-        return 0
-    
-    def receiveInput(self, conn, data):
-        """Receive console input from a TCP connection.  Ignores the
-        input if the calling connection (conn) is not the one
-        connected to the console (self.conn).
-
-        conn connection
-        data input data
-        """
-        try:
-            self.lock.acquire()
-            if self.closed(): return -1
-            if conn != self.conn: return 0
-            self.ibuf.write(data)
-            self.writeInput()
-        finally:
-            self.lock.release()
-        return 0
-
-    def writeInput(self):
-        """Write pending console input to the console channel.
-        Writes as much to the channel as it can.
-        """
-        try:
-            self.lock.acquire()
-            while self.channel and not self.ibuf.empty():
-                msg = xu.message(CMSG_CONSOLE, 0, 0)
-                msg.append_payload(self.ibuf.read(msg.MAX_PAYLOAD))
-                self.channel.writeRequest(msg)
-        finally:
-            self.lock.release()
-
-class ConsoleController(DevController):
-    """Device controller for all the consoles for a domain.
-    """
-
-    def __init__(self, vm, recreate=False):
-        DevController.__init__(self, vm, recreate=recreate)
-        self.rcvr = None
-
-    def initController(self, recreate=False, reboot=False):
-        self.destroyed = False
-        self.rcvr = CtrlMsgRcvr(self.getChannel())
-        self.rcvr.addHandler(CMSG_CONSOLE,
-                             0,
-                             self.receiveOutput)
-        self.rcvr.registerChannel()
-        if reboot:
-            self.rebootDevices()
-
-    def destroyController(self, reboot=False):
-        self.destroyed = True
-        self.destroyDevices(reboot=reboot)
-        self.rcvr.deregisterChannel()
-
-    def newDevice(self, id, config, recreate=False):
-        return ConsoleDev(self, id, config, recreate=recreate)
-
-    def checkConsolePort(self, console_port):
-        """Check that a console port is not in use by a console.
-        """
-        for c in self.getDevices():
-            if c.console_port == console_port:
-                raise XendError('console port in use: ' + str(console_port))
-
-    def receiveOutput(self, msg):
-        """Handle a control request.
-        The CMSG_CONSOLE messages just contain data, and no console id,
-        so just send to console 0 (if there is one).
-
-        todo: extend CMSG_CONSOLE to support more than one console?
-        """
-        console = self.getDevice(0)
-        if console:
-            console.receiveOutput(msg)
-        else:
-            log.warning('no console: domain %d', self.getDomain())
-
diff --git a/tools/python/xen/xend/server/event.py b/tools/python/xen/xend/server/event.py
index f16c786c3e..0346fee43e 100644
--- a/tools/python/xen/xend/server/event.py
+++ b/tools/python/xen/xend/server/event.py
@@ -128,16 +128,8 @@ class EventProtocol(protocol.Protocol):
     def op_pretty(self, name, req):
         self.pretty = 1
 
-    def op_console_disconnect(self, name, req):
-        id = sxp.child_value(req, 'id')
-        if not id:
-            raise XendError('Missing console id')
-        id = int(id)
-        self.daemon.console_disconnect(id)
-
     def op_info(self, name, req):
         val = ['info']
-        #val += self.daemon.consoles()
         #val += self.daemon.blkifs()
         #val += self.daemon.netifs()
         #val += self.daemon.usbifs()
diff --git a/tools/python/xen/xend/server/messages.py b/tools/python/xen/xend/server/messages.py
index 84fc738e68..9c9e405a7a 100644
--- a/tools/python/xen/xend/server/messages.py
+++ b/tools/python/xen/xend/server/messages.py
@@ -17,16 +17,6 @@ See below.
 """
 msg_formats = {}
 
-#============================================================================
-# Console message types.
-#============================================================================
-
-CMSG_CONSOLE  = 0
-
-console_formats = { 'console_data': (CMSG_CONSOLE, 0) }
-
-msg_formats.update(console_formats)
-
 #============================================================================
 # Block interface message types.
 #============================================================================
diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py
index 6b4d8a27ed..cfae6d0b87 100644
--- a/tools/python/xen/xm/create.py
+++ b/tools/python/xen/xm/create.py
@@ -7,6 +7,7 @@ import random
 import string
 import sys
 import socket
+import commands
 
 import xen.lowlevel.xc
 
@@ -17,8 +18,6 @@ from xen.xend.XendBootloader import bootloader
 from xen.xend import XendRoot; xroot = XendRoot.instance()
 from xen.util import blkif
 
-from xen.util import console_client
-
 from xen.xm.opts import *
 
 gopts = Opts(use="""[options] [vars]
@@ -145,10 +144,6 @@ gopts.var('cpu_weight', val='WEIGHT',
           use="""Set the new domain's cpu weight.
           WEIGHT is a float that controls the domain's share of the cpu.""")
 
-gopts.var('console', val='PORT',
-          fn=set_int, default=None,
-          use="Console port to use. Default is 9600 + domain id.")
-
 gopts.var('restart', val='onreboot|always|never',
           fn=set_value, default=None,
           use="""Whether the domain should be restarted on exit.
@@ -471,8 +466,6 @@ def make_config(opts, vals):
         config.append(['backend', ['netif']])
     if vals.restart:
         config.append(['restart', vals.restart])
-    if vals.console:
-        config.append(['console', vals.console])
 
     if vals.bootloader:
         run_bootloader(opts, config, vals)
@@ -620,8 +613,8 @@ def make_domain(opts, config):
 
     @param opts:   options
     @param config: configuration
-    @return: domain id, console port
-    @rtype:  (int, int)
+    @return: domain id
+    @rtype:  int
     """
 
     try:
@@ -634,19 +627,13 @@ def make_domain(opts, config):
         opts.err(str(ex))
 
     dom = sxp.child_value(dominfo, 'name')
-    console_info = sxp.child(dominfo, 'console')
-    if console_info:
-        console_port = int(sxp.child_value(console_info, 'console_port'))
-    else:
-        console_port = None
 
     if not opts.vals.paused:
         if server.xend_domain_unpause(dom) < 0:
             server.xend_domain_destroy(dom)
             opts.err("Failed to unpause domain %s" % dom)
-    opts.info("Started domain %s, console on port %d"
-              % (dom, console_port))
-    return (dom, console_port)
+    opts.info("Started domain %s" % (dom))
+    return int(sxp.child_value(dominfo, 'id'))
 
 def get_dom0_alloc():
     """Return current allocation memory of dom0 (in MB). Return 0 on error"""
@@ -709,10 +696,10 @@ def main(argv):
         if dom0_min_mem != 0:
             balloon_out(dom0_min_mem, opts)
 
-        (dom, console) = make_domain(opts, config)
+        dom = make_domain(opts, config)
         if opts.vals.console_autoconnect:
-            path = "/var/lib/xend/console-%s" % console
-            console_client.connect('localhost', console, path=path)
+            cmd = "/usr/libexec/xen/xc_console %d" % dom
+            os.execvp('/usr/libexec/xen/xc_console', cmd.split())
         
 if __name__ == '__main__':
     main(sys.argv)
diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py
index 141da198ca..d890380103 100644
--- a/tools/python/xen/xm/main.py
+++ b/tools/python/xen/xm/main.py
@@ -4,6 +4,7 @@
 import os
 import os.path
 import sys
+import commands
 from getopt import getopt
 import socket
 import warnings
@@ -390,7 +391,7 @@ class ProgList(Prog):
             self.brief_list(doms)
 
     def brief_list(self, doms):
-        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console'
+        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
         for dom in doms:
             info = server.xend_domain(dom)
             d = {}
@@ -401,19 +402,14 @@ class ProgList(Prog):
             d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
             d['state'] = sxp.child_value(info, 'state', '??')
             d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
-            console = sxp.child(info, 'console')
-            if console:
-                d['port'] = sxp.child_value(console, 'console_port')
-            else:
-                d['port'] = ''
             if d['vcpus'] > 1:
                 d['cpu'] = '-'
             if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
                 d['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '0')) & 0xffff
                 d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff
-                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)
+                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
             else:
-                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s" % d)
+                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f" % d)
 
     def show_vcpus(self, doms):
         print 'Name              Id  VCPU  CPU  CPUMAP'
@@ -699,29 +695,6 @@ class ProgInfo(Prog):
 
 xm.prog(ProgInfo)
 
-class ProgConsoles(Prog):
-    group = 'console'
-    name = "consoles"
-    info = """Get information about domain consoles."""
-
-    def main(self, args):
-        l = server.xend_consoles()
-        print "Dom Port  Id Connection"
-        for x in l:
-            info = server.xend_console(x)
-            d = {}
-            d['dom'] = sxp.child(info, 'domain', '?')[1]
-            d['port'] = sxp.child_value(info, 'console_port', '?')
-            d['id'] = sxp.child_value(info, 'id', '?')
-            connected = sxp.child(info, 'connected')
-            if connected:
-                d['conn'] = '%s:%s' % (connected[1], connected[2])
-            else:
-                d['conn'] = ''
-            print "%(dom)3s %(port)4s %(id)3s %(conn)s" % d
-
-xm.prog(ProgConsoles)
-
 class ProgConsole(Prog):
     group = 'console'
     name = "console"
@@ -735,13 +708,9 @@ class ProgConsole(Prog):
         if len(args) < 2: self.err("%s: Missing domain" % args[0])
         dom = args[1]
         info = server.xend_domain(dom)
-        console = sxp.child(info, "console")
-        if not console:
-            self.err("No console information")
-        port = sxp.child_value(console, "console_port")
-        from xen.util import console_client
-        path = "/var/lib/xend/console-%s" % port
-        console_client.connect("localhost", int(port), path=path)
+        domid = int(sxp.child_value(info, 'id', '-1'))
+        cmd = "/usr/libexec/xen/xc_console %d" % domid
+        os.execvp('/usr/libexec/xen/xc_console', cmd.split())
 
 xm.prog(ProgConsole)