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>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-08-04 09:00:16 +00:00
1 parent c025f1530a
commit f6d93de51e
17 files changed
+21 -808

No files matched your search

-108
View File
@@ -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], "<host> <port> [<path>]"
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)
+1 -16
View File
@@ -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())
-44
View File
@@ -1,44 +0,0 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
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
+1 -40
View File
@@ -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")
-19
View File
@@ -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, '')
@@ -1,41 +0,0 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
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('<html><head></head><body>')
self.print_path(req)
#self.ls()
req.write('<p>%s</p>' % self.info)
req.write('<p><a href="%s">Connect to domain %d</a></p>'
% (self.info.uri(), self.info.id))
self.form(req)
req.write('</body></html>')
def form(self, req):
req.write('<form method="post" action="%s">' % req.prePathURL())
if self.info.connected():
req.write('<input type="submit" name="op" value="disconnect">')
req.write('</form>')
@@ -1,59 +0,0 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
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("<html><head></head><body>")
self.print_path(req)
self.ls(req)
self.ls_console(req)
#self.form(req.wfile)
req.write("</body></html>")
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('<ul>')
for c in consoles:
cid = str(c.console_port)
req.write('<li><a href="%s%s"> %s</a></li>' % (url, cid, cid))
req.write('</ul>')
-10
View File
@@ -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('<p>%s</p>' % 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('<p><a href="/xend/console/%s">Console %s</a></p>'
% (cid, cid))
req.write('<p><a href="%s">Connect to console</a></p>'
% cinfo.uri())
if self.dom.config:
req.write("<code><pre>")
PrettyPrint.prettyprint(self.dom.config, out=req)
-1
View File
@@ -15,7 +15,6 @@ class SrvRoot(SrvDir):
subdirs = [
('node', 'SrvNode' ),
('domain', 'SrvDomainDir' ),
('console', 'SrvConsoleDir' ),
('vnet', 'SrvVnetDir' ),
]
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/python
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
"""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.
-391
View File
@@ -1,391 +0,0 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
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())
-8
View File
@@ -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()
-10
View File
@@ -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.
#============================================================================
+8 -21
View File
@@ -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)
+7 -38
View File
@@ -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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.