aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile13
-rw-r--r--tools/misc/Makefile2
-rw-r--r--tools/xc/lib/Makefile2
-rw-r--r--tools/xc/py/Xc.c214
-rw-r--r--tools/xc/py/setup.py7
-rw-r--r--tools/xen/Makefile (renamed from tools/xenmgr/Makefile)0
-rw-r--r--tools/xen/lib/__init__.py (renamed from tools/xenmgr/lib/__init__.py)0
-rw-r--r--tools/xen/lib/xend/Args.py (renamed from tools/xenmgr/lib/Args.py)0
-rw-r--r--tools/xen/lib/xend/EventServer.py (renamed from tools/xenmgr/lib/EventServer.py)0
-rw-r--r--tools/xen/lib/xend/EventTypes.py (renamed from tools/xenmgr/lib/EventTypes.py)0
-rw-r--r--tools/xen/lib/xend/PrettyPrint.py (renamed from tools/xenmgr/lib/PrettyPrint.py)0
-rw-r--r--tools/xen/lib/xend/XendBridge.py (renamed from tools/xenmgr/lib/XendBridge.py)2
-rw-r--r--tools/xen/lib/xend/XendClient.py (renamed from tools/xenmgr/lib/XendClient.py)7
-rw-r--r--tools/xen/lib/xend/XendConsole.py (renamed from tools/xenmgr/lib/XendConsole.py)16
-rw-r--r--tools/xen/lib/xend/XendDB.py (renamed from tools/xenmgr/lib/XendDB.py)0
-rw-r--r--tools/xen/lib/xend/XendDomain.py (renamed from tools/xenmgr/lib/XendDomain.py)6
-rw-r--r--tools/xen/lib/xend/XendDomainConfig.py (renamed from tools/xenmgr/lib/XendDomainConfig.py)0
-rw-r--r--tools/xen/lib/xend/XendDomainInfo.py (renamed from tools/xenmgr/lib/XendDomainInfo.py)6
-rw-r--r--tools/xen/lib/xend/XendMigrate.py (renamed from tools/xenmgr/lib/XendMigrate.py)0
-rw-r--r--tools/xen/lib/xend/XendNode.py (renamed from tools/xenmgr/lib/XendNode.py)4
-rw-r--r--tools/xen/lib/xend/XendRoot.py (renamed from tools/xenmgr/lib/XendRoot.py)0
-rw-r--r--tools/xen/lib/xend/XendVnet.py (renamed from tools/xenmgr/lib/XendVnet.py)0
-rw-r--r--tools/xen/lib/xend/__init__.py1
-rw-r--r--tools/xen/lib/xend/encode.py (renamed from tools/xenmgr/lib/encode.py)0
-rw-r--r--tools/xen/lib/xend/server/SrvBase.py (renamed from tools/xenmgr/lib/server/SrvBase.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvConsole.py (renamed from tools/xenmgr/lib/server/SrvConsole.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvConsoleDir.py (renamed from tools/xenmgr/lib/server/SrvConsoleDir.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvDaemon.py (renamed from tools/xenmgr/lib/server/SrvConsoleServer.py)14
-rw-r--r--tools/xen/lib/xend/server/SrvDeviceDir.py (renamed from tools/xenmgr/lib/server/SrvDeviceDir.py)0
-rw-r--r--tools/xen/lib/xend/server/SrvDir.py (renamed from tools/xenmgr/lib/server/SrvDir.py)2
-rw-r--r--tools/xen/lib/xend/server/SrvDomain.py (renamed from tools/xenmgr/lib/server/SrvDomain.py)10
-rw-r--r--tools/xen/lib/xend/server/SrvDomainDir.py (renamed from tools/xenmgr/lib/server/SrvDomainDir.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvEventDir.py (renamed from tools/xenmgr/lib/server/SrvEventDir.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvNode.py (renamed from tools/xenmgr/lib/server/SrvNode.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvRoot.py (renamed from tools/xenmgr/lib/server/SrvRoot.py)2
-rw-r--r--tools/xen/lib/xend/server/SrvServer.py (renamed from tools/xenmgr/lib/server/SrvServer.py)4
-rw-r--r--tools/xen/lib/xend/server/SrvVnetDir.py (renamed from tools/xenmgr/lib/server/SrvVnetDir.py)0
-rw-r--r--tools/xen/lib/xend/server/__init__.py (renamed from tools/xenmgr/lib/server/__init__.py)0
-rwxr-xr-xtools/xen/lib/xend/server/blkif.py (renamed from tools/xenmgr/lib/server/blkif.py)4
-rwxr-xr-xtools/xen/lib/xend/server/channel.py (renamed from tools/xenmgr/lib/server/channel.py)8
-rwxr-xr-xtools/xen/lib/xend/server/console.py (renamed from tools/xenmgr/lib/server/console.py)10
-rwxr-xr-xtools/xen/lib/xend/server/controller.py (renamed from tools/xenmgr/lib/server/controller.py)0
-rwxr-xr-xtools/xen/lib/xend/server/cstruct.py (renamed from tools/xenmgr/lib/server/cstruct.py)0
-rw-r--r--tools/xen/lib/xend/server/domain.py (renamed from tools/xenmgr/lib/server/domain.py)0
-rw-r--r--tools/xen/lib/xend/server/messages.py (renamed from tools/xenmgr/lib/server/messages.py)4
-rwxr-xr-xtools/xen/lib/xend/server/netif.py (renamed from tools/xenmgr/lib/server/netif.py)8
-rw-r--r--tools/xen/lib/xend/server/params.py (renamed from tools/xenmgr/lib/server/params.py)2
-rw-r--r--tools/xen/lib/xend/sxp.py (renamed from tools/xenmgr/lib/sxp.py)0
-rw-r--r--tools/xen/lib/xm/__init__.py (renamed from tools/xend/lib/__init__.py)0
-rw-r--r--tools/xen/lib/xm/create.py (renamed from tools/xenmgr/lib/xm/create.py)8
-rw-r--r--tools/xen/lib/xm/main.py (renamed from tools/xenmgr/lib/xm/main.py)8
-rw-r--r--tools/xen/lib/xm/opts.py (renamed from tools/xenmgr/lib/xm/opts.py)0
-rw-r--r--tools/xen/lib/xm/shutdown.py (renamed from tools/xenmgr/lib/xm/shutdown.py)4
-rw-r--r--tools/xen/netfix (renamed from tools/xenmgr/netfix)2
-rw-r--r--tools/xen/setup.py16
-rw-r--r--tools/xen/xend (renamed from tools/xenmgr/xend)4
-rwxr-xr-xtools/xen/xm (renamed from tools/xenmgr/xm)2
-rw-r--r--tools/xend-old/Makefile (renamed from tools/xend/Makefile)0
-rw-r--r--tools/xend-old/lib/__init__.py (renamed from tools/xenmgr/lib/xm/__init__.py)0
-rw-r--r--tools/xend-old/lib/blkif.py (renamed from tools/xend/lib/blkif.py)0
-rw-r--r--tools/xend-old/lib/console.py (renamed from tools/xend/lib/console.py)0
-rw-r--r--tools/xend-old/lib/domain_controller.h (renamed from tools/xend/lib/domain_controller.h)0
-rwxr-xr-xtools/xend-old/lib/main.py (renamed from tools/xend/lib/main.py)0
-rw-r--r--tools/xend-old/lib/manager.py (renamed from tools/xend/lib/manager.py)0
-rw-r--r--tools/xend-old/lib/netif.py (renamed from tools/xend/lib/netif.py)0
-rw-r--r--tools/xend-old/lib/utils.c (renamed from tools/xend/lib/utils.c)0
-rw-r--r--tools/xend-old/setup.py (renamed from tools/xend/setup.py)0
-rwxr-xr-xtools/xend-old/xend (renamed from tools/xend/xend)0
-rw-r--r--tools/xenmgr/setup.py14
-rwxr-xr-xtools/xenmgr/xenmgrd10
-rw-r--r--tools/xentrace/Makefile2
-rw-r--r--tools/xu/lib/__init__.py0
-rw-r--r--tools/xu/lib/domain_controller.h532
-rw-r--r--tools/xu/lib/xu.c1386
-rw-r--r--tools/xu/setup.py19
75 files changed, 2149 insertions, 230 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 658ff284d1..69b05709f6 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -1,21 +1,22 @@
all:
$(MAKE) -C xc
+ $(MAKE) -C xu
$(MAKE) -C misc
$(MAKE) -C examples
$(MAKE) -C xentrace
$(MAKE) -C xenctl
- $(MAKE) -C xend
- $(MAKE) -C xenmgr
+ $(MAKE) -C xen
install: all
$(MAKE) -C xc install
+ $(MAKE) -C xu install
$(MAKE) -C misc install
+ $(MAKE) -C xenctl install
$(MAKE) -C examples install
$(MAKE) -C xentrace install
$(MAKE) -C xenctl install
- $(MAKE) -C xend install
- $(MAKE) -C xenmgr install
+ $(MAKE) -C xen install
dist: $(TARGET)
$(MAKE) prefix=`pwd`/../../install dist=yes install
@@ -23,10 +24,10 @@ dist: $(TARGET)
clean:
$(MAKE) -C xc clean
+ $(MAKE) -C xu clean
$(MAKE) -C misc clean
$(MAKE) -C examples clean
$(MAKE) -C xentrace clean
$(MAKE) -C xenctl clean
- $(MAKE) -C xend clean
- $(MAKE) -C xenmgr clean
+ $(MAKE) -C xen clean
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 36e9cab93f..69651f2152 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -3,7 +3,7 @@ CC = gcc
CFLAGS = -Wall -O3
EXTRA_INC = -I../../xen/include/hypervisor-ifs
EXTRA_INC += -I../../linux-xen-sparse/include -I../xc/lib
-EXTRA_INC += -I../xend/lib
+EXTRA_INC += -I../xu/lib
HDRS = $(wildcard *.h)
SRCS = $(wildcard *.c)
diff --git a/tools/xc/lib/Makefile b/tools/xc/lib/Makefile
index 7a6fd2fa12..271a9c4703 100644
--- a/tools/xc/lib/Makefile
+++ b/tools/xc/lib/Makefile
@@ -6,7 +6,7 @@ SONAME = libxc.so.$(MAJOR)
CC = gcc
CFLAGS = -c -Werror -O3 -fno-strict-aliasing
CFLAGS += -I../../../xen/include/hypervisor-ifs
-CFLAGS += -I../../xend/lib
+CFLAGS += -I../../xu/lib
CFLAGS += -I../../../linux-xen-sparse/include
HDRS = $(wildcard *.h)
diff --git a/tools/xc/py/Xc.c b/tools/xc/py/Xc.c
index 299202609e..b52114aab2 100644
--- a/tools/xc/py/Xc.c
+++ b/tools/xc/py/Xc.c
@@ -20,6 +20,8 @@
#define PyMODINIT_FUNC DL_EXPORT(void)
#endif
+#define XENPKG "xen.ext.xc"
+
static PyObject *xc_error, *zero;
typedef struct {
@@ -187,112 +189,73 @@ static PyObject *pyxc_domain_getinfo(PyObject *self,
return list;
}
-static PyObject *pyxc_linux_save(PyObject *self,
- PyObject *args,
- PyObject *kwds)
-{
- XcObject *xc = (XcObject *)self;
-
- u32 dom;
- char *state_file;
- int progress = 1, live = -1, debug = 0;
- unsigned int flags = 0;
-
- static char *kwd_list[] = { "dom", "state_file", "progress",
- "live", "debug", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|iii", kwd_list,
- &dom, &state_file, &progress,
- &live, &debug) )
- return NULL;
-
- if (progress) flags |= XCFLAGS_VERBOSE;
- if (live == 1) flags |= XCFLAGS_LIVE;
- if (debug) flags |= XCFLAGS_DEBUG;
-
- if ( strncmp(state_file,"tcp:", strlen("tcp:")) == 0 )
- {
+static PyObject *tcp_save(XcObject *xc, u32 dom, char *url, unsigned flags){
#define max_namelen 64
- char server[max_namelen];
- char *port_s;
- int port=777;
- int sd = -1;
- struct hostent *h;
- struct sockaddr_in s;
- int sockbufsize;
- int rc = -1;
-
- int writerfn(void *fd, const void *buf, size_t count)
- {
- int tot = 0, rc;
- do {
- rc = write( (int) fd, ((char*)buf)+tot, count-tot );
- if ( rc < 0 ) { perror("WRITE"); return rc; };
- tot += rc;
- }
- while ( tot < count );
- return 0;
- }
-
- if (live == -1) flags |= XCFLAGS_LIVE; /* default to live for tcp */
-
- strncpy( server, state_file+strlen("tcp://"), max_namelen);
- server[max_namelen-1]='\0';
- if ( (port_s = strchr(server,':')) != NULL )
- {
- *port_s = '\0';
- port = atoi(port_s+1);
+ char server[max_namelen];
+ char *port_s;
+ int port=777;
+ int sd = -1;
+ struct hostent *h;
+ struct sockaddr_in s;
+ int sockbufsize;
+ int rc = -1;
+
+ int writerfn(void *fd, const void *buf, size_t count) {
+ int tot = 0, rc;
+ do {
+ rc = write( (int) fd, ((char*)buf)+tot, count-tot );
+ if ( rc < 0 ) { perror("WRITE"); return rc; };
+ tot += rc;
}
-
- printf("X server=%s port=%d\n",server,port);
-
- h = gethostbyname(server);
- sd = socket (AF_INET,SOCK_STREAM,0);
- if ( sd < 0 )
- goto serr;
- s.sin_family = AF_INET;
- bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
- s.sin_port = htons(port);
- if ( connect(sd, (struct sockaddr *) &s, sizeof(s)) )
- goto serr;
-
- sockbufsize=128*1024;
- if ( setsockopt(sd, SOL_SOCKET, SO_SNDBUF,
- &sockbufsize, sizeof sockbufsize) < 0 )
- goto serr;
-
- if ( xc_linux_save(xc->xc_handle, dom, flags,
- writerfn, (void*)sd) == 0 )
- {
- if ( read( sd, &rc, sizeof(int) ) != sizeof(int) )
- goto serr;
+ while ( tot < count );
+ return 0;
+ }
+
+ strncpy( server, url+strlen("tcp://"), max_namelen);
+ server[max_namelen-1]='\0';
+ if ( (port_s = strchr(server,':')) != NULL ) {
+ *port_s = '\0';
+ port = atoi(port_s+1);
+ }
+ printf("X server=%s port=%d\n",server,port);
+ h = gethostbyname(server);
+ sd = socket(AF_INET, SOCK_STREAM,0);
+ if (sd < 0) goto serr;
+ s.sin_family = AF_INET;
+ bcopy ( h->h_addr, &(s.sin_addr.s_addr), h->h_length);
+ s.sin_port = htons(port);
+ if ( connect(sd, (struct sockaddr *) &s, sizeof(s)) ) goto serr;
+ sockbufsize=128*1024;
+ if ( setsockopt(sd, SOL_SOCKET, SO_SNDBUF, &sockbufsize, sizeof sockbufsize) < 0 ) goto serr;
+
+ if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, (void*)sd) == 0 ) {
+ if ( read( sd, &rc, sizeof(int) ) != sizeof(int) ) goto serr;
- if ( rc == 0 )
- {
+ if ( rc == 0 ) {
printf("Migration succesful -- destroy local copy\n");
xc_domain_destroy(xc->xc_handle, dom);
close(sd);
Py_INCREF(zero);
return zero;
- }
- else
- errno = rc;
+ } else {
+ errno = rc;
}
+ }
- serr:
- printf("Migration failed -- restart local copy\n");
- xc_domain_unpause(xc->xc_handle, dom);
- PyErr_SetFromErrno(xc_error);
- if ( sd >= 0 ) close(sd);
- return NULL;
- }
- else
- {
+ serr:
+ printf("Migration failed -- restart local copy\n");
+ xc_domain_unpause(xc->xc_handle, dom);
+ PyErr_SetFromErrno(xc_error);
+ if ( sd >= 0 ) close(sd);
+ return NULL;
+
+}
+
+static PyObject *file_save(XcObject *xc, u32 dom, char *state_file, unsigned flags){
int fd = -1;
gzFile gfd = NULL;
- int writerfn(void *fd, const void *buf, size_t count)
- {
+ int writerfn(void *fd, const void *buf, size_t count) {
int rc;
while ( ((rc = gzwrite( (gzFile*)fd, (void*)buf, count)) == -1) &&
(errno = EINTR) )
@@ -300,30 +263,24 @@ static PyObject *pyxc_linux_save(PyObject *self,
return ! (rc == count);
}
- if (strncmp(state_file,"file:",strlen("file:")) == 0)
+ if (strncmp(state_file,"file:",strlen("file:")) == 0){
state_file += strlen("file:");
+ }
- if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 )
- {
+ if ( (fd = open(state_file, O_CREAT|O_EXCL|O_WRONLY, 0644)) == -1 ) {
perror("Could not open file for writing");
goto err;
}
-
/*
* Compression rate 1: we want speed over compression.
* We're mainly going for those zero pages, after all.
*/
-
- if ( (gfd = gzdopen(fd, "wb1")) == NULL )
- {
+ if ( (gfd = gzdopen(fd, "wb1")) == NULL ) {
perror("Could not allocate compression state for state file");
close(fd);
goto err;
}
-
-
- if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, gfd) == 0 )
- {
+ if ( xc_linux_save(xc->xc_handle, dom, flags, writerfn, gfd) == 0 ) {
/* kill domain. We don't want to do this for checkpointing, but
if we don't do it here I think people will hurt themselves
by accident... */
@@ -337,14 +294,45 @@ static PyObject *pyxc_linux_save(PyObject *self,
err:
PyErr_SetFromErrno(xc_error);
- if ( gfd != NULL )
- gzclose(gfd);
- if ( fd >= 0 )
- close(fd);
+ if ( gfd != NULL ) gzclose(gfd);
+ if ( fd >= 0 ) close(fd);
unlink(state_file);
return NULL;
- }
+}
+
+static PyObject *pyxc_linux_save(PyObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ XcObject *xc = (XcObject *)self;
+ u32 dom;
+ char *state_file;
+ int progress = 1, live = -1, debug = 0;
+ unsigned int flags = 0;
+ PyObject *val = NULL;
+
+ static char *kwd_list[] = { "dom", "state_file", "progress",
+ "live", "debug", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|iii", kwd_list,
+ &dom, &state_file, &progress,
+ &live, &debug) )
+ goto exit;
+
+ if (progress) flags |= XCFLAGS_VERBOSE;
+ if (live == 1) flags |= XCFLAGS_LIVE;
+ if (debug) flags |= XCFLAGS_DEBUG;
+
+ if ( strncmp(state_file,"tcp:", strlen("tcp:")) == 0 ) {
+ /* default to live for tcp */
+ if (live == -1) flags |= XCFLAGS_LIVE;
+ val = tcp_save(xc, dom, state_file, flags);
+ } else {
+ val = file_save(xc, dom, state_file, flags);
+ }
+ exit:
+ return val;
}
static PyObject *pyxc_linux_restore(PyObject *self,
@@ -1335,18 +1323,18 @@ static PyTypeObject PyXcType = {
};
static PyMethodDef PyXc_methods[] = {
- { "new", PyXc_new, METH_VARARGS, "Create a new Xc object." },
+ { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
{ NULL, NULL, 0, NULL }
};
-PyMODINIT_FUNC initXc(void)
+PyMODINIT_FUNC initxc(void)
{
PyObject *m, *d;
- m = Py_InitModule("Xc", PyXc_methods);
+ m = Py_InitModule(XENPKG, PyXc_methods);
d = PyModule_GetDict(m);
- xc_error = PyErr_NewException("Xc.error", NULL, NULL);
+ xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
PyDict_SetItemString(d, "error", xc_error);
zero = PyInt_FromLong(0);
diff --git a/tools/xc/py/setup.py b/tools/xc/py/setup.py
index 84eb6239a2..b295ed295b 100644
--- a/tools/xc/py/setup.py
+++ b/tools/xc/py/setup.py
@@ -1,11 +1,14 @@
from distutils.core import setup, Extension
-module = Extension("Xc",
+module = Extension("xc",
extra_compile_args = ["-fno-strict-aliasing"],
include_dirs = ["../lib"],
library_dirs = ["../lib"],
libraries = ["xc"],
sources = ["Xc.c"])
-setup(name = "Xc", version = "1.0", ext_modules = [module])
+setup(name = "xc",
+ version = "1.0",
+ ext_package = "xen.ext",
+ ext_modules = [module])
diff --git a/tools/xenmgr/Makefile b/tools/xen/Makefile
index 642cd2273e..642cd2273e 100644
--- a/tools/xenmgr/Makefile
+++ b/tools/xen/Makefile
diff --git a/tools/xenmgr/lib/__init__.py b/tools/xen/lib/__init__.py
index 8d1c8b69c3..8d1c8b69c3 100644
--- a/tools/xenmgr/lib/__init__.py
+++ b/tools/xen/lib/__init__.py
diff --git a/tools/xenmgr/lib/Args.py b/tools/xen/lib/xend/Args.py
index 527e841d3d..527e841d3d 100644
--- a/tools/xenmgr/lib/Args.py
+++ b/tools/xen/lib/xend/Args.py
diff --git a/tools/xenmgr/lib/EventServer.py b/tools/xen/lib/xend/EventServer.py
index 20c567ada7..20c567ada7 100644
--- a/tools/xenmgr/lib/EventServer.py
+++ b/tools/xen/lib/xend/EventServer.py
diff --git a/tools/xenmgr/lib/EventTypes.py b/tools/xen/lib/xend/EventTypes.py
index 6350baa5dd..6350baa5dd 100644
--- a/tools/xenmgr/lib/EventTypes.py
+++ b/tools/xen/lib/xend/EventTypes.py
diff --git a/tools/xenmgr/lib/PrettyPrint.py b/tools/xen/lib/xend/PrettyPrint.py
index 9e91b11448..9e91b11448 100644
--- a/tools/xenmgr/lib/PrettyPrint.py
+++ b/tools/xen/lib/xend/PrettyPrint.py
diff --git a/tools/xenmgr/lib/XendBridge.py b/tools/xen/lib/xend/XendBridge.py
index 10e2234eae..f1584552de 100644
--- a/tools/xenmgr/lib/XendBridge.py
+++ b/tools/xen/lib/xend/XendBridge.py
@@ -5,7 +5,7 @@ import os.path
import re
import sys
-from xenmgr import XendRoot
+from xen.xend import XendRoot
xroot = XendRoot.instance()
os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin'
diff --git a/tools/xenmgr/lib/XendClient.py b/tools/xen/lib/xend/XendClient.py
index 664835a155..13dc3dbb1e 100644
--- a/tools/xenmgr/lib/XendClient.py
+++ b/tools/xen/lib/xend/XendClient.py
@@ -208,16 +208,15 @@ class Xend:
{'op' : 'save',
'file' : filename})
- def xend_domain_restore(self, id, filename, conf):
+ def xend_domain_restore(self, id, filename):
return xend_call(self.domainurl(id),
{'op' : 'restore',
- 'file' : filename,
- 'config' : fileof(conf) })
+ 'file' : filename })
def xend_domain_migrate(self, id, dst):
return xend_call(self.domainurl(id),
{'op' : 'migrate',
- 'dst' : dst})
+ 'destination': dst})
def xend_domain_pincpu(self, id, cpu):
return xend_call(self.domainurl(id),
diff --git a/tools/xenmgr/lib/XendConsole.py b/tools/xen/lib/xend/XendConsole.py
index dcf992d376..4420c388f2 100644
--- a/tools/xenmgr/lib/XendConsole.py
+++ b/tools/xen/lib/xend/XendConsole.py
@@ -1,8 +1,8 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
import socket
-import Xc
-xc = Xc.new()
+import xen.ext.xc
+xc = xen.ext.xc.new()
import sxp
import XendRoot
@@ -12,8 +12,8 @@ import XendDB
import EventServer
eserver = EventServer.instance()
-from xenmgr.server import SrvConsoleServer
-xcd = SrvConsoleServer.instance()
+from xen.xend.server import SrvDaemon
+daemon = SrvDaemon.instance()
class XendConsoleInfo:
"""Console information record.
@@ -90,7 +90,7 @@ class XendConsole:
self._delete_console(k)
def refresh(self):
- consoles = xcd.consoles()
+ consoles = daemon.consoles()
cons = {}
for consinfo in consoles:
id = str(sxp.child_value(consinfo, 'id'))
@@ -111,7 +111,7 @@ class XendConsole:
#print 'onDomainDied', "dom=", dom, "dom1=", c.dom1, "dom2=", c.dom2
if (c.dom1 == dom) or (c.dom2 == dom):
'XendConsole>onDomainDied', 'delete console dom=', dom
- ctrl = xcd.get_domain_console(dom)
+ ctrl = daemon.get_domain_console(dom)
if ctrl:
ctrl.close()
self._delete_console(c.id)
@@ -155,7 +155,7 @@ class XendConsole:
return self.console.values()
def console_create(self, dom):
- consinfo = xcd.console_create(dom)
+ consinfo = daemon.console_create(dom)
info = self._new_console(consinfo)
return info
@@ -168,7 +168,7 @@ class XendConsole:
def console_disconnect(self, id):
id = int(id)
- xcd.console_disconnect(id)
+ daemon.console_disconnect(id)
def instance():
global inst
diff --git a/tools/xenmgr/lib/XendDB.py b/tools/xen/lib/xend/XendDB.py
index 6a27e65b58..6a27e65b58 100644
--- a/tools/xenmgr/lib/XendDB.py
+++ b/tools/xen/lib/xend/XendDB.py
diff --git a/tools/xenmgr/lib/XendDomain.py b/tools/xen/lib/xend/XendDomain.py
index 2eaa9b6241..446b7f7fae 100644
--- a/tools/xenmgr/lib/XendDomain.py
+++ b/tools/xen/lib/xend/XendDomain.py
@@ -8,7 +8,7 @@ import sys
from twisted.internet import defer
-import Xc; xc = Xc.new()
+import xen.ext.xc; xc = xen.ext.xc.new()
import xenctl.ip
import sxp
@@ -19,8 +19,8 @@ import XendDomainInfo
import XendConsole
import EventServer
-from xenmgr.server import SrvConsoleServer
-xend = SrvConsoleServer.instance()
+from xen.xend.server import SrvDaemon
+xend = SrvDaemon.instance()
eserver = EventServer.instance()
diff --git a/tools/xenmgr/lib/XendDomainConfig.py b/tools/xen/lib/xend/XendDomainConfig.py
index 35db31ff51..35db31ff51 100644
--- a/tools/xenmgr/lib/XendDomainConfig.py
+++ b/tools/xen/lib/xend/XendDomainConfig.py
diff --git a/tools/xenmgr/lib/XendDomainInfo.py b/tools/xen/lib/xend/XendDomainInfo.py
index 1f44f026a4..964285ec13 100644
--- a/tools/xenmgr/lib/XendDomainInfo.py
+++ b/tools/xen/lib/xend/XendDomainInfo.py
@@ -16,7 +16,7 @@ import os
from twisted.internet import defer
-import Xc; xc = Xc.new()
+import xen.ext.xc; xc = xen.ext.xc.new()
import xenctl.ip
import sxp
@@ -26,8 +26,8 @@ xendConsole = XendConsole.instance()
import XendBridge
-import server.SrvConsoleServer
-xend = server.SrvConsoleServer.instance()
+import server.SrvDaemon
+xend = server.SrvDaemon.instance()
SIF_BLK_BE_DOMAIN = (1<<4)
SIF_NET_BE_DOMAIN = (1<<5)
diff --git a/tools/xenmgr/lib/XendMigrate.py b/tools/xen/lib/xend/XendMigrate.py
index 1580ba83ed..1580ba83ed 100644
--- a/tools/xenmgr/lib/XendMigrate.py
+++ b/tools/xen/lib/xend/XendMigrate.py
diff --git a/tools/xenmgr/lib/XendNode.py b/tools/xen/lib/xend/XendNode.py
index d293da8e77..7221785aff 100644
--- a/tools/xenmgr/lib/XendNode.py
+++ b/tools/xen/lib/xend/XendNode.py
@@ -8,12 +8,12 @@
"""
import os
-import Xc
+import xen.ext.xc
class XendNode:
def __init__(self):
- self.xc = Xc.new()
+ self.xc = xen.ext.xc.new()
def shutdown(self):
return 0
diff --git a/tools/xenmgr/lib/XendRoot.py b/tools/xen/lib/xend/XendRoot.py
index 665f5df29e..665f5df29e 100644
--- a/tools/xenmgr/lib/XendRoot.py
+++ b/tools/xen/lib/xend/XendRoot.py
diff --git a/tools/xenmgr/lib/XendVnet.py b/tools/xen/lib/xend/XendVnet.py
index 213408e111..213408e111 100644
--- a/tools/xenmgr/lib/XendVnet.py
+++ b/tools/xen/lib/xend/XendVnet.py
diff --git a/tools/xen/lib/xend/__init__.py b/tools/xen/lib/xend/__init__.py
new file mode 100644
index 0000000000..8d1c8b69c3
--- /dev/null
+++ b/tools/xen/lib/xend/__init__.py
@@ -0,0 +1 @@
+
diff --git a/tools/xenmgr/lib/encode.py b/tools/xen/lib/xend/encode.py
index 38c9351db7..38c9351db7 100644
--- a/tools/xenmgr/lib/encode.py
+++ b/tools/xen/lib/xend/encode.py
diff --git a/tools/xenmgr/lib/server/SrvBase.py b/tools/xen/lib/xend/server/SrvBase.py
index 722b60f49d..bcff1bc3a0 100644
--- a/tools/xenmgr/lib/server/SrvBase.py
+++ b/tools/xen/lib/xend/server/SrvBase.py
@@ -13,8 +13,8 @@ from twisted.web import error
from twisted.web import resource
from twisted.web import server
-from xenmgr import sxp
-from xenmgr import PrettyPrint
+from xen.xend import sxp
+from xen.xend import PrettyPrint
def uri_pathlist(p):
"""Split a path into a list.
diff --git a/tools/xenmgr/lib/server/SrvConsole.py b/tools/xen/lib/xend/server/SrvConsole.py
index ea25bb6113..59d0e5f11c 100644
--- a/tools/xenmgr/lib/server/SrvConsole.py
+++ b/tools/xen/lib/xend/server/SrvConsole.py
@@ -1,7 +1,7 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-from xenmgr import sxp
-from xenmgr import XendConsole
+from xen.xend import sxp
+from xen.xend import XendConsole
from SrvDir import SrvDir
class SrvConsole(SrvDir):
diff --git a/tools/xenmgr/lib/server/SrvConsoleDir.py b/tools/xen/lib/xend/server/SrvConsoleDir.py
index e5c0308f80..814b448370 100644
--- a/tools/xenmgr/lib/server/SrvConsoleDir.py
+++ b/tools/xen/lib/xend/server/SrvConsoleDir.py
@@ -2,8 +2,8 @@
from SrvDir import SrvDir
from SrvConsole import SrvConsole
-from xenmgr import XendConsole
-from xenmgr import sxp
+from xen.xend import XendConsole
+from xen.xend import sxp
class SrvConsoleDir(SrvDir):
"""Console directory.
diff --git a/tools/xenmgr/lib/server/SrvConsoleServer.py b/tools/xen/lib/xend/server/SrvDaemon.py
index d6bb976b3c..385588b86f 100644
--- a/tools/xenmgr/lib/server/SrvConsoleServer.py
+++ b/tools/xen/lib/xend/server/SrvDaemon.py
@@ -21,16 +21,14 @@ from twisted.internet import protocol
from twisted.internet import abstract
from twisted.internet import defer
-import Xc; xc = Xc.new()
+from xen.ext import xu
-import xend.utils
-
-from xenmgr import sxp
-from xenmgr import PrettyPrint
-from xenmgr import EventServer
+from xen.xend import sxp
+from xen.xend import PrettyPrint
+from xen.xend import EventServer
eserver = EventServer.instance()
-from xenmgr.server import SrvServer
+from xen.xend.server import SrvServer
import channel
import blkif
@@ -479,7 +477,7 @@ class Daemon:
def install_child_reaper(self):
#signal.signal(signal.SIGCHLD, self.onSIGCHLD)
# Ensure that zombie children are automatically reaped.
- xend.utils.autoreap()
+ xu.autoreap()
def onSIGCHLD(self, signum, frame):
code = 1
diff --git a/tools/xenmgr/lib/server/SrvDeviceDir.py b/tools/xen/lib/xend/server/SrvDeviceDir.py
index 52f428540d..52f428540d 100644
--- a/tools/xenmgr/lib/server/SrvDeviceDir.py
+++ b/tools/xen/lib/xend/server/SrvDeviceDir.py
diff --git a/tools/xenmgr/lib/server/SrvDir.py b/tools/xen/lib/xend/server/SrvDir.py
index f4310e279c..c49c0b36ba 100644
--- a/tools/xenmgr/lib/server/SrvDir.py
+++ b/tools/xen/lib/xend/server/SrvDir.py
@@ -1,7 +1,7 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
from twisted.web import error
-from xenmgr import sxp
+from xen.xend import sxp
from SrvBase import SrvBase
class SrvConstructor:
diff --git a/tools/xenmgr/lib/server/SrvDomain.py b/tools/xen/lib/xend/server/SrvDomain.py
index 44d8f4cf6d..c3684f242b 100644
--- a/tools/xenmgr/lib/server/SrvDomain.py
+++ b/tools/xen/lib/xend/server/SrvDomain.py
@@ -1,10 +1,10 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-from xenmgr import sxp
-from xenmgr import XendDomain
-from xenmgr import XendConsole
-from xenmgr import PrettyPrint
-from xenmgr.Args import FormFn
+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
from SrvDir import SrvDir
diff --git a/tools/xenmgr/lib/server/SrvDomainDir.py b/tools/xen/lib/xend/server/SrvDomainDir.py
index 67a6a9bc7f..cb5d8e38cd 100644
--- a/tools/xenmgr/lib/server/SrvDomainDir.py
+++ b/tools/xen/lib/xend/server/SrvDomainDir.py
@@ -5,8 +5,8 @@ from StringIO import StringIO
from twisted.protocols import http
from twisted.web import error
-from xenmgr import sxp
-from xenmgr import XendDomain
+from xen.xend import sxp
+from xen.xend import XendDomain
from SrvDir import SrvDir
from SrvDomain import SrvDomain
diff --git a/tools/xenmgr/lib/server/SrvEventDir.py b/tools/xen/lib/xend/server/SrvEventDir.py
index eda56972da..02871a426a 100644
--- a/tools/xenmgr/lib/server/SrvEventDir.py
+++ b/tools/xen/lib/xend/server/SrvEventDir.py
@@ -1,7 +1,7 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-from xenmgr import sxp
-from xenmgr import EventServer
+from xen.xend import sxp
+from xen.xend import EventServer
from SrvDir import SrvDir
class SrvEventDir(SrvDir):
diff --git a/tools/xenmgr/lib/server/SrvNode.py b/tools/xen/lib/xend/server/SrvNode.py
index d4411d5e5d..69747d80c1 100644
--- a/tools/xenmgr/lib/server/SrvNode.py
+++ b/tools/xen/lib/xend/server/SrvNode.py
@@ -2,8 +2,8 @@
import os
from SrvDir import SrvDir
-from xenmgr import sxp
-from xenmgr import XendNode
+from xen.xend import sxp
+from xen.xend import XendNode
class SrvNode(SrvDir):
"""Information about the node.
diff --git a/tools/xenmgr/lib/server/SrvRoot.py b/tools/xen/lib/xend/server/SrvRoot.py
index 6256d83a4b..8d38937b72 100644
--- a/tools/xenmgr/lib/server/SrvRoot.py
+++ b/tools/xen/lib/xend/server/SrvRoot.py
@@ -1,6 +1,6 @@
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-from xenmgr import XendRoot
+from xen.xend import XendRoot
xroot = XendRoot.instance()
from SrvDir import SrvDir
diff --git a/tools/xenmgr/lib/server/SrvServer.py b/tools/xen/lib/xend/server/SrvServer.py
index d507c2002b..6535ad3f37 100644
--- a/tools/xenmgr/lib/server/SrvServer.py
+++ b/tools/xen/lib/xend/server/SrvServer.py
@@ -29,10 +29,10 @@ from twisted.web import server
from twisted.web import resource
from twisted.internet import reactor
-from xenmgr import XendRoot
+from xen.xend import XendRoot
xroot = XendRoot.instance()
-from xenmgr import XendBridge
+from xen.xend import XendBridge
from SrvRoot import SrvRoot
diff --git a/tools/xenmgr/lib/server/SrvVnetDir.py b/tools/xen/lib/xend/server/SrvVnetDir.py
index a8a814192d..a8a814192d 100644
--- a/tools/xenmgr/lib/server/SrvVnetDir.py
+++ b/tools/xen/lib/xend/server/SrvVnetDir.py
diff --git a/tools/xenmgr/lib/server/__init__.py b/tools/xen/lib/xend/server/__init__.py
index 8b13789179..8b13789179 100644
--- a/tools/xenmgr/lib/server/__init__.py
+++ b/tools/xen/lib/xend/server/__init__.py
diff --git a/tools/xenmgr/lib/server/blkif.py b/tools/xen/lib/xend/server/blkif.py
index fa46e3b642..4e2a49f7d8 100755
--- a/tools/xenmgr/lib/server/blkif.py
+++ b/tools/xen/lib/xend/server/blkif.py
@@ -1,7 +1,7 @@
from twisted.internet import defer
-from xenmgr import sxp
-from xenmgr import PrettyPrint
+from xen.xend import sxp
+from xen.xend import PrettyPrint
import channel
import controller
diff --git a/tools/xenmgr/lib/server/channel.py b/tools/xen/lib/xend/server/channel.py
index cf890918e5..be98a37fd5 100755
--- a/tools/xenmgr/lib/server/channel.py
+++ b/tools/xen/lib/xend/server/channel.py
@@ -1,5 +1,5 @@
-import Xc; xc = Xc.new()
-import xend.utils
+import xen.ext.xc; xc = xen.ext.xc.new()
+from xen.ext import xu
from messages import msgTypeName
VIRQ_MISDIRECT = 0 # Catch-all interrupt for unbound VIRQs.
@@ -21,7 +21,7 @@ class ChannelFactory:
def __init__(self):
"""Constructor - do not use. Use the channelFactory function."""
- self.notifier = xend.utils.notifier()
+ self.notifier = xu.notifier()
def addChannel(self, channel):
"""Add a channel.
@@ -78,7 +78,7 @@ class ChannelFactory:
def createPort(self, dom):
"""Create a port for a channel to the given domain.
"""
- return xend.utils.port(dom)
+ return xu.port(dom)
def channelFactory():
"""Singleton constructor for the channel factory.
diff --git a/tools/xenmgr/lib/server/console.py b/tools/xen/lib/xend/server/console.py
index f26a4dd3c6..75793d3bfc 100755
--- a/tools/xenmgr/lib/server/console.py
+++ b/tools/xen/lib/xend/server/console.py
@@ -3,9 +3,9 @@ from twisted.internet import reactor
from twisted.internet import protocol
from twisted.protocols import telnet
-import xend.utils
+from xen.ext import xu
-from xenmgr import EventServer
+from xen.xend import EventServer
eserver = EventServer.instance()
import controller
@@ -109,8 +109,8 @@ class ConsoleController(controller.Controller):
self.status = "new"
self.addr = None
self.conn = None
- self.rbuf = xend.utils.buffer()
- self.wbuf = xend.utils.buffer()
+ self.rbuf = xu.buffer()
+ self.wbuf = xu.buffer()
self.console_port = console_port
self.registerChannel()
@@ -192,7 +192,7 @@ class ConsoleController(controller.Controller):
# Send as much pending console data as there is room for.
work = 0
while not self.wbuf.empty() and self.channel.writeReady():
- msg = xend.utils.message(CMSG_CONSOLE, 0, 0)
+ msg = xu.message(CMSG_CONSOLE, 0, 0)
msg.append_payload(self.wbuf.read(msg.MAX_PAYLOAD))
work += self.channel.writeRequest(msg, notify=0)
return work
diff --git a/tools/xenmgr/lib/server/controller.py b/tools/xen/lib/xend/server/controller.py
index 900c2d55b0..900c2d55b0 100755
--- a/tools/xenmgr/lib/server/controller.py
+++ b/tools/xen/lib/xend/server/controller.py
diff --git a/tools/xenmgr/lib/server/cstruct.py b/tools/xen/lib/xend/server/cstruct.py
index 880931b41f..880931b41f 100755
--- a/tools/xenmgr/lib/server/cstruct.py
+++ b/tools/xen/lib/xend/server/cstruct.py
diff --git a/tools/xenmgr/lib/server/domain.py b/tools/xen/lib/xend/server/domain.py
index ab22234480..ab22234480 100644
--- a/tools/xenmgr/lib/server/domain.py
+++ b/tools/xen/lib/xend/server/domain.py
diff --git a/tools/xenmgr/lib/server/messages.py b/tools/xen/lib/xend/server/messages.py
index f920bd679e..e12d7b6e24 100644
--- a/tools/xenmgr/lib/server/messages.py
+++ b/tools/xen/lib/xend/server/messages.py
@@ -1,6 +1,6 @@
import struct
-import xend.utils
+from xen.ext import xu
DEBUG = 0
@@ -190,7 +190,7 @@ def packMsg(ty, params):
for (k, v) in args.items():
print 'packMsg>', k, v, type(v)
msgid = 0
- msg = xend.utils.message(major, minor, msgid, args)
+ msg = xu.message(major, minor, msgid, args)
return msg
def unpackMsg(ty, msg):
diff --git a/tools/xenmgr/lib/server/netif.py b/tools/xen/lib/xend/server/netif.py
index cb7496cd02..01391f7b5f 100755
--- a/tools/xenmgr/lib/server/netif.py
+++ b/tools/xen/lib/xend/server/netif.py
@@ -2,9 +2,9 @@ import random
from twisted.internet import defer
-from xenmgr import sxp
-from xenmgr import PrettyPrint
-from xenmgr import XendBridge
+from xen.xend import sxp
+from xen.xend import PrettyPrint
+from xen.xend import XendBridge
import channel
import controller
@@ -97,7 +97,7 @@ class NetifControllerFactory(controller.ControllerFactory):
## netif = interface.list[netif_key]
## netif.create()
## print " Notifying %d" % netif.dom
-## msg = xend.utils.message(
+## msg = xu.message(
## CMSG_NETIF_FE,
## CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED, 0,
## { 'handle' : 0, 'status' : 1 })
diff --git a/tools/xenmgr/lib/server/params.py b/tools/xen/lib/xend/server/params.py
index d8f064cf0c..7949f1431f 100644
--- a/tools/xenmgr/lib/server/params.py
+++ b/tools/xen/lib/xend/server/params.py
@@ -3,7 +3,7 @@ PID_FILE = '/var/run/xend.pid'
LOG_FILE = '/var/log/xend.log'
USER = 'root'
CONTROL_DIR = '/var/run/xend'
-MGMT_SOCK = 'xenmgrsock' # relative to CONTROL_DIR
+MGMT_SOCK = 'xendsock' # relative to CONTROL_DIR
EVENT_PORT = 8001
CONSOLE_PORT_BASE = 9600
diff --git a/tools/xenmgr/lib/sxp.py b/tools/xen/lib/xend/sxp.py
index dd4fece6f0..dd4fece6f0 100644
--- a/tools/xenmgr/lib/sxp.py
+++ b/tools/xen/lib/xend/sxp.py
diff --git a/tools/xend/lib/__init__.py b/tools/xen/lib/xm/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tools/xend/lib/__init__.py
+++ b/tools/xen/lib/xm/__init__.py
diff --git a/tools/xenmgr/lib/xm/create.py b/tools/xen/lib/xm/create.py
index d0bfa0859c..1def1903f2 100644
--- a/tools/xenmgr/lib/xm/create.py
+++ b/tools/xen/lib/xm/create.py
@@ -4,11 +4,11 @@
import string
import sys
-from xenmgr import sxp
-from xenmgr import PrettyPrint
-from xenmgr.XendClient import server
+from xen.xend import sxp
+from xen.xend import PrettyPrint
+from xen.xend.XendClient import server
-from xenmgr.xm.opts import *
+from xen.xend.xm.opts import *
gopts = Opts(use="""[options]
diff --git a/tools/xenmgr/lib/xm/main.py b/tools/xen/lib/xm/main.py
index 673cccd9fa..d03ceae7f2 100644
--- a/tools/xenmgr/lib/xm/main.py
+++ b/tools/xen/lib/xm/main.py
@@ -6,10 +6,10 @@ import os.path
import sys
from getopt import getopt
-from xenmgr import PrettyPrint
-from xenmgr import sxp
-from xenmgr.XendClient import server
-from xenmgr.xm import create, shutdown
+from xen.xend import PrettyPrint
+from xen.xend import sxp
+from xen.xend.XendClient import server
+from xen.xend.xm import create, shutdown
class Prog:
"""Base class for sub-programs.
diff --git a/tools/xenmgr/lib/xm/opts.py b/tools/xen/lib/xm/opts.py
index 5b9515215d..5b9515215d 100644
--- a/tools/xenmgr/lib/xm/opts.py
+++ b/tools/xen/lib/xm/opts.py
diff --git a/tools/xenmgr/lib/xm/shutdown.py b/tools/xen/lib/xm/shutdown.py
index 2c7831876b..7dc81008f1 100644
--- a/tools/xenmgr/lib/xm/shutdown.py
+++ b/tools/xen/lib/xm/shutdown.py
@@ -5,8 +5,8 @@ import string
import sys
import time
-from xenmgr.XendClient import server
-from xenmgr.xm.opts import *
+from xen.xend.XendClient import server
+from xen.xend.xm.opts import *
gopts = Opts(use="""[options] [DOM]
diff --git a/tools/xenmgr/netfix b/tools/xen/netfix
index 998a78a0d9..def4e28a6c 100644
--- a/tools/xenmgr/netfix
+++ b/tools/xen/netfix
@@ -7,7 +7,7 @@
#============================================================================
from getopt import getopt
-from xenmgr.XendBridge import *
+from xen.xend.XendBridge import *
short_options = 'hvqni:b:c'
long_options = ['help', 'verbose', 'quiet',
diff --git a/tools/xen/setup.py b/tools/xen/setup.py
new file mode 100644
index 0000000000..e099e00166
--- /dev/null
+++ b/tools/xen/setup.py
@@ -0,0 +1,16 @@
+
+from distutils.core import setup, Extension
+
+setup(name = 'xen',
+ version = '1.0',
+ description = 'Xen',
+ author = 'Mike Wray',
+ author_email = 'mike.wray@hp.com',
+ packages = ['xen',
+ 'xen.ext',
+ 'xen.xend',
+ 'xen.xend.server',
+ 'xen.xm',
+ ],
+ package_dir = { 'xen': 'lib' },
+ )
diff --git a/tools/xenmgr/xend b/tools/xen/xend
index e575eeccd5..65cfe8d820 100644
--- a/tools/xenmgr/xend
+++ b/tools/xen/xend
@@ -18,10 +18,10 @@
"""
import os
import sys
-from xenmgr.server import SrvConsoleServer
+from xen.xend.server import SrvDaemon
def main():
- daemon = SrvConsoleServer.instance()
+ daemon = SrvDaemon.instance()
if not sys.argv[1:]:
print 'usage: %s {start|stop|restart}' % sys.argv[0]
elif os.fork():
diff --git a/tools/xenmgr/xm b/tools/xen/xm
index ff5bbd75ca..09d8036f0f 100755
--- a/tools/xenmgr/xm
+++ b/tools/xen/xm
@@ -1,6 +1,6 @@
#!/usr/bin/python
# -*- mode: python; -*-
import sys
-from xenmgr.xm import main
+from xen.xm import main
main.main(sys.argv)
diff --git a/tools/xend/Makefile b/tools/xend-old/Makefile
index 8e28c0386a..8e28c0386a 100644
--- a/tools/xend/Makefile
+++ b/tools/xend-old/Makefile
diff --git a/tools/xenmgr/lib/xm/__init__.py b/tools/xend-old/lib/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tools/xenmgr/lib/xm/__init__.py
+++ b/tools/xend-old/lib/__init__.py
diff --git a/tools/xend/lib/blkif.py b/tools/xend-old/lib/blkif.py
index 51431b694a..51431b694a 100644
--- a/tools/xend/lib/blkif.py
+++ b/tools/xend-old/lib/blkif.py
diff --git a/tools/xend/lib/console.py b/tools/xend-old/lib/console.py
index 57898817f5..57898817f5 100644
--- a/tools/xend/lib/console.py
+++ b/tools/xend-old/lib/console.py
diff --git a/tools/xend/lib/domain_controller.h b/tools/xend-old/lib/domain_controller.h
index 76dd164fcb..76dd164fcb 100644
--- a/tools/xend/lib/domain_controller.h
+++ b/tools/xend-old/lib/domain_controller.h
diff --git a/tools/xend/lib/main.py b/tools/xend-old/lib/main.py
index 0eecd17a05..0eecd17a05 100755
--- a/tools/xend/lib/main.py
+++ b/tools/xend-old/lib/main.py
diff --git a/tools/xend/lib/manager.py b/tools/xend-old/lib/manager.py
index 49517583b5..49517583b5 100644
--- a/tools/xend/lib/manager.py
+++ b/tools/xend-old/lib/manager.py
diff --git a/tools/xend/lib/netif.py b/tools/xend-old/lib/netif.py
index eaa10086a2..eaa10086a2 100644
--- a/tools/xend/lib/netif.py
+++ b/tools/xend-old/lib/netif.py
diff --git a/tools/xend/lib/utils.c b/tools/xend-old/lib/utils.c
index 2d96577203..2d96577203 100644
--- a/tools/xend/lib/utils.c
+++ b/tools/xend-old/lib/utils.c
diff --git a/tools/xend/setup.py b/tools/xend-old/setup.py
index 66ed7a937e..66ed7a937e 100644
--- a/tools/xend/setup.py
+++ b/tools/xend-old/setup.py
diff --git a/tools/xend/xend b/tools/xend-old/xend
index 6e321bbad3..6e321bbad3 100755
--- a/tools/xend/xend
+++ b/tools/xend-old/xend
diff --git a/tools/xenmgr/setup.py b/tools/xenmgr/setup.py
deleted file mode 100644
index b7f76139be..0000000000
--- a/tools/xenmgr/setup.py
+++ /dev/null
@@ -1,14 +0,0 @@
-
-from distutils.core import setup, Extension
-
-PACKAGE = 'xenmgr'
-VERSION = '1.0'
-
-setup(name = PACKAGE,
- version = VERSION,
- description = 'Xen Management API',
- author = 'Mike Wray',
- author_email = 'mike.wray@hp.com',
- packages = [ PACKAGE, PACKAGE + '.server', PACKAGE + '.xm' ],
- package_dir = { PACKAGE: 'lib' },
- )
diff --git a/tools/xenmgr/xenmgrd b/tools/xenmgr/xenmgrd
deleted file mode 100755
index c871d4dece..0000000000
--- a/tools/xenmgr/xenmgrd
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-"""Xen management daemon. Lives in /usr/sbin.
- Run after running xend to provide http access to the management API.
-
- NO LONGER NEEDED.
-"""
-from xenmgr.server import SrvServer
-SrvServer.main()
diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile
index 6a03b42499..cce1150b16 100644
--- a/tools/xentrace/Makefile
+++ b/tools/xentrace/Makefile
@@ -3,7 +3,7 @@ CC = gcc
CFLAGS = -Wall -O3 -Werror
CFLAGS += -I../../xen/include/hypervisor-ifs
CFLAGS += -I../../linux-xen-sparse/include
-CFLAGS += -I../xend/lib
+CFLAGS += -I../xu/lib
HDRS = $(wildcard *.h)
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
diff --git a/tools/xu/lib/__init__.py b/tools/xu/lib/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tools/xu/lib/__init__.py
diff --git a/tools/xu/lib/domain_controller.h b/tools/xu/lib/domain_controller.h
new file mode 100644
index 0000000000..76dd164fcb
--- /dev/null
+++ b/tools/xu/lib/domain_controller.h
@@ -0,0 +1,532 @@
+/******************************************************************************
+ * domain_controller.h
+ *
+ * Interface to server controller (e.g., 'xend'). This header file defines the
+ * interface that is shared with guest OSes.
+ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#ifndef __DOMAIN_CONTROLLER_H__
+#define __DOMAIN_CONTROLLER_H__
+
+
+#ifndef BASIC_START_INFO
+#error "Xen header file hypervisor-if.h must already be included here."
+#endif
+
+
+/*
+ * EXTENDED BOOTSTRAP STRUCTURE FOR NEW DOMAINS.
+ */
+
+typedef struct {
+ BASIC_START_INFO;
+ u16 domain_controller_evtchn; /* 320 */
+} PACKED extended_start_info_t; /* 322 bytes */
+#define SIF_BLK_BE_DOMAIN (1<<4) /* Is this a block backend domain? */
+#define SIF_NET_BE_DOMAIN (1<<5) /* Is this a net backend domain? */
+
+
+/*
+ * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be
+ * interpreted by control software to determine the appropriate action. These
+ * are only really advisories: the controller can actually do as it likes.
+ */
+#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */
+#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */
+#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */
+
+
+/*
+ * CONTROLLER MESSAGING INTERFACE.
+ */
+
+typedef struct {
+ u8 type; /* 0: echoed in response */
+ u8 subtype; /* 1: echoed in response */
+ u8 id; /* 2: echoed in response */
+ u8 length; /* 3: number of bytes in 'msg' */
+ u8 msg[60]; /* 4: type-specific message data */
+} PACKED control_msg_t; /* 64 bytes */
+
+#define CONTROL_RING_SIZE 8
+typedef u32 CONTROL_RING_IDX;
+#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1))
+
+typedef struct {
+ control_msg_t tx_ring[CONTROL_RING_SIZE]; /* 0: guest -> controller */
+ control_msg_t rx_ring[CONTROL_RING_SIZE]; /* 512: controller -> guest */
+ CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */
+ CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */
+} PACKED control_if_t; /* 1040 bytes */
+
+/*
+ * Top-level command types.
+ */
+#define CMSG_CONSOLE 0 /* Console */
+#define CMSG_BLKIF_BE 1 /* Block-device backend */
+#define CMSG_BLKIF_FE 2 /* Block-device frontend */
+#define CMSG_NETIF_BE 3 /* Network-device backend */
+#define CMSG_NETIF_FE 4 /* Network-device frontend */
+#define CMSG_SHUTDOWN 6 /* Shutdown messages */
+
+
+/******************************************************************************
+ * CONSOLE DEFINITIONS
+ */
+
+/*
+ * Subtypes for console messages.
+ */
+#define CMSG_CONSOLE_DATA 0
+
+
+/******************************************************************************
+ * BLOCK-INTERFACE FRONTEND DEFINITIONS
+ */
+
+/* Messages from domain controller to guest. */
+#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED 0
+
+/* Messages from guest to domain controller. */
+#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED 32
+#define CMSG_BLKIF_FE_INTERFACE_CONNECT 33
+#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT 34
+
+/* These are used by both front-end and back-end drivers. */
+#define blkif_vdev_t u16
+#define blkif_pdev_t u16
+#define blkif_sector_t u64
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
+ * Notify a guest about a status change on one of its block interfaces.
+ * If the interface is DESTROYED or DOWN then the interface is disconnected:
+ * 1. The shared-memory frame is available for reuse.
+ * 2. Any unacknowledged messgaes pending on the interface were dropped.
+ */
+#define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
+#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
+#define BLKIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
+typedef struct {
+ u32 handle; /* 0 */
+ u32 status; /* 4 */
+ u16 evtchn; /* 8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
+} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */
+
+/*
+ * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the front-end driver is DOWN or UP.
+ * When the driver goes DOWN then the controller will send no more
+ * status-change notifications. When the driver comes UP then the controller
+ * will send a notification for each interface that currently exists.
+ * If the driver goes DOWN while interfaces are still UP, the domain
+ * will automatically take the interfaces DOWN.
+ */
+#define BLKIF_DRIVER_STATUS_DOWN 0
+#define BLKIF_DRIVER_STATUS_UP 1
+typedef struct {
+ /* IN */
+ u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */
+ /* OUT */
+ /*
+ * Tells driver how many interfaces it should expect to immediately
+ * receive notifications about.
+ */
+ u32 nr_interfaces; /* 4 */
+} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_CONNECT:
+ * If successful, the domain controller will acknowledge with a
+ * STATUS_CONNECTED message.
+ */
+typedef struct {
+ u32 handle; /* 0 */
+ u32 __pad;
+ memory_t shmem_frame; /* 8 */
+ MEMORY_PADDING;
+} PACKED blkif_fe_interface_connect_t; /* 16 bytes */
+
+/*
+ * CMSG_BLKIF_FE_INTERFACE_DISCONNECT:
+ * If successful, the domain controller will acknowledge with a
+ * STATUS_DISCONNECTED message.
+ */
+typedef struct {
+ u32 handle; /* 0 */
+} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */
+
+
+/******************************************************************************
+ * BLOCK-INTERFACE BACKEND DEFINITIONS
+ */
+
+/* Messages from domain controller. */
+#define CMSG_BLKIF_BE_CREATE 0 /* Create a new block-device interface. */
+#define CMSG_BLKIF_BE_DESTROY 1 /* Destroy a block-device interface. */
+#define CMSG_BLKIF_BE_CONNECT 2 /* Connect i/f to remote driver. */
+#define CMSG_BLKIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */
+#define CMSG_BLKIF_BE_VBD_CREATE 4 /* Create a new VBD for an interface. */
+#define CMSG_BLKIF_BE_VBD_DESTROY 5 /* Delete a VBD from an interface. */
+#define CMSG_BLKIF_BE_VBD_GROW 6 /* Append an extent to a given VBD. */
+#define CMSG_BLKIF_BE_VBD_SHRINK 7 /* Remove last extent from a given VBD. */
+
+/* Messages to domain controller. */
+#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
+
+/*
+ * Message request/response definitions for block-device messages.
+ */
+
+typedef struct {
+ blkif_sector_t sector_start; /* 0 */
+ blkif_sector_t sector_length; /* 8 */
+ blkif_pdev_t device; /* 16 */
+ u16 __pad; /* 18 */
+} PACKED blkif_extent_t; /* 20 bytes */
+
+/* Non-specific 'okay' return. */
+#define BLKIF_BE_STATUS_OKAY 0
+/* Non-specific 'error' return. */
+#define BLKIF_BE_STATUS_ERROR 1
+/* The following are specific error returns. */
+#define BLKIF_BE_STATUS_INTERFACE_EXISTS 2
+#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
+#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4
+#define BLKIF_BE_STATUS_VBD_EXISTS 5
+#define BLKIF_BE_STATUS_VBD_NOT_FOUND 6
+#define BLKIF_BE_STATUS_OUT_OF_MEMORY 7
+#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND 8
+#define BLKIF_BE_STATUS_MAPPING_ERROR 9
+
+/* This macro can be used to create an array of descriptive error strings. */
+#define BLKIF_BE_STATUS_ERRORS { \
+ "Okay", \
+ "Non-specific error", \
+ "Interface already exists", \
+ "Interface not found", \
+ "Interface is still connected", \
+ "VBD already exists", \
+ "VBD not found", \
+ "Out of memory", \
+ "Extent not found for VBD", \
+ "Could not map domain memory" }
+
+/*
+ * CMSG_BLKIF_BE_CREATE:
+ * When the driver sends a successful response then the interface is fully
+ * created. The controller will send a DOWN notification to the front-end
+ * driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 blkif_handle; /* 4: Domain-specific interface handle. */
+ /* OUT */
+ u32 status; /* 8 */
+} PACKED blkif_be_create_t; /* 12 bytes */
+
+/*
+ * CMSG_BLKIF_BE_DESTROY:
+ * When the driver sends a successful response then the interface is fully
+ * torn down. The controller will send a DESTROYED notification to the
+ * front-end driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify interface to be destroyed. */
+ u32 blkif_handle; /* 4: ...ditto... */
+ /* OUT */
+ u32 status; /* 8 */
+} PACKED blkif_be_destroy_t; /* 12 bytes */
+
+/*
+ * CMSG_BLKIF_BE_CONNECT:
+ * When the driver sends a successful response then the interface is fully
+ * connected. The controller will send a CONNECTED notification to the
+ * front-end driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 blkif_handle; /* 4: Domain-specific interface handle. */
+ memory_t shmem_frame; /* 8: Page cont. shared comms window. */
+ MEMORY_PADDING;
+ u32 evtchn; /* 16: Event channel for notifications. */
+ /* OUT */
+ u32 status; /* 20 */
+} PACKED blkif_be_connect_t; /* 24 bytes */
+
+/*
+ * CMSG_BLKIF_BE_DISCONNECT:
+ * When the driver sends a successful response then the interface is fully
+ * disconnected. The controller will send a DOWN notification to the front-end
+ * driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 blkif_handle; /* 4: Domain-specific interface handle. */
+ /* OUT */
+ u32 status; /* 8 */
+} PACKED blkif_be_disconnect_t; /* 12 bytes */
+
+/* CMSG_BLKIF_BE_VBD_CREATE */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify blkdev interface. */
+ u32 blkif_handle; /* 4: ...ditto... */
+ blkif_vdev_t vdevice; /* 8: Interface-specific id for this VBD. */
+ u16 readonly; /* 10: Non-zero -> VBD isn't writeable. */
+ /* OUT */
+ u32 status; /* 12 */
+} PACKED blkif_be_vbd_create_t; /* 16 bytes */
+
+/* CMSG_BLKIF_BE_VBD_DESTROY */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify blkdev interface. */
+ u32 blkif_handle; /* 4: ...ditto... */
+ blkif_vdev_t vdevice; /* 8: Interface-specific id of the VBD. */
+ u16 __pad; /* 10 */
+ /* OUT */
+ u32 status; /* 12 */
+} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
+
+/* CMSG_BLKIF_BE_VBD_GROW */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify blkdev interface. */
+ u32 blkif_handle; /* 4: ...ditto... */
+ blkif_extent_t extent; /* 8: Physical extent to append to VBD. */
+ blkif_vdev_t vdevice; /* 28: Interface-specific id of the VBD. */
+ u16 __pad; /* 30 */
+ /* OUT */
+ u32 status; /* 32 */
+} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
+
+/* CMSG_BLKIF_BE_VBD_SHRINK */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify blkdev interface. */
+ u32 blkif_handle; /* 4: ...ditto... */
+ blkif_vdev_t vdevice; /* 8: Interface-specific id of the VBD. */
+ u16 __pad; /* 10 */
+ /* OUT */
+ u32 status; /* 12 */
+} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
+
+/*
+ * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the back-end driver is DOWN or UP.
+ * If the driver goes DOWN while interfaces are still UP, the controller
+ * will automatically send DOWN notifications.
+ */
+typedef struct {
+ u32 status; /* 0: BLKIF_DRIVER_STATUS_??? */
+} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
+
+
+/******************************************************************************
+ * NETWORK-INTERFACE FRONTEND DEFINITIONS
+ */
+
+/* Messages from domain controller to guest. */
+#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED 0
+
+/* Messages from guest to domain controller. */
+#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED 32
+#define CMSG_NETIF_FE_INTERFACE_CONNECT 33
+#define CMSG_NETIF_FE_INTERFACE_DISCONNECT 34
+
+/*
+ * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
+ * Notify a guest about a status change on one of its network interfaces.
+ * If the interface is DESTROYED or DOWN then the interface is disconnected:
+ * 1. The shared-memory frame is available for reuse.
+ * 2. Any unacknowledged messgaes pending on the interface were dropped.
+ */
+#define NETIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
+#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
+#define NETIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
+typedef struct {
+ u32 handle; /* 0 */
+ u32 status; /* 4 */
+ u16 evtchn; /* 8: status == NETIF_INTERFACE_STATUS_CONNECTED */
+ u8 mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
+} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */
+
+/*
+ * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the front-end driver is DOWN or UP.
+ * When the driver goes DOWN then the controller will send no more
+ * status-change notifications. When the driver comes UP then the controller
+ * will send a notification for each interface that currently exists.
+ * If the driver goes DOWN while interfaces are still UP, the domain
+ * will automatically take the interfaces DOWN.
+ */
+#define NETIF_DRIVER_STATUS_DOWN 0
+#define NETIF_DRIVER_STATUS_UP 1
+typedef struct {
+ /* IN */
+ u32 status; /* 0: NETIF_DRIVER_STATUS_??? */
+ /* OUT */
+ /*
+ * Tells driver how many interfaces it should expect to immediately
+ * receive notifications about.
+ */
+ u32 nr_interfaces; /* 4 */
+} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
+
+/*
+ * CMSG_NETIF_FE_INTERFACE_CONNECT:
+ * If successful, the domain controller will acknowledge with a
+ * STATUS_CONNECTED message.
+ */
+typedef struct {
+ u32 handle; /* 0 */
+ u32 __pad; /* 4 */
+ memory_t tx_shmem_frame; /* 8 */
+ MEMORY_PADDING;
+ memory_t rx_shmem_frame; /* 16 */
+ MEMORY_PADDING;
+} PACKED netif_fe_interface_connect_t; /* 24 bytes */
+
+/*
+ * CMSG_NETIF_FE_INTERFACE_DISCONNECT:
+ * If successful, the domain controller will acknowledge with a
+ * STATUS_DISCONNECTED message.
+ */
+typedef struct {
+ u32 handle; /* 0 */
+} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */
+
+
+/******************************************************************************
+ * NETWORK-INTERFACE BACKEND DEFINITIONS
+ */
+
+/* Messages from domain controller. */
+#define CMSG_NETIF_BE_CREATE 0 /* Create a new net-device interface. */
+#define CMSG_NETIF_BE_DESTROY 1 /* Destroy a net-device interface. */
+#define CMSG_NETIF_BE_CONNECT 2 /* Connect i/f to remote driver. */
+#define CMSG_NETIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */
+
+/* Messages to domain controller. */
+#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
+
+/*
+ * Message request/response definitions for net-device messages.
+ */
+
+/* Non-specific 'okay' return. */
+#define NETIF_BE_STATUS_OKAY 0
+/* Non-specific 'error' return. */
+#define NETIF_BE_STATUS_ERROR 1
+/* The following are specific error returns. */
+#define NETIF_BE_STATUS_INTERFACE_EXISTS 2
+#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3
+#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4
+#define NETIF_BE_STATUS_OUT_OF_MEMORY 5
+#define NETIF_BE_STATUS_MAPPING_ERROR 6
+
+/* This macro can be used to create an array of descriptive error strings. */
+#define NETIF_BE_STATUS_ERRORS { \
+ "Okay", \
+ "Non-specific error", \
+ "Interface already exists", \
+ "Interface not found", \
+ "Interface is still connected", \
+ "Out of memory", \
+ "Could not map domain memory" }
+
+/*
+ * CMSG_NETIF_BE_CREATE:
+ * When the driver sends a successful response then the interface is fully
+ * created. The controller will send a DOWN notification to the front-end
+ * driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 netif_handle; /* 4: Domain-specific interface handle. */
+ u8 mac[6]; /* 8 */
+ u16 __pad; /* 14 */
+ /* OUT */
+ u32 status; /* 16 */
+} PACKED netif_be_create_t; /* 20 bytes */
+
+/*
+ * CMSG_NETIF_BE_DESTROY:
+ * When the driver sends a successful response then the interface is fully
+ * torn down. The controller will send a DESTROYED notification to the
+ * front-end driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Identify interface to be destroyed. */
+ u32 netif_handle; /* 4: ...ditto... */
+ /* OUT */
+ u32 status; /* 8 */
+} PACKED netif_be_destroy_t; /* 12 bytes */
+
+/*
+ * CMSG_NETIF_BE_CONNECT:
+ * When the driver sends a successful response then the interface is fully
+ * connected. The controller will send a CONNECTED notification to the
+ * front-end driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 netif_handle; /* 4: Domain-specific interface handle. */
+ memory_t tx_shmem_frame; /* 8: Page cont. tx shared comms window. */
+ MEMORY_PADDING;
+ memory_t rx_shmem_frame; /* 16: Page cont. rx shared comms window. */
+ MEMORY_PADDING;
+ u16 evtchn; /* 24: Event channel for notifications. */
+ u16 __pad; /* 26 */
+ /* OUT */
+ u32 status; /* 28 */
+} PACKED netif_be_connect_t; /* 32 bytes */
+
+/*
+ * CMSG_NETIF_BE_DISCONNECT:
+ * When the driver sends a successful response then the interface is fully
+ * disconnected. The controller will send a DOWN notification to the front-end
+ * driver.
+ */
+typedef struct {
+ /* IN */
+ domid_t domid; /* 0: Domain attached to new interface. */
+ u32 netif_handle; /* 4: Domain-specific interface handle. */
+ /* OUT */
+ u32 status; /* 8 */
+} PACKED netif_be_disconnect_t; /* 12 bytes */
+
+/*
+ * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
+ * Notify the domain controller that the back-end driver is DOWN or UP.
+ * If the driver goes DOWN while interfaces are still UP, the domain
+ * will automatically send DOWN notifications.
+ */
+typedef struct {
+ u32 status; /* 0: NETIF_DRIVER_STATUS_??? */
+} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
+
+
+/******************************************************************************
+ * SHUTDOWN DEFINITIONS
+ */
+
+/*
+ * Subtypes for shutdown messages.
+ */
+#define CMSG_SHUTDOWN_POWEROFF 0 /* Clean shutdown (SHUTDOWN_poweroff). */
+#define CMSG_SHUTDOWN_REBOOT 1 /* Clean shutdown (SHUTDOWN_reboot). */
+#define CMSG_SHUTDOWN_SUSPEND 2 /* Create suspend info, then */
+ /* SHUTDOWN_suspend. */
+
+#endif /* __DOMAIN_CONTROLLER_H__ */
diff --git a/tools/xu/lib/xu.c b/tools/xu/lib/xu.c
new file mode 100644
index 0000000000..48c975912d
--- /dev/null
+++ b/tools/xu/lib/xu.c
@@ -0,0 +1,1386 @@
+/******************************************************************************
+ * utils.c
+ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#include <Python.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <xc.h>
+
+#include <hypervisor-if.h>
+#include "domain_controller.h"
+
+#include <asm-xen/proc_cmd.h>
+
+#define XENPKG "xen.ext.xu"
+
+/* Needed for Python versions earlier than 2.3. */
+#ifndef PyMODINIT_FUNC
+#define PyMODINIT_FUNC DL_EXPORT(void)
+#endif
+
+/* NB. The following should be kept in sync with the kernel's evtchn driver. */
+#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
+#define EVTCHN_DEV_MAJOR 10
+#define EVTCHN_DEV_MINOR 200
+#define PORT_NORMAL 0x0000 /* A standard event notification. */
+#define PORT_EXCEPTION 0x8000 /* An exceptional notification. */
+#define PORTIDX_MASK 0x7fff /* Strip subtype to obtain port index. */
+/* /dev/xen/evtchn ioctls: */
+/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
+#define EVTCHN_RESET _IO('E', 1)
+/* EVTCHN_BIND: Bind to teh specified event-channel port. */
+#define EVTCHN_BIND _IO('E', 2)
+/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
+#define EVTCHN_UNBIND _IO('E', 3)
+
+/* Size of a machine page frame. */
+#define PAGE_SIZE 4096
+
+
+/*
+ * *********************** NOTIFIER ***********************
+ */
+
+typedef struct {
+ PyObject_HEAD;
+ int evtchn_fd;
+} xu_notifier_object;
+
+static PyObject *xu_notifier_read(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ u16 v;
+ int bytes;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ while ( (bytes = read(xun->evtchn_fd, &v, sizeof(v))) == -1 )
+ {
+ if ( errno == EINTR )
+ continue;
+ if ( errno == EAGAIN )
+ goto none;
+ return PyErr_SetFromErrno(PyExc_IOError);
+ }
+
+ if ( bytes == sizeof(v) )
+ return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK);
+
+ none:
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_notifier_unmask(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ u16 v;
+ int idx;
+
+ if ( !PyArg_ParseTuple(args, "i", &idx) )
+ return NULL;
+
+ v = (u16)idx;
+
+ (void)write(xun->evtchn_fd, &v, sizeof(v));
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_notifier_bind(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ int idx;
+
+ if ( !PyArg_ParseTuple(args, "i", &idx) )
+ return NULL;
+
+ if ( ioctl(xun->evtchn_fd, EVTCHN_BIND, idx) != 0 )
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_notifier_unbind(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ int idx;
+
+ if ( !PyArg_ParseTuple(args, "i", &idx) )
+ return NULL;
+
+ if ( ioctl(xun->evtchn_fd, EVTCHN_UNBIND, idx) != 0 )
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_notifier_fileno(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ return PyInt_FromLong(xun->evtchn_fd);
+}
+
+static PyMethodDef xu_notifier_methods[] = {
+ { "read",
+ (PyCFunction)xu_notifier_read,
+ METH_VARARGS,
+ "Read a (@port, @type) pair.\n" },
+
+ { "unmask",
+ (PyCFunction)xu_notifier_unmask,
+ METH_VARARGS,
+ "Unmask notifications for a @port.\n" },
+
+ { "bind",
+ (PyCFunction)xu_notifier_bind,
+ METH_VARARGS,
+ "Get notifications for a @port.\n" },
+
+ { "unbind",
+ (PyCFunction)xu_notifier_unbind,
+ METH_VARARGS,
+ "No longer get notifications for a @port.\n" },
+
+ { "fileno",
+ (PyCFunction)xu_notifier_fileno,
+ METH_VARARGS,
+ "Return the file descriptor for the notification channel.\n" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+staticforward PyTypeObject xu_notifier_type;
+
+static PyObject *xu_notifier_new(PyObject *self, PyObject *args)
+{
+ xu_notifier_object *xun;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ xun = PyObject_New(xu_notifier_object, &xu_notifier_type);
+
+ reopen:
+ xun->evtchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+ if ( xun->evtchn_fd == -1 )
+ {
+ if ( (errno == ENOENT) &&
+ ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
+ (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
+ (EVTCHN_DEV_MAJOR << 8) | EVTCHN_DEV_MINOR) == 0) )
+ goto reopen;
+ PyObject_Del((PyObject *)xun);
+ return PyErr_SetFromErrno(PyExc_IOError);
+ }
+
+ return (PyObject *)xun;
+}
+
+static PyObject *xu_notifier_getattr(PyObject *obj, char *name)
+{
+ if ( strcmp(name, "EXCEPTION") == 0 )
+ return PyInt_FromLong(PORT_EXCEPTION);
+ if ( strcmp(name, "NORMAL") == 0 )
+ return PyInt_FromLong(PORT_NORMAL);
+ return Py_FindMethod(xu_notifier_methods, obj, name);
+}
+
+static void xu_notifier_dealloc(PyObject *self)
+{
+ xu_notifier_object *xun = (xu_notifier_object *)self;
+ (void)close(xun->evtchn_fd);
+ PyObject_Del(self);
+}
+
+static PyTypeObject xu_notifier_type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "notifier",
+ sizeof(xu_notifier_object),
+ 0,
+ xu_notifier_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ xu_notifier_getattr, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL /* tp_hash */
+};
+
+
+
+/*
+ * *********************** MESSAGE ***********************
+ */
+
+#define TYPE(_x,_y) (((_x)<<8)|(_y))
+#define P2C(_struct, _field, _ctype) \
+ do { \
+ PyObject *obj; \
+ if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL ) \
+ { \
+ if ( PyInt_Check(obj) ) \
+ { \
+ ((_struct *)&xum->msg.msg[0])->_field = \
+ (_ctype)PyInt_AsLong(obj); \
+ dict_items_parsed++; \
+ } \
+ else if ( PyLong_Check(obj) ) \
+ { \
+ ((_struct *)&xum->msg.msg[0])->_field = \
+ (_ctype)PyLong_AsUnsignedLongLong(obj); \
+ dict_items_parsed++; \
+ } \
+ } \
+ xum->msg.length = sizeof(_struct); \
+ } while ( 0 )
+#define C2P(_struct, _field, _pytype, _ctype) \
+ do { \
+ PyObject *obj = Py ## _pytype ## _From ## _ctype \
+ (((_struct *)&xum->msg.msg[0])->_field); \
+ if ( dict == NULL ) dict = PyDict_New(); \
+ PyDict_SetItemString(dict, #_field, obj); \
+ } while ( 0 )
+
+typedef struct {
+ PyObject_HEAD;
+ control_msg_t msg;
+} xu_message_object;
+
+static PyObject *xu_message_append_payload(PyObject *self, PyObject *args)
+{
+ xu_message_object *xum = (xu_message_object *)self;
+ char *str;
+ int len;
+
+ if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
+ return NULL;
+
+ if ( (len + xum->msg.length) > sizeof(xum->msg.msg) )
+ {
+ PyErr_SetString(PyExc_RuntimeError, "out of space in control message");
+ return NULL;
+ }
+
+ memcpy(&xum->msg.msg[xum->msg.length], str, len);
+ xum->msg.length += len;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args)
+{
+ xu_message_object *xum = (xu_message_object *)self;
+ PyObject *payload;
+ int dict_items_parsed = 0;
+
+ if ( !PyArg_ParseTuple(args, "O", &payload) )
+ return NULL;
+
+ if ( !PyDict_Check(payload) )
+ {
+ PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
+ return NULL;
+ }
+
+ switch ( TYPE(xum->msg.type, xum->msg.subtype) )
+ {
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
+ P2C(blkif_fe_driver_status_changed_t, nr_interfaces, u32);
+ break;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
+ P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
+ break;
+ }
+
+ if ( dict_items_parsed != PyDict_Size(payload) )
+ {
+ PyErr_SetString(PyExc_TypeError, "payload contains bad items");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
+{
+ xu_message_object *xum = (xu_message_object *)self;
+ PyObject *dict = NULL;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ switch ( TYPE(xum->msg.type, xum->msg.subtype) )
+ {
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
+ C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
+ C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
+ C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
+ C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
+ C2P(blkif_fe_interface_connect_t, handle, Int, Long);
+ C2P(blkif_fe_interface_connect_t, shmem_frame, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_DISCONNECT):
+ C2P(blkif_fe_interface_disconnect_t, handle, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
+ C2P(blkif_be_create_t, domid, Int, Long);
+ C2P(blkif_be_create_t, blkif_handle, Int, Long);
+ C2P(blkif_be_create_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
+ C2P(blkif_be_destroy_t, domid, Int, Long);
+ C2P(blkif_be_destroy_t, blkif_handle, Int, Long);
+ C2P(blkif_be_destroy_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
+ C2P(blkif_be_connect_t, domid, Int, Long);
+ C2P(blkif_be_connect_t, blkif_handle, Int, Long);
+ C2P(blkif_be_connect_t, shmem_frame, Int, Long);
+ C2P(blkif_be_connect_t, evtchn, Int, Long);
+ C2P(blkif_be_connect_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
+ C2P(blkif_be_disconnect_t, domid, Int, Long);
+ C2P(blkif_be_disconnect_t, blkif_handle, Int, Long);
+ C2P(blkif_be_disconnect_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
+ C2P(blkif_be_vbd_create_t, domid, Int, Long);
+ C2P(blkif_be_vbd_create_t, blkif_handle, Int, Long);
+ C2P(blkif_be_vbd_create_t, vdevice, Int, Long);
+ C2P(blkif_be_vbd_create_t, readonly, Int, Long);
+ C2P(blkif_be_vbd_create_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
+ C2P(blkif_be_vbd_destroy_t, domid, Int, Long);
+ C2P(blkif_be_vbd_destroy_t, blkif_handle, Int, Long);
+ C2P(blkif_be_vbd_destroy_t, vdevice, Int, Long);
+ C2P(blkif_be_vbd_destroy_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
+ C2P(blkif_be_vbd_grow_t, domid, Int, Long);
+ C2P(blkif_be_vbd_grow_t, blkif_handle, Int, Long);
+ C2P(blkif_be_vbd_grow_t, vdevice, Int, Long);
+ C2P(blkif_be_vbd_grow_t, extent.sector_start,
+ Long, UnsignedLongLong);
+ C2P(blkif_be_vbd_grow_t, extent.sector_length,
+ Long, UnsignedLongLong);
+ C2P(blkif_be_vbd_grow_t, extent.device, Int, Long);
+ C2P(blkif_be_vbd_grow_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
+ C2P(blkif_be_vbd_shrink_t, domid, Int, Long);
+ C2P(blkif_be_vbd_shrink_t, blkif_handle, Int, Long);
+ C2P(blkif_be_vbd_shrink_t, vdevice, Int, Long);
+ C2P(blkif_be_vbd_shrink_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
+ C2P(blkif_be_driver_status_changed_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
+ C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
+ C2P(netif_fe_interface_status_changed_t, status, Int, Long);
+ C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
+ C2P(netif_fe_driver_status_changed_t, status, Int, Long);
+ C2P(netif_fe_driver_status_changed_t, nr_interfaces, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
+ C2P(netif_fe_interface_connect_t, handle, Int, Long);
+ C2P(netif_fe_interface_connect_t, tx_shmem_frame, Int, Long);
+ C2P(netif_fe_interface_connect_t, rx_shmem_frame, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_DISCONNECT):
+ C2P(netif_fe_interface_disconnect_t, handle, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
+ C2P(netif_be_create_t, domid, Int, Long);
+ C2P(netif_be_create_t, netif_handle, Int, Long);
+ C2P(netif_be_create_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
+ C2P(netif_be_destroy_t, domid, Int, Long);
+ C2P(netif_be_destroy_t, netif_handle, Int, Long);
+ C2P(netif_be_destroy_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
+ C2P(netif_be_connect_t, domid, Int, Long);
+ C2P(netif_be_connect_t, netif_handle, Int, Long);
+ C2P(netif_be_connect_t, tx_shmem_frame, Int, Long);
+ C2P(netif_be_connect_t, rx_shmem_frame, Int, Long);
+ C2P(netif_be_connect_t, evtchn, Int, Long);
+ C2P(netif_be_connect_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
+ C2P(netif_be_disconnect_t, domid, Int, Long);
+ C2P(netif_be_disconnect_t, netif_handle, Int, Long);
+ C2P(netif_be_disconnect_t, status, Int, Long);
+ return dict;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
+ C2P(netif_be_driver_status_changed_t, status, Int, Long);
+ return dict;
+ }
+
+ return PyString_FromStringAndSize(xum->msg.msg, xum->msg.length);
+}
+
+static PyObject *xu_message_get_header(PyObject *self, PyObject *args)
+{
+ xu_message_object *xum = (xu_message_object *)self;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ return Py_BuildValue("{s:i,s:i,s:i}",
+ "type", xum->msg.type,
+ "subtype", xum->msg.subtype,
+ "id", xum->msg.id);
+}
+
+static PyMethodDef xu_message_methods[] = {
+ { "append_payload",
+ (PyCFunction)xu_message_append_payload,
+ METH_VARARGS,
+ "Append @str to the message payload.\n" },
+
+ { "set_response_fields",
+ (PyCFunction)xu_message_set_response_fields,
+ METH_VARARGS,
+ "Fill in the response fields in a message that was passed to us.\n" },
+
+ { "get_payload",
+ (PyCFunction)xu_message_get_payload,
+ METH_VARARGS,
+ "Return the message payload in string form.\n" },
+
+ { "get_header",
+ (PyCFunction)xu_message_get_header,
+ METH_VARARGS,
+ "Returns a dictionary of values for @type, @subtype, and @id.\n" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+staticforward PyTypeObject xu_message_type;
+
+static PyObject *xu_message_new(PyObject *self, PyObject *args)
+{
+ xu_message_object *xum;
+ int type, subtype, id, dict_items_parsed = 0;
+ PyObject *payload = NULL;
+
+ if ( !PyArg_ParseTuple(args, "iii|O", &type, &subtype, &id, &payload) )
+ return NULL;
+
+ xum = PyObject_New(xu_message_object, &xu_message_type);
+
+ xum->msg.type = type;
+ xum->msg.subtype = subtype;
+ xum->msg.id = id;
+ xum->msg.length = 0;
+
+ if ( payload == NULL )
+ return (PyObject *)xum;
+
+ if ( !PyDict_Check(payload) )
+ {
+ PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
+ PyObject_Del((PyObject *)xum);
+ return NULL;
+ }
+
+ switch ( TYPE(type, subtype) )
+ {
+ case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
+ P2C(blkif_fe_interface_status_changed_t, handle, u32);
+ P2C(blkif_fe_interface_status_changed_t, status, u32);
+ P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
+ P2C(blkif_be_create_t, domid, u32);
+ P2C(blkif_be_create_t, blkif_handle, u32);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
+ P2C(blkif_be_destroy_t, domid, u32);
+ P2C(blkif_be_destroy_t, blkif_handle, u32);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
+ P2C(blkif_be_connect_t, domid, u32);
+ P2C(blkif_be_connect_t, blkif_handle, u32);
+ P2C(blkif_be_connect_t, shmem_frame, memory_t);
+ P2C(blkif_be_connect_t, evtchn, u16);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
+ P2C(blkif_be_disconnect_t, domid, u32);
+ P2C(blkif_be_disconnect_t, blkif_handle, u32);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
+ P2C(blkif_be_vbd_create_t, domid, u32);
+ P2C(blkif_be_vbd_create_t, blkif_handle, u32);
+ P2C(blkif_be_vbd_create_t, vdevice, blkif_vdev_t);
+ P2C(blkif_be_vbd_create_t, readonly, u16);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
+ P2C(blkif_be_vbd_destroy_t, domid, u32);
+ P2C(blkif_be_vbd_destroy_t, blkif_handle, u32);
+ P2C(blkif_be_vbd_destroy_t, vdevice, blkif_vdev_t);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
+ P2C(blkif_be_vbd_grow_t, domid, u32);
+ P2C(blkif_be_vbd_grow_t, blkif_handle, u32);
+ P2C(blkif_be_vbd_grow_t, vdevice, blkif_vdev_t);
+ P2C(blkif_be_vbd_grow_t, extent.sector_start, blkif_sector_t);
+ P2C(blkif_be_vbd_grow_t, extent.sector_length, blkif_sector_t);
+ P2C(blkif_be_vbd_grow_t, extent.device, blkif_pdev_t);
+ break;
+ case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
+ P2C(blkif_be_vbd_shrink_t, domid, u32);
+ P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
+ P2C(blkif_be_vbd_shrink_t, vdevice, blkif_vdev_t);
+ break;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
+ P2C(netif_fe_interface_status_changed_t, handle, u32);
+ P2C(netif_fe_interface_status_changed_t, status, u32);
+ P2C(netif_fe_interface_status_changed_t, evtchn, u16);
+ P2C(netif_fe_interface_status_changed_t, mac[0], u8);
+ P2C(netif_fe_interface_status_changed_t, mac[1], u8);
+ P2C(netif_fe_interface_status_changed_t, mac[2], u8);
+ P2C(netif_fe_interface_status_changed_t, mac[3], u8);
+ P2C(netif_fe_interface_status_changed_t, mac[4], u8);
+ P2C(netif_fe_interface_status_changed_t, mac[5], u8);
+ break;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
+ P2C(netif_be_create_t, domid, u32);
+ P2C(netif_be_create_t, netif_handle, u32);
+ P2C(netif_be_create_t, mac[0], u8);
+ P2C(netif_be_create_t, mac[1], u8);
+ P2C(netif_be_create_t, mac[2], u8);
+ P2C(netif_be_create_t, mac[3], u8);
+ P2C(netif_be_create_t, mac[4], u8);
+ P2C(netif_be_create_t, mac[5], u8);
+ break;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
+ P2C(netif_be_destroy_t, domid, u32);
+ P2C(netif_be_destroy_t, netif_handle, u32);
+ break;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
+ P2C(netif_be_connect_t, domid, u32);
+ P2C(netif_be_connect_t, netif_handle, u32);
+ P2C(netif_be_connect_t, tx_shmem_frame, memory_t);
+ P2C(netif_be_connect_t, rx_shmem_frame, memory_t);
+ P2C(netif_be_connect_t, evtchn, u16);
+ break;
+ case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
+ P2C(netif_be_disconnect_t, domid, u32);
+ P2C(netif_be_disconnect_t, netif_handle, u32);
+ break;
+ case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
+ P2C(netif_fe_driver_status_changed_t, status, u32);
+ P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
+ break;
+ }
+
+ if ( dict_items_parsed != PyDict_Size(payload) )
+ {
+ PyErr_SetString(PyExc_TypeError, "payload contains bad items");
+ PyObject_Del((PyObject *)xum);
+ return NULL;
+ }
+
+ return (PyObject *)xum;
+}
+
+static PyObject *xu_message_getattr(PyObject *obj, char *name)
+{
+ xu_message_object *xum;
+ if ( strcmp(name, "MAX_PAYLOAD") == 0 )
+ return PyInt_FromLong(sizeof(xum->msg.msg));
+ return Py_FindMethod(xu_message_methods, obj, name);
+}
+
+static void xu_message_dealloc(PyObject *self)
+{
+ PyObject_Del(self);
+}
+
+static PyTypeObject xu_message_type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "message",
+ sizeof(xu_message_object),
+ 0,
+ xu_message_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ xu_message_getattr, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL /* tp_hash */
+};
+
+
+
+/*
+ * *********************** PORT ***********************
+ */
+
+static control_if_t *map_control_interface(int fd, unsigned long pfn)
+{
+ char *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, pfn * PAGE_SIZE);
+ if ( vaddr == MAP_FAILED )
+ return NULL;
+ return (control_if_t *)(vaddr + 2048);
+}
+static void unmap_control_interface(int fd, control_if_t *c)
+{
+ char *vaddr = (char *)c - 2048;
+ (void)munmap(vaddr, PAGE_SIZE);
+}
+
+typedef struct xu_port_object {
+ PyObject_HEAD;
+ int mem_fd;
+ int xc_handle;
+ u32 remote_dom;
+ int local_port, remote_port;
+ control_if_t *interface;
+ CONTROL_RING_IDX tx_req_cons, tx_resp_prod;
+ CONTROL_RING_IDX rx_req_prod, rx_resp_cons;
+} xu_port_object;
+
+static PyObject *port_error;
+
+static int xup_connect(xu_port_object *xup, domid_t dom,
+ int local_port, int remote_port){
+ // From our prespective rx = producer, tx = consumer.
+ int err = 0;
+ printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom,
+ local_port, remote_port);
+
+ // Consumer = tx.
+ //xup->interface->tx_resp_prod = 0;
+ //xup->interface->tx_req_prod = 0;
+ xup->tx_resp_prod = xup->interface->tx_resp_prod;
+ xup->tx_req_cons = xup->interface->tx_resp_prod;
+ printf("%s> tx: %u %u : %u %u\n", __FUNCTION__,
+ (unsigned int)xup->interface->tx_resp_prod,
+ (unsigned int)xup->tx_resp_prod,
+ (unsigned int)xup->tx_req_cons,
+ (unsigned int)xup->interface->tx_req_prod);
+
+ // Producer = rx.
+ //xup->interface->rx_req_prod = 0;
+ //xup->interface->rx_resp_prod = 0;
+ xup->rx_req_prod = xup->interface->rx_req_prod;
+ xup->rx_resp_cons = xup->interface->rx_resp_prod;
+ printf("%s> rx: %u %u : %u %u\n", __FUNCTION__,
+ (unsigned int)xup->rx_resp_cons,
+ (unsigned int)xup->interface->rx_resp_prod,
+ (unsigned int)xup->interface->rx_req_prod,
+ (unsigned int)xup->rx_req_prod);
+
+ xup->remote_dom = dom;
+ xup->local_port = local_port;
+ xup->remote_port = remote_port;
+
+ printf("%s< err=%d\n", __FUNCTION__, err);
+ return err;
+}
+
+static PyObject *xu_port_notify(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ (void)xc_evtchn_send(xup->xc_handle, xup->local_port);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_port_read_request(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ xu_message_object *xum;
+ CONTROL_RING_IDX c = xup->tx_req_cons;
+ control_if_t *cif = xup->interface;
+ control_msg_t *cmsg;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( (c == cif->tx_req_prod) ||
+ ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
+ {
+ PyErr_SetString(port_error, "no request to read");
+ return NULL;
+ }
+
+ cmsg = &cif->tx_ring[MASK_CONTROL_IDX(c)];
+ xum = PyObject_New(xu_message_object, &xu_message_type);
+ memcpy(&xum->msg, cmsg, sizeof(*cmsg));
+ if ( xum->msg.length > sizeof(xum->msg.msg) )
+ xum->msg.length = sizeof(xum->msg.msg);
+ xup->tx_req_cons++;
+ return (PyObject *)xum;
+}
+
+static PyObject *xu_port_write_request(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ xu_message_object *xum;
+ CONTROL_RING_IDX p = xup->rx_req_prod;
+ control_if_t *cif = xup->interface;
+ control_msg_t *cmsg;
+
+ if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
+ return NULL;
+
+ if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
+ {
+ PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
+ return NULL;
+ }
+
+ if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
+ {
+ PyErr_SetString(port_error, "no space to write request");
+ return NULL;
+ }
+
+ cmsg = &cif->rx_ring[MASK_CONTROL_IDX(p)];
+ memcpy(cmsg, &xum->msg, sizeof(*cmsg));
+
+ xup->rx_req_prod = cif->rx_req_prod = p + 1;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_port_read_response(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ xu_message_object *xum;
+ CONTROL_RING_IDX c = xup->rx_resp_cons;
+ control_if_t *cif = xup->interface;
+ control_msg_t *cmsg;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
+ {
+ PyErr_SetString(port_error, "no response to read");
+ return NULL;
+ }
+
+ cmsg = &cif->rx_ring[MASK_CONTROL_IDX(c)];
+ xum = PyObject_New(xu_message_object, &xu_message_type);
+ memcpy(&xum->msg, cmsg, sizeof(*cmsg));
+ if ( xum->msg.length > sizeof(xum->msg.msg) )
+ xum->msg.length = sizeof(xum->msg.msg);
+ xup->rx_resp_cons++;
+ return (PyObject *)xum;
+}
+
+static PyObject *xu_port_write_response(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ xu_message_object *xum;
+ CONTROL_RING_IDX p = xup->tx_resp_prod;
+ control_if_t *cif = xup->interface;
+ control_msg_t *cmsg;
+
+ if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
+ return NULL;
+
+ if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
+ {
+ PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
+ return NULL;
+ }
+
+ if ( p == xup->tx_req_cons )
+ {
+ PyErr_SetString(port_error, "no space to write response");
+ return NULL;
+ }
+
+ cmsg = &cif->tx_ring[MASK_CONTROL_IDX(p)];
+ memcpy(cmsg, &xum->msg, sizeof(*cmsg));
+
+ xup->tx_resp_prod = cif->tx_resp_prod = p + 1;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *xu_port_request_to_read(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ CONTROL_RING_IDX c = xup->tx_req_cons;
+ control_if_t *cif = xup->interface;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( (c == cif->tx_req_prod) ||
+ ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
+ return PyInt_FromLong(0);
+
+ return PyInt_FromLong(1);
+}
+
+static PyObject *xu_port_space_to_write_request(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ CONTROL_RING_IDX p = xup->rx_req_prod;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
+ return PyInt_FromLong(0);
+
+ return PyInt_FromLong(1);
+}
+
+static PyObject *xu_port_response_to_read(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ CONTROL_RING_IDX c = xup->rx_resp_cons;
+ control_if_t *cif = xup->interface;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
+ return PyInt_FromLong(0);
+
+ return PyInt_FromLong(1);
+}
+
+static PyObject *xu_port_space_to_write_response(
+ PyObject *self, PyObject *args)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ CONTROL_RING_IDX p = xup->tx_resp_prod;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( p == xup->tx_req_cons )
+ return PyInt_FromLong(0);
+
+ return PyInt_FromLong(1);
+}
+
+static PyMethodDef xu_port_methods[] = {
+ { "notify",
+ (PyCFunction)xu_port_notify,
+ METH_VARARGS,
+ "Send a notification to the remote end.\n" },
+
+ { "read_request",
+ (PyCFunction)xu_port_read_request,
+ METH_VARARGS,
+ "Read a request message from the control interface.\n" },
+
+ { "write_request",
+ (PyCFunction)xu_port_write_request,
+ METH_VARARGS,
+ "Write a request message to the control interface.\n" },
+
+ { "read_response",
+ (PyCFunction)xu_port_read_response,
+ METH_VARARGS,
+ "Read a response message from the control interface.\n" },
+
+ { "write_response",
+ (PyCFunction)xu_port_write_response,
+ METH_VARARGS,
+ "Write a response message to the control interface.\n" },
+
+ { "request_to_read",
+ (PyCFunction)xu_port_request_to_read,
+ METH_VARARGS,
+ "Returns TRUE if there is a request message to read.\n" },
+
+ { "space_to_write_request",
+ (PyCFunction)xu_port_space_to_write_request,
+ METH_VARARGS,
+ "Returns TRUE if there is space to write a request message.\n" },
+
+ { "response_to_read",
+ (PyCFunction)xu_port_response_to_read,
+ METH_VARARGS,
+ "Returns TRUE if there is a response message to read.\n" },
+
+ { "space_to_write_response",
+ (PyCFunction)xu_port_space_to_write_response,
+ METH_VARARGS,
+ "Returns TRUE if there is space to write a response message.\n" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+staticforward PyTypeObject xu_port_type;
+
+static PyObject *xu_port_new(PyObject *self, PyObject *args)
+{
+ xu_port_object *xup;
+ u32 dom;
+ int port1, port2;
+ xc_dominfo_t info;
+
+ if ( !PyArg_ParseTuple(args, "i", &dom) )
+ return NULL;
+
+ xup = PyObject_New(xu_port_object, &xu_port_type);
+
+ if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
+ {
+ PyErr_SetString(port_error, "Could not open '/dev/mem'");
+ goto fail1;
+ }
+
+ /* Set the General-Purpose Subject whose page frame will be mapped. */
+ (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom);
+
+ if ( (xup->xc_handle = xc_interface_open()) == -1 )
+ {
+ PyErr_SetString(port_error, "Could not open Xen control interface");
+ goto fail2;
+ }
+
+ if ( dom == 0 )
+ {
+ /*
+ * The control-interface event channel for DOM0 is already set up.
+ * We use an ioctl to discover the port at our end of the channel.
+ */
+ port1 = ioctl(xup->xc_handle, IOCTL_PRIVCMD_INITDOMAIN_EVTCHN, NULL);
+ port2 = -1; /* We don't need the remote end of the DOM0 link. */
+ if ( port1 < 0 )
+ {
+ PyErr_SetString(port_error, "Could not open channel to DOM0");
+ goto fail3;
+ }
+ }
+ else if ( xc_evtchn_bind_interdomain(xup->xc_handle,
+ DOMID_SELF, dom,
+ &port1, &port2) != 0 )
+ {
+ PyErr_SetString(port_error, "Could not open channel to domain");
+ goto fail3;
+ }
+
+ if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) ||
+ (info.domid != dom) )
+ {
+ PyErr_SetString(port_error, "Failed to obtain domain status");
+ goto fail4;
+ }
+
+ xup->interface =
+ map_control_interface(xup->mem_fd, info.shared_info_frame);
+ if ( xup->interface == NULL )
+ {
+ PyErr_SetString(port_error, "Failed to map domain control interface");
+ goto fail4;
+ }
+
+ xup_connect(xup, dom, port1, port2);
+ return (PyObject *)xup;
+
+
+ fail4:
+ (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
+ fail3:
+ (void)xc_interface_close(xup->xc_handle);
+ fail2:
+ (void)close(xup->mem_fd);
+ fail1:
+ PyObject_Del((PyObject *)xup);
+ return NULL;
+}
+
+static PyObject *xu_port_getattr(PyObject *obj, char *name)
+{
+ xu_port_object *xup = (xu_port_object *)obj;
+ if ( strcmp(name, "local_port") == 0 )
+ return PyInt_FromLong(xup->local_port);
+ if ( strcmp(name, "remote_port") == 0 )
+ return PyInt_FromLong(xup->remote_port);
+ if ( strcmp(name, "remote_dom") == 0 )
+ return PyInt_FromLong(xup->remote_dom);
+ return Py_FindMethod(xu_port_methods, obj, name);
+}
+
+static void xu_port_dealloc(PyObject *self)
+{
+ xu_port_object *xup = (xu_port_object *)self;
+ unmap_control_interface(xup->mem_fd, xup->interface);
+ if ( xup->remote_dom != 0 )
+ (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
+ (void)xc_interface_close(xup->xc_handle);
+ (void)close(xup->mem_fd);
+ PyObject_Del(self);
+}
+
+static PyTypeObject xu_port_type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "port",
+ sizeof(xu_port_object),
+ 0,
+ xu_port_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ xu_port_getattr, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL /* tp_hash */
+};
+
+
+
+/*
+ * *********************** BUFFER ***********************
+ */
+
+#define BUFSZ 65536
+#define MASK_BUF_IDX(_i) ((_i)&(BUFSZ-1))
+typedef unsigned int BUF_IDX;
+
+typedef struct {
+ PyObject_HEAD;
+ char *buf;
+ unsigned int prod, cons;
+} xu_buffer_object;
+
+static PyObject *__xu_buffer_peek(xu_buffer_object *xub, int max)
+{
+ PyObject *str1, *str2;
+ int len1, len2, c = MASK_BUF_IDX(xub->cons);
+
+ len1 = xub->prod - xub->cons;
+ if ( len1 > (BUFSZ - c) ) /* clip to ring wrap */
+ len1 = BUFSZ - c;
+ if ( len1 > max ) /* clip to specified maximum */
+ len1 = max;
+ if ( len1 < 0 ) /* sanity */
+ len1 = 0;
+
+ if ( (str1 = PyString_FromStringAndSize(&xub->buf[c], len1)) == NULL )
+ return NULL;
+
+ if ( (len1 < (xub->prod - xub->cons)) && (len1 < max) )
+ {
+ len2 = max - len1;
+ if ( len2 > MASK_BUF_IDX(xub->prod) )
+ len2 = MASK_BUF_IDX(xub->prod);
+ if ( len2 > 0 )
+ {
+ str2 = PyString_FromStringAndSize(&xub->buf[0], len2);
+ if ( str2 == NULL )
+ return NULL;
+ PyString_ConcatAndDel(&str1, str2);
+ if ( str1 == NULL )
+ return NULL;
+ }
+ }
+
+ return str1;
+}
+
+static PyObject *xu_buffer_peek(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+ int max = 1024;
+
+ if ( !PyArg_ParseTuple(args, "|i", &max) )
+ return NULL;
+
+ return __xu_buffer_peek(xub, max);
+}
+
+static PyObject *xu_buffer_read(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+ PyObject *str;
+ int max = 1024;
+
+ if ( !PyArg_ParseTuple(args, "|i", &max) )
+ return NULL;
+
+ if ( (str = __xu_buffer_peek(xub, max)) != NULL )
+ xub->cons += PyString_Size(str);
+
+ return str;
+}
+
+static PyObject *xu_buffer_discard(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+ int max, len;
+
+ if ( !PyArg_ParseTuple(args, "i", &max) )
+ return NULL;
+
+ len = xub->prod - xub->cons;
+ if ( len > max )
+ len = max;
+ if ( len < 0 )
+ len = 0;
+
+ xub->cons += len;
+
+ return PyInt_FromLong(len);
+}
+
+static PyObject *xu_buffer_write(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+ char *str;
+ int len, len1, len2;
+
+ if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
+ return NULL;
+
+ len1 = len;
+ if ( len1 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
+ len1 = BUFSZ - MASK_BUF_IDX(xub->prod);
+ if ( len1 > (BUFSZ - (xub->prod - xub->cons)) )
+ len1 = BUFSZ - (xub->prod - xub->cons);
+
+ if ( len1 == 0 )
+ return PyInt_FromLong(0);
+
+ memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[0], len1);
+ xub->prod += len1;
+
+ if ( len1 < len )
+ {
+ len2 = len - len1;
+ if ( len2 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
+ len2 = BUFSZ - MASK_BUF_IDX(xub->prod);
+ if ( len2 > (BUFSZ - (xub->prod - xub->cons)) )
+ len2 = BUFSZ - (xub->prod - xub->cons);
+ if ( len2 != 0 )
+ {
+ memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[len1], len2);
+ xub->prod += len2;
+ return PyInt_FromLong(len1 + len2);
+ }
+ }
+
+ return PyInt_FromLong(len1);
+}
+
+static PyObject *xu_buffer_empty(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( xub->cons == xub->prod )
+ return PyInt_FromLong(1);
+
+ return PyInt_FromLong(0);
+}
+
+static PyObject *xu_buffer_full(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ if ( (xub->prod - xub->cons) == BUFSZ )
+ return PyInt_FromLong(1);
+
+ return PyInt_FromLong(0);
+}
+
+static PyMethodDef xu_buffer_methods[] = {
+ { "peek",
+ (PyCFunction)xu_buffer_peek,
+ METH_VARARGS,
+ "Peek up to @max bytes from the buffer. Returns a string.\n" },
+
+ { "read",
+ (PyCFunction)xu_buffer_read,
+ METH_VARARGS,
+ "Read up to @max bytes from the buffer. Returns a string.\n" },
+
+ { "discard",
+ (PyCFunction)xu_buffer_discard,
+ METH_VARARGS,
+ "Discard up to @max bytes from the buffer. Returns number of bytes.\n" },
+
+ { "write",
+ (PyCFunction)xu_buffer_write,
+ METH_VARARGS,
+ "Write @string into buffer. Return number of bytes written.\n" },
+
+ { "empty",
+ (PyCFunction)xu_buffer_empty,
+ METH_VARARGS,
+ "Return TRUE if the buffer is empty.\n" },
+
+ { "full",
+ (PyCFunction)xu_buffer_full,
+ METH_VARARGS,
+ "Return TRUE if the buffer is full.\n" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+staticforward PyTypeObject xu_buffer_type;
+
+static PyObject *xu_buffer_new(PyObject *self, PyObject *args)
+{
+ xu_buffer_object *xub;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ xub = PyObject_New(xu_buffer_object, &xu_buffer_type);
+
+ if ( (xub->buf = malloc(BUFSZ)) == NULL )
+ {
+ PyObject_Del((PyObject *)xub);
+ return NULL;
+ }
+
+ xub->prod = xub->cons = 0;
+
+ return (PyObject *)xub;
+}
+
+static PyObject *xu_buffer_getattr(PyObject *obj, char *name)
+{
+ return Py_FindMethod(xu_buffer_methods, obj, name);
+}
+
+static void xu_buffer_dealloc(PyObject *self)
+{
+ xu_buffer_object *xub = (xu_buffer_object *)self;
+ free(xub->buf);
+ PyObject_Del(self);
+}
+
+static PyTypeObject xu_buffer_type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "buffer",
+ sizeof(xu_buffer_object),
+ 0,
+ xu_buffer_dealloc, /* tp_dealloc */
+ NULL, /* tp_print */
+ xu_buffer_getattr, /* tp_getattr */
+ NULL, /* tp_setattr */
+ NULL, /* tp_compare */
+ NULL, /* tp_repr */
+ NULL, /* tp_as_number */
+ NULL, /* tp_as_sequence */
+ NULL, /* tp_as_mapping */
+ NULL /* tp_hash */
+};
+
+
+
+/*
+ * *********************** MODULE WRAPPER ***********************
+ */
+
+static void handle_child_death(int dummy)
+{
+ while ( waitpid(-1, NULL, WNOHANG) > 0 )
+ continue;
+}
+
+static PyObject *xu_autoreap(PyObject *self, PyObject *args)
+{
+ struct sigaction sa;
+
+ if ( !PyArg_ParseTuple(args, "") )
+ return NULL;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = handle_child_death;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+ (void)sigaction(SIGCHLD, &sa, NULL);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef xu_methods[] = {
+ { "notifier", xu_notifier_new, METH_VARARGS,
+ "Create a new notifier." },
+ { "message", xu_message_new, METH_VARARGS,
+ "Create a new communications message." },
+ { "port", xu_port_new, METH_VARARGS,
+ "Create a new communications port." },
+ { "buffer", xu_buffer_new, METH_VARARGS,
+ "Create a new ring buffer." },
+ { "autoreap", xu_autoreap, METH_VARARGS,
+ "Ensure that zombie children are automatically reaped by the OS." },
+ { NULL, NULL, 0, NULL }
+};
+
+PyMODINIT_FUNC initxu(void)
+{
+ PyObject *m, *d;
+
+ m = Py_InitModule(XENPKG, xu_methods);
+
+ d = PyModule_GetDict(m);
+ port_error = PyErr_NewException(XENPKG ".PortError", NULL, NULL);
+ PyDict_SetItemString(d, "PortError", port_error);
+}
diff --git a/tools/xu/setup.py b/tools/xu/setup.py
new file mode 100644
index 0000000000..e342c78a14
--- /dev/null
+++ b/tools/xu/setup.py
@@ -0,0 +1,19 @@
+
+from distutils.core import setup, Extension
+
+xu = Extension("xu",
+ extra_compile_args = ["-fno-strict-aliasing"],
+ include_dirs = ["../xc/lib",
+ "../../xen/include/hypervisor-ifs",
+ "../../linux-xen-sparse/include"],
+ library_dirs = ["../xc/lib"],
+ libraries = ["xc"],
+ sources = ["lib/xu.c"])
+
+setup(name = "xu",
+ version = "1.0",
+ #packages = ["xend"],
+ #package_dir = { "xend" : "lib" },
+ ext_package = "xen.ext",
+ ext_modules = [ xu ]
+ )