mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1159.1.359 (41898114F_zAayDscoCC43HUnOIsPw)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
This commit is contained in:
commit
f2fd7b7419
9 files changed
+90
-67
No files matched your search
@@ -1054,13 +1054,16 @@ static PyMethodDef xu_port_methods[] = {
|
||||
|
||||
staticforward PyTypeObject xu_port_type;
|
||||
|
||||
static PyObject *xu_port_new(PyObject *self, PyObject *args)
|
||||
static PyObject *xu_port_new(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
xu_port_object *xup;
|
||||
u32 dom;
|
||||
int port1 = 0, port2 = 0;
|
||||
|
||||
if ( !PyArg_ParseTuple(args, "i|ii", &dom, &port1, &port2) )
|
||||
static char *kwd_list[] = { "dom", "local_port", "remote_port", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
|
||||
&dom, &port1, &port2) )
|
||||
return NULL;
|
||||
|
||||
xup = PyObject_New(xu_port_object, &xu_port_type);
|
||||
@@ -1435,7 +1438,7 @@ static PyMethodDef xu_methods[] = {
|
||||
"Create a new notifier." },
|
||||
{ "message", xu_message_new, METH_VARARGS,
|
||||
"Create a new communications message." },
|
||||
{ "port", xu_port_new, METH_VARARGS,
|
||||
{ "port", (PyCFunction)xu_port_new, METH_VARARGS | METH_KEYWORDS,
|
||||
"Create a new communications port." },
|
||||
{ "buffer", xu_buffer_new, METH_VARARGS,
|
||||
"Create a new ring buffer." },
|
||||
|
||||
@@ -32,9 +32,8 @@ class XendConsole:
|
||||
def consoles(self):
|
||||
return daemon.get_consoles()
|
||||
|
||||
def console_create(self, dom, console_port=None, remote_port=0):
|
||||
consinfo = daemon.console_create(dom, console_port=console_port,
|
||||
remote_port=remote_port)
|
||||
def console_create(self, dom, console_port=None):
|
||||
consinfo = daemon.console_create(dom, console_port=console_port)
|
||||
return consinfo
|
||||
|
||||
def console_get(self, id):
|
||||
|
||||
@@ -753,17 +753,34 @@ class XendDomainInfo:
|
||||
@param ramdisk: kernel ramdisk
|
||||
@param cmdline: kernel commandline
|
||||
"""
|
||||
#self.init_domain()
|
||||
|
||||
self.create_channel()
|
||||
if self.console:
|
||||
self.console.registerChannel()
|
||||
else:
|
||||
self.console = xendConsole.console_create(
|
||||
self.dom, console_port=self.console_port, remote_port=1)
|
||||
self.dom, console_port=self.console_port)
|
||||
self.build_domain(ostype, kernel, ramdisk, cmdline)
|
||||
self.image = kernel
|
||||
self.ramdisk = ramdisk
|
||||
self.cmdline = cmdline
|
||||
|
||||
def create_channel(self):
|
||||
"""Create the channel to the domain.
|
||||
If saved info is available recreate the channel using the saved ports.
|
||||
|
||||
@return: channel
|
||||
"""
|
||||
local = 0
|
||||
remote = 1
|
||||
if self.savedinfo:
|
||||
consinfo = sxp.child(self.savedinfo, "console")
|
||||
if consinfo:
|
||||
local = int(sxp.child_value(consinfo, "local_port", 0))
|
||||
remote = int(sxp.child_value(consinfo, "remote_port", 1))
|
||||
return xend.createDomChannel(self.dom, local_port=local,
|
||||
remote_port=remote)
|
||||
|
||||
def create_devices(self):
|
||||
"""Create the devices for a vm.
|
||||
|
||||
|
||||
@@ -8,17 +8,18 @@ import types
|
||||
import StringIO
|
||||
|
||||
from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
from twisted.internet import reactor
|
||||
from twisted.protocols import http
|
||||
from twisted.web import error
|
||||
from twisted.web import resource
|
||||
from twisted.web import server
|
||||
from twisted.python.failure import Failure
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend.Args import ArgError
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
def uri_pathlist(p):
|
||||
"""Split a path into a list.
|
||||
@@ -105,17 +106,17 @@ class SrvBase(resource.Resource):
|
||||
try:
|
||||
val = op_method(op, req)
|
||||
except Exception, err:
|
||||
return self._perform_err(err, req)
|
||||
return self._perform_err(err, op, req)
|
||||
|
||||
if isinstance(val, defer.Deferred):
|
||||
val.addCallback(self._perform_cb, req, dfr=1)
|
||||
val.addErrback(self._perform_err, req, dfr=1)
|
||||
val.addCallback(self._perform_cb, op, req, dfr=1)
|
||||
val.addErrback(self._perform_err, op, req, dfr=1)
|
||||
return server.NOT_DONE_YET
|
||||
else:
|
||||
self._perform_cb(val, req, 0)
|
||||
self._perform_cb(val, op, req, dfr=0)
|
||||
return ''
|
||||
|
||||
def _perform_cb(self, val, req, dfr):
|
||||
def _perform_cb(self, val, op, req, dfr=0):
|
||||
"""Callback to complete the request.
|
||||
May be called from a Deferred.
|
||||
|
||||
@@ -141,7 +142,7 @@ class SrvBase(resource.Resource):
|
||||
if dfr:
|
||||
req.finish()
|
||||
|
||||
def _perform_err(self, err, req, dfr=0):
|
||||
def _perform_err(self, err, op, req, dfr=0):
|
||||
"""Error callback to complete a request.
|
||||
May be called from a Deferred.
|
||||
|
||||
@@ -149,13 +150,16 @@ class SrvBase(resource.Resource):
|
||||
@param req: request causing the error
|
||||
@param dfr: deferred flag
|
||||
"""
|
||||
if not (isinstance(err, ArgError) or
|
||||
isinstance(err, sxp.ParseError) or
|
||||
isinstance(err, XendError)):
|
||||
if isinstance(err, Failure):
|
||||
err = err.getErrorMessage()
|
||||
elif not (isinstance(err, ArgError) or
|
||||
isinstance(err, sxp.ParseError) or
|
||||
isinstance(err, XendError)):
|
||||
if dfr:
|
||||
return err
|
||||
else:
|
||||
raise
|
||||
log.exception("op=%s: %s", op, str(err))
|
||||
if self.use_sxp(req):
|
||||
req.setHeader("Content-Type", sxp.mime_type)
|
||||
sxp.show(['xend.err', str(err)], out=req)
|
||||
|
||||
@@ -639,12 +639,22 @@ class Daemon:
|
||||
def getDomChannel(self, dom):
|
||||
"""Get the channel to a domain.
|
||||
|
||||
dom domain
|
||||
|
||||
returns channel (or None)
|
||||
@param dom: domain
|
||||
@return: channel (or None)
|
||||
"""
|
||||
return self.channelF.getDomChannel(dom)
|
||||
|
||||
def createDomChannel(self, dom, local_port=0, remote_port=0):
|
||||
"""Get the channel to a domain, creating if necessary.
|
||||
|
||||
@param dom: domain
|
||||
@param local_port: optional local port to re-use
|
||||
@param remote_port: optional remote port to re-use
|
||||
@return: channel
|
||||
"""
|
||||
return self.channelF.domChannel(dom, local_port=local_port,
|
||||
remote_port=remote_port)
|
||||
|
||||
def blkif_create(self, dom, recreate=0):
|
||||
"""Create or get a block device interface controller.
|
||||
|
||||
@@ -672,13 +682,12 @@ class Daemon:
|
||||
def netif_get(self, dom):
|
||||
return self.netifCF.getControllerByDom(dom)
|
||||
|
||||
def console_create(self, dom, console_port=None, remote_port=0):
|
||||
def console_create(self, dom, console_port=None):
|
||||
"""Create a console for a domain.
|
||||
"""
|
||||
console = self.consoleCF.getControllerByDom(dom)
|
||||
if console is None:
|
||||
console = self.consoleCF.createController(dom, console_port,
|
||||
remote_port=remote_port)
|
||||
console = self.consoleCF.createController(dom, console_port)
|
||||
return console
|
||||
|
||||
def consoles(self):
|
||||
|
||||
@@ -11,6 +11,7 @@ from xen.xend import sxp
|
||||
from xen.xend import XendDomain
|
||||
from xen.xend.Args import FormFn
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
from SrvDir import SrvDir
|
||||
from SrvDomain import SrvDomain
|
||||
@@ -59,18 +60,15 @@ class SrvDomainDir(SrvDir):
|
||||
except sxp.ParseError, ex:
|
||||
errmsg = 'Invalid configuration ' + str(ex)
|
||||
if not ok:
|
||||
req.setResponseCode(http.BAD_REQUEST, errmsg)
|
||||
return errmsg
|
||||
raise XendError(errmsg)
|
||||
try:
|
||||
deferred = self.xd.domain_create(config)
|
||||
deferred.addCallback(self._op_create_cb, configstring, req)
|
||||
deferred.addErrback(self._op_create_err, req)
|
||||
return deferred
|
||||
except Exception, ex:
|
||||
print 'op_create> Exception creating domain:'
|
||||
traceback.print_exc()
|
||||
req.setResponseCode(http.BAD_REQUEST, "Error creating domain: " + str(ex))
|
||||
return str(ex)
|
||||
raise XendError("Error creating domain: " + str(ex))
|
||||
|
||||
def _op_create_cb(self, dominfo, configstring, req):
|
||||
"""Callback to handle deferred domain creation.
|
||||
@@ -92,27 +90,15 @@ class SrvDomainDir(SrvDir):
|
||||
out.close()
|
||||
return val
|
||||
|
||||
def _op_create_err(self, err, req):
|
||||
"""Callback to handle errors in deferred domain creation.
|
||||
"""
|
||||
if isinstance(err, Failure):
|
||||
err = err.getErrorMessage()
|
||||
print 'op_create> Deferred Exception creating domain:', err
|
||||
traceback.print_exc()
|
||||
req.setResponseCode(http.BAD_REQUEST, "Error creating domain: " + str(err))
|
||||
return str(err)
|
||||
|
||||
def op_restore(self, op, req):
|
||||
"""Restore a domain from file.
|
||||
|
||||
@return: deferred
|
||||
"""
|
||||
#todo: return is deferred. May need ok and err callbacks.
|
||||
fn = FormFn(self.xd.domain_restore,
|
||||
[['file', 'str']])
|
||||
deferred = fn(req.args)
|
||||
deferred.addCallback(self._op_restore_cb, req)
|
||||
#deferred.addErrback(self._op_restore_err, req)
|
||||
return deferred
|
||||
|
||||
def _op_restore_cb(self, dominfo, req):
|
||||
@@ -130,13 +116,6 @@ class SrvDomainDir(SrvDir):
|
||||
out.close()
|
||||
return val
|
||||
|
||||
def _op_restore_err(self, err, req):
|
||||
if isinstance(err, Failure):
|
||||
err = err.getErrorMessage()
|
||||
print 'op_create> Deferred Exception restoring domain:', err
|
||||
req.setResponseCode(http.BAD_REQUEST, "Error restoring domain: "+ str(err))
|
||||
return str(err)
|
||||
|
||||
def render_POST(self, req):
|
||||
return self.perform(req)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class ChannelFactory:
|
||||
del self.channels[idx]
|
||||
self.notifier.unbind(idx)
|
||||
|
||||
def domChannel(self, dom, remote_port=0):
|
||||
def domChannel(self, dom, local_port=0, remote_port=0):
|
||||
"""Get the channel for the given domain.
|
||||
Construct if necessary.
|
||||
|
||||
@@ -55,7 +55,8 @@ class ChannelFactory:
|
||||
"""
|
||||
chan = self.getDomChannel(dom)
|
||||
if not chan:
|
||||
chan = Channel(self, dom, remote_port=remote_port)
|
||||
chan = Channel(self, dom, local_port=local_port,
|
||||
remote_port=remote_port)
|
||||
self.addChannel(chan)
|
||||
return chan
|
||||
|
||||
@@ -91,10 +92,25 @@ class ChannelFactory:
|
||||
"""
|
||||
self.delChannel(channel.idx)
|
||||
|
||||
def createPort(self, dom, remote_port=0):
|
||||
def createPort(self, dom, local_port=0, remote_port=0):
|
||||
"""Create a port for a channel to the given domain.
|
||||
If only the domain is specified, a new channel with new port ids is
|
||||
created. If one port id is specified and the given port id is in use,
|
||||
the other port id is filled. If one port id is specified and the
|
||||
given port id is not in use, a new channel is created with one port
|
||||
id equal to the given id and a new id for the other end. If both
|
||||
port ids are specified, a port is reconnected using the given port
|
||||
ids.
|
||||
|
||||
@param dom: domain
|
||||
@param local: local port id to use
|
||||
@type local: int
|
||||
@param remote: remote port id to use
|
||||
@type remote: int
|
||||
@return: port object
|
||||
"""
|
||||
return xu.port(dom, 0, remote_port)
|
||||
return xu.port(dom, local_port=int(local_port),
|
||||
remote_port=int(remote_port))
|
||||
|
||||
def channelFactory():
|
||||
"""Singleton constructor for the channel factory.
|
||||
@@ -200,7 +216,7 @@ class Channel(BaseChannel):
|
||||
are multiplexed over the channel (console, block devs, net devs).
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom, remote_port=0):
|
||||
def __init__(self, factory, dom, local_port=0, remote_port=0):
|
||||
"""Create a channel to the given domain using the given factory.
|
||||
|
||||
Do not call directly, use domChannel on the factory.
|
||||
@@ -209,7 +225,8 @@ class Channel(BaseChannel):
|
||||
# Domain.
|
||||
self.dom = int(dom)
|
||||
# Domain port (object).
|
||||
self.port = self.factory.createPort(dom, remote_port=remote_port)
|
||||
self.port = self.factory.createPort(dom, local_port=local_port,
|
||||
remote_port=remote_port)
|
||||
# Channel port (int).
|
||||
self.idx = self.port.local_port
|
||||
# Registered devices.
|
||||
|
||||
@@ -48,7 +48,6 @@ class ConsoleProtocol(protocol.Protocol):
|
||||
self.loseConnection()
|
||||
|
||||
def write(self, data):
|
||||
#if not self.connected: return -1
|
||||
self.transport.write(data)
|
||||
return len(data)
|
||||
|
||||
@@ -81,14 +80,13 @@ class ConsoleControllerFactory(controller.ControllerFactory):
|
||||
"""Factory for creating console controllers.
|
||||
"""
|
||||
|
||||
def createController(self, dom, console_port=None, remote_port=0):
|
||||
def createController(self, dom, console_port=None):
|
||||
if console_port is None:
|
||||
console_port = CONSOLE_PORT_BASE + dom
|
||||
for c in self.getControllers():
|
||||
if c.console_port == console_port:
|
||||
raise XendError('console port in use: ' + str(console_port))
|
||||
console = ConsoleController(self, dom, console_port,
|
||||
remote_port=remote_port)
|
||||
console = ConsoleController(self, dom, console_port)
|
||||
self.addController(console)
|
||||
log.info("Created console id=%s domain=%d port=%d",
|
||||
console.idx, console.dom, console.console_port)
|
||||
@@ -112,9 +110,8 @@ class ConsoleController(controller.Controller):
|
||||
STATUS_CONNECTED = 'connected'
|
||||
STATUS_LISTENING = 'listening'
|
||||
|
||||
def __init__(self, factory, dom, console_port, remote_port=0):
|
||||
controller.Controller.__init__(self, factory, dom,
|
||||
remote_port=remote_port)
|
||||
def __init__(self, factory, dom, console_port):
|
||||
controller.Controller.__init__(self, factory, dom)
|
||||
self.addMethod(CMSG_CONSOLE, 0, None)
|
||||
self.status = self.STATUS_NEW
|
||||
self.addr = None
|
||||
|
||||
@@ -68,7 +68,7 @@ class CtrlMsgRcvr:
|
||||
@type responders: {int:Responder}
|
||||
"""
|
||||
|
||||
def __init__(self, remote_port=0):
|
||||
def __init__(self):
|
||||
self.channelFactory = channel.channelFactory()
|
||||
self.majorTypes = {}
|
||||
self.dom = None
|
||||
@@ -76,7 +76,6 @@ class CtrlMsgRcvr:
|
||||
self.idx = None
|
||||
self.responders = {}
|
||||
self.timeout = 10
|
||||
self.remote_port = remote_port
|
||||
|
||||
def setTimeout(self, timeout):
|
||||
self.timeout = timeout
|
||||
@@ -218,8 +217,7 @@ class CtrlMsgRcvr:
|
||||
channel to our domain. Once we have registered, the channel
|
||||
will call requestReceived or responseReceived for our messages.
|
||||
"""
|
||||
self.channel = self.channelFactory.domChannel(self.dom,
|
||||
self.remote_port)
|
||||
self.channel = self.channelFactory.domChannel(self.dom)
|
||||
self.idx = self.channel.getIndex()
|
||||
if self.majorTypes:
|
||||
self.channel.registerDevice(self.getMajorTypes(), self)
|
||||
@@ -364,8 +362,8 @@ class Controller(CtrlMsgRcvr):
|
||||
@type idx: String
|
||||
"""
|
||||
|
||||
def __init__(self, factory, dom, remote_port=0):
|
||||
CtrlMsgRcvr.__init__(self, remote_port=remote_port)
|
||||
def __init__(self, factory, dom):
|
||||
CtrlMsgRcvr.__init__(self)
|
||||
self.factory = factory
|
||||
self.dom = int(dom)
|
||||
self.channel = None
|
||||
|
||||