mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Merged.
This commit is contained in:
commit
2a3e2af26c
23 files changed
+402
-614
No files matched your search
@@ -433,105 +433,20 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
u32 dom = DOMID_SELF, remote_dom;
|
||||
int port = 0;
|
||||
int port;
|
||||
|
||||
static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
|
||||
static char *kwd_list[] = { "remote_dom", "dom", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
|
||||
&remote_dom, &dom, &port) )
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
|
||||
&remote_dom, &dom) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
|
||||
if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return PyInt_FromLong(port);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
|
||||
int port1 = 0, port2 = 0;
|
||||
|
||||
static char *kwd_list[] = { "dom1", "dom2", "port1", "port2", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiii", kwd_list,
|
||||
&dom1, &dom2, &port1, &port2) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1,
|
||||
dom2, &port1, &port2) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("{s:i,s:i}",
|
||||
"port1", port1,
|
||||
"port2", port2);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
int virq, port;
|
||||
|
||||
static char *kwd_list[] = { "virq", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return PyInt_FromLong(port);
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_close(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
u32 dom = DOMID_SELF;
|
||||
int port;
|
||||
|
||||
static char *kwd_list[] = { "port", "dom", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
|
||||
&port, &dom) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_send(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
XcObject *xc = (XcObject *)self;
|
||||
|
||||
int port;
|
||||
|
||||
static char *kwd_list[] = { "port", NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
return zero;
|
||||
}
|
||||
|
||||
static PyObject *pyxc_evtchn_status(PyObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
@@ -1032,38 +947,6 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" dom [int]: Remote domain to accept connections from.\n\n"
|
||||
"Returns: [int] Unbound event-channel port.\n" },
|
||||
|
||||
{ "evtchn_bind_interdomain",
|
||||
(PyCFunction)pyxc_evtchn_bind_interdomain,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Open an event channel between two domains.\n"
|
||||
" dom1 [int, SELF]: First domain to be connected.\n"
|
||||
" dom2 [int, SELF]: Second domain to be connected.\n\n"
|
||||
"Returns: [dict] dictionary is empty on failure.\n"
|
||||
" port1 [int]: Port-id for endpoint at dom1.\n"
|
||||
" port2 [int]: Port-id for endpoint at dom2.\n" },
|
||||
|
||||
{ "evtchn_bind_virq",
|
||||
(PyCFunction)pyxc_evtchn_bind_virq,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Bind an event channel to the specified VIRQ.\n"
|
||||
" virq [int]: VIRQ to bind.\n\n"
|
||||
"Returns: [int] Bound event-channel port.\n" },
|
||||
|
||||
{ "evtchn_close",
|
||||
(PyCFunction)pyxc_evtchn_close,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Close an event channel. If interdomain, sets remote end to 'unbound'.\n"
|
||||
" dom [int, SELF]: Dom-id of one endpoint of the channel.\n"
|
||||
" port [int]: Port-id of one endpoint of the channel.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "evtchn_send",
|
||||
(PyCFunction)pyxc_evtchn_send,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Send an event along a locally-connected event channel.\n"
|
||||
" port [int]: Port-id of a local channel endpoint.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "evtchn_status",
|
||||
(PyCFunction)pyxc_evtchn_status,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
|
||||
@@ -126,8 +126,8 @@ def restore(xd, fd):
|
||||
raise XendError(
|
||||
"not a valid guest state file: pfn count out of range")
|
||||
|
||||
store_evtchn = dominfo.store_channel.port2
|
||||
console_evtchn = dominfo.console_channel.port2
|
||||
store_evtchn = dominfo.store_channel
|
||||
console_evtchn = dominfo.console_channel
|
||||
|
||||
cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
|
||||
str(dominfo.getDomid()), str(nr_pfns),
|
||||
@@ -146,7 +146,7 @@ def restore(xd, fd):
|
||||
dominfo.getDomainPath())
|
||||
IntroduceDomain(dominfo.getDomid(),
|
||||
store_mfn,
|
||||
dominfo.store_channel.port1,
|
||||
dominfo.store_channel,
|
||||
dominfo.getDomainPath())
|
||||
else:
|
||||
m = re.match(r"^(console-mfn) (\d+)$", line)
|
||||
|
||||
@@ -32,8 +32,6 @@ import errno
|
||||
import xen.lowlevel.xc
|
||||
from xen.util.blkif import blkdev_uname_to_file
|
||||
|
||||
from xen.xend.server import channel
|
||||
|
||||
from xen.xend import image
|
||||
from xen.xend import scheduler
|
||||
from xen.xend import sxp
|
||||
@@ -785,32 +783,6 @@ class XendDomainInfo:
|
||||
self.domid, self.info['name'])
|
||||
|
||||
|
||||
def closeChannel(self, chan, entry):
|
||||
"""Close the given channel, if set, and remove the given entry in the
|
||||
store. Nothrow guarantee."""
|
||||
|
||||
if chan:
|
||||
chan.close()
|
||||
try:
|
||||
self.removeDom(entry)
|
||||
except:
|
||||
log.exception('Removing entry %s failed', entry)
|
||||
|
||||
|
||||
def closeStoreChannel(self):
|
||||
"""Close the store channel, if any. Nothrow guarantee."""
|
||||
|
||||
self.closeChannel(self.store_channel, "store/port")
|
||||
self.store_channel = None
|
||||
|
||||
|
||||
def closeConsoleChannel(self):
|
||||
"""Close the console channel, if any. Nothrow guarantee."""
|
||||
|
||||
self.closeChannel(self.console_channel, "console/port")
|
||||
self.console_channel = None
|
||||
|
||||
|
||||
## public:
|
||||
|
||||
def setConsoleRef(self, ref):
|
||||
@@ -964,12 +936,8 @@ class XendDomainInfo:
|
||||
sxpr.append(['up_time', str(up_time) ])
|
||||
sxpr.append(['start_time', str(self.info['start_time']) ])
|
||||
|
||||
if self.store_channel:
|
||||
sxpr.append(self.store_channel.sxpr())
|
||||
if self.store_mfn:
|
||||
sxpr.append(['store_mfn', self.store_mfn])
|
||||
if self.console_channel:
|
||||
sxpr.append(['console_channel', self.console_channel.sxpr()])
|
||||
if self.console_mfn:
|
||||
sxpr.append(['console_mfn', self.console_mfn])
|
||||
|
||||
@@ -1077,7 +1045,7 @@ class XendDomainInfo:
|
||||
self.create_channel()
|
||||
self.image.createImage()
|
||||
IntroduceDomain(self.domid, self.store_mfn,
|
||||
self.store_channel.port1, self.dompath)
|
||||
self.store_channel, self.dompath)
|
||||
|
||||
|
||||
## public:
|
||||
@@ -1087,8 +1055,6 @@ class XendDomainInfo:
|
||||
guarantee."""
|
||||
|
||||
self.release_devices()
|
||||
self.closeStoreChannel()
|
||||
self.closeConsoleChannel()
|
||||
|
||||
if self.image:
|
||||
try:
|
||||
@@ -1168,35 +1134,22 @@ class XendDomainInfo:
|
||||
|
||||
@param path under which port is stored in db
|
||||
"""
|
||||
port = 0
|
||||
if path:
|
||||
try:
|
||||
port = int(self.readDom(path))
|
||||
return int(self.readDom(path))
|
||||
except:
|
||||
# The port is not yet set, i.e. the channel has not yet been
|
||||
# created.
|
||||
pass
|
||||
|
||||
# Stale port information from above causes an Invalid Argument to be
|
||||
# thrown by the eventChannel call below. To recover, we throw away
|
||||
# port if it turns out to be bad, and just create a new channel.
|
||||
# If creating a new channel with two new ports fails, then something
|
||||
# else is going wrong, so we bail.
|
||||
while True:
|
||||
try:
|
||||
ret = channel.eventChannel(0, self.domid, port1 = port,
|
||||
port2 = 0)
|
||||
break
|
||||
except:
|
||||
log.exception("Exception in eventChannel(0, %d, %d, %d)",
|
||||
self.domid, port, 0)
|
||||
if port == 0:
|
||||
raise
|
||||
else:
|
||||
port = 0
|
||||
log.error("Recovering from above exception.")
|
||||
self.storeDom(path, ret.port1)
|
||||
return ret
|
||||
try:
|
||||
port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
|
||||
except:
|
||||
log.exception("Exception in alloc_unbound(%d)", self.domid)
|
||||
raise
|
||||
|
||||
self.storeDom(path, port)
|
||||
return port
|
||||
|
||||
def create_channel(self):
|
||||
"""Create the channels to the domain.
|
||||
@@ -1423,11 +1376,11 @@ class XendDomainInfo:
|
||||
|
||||
|
||||
def initStoreConnection(self):
|
||||
ref = xc.init_store(self.store_channel.port2)
|
||||
ref = xc.init_store(self.store_channel)
|
||||
if ref and ref >= 0:
|
||||
self.setStoreRef(ref)
|
||||
try:
|
||||
IntroduceDomain(self.domid, ref, self.store_channel.port1,
|
||||
IntroduceDomain(self.domid, ref, self.store_channel,
|
||||
self.dompath)
|
||||
except RuntimeError, ex:
|
||||
if ex.args[0] == errno.EISCONN:
|
||||
|
||||
@@ -25,8 +25,6 @@ from xen.xend import sxp
|
||||
from xen.xend.XendError import VmError
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
from xen.xend.server import channel
|
||||
|
||||
|
||||
xc = xen.lowlevel.xc.new()
|
||||
|
||||
@@ -168,11 +166,11 @@ class LinuxImageHandler(ImageHandler):
|
||||
|
||||
def buildDomain(self):
|
||||
if self.vm.store_channel:
|
||||
store_evtchn = self.vm.store_channel.port2
|
||||
store_evtchn = self.vm.store_channel
|
||||
else:
|
||||
store_evtchn = 0
|
||||
if self.vm.console_channel:
|
||||
console_evtchn = self.vm.console_channel.port2
|
||||
console_evtchn = self.vm.console_channel
|
||||
else:
|
||||
console_evtchn = 0
|
||||
|
||||
@@ -228,16 +226,17 @@ class VmxImageHandler(ImageHandler):
|
||||
|
||||
def buildDomain(self):
|
||||
# Create an event channel
|
||||
self.device_channel = channel.eventChannel(0, self.vm.getDomid())
|
||||
log.info("VMX device model port: %d", self.device_channel.port2)
|
||||
self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
|
||||
remote_dom=0)
|
||||
log.info("VMX device model port: %d", self.device_channel)
|
||||
if self.vm.store_channel:
|
||||
store_evtchn = self.vm.store_channel.port2
|
||||
store_evtchn = self.vm.store_channel
|
||||
else:
|
||||
store_evtchn = 0
|
||||
|
||||
log.debug("dom = %d", self.vm.getDomid())
|
||||
log.debug("image = %s", self.kernel)
|
||||
log.debug("control_evtchn = %d", self.device_channel.port2)
|
||||
log.debug("control_evtchn = %d", self.device_channel)
|
||||
log.debug("store_evtchn = %d", store_evtchn)
|
||||
log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024)
|
||||
log.debug("flags = %d", self.flags)
|
||||
@@ -245,7 +244,7 @@ class VmxImageHandler(ImageHandler):
|
||||
|
||||
ret = xc.vmx_build(dom = self.vm.getDomid(),
|
||||
image = self.kernel,
|
||||
control_evtchn = self.device_channel.port2,
|
||||
control_evtchn = self.device_channel,
|
||||
store_evtchn = store_evtchn,
|
||||
memsize = self.vm.getMemoryTarget() / 1024,
|
||||
flags = self.flags,
|
||||
@@ -334,7 +333,7 @@ class VmxImageHandler(ImageHandler):
|
||||
if len(vnc):
|
||||
args = args + vnc
|
||||
args = args + ([ "-d", "%d" % self.vm.getDomid(),
|
||||
"-p", "%d" % self.device_channel.port1,
|
||||
"-p", "%d" % self.device_channel,
|
||||
"-m", "%s" % (self.vm.getMemoryTarget() / 1024)])
|
||||
args = args + self.dmargs
|
||||
env = dict(os.environ)
|
||||
@@ -358,8 +357,6 @@ class VmxImageHandler(ImageHandler):
|
||||
return vncconnect
|
||||
|
||||
def destroy(self):
|
||||
if self.device_channel:
|
||||
self.device_channel.close()
|
||||
import signal
|
||||
if not self.pid:
|
||||
return
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#============================================================================
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
|
||||
# Copyright (C) 2005 XenSource Ltd
|
||||
#============================================================================
|
||||
|
||||
import xen.lowlevel.xc
|
||||
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
|
||||
xc = xen.lowlevel.xc.new()
|
||||
|
||||
|
||||
class EventChannel:
|
||||
"""An event channel between domains.
|
||||
"""
|
||||
|
||||
def __init__(self, dom1, dom2, port1, port2):
|
||||
self.dom1 = dom1
|
||||
self.dom2 = dom2
|
||||
self.port1 = port1
|
||||
self.port2 = port2
|
||||
|
||||
|
||||
def close(self):
|
||||
"""Close the event channel. Nothrow guarantee.
|
||||
"""
|
||||
def evtchn_close(dom, port):
|
||||
try:
|
||||
xc.evtchn_close(dom=dom, port=port)
|
||||
except Exception:
|
||||
log.exception("Exception closing event channel %d, %d.", dom,
|
||||
port)
|
||||
|
||||
evtchn_close(self.dom1, self.port1)
|
||||
evtchn_close(self.dom2, self.port2)
|
||||
|
||||
|
||||
def sxpr(self):
|
||||
return ['event-channel',
|
||||
['dom1', self.dom1 ],
|
||||
['port1', self.port1 ],
|
||||
['dom2', self.dom2 ],
|
||||
['port2', self.port2 ]
|
||||
]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return ("<EventChannel dom1:%d:%d dom2:%d:%d>"
|
||||
% (self.dom1, self.port1, self.dom2, self.port2))
|
||||
|
||||
|
||||
def eventChannel(dom1, dom2, port1 = 0, port2 = 0):
|
||||
"""Create an event channel between domains.
|
||||
|
||||
@return EventChannel (None on error)
|
||||
"""
|
||||
v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2,
|
||||
port1=port1, port2=port2)
|
||||
if v and v.get('port1'):
|
||||
return EventChannel(dom1, dom2, v['port1'], v['port2'])
|
||||
else:
|
||||
return None
|
||||