diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/Makefile | 13 | ||||
| -rw-r--r-- | tools/misc/Makefile | 2 | ||||
| -rw-r--r-- | tools/xc/lib/Makefile | 2 | ||||
| -rw-r--r-- | tools/xc/py/Xc.c | 214 | ||||
| -rw-r--r-- | tools/xc/py/setup.py | 7 | ||||
| -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__.py | 1 | ||||
| -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-x | tools/xen/lib/xend/server/blkif.py (renamed from tools/xenmgr/lib/server/blkif.py) | 4 | ||||
| -rwxr-xr-x | tools/xen/lib/xend/server/channel.py (renamed from tools/xenmgr/lib/server/channel.py) | 8 | ||||
| -rwxr-xr-x | tools/xen/lib/xend/server/console.py (renamed from tools/xenmgr/lib/server/console.py) | 10 | ||||
| -rwxr-xr-x | tools/xen/lib/xend/server/controller.py (renamed from tools/xenmgr/lib/server/controller.py) | 0 | ||||
| -rwxr-xr-x | tools/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-x | tools/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.py | 16 | ||||
| -rw-r--r-- | tools/xen/xend (renamed from tools/xenmgr/xend) | 4 | ||||
| -rwxr-xr-x | tools/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-x | tools/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-x | tools/xend-old/xend (renamed from tools/xend/xend) | 0 | ||||
| -rw-r--r-- | tools/xenmgr/setup.py | 14 | ||||
| -rwxr-xr-x | tools/xenmgr/xenmgrd | 10 | ||||
| -rw-r--r-- | tools/xentrace/Makefile | 2 | ||||
| -rw-r--r-- | tools/xu/lib/__init__.py | 0 | ||||
| -rw-r--r-- | tools/xu/lib/domain_controller.h | 532 | ||||
| -rw-r--r-- | tools/xu/lib/xu.c | 1386 | ||||
| -rw-r--r-- | tools/xu/setup.py | 19 |
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 ] + ) |
