ia64/xen-unstable

changeset 1629:0f7bf86dedaf

bitkeeper revision 1.1034 (40e28d7bx0XoTn2USwCDCvPvUTLZjQ)

Rename ext to lowlevel.
author mjw@wray-m-3.hpl.hp.com
date Wed Jun 30 09:52:59 2004 +0000 (2004-06-30)
parents 89c33a00a968
children 2d62e75bbaea
files .rootkeys tools/Make.defs tools/python/setup.py tools/python/xen/ext/__init__.py tools/python/xen/ext/xc/Makefile tools/python/xen/ext/xc/setup.py tools/python/xen/ext/xc/xc.c tools/python/xen/ext/xu/__init__.py tools/python/xen/ext/xu/domain_controller.h tools/python/xen/ext/xu/xu.c tools/python/xen/lowlevel/__init__.py tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xu/__init__.py tools/python/xen/lowlevel/xu/domain_controller.h tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/XendConsole.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/console.py tools/python/xen/xend/server/messages.py
line diff
     1.1 --- a/.rootkeys	Tue Jun 29 21:08:51 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jun 30 09:52:59 2004 +0000
     1.3 @@ -240,13 +240,11 @@ 40cf2937dqM1jWW87O5OoOYND8leuA tools/mis
     1.4  40c9c468icGyC5RAF1bRKsCXPDCvsA tools/python/Makefile
     1.5  40c9c469n2RRwCmjWdjdyyVRWKmgWg tools/python/setup.py
     1.6  40dc4076hGpwa8-sWRN0jtXZeQJuKg tools/python/xen/__init__.py
     1.7 -40dfd40aMOhnw_cQLve9462UR5yYxQ tools/python/xen/ext/__init__.py
     1.8 -3fbd0a3dTwnDcfdw0-v46dPbX98zDw tools/python/xen/ext/xc/Makefile
     1.9 -3fbd0a40yT6G3M9hMpaz5xTUdl0E4g tools/python/xen/ext/xc/setup.py
    1.10 -3fbd0a42l40lM0IICw2jXbQBVZSdZg tools/python/xen/ext/xc/xc.c
    1.11 -40dc4076St6AmPTmQPrtQ6LGHPxGmw tools/python/xen/ext/xu/__init__.py
    1.12 -40dc4076pVeE1kEEWzcUaNZin65kCA tools/python/xen/ext/xu/domain_controller.h
    1.13 -40dc4076CwBYRTUQDdbdU1L6KcLgSw tools/python/xen/ext/xu/xu.c
    1.14 +40dfd40aMOhnw_cQLve9462UR5yYxQ tools/python/xen/lowlevel/__init__.py
    1.15 +3fbd0a42l40lM0IICw2jXbQBVZSdZg tools/python/xen/lowlevel/xc/xc.c
    1.16 +40dc4076St6AmPTmQPrtQ6LGHPxGmw tools/python/xen/lowlevel/xu/__init__.py
    1.17 +40dc4076pVeE1kEEWzcUaNZin65kCA tools/python/xen/lowlevel/xu/domain_controller.h
    1.18 +40dc4076CwBYRTUQDdbdU1L6KcLgSw tools/python/xen/lowlevel/xu/xu.c
    1.19  40d8915cyoVA0hJxiBFNymL7YvDaRg tools/python/xen/util/Brctl.py
    1.20  40dfd40aGqGkiopOOgJxSF4iCbHM0Q tools/python/xen/util/__init__.py
    1.21  4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/python/xen/util/console_client.py
     2.1 --- a/tools/Make.defs	Tue Jun 29 21:08:51 2004 +0000
     2.2 +++ b/tools/Make.defs	Wed Jun 30 09:52:59 2004 +0000
     2.3 @@ -1,7 +1,7 @@
     2.4  #  -*- mode: Makefile; -*-
     2.5  XEN_HYPERVISOR_IFS = $(XEN_ROOT)/xen/include/hypervisor-ifs
     2.6  XEN_LINUX_INCLUDE  = $(XEN_ROOT)/linux-xen-sparse/include
     2.7 -XEN_XU             = $(XEN_ROOT)/tools/python/xen/ext/xu
     2.8 -XEN_XC             = $(XEN_ROOT)/tools/python/xen/ext/xc
     2.9 +XEN_XU             = $(XEN_ROOT)/tools/python/xen/lowlevel/xu
    2.10 +XEN_XC             = $(XEN_ROOT)/tools/python/xen/lowlevel/xc
    2.11  XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
    2.12  XEN_LIBXUTIL       = $(XEN_ROOT)/tools/libxutil
     3.1 --- a/tools/python/setup.py	Tue Jun 29 21:08:51 2004 +0000
     3.2 +++ b/tools/python/setup.py	Wed Jun 30 09:52:59 2004 +0000
     3.3 @@ -8,7 +8,7 @@ extra_compile_args  = [ "-fno-strict-ali
     3.4  
     3.5  include_dirs = [ XEN_ROOT + "/xen/include/hypervisor-ifs",
     3.6                   XEN_ROOT + "/linux-xen-sparse/include",
     3.7 -                 XEN_ROOT + "/tools/python/xen/ext/xu",
     3.8 +                 XEN_ROOT + "/tools/python/xen/lowlevel/xu",
     3.9                   XEN_ROOT + "/tools/libxc",
    3.10                   XEN_ROOT + "/tools/libxutil",
    3.11                   ]
    3.12 @@ -21,28 +21,28 @@ libraries = [ "xc", "xutil" ]
    3.13  
    3.14  xc = Extension("xc",
    3.15                 extra_compile_args = extra_compile_args,
    3.16 -               include_dirs       = include_dirs + [ "xen/ext/xc" ],
    3.17 +               include_dirs       = include_dirs + [ "xen/lowlevel/xc" ],
    3.18                 library_dirs       = library_dirs,
    3.19                 libraries          = libraries,
    3.20 -               sources            = [ "xen/ext/xc/xc.c" ])
    3.21 +               sources            = [ "xen/lowlevel/xc/xc.c" ])
    3.22  
    3.23  xu = Extension("xu",
    3.24                 extra_compile_args = extra_compile_args,
    3.25 -               include_dirs       = include_dirs + [ "xen/ext/xu" ],
    3.26 +               include_dirs       = include_dirs + [ "xen/lowlevel/xu" ],
    3.27                 library_dirs       = library_dirs,
    3.28                 libraries          = libraries,
    3.29 -               sources            = [ "xen/ext/xu/xu.c" ])
    3.30 +               sources            = [ "xen/lowlevel/xu/xu.c" ])
    3.31                 
    3.32  setup(name            = 'xen',
    3.33        version         = '2.0',
    3.34        description     = 'Xen',
    3.35        packages        = ['xen',
    3.36 -                         'xen.ext',
    3.37 +                         'xen.lowlevel',
    3.38                           'xen.util',
    3.39                           'xen.xend',
    3.40                           'xen.xend.server',
    3.41                           'xen.xm',
    3.42                           ],
    3.43 -      ext_package = "xen.ext",
    3.44 +      ext_package = "xen.lowlevel",
    3.45        ext_modules = [ xc, xu ]
    3.46        )
     4.1 --- a/tools/python/xen/ext/__init__.py	Tue Jun 29 21:08:51 2004 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,1 +0,0 @@
     4.4 - 
     5.1 --- a/tools/python/xen/ext/xc/Makefile	Tue Jun 29 21:08:51 2004 +0000
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,15 +0,0 @@
     5.4 -
     5.5 -all:
     5.6 -	python setup.py build
     5.7 -
     5.8 -install: all
     5.9 -	if [ "$(prefix)" = "" ]; then                   \
    5.10 -	    python setup.py install;                    \
    5.11 -	elif [ "$(dist)" = "yes" ]; then                \
    5.12 -	    python setup.py install --home="$(prefix)"; \
    5.13 -	else                                            \
    5.14 -	    python setup.py install --root="$(prefix)"; \
    5.15 -	fi
    5.16 -
    5.17 -clean:
    5.18 -	rm -rf build *.pyc *.pyo *.o *.a *~
     6.1 --- a/tools/python/xen/ext/xc/setup.py	Tue Jun 29 21:08:51 2004 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,19 +0,0 @@
     6.4 -
     6.5 -from distutils.core import setup, Extension
     6.6 -
     6.7 -module = Extension("xc",
     6.8 -                   extra_compile_args   = ["-fno-strict-aliasing"],
     6.9 -                   include_dirs         = ["../lib",
    6.10 -                                           "../../../xen/include/hypervisor-ifs",
    6.11 -                                           "../../../linux-xen-sparse/include",
    6.12 -                                           "../../xu/lib",
    6.13 -                                           "../../lib" ],
    6.14 -                   library_dirs         = ["../lib",
    6.15 -                                           "../../lib" ],
    6.16 -                   libraries            = ["xc"],
    6.17 -                   sources              = ["Xc.c"])
    6.18 -
    6.19 -setup(name = "xc",
    6.20 -      version = "2.0",
    6.21 -      ext_package = "xen.ext",
    6.22 -      ext_modules = [module])
     7.1 --- a/tools/python/xen/ext/xc/xc.c	Tue Jun 29 21:08:51 2004 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,1184 +0,0 @@
     7.4 -/******************************************************************************
     7.5 - * Xc.c
     7.6 - * 
     7.7 - * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
     7.8 - */
     7.9 -
    7.10 -#include <Python.h>
    7.11 -#include <xc.h>
    7.12 -#include <zlib.h>
    7.13 -#include <fcntl.h>
    7.14 -#include <netinet/in.h>
    7.15 -#include <netinet/tcp.h>
    7.16 -#include <sys/types.h>
    7.17 -#include <sys/socket.h>
    7.18 -#include <netdb.h>
    7.19 -#include <arpa/inet.h>
    7.20 -#include "xc_private.h"
    7.21 -#include "gzip_stream.h"
    7.22 -
    7.23 -/* Needed for Python versions earlier than 2.3. */
    7.24 -#ifndef PyMODINIT_FUNC
    7.25 -#define PyMODINIT_FUNC DL_EXPORT(void)
    7.26 -#endif
    7.27 -
    7.28 -#define XENPKG "xen.ext.xc"
    7.29 -
    7.30 -static PyObject *xc_error, *zero;
    7.31 -
    7.32 -typedef struct {
    7.33 -    PyObject_HEAD;
    7.34 -    int xc_handle;
    7.35 -} XcObject;
    7.36 -
    7.37 -/*
    7.38 - * Definitions for the 'xc' object type.
    7.39 - */
    7.40 -
    7.41 -static PyObject *pyxc_domain_create(PyObject *self,
    7.42 -                                    PyObject *args,
    7.43 -                                    PyObject *kwds)
    7.44 -{
    7.45 -    XcObject *xc = (XcObject *)self;
    7.46 -
    7.47 -    unsigned int mem_kb = 0;
    7.48 -    char        *name   = "(anon)";
    7.49 -    int          cpu = -1;
    7.50 -    u32          dom;
    7.51 -    int          ret;
    7.52 -
    7.53 -    static char *kwd_list[] = { "mem_kb", "name", "cpu", NULL };
    7.54 -
    7.55 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|isi", kwd_list, 
    7.56 -                                      &mem_kb, &name, &cpu) )
    7.57 -        return NULL;
    7.58 -
    7.59 -    if ( (ret = xc_domain_create(xc->xc_handle, mem_kb, name, cpu, &dom)) < 0 )
    7.60 -        return PyErr_SetFromErrno(xc_error);
    7.61 -
    7.62 -    return PyInt_FromLong(dom);
    7.63 -}
    7.64 -
    7.65 -static PyObject *pyxc_domain_pause(PyObject *self,
    7.66 -                                   PyObject *args,
    7.67 -                                   PyObject *kwds)
    7.68 -{
    7.69 -    XcObject *xc = (XcObject *)self;
    7.70 -
    7.71 -    u32 dom;
    7.72 -
    7.73 -    static char *kwd_list[] = { "dom", NULL };
    7.74 -
    7.75 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
    7.76 -        return NULL;
    7.77 -
    7.78 -    if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
    7.79 -        return PyErr_SetFromErrno(xc_error);
    7.80 -    
    7.81 -    Py_INCREF(zero);
    7.82 -    return zero;
    7.83 -}
    7.84 -
    7.85 -static PyObject *pyxc_domain_unpause(PyObject *self,
    7.86 -                                     PyObject *args,
    7.87 -                                     PyObject *kwds)
    7.88 -{
    7.89 -    XcObject *xc = (XcObject *)self;
    7.90 -
    7.91 -    u32 dom;
    7.92 -
    7.93 -    static char *kwd_list[] = { "dom", NULL };
    7.94 -
    7.95 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
    7.96 -        return NULL;
    7.97 -
    7.98 -    if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
    7.99 -        return PyErr_SetFromErrno(xc_error);
   7.100 -    
   7.101 -    Py_INCREF(zero);
   7.102 -    return zero;
   7.103 -}
   7.104 -
   7.105 -static PyObject *pyxc_domain_destroy(PyObject *self,
   7.106 -                                     PyObject *args,
   7.107 -                                     PyObject *kwds)
   7.108 -{
   7.109 -    XcObject *xc = (XcObject *)self;
   7.110 -
   7.111 -    u32 dom;
   7.112 -
   7.113 -    static char *kwd_list[] = { "dom", NULL };
   7.114 -
   7.115 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
   7.116 -        return NULL;
   7.117 -
   7.118 -    if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
   7.119 -        return PyErr_SetFromErrno(xc_error);
   7.120 -    
   7.121 -    Py_INCREF(zero);
   7.122 -    return zero;
   7.123 -}
   7.124 -
   7.125 -static PyObject *pyxc_domain_pincpu(PyObject *self,
   7.126 -                                    PyObject *args,
   7.127 -                                    PyObject *kwds)
   7.128 -{
   7.129 -    XcObject *xc = (XcObject *)self;
   7.130 -
   7.131 -    u32 dom;
   7.132 -    int cpu = -1;
   7.133 -
   7.134 -    static char *kwd_list[] = { "dom", "cpu", NULL };
   7.135 -
   7.136 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
   7.137 -                                      &dom, &cpu) )
   7.138 -        return NULL;
   7.139 -
   7.140 -    if ( xc_domain_pincpu(xc->xc_handle, dom, cpu) != 0 )
   7.141 -        return PyErr_SetFromErrno(xc_error);
   7.142 -    
   7.143 -    Py_INCREF(zero);
   7.144 -    return zero;
   7.145 -}
   7.146 -
   7.147 -static PyObject *pyxc_domain_getinfo(PyObject *self,
   7.148 -                                     PyObject *args,
   7.149 -                                     PyObject *kwds)
   7.150 -{
   7.151 -    XcObject *xc = (XcObject *)self;
   7.152 -    PyObject *list;
   7.153 -
   7.154 -    u32 first_dom = 0;
   7.155 -    int max_doms = 1024, nr_doms, i;
   7.156 -    xc_dominfo_t *info;
   7.157 -
   7.158 -    static char *kwd_list[] = { "first_dom", "max_doms", NULL };
   7.159 -    
   7.160 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
   7.161 -                                      &first_dom, &max_doms) )
   7.162 -        return NULL;
   7.163 -
   7.164 -    if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
   7.165 -        return PyErr_NoMemory();
   7.166 -
   7.167 -    nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
   7.168 -    
   7.169 -    list = PyList_New(nr_doms);
   7.170 -    for ( i = 0 ; i < nr_doms; i++ )
   7.171 -    {
   7.172 -        PyList_SetItem(
   7.173 -            list, i, 
   7.174 -            Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
   7.175 -                          ",s:l,s:L,s:s,s:l,s:i}",
   7.176 -                          "dom",       info[i].domid,
   7.177 -                          "cpu",       info[i].cpu,
   7.178 -                          "dying",     info[i].dying,
   7.179 -                          "crashed",   info[i].crashed,
   7.180 -                          "shutdown",  info[i].shutdown,
   7.181 -                          "paused",    info[i].paused,
   7.182 -                          "blocked",   info[i].blocked,
   7.183 -                          "running",   info[i].running,
   7.184 -                          "mem_kb",    info[i].nr_pages*4,
   7.185 -                          "cpu_time",  info[i].cpu_time,
   7.186 -                          "name",      info[i].name,
   7.187 -                          "maxmem_kb", info[i].max_memkb,
   7.188 -                          "shutdown_reason", info[i].shutdown_reason
   7.189 -                ));
   7.190 -    }
   7.191 -
   7.192 -    free(info);
   7.193 -
   7.194 -    return list;
   7.195 -}
   7.196 -
   7.197 -static int file_save(XcObject *xc, XcIOContext *ctxt, char *state_file)
   7.198 -{
   7.199 -    int rc = -1;
   7.200 -    int fd = -1;
   7.201 -    int open_flags = (O_CREAT | O_EXCL | O_WRONLY);
   7.202 -    int open_mode = 0644;
   7.203 -
   7.204 -    printf("%s>\n", __FUNCTION__);
   7.205 -
   7.206 -    if ( (fd = open(state_file, open_flags, open_mode)) < 0 )
   7.207 -    {
   7.208 -        xcio_perror(ctxt, "Could not open file for writing");
   7.209 -        goto exit;
   7.210 -    }
   7.211 -
   7.212 -    printf("%s>gzip_stream_fdopen... \n", __FUNCTION__);
   7.213 -
   7.214 -    /* Compression rate 1: we want speed over compression. 
   7.215 -     * We're mainly going for those zero pages, after all.
   7.216 -     */
   7.217 -    ctxt->io = gzip_stream_fdopen(fd, "wb1");
   7.218 -    if ( ctxt->io == NULL )
   7.219 -    {
   7.220 -        xcio_perror(ctxt, "Could not allocate compression state");
   7.221 -        goto exit;
   7.222 -    }
   7.223 -
   7.224 -    printf("%s> xc_linux_save...\n", __FUNCTION__);
   7.225 -
   7.226 -    rc = xc_linux_save(xc->xc_handle, ctxt);
   7.227 -
   7.228 -  exit:
   7.229 -    if ( ctxt->io != NULL )
   7.230 -        IOStream_close(ctxt->io);
   7.231 -    if ( fd >= 0 )
   7.232 -        close(fd);
   7.233 -    unlink(state_file);
   7.234 -    printf("%s> rc=%d\n", __FUNCTION__, rc);
   7.235 -    return rc;
   7.236 -}
   7.237 -
   7.238 -static PyObject *pyxc_linux_save(PyObject *self,
   7.239 -                                 PyObject *args,
   7.240 -                                 PyObject *kwds)
   7.241 -{
   7.242 -    XcObject *xc = (XcObject *)self;
   7.243 -
   7.244 -    char *state_file;
   7.245 -    int progress = 1, debug = 0;
   7.246 -    PyObject *val = NULL;
   7.247 -    int rc = -1;
   7.248 -    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
   7.249 -
   7.250 -    static char *kwd_list[] = { "dom", "state_file", "vmconfig", "progress", "debug", NULL };
   7.251 -
   7.252 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|sii", kwd_list, 
   7.253 -                                      &ioctxt.domain,
   7.254 -                                      &state_file,
   7.255 -                                      &ioctxt.vmconfig,
   7.256 -                                      &progress, 
   7.257 -                                      &debug) )
   7.258 -        goto exit;
   7.259 -
   7.260 -    ioctxt.vmconfig_n = (ioctxt.vmconfig ? strlen(ioctxt.vmconfig) : 0);
   7.261 -
   7.262 -    if ( progress )
   7.263 -        ioctxt.flags |= XCFLAGS_VERBOSE;
   7.264 -    if ( debug )
   7.265 -        ioctxt.flags |= XCFLAGS_DEBUG;
   7.266 -
   7.267 -    if ( (state_file == NULL) || (state_file[0] == '\0') )
   7.268 -        goto exit;
   7.269 -    
   7.270 -    rc = file_save(xc, &ioctxt, state_file);
   7.271 -    if ( rc != 0 )
   7.272 -    {
   7.273 -        PyErr_SetFromErrno(xc_error);
   7.274 -        goto exit;
   7.275 -    } 
   7.276 -
   7.277 -    Py_INCREF(zero);
   7.278 -    val = zero;
   7.279 -
   7.280 -  exit:
   7.281 -    return val;
   7.282 -}
   7.283 -
   7.284 -
   7.285 -static int file_restore(XcObject *xc, XcIOContext *ioctxt, char *state_file)
   7.286 -{
   7.287 -    int rc = -1;
   7.288 -
   7.289 -    ioctxt->io = gzip_stream_fopen(state_file, "rb");
   7.290 -    if ( ioctxt->io == NULL )
   7.291 -    {
   7.292 -        xcio_perror(ioctxt, "Could not open file for reading");
   7.293 -        return rc;
   7.294 -    }
   7.295 -
   7.296 -    rc = xc_linux_restore(xc->xc_handle, ioctxt);
   7.297 -
   7.298 -    IOStream_close(ioctxt->io);
   7.299 -    
   7.300 -    return rc;
   7.301 -}
   7.302 -
   7.303 -static PyObject *pyxc_linux_restore(PyObject *self,
   7.304 -                                    PyObject *args,
   7.305 -                                    PyObject *kwds)
   7.306 -{
   7.307 -    XcObject *xc = (XcObject *)self;
   7.308 -    char *state_file;
   7.309 -    int progress = 1, debug = 0;
   7.310 -    PyObject *val = NULL;
   7.311 -    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
   7.312 -    int rc =-1;
   7.313 -
   7.314 -    static char *kwd_list[] = { "state_file", "progress", "debug", NULL };
   7.315 -
   7.316 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|ii", kwd_list,
   7.317 -                                      &ioctxt.domain,
   7.318 -                                      &state_file,
   7.319 -                                      &progress,
   7.320 -                                      &debug) )
   7.321 -        goto exit;
   7.322 -
   7.323 -    if ( progress )
   7.324 -        ioctxt.flags |= XCFLAGS_VERBOSE;
   7.325 -    if ( debug )
   7.326 -        ioctxt.flags |= XCFLAGS_DEBUG;
   7.327 -
   7.328 -    if ( (state_file == NULL) || (state_file[0] == '\0') )
   7.329 -        goto exit;
   7.330 -
   7.331 -    rc = file_restore(xc, &ioctxt, state_file);
   7.332 -    if ( rc != 0 )
   7.333 -    {
   7.334 -        PyErr_SetFromErrno(xc_error);
   7.335 -        goto exit;
   7.336 -    }
   7.337 -
   7.338 -    val = Py_BuildValue("{s:i,s:s}",
   7.339 -                        "dom", ioctxt.domain,
   7.340 -                        "vmconfig", ioctxt.vmconfig);
   7.341 -
   7.342 -  exit:
   7.343 -    return val;
   7.344 -}
   7.345 -
   7.346 -static PyObject *pyxc_linux_build(PyObject *self,
   7.347 -                                  PyObject *args,
   7.348 -                                  PyObject *kwds)
   7.349 -{
   7.350 -    XcObject *xc = (XcObject *)self;
   7.351 -
   7.352 -    u32   dom;
   7.353 -    char *image, *ramdisk = NULL, *cmdline = "";
   7.354 -    int   control_evtchn, flags = 0;
   7.355 -
   7.356 -    static char *kwd_list[] = { "dom", "control_evtchn", 
   7.357 -                                "image", "ramdisk", "cmdline", "flags",
   7.358 -                                NULL };
   7.359 -
   7.360 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 
   7.361 -                                      &dom, &control_evtchn, 
   7.362 -                                      &image, &ramdisk, &cmdline, &flags) )
   7.363 -        return NULL;
   7.364 -
   7.365 -    if ( xc_linux_build(xc->xc_handle, dom, image,
   7.366 -                        ramdisk, cmdline, control_evtchn, flags) != 0 )
   7.367 -        return PyErr_SetFromErrno(xc_error);
   7.368 -    
   7.369 -    Py_INCREF(zero);
   7.370 -    return zero;
   7.371 -}
   7.372 -
   7.373 -static PyObject *pyxc_netbsd_build(PyObject *self,
   7.374 -                                   PyObject *args,
   7.375 -                                   PyObject *kwds)
   7.376 -{
   7.377 -    XcObject *xc = (XcObject *)self;
   7.378 -
   7.379 -    u32   dom;
   7.380 -    char *image, *ramdisk = NULL, *cmdline = "";
   7.381 -    int   control_evtchn;
   7.382 -
   7.383 -    static char *kwd_list[] = { "dom", "control_evtchn",
   7.384 -                                "image", "ramdisk", "cmdline", NULL };
   7.385 -
   7.386 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 
   7.387 -                                      &dom, &control_evtchn,
   7.388 -                                      &image, &ramdisk, &cmdline) )
   7.389 -        return NULL;
   7.390 -
   7.391 -    if ( xc_netbsd_build(xc->xc_handle, dom, image, 
   7.392 -                         cmdline, control_evtchn) != 0 )
   7.393 -        return PyErr_SetFromErrno(xc_error);
   7.394 -    
   7.395 -    Py_INCREF(zero);
   7.396 -    return zero;
   7.397 -}
   7.398 -
   7.399 -static PyObject *pyxc_bvtsched_global_set(PyObject *self,
   7.400 -                                          PyObject *args,
   7.401 -                                          PyObject *kwds)
   7.402 -{
   7.403 -    XcObject *xc = (XcObject *)self;
   7.404 -
   7.405 -    unsigned long ctx_allow;
   7.406 -
   7.407 -    static char *kwd_list[] = { "ctx_allow", NULL };
   7.408 -
   7.409 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
   7.410 -        return NULL;
   7.411 -
   7.412 -    if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
   7.413 -        return PyErr_SetFromErrno(xc_error);
   7.414 -    
   7.415 -    Py_INCREF(zero);
   7.416 -    return zero;
   7.417 -}
   7.418 -
   7.419 -static PyObject *pyxc_bvtsched_global_get(PyObject *self,
   7.420 -                                          PyObject *args,
   7.421 -                                          PyObject *kwds)
   7.422 -{
   7.423 -    XcObject *xc = (XcObject *)self;
   7.424 -    
   7.425 -    unsigned long ctx_allow;
   7.426 -    
   7.427 -    if ( !PyArg_ParseTuple(args, "") )
   7.428 -        return NULL;
   7.429 -    
   7.430 -    if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
   7.431 -        return PyErr_SetFromErrno(xc_error);
   7.432 -    
   7.433 -    return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
   7.434 -}
   7.435 -
   7.436 -static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
   7.437 -                                          PyObject *args,
   7.438 -                                          PyObject *kwds)
   7.439 -{
   7.440 -    XcObject *xc = (XcObject *)self;
   7.441 -
   7.442 -    u32           dom;
   7.443 -    unsigned long mcuadv, warp, warpl, warpu;
   7.444 -
   7.445 -    static char *kwd_list[] = { "dom", "mcuadv", "warp", "warpl",
   7.446 -                                "warpu", NULL };
   7.447 -
   7.448 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illll", kwd_list,
   7.449 -                                      &dom, &mcuadv, &warp, &warpl, &warpu) )
   7.450 -        return NULL;
   7.451 -
   7.452 -    if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv, 
   7.453 -                                warp, warpl, warpu) != 0 )
   7.454 -        return PyErr_SetFromErrno(xc_error);
   7.455 -    
   7.456 -    Py_INCREF(zero);
   7.457 -    return zero;
   7.458 -}
   7.459 -
   7.460 -static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
   7.461 -                                          PyObject *args,
   7.462 -                                          PyObject *kwds)
   7.463 -{
   7.464 -    XcObject *xc = (XcObject *)self;
   7.465 -    u32 dom;
   7.466 -    unsigned long mcuadv, warp, warpl, warpu;
   7.467 -    
   7.468 -    static char *kwd_list[] = { "dom", NULL };
   7.469 -
   7.470 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
   7.471 -        return NULL;
   7.472 -    
   7.473 -    if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warp,
   7.474 -                                &warpl, &warpu) != 0 )
   7.475 -        return PyErr_SetFromErrno(xc_error);
   7.476 -
   7.477 -    return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
   7.478 -                         "domain", dom,
   7.479 -                         "mcuadv", mcuadv,
   7.480 -                         "warp",   warp,
   7.481 -                         "warpl",  warpl,
   7.482 -                         "warpu",  warpu);
   7.483 -}
   7.484 -
   7.485 -static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
   7.486 -                                              PyObject *args,
   7.487 -                                              PyObject *kwds)
   7.488 -{
   7.489 -    XcObject *xc = (XcObject *)self;
   7.490 -
   7.491 -    u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
   7.492 -    int port1, port2;
   7.493 -
   7.494 -    static char *kwd_list[] = { "dom1", "dom2", NULL };
   7.495 -
   7.496 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, 
   7.497 -                                      &dom1, &dom2) )
   7.498 -        return NULL;
   7.499 -
   7.500 -    if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1, 
   7.501 -                                    dom2, &port1, &port2) != 0 )
   7.502 -        return PyErr_SetFromErrno(xc_error);
   7.503 -
   7.504 -    return Py_BuildValue("{s:i,s:i}", 
   7.505 -                         "port1", port1,
   7.506 -                         "port2", port2);
   7.507 -}
   7.508 -
   7.509 -static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
   7.510 -                                       PyObject *args,
   7.511 -                                       PyObject *kwds)
   7.512 -{
   7.513 -    XcObject *xc = (XcObject *)self;
   7.514 -
   7.515 -    int virq, port;
   7.516 -
   7.517 -    static char *kwd_list[] = { "virq", NULL };
   7.518 -
   7.519 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
   7.520 -        return NULL;
   7.521 -
   7.522 -    if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
   7.523 -        return PyErr_SetFromErrno(xc_error);
   7.524 -
   7.525 -    return PyInt_FromLong(port);
   7.526 -}
   7.527 -
   7.528 -static PyObject *pyxc_evtchn_close(PyObject *self,
   7.529 -                                   PyObject *args,
   7.530 -                                   PyObject *kwds)
   7.531 -{
   7.532 -    XcObject *xc = (XcObject *)self;
   7.533 -
   7.534 -    u32 dom = DOMID_SELF;
   7.535 -    int port;
   7.536 -
   7.537 -    static char *kwd_list[] = { "port", "dom", NULL };
   7.538 -
   7.539 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
   7.540 -                                      &port, &dom) )
   7.541 -        return NULL;
   7.542 -
   7.543 -    if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
   7.544 -        return PyErr_SetFromErrno(xc_error);
   7.545 -
   7.546 -    Py_INCREF(zero);
   7.547 -    return zero;
   7.548 -}
   7.549 -
   7.550 -static PyObject *pyxc_evtchn_send(PyObject *self,
   7.551 -                                  PyObject *args,
   7.552 -                                  PyObject *kwds)
   7.553 -{
   7.554 -    XcObject *xc = (XcObject *)self;
   7.555 -
   7.556 -    int port;
   7.557 -
   7.558 -    static char *kwd_list[] = { "port", NULL };
   7.559 -
   7.560 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
   7.561 -        return NULL;
   7.562 -
   7.563 -    if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
   7.564 -        return PyErr_SetFromErrno(xc_error);
   7.565 -
   7.566 -    Py_INCREF(zero);
   7.567 -    return zero;
   7.568 -}
   7.569 -
   7.570 -static PyObject *pyxc_evtchn_status(PyObject *self,
   7.571 -                                    PyObject *args,
   7.572 -                                    PyObject *kwds)
   7.573 -{
   7.574 -    XcObject *xc = (XcObject *)self;
   7.575 -    PyObject *dict;
   7.576 -
   7.577 -    u32 dom = DOMID_SELF;
   7.578 -    int port, ret;
   7.579 -    xc_evtchn_status_t status;
   7.580 -
   7.581 -    static char *kwd_list[] = { "port", "dom", NULL };
   7.582 -
   7.583 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
   7.584 -                                      &port, &dom) )
   7.585 -        return NULL;
   7.586 -
   7.587 -    ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
   7.588 -    if ( ret != 0 )
   7.589 -        return PyErr_SetFromErrno(xc_error);
   7.590 -
   7.591 -    switch ( status.status )
   7.592 -    {
   7.593 -    case EVTCHNSTAT_closed:
   7.594 -        dict = Py_BuildValue("{s:s}", 
   7.595 -                             "status", "closed");
   7.596 -        break;
   7.597 -    case EVTCHNSTAT_unbound:
   7.598 -        dict = Py_BuildValue("{s:s}", 
   7.599 -                             "status", "unbound");
   7.600 -        break;
   7.601 -    case EVTCHNSTAT_interdomain:
   7.602 -        dict = Py_BuildValue("{s:s,s:i,s:i}", 
   7.603 -                             "status", "interdomain",
   7.604 -                             "dom", status.u.interdomain.dom,
   7.605 -                             "port", status.u.interdomain.port);
   7.606 -        break;
   7.607 -    case EVTCHNSTAT_pirq:
   7.608 -        dict = Py_BuildValue("{s:s,s:i}", 
   7.609 -                             "status", "pirq",
   7.610 -                             "irq", status.u.pirq);
   7.611 -        break;
   7.612 -    case EVTCHNSTAT_virq:
   7.613 -        dict = Py_BuildValue("{s:s,s:i}", 
   7.614 -                             "status", "virq",
   7.615 -                             "irq", status.u.virq);
   7.616 -        break;
   7.617 -    default:
   7.618 -        dict = Py_BuildValue("{}");
   7.619 -        break;
   7.620 -    }
   7.621 -    
   7.622 -    return dict;
   7.623 -}
   7.624 -
   7.625 -static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
   7.626 -                                                PyObject *args,
   7.627 -                                                PyObject *kwds)
   7.628 -{
   7.629 -    XcObject *xc = (XcObject *)self;
   7.630 -    u32 dom;
   7.631 -    int bus, dev, func, enable, ret;
   7.632 -
   7.633 -    static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
   7.634 -
   7.635 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list, 
   7.636 -                                      &dom, &bus, &dev, &func, &enable) )
   7.637 -        return NULL;
   7.638 -
   7.639 -    ret = xc_physdev_pci_access_modify(
   7.640 -        xc->xc_handle, dom, bus, dev, func, enable);
   7.641 -    if ( ret != 0 )
   7.642 -        return PyErr_SetFromErrno(xc_error);
   7.643 -
   7.644 -    Py_INCREF(zero);
   7.645 -    return zero;
   7.646 -}
   7.647 -
   7.648 -static PyObject *pyxc_readconsolering(PyObject *self,
   7.649 -                                      PyObject *args,
   7.650 -                                      PyObject *kwds)
   7.651 -{
   7.652 -    XcObject *xc = (XcObject *)self;
   7.653 -
   7.654 -    unsigned int clear = 0;
   7.655 -    char         str[32768];
   7.656 -    int          ret;
   7.657 -
   7.658 -    static char *kwd_list[] = { "clear", NULL };
   7.659 -
   7.660 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
   7.661 -        return NULL;
   7.662 -
   7.663 -    ret = xc_readconsolering(xc->xc_handle, str, sizeof(str), clear);
   7.664 -    if ( ret < 0 )
   7.665 -        return PyErr_SetFromErrno(xc_error);
   7.666 -
   7.667 -    return PyString_FromStringAndSize(str, ret);
   7.668 -}
   7.669 -
   7.670 -static PyObject *pyxc_physinfo(PyObject *self,
   7.671 -                               PyObject *args,
   7.672 -                               PyObject *kwds)
   7.673 -{
   7.674 -    XcObject *xc = (XcObject *)self;
   7.675 -    xc_physinfo_t info;
   7.676 -    
   7.677 -    if ( !PyArg_ParseTuple(args, "") )
   7.678 -        return NULL;
   7.679 -
   7.680 -    if ( xc_physinfo(xc->xc_handle, &info) != 0 )
   7.681 -        return PyErr_SetFromErrno(xc_error);
   7.682 -
   7.683 -    return Py_BuildValue("{s:i,s:i,s:l,s:l,s:l}",
   7.684 -                         "ht_per_core", info.ht_per_core,
   7.685 -                         "cores",       info.cores,
   7.686 -                         "total_pages", info.total_pages,
   7.687 -                         "free_pages",  info.free_pages,
   7.688 -                         "cpu_khz",     info.cpu_khz);
   7.689 -}
   7.690 -
   7.691 -static PyObject *pyxc_atropos_domain_set(PyObject *self,
   7.692 -                                         PyObject *args,
   7.693 -                                         PyObject *kwds)
   7.694 -{
   7.695 -    XcObject *xc = (XcObject *)self;
   7.696 -    u32 domid;
   7.697 -    u64 period, slice, latency;
   7.698 -    int xtratime;
   7.699 -
   7.700 -    static char *kwd_list[] = { "dom", "period", "slice", "latency",
   7.701 -                                "xtratime", NULL };
   7.702 -    
   7.703 -    if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLi", kwd_list, &domid,
   7.704 -                                     &period, &slice, &latency, &xtratime) )
   7.705 -        return NULL;
   7.706 -   
   7.707 -    if ( xc_atropos_domain_set(xc->xc_handle, domid, period, slice,
   7.708 -                               latency, xtratime) != 0 )
   7.709 -        return PyErr_SetFromErrno(xc_error);
   7.710 -
   7.711 -    Py_INCREF(zero);
   7.712 -    return zero;
   7.713 -}
   7.714 -
   7.715 -static PyObject *pyxc_atropos_domain_get(PyObject *self,
   7.716 -                                         PyObject *args,
   7.717 -                                         PyObject *kwds)
   7.718 -{
   7.719 -    XcObject *xc = (XcObject *)self;
   7.720 -    u32 domid;
   7.721 -    u64 period, slice, latency;
   7.722 -    int xtratime;
   7.723 -    
   7.724 -    static char *kwd_list[] = { "dom", NULL };
   7.725 -
   7.726 -    if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
   7.727 -        return NULL;
   7.728 -    
   7.729 -    if ( xc_atropos_domain_get( xc->xc_handle, domid, &period,
   7.730 -                                &slice, &latency, &xtratime ) )
   7.731 -        return PyErr_SetFromErrno(xc_error);
   7.732 -
   7.733 -    return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
   7.734 -                         "domain",  domid,
   7.735 -                         "period",  period,
   7.736 -                         "slice",   slice,
   7.737 -                         "latency", latency,
   7.738 -                         "xtratime", xtratime);
   7.739 -}
   7.740 -
   7.741 -
   7.742 -static PyObject *pyxc_rrobin_global_set(PyObject *self,
   7.743 -                                        PyObject *args,
   7.744 -                                        PyObject *kwds)
   7.745 -{
   7.746 -    XcObject *xc = (XcObject *)self;
   7.747 -    u64 slice;
   7.748 -    
   7.749 -    static char *kwd_list[] = { "slice", NULL };
   7.750 -
   7.751 -    if( !PyArg_ParseTupleAndKeywords(args, kwds, "L", kwd_list, &slice) )
   7.752 -        return NULL;
   7.753 -    
   7.754 -    if ( xc_rrobin_global_set(xc->xc_handle, slice) != 0 )
   7.755 -        return PyErr_SetFromErrno(xc_error);
   7.756 -    
   7.757 -    Py_INCREF(zero);
   7.758 -    return zero;
   7.759 -}
   7.760 -
   7.761 -static PyObject *pyxc_shadow_control(PyObject *self,
   7.762 -                                     PyObject *args,
   7.763 -                                     PyObject *kwds)
   7.764 -{
   7.765 -    XcObject *xc = (XcObject *)self;
   7.766 -
   7.767 -    u32 dom;
   7.768 -    int op=0;
   7.769 -
   7.770 -    static char *kwd_list[] = { "dom", "op", NULL };
   7.771 -
   7.772 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
   7.773 -                                      &dom, &op) )
   7.774 -        return NULL;
   7.775 -
   7.776 -    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
   7.777 -        return PyErr_SetFromErrno(xc_error);
   7.778 -    
   7.779 -    Py_INCREF(zero);
   7.780 -    return zero;
   7.781 -}
   7.782 -
   7.783 -static PyObject *pyxc_rrobin_global_get(PyObject *self,
   7.784 -                                        PyObject *args,
   7.785 -                                        PyObject *kwds)
   7.786 -{
   7.787 -    XcObject *xc = (XcObject *)self;
   7.788 -    u64 slice;
   7.789 -
   7.790 -    if ( !PyArg_ParseTuple(args, "") )
   7.791 -        return NULL;
   7.792 -
   7.793 -    if ( xc_rrobin_global_get(xc->xc_handle, &slice) != 0 )
   7.794 -        return PyErr_SetFromErrno(xc_error);
   7.795 -    
   7.796 -    return Py_BuildValue("{s:L}", "slice", slice);
   7.797 -}
   7.798 -
   7.799 -static PyObject *pyxc_domain_setname(PyObject *self,
   7.800 -                                     PyObject *args,
   7.801 -                                     PyObject *kwds)
   7.802 -{
   7.803 -    XcObject *xc = (XcObject *)self;
   7.804 -    u32 dom;
   7.805 -    char *name;
   7.806 -
   7.807 -    static char *kwd_list[] = { "dom", "name", NULL };
   7.808 -
   7.809 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list, 
   7.810 -                                      &dom, &name) )
   7.811 -        return NULL;
   7.812 -
   7.813 -    if ( xc_domain_setname(xc->xc_handle, dom, name) != 0 )
   7.814 -        return PyErr_SetFromErrno(xc_error);
   7.815 -    
   7.816 -    Py_INCREF(zero);
   7.817 -    return zero;
   7.818 -}
   7.819 -
   7.820 -static PyObject *pyxc_domain_setmaxmem(PyObject *self,
   7.821 -                                       PyObject *args,
   7.822 -                                       PyObject *kwds)
   7.823 -{
   7.824 -    XcObject *xc = (XcObject *)self;
   7.825 -
   7.826 -    u32 dom;
   7.827 -    unsigned long max_memkb;
   7.828 -
   7.829 -    static char *kwd_list[] = { "dom", "max_memkb", NULL };
   7.830 -
   7.831 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
   7.832 -                                      &dom, &max_memkb) )
   7.833 -        return NULL;
   7.834 -
   7.835 -    if ( xc_domain_setmaxmem(xc->xc_handle, dom, max_memkb) != 0 )
   7.836 -        return PyErr_SetFromErrno(xc_error);
   7.837 -    
   7.838 -    Py_INCREF(zero);
   7.839 -    return zero;
   7.840 -}
   7.841 -
   7.842 -
   7.843 -static PyMethodDef pyxc_methods[] = {
   7.844 -    { "domain_create", 
   7.845 -      (PyCFunction)pyxc_domain_create, 
   7.846 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.847 -      "Create a new domain.\n"
   7.848 -      " mem_kb [int, 0]:        Memory allocation, in kilobytes.\n"
   7.849 -      " name   [str, '(anon)']: Informative textual name.\n\n"
   7.850 -      "Returns: [int] new domain identifier; -1 on error.\n" },
   7.851 -
   7.852 -    { "domain_pause", 
   7.853 -      (PyCFunction)pyxc_domain_pause, 
   7.854 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.855 -      "Temporarily pause execution of a domain.\n"
   7.856 -      " dom [int]: Identifier of domain to be paused.\n\n"
   7.857 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.858 -
   7.859 -    { "domain_unpause", 
   7.860 -      (PyCFunction)pyxc_domain_unpause, 
   7.861 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.862 -      "(Re)start execution of a domain.\n"
   7.863 -      " dom [int]: Identifier of domain to be unpaused.\n\n"
   7.864 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.865 -
   7.866 -    { "domain_destroy", 
   7.867 -      (PyCFunction)pyxc_domain_destroy, 
   7.868 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.869 -      "Destroy a domain.\n"
   7.870 -      " dom [int]:    Identifier of domain to be destroyed.\n\n"
   7.871 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.872 -
   7.873 -    { "domain_pincpu", 
   7.874 -      (PyCFunction)pyxc_domain_pincpu, 
   7.875 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.876 -      "Pin a domain to a specified CPU.\n"
   7.877 -      " dom [int]:     Identifier of domain to be pinned.\n"
   7.878 -      " cpu [int, -1]: CPU to pin to, or -1 to unpin\n\n"
   7.879 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.880 -
   7.881 -    { "domain_getinfo", 
   7.882 -      (PyCFunction)pyxc_domain_getinfo, 
   7.883 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.884 -      "Get information regarding a set of domains, in increasing id order.\n"
   7.885 -      " first_dom [int, 0]:    First domain to retrieve info about.\n"
   7.886 -      " max_doms  [int, 1024]: Maximum number of domains to retrieve info"
   7.887 -      " about.\n\n"
   7.888 -      "Returns: [list of dicts] if list length is less than 'max_doms'\n"
   7.889 -      "         parameter then there was an error, or the end of the\n"
   7.890 -      "         domain-id space was reached.\n"
   7.891 -      " dom      [int]: Identifier of domain to which this info pertains\n"
   7.892 -      " cpu      [int]:  CPU to which this domain is bound\n"
   7.893 -      " dying    [int]:  Bool - is the domain dying?\n"
   7.894 -      " crashed  [int]:  Bool - has the domain crashed?\n"
   7.895 -      " shutdown [int]:  Bool - has the domain shut itself down?\n"
   7.896 -      " paused   [int]:  Bool - is the domain paused by control software?\n"
   7.897 -      " blocked  [int]:  Bool - is the domain blocked waiting for an event?\n"
   7.898 -      " running  [int]:  Bool - is the domain currently running?\n"
   7.899 -      " mem_kb   [int]:  Memory reservation, in kilobytes\n"
   7.900 -      " cpu_time [long]: CPU time consumed, in nanoseconds\n"
   7.901 -      " name     [str]:  Identifying name\n"
   7.902 -      " shutdown_reason [int]: Numeric code from guest OS, explaining "
   7.903 -      "reason why it shut itself down.\n" },
   7.904 -
   7.905 -    { "linux_save", 
   7.906 -      (PyCFunction)pyxc_linux_save, 
   7.907 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.908 -      "Save the CPU and memory state of a Linux guest OS.\n"
   7.909 -      " dom        [int]:    Identifier of domain to be saved.\n"
   7.910 -      " state_file [str]:    Name of state file. Must not currently exist.\n"
   7.911 -      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
   7.912 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.913 -
   7.914 -    { "linux_restore", 
   7.915 -      (PyCFunction)pyxc_linux_restore, 
   7.916 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.917 -      "Restore the CPU and memory state of a Linux guest OS.\n"
   7.918 -      " state_file [str]:    Name of state file. Must not currently exist.\n"
   7.919 -      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
   7.920 -      "Returns: [int] new domain identifier on success; -1 on error.\n" },
   7.921 -
   7.922 -    { "linux_build", 
   7.923 -      (PyCFunction)pyxc_linux_build, 
   7.924 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.925 -      "Build a new Linux guest OS.\n"
   7.926 -      " dom     [int]:      Identifier of domain to build into.\n"
   7.927 -      " image   [str]:      Name of kernel image file. May be gzipped.\n"
   7.928 -      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
   7.929 -      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   7.930 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.931 -
   7.932 -    { "netbsd_build", 
   7.933 -      (PyCFunction)pyxc_netbsd_build, 
   7.934 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.935 -      "Build a new NetBSD guest OS.\n"
   7.936 -      " dom     [int]:     Identifier of domain to build into.\n"
   7.937 -      " image   [str]:      Name of kernel image file. May be gzipped.\n"
   7.938 -      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   7.939 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.940 -
   7.941 -    { "bvtsched_global_set",
   7.942 -      (PyCFunction)pyxc_bvtsched_global_set,
   7.943 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.944 -      "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
   7.945 -      " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
   7.946 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.947 -
   7.948 -    { "bvtsched_global_get",
   7.949 -      (PyCFunction)pyxc_bvtsched_global_get,
   7.950 -      METH_KEYWORDS, "\n"
   7.951 -      "Get global tuning parameters for BVT scheduler.\n"
   7.952 -      "Returns: [dict]:\n"
   7.953 -      " ctx_allow [int]: context switch allowance\n" },
   7.954 -
   7.955 -    { "bvtsched_domain_set",
   7.956 -      (PyCFunction)pyxc_bvtsched_domain_set,
   7.957 -      METH_VARARGS | METH_KEYWORDS, "\n"
   7.958 -      "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
   7.959 -      " dom    [int]: Identifier of domain to be tuned.\n"
   7.960 -      " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
   7.961 -      " warp   [int]: How far to warp domain's EVT on unblock.\n"
   7.962 -      " warpl  [int]: How long the domain can run warped.\n"
   7.963 -      " warpu  [int]: How long before the domain can warp again.\n\n"
   7.964 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.965 -
   7.966 -    { "bvtsched_domain_get",
   7.967 -      (PyCFunction)pyxc_bvtsched_domain_get,
   7.968 -      METH_KEYWORDS, "\n"
   7.969 -      "Get per-domain tuning parameters under the BVT scheduler.\n"
   7.970 -      " dom [int]: Identifier of domain to be queried.\n"
   7.971 -      "Returns [dict]:\n"
   7.972 -      " domain [int]:  Domain ID.\n"
   7.973 -      " mcuadv [long]: MCU Advance.\n"
   7.974 -      " warp   [long]: Warp.\n"
   7.975 -      " warpu  [long]: Unwarp requirement.\n"
   7.976 -      " warpl  [long]: Warp limit,\n"
   7.977 -    },
   7.978 -
   7.979 -    { "atropos_domain_set",
   7.980 -      (PyCFunction)pyxc_atropos_domain_set,
   7.981 -      METH_KEYWORDS, "\n"
   7.982 -      "Set the scheduling parameters for a domain when running with Atropos.\n"
   7.983 -      " dom      [int]:  domain to set\n"
   7.984 -      " period   [long]: domain's scheduling period\n"
   7.985 -      " slice    [long]: domain's slice per period\n"
   7.986 -      " latency  [long]: wakeup latency hint\n"
   7.987 -      " xtratime [int]: boolean\n"
   7.988 -      "Returns: [int] 0 on success; -1 on error.\n" },
   7.989 -
   7.990 -    { "atropos_domain_get",
   7.991 -      (PyCFunction)pyxc_atropos_domain_get,
   7.992 -      METH_KEYWORDS, "\n"
   7.993 -      "Get the current scheduling parameters for a domain when running with\n"
   7.994 -      "the Atropos scheduler."
   7.995 -      " dom      [int]: domain to query\n"
   7.996 -      "Returns:  [dict]\n"
   7.997 -      " domain   [int]: domain ID\n"
   7.998 -      " period   [long]: scheduler period\n"
   7.999 -      " slice    [long]: CPU reservation per period\n"
  7.1000 -      " latency  [long]: unblocking latency hint\n"
  7.1001 -      " xtratime [int] : 0 if not using slack time, nonzero otherwise\n" },
  7.1002 -
  7.1003 -    { "rrobin_global_set",
  7.1004 -      (PyCFunction)pyxc_rrobin_global_set,
  7.1005 -      METH_KEYWORDS, "\n"
  7.1006 -      "Set Round Robin scheduler slice.\n"
  7.1007 -      " slice [long]: Round Robin scheduler slice\n"
  7.1008 -      "Returns: [int] 0 on success, throws an exception on failure\n" },
  7.1009 -
  7.1010 -    { "rrobin_global_get",
  7.1011 -      (PyCFunction)pyxc_rrobin_global_get,
  7.1012 -      METH_KEYWORDS, "\n"
  7.1013 -      "Get Round Robin scheduler settings\n"
  7.1014 -      "Returns [dict]:\n"
  7.1015 -      " slice  [long]: Scheduler time slice.\n" },    
  7.1016 -
  7.1017 -    { "evtchn_bind_interdomain", 
  7.1018 -      (PyCFunction)pyxc_evtchn_bind_interdomain, 
  7.1019 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1020 -      "Open an event channel between two domains.\n"
  7.1021 -      " dom1 [int, SELF]: First domain to be connected.\n"
  7.1022 -      " dom2 [int, SELF]: Second domain to be connected.\n\n"
  7.1023 -      "Returns: [dict] dictionary is empty on failure.\n"
  7.1024 -      " port1 [int]: Port-id for endpoint at dom1.\n"
  7.1025 -      " port2 [int]: Port-id for endpoint at dom2.\n" },
  7.1026 -
  7.1027 -    { "evtchn_bind_virq", 
  7.1028 -      (PyCFunction)pyxc_evtchn_bind_virq, 
  7.1029 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1030 -      "Bind an event channel to the specified VIRQ.\n"
  7.1031 -      " virq [int]: VIRQ to bind.\n\n"
  7.1032 -      "Returns: [int] Bound event-channel port.\n" },
  7.1033 -
  7.1034 -    { "evtchn_close", 
  7.1035 -      (PyCFunction)pyxc_evtchn_close, 
  7.1036 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1037 -      "Close an event channel.\n"
  7.1038 -      " dom  [int, SELF]: Dom-id of one endpoint of the channel.\n"
  7.1039 -      " port [int]:       Port-id of one endpoint of the channel.\n\n"
  7.1040 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1041 -
  7.1042 -    { "evtchn_send", 
  7.1043 -      (PyCFunction)pyxc_evtchn_send, 
  7.1044 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1045 -      "Send an event along a locally-connected event channel.\n"
  7.1046 -      " port [int]: Port-id of a local channel endpoint.\n\n"
  7.1047 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1048 -
  7.1049 -    { "evtchn_status", 
  7.1050 -      (PyCFunction)pyxc_evtchn_status, 
  7.1051 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1052 -      "Query the status of an event channel.\n"
  7.1053 -      " dom  [int, SELF]: Dom-id of one endpoint of the channel.\n"
  7.1054 -      " port [int]:       Port-id of one endpoint of the channel.\n\n"
  7.1055 -      "Returns: [dict] dictionary is empty on failure.\n"
  7.1056 -      " status [str]:  'closed', 'unbound', 'interdomain', 'pirq',"
  7.1057 -      " or 'virq'.\n"
  7.1058 -      "The following are returned if 'status' is 'interdomain':\n"
  7.1059 -      " dom  [int]: Dom-id of remote endpoint.\n"
  7.1060 -      " port [int]: Port-id of remote endpoint.\n"
  7.1061 -      "The following are returned if 'status' is 'pirq' or 'virq':\n"
  7.1062 -      " irq  [int]: IRQ number.\n" },
  7.1063 -
  7.1064 -    { "physdev_pci_access_modify",
  7.1065 -      (PyCFunction)pyxc_physdev_pci_access_modify,
  7.1066 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1067 -      "Allow a domain access to a PCI device\n"
  7.1068 -      " dom    [int]: Identifier of domain to be allowed access.\n"
  7.1069 -      " bus    [int]: PCI bus\n"
  7.1070 -      " dev    [int]: PCI slot\n"
  7.1071 -      " func   [int]: PCI function\n"
  7.1072 -      " enable [int]: Non-zero means enable access; else disable access\n\n"
  7.1073 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1074 - 
  7.1075 -    { "readconsolering", 
  7.1076 -      (PyCFunction)pyxc_readconsolering, 
  7.1077 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1078 -      "Read Xen's console ring.\n"
  7.1079 -      " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
  7.1080 -      "Returns: [str] string is empty on failure.\n" },
  7.1081 -
  7.1082 -    { "physinfo",
  7.1083 -      (PyCFunction)pyxc_physinfo,
  7.1084 -      METH_VARARGS, "\n"
  7.1085 -      "Get information about the physical host machine\n"
  7.1086 -      "Returns [dict]: information about the hardware"
  7.1087 -      "        [None]: on failure.\n" },
  7.1088 -
  7.1089 -    { "shadow_control", 
  7.1090 -      (PyCFunction)pyxc_shadow_control, 
  7.1091 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1092 -      "Set parameter for shadow pagetable interface\n"
  7.1093 -      " dom [int]:   Identifier of domain.\n"
  7.1094 -      " op [int, 0]: operation\n\n"
  7.1095 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1096 -
  7.1097 -    { "domain_setname", 
  7.1098 -      (PyCFunction)pyxc_domain_setname, 
  7.1099 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1100 -      "Set domain informative textual name\n"
  7.1101 -      " dom [int]:  Identifier of domain.\n"
  7.1102 -      " name [str]: Text string.\n\n"
  7.1103 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1104 -
  7.1105 -    { "domain_setmaxmem", 
  7.1106 -      (PyCFunction)pyxc_domain_setmaxmem, 
  7.1107 -      METH_VARARGS | METH_KEYWORDS, "\n"
  7.1108 -      "Set a domain's memory limit\n"
  7.1109 -      " dom [int]: Identifier of domain.\n"
  7.1110 -      " max_memkb [long]: .\n"
  7.1111 -      "Returns: [int] 0 on success; -1 on error.\n" },
  7.1112 -
  7.1113 -    { NULL, NULL, 0, NULL }
  7.1114 -};
  7.1115 -
  7.1116 -
  7.1117 -/*
  7.1118 - * Definitions for the 'Xc' module wrapper.
  7.1119 - */
  7.1120 -
  7.1121 -staticforward PyTypeObject PyXcType;
  7.1122 -
  7.1123 -static PyObject *PyXc_new(PyObject *self, PyObject *args)
  7.1124 -{
  7.1125 -    XcObject *xc;
  7.1126 -
  7.1127 -    if ( !PyArg_ParseTuple(args, ":new") )
  7.1128 -        return NULL;
  7.1129 -
  7.1130 -    xc = PyObject_New(XcObject, &PyXcType);
  7.1131 -
  7.1132 -    if ( (xc->xc_handle = xc_interface_open()) == -1 )
  7.1133 -    {
  7.1134 -        PyObject_Del((PyObject *)xc);
  7.1135 -        return PyErr_SetFromErrno(xc_error);
  7.1136 -    }
  7.1137 -
  7.1138 -    return (PyObject *)xc;
  7.1139 -}
  7.1140 -
  7.1141 -static PyObject *PyXc_getattr(PyObject *obj, char *name)
  7.1142 -{
  7.1143 -    return Py_FindMethod(pyxc_methods, obj, name);
  7.1144 -}
  7.1145 -
  7.1146 -static void PyXc_dealloc(PyObject *self)
  7.1147 -{
  7.1148 -    XcObject *xc = (XcObject *)self;
  7.1149 -    (void)xc_interface_close(xc->xc_handle);
  7.1150 -    PyObject_Del(self);
  7.1151 -}
  7.1152 -
  7.1153 -static PyTypeObject PyXcType = {
  7.1154 -    PyObject_HEAD_INIT(&PyType_Type)
  7.1155 -    0,
  7.1156 -    "Xc",
  7.1157 -    sizeof(XcObject),
  7.1158 -    0,
  7.1159 -    PyXc_dealloc,    /* tp_dealloc     */
  7.1160 -    NULL,            /* tp_print       */
  7.1161 -    PyXc_getattr,    /* tp_getattr     */
  7.1162 -    NULL,            /* tp_setattr     */
  7.1163 -    NULL,            /* tp_compare     */
  7.1164 -    NULL,            /* tp_repr        */
  7.1165 -    NULL,            /* tp_as_number   */
  7.1166 -    NULL,            /* tp_as_sequence */
  7.1167 -    NULL,            /* tp_as_mapping  */
  7.1168 -    NULL             /* tp_hash        */
  7.1169 -};
  7.1170 -
  7.1171 -static PyMethodDef PyXc_methods[] = {
  7.1172 -    { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
  7.1173 -    { NULL, NULL, 0, NULL }
  7.1174 -};
  7.1175 -
  7.1176 -PyMODINIT_FUNC initxc(void)
  7.1177 -{
  7.1178 -    PyObject *m, *d;
  7.1179 -
  7.1180 -    m = Py_InitModule(XENPKG, PyXc_methods);
  7.1181 -
  7.1182 -    d = PyModule_GetDict(m);
  7.1183 -    xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
  7.1184 -    PyDict_SetItemString(d, "error", xc_error);
  7.1185 -
  7.1186 -    zero = PyInt_FromLong(0);
  7.1187 -}
     9.1 --- a/tools/python/xen/ext/xu/domain_controller.h	Tue Jun 29 21:08:51 2004 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,532 +0,0 @@
     9.4 -/******************************************************************************
     9.5 - * domain_controller.h
     9.6 - * 
     9.7 - * Interface to server controller (e.g., 'xend'). This header file defines the 
     9.8 - * interface that is shared with guest OSes.
     9.9 - * 
    9.10 - * Copyright (c) 2004, K A Fraser
    9.11 - */
    9.12 -
    9.13 -#ifndef __DOMAIN_CONTROLLER_H__
    9.14 -#define __DOMAIN_CONTROLLER_H__
    9.15 -
    9.16 -
    9.17 -#ifndef BASIC_START_INFO
    9.18 -#error "Xen header file hypervisor-if.h must already be included here."
    9.19 -#endif
    9.20 -
    9.21 -
    9.22 -/*
    9.23 - * EXTENDED BOOTSTRAP STRUCTURE FOR NEW DOMAINS.
    9.24 - */
    9.25 -
    9.26 -typedef struct {
    9.27 -    BASIC_START_INFO;
    9.28 -    u16 domain_controller_evtchn; /* 320 */
    9.29 -} PACKED extended_start_info_t; /* 322 bytes */
    9.30 -#define SIF_BLK_BE_DOMAIN (1<<4)  /* Is this a block backend domain? */
    9.31 -#define SIF_NET_BE_DOMAIN (1<<5)  /* Is this a net backend domain? */
    9.32 -
    9.33 -
    9.34 -/*
    9.35 - * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be
    9.36 - * interpreted by control software to determine the appropriate action. These 
    9.37 - * are only really advisories: the controller can actually do as it likes.
    9.38 - */
    9.39 -#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
    9.40 -#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
    9.41 -#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
    9.42 -
    9.43 -
    9.44 -/*
    9.45 - * CONTROLLER MESSAGING INTERFACE.
    9.46 - */
    9.47 -
    9.48 -typedef struct {
    9.49 -    u8 type;     /*  0: echoed in response */
    9.50 -    u8 subtype;  /*  1: echoed in response */
    9.51 -    u8 id;       /*  2: echoed in response */
    9.52 -    u8 length;   /*  3: number of bytes in 'msg' */
    9.53 -    u8 msg[60];  /*  4: type-specific message data */
    9.54 -} PACKED control_msg_t; /* 64 bytes */
    9.55 -
    9.56 -#define CONTROL_RING_SIZE 8
    9.57 -typedef u32 CONTROL_RING_IDX;
    9.58 -#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1))
    9.59 -
    9.60 -typedef struct {
    9.61 -    control_msg_t tx_ring[CONTROL_RING_SIZE];   /*    0: guest -> controller */
    9.62 -    control_msg_t rx_ring[CONTROL_RING_SIZE];   /*  512: controller -> guest */
    9.63 -    CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */
    9.64 -    CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */
    9.65 -} PACKED control_if_t; /* 1040 bytes */
    9.66 -
    9.67 -/*
    9.68 - * Top-level command types.
    9.69 - */
    9.70 -#define CMSG_CONSOLE        0  /* Console                 */
    9.71 -#define CMSG_BLKIF_BE       1  /* Block-device backend    */
    9.72 -#define CMSG_BLKIF_FE       2  /* Block-device frontend   */
    9.73 -#define CMSG_NETIF_BE       3  /* Network-device backend  */
    9.74 -#define CMSG_NETIF_FE       4  /* Network-device frontend */
    9.75 -#define CMSG_SHUTDOWN       6  /* Shutdown messages       */
    9.76 -
    9.77 -
    9.78 -/******************************************************************************
    9.79 - * CONSOLE DEFINITIONS
    9.80 - */
    9.81 -
    9.82 -/*
    9.83 - * Subtypes for console messages.
    9.84 - */
    9.85 -#define CMSG_CONSOLE_DATA       0
    9.86 -
    9.87 -
    9.88 -/******************************************************************************
    9.89 - * BLOCK-INTERFACE FRONTEND DEFINITIONS
    9.90 - */
    9.91 -
    9.92 -/* Messages from domain controller to guest. */
    9.93 -#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED   0
    9.94 -
    9.95 -/* Messages from guest to domain controller. */
    9.96 -#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED     32
    9.97 -#define CMSG_BLKIF_FE_INTERFACE_CONNECT         33
    9.98 -#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT      34
    9.99 -
   9.100 -/* These are used by both front-end and back-end drivers. */
   9.101 -#define blkif_vdev_t   u16
   9.102 -#define blkif_pdev_t   u16
   9.103 -#define blkif_sector_t u64
   9.104 -
   9.105 -/*
   9.106 - * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
   9.107 - *  Notify a guest about a status change on one of its block interfaces.
   9.108 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
   9.109 - *   1. The shared-memory frame is available for reuse.
   9.110 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   9.111 - */
   9.112 -#define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   9.113 -#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   9.114 -#define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   9.115 -typedef struct {
   9.116 -    u32 handle; /*  0 */
   9.117 -    u32 status; /*  4 */
   9.118 -    u16 evtchn; /*  8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
   9.119 -} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */
   9.120 -
   9.121 -/*
   9.122 - * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
   9.123 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   9.124 - *  When the driver goes DOWN then the controller will send no more
   9.125 - *  status-change notifications. When the driver comes UP then the controller
   9.126 - *  will send a notification for each interface that currently exists.
   9.127 - *  If the driver goes DOWN while interfaces are still UP, the domain
   9.128 - *  will automatically take the interfaces DOWN.
   9.129 - */
   9.130 -#define BLKIF_DRIVER_STATUS_DOWN   0
   9.131 -#define BLKIF_DRIVER_STATUS_UP     1
   9.132 -typedef struct {
   9.133 -    /* IN */
   9.134 -    u32 status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   9.135 -    /* OUT */
   9.136 -    /*
   9.137 -     * Tells driver how many interfaces it should expect to immediately
   9.138 -     * receive notifications about.
   9.139 -     */
   9.140 -    u32 nr_interfaces; /*  4 */
   9.141 -} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
   9.142 -
   9.143 -/*
   9.144 - * CMSG_BLKIF_FE_INTERFACE_CONNECT:
   9.145 - *  If successful, the domain controller will acknowledge with a
   9.146 - *  STATUS_CONNECTED message.
   9.147 - */
   9.148 -typedef struct {
   9.149 -    u32      handle;      /*  0 */
   9.150 -    u32      __pad;
   9.151 -    memory_t shmem_frame; /*  8 */
   9.152 -    MEMORY_PADDING;
   9.153 -} PACKED blkif_fe_interface_connect_t; /* 16 bytes */
   9.154 -
   9.155 -/*
   9.156 - * CMSG_BLKIF_FE_INTERFACE_DISCONNECT:
   9.157 - *  If successful, the domain controller will acknowledge with a
   9.158 - *  STATUS_DISCONNECTED message.
   9.159 - */
   9.160 -typedef struct {
   9.161 -    u32 handle; /*  0 */
   9.162 -} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */
   9.163 -
   9.164 -
   9.165 -/******************************************************************************
   9.166 - * BLOCK-INTERFACE BACKEND DEFINITIONS
   9.167 - */
   9.168 -
   9.169 -/* Messages from domain controller. */
   9.170 -#define CMSG_BLKIF_BE_CREATE      0  /* Create a new block-device interface. */
   9.171 -#define CMSG_BLKIF_BE_DESTROY     1  /* Destroy a block-device interface.    */
   9.172 -#define CMSG_BLKIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   9.173 -#define CMSG_BLKIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   9.174 -#define CMSG_BLKIF_BE_VBD_CREATE  4  /* Create a new VBD for an interface.   */
   9.175 -#define CMSG_BLKIF_BE_VBD_DESTROY 5  /* Delete a VBD from an interface.      */
   9.176 -#define CMSG_BLKIF_BE_VBD_GROW    6  /* Append an extent to a given VBD.     */
   9.177 -#define CMSG_BLKIF_BE_VBD_SHRINK  7  /* Remove last extent from a given VBD. */
   9.178 -
   9.179 -/* Messages to domain controller. */
   9.180 -#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
   9.181 -
   9.182 -/*
   9.183 - * Message request/response definitions for block-device messages.
   9.184 - */
   9.185 -
   9.186 -typedef struct {
   9.187 -    blkif_sector_t sector_start;   /*  0 */
   9.188 -    blkif_sector_t sector_length;  /*  8 */
   9.189 -    blkif_pdev_t   device;         /* 16 */
   9.190 -    u16            __pad;          /* 18 */
   9.191 -} PACKED blkif_extent_t; /* 20 bytes */
   9.192 -
   9.193 -/* Non-specific 'okay' return. */
   9.194 -#define BLKIF_BE_STATUS_OKAY                0
   9.195 -/* Non-specific 'error' return. */
   9.196 -#define BLKIF_BE_STATUS_ERROR               1
   9.197 -/* The following are specific error returns. */
   9.198 -#define BLKIF_BE_STATUS_INTERFACE_EXISTS    2
   9.199 -#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   9.200 -#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4
   9.201 -#define BLKIF_BE_STATUS_VBD_EXISTS          5
   9.202 -#define BLKIF_BE_STATUS_VBD_NOT_FOUND       6
   9.203 -#define BLKIF_BE_STATUS_OUT_OF_MEMORY       7
   9.204 -#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND    8
   9.205 -#define BLKIF_BE_STATUS_MAPPING_ERROR       9
   9.206 -
   9.207 -/* This macro can be used to create an array of descriptive error strings. */
   9.208 -#define BLKIF_BE_STATUS_ERRORS {    \
   9.209 -    "Okay",                         \
   9.210 -    "Non-specific error",           \
   9.211 -    "Interface already exists",     \
   9.212 -    "Interface not found",          \
   9.213 -    "Interface is still connected", \
   9.214 -    "VBD already exists",           \
   9.215 -    "VBD not found",                \
   9.216 -    "Out of memory",                \
   9.217 -    "Extent not found for VBD",     \
   9.218 -    "Could not map domain memory" }
   9.219 -
   9.220 -/*
   9.221 - * CMSG_BLKIF_BE_CREATE:
   9.222 - *  When the driver sends a successful response then the interface is fully
   9.223 - *  created. The controller will send a DOWN notification to the front-end
   9.224 - *  driver.
   9.225 - */
   9.226 -typedef struct { 
   9.227 -    /* IN */
   9.228 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   9.229 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   9.230 -    /* OUT */
   9.231 -    u32        status;        /*  8 */
   9.232 -} PACKED blkif_be_create_t; /* 12 bytes */
   9.233 -
   9.234 -/*
   9.235 - * CMSG_BLKIF_BE_DESTROY:
   9.236 - *  When the driver sends a successful response then the interface is fully
   9.237 - *  torn down. The controller will send a DESTROYED notification to the
   9.238 - *  front-end driver.
   9.239 - */
   9.240 -typedef struct { 
   9.241 -    /* IN */
   9.242 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   9.243 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   9.244 -    /* OUT */
   9.245 -    u32        status;        /*  8 */
   9.246 -} PACKED blkif_be_destroy_t; /* 12 bytes */
   9.247 -
   9.248 -/*
   9.249 - * CMSG_BLKIF_BE_CONNECT:
   9.250 - *  When the driver sends a successful response then the interface is fully
   9.251 - *  connected. The controller will send a CONNECTED notification to the
   9.252 - *  front-end driver.
   9.253 - */
   9.254 -typedef struct { 
   9.255 -    /* IN */
   9.256 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   9.257 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   9.258 -    memory_t   shmem_frame;   /*  8: Page cont. shared comms window.     */
   9.259 -    MEMORY_PADDING;
   9.260 -    u32        evtchn;        /* 16: Event channel for notifications.    */
   9.261 -    /* OUT */
   9.262 -    u32        status;        /* 20 */
   9.263 -} PACKED blkif_be_connect_t;  /* 24 bytes */
   9.264 -
   9.265 -/*
   9.266 - * CMSG_BLKIF_BE_DISCONNECT:
   9.267 - *  When the driver sends a successful response then the interface is fully
   9.268 - *  disconnected. The controller will send a DOWN notification to the front-end
   9.269 - *  driver.
   9.270 - */
   9.271 -typedef struct { 
   9.272 -    /* IN */
   9.273 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   9.274 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   9.275 -    /* OUT */
   9.276 -    u32        status;        /*  8 */
   9.277 -} PACKED blkif_be_disconnect_t; /* 12 bytes */
   9.278 -
   9.279 -/* CMSG_BLKIF_BE_VBD_CREATE */
   9.280 -typedef struct { 
   9.281 -    /* IN */
   9.282 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   9.283 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   9.284 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id for this VBD. */
   9.285 -    u16        readonly;      /* 10: Non-zero -> VBD isn't writeable.    */
   9.286 -    /* OUT */
   9.287 -    u32        status;        /* 12 */
   9.288 -} PACKED blkif_be_vbd_create_t; /* 16 bytes */
   9.289 -
   9.290 -/* CMSG_BLKIF_BE_VBD_DESTROY */
   9.291 -typedef struct {
   9.292 -    /* IN */
   9.293 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   9.294 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   9.295 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   9.296 -    u16        __pad;         /* 10 */
   9.297 -    /* OUT */
   9.298 -    u32        status;        /* 12 */
   9.299 -} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
   9.300 -
   9.301 -/* CMSG_BLKIF_BE_VBD_GROW */
   9.302 -typedef struct { 
   9.303 -    /* IN */
   9.304 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   9.305 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   9.306 -    blkif_extent_t extent;    /*  8: Physical extent to append to VBD.   */
   9.307 -    blkif_vdev_t vdevice;     /* 28: Interface-specific id of the VBD.   */
   9.308 -    u16        __pad;         /* 30 */
   9.309 -    /* OUT */
   9.310 -    u32        status;        /* 32 */
   9.311 -} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
   9.312 -
   9.313 -/* CMSG_BLKIF_BE_VBD_SHRINK */
   9.314 -typedef struct { 
   9.315 -    /* IN */
   9.316 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   9.317 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   9.318 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   9.319 -    u16        __pad;         /* 10 */
   9.320 -    /* OUT */
   9.321 -    u32        status;        /* 12 */
   9.322 -} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
   9.323 -
   9.324 -/*
   9.325 - * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
   9.326 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   9.327 - *  If the driver goes DOWN while interfaces are still UP, the controller
   9.328 - *  will automatically send DOWN notifications.
   9.329 - */
   9.330 -typedef struct {
   9.331 -    u32        status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   9.332 -} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
   9.333 -
   9.334 -
   9.335 -/******************************************************************************
   9.336 - * NETWORK-INTERFACE FRONTEND DEFINITIONS
   9.337 - */
   9.338 -
   9.339 -/* Messages from domain controller to guest. */
   9.340 -#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED   0
   9.341 -
   9.342 -/* Messages from guest to domain controller. */
   9.343 -#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED     32
   9.344 -#define CMSG_NETIF_FE_INTERFACE_CONNECT         33
   9.345 -#define CMSG_NETIF_FE_INTERFACE_DISCONNECT      34
   9.346 -
   9.347 -/*
   9.348 - * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
   9.349 - *  Notify a guest about a status change on one of its network interfaces.
   9.350 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
   9.351 - *   1. The shared-memory frame is available for reuse.
   9.352 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   9.353 - */
   9.354 -#define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   9.355 -#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   9.356 -#define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   9.357 -typedef struct {
   9.358 -    u32        handle; /*  0 */
   9.359 -    u32        status; /*  4 */
   9.360 -    u16        evtchn; /*  8: status == NETIF_INTERFACE_STATUS_CONNECTED */
   9.361 -    u8         mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
   9.362 -} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */
   9.363 -
   9.364 -/*
   9.365 - * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   9.366 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   9.367 - *  When the driver goes DOWN then the controller will send no more
   9.368 - *  status-change notifications. When the driver comes UP then the controller
   9.369 - *  will send a notification for each interface that currently exists.
   9.370 - *  If the driver goes DOWN while interfaces are still UP, the domain
   9.371 - *  will automatically take the interfaces DOWN.
   9.372 - */
   9.373 -#define NETIF_DRIVER_STATUS_DOWN   0
   9.374 -#define NETIF_DRIVER_STATUS_UP     1
   9.375 -typedef struct {
   9.376 -    /* IN */
   9.377 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   9.378 -    /* OUT */
   9.379 -    /*
   9.380 -     * Tells driver how many interfaces it should expect to immediately
   9.381 -     * receive notifications about.
   9.382 -     */
   9.383 -    u32        nr_interfaces; /*  4 */
   9.384 -} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
   9.385 -
   9.386 -/*
   9.387 - * CMSG_NETIF_FE_INTERFACE_CONNECT:
   9.388 - *  If successful, the domain controller will acknowledge with a
   9.389 - *  STATUS_CONNECTED message.
   9.390 - */
   9.391 -typedef struct {
   9.392 -    u32        handle;         /*  0 */
   9.393 -    u32        __pad;          /*  4 */
   9.394 -    memory_t   tx_shmem_frame; /*  8 */
   9.395 -    MEMORY_PADDING;
   9.396 -    memory_t   rx_shmem_frame; /* 16 */
   9.397 -    MEMORY_PADDING;
   9.398 -} PACKED netif_fe_interface_connect_t; /* 24 bytes */
   9.399 -
   9.400 -/*
   9.401 - * CMSG_NETIF_FE_INTERFACE_DISCONNECT:
   9.402 - *  If successful, the domain controller will acknowledge with a
   9.403 - *  STATUS_DISCONNECTED message.
   9.404 - */
   9.405 -typedef struct {
   9.406 -    u32        handle;        /*  0 */
   9.407 -} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */
   9.408 -
   9.409 -
   9.410 -/******************************************************************************
   9.411 - * NETWORK-INTERFACE BACKEND DEFINITIONS
   9.412 - */
   9.413 -
   9.414 -/* Messages from domain controller. */
   9.415 -#define CMSG_NETIF_BE_CREATE      0  /* Create a new net-device interface. */
   9.416 -#define CMSG_NETIF_BE_DESTROY     1  /* Destroy a net-device interface.    */
   9.417 -#define CMSG_NETIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   9.418 -#define CMSG_NETIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   9.419 -
   9.420 -/* Messages to domain controller. */
   9.421 -#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
   9.422 -
   9.423 -/*
   9.424 - * Message request/response definitions for net-device messages.
   9.425 - */
   9.426 -
   9.427 -/* Non-specific 'okay' return. */
   9.428 -#define NETIF_BE_STATUS_OKAY                0
   9.429 -/* Non-specific 'error' return. */
   9.430 -#define NETIF_BE_STATUS_ERROR               1
   9.431 -/* The following are specific error returns. */
   9.432 -#define NETIF_BE_STATUS_INTERFACE_EXISTS    2
   9.433 -#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   9.434 -#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4
   9.435 -#define NETIF_BE_STATUS_OUT_OF_MEMORY       5
   9.436 -#define NETIF_BE_STATUS_MAPPING_ERROR       6
   9.437 -
   9.438 -/* This macro can be used to create an array of descriptive error strings. */
   9.439 -#define NETIF_BE_STATUS_ERRORS {    \
   9.440 -    "Okay",                         \
   9.441 -    "Non-specific error",           \
   9.442 -    "Interface already exists",     \
   9.443 -    "Interface not found",          \
   9.444 -    "Interface is still connected", \
   9.445 -    "Out of memory",                \
   9.446 -    "Could not map domain memory" }
   9.447 -
   9.448 -/*
   9.449 - * CMSG_NETIF_BE_CREATE:
   9.450 - *  When the driver sends a successful response then the interface is fully
   9.451 - *  created. The controller will send a DOWN notification to the front-end
   9.452 - *  driver.
   9.453 - */
   9.454 -typedef struct { 
   9.455 -    /* IN */
   9.456 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   9.457 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   9.458 -    u8         mac[6];        /*  8 */
   9.459 -    u16        __pad;         /* 14 */
   9.460 -    /* OUT */
   9.461 -    u32        status;        /* 16 */
   9.462 -} PACKED netif_be_create_t; /* 20 bytes */
   9.463 -
   9.464 -/*
   9.465 - * CMSG_NETIF_BE_DESTROY:
   9.466 - *  When the driver sends a successful response then the interface is fully
   9.467 - *  torn down. The controller will send a DESTROYED notification to the
   9.468 - *  front-end driver.
   9.469 - */
   9.470 -typedef struct { 
   9.471 -    /* IN */
   9.472 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   9.473 -    u32        netif_handle;  /*  4: ...ditto...                         */
   9.474 -    /* OUT */
   9.475 -    u32   status;             /*  8 */
   9.476 -} PACKED netif_be_destroy_t; /* 12 bytes */
   9.477 -
   9.478 -/*
   9.479 - * CMSG_NETIF_BE_CONNECT:
   9.480 - *  When the driver sends a successful response then the interface is fully
   9.481 - *  connected. The controller will send a CONNECTED notification to the
   9.482 - *  front-end driver.
   9.483 - */
   9.484 -typedef struct { 
   9.485 -    /* IN */
   9.486 -    domid_t    domid;          /*  0: Domain attached to new interface.   */
   9.487 -    u32        netif_handle;   /*  4: Domain-specific interface handle.   */
   9.488 -    memory_t   tx_shmem_frame; /*  8: Page cont. tx shared comms window.  */
   9.489 -    MEMORY_PADDING;
   9.490 -    memory_t   rx_shmem_frame; /* 16: Page cont. rx shared comms window.  */
   9.491 -    MEMORY_PADDING;
   9.492 -    u16        evtchn;         /* 24: Event channel for notifications.    */
   9.493 -    u16        __pad;          /* 26 */
   9.494 -    /* OUT */
   9.495 -    u32        status;         /* 28 */
   9.496 -} PACKED netif_be_connect_t; /* 32 bytes */
   9.497 -
   9.498 -/*
   9.499 - * CMSG_NETIF_BE_DISCONNECT:
   9.500 - *  When the driver sends a successful response then the interface is fully
   9.501 - *  disconnected. The controller will send a DOWN notification to the front-end
   9.502 - *  driver.
   9.503 - */
   9.504 -typedef struct { 
   9.505 -    /* IN */
   9.506 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   9.507 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   9.508 -    /* OUT */
   9.509 -    u32        status;        /*  8 */
   9.510 -} PACKED netif_be_disconnect_t; /* 12 bytes */
   9.511 -
   9.512 -/*
   9.513 - * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
   9.514 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   9.515 - *  If the driver goes DOWN while interfaces are still UP, the domain
   9.516 - *  will automatically send DOWN notifications.
   9.517 - */
   9.518 -typedef struct {
   9.519 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   9.520 -} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
   9.521 -
   9.522 -
   9.523 -/******************************************************************************
   9.524 - * SHUTDOWN DEFINITIONS
   9.525 - */
   9.526 -
   9.527 -/*
   9.528 - * Subtypes for shutdown messages.
   9.529 - */
   9.530 -#define CMSG_SHUTDOWN_POWEROFF  0   /* Clean shutdown (SHUTDOWN_poweroff).   */
   9.531 -#define CMSG_SHUTDOWN_REBOOT    1   /* Clean shutdown (SHUTDOWN_reboot).     */
   9.532 -#define CMSG_SHUTDOWN_SUSPEND   2   /* Create suspend info, then             */
   9.533 -                                    /* SHUTDOWN_suspend.                     */
   9.534 -
   9.535 -#endif /* __DOMAIN_CONTROLLER_H__ */
    10.1 --- a/tools/python/xen/ext/xu/xu.c	Tue Jun 29 21:08:51 2004 +0000
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,1386 +0,0 @@
    10.4 -/******************************************************************************
    10.5 - * utils.c
    10.6 - * 
    10.7 - * Copyright (c) 2004, K A Fraser
    10.8 - */
    10.9 -
   10.10 -#include <Python.h>
   10.11 -#include <stdio.h>
   10.12 -#include <stdlib.h>
   10.13 -#include <string.h>
   10.14 -#include <sys/ioctl.h>
   10.15 -#include <sys/types.h>
   10.16 -#include <sys/wait.h>
   10.17 -#include <sys/stat.h>
   10.18 -#include <sys/socket.h>
   10.19 -#include <sys/mman.h>
   10.20 -#include <sys/poll.h>
   10.21 -#include <netinet/in.h>
   10.22 -#include <fcntl.h>
   10.23 -#include <unistd.h>
   10.24 -#include <errno.h>
   10.25 -#include <signal.h>
   10.26 -#include <xc.h>
   10.27 -
   10.28 -#include <hypervisor-if.h>
   10.29 -#include "domain_controller.h"
   10.30 -
   10.31 -#include <asm-xen/proc_cmd.h>
   10.32 -
   10.33 -#define XENPKG "xen.ext.xu"
   10.34 -
   10.35 -/* Needed for Python versions earlier than 2.3. */
   10.36 -#ifndef PyMODINIT_FUNC
   10.37 -#define PyMODINIT_FUNC DL_EXPORT(void)
   10.38 -#endif
   10.39 -
   10.40 -/* NB. The following should be kept in sync with the kernel's evtchn driver. */
   10.41 -#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
   10.42 -#define EVTCHN_DEV_MAJOR 10
   10.43 -#define EVTCHN_DEV_MINOR 200
   10.44 -#define PORT_NORMAL     0x0000   /* A standard event notification.      */ 
   10.45 -#define PORT_EXCEPTION  0x8000   /* An exceptional notification.        */
   10.46 -#define PORTIDX_MASK    0x7fff   /* Strip subtype to obtain port index. */
   10.47 -/* /dev/xen/evtchn ioctls: */
   10.48 -/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
   10.49 -#define EVTCHN_RESET  _IO('E', 1)
   10.50 -/* EVTCHN_BIND: Bind to teh specified event-channel port. */
   10.51 -#define EVTCHN_BIND   _IO('E', 2)
   10.52 -/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
   10.53 -#define EVTCHN_UNBIND _IO('E', 3)
   10.54 -
   10.55 -/* Size of a machine page frame. */
   10.56 -#define PAGE_SIZE 4096
   10.57 -
   10.58 -
   10.59 -/*
   10.60 - * *********************** NOTIFIER ***********************
   10.61 - */
   10.62 -
   10.63 -typedef struct {
   10.64 -    PyObject_HEAD;
   10.65 -    int evtchn_fd;
   10.66 -} xu_notifier_object;
   10.67 -
   10.68 -static PyObject *xu_notifier_read(PyObject *self, PyObject *args)
   10.69 -{
   10.70 -    xu_notifier_object *xun = (xu_notifier_object *)self;
   10.71 -    u16 v;
   10.72 -    int bytes;
   10.73 -
   10.74 -    if ( !PyArg_ParseTuple(args, "") )
   10.75 -        return NULL;
   10.76 -    
   10.77 -    while ( (bytes = read(xun->evtchn_fd, &v, sizeof(v))) == -1 )
   10.78 -    {
   10.79 -        if ( errno == EINTR )
   10.80 -            continue;
   10.81 -        if ( errno == EAGAIN )
   10.82 -            goto none;
   10.83 -        return PyErr_SetFromErrno(PyExc_IOError);
   10.84 -    }
   10.85 -    
   10.86 -    if ( bytes == sizeof(v) )
   10.87 -        return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK);
   10.88 -
   10.89 - none:
   10.90 -    Py_INCREF(Py_None);
   10.91 -    return Py_None;
   10.92 -}
   10.93 -
   10.94 -static PyObject *xu_notifier_unmask(PyObject *self, PyObject *args)
   10.95 -{
   10.96 -    xu_notifier_object *xun = (xu_notifier_object *)self;
   10.97 -    u16 v;
   10.98 -    int idx;
   10.99 -
  10.100 -    if ( !PyArg_ParseTuple(args, "i", &idx) )
  10.101 -        return NULL;
  10.102 -
  10.103 -    v = (u16)idx;
  10.104 -    
  10.105 -    (void)write(xun->evtchn_fd, &v, sizeof(v));
  10.106 -
  10.107 -    Py_INCREF(Py_None);
  10.108 -    return Py_None;
  10.109 -}
  10.110 -
  10.111 -static PyObject *xu_notifier_bind(PyObject *self, PyObject *args)
  10.112 -{
  10.113 -    xu_notifier_object *xun = (xu_notifier_object *)self;
  10.114 -    int idx;
  10.115 -
  10.116 -    if ( !PyArg_ParseTuple(args, "i", &idx) )
  10.117 -        return NULL;
  10.118 -
  10.119 -    if ( ioctl(xun->evtchn_fd, EVTCHN_BIND, idx) != 0 )
  10.120 -        return PyErr_SetFromErrno(PyExc_IOError);
  10.121 -
  10.122 -    Py_INCREF(Py_None);
  10.123 -    return Py_None;
  10.124 -}
  10.125 -
  10.126 -static PyObject *xu_notifier_unbind(PyObject *self, PyObject *args)
  10.127 -{
  10.128 -    xu_notifier_object *xun = (xu_notifier_object *)self;
  10.129 -    int idx;
  10.130 -
  10.131 -    if ( !PyArg_ParseTuple(args, "i", &idx) )
  10.132 -        return NULL;
  10.133 -
  10.134 -    if ( ioctl(xun->evtchn_fd, EVTCHN_UNBIND, idx) != 0 )
  10.135 -        return PyErr_SetFromErrno(PyExc_IOError);
  10.136 -
  10.137 -    Py_INCREF(Py_None);
  10.138 -    return Py_None;
  10.139 -}
  10.140 -
  10.141 -static PyObject *xu_notifier_fileno(PyObject *self, PyObject *args)
  10.142 -{
  10.143 -    xu_notifier_object *xun = (xu_notifier_object *)self;
  10.144 -    return PyInt_FromLong(xun->evtchn_fd);
  10.145 -}
  10.146 -
  10.147 -static PyMethodDef xu_notifier_methods[] = {
  10.148 -    { "read",
  10.149 -      (PyCFunction)xu_notifier_read,
  10.150 -      METH_VARARGS,
  10.151 -      "Read a (@port, @type) pair.\n" },
  10.152 -
  10.153 -    { "unmask", 
  10.154 -      (PyCFunction)xu_notifier_unmask,
  10.155 -      METH_VARARGS,
  10.156 -      "Unmask notifications for a @port.\n" },
  10.157 -
  10.158 -    { "bind", 
  10.159 -      (PyCFunction)xu_notifier_bind,
  10.160 -      METH_VARARGS,
  10.161 -      "Get notifications for a @port.\n" },
  10.162 -
  10.163 -    { "unbind", 
  10.164 -      (PyCFunction)xu_notifier_unbind,
  10.165 -      METH_VARARGS,
  10.166 -      "No longer get notifications for a @port.\n" },
  10.167 -
  10.168 -    { "fileno", 
  10.169 -      (PyCFunction)xu_notifier_fileno,
  10.170 -      METH_VARARGS,
  10.171 -      "Return the file descriptor for the notification channel.\n" },
  10.172 -
  10.173 -    { NULL, NULL, 0, NULL }
  10.174 -};
  10.175 -
  10.176 -staticforward PyTypeObject xu_notifier_type;
  10.177 -
  10.178 -static PyObject *xu_notifier_new(PyObject *self, PyObject *args)
  10.179 -{
  10.180 -    xu_notifier_object *xun;
  10.181 -
  10.182 -    if ( !PyArg_ParseTuple(args, "") )
  10.183 -        return NULL;
  10.184 -
  10.185 -    xun = PyObject_New(xu_notifier_object, &xu_notifier_type);
  10.186 -
  10.187 - reopen:
  10.188 -    xun->evtchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
  10.189 -    if ( xun->evtchn_fd == -1 )
  10.190 -    {
  10.191 -        if ( (errno == ENOENT) &&
  10.192 -             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
  10.193 -             (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, 
  10.194 -                    (EVTCHN_DEV_MAJOR << 8) | EVTCHN_DEV_MINOR) == 0) )
  10.195 -            goto reopen;
  10.196 -        PyObject_Del((PyObject *)xun);
  10.197 -        return PyErr_SetFromErrno(PyExc_IOError);
  10.198 -    }
  10.199 -
  10.200 -    return (PyObject *)xun;
  10.201 -}
  10.202 -
  10.203 -static PyObject *xu_notifier_getattr(PyObject *obj, char *name)
  10.204 -{
  10.205 -    if ( strcmp(name, "EXCEPTION") == 0 )
  10.206 -        return PyInt_FromLong(PORT_EXCEPTION);
  10.207 -    if ( strcmp(name, "NORMAL") == 0 )
  10.208 -        return PyInt_FromLong(PORT_NORMAL);
  10.209 -    return Py_FindMethod(xu_notifier_methods, obj, name);
  10.210 -}
  10.211 -
  10.212 -static void xu_notifier_dealloc(PyObject *self)
  10.213 -{
  10.214 -    xu_notifier_object *xun = (xu_notifier_object *)self;
  10.215 -    (void)close(xun->evtchn_fd);
  10.216 -    PyObject_Del(self);
  10.217 -}
  10.218 -
  10.219 -static PyTypeObject xu_notifier_type = {
  10.220 -    PyObject_HEAD_INIT(&PyType_Type)
  10.221 -    0,
  10.222 -    "notifier",
  10.223 -    sizeof(xu_notifier_object),
  10.224 -    0,
  10.225 -    xu_notifier_dealloc, /* tp_dealloc     */
  10.226 -    NULL,                /* tp_print       */
  10.227 -    xu_notifier_getattr, /* tp_getattr     */
  10.228 -    NULL,                /* tp_setattr     */
  10.229 -    NULL,                /* tp_compare     */
  10.230 -    NULL,                /* tp_repr        */
  10.231 -    NULL,                /* tp_as_number   */
  10.232 -    NULL,                /* tp_as_sequence */
  10.233 -    NULL,                /* tp_as_mapping  */
  10.234 -    NULL                 /* tp_hash        */
  10.235 -};
  10.236 -
  10.237 -
  10.238 -
  10.239 -/*
  10.240 - * *********************** MESSAGE ***********************
  10.241 - */
  10.242 -
  10.243 -#define TYPE(_x,_y) (((_x)<<8)|(_y))
  10.244 -#define P2C(_struct, _field, _ctype)                                      \
  10.245 -    do {                                                                  \
  10.246 -        PyObject *obj;                                                    \
  10.247 -        if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL )     \
  10.248 -        {                                                                 \
  10.249 -            if ( PyInt_Check(obj) )                                       \
  10.250 -            {                                                             \
  10.251 -                ((_struct *)&xum->msg.msg[0])->_field =                   \
  10.252 -                  (_ctype)PyInt_AsLong(obj);                              \
  10.253 -                dict_items_parsed++;                                      \
  10.254 -            }                                                             \
  10.255 -            else if ( PyLong_Check(obj) )                                 \
  10.256 -            {                                                             \
  10.257 -                ((_struct *)&xum->msg.msg[0])->_field =                   \
  10.258 -                  (_ctype)PyLong_AsUnsignedLongLong(obj);                 \
  10.259 -                dict_items_parsed++;                                      \
  10.260 -            }                                                             \
  10.261 -        }                                                                 \
  10.262 -        xum->msg.length = sizeof(_struct);                                \
  10.263 -    } while ( 0 )
  10.264 -#define C2P(_struct, _field, _pytype, _ctype)                             \
  10.265 -    do {                                                                  \
  10.266 -        PyObject *obj = Py ## _pytype ## _From ## _ctype                  \
  10.267 -                        (((_struct *)&xum->msg.msg[0])->_field);          \
  10.268 -        if ( dict == NULL ) dict = PyDict_New();                          \
  10.269 -        PyDict_SetItemString(dict, #_field, obj);                         \
  10.270 -    } while ( 0 )
  10.271 -
  10.272 -typedef struct {
  10.273 -    PyObject_HEAD;
  10.274 -    control_msg_t msg;
  10.275 -} xu_message_object;
  10.276 -
  10.277 -static PyObject *xu_message_append_payload(PyObject *self, PyObject *args)
  10.278 -{
  10.279 -    xu_message_object *xum = (xu_message_object *)self;
  10.280 -    char *str;
  10.281 -    int len;
  10.282 -
  10.283 -    if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
  10.284 -        return NULL;
  10.285 -
  10.286 -    if ( (len + xum->msg.length) > sizeof(xum->msg.msg) )
  10.287 -    {
  10.288 -        PyErr_SetString(PyExc_RuntimeError, "out of space in control message");
  10.289 -        return NULL;
  10.290 -    }
  10.291 -
  10.292 -    memcpy(&xum->msg.msg[xum->msg.length], str, len);
  10.293 -    xum->msg.length += len;
  10.294 -
  10.295 -    Py_INCREF(Py_None);
  10.296 -    return Py_None;
  10.297 -}
  10.298 -
  10.299 -static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args)
  10.300 -{
  10.301 -    xu_message_object *xum = (xu_message_object *)self;
  10.302 -    PyObject *payload;
  10.303 -    int dict_items_parsed = 0;
  10.304 -
  10.305 -    if ( !PyArg_ParseTuple(args, "O", &payload) )
  10.306 -        return NULL;
  10.307 -
  10.308 -    if ( !PyDict_Check(payload) )
  10.309 -    {
  10.310 -        PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
  10.311 -        return NULL;
  10.312 -    }
  10.313 -
  10.314 -    switch ( TYPE(xum->msg.type, xum->msg.subtype) )
  10.315 -    {
  10.316 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
  10.317 -        P2C(blkif_fe_driver_status_changed_t, nr_interfaces, u32);
  10.318 -        break;
  10.319 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  10.320 -        P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
  10.321 -        break;
  10.322 -    }
  10.323 -
  10.324 -    if ( dict_items_parsed != PyDict_Size(payload) )
  10.325 -    {
  10.326 -        PyErr_SetString(PyExc_TypeError, "payload contains bad items");
  10.327 -        return NULL;
  10.328 -    }
  10.329 -
  10.330 -    Py_INCREF(Py_None);
  10.331 -    return Py_None;
  10.332 -}
  10.333 -
  10.334 -static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
  10.335 -{
  10.336 -    xu_message_object *xum = (xu_message_object *)self;
  10.337 -    PyObject *dict = NULL;
  10.338 -
  10.339 -    if ( !PyArg_ParseTuple(args, "") )
  10.340 -        return NULL;
  10.341 -
  10.342 -    switch ( TYPE(xum->msg.type, xum->msg.subtype) )
  10.343 -    {
  10.344 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
  10.345 -        C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
  10.346 -        C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
  10.347 -        C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
  10.348 -        return dict;
  10.349 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
  10.350 -        C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
  10.351 -        return dict;
  10.352 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
  10.353 -        C2P(blkif_fe_interface_connect_t, handle,      Int, Long);
  10.354 -        C2P(blkif_fe_interface_connect_t, shmem_frame, Int, Long);
  10.355 -        return dict;
  10.356 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_DISCONNECT):
  10.357 -        C2P(blkif_fe_interface_disconnect_t, handle, Int, Long);
  10.358 -        return dict;
  10.359 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
  10.360 -        C2P(blkif_be_create_t, domid,        Int, Long);
  10.361 -        C2P(blkif_be_create_t, blkif_handle, Int, Long);
  10.362 -        C2P(blkif_be_create_t, status,       Int, Long);
  10.363 -        return dict;
  10.364 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
  10.365 -        C2P(blkif_be_destroy_t, domid,        Int, Long);
  10.366 -        C2P(blkif_be_destroy_t, blkif_handle, Int, Long);
  10.367 -        C2P(blkif_be_destroy_t, status,       Int, Long);
  10.368 -        return dict;
  10.369 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
  10.370 -        C2P(blkif_be_connect_t, domid,        Int, Long);
  10.371 -        C2P(blkif_be_connect_t, blkif_handle, Int, Long);
  10.372 -        C2P(blkif_be_connect_t, shmem_frame,  Int, Long);
  10.373 -        C2P(blkif_be_connect_t, evtchn,       Int, Long);
  10.374 -        C2P(blkif_be_connect_t, status,       Int, Long);
  10.375 -        return dict;
  10.376 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
  10.377 -        C2P(blkif_be_disconnect_t, domid,        Int, Long);
  10.378 -        C2P(blkif_be_disconnect_t, blkif_handle, Int, Long);
  10.379 -        C2P(blkif_be_disconnect_t, status,       Int, Long);
  10.380 -        return dict;
  10.381 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
  10.382 -        C2P(blkif_be_vbd_create_t, domid,        Int, Long);
  10.383 -        C2P(blkif_be_vbd_create_t, blkif_handle, Int, Long);
  10.384 -        C2P(blkif_be_vbd_create_t, vdevice,      Int, Long);
  10.385 -        C2P(blkif_be_vbd_create_t, readonly,     Int, Long);
  10.386 -        C2P(blkif_be_vbd_create_t, status,       Int, Long);
  10.387 -        return dict;
  10.388 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
  10.389 -        C2P(blkif_be_vbd_destroy_t, domid,        Int, Long);
  10.390 -        C2P(blkif_be_vbd_destroy_t, blkif_handle, Int, Long);
  10.391 -        C2P(blkif_be_vbd_destroy_t, vdevice,      Int, Long);
  10.392 -        C2P(blkif_be_vbd_destroy_t, status,       Int, Long);
  10.393 -        return dict;
  10.394 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
  10.395 -        C2P(blkif_be_vbd_grow_t, domid,         Int, Long);
  10.396 -        C2P(blkif_be_vbd_grow_t, blkif_handle,  Int, Long);
  10.397 -        C2P(blkif_be_vbd_grow_t, vdevice,       Int, Long);
  10.398 -        C2P(blkif_be_vbd_grow_t, extent.sector_start, 
  10.399 -             Long, UnsignedLongLong);
  10.400 -        C2P(blkif_be_vbd_grow_t, extent.sector_length, 
  10.401 -             Long, UnsignedLongLong);
  10.402 -        C2P(blkif_be_vbd_grow_t, extent.device, Int, Long);
  10.403 -        C2P(blkif_be_vbd_grow_t, status,        Int, Long);
  10.404 -        return dict;
  10.405 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
  10.406 -        C2P(blkif_be_vbd_shrink_t, domid,        Int, Long);
  10.407 -        C2P(blkif_be_vbd_shrink_t, blkif_handle, Int, Long);
  10.408 -        C2P(blkif_be_vbd_shrink_t, vdevice,      Int, Long);
  10.409 -        C2P(blkif_be_vbd_shrink_t, status,       Int, Long);
  10.410 -        return dict;
  10.411 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
  10.412 -        C2P(blkif_be_driver_status_changed_t, status, Int, Long);
  10.413 -        return dict;
  10.414 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
  10.415 -        C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
  10.416 -        C2P(netif_fe_interface_status_changed_t, status, Int, Long);
  10.417 -        C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
  10.418 -        return dict;
  10.419 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  10.420 -        C2P(netif_fe_driver_status_changed_t, status,        Int, Long);
  10.421 -        C2P(netif_fe_driver_status_changed_t, nr_interfaces, Int, Long);
  10.422 -        return dict;
  10.423 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
  10.424 -        C2P(netif_fe_interface_connect_t, handle,         Int, Long);
  10.425 -        C2P(netif_fe_interface_connect_t, tx_shmem_frame, Int, Long);
  10.426 -        C2P(netif_fe_interface_connect_t, rx_shmem_frame, Int, Long);
  10.427 -        return dict;
  10.428 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_DISCONNECT):
  10.429 -        C2P(netif_fe_interface_disconnect_t, handle, Int, Long);
  10.430 -        return dict;
  10.431 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
  10.432 -        C2P(netif_be_create_t, domid,        Int, Long);
  10.433 -        C2P(netif_be_create_t, netif_handle, Int, Long);
  10.434 -        C2P(netif_be_create_t, status,       Int, Long);
  10.435 -        return dict;
  10.436 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
  10.437 -        C2P(netif_be_destroy_t, domid,        Int, Long);
  10.438 -        C2P(netif_be_destroy_t, netif_handle, Int, Long);
  10.439 -        C2P(netif_be_destroy_t, status,       Int, Long);
  10.440 -        return dict;
  10.441 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
  10.442 -        C2P(netif_be_connect_t, domid,          Int, Long);
  10.443 -        C2P(netif_be_connect_t, netif_handle,   Int, Long);
  10.444 -        C2P(netif_be_connect_t, tx_shmem_frame, Int, Long);
  10.445 -        C2P(netif_be_connect_t, rx_shmem_frame, Int, Long);
  10.446 -        C2P(netif_be_connect_t, evtchn,         Int, Long);
  10.447 -        C2P(netif_be_connect_t, status,         Int, Long);
  10.448 -        return dict;
  10.449 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
  10.450 -        C2P(netif_be_disconnect_t, domid,        Int, Long);
  10.451 -        C2P(netif_be_disconnect_t, netif_handle, Int, Long);
  10.452 -        C2P(netif_be_disconnect_t, status,       Int, Long);
  10.453 -        return dict;
  10.454 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
  10.455 -        C2P(netif_be_driver_status_changed_t, status, Int, Long);
  10.456 -        return dict;
  10.457 -    }
  10.458 -
  10.459 -    return PyString_FromStringAndSize(xum->msg.msg, xum->msg.length);
  10.460 -}
  10.461 -
  10.462 -static PyObject *xu_message_get_header(PyObject *self, PyObject *args)
  10.463 -{
  10.464 -    xu_message_object *xum = (xu_message_object *)self;
  10.465 -
  10.466 -    if ( !PyArg_ParseTuple(args, "") )
  10.467 -        return NULL;
  10.468 -
  10.469 -    return Py_BuildValue("{s:i,s:i,s:i}",
  10.470 -                         "type",    xum->msg.type,
  10.471 -                         "subtype", xum->msg.subtype,
  10.472 -                         "id",      xum->msg.id);
  10.473 -}
  10.474 -
  10.475 -static PyMethodDef xu_message_methods[] = {
  10.476 -    { "append_payload", 
  10.477 -      (PyCFunction)xu_message_append_payload,
  10.478 -      METH_VARARGS,
  10.479 -      "Append @str to the message payload.\n" },
  10.480 -
  10.481 -    { "set_response_fields",
  10.482 -      (PyCFunction)xu_message_set_response_fields,
  10.483 -      METH_VARARGS,
  10.484 -      "Fill in the response fields in a message that was passed to us.\n" },
  10.485 -
  10.486 -    { "get_payload",
  10.487 -      (PyCFunction)xu_message_get_payload,
  10.488 -      METH_VARARGS,
  10.489 -      "Return the message payload in string form.\n" },
  10.490 -
  10.491 -    { "get_header",
  10.492 -      (PyCFunction)xu_message_get_header,
  10.493 -      METH_VARARGS,
  10.494 -      "Returns a dictionary of values for @type, @subtype, and @id.\n" },
  10.495 -
  10.496 -    { NULL, NULL, 0, NULL }
  10.497 -};
  10.498 -
  10.499 -staticforward PyTypeObject xu_message_type;
  10.500 -
  10.501 -static PyObject *xu_message_new(PyObject *self, PyObject *args)
  10.502 -{
  10.503 -    xu_message_object *xum;
  10.504 -    int type, subtype, id, dict_items_parsed = 0;
  10.505 -    PyObject *payload = NULL;
  10.506 -
  10.507 -    if ( !PyArg_ParseTuple(args, "iii|O", &type, &subtype, &id, &payload) )
  10.508 -        return NULL;
  10.509 -
  10.510 -    xum = PyObject_New(xu_message_object, &xu_message_type);
  10.511 -
  10.512 -    xum->msg.type    = type;
  10.513 -    xum->msg.subtype = subtype;
  10.514 -    xum->msg.id      = id;
  10.515 -    xum->msg.length  = 0;
  10.516 -
  10.517 -    if ( payload == NULL )
  10.518 -        return (PyObject *)xum;
  10.519 -
  10.520 -    if ( !PyDict_Check(payload) )
  10.521 -    {
  10.522 -        PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
  10.523 -        PyObject_Del((PyObject *)xum);
  10.524 -        return NULL;
  10.525 -    }
  10.526 -
  10.527 -    switch ( TYPE(type, subtype) )
  10.528 -    {
  10.529 -    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
  10.530 -        P2C(blkif_fe_interface_status_changed_t, handle, u32);
  10.531 -        P2C(blkif_fe_interface_status_changed_t, status, u32);
  10.532 -        P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
  10.533 -        break;
  10.534 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
  10.535 -        P2C(blkif_be_create_t, domid,        u32);
  10.536 -        P2C(blkif_be_create_t, blkif_handle, u32);
  10.537 -        break;
  10.538 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
  10.539 -        P2C(blkif_be_destroy_t, domid,        u32);
  10.540 -        P2C(blkif_be_destroy_t, blkif_handle, u32);
  10.541 -        break;
  10.542 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
  10.543 -        P2C(blkif_be_connect_t, domid,        u32);
  10.544 -        P2C(blkif_be_connect_t, blkif_handle, u32);
  10.545 -        P2C(blkif_be_connect_t, shmem_frame,  memory_t);
  10.546 -        P2C(blkif_be_connect_t, evtchn,       u16);
  10.547 -        break;
  10.548 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
  10.549 -        P2C(blkif_be_disconnect_t, domid,        u32);
  10.550 -        P2C(blkif_be_disconnect_t, blkif_handle, u32);
  10.551 -        break;
  10.552 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
  10.553 -        P2C(blkif_be_vbd_create_t, domid,        u32);
  10.554 -        P2C(blkif_be_vbd_create_t, blkif_handle, u32);
  10.555 -        P2C(blkif_be_vbd_create_t, vdevice,      blkif_vdev_t);
  10.556 -        P2C(blkif_be_vbd_create_t, readonly,     u16);
  10.557 -        break;
  10.558 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
  10.559 -        P2C(blkif_be_vbd_destroy_t, domid,        u32);
  10.560 -        P2C(blkif_be_vbd_destroy_t, blkif_handle, u32);
  10.561 -        P2C(blkif_be_vbd_destroy_t, vdevice,      blkif_vdev_t);
  10.562 -        break;
  10.563 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
  10.564 -        P2C(blkif_be_vbd_grow_t, domid,                u32);
  10.565 -        P2C(blkif_be_vbd_grow_t, blkif_handle,         u32);
  10.566 -        P2C(blkif_be_vbd_grow_t, vdevice,              blkif_vdev_t);
  10.567 -        P2C(blkif_be_vbd_grow_t, extent.sector_start,  blkif_sector_t);
  10.568 -        P2C(blkif_be_vbd_grow_t, extent.sector_length, blkif_sector_t);
  10.569 -        P2C(blkif_be_vbd_grow_t, extent.device,        blkif_pdev_t);
  10.570 -        break;
  10.571 -    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
  10.572 -        P2C(blkif_be_vbd_shrink_t, domid,        u32);
  10.573 -        P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
  10.574 -        P2C(blkif_be_vbd_shrink_t, vdevice,      blkif_vdev_t);
  10.575 -        break;
  10.576 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
  10.577 -        P2C(netif_fe_interface_status_changed_t, handle, u32);
  10.578 -        P2C(netif_fe_interface_status_changed_t, status, u32);
  10.579 -        P2C(netif_fe_interface_status_changed_t, evtchn, u16);
  10.580 -        P2C(netif_fe_interface_status_changed_t, mac[0], u8);
  10.581 -        P2C(netif_fe_interface_status_changed_t, mac[1], u8);
  10.582 -        P2C(netif_fe_interface_status_changed_t, mac[2], u8);
  10.583 -        P2C(netif_fe_interface_status_changed_t, mac[3], u8);
  10.584 -        P2C(netif_fe_interface_status_changed_t, mac[4], u8);
  10.585 -        P2C(netif_fe_interface_status_changed_t, mac[5], u8);
  10.586 -        break;
  10.587 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
  10.588 -        P2C(netif_be_create_t, domid,        u32);
  10.589 -        P2C(netif_be_create_t, netif_handle, u32);
  10.590 -        P2C(netif_be_create_t, mac[0],       u8);
  10.591 -        P2C(netif_be_create_t, mac[1],       u8);
  10.592 -        P2C(netif_be_create_t, mac[2],       u8);
  10.593 -        P2C(netif_be_create_t, mac[3],       u8);
  10.594 -        P2C(netif_be_create_t, mac[4],       u8);
  10.595 -        P2C(netif_be_create_t, mac[5],       u8);
  10.596 -        break;
  10.597 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
  10.598 -        P2C(netif_be_destroy_t, domid,        u32);
  10.599 -        P2C(netif_be_destroy_t, netif_handle, u32);
  10.600 -        break;
  10.601 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
  10.602 -        P2C(netif_be_connect_t, domid,          u32);
  10.603 -        P2C(netif_be_connect_t, netif_handle,   u32);
  10.604 -        P2C(netif_be_connect_t, tx_shmem_frame, memory_t);
  10.605 -        P2C(netif_be_connect_t, rx_shmem_frame, memory_t);
  10.606 -        P2C(netif_be_connect_t, evtchn,         u16);
  10.607 -        break;
  10.608 -    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
  10.609 -        P2C(netif_be_disconnect_t, domid,        u32);
  10.610 -        P2C(netif_be_disconnect_t, netif_handle, u32);
  10.611 -        break;
  10.612 -    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  10.613 -        P2C(netif_fe_driver_status_changed_t, status,        u32);
  10.614 -        P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
  10.615 -        break;
  10.616 -    }
  10.617 -
  10.618 -    if ( dict_items_parsed != PyDict_Size(payload) )
  10.619 -    {
  10.620 -        PyErr_SetString(PyExc_TypeError, "payload contains bad items");
  10.621 -        PyObject_Del((PyObject *)xum);
  10.622 -        return NULL;
  10.623 -    }
  10.624 -
  10.625 -    return (PyObject *)xum;
  10.626 -}
  10.627 -
  10.628 -static PyObject *xu_message_getattr(PyObject *obj, char *name)
  10.629 -{
  10.630 -    xu_message_object *xum;
  10.631 -    if ( strcmp(name, "MAX_PAYLOAD") == 0 )
  10.632 -        return PyInt_FromLong(sizeof(xum->msg.msg));
  10.633 -    return Py_FindMethod(xu_message_methods, obj, name);
  10.634 -}
  10.635 -
  10.636 -static void xu_message_dealloc(PyObject *self)
  10.637 -{
  10.638 -    PyObject_Del(self);
  10.639 -}
  10.640 -
  10.641 -static PyTypeObject xu_message_type = {
  10.642 -    PyObject_HEAD_INIT(&PyType_Type)
  10.643 -    0,
  10.644 -    "message",
  10.645 -    sizeof(xu_message_object),
  10.646 -    0,
  10.647 -    xu_message_dealloc,   /* tp_dealloc     */
  10.648 -    NULL,                /* tp_print       */
  10.649 -    xu_message_getattr,   /* tp_getattr     */
  10.650 -    NULL,                /* tp_setattr     */
  10.651 -    NULL,                /* tp_compare     */
  10.652 -    NULL,                /* tp_repr        */
  10.653 -    NULL,                /* tp_as_number   */
  10.654 -    NULL,                /* tp_as_sequence */
  10.655 -    NULL,                /* tp_as_mapping  */
  10.656 -    NULL                 /* tp_hash        */
  10.657 -};
  10.658 -
  10.659 -
  10.660 -
  10.661 -/*
  10.662 - * *********************** PORT ***********************
  10.663 - */
  10.664 -
  10.665 -static control_if_t *map_control_interface(int fd, unsigned long pfn)
  10.666 -{
  10.667 -    char *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
  10.668 -                       MAP_SHARED, fd, pfn * PAGE_SIZE);
  10.669 -    if ( vaddr == MAP_FAILED )
  10.670 -        return NULL;
  10.671 -    return (control_if_t *)(vaddr + 2048);
  10.672 -}
  10.673 -static void unmap_control_interface(int fd, control_if_t *c)
  10.674 -{
  10.675 -    char *vaddr = (char *)c - 2048;
  10.676 -    (void)munmap(vaddr, PAGE_SIZE);
  10.677 -}
  10.678 -
  10.679 -typedef struct xu_port_object {
  10.680 -    PyObject_HEAD;
  10.681 -    int mem_fd;
  10.682 -    int xc_handle;
  10.683 -    u32 remote_dom;
  10.684 -    int local_port, remote_port;
  10.685 -    control_if_t    *interface;
  10.686 -    CONTROL_RING_IDX tx_req_cons, tx_resp_prod;
  10.687 -    CONTROL_RING_IDX rx_req_prod, rx_resp_cons;
  10.688 -} xu_port_object;
  10.689 -
  10.690 -static PyObject *port_error;
  10.691 -
  10.692 -static int xup_connect(xu_port_object *xup, domid_t dom,
  10.693 -                       int local_port, int remote_port){
  10.694 -    // From our prespective rx = producer, tx = consumer.
  10.695 -    int err = 0;
  10.696 -    printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom, 
  10.697 -           local_port, remote_port);
  10.698 -
  10.699 -    // Consumer = tx.
  10.700 -    //xup->interface->tx_resp_prod = 0;
  10.701 -    //xup->interface->tx_req_prod = 0;
  10.702 -    xup->tx_resp_prod = xup->interface->tx_resp_prod;
  10.703 -    xup->tx_req_cons = xup->interface->tx_resp_prod;
  10.704 -    printf("%s> tx: %u %u : %u %u\n", __FUNCTION__,
  10.705 -           (unsigned int)xup->interface->tx_resp_prod,
  10.706 -           (unsigned int)xup->tx_resp_prod,
  10.707 -           (unsigned int)xup->tx_req_cons,
  10.708 -           (unsigned int)xup->interface->tx_req_prod);
  10.709 -
  10.710 -    // Producer = rx.
  10.711 -    //xup->interface->rx_req_prod  = 0;
  10.712 -    //xup->interface->rx_resp_prod = 0;
  10.713 -    xup->rx_req_prod  = xup->interface->rx_req_prod;
  10.714 -    xup->rx_resp_cons = xup->interface->rx_resp_prod;
  10.715 -    printf("%s> rx: %u %u : %u %u\n", __FUNCTION__,
  10.716 -           (unsigned int)xup->rx_resp_cons,
  10.717 -           (unsigned int)xup->interface->rx_resp_prod,
  10.718 -           (unsigned int)xup->interface->rx_req_prod,
  10.719 -           (unsigned int)xup->rx_req_prod);
  10.720 -
  10.721 -    xup->remote_dom   = dom;
  10.722 -    xup->local_port   = local_port;
  10.723 -    xup->remote_port  = remote_port;
  10.724 -
  10.725 -    printf("%s< err=%d\n", __FUNCTION__, err);
  10.726 -    return err;
  10.727 -}
  10.728 -
  10.729 -static PyObject *xu_port_notify(PyObject *self, PyObject *args)
  10.730 -{
  10.731 -    xu_port_object *xup = (xu_port_object *)self;
  10.732 -
  10.733 -    if ( !PyArg_ParseTuple(args, "") )
  10.734 -        return NULL;
  10.735 -
  10.736 -    (void)xc_evtchn_send(xup->xc_handle, xup->local_port);
  10.737 -
  10.738 -    Py_INCREF(Py_None);
  10.739 -    return Py_None;
  10.740 -}
  10.741 -
  10.742 -static PyObject *xu_port_read_request(PyObject *self, PyObject *args)
  10.743 -{
  10.744 -    xu_port_object    *xup = (xu_port_object *)self;
  10.745 -    xu_message_object *xum;
  10.746 -    CONTROL_RING_IDX   c = xup->tx_req_cons;
  10.747 -    control_if_t      *cif = xup->interface;
  10.748 -    control_msg_t     *cmsg;
  10.749 -
  10.750 -    if ( !PyArg_ParseTuple(args, "") )
  10.751 -        return NULL;
  10.752 -
  10.753 -    if ( (c == cif->tx_req_prod) || 
  10.754 -         ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
  10.755 -    {
  10.756 -        PyErr_SetString(port_error, "no request to read");
  10.757 -        return NULL;
  10.758 -    }
  10.759 -
  10.760 -    cmsg = &cif->tx_ring[MASK_CONTROL_IDX(c)];
  10.761 -    xum = PyObject_New(xu_message_object, &xu_message_type);
  10.762 -    memcpy(&xum->msg, cmsg, sizeof(*cmsg));
  10.763 -    if ( xum->msg.length > sizeof(xum->msg.msg) )
  10.764 -        xum->msg.length = sizeof(xum->msg.msg);
  10.765 -    xup->tx_req_cons++;
  10.766 -    return (PyObject *)xum;
  10.767 -}
  10.768 -
  10.769 -static PyObject *xu_port_write_request(PyObject *self, PyObject *args)
  10.770 -{
  10.771 -    xu_port_object    *xup = (xu_port_object *)self;
  10.772 -    xu_message_object *xum;
  10.773 -    CONTROL_RING_IDX   p = xup->rx_req_prod;
  10.774 -    control_if_t      *cif = xup->interface;
  10.775 -    control_msg_t     *cmsg;
  10.776 -
  10.777 -    if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
  10.778 -        return NULL;
  10.779 -
  10.780 -    if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
  10.781 -    {
  10.782 -        PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
  10.783 -        return NULL;        
  10.784 -    }
  10.785 -
  10.786 -    if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
  10.787 -    {
  10.788 -        PyErr_SetString(port_error, "no space to write request");
  10.789 -        return NULL;
  10.790 -    }
  10.791 -
  10.792 -    cmsg = &cif->rx_ring[MASK_CONTROL_IDX(p)];
  10.793 -    memcpy(cmsg, &xum->msg, sizeof(*cmsg));
  10.794 -
  10.795 -    xup->rx_req_prod = cif->rx_req_prod = p + 1;
  10.796 -
  10.797 -    Py_INCREF(Py_None);
  10.798 -    return Py_None;
  10.799 -}
  10.800 -
  10.801 -static PyObject *xu_port_read_response(PyObject *self, PyObject *args)
  10.802 -{
  10.803 -    xu_port_object    *xup = (xu_port_object *)self;
  10.804 -    xu_message_object *xum;
  10.805 -    CONTROL_RING_IDX   c = xup->rx_resp_cons;
  10.806 -    control_if_t      *cif = xup->interface;
  10.807 -    control_msg_t     *cmsg;
  10.808 -
  10.809 -    if ( !PyArg_ParseTuple(args, "") )
  10.810 -        return NULL;
  10.811 -
  10.812 -    if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
  10.813 -    {
  10.814 -        PyErr_SetString(port_error, "no response to read");
  10.815 -        return NULL;
  10.816 -    }
  10.817 -
  10.818 -    cmsg = &cif->rx_ring[MASK_CONTROL_IDX(c)];
  10.819 -    xum = PyObject_New(xu_message_object, &xu_message_type);
  10.820 -    memcpy(&xum->msg, cmsg, sizeof(*cmsg));
  10.821 -    if ( xum->msg.length > sizeof(xum->msg.msg) )
  10.822 -        xum->msg.length = sizeof(xum->msg.msg);
  10.823 -    xup->rx_resp_cons++;
  10.824 -    return (PyObject *)xum;
  10.825 -}
  10.826 -
  10.827 -static PyObject *xu_port_write_response(PyObject *self, PyObject *args)
  10.828 -{
  10.829 -    xu_port_object    *xup = (xu_port_object *)self;
  10.830 -    xu_message_object *xum;
  10.831 -    CONTROL_RING_IDX   p = xup->tx_resp_prod;
  10.832 -    control_if_t      *cif = xup->interface;
  10.833 -    control_msg_t     *cmsg;
  10.834 -
  10.835 -    if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
  10.836 -        return NULL;
  10.837 -
  10.838 -    if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
  10.839 -    {
  10.840 -        PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
  10.841 -        return NULL;        
  10.842 -    }
  10.843 -
  10.844 -    if ( p == xup->tx_req_cons )
  10.845 -    {
  10.846 -        PyErr_SetString(port_error, "no space to write response");
  10.847 -        return NULL;
  10.848 -    }
  10.849 -
  10.850 -    cmsg = &cif->tx_ring[MASK_CONTROL_IDX(p)];
  10.851 -    memcpy(cmsg, &xum->msg, sizeof(*cmsg));
  10.852 -
  10.853 -    xup->tx_resp_prod = cif->tx_resp_prod = p + 1;
  10.854 -
  10.855 -    Py_INCREF(Py_None);
  10.856 -    return Py_None;
  10.857 -}
  10.858 -
  10.859 -static PyObject *xu_port_request_to_read(PyObject *self, PyObject *args)
  10.860 -{
  10.861 -    xu_port_object    *xup = (xu_port_object *)self;
  10.862 -    CONTROL_RING_IDX   c = xup->tx_req_cons;
  10.863 -    control_if_t      *cif = xup->interface;
  10.864 -
  10.865 -    if ( !PyArg_ParseTuple(args, "") )
  10.866 -        return NULL;
  10.867 -
  10.868 -    if ( (c == cif->tx_req_prod) || 
  10.869 -         ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
  10.870 -        return PyInt_FromLong(0);
  10.871 -
  10.872 -    return PyInt_FromLong(1);
  10.873 -}
  10.874 -
  10.875 -static PyObject *xu_port_space_to_write_request(PyObject *self, PyObject *args)
  10.876 -{
  10.877 -    xu_port_object    *xup = (xu_port_object *)self;
  10.878 -    CONTROL_RING_IDX   p = xup->rx_req_prod;
  10.879 -
  10.880 -    if ( !PyArg_ParseTuple(args, "") )
  10.881 -        return NULL;
  10.882 -
  10.883 -    if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
  10.884 -        return PyInt_FromLong(0);
  10.885 -
  10.886 -    return PyInt_FromLong(1);
  10.887 -}
  10.888 -
  10.889 -static PyObject *xu_port_response_to_read(PyObject *self, PyObject *args)
  10.890 -{
  10.891 -    xu_port_object    *xup = (xu_port_object *)self;
  10.892 -    CONTROL_RING_IDX   c = xup->rx_resp_cons;
  10.893 -    control_if_t      *cif = xup->interface;
  10.894 -
  10.895 -    if ( !PyArg_ParseTuple(args, "") )
  10.896 -        return NULL;
  10.897 -
  10.898 -    if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
  10.899 -        return PyInt_FromLong(0);
  10.900 -
  10.901 -    return PyInt_FromLong(1);
  10.902 -}
  10.903 -
  10.904 -static PyObject *xu_port_space_to_write_response(
  10.905 -    PyObject *self, PyObject *args)
  10.906 -{
  10.907 -    xu_port_object    *xup = (xu_port_object *)self;
  10.908 -    CONTROL_RING_IDX   p = xup->tx_resp_prod;
  10.909 -
  10.910 -    if ( !PyArg_ParseTuple(args, "") )
  10.911 -        return NULL;
  10.912 -
  10.913 -    if ( p == xup->tx_req_cons )
  10.914 -        return PyInt_FromLong(0);
  10.915 -
  10.916 -    return PyInt_FromLong(1);
  10.917 -}
  10.918 -
  10.919 -static PyMethodDef xu_port_methods[] = {
  10.920 -    { "notify",
  10.921 -      (PyCFunction)xu_port_notify,
  10.922 -      METH_VARARGS,
  10.923 -      "Send a notification to the remote end.\n" },
  10.924 -
  10.925 -    { "read_request",
  10.926 -      (PyCFunction)xu_port_read_request,
  10.927 -      METH_VARARGS,
  10.928 -      "Read a request message from the control interface.\n" },
  10.929 -
  10.930 -    { "write_request",
  10.931 -      (PyCFunction)xu_port_write_request,
  10.932 -      METH_VARARGS,
  10.933 -      "Write a request message to the control interface.\n" },
  10.934 -
  10.935 -    { "read_response",
  10.936 -      (PyCFunction)xu_port_read_response,
  10.937 -      METH_VARARGS,
  10.938 -      "Read a response message from the control interface.\n" },
  10.939 -
  10.940 -    { "write_response",
  10.941 -      (PyCFunction)xu_port_write_response,
  10.942 -      METH_VARARGS,
  10.943 -      "Write a response message to the control interface.\n" },
  10.944 -
  10.945 -    { "request_to_read",
  10.946 -      (PyCFunction)xu_port_request_to_read,
  10.947 -      METH_VARARGS,
  10.948 -      "Returns TRUE if there is a request message to read.\n" },
  10.949 -
  10.950 -    { "space_to_write_request",
  10.951 -      (PyCFunction)xu_port_space_to_write_request,
  10.952 -      METH_VARARGS,
  10.953 -      "Returns TRUE if there is space to write a request message.\n" },
  10.954 -
  10.955 -    { "response_to_read",
  10.956 -      (PyCFunction)xu_port_response_to_read,
  10.957 -      METH_VARARGS,
  10.958 -      "Returns TRUE if there is a response message to read.\n" },
  10.959 -
  10.960 -    { "space_to_write_response",
  10.961 -      (PyCFunction)xu_port_space_to_write_response,
  10.962 -      METH_VARARGS,
  10.963 -      "Returns TRUE if there is space to write a response message.\n" },
  10.964 -
  10.965 -    { NULL, NULL, 0, NULL }
  10.966 -};
  10.967 -
  10.968 -staticforward PyTypeObject xu_port_type;
  10.969 -
  10.970 -static PyObject *xu_port_new(PyObject *self, PyObject *args)
  10.971 -{
  10.972 -    xu_port_object *xup;
  10.973 -    u32 dom;
  10.974 -    int port1, port2;
  10.975 -    xc_dominfo_t info;
  10.976 -
  10.977 -    if ( !PyArg_ParseTuple(args, "i", &dom) )
  10.978 -        return NULL;
  10.979 -
  10.980 -    xup = PyObject_New(xu_port_object, &xu_port_type);
  10.981 -
  10.982 -    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
  10.983 -    {
  10.984 -        PyErr_SetString(port_error, "Could not open '/dev/mem'");
  10.985 -        goto fail1;
  10.986 -    }
  10.987 -
  10.988 -    /* Set the General-Purpose Subject whose page frame will be mapped. */
  10.989 -    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom);
  10.990 -
  10.991 -    if ( (xup->xc_handle = xc_interface_open()) == -1 )
  10.992 -    {
  10.993 -        PyErr_SetString(port_error, "Could not open Xen control interface");
  10.994 -        goto fail2;
  10.995 -    }
  10.996 -
  10.997 -    if ( dom == 0 )
  10.998 -    {
  10.999 -        /*
 10.1000 -         * The control-interface event channel for DOM0 is already set up.
 10.1001 -         * We use an ioctl to discover the port at our end of the channel.
 10.1002 -         */
 10.1003 -        port1 = ioctl(xup->xc_handle, IOCTL_PRIVCMD_INITDOMAIN_EVTCHN, NULL);
 10.1004 -        port2 = -1; /* We don't need the remote end of the DOM0 link. */
 10.1005 -        if ( port1 < 0 )
 10.1006 -        {
 10.1007 -            PyErr_SetString(port_error, "Could not open channel to DOM0");
 10.1008 -            goto fail3;
 10.1009 -        }
 10.1010 -    }
 10.1011 -    else if ( xc_evtchn_bind_interdomain(xup->xc_handle, 
 10.1012 -                                         DOMID_SELF, dom, 
 10.1013 -                                         &port1, &port2) != 0 )
 10.1014 -    {
 10.1015 -        PyErr_SetString(port_error, "Could not open channel to domain");
 10.1016 -        goto fail3;
 10.1017 -    }
 10.1018 -
 10.1019 -    if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) ||
 10.1020 -         (info.domid != dom) )
 10.1021 -    {
 10.1022 -        PyErr_SetString(port_error, "Failed to obtain domain status");
 10.1023 -        goto fail4;
 10.1024 -    }
 10.1025 -
 10.1026 -    xup->interface = 
 10.1027 -        map_control_interface(xup->mem_fd, info.shared_info_frame);
 10.1028 -    if ( xup->interface == NULL )
 10.1029 -    {
 10.1030 -        PyErr_SetString(port_error, "Failed to map domain control interface");
 10.1031 -        goto fail4;
 10.1032 -    }
 10.1033 -
 10.1034 -    xup_connect(xup, dom, port1, port2);
 10.1035 -    return (PyObject *)xup;
 10.1036 -
 10.1037 -    
 10.1038 - fail4:
 10.1039 -    (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
 10.1040 - fail3:
 10.1041 -    (void)xc_interface_close(xup->xc_handle);
 10.1042 - fail2:
 10.1043 -    (void)close(xup->mem_fd);
 10.1044 - fail1:
 10.1045 -    PyObject_Del((PyObject *)xup);
 10.1046 -    return NULL;        
 10.1047 -}
 10.1048 -
 10.1049 -static PyObject *xu_port_getattr(PyObject *obj, char *name)
 10.1050 -{
 10.1051 -    xu_port_object *xup = (xu_port_object *)obj;
 10.1052 -    if ( strcmp(name, "local_port") == 0 )
 10.1053 -        return PyInt_FromLong(xup->local_port);
 10.1054 -    if ( strcmp(name, "remote_port") == 0 )
 10.1055 -        return PyInt_FromLong(xup->remote_port);
 10.1056 -    if ( strcmp(name, "remote_dom") == 0 )
 10.1057 -        return PyInt_FromLong(xup->remote_dom);
 10.1058 -    return Py_FindMethod(xu_port_methods, obj, name);
 10.1059 -}
 10.1060 -
 10.1061 -static void xu_port_dealloc(PyObject *self)
 10.1062 -{
 10.1063 -    xu_port_object *xup = (xu_port_object *)self;
 10.1064 -    unmap_control_interface(xup->mem_fd, xup->interface);
 10.1065 -    if ( xup->remote_dom != 0 )
 10.1066 -        (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
 10.1067 -    (void)xc_interface_close(xup->xc_handle);
 10.1068 -    (void)close(xup->mem_fd);
 10.1069 -    PyObject_Del(self);
 10.1070 -}
 10.1071 -
 10.1072 -static PyTypeObject xu_port_type = {
 10.1073 -    PyObject_HEAD_INIT(&PyType_Type)
 10.1074 -    0,
 10.1075 -    "port",
 10.1076 -    sizeof(xu_port_object),
 10.1077 -    0,
 10.1078 -    xu_port_dealloc,     /* tp_dealloc     */
 10.1079 -    NULL,                /* tp_print       */
 10.1080 -    xu_port_getattr,     /* tp_getattr     */
 10.1081 -    NULL,                /* tp_setattr     */
 10.1082 -    NULL,                /* tp_compare     */
 10.1083 -    NULL,                /* tp_repr        */
 10.1084 -    NULL,                /* tp_as_number   */
 10.1085 -    NULL,                /* tp_as_sequence */
 10.1086 -    NULL,                /* tp_as_mapping  */
 10.1087 -    NULL                 /* tp_hash        */
 10.1088 -};
 10.1089 -
 10.1090 -
 10.1091 -
 10.1092 -/*
 10.1093 - * *********************** BUFFER ***********************
 10.1094 - */
 10.1095 -
 10.1096 -#define BUFSZ 65536
 10.1097 -#define MASK_BUF_IDX(_i) ((_i)&(BUFSZ-1))
 10.1098 -typedef unsigned int BUF_IDX;
 10.1099 -
 10.1100 -typedef struct {
 10.1101 -    PyObject_HEAD;
 10.1102 -    char        *buf;
 10.1103 -    unsigned int prod, cons;
 10.1104 -} xu_buffer_object;
 10.1105 -
 10.1106 -static PyObject *__xu_buffer_peek(xu_buffer_object *xub, int max)
 10.1107 -{
 10.1108 -    PyObject *str1, *str2;
 10.1109 -    int len1, len2, c = MASK_BUF_IDX(xub->cons);
 10.1110 -
 10.1111 -    len1 = xub->prod - xub->cons;
 10.1112 -    if ( len1 > (BUFSZ - c) ) /* clip to ring wrap */
 10.1113 -        len1 = BUFSZ - c;
 10.1114 -    if ( len1 > max )         /* clip to specified maximum */
 10.1115 -        len1 = max;
 10.1116 -    if ( len1 < 0 )           /* sanity */
 10.1117 -        len1 = 0;
 10.1118 -
 10.1119 -    if ( (str1 = PyString_FromStringAndSize(&xub->buf[c], len1)) == NULL )
 10.1120 -        return NULL;
 10.1121 -
 10.1122 -    if ( (len1 < (xub->prod - xub->cons)) && (len1 < max) )
 10.1123 -    {
 10.1124 -        len2 = max - len1;
 10.1125 -        if ( len2 > MASK_BUF_IDX(xub->prod) )
 10.1126 -            len2 = MASK_BUF_IDX(xub->prod);
 10.1127 -        if ( len2 > 0 )
 10.1128 -        {
 10.1129 -            str2 = PyString_FromStringAndSize(&xub->buf[0], len2);
 10.1130 -            if ( str2 == NULL )
 10.1131 -                return NULL;
 10.1132 -            PyString_ConcatAndDel(&str1, str2);
 10.1133 -            if ( str1 == NULL )
 10.1134 -                return NULL;
 10.1135 -        }
 10.1136 -    }
 10.1137 -
 10.1138 -    return str1;
 10.1139 -}
 10.1140 -
 10.1141 -static PyObject *xu_buffer_peek(PyObject *self, PyObject *args)
 10.1142 -{
 10.1143 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1144 -    int max = 1024;
 10.1145 -
 10.1146 -    if ( !PyArg_ParseTuple(args, "|i", &max) )
 10.1147 -        return NULL;
 10.1148 -    
 10.1149 -    return __xu_buffer_peek(xub, max);
 10.1150 -}
 10.1151 -
 10.1152 -static PyObject *xu_buffer_read(PyObject *self, PyObject *args)
 10.1153 -{
 10.1154 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1155 -    PyObject *str;
 10.1156 -    int max = 1024;
 10.1157 -
 10.1158 -    if ( !PyArg_ParseTuple(args, "|i", &max) )
 10.1159 -        return NULL;
 10.1160 -
 10.1161 -    if ( (str = __xu_buffer_peek(xub, max)) != NULL )
 10.1162 -        xub->cons += PyString_Size(str);
 10.1163 -
 10.1164 -    return str;
 10.1165 -}
 10.1166 -
 10.1167 -static PyObject *xu_buffer_discard(PyObject *self, PyObject *args)
 10.1168 -{
 10.1169 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1170 -    int max, len;
 10.1171 -
 10.1172 -    if ( !PyArg_ParseTuple(args, "i", &max) )
 10.1173 -        return NULL;
 10.1174 -
 10.1175 -    len = xub->prod - xub->cons;
 10.1176 -    if ( len > max )
 10.1177 -        len = max;
 10.1178 -    if ( len < 0 )
 10.1179 -        len = 0;
 10.1180 -
 10.1181 -    xub->cons += len;
 10.1182 -
 10.1183 -    return PyInt_FromLong(len);
 10.1184 -}
 10.1185 -
 10.1186 -static PyObject *xu_buffer_write(PyObject *self, PyObject *args)
 10.1187 -{
 10.1188 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1189 -    char *str;
 10.1190 -    int len, len1, len2;
 10.1191 -
 10.1192 -    if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
 10.1193 -        return NULL;
 10.1194 -
 10.1195 -    len1 = len;
 10.1196 -    if ( len1 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
 10.1197 -        len1 = BUFSZ - MASK_BUF_IDX(xub->prod);
 10.1198 -    if ( len1 > (BUFSZ - (xub->prod - xub->cons)) )
 10.1199 -        len1 = BUFSZ - (xub->prod - xub->cons);
 10.1200 -
 10.1201 -    if ( len1 == 0 )
 10.1202 -        return PyInt_FromLong(0);
 10.1203 -
 10.1204 -    memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[0], len1);
 10.1205 -    xub->prod += len1;
 10.1206 -
 10.1207 -    if ( len1 < len )
 10.1208 -    {
 10.1209 -        len2 = len - len1;
 10.1210 -        if ( len2 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
 10.1211 -            len2 = BUFSZ - MASK_BUF_IDX(xub->prod);
 10.1212 -        if ( len2 > (BUFSZ - (xub->prod - xub->cons)) )
 10.1213 -            len2 = BUFSZ - (xub->prod - xub->cons);
 10.1214 -        if ( len2 != 0 )
 10.1215 -        {
 10.1216 -            memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[len1], len2);
 10.1217 -            xub->prod += len2;
 10.1218 -            return PyInt_FromLong(len1 + len2);
 10.1219 -        }
 10.1220 -    }
 10.1221 -
 10.1222 -    return PyInt_FromLong(len1);
 10.1223 -}
 10.1224 -
 10.1225 -static PyObject *xu_buffer_empty(PyObject *self, PyObject *args)
 10.1226 -{
 10.1227 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1228 -
 10.1229 -    if ( !PyArg_ParseTuple(args, "") )
 10.1230 -        return NULL;
 10.1231 -
 10.1232 -    if ( xub->cons == xub->prod )
 10.1233 -        return PyInt_FromLong(1);
 10.1234 -
 10.1235 -    return PyInt_FromLong(0);
 10.1236 -}
 10.1237 -
 10.1238 -static PyObject *xu_buffer_full(PyObject *self, PyObject *args)
 10.1239 -{
 10.1240 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1241 -
 10.1242 -    if ( !PyArg_ParseTuple(args, "") )
 10.1243 -        return NULL;
 10.1244 -
 10.1245 -    if ( (xub->prod - xub->cons) == BUFSZ )
 10.1246 -        return PyInt_FromLong(1);
 10.1247 -
 10.1248 -    return PyInt_FromLong(0);
 10.1249 -}
 10.1250 -
 10.1251 -static PyMethodDef xu_buffer_methods[] = {
 10.1252 -    { "peek", 
 10.1253 -      (PyCFunction)xu_buffer_peek,
 10.1254 -      METH_VARARGS,
 10.1255 -      "Peek up to @max bytes from the buffer. Returns a string.\n" },
 10.1256 -
 10.1257 -    { "read", 
 10.1258 -      (PyCFunction)xu_buffer_read,
 10.1259 -      METH_VARARGS,
 10.1260 -      "Read up to @max bytes from the buffer. Returns a string.\n" },
 10.1261 -
 10.1262 -    { "discard", 
 10.1263 -      (PyCFunction)xu_buffer_discard,
 10.1264 -      METH_VARARGS,
 10.1265 -      "Discard up to @max bytes from the buffer. Returns number of bytes.\n" },
 10.1266 -
 10.1267 -    { "write", 
 10.1268 -      (PyCFunction)xu_buffer_write,
 10.1269 -      METH_VARARGS,
 10.1270 -      "Write @string into buffer. Return number of bytes written.\n" },
 10.1271 -
 10.1272 -    { "empty", 
 10.1273 -      (PyCFunction)xu_buffer_empty,
 10.1274 -      METH_VARARGS,
 10.1275 -      "Return TRUE if the buffer is empty.\n" },
 10.1276 -
 10.1277 -    { "full", 
 10.1278 -      (PyCFunction)xu_buffer_full,
 10.1279 -      METH_VARARGS,
 10.1280 -      "Return TRUE if the buffer is full.\n" },
 10.1281 -
 10.1282 -    { NULL, NULL, 0, NULL }
 10.1283 -};
 10.1284 -
 10.1285 -staticforward PyTypeObject xu_buffer_type;
 10.1286 -
 10.1287 -static PyObject *xu_buffer_new(PyObject *self, PyObject *args)
 10.1288 -{
 10.1289 -    xu_buffer_object *xub;
 10.1290 -
 10.1291 -    if ( !PyArg_ParseTuple(args, "") )
 10.1292 -        return NULL;
 10.1293 -
 10.1294 -    xub = PyObject_New(xu_buffer_object, &xu_buffer_type);
 10.1295 -
 10.1296 -    if ( (xub->buf = malloc(BUFSZ)) == NULL )
 10.1297 -    {
 10.1298 -        PyObject_Del((PyObject *)xub);
 10.1299 -        return NULL;
 10.1300 -    }
 10.1301 -
 10.1302 -    xub->prod = xub->cons = 0;
 10.1303 -
 10.1304 -    return (PyObject *)xub;
 10.1305 -}
 10.1306 -
 10.1307 -static PyObject *xu_buffer_getattr(PyObject *obj, char *name)
 10.1308 -{
 10.1309 -    return Py_FindMethod(xu_buffer_methods, obj, name);
 10.1310 -}
 10.1311 -
 10.1312 -static void xu_buffer_dealloc(PyObject *self)
 10.1313 -{
 10.1314 -    xu_buffer_object *xub = (xu_buffer_object *)self;
 10.1315 -    free(xub->buf);
 10.1316 -    PyObject_Del(self);
 10.1317 -}
 10.1318 -
 10.1319 -static PyTypeObject xu_buffer_type = {
 10.1320 -    PyObject_HEAD_INIT(&PyType_Type)
 10.1321 -    0,
 10.1322 -    "buffer",
 10.1323 -    sizeof(xu_buffer_object),
 10.1324 -    0,
 10.1325 -    xu_buffer_dealloc,   /* tp_dealloc     */
 10.1326 -    NULL,                /* tp_print       */
 10.1327 -    xu_buffer_getattr,   /* tp_getattr     */
 10.1328 -    NULL,                /* tp_setattr     */
 10.1329 -    NULL,                /* tp_compare     */
 10.1330 -    NULL,                /* tp_repr        */
 10.1331 -    NULL,                /* tp_as_number   */
 10.1332 -    NULL,                /* tp_as_sequence */
 10.1333 -    NULL,                /* tp_as_mapping  */
 10.1334 -    NULL                 /* tp_hash        */
 10.1335 -};
 10.1336 -
 10.1337 -
 10.1338 -
 10.1339 -/*
 10.1340 - * *********************** MODULE WRAPPER ***********************
 10.1341 - */
 10.1342 -
 10.1343 -static void handle_child_death(int dummy)
 10.1344 -{
 10.1345 -    while ( waitpid(-1, NULL, WNOHANG) > 0 )
 10.1346 -        continue;
 10.1347 -}
 10.1348 -
 10.1349 -static PyObject *xu_autoreap(PyObject *self, PyObject *args)
 10.1350 -{
 10.1351 -    struct sigaction sa;
 10.1352 -
 10.1353 -    if ( !PyArg_ParseTuple(args, "") )
 10.1354 -        return NULL;
 10.1355 -
 10.1356 -    memset(&sa, 0, sizeof(sa));
 10.1357 -    sa.sa_handler = handle_child_death;
 10.1358 -    sigemptyset(&sa.sa_mask);
 10.1359 -    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
 10.1360 -    (void)sigaction(SIGCHLD, &sa, NULL);
 10.1361 -
 10.1362 -    Py_INCREF(Py_None);
 10.1363 -    return Py_None;
 10.1364 -}
 10.1365 -
 10.1366 -static PyMethodDef xu_methods[] = {
 10.1367 -    { "notifier", xu_notifier_new, METH_VARARGS, 
 10.1368 -      "Create a new notifier." },
 10.1369 -    { "message", xu_message_new, METH_VARARGS, 
 10.1370 -      "Create a new communications message." },
 10.1371 -    { "port", xu_port_new, METH_VARARGS, 
 10.1372 -      "Create a new communications port." },
 10.1373 -    { "buffer", xu_buffer_new, METH_VARARGS, 
 10.1374 -      "Create a new ring buffer." },
 10.1375 -    { "autoreap", xu_autoreap, METH_VARARGS,
 10.1376 -      "Ensure that zombie children are automatically reaped by the OS." },
 10.1377 -    { NULL, NULL, 0, NULL }
 10.1378 -};
 10.1379 -
 10.1380 -PyMODINIT_FUNC initxu(void)
 10.1381 -{
 10.1382 -    PyObject *m, *d;
 10.1383 -
 10.1384 -    m = Py_InitModule(XENPKG, xu_methods);
 10.1385 -
 10.1386 -    d = PyModule_GetDict(m);
 10.1387 -    port_error = PyErr_NewException(XENPKG ".PortError", NULL, NULL);
 10.1388 -    PyDict_SetItemString(d, "PortError", port_error);
 10.1389 -}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/python/xen/lowlevel/__init__.py	Wed Jun 30 09:52:59 2004 +0000
    11.3 @@ -0,0 +1,1 @@
    11.4 + 
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Jun 30 09:52:59 2004 +0000
    12.3 @@ -0,0 +1,1184 @@
    12.4 +/******************************************************************************
    12.5 + * Xc.c
    12.6 + * 
    12.7 + * Copyright (c) 2003-2004, K A Fraser (University of Cambridge)
    12.8 + */
    12.9 +
   12.10 +#include <Python.h>
   12.11 +#include <xc.h>
   12.12 +#include <zlib.h>
   12.13 +#include <fcntl.h>
   12.14 +#include <netinet/in.h>
   12.15 +#include <netinet/tcp.h>
   12.16 +#include <sys/types.h>
   12.17 +#include <sys/socket.h>
   12.18 +#include <netdb.h>
   12.19 +#include <arpa/inet.h>
   12.20 +#include "xc_private.h"
   12.21 +#include "gzip_stream.h"
   12.22 +
   12.23 +/* Needed for Python versions earlier than 2.3. */
   12.24 +#ifndef PyMODINIT_FUNC
   12.25 +#define PyMODINIT_FUNC DL_EXPORT(void)
   12.26 +#endif
   12.27 +
   12.28 +#define XENPKG "xen.lowlevel.xc"
   12.29 +
   12.30 +static PyObject *xc_error, *zero;
   12.31 +
   12.32 +typedef struct {
   12.33 +    PyObject_HEAD;
   12.34 +    int xc_handle;
   12.35 +} XcObject;
   12.36 +
   12.37 +/*
   12.38 + * Definitions for the 'xc' object type.
   12.39 + */
   12.40 +
   12.41 +static PyObject *pyxc_domain_create(PyObject *self,
   12.42 +                                    PyObject *args,
   12.43 +                                    PyObject *kwds)
   12.44 +{
   12.45 +    XcObject *xc = (XcObject *)self;
   12.46 +
   12.47 +    unsigned int mem_kb = 0;
   12.48 +    char        *name   = "(anon)";
   12.49 +    int          cpu = -1;
   12.50 +    u32          dom;
   12.51 +    int          ret;
   12.52 +
   12.53 +    static char *kwd_list[] = { "mem_kb", "name", "cpu", NULL };
   12.54 +
   12.55 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|isi", kwd_list, 
   12.56 +                                      &mem_kb, &name, &cpu) )
   12.57 +        return NULL;
   12.58 +
   12.59 +    if ( (ret = xc_domain_create(xc->xc_handle, mem_kb, name, cpu, &dom)) < 0 )
   12.60 +        return PyErr_SetFromErrno(xc_error);
   12.61 +
   12.62 +    return PyInt_FromLong(dom);
   12.63 +}
   12.64 +
   12.65 +static PyObject *pyxc_domain_pause(PyObject *self,
   12.66 +                                   PyObject *args,
   12.67 +                                   PyObject *kwds)
   12.68 +{
   12.69 +    XcObject *xc = (XcObject *)self;
   12.70 +
   12.71 +    u32 dom;
   12.72 +
   12.73 +    static char *kwd_list[] = { "dom", NULL };
   12.74 +
   12.75 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
   12.76 +        return NULL;
   12.77 +
   12.78 +    if ( xc_domain_pause(xc->xc_handle, dom) != 0 )
   12.79 +        return PyErr_SetFromErrno(xc_error);
   12.80 +    
   12.81 +    Py_INCREF(zero);
   12.82 +    return zero;
   12.83 +}
   12.84 +
   12.85 +static PyObject *pyxc_domain_unpause(PyObject *self,
   12.86 +                                     PyObject *args,
   12.87 +                                     PyObject *kwds)
   12.88 +{
   12.89 +    XcObject *xc = (XcObject *)self;
   12.90 +
   12.91 +    u32 dom;
   12.92 +
   12.93 +    static char *kwd_list[] = { "dom", NULL };
   12.94 +
   12.95 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
   12.96 +        return NULL;
   12.97 +
   12.98 +    if ( xc_domain_unpause(xc->xc_handle, dom) != 0 )
   12.99 +        return PyErr_SetFromErrno(xc_error);
  12.100 +    
  12.101 +    Py_INCREF(zero);
  12.102 +    return zero;
  12.103 +}
  12.104 +
  12.105 +static PyObject *pyxc_domain_destroy(PyObject *self,
  12.106 +                                     PyObject *args,
  12.107 +                                     PyObject *kwds)
  12.108 +{
  12.109 +    XcObject *xc = (XcObject *)self;
  12.110 +
  12.111 +    u32 dom;
  12.112 +
  12.113 +    static char *kwd_list[] = { "dom", NULL };
  12.114 +
  12.115 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
  12.116 +        return NULL;
  12.117 +
  12.118 +    if ( xc_domain_destroy(xc->xc_handle, dom) != 0 )
  12.119 +        return PyErr_SetFromErrno(xc_error);
  12.120 +    
  12.121 +    Py_INCREF(zero);
  12.122 +    return zero;
  12.123 +}
  12.124 +
  12.125 +static PyObject *pyxc_domain_pincpu(PyObject *self,
  12.126 +                                    PyObject *args,
  12.127 +                                    PyObject *kwds)
  12.128 +{
  12.129 +    XcObject *xc = (XcObject *)self;
  12.130 +
  12.131 +    u32 dom;
  12.132 +    int cpu = -1;
  12.133 +
  12.134 +    static char *kwd_list[] = { "dom", "cpu", NULL };
  12.135 +
  12.136 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
  12.137 +                                      &dom, &cpu) )
  12.138 +        return NULL;
  12.139 +
  12.140 +    if ( xc_domain_pincpu(xc->xc_handle, dom, cpu) != 0 )
  12.141 +        return PyErr_SetFromErrno(xc_error);
  12.142 +    
  12.143 +    Py_INCREF(zero);
  12.144 +    return zero;
  12.145 +}
  12.146 +
  12.147 +static PyObject *pyxc_domain_getinfo(PyObject *self,
  12.148 +                                     PyObject *args,
  12.149 +                                     PyObject *kwds)
  12.150 +{
  12.151 +    XcObject *xc = (XcObject *)self;
  12.152 +    PyObject *list;
  12.153 +
  12.154 +    u32 first_dom = 0;
  12.155 +    int max_doms = 1024, nr_doms, i;
  12.156 +    xc_dominfo_t *info;
  12.157 +
  12.158 +    static char *kwd_list[] = { "first_dom", "max_doms", NULL };
  12.159 +    
  12.160 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list,
  12.161 +                                      &first_dom, &max_doms) )
  12.162 +        return NULL;
  12.163 +
  12.164 +    if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
  12.165 +        return PyErr_NoMemory();
  12.166 +
  12.167 +    nr_doms = xc_domain_getinfo(xc->xc_handle, first_dom, max_doms, info);
  12.168 +    
  12.169 +    list = PyList_New(nr_doms);
  12.170 +    for ( i = 0 ; i < nr_doms; i++ )
  12.171 +    {
  12.172 +        PyList_SetItem(
  12.173 +            list, i, 
  12.174 +            Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i"
  12.175 +                          ",s:l,s:L,s:s,s:l,s:i}",
  12.176 +                          "dom",       info[i].domid,
  12.177 +                          "cpu",       info[i].cpu,
  12.178 +                          "dying",     info[i].dying,
  12.179 +                          "crashed",   info[i].crashed,
  12.180 +                          "shutdown",  info[i].shutdown,
  12.181 +                          "paused",    info[i].paused,
  12.182 +                          "blocked",   info[i].blocked,
  12.183 +                          "running",   info[i].running,
  12.184 +                          "mem_kb",    info[i].nr_pages*4,
  12.185 +                          "cpu_time",  info[i].cpu_time,
  12.186 +                          "name",      info[i].name,
  12.187 +                          "maxmem_kb", info[i].max_memkb,
  12.188 +                          "shutdown_reason", info[i].shutdown_reason
  12.189 +                ));
  12.190 +    }
  12.191 +
  12.192 +    free(info);
  12.193 +
  12.194 +    return list;
  12.195 +}
  12.196 +
  12.197 +static int file_save(XcObject *xc, XcIOContext *ctxt, char *state_file)
  12.198 +{
  12.199 +    int rc = -1;
  12.200 +    int fd = -1;
  12.201 +    int open_flags = (O_CREAT | O_EXCL | O_WRONLY);
  12.202 +    int open_mode = 0644;
  12.203 +
  12.204 +    printf("%s>\n", __FUNCTION__);
  12.205 +
  12.206 +    if ( (fd = open(state_file, open_flags, open_mode)) < 0 )
  12.207 +    {
  12.208 +        xcio_perror(ctxt, "Could not open file for writing");
  12.209 +        goto exit;
  12.210 +    }
  12.211 +
  12.212 +    printf("%s>gzip_stream_fdopen... \n", __FUNCTION__);
  12.213 +
  12.214 +    /* Compression rate 1: we want speed over compression. 
  12.215 +     * We're mainly going for those zero pages, after all.
  12.216 +     */
  12.217 +    ctxt->io = gzip_stream_fdopen(fd, "wb1");
  12.218 +    if ( ctxt->io == NULL )
  12.219 +    {
  12.220 +        xcio_perror(ctxt, "Could not allocate compression state");
  12.221 +        goto exit;
  12.222 +    }
  12.223 +
  12.224 +    printf("%s> xc_linux_save...\n", __FUNCTION__);
  12.225 +
  12.226 +    rc = xc_linux_save(xc->xc_handle, ctxt);
  12.227 +
  12.228 +  exit:
  12.229 +    if ( ctxt->io != NULL )
  12.230 +        IOStream_close(ctxt->io);
  12.231 +    if ( fd >= 0 )
  12.232 +        close(fd);
  12.233 +    unlink(state_file);
  12.234 +    printf("%s> rc=%d\n", __FUNCTION__, rc);
  12.235 +    return rc;
  12.236 +}
  12.237 +
  12.238 +static PyObject *pyxc_linux_save(PyObject *self,
  12.239 +                                 PyObject *args,
  12.240 +                                 PyObject *kwds)
  12.241 +{
  12.242 +    XcObject *xc = (XcObject *)self;
  12.243 +
  12.244 +    char *state_file;
  12.245 +    int progress = 1, debug = 0;
  12.246 +    PyObject *val = NULL;
  12.247 +    int rc = -1;
  12.248 +    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
  12.249 +
  12.250 +    static char *kwd_list[] = { "dom", "state_file", "vmconfig", "progress", "debug", NULL };
  12.251 +
  12.252 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|sii", kwd_list, 
  12.253 +                                      &ioctxt.domain,
  12.254 +                                      &state_file,
  12.255 +                                      &ioctxt.vmconfig,
  12.256 +                                      &progress, 
  12.257 +                                      &debug) )
  12.258 +        goto exit;
  12.259 +
  12.260 +    ioctxt.vmconfig_n = (ioctxt.vmconfig ? strlen(ioctxt.vmconfig) : 0);
  12.261 +
  12.262 +    if ( progress )
  12.263 +        ioctxt.flags |= XCFLAGS_VERBOSE;
  12.264 +    if ( debug )
  12.265 +        ioctxt.flags |= XCFLAGS_DEBUG;
  12.266 +
  12.267 +    if ( (state_file == NULL) || (state_file[0] == '\0') )
  12.268 +        goto exit;
  12.269 +    
  12.270 +    rc = file_save(xc, &ioctxt, state_file);
  12.271 +    if ( rc != 0 )
  12.272 +    {
  12.273 +        PyErr_SetFromErrno(xc_error);
  12.274 +        goto exit;
  12.275 +    } 
  12.276 +
  12.277 +    Py_INCREF(zero);
  12.278 +    val = zero;
  12.279 +
  12.280 +  exit:
  12.281 +    return val;
  12.282 +}
  12.283 +
  12.284 +
  12.285 +static int file_restore(XcObject *xc, XcIOContext *ioctxt, char *state_file)
  12.286 +{
  12.287 +    int rc = -1;
  12.288 +
  12.289 +    ioctxt->io = gzip_stream_fopen(state_file, "rb");
  12.290 +    if ( ioctxt->io == NULL )
  12.291 +    {
  12.292 +        xcio_perror(ioctxt, "Could not open file for reading");
  12.293 +        return rc;
  12.294 +    }
  12.295 +
  12.296 +    rc = xc_linux_restore(xc->xc_handle, ioctxt);
  12.297 +
  12.298 +    IOStream_close(ioctxt->io);
  12.299 +    
  12.300 +    return rc;
  12.301 +}
  12.302 +
  12.303 +static PyObject *pyxc_linux_restore(PyObject *self,
  12.304 +                                    PyObject *args,
  12.305 +                                    PyObject *kwds)
  12.306 +{
  12.307 +    XcObject *xc = (XcObject *)self;
  12.308 +    char *state_file;
  12.309 +    int progress = 1, debug = 0;
  12.310 +    PyObject *val = NULL;
  12.311 +    XcIOContext ioctxt = { .info = iostdout, .err = iostderr };
  12.312 +    int rc =-1;
  12.313 +
  12.314 +    static char *kwd_list[] = { "state_file", "progress", "debug", NULL };
  12.315 +
  12.316 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is|ii", kwd_list,
  12.317 +                                      &ioctxt.domain,
  12.318 +                                      &state_file,
  12.319 +                                      &progress,
  12.320 +                                      &debug) )
  12.321 +        goto exit;
  12.322 +
  12.323 +    if ( progress )
  12.324 +        ioctxt.flags |= XCFLAGS_VERBOSE;
  12.325 +    if ( debug )
  12.326 +        ioctxt.flags |= XCFLAGS_DEBUG;
  12.327 +
  12.328 +    if ( (state_file == NULL) || (state_file[0] == '\0') )
  12.329 +        goto exit;
  12.330 +
  12.331 +    rc = file_restore(xc, &ioctxt, state_file);
  12.332 +    if ( rc != 0 )
  12.333 +    {
  12.334 +        PyErr_SetFromErrno(xc_error);
  12.335 +        goto exit;
  12.336 +    }
  12.337 +
  12.338 +    val = Py_BuildValue("{s:i,s:s}",
  12.339 +                        "dom", ioctxt.domain,
  12.340 +                        "vmconfig", ioctxt.vmconfig);
  12.341 +
  12.342 +  exit:
  12.343 +    return val;
  12.344 +}
  12.345 +
  12.346 +static PyObject *pyxc_linux_build(PyObject *self,
  12.347 +                                  PyObject *args,
  12.348 +                                  PyObject *kwds)
  12.349 +{
  12.350 +    XcObject *xc = (XcObject *)self;
  12.351 +
  12.352 +    u32   dom;
  12.353 +    char *image, *ramdisk = NULL, *cmdline = "";
  12.354 +    int   control_evtchn, flags = 0;
  12.355 +
  12.356 +    static char *kwd_list[] = { "dom", "control_evtchn", 
  12.357 +                                "image", "ramdisk", "cmdline", "flags",
  12.358 +                                NULL };
  12.359 +
  12.360 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 
  12.361 +                                      &dom, &control_evtchn, 
  12.362 +                                      &image, &ramdisk, &cmdline, &flags) )
  12.363 +        return NULL;
  12.364 +
  12.365 +    if ( xc_linux_build(xc->xc_handle, dom, image,
  12.366 +                        ramdisk, cmdline, control_evtchn, flags) != 0 )
  12.367 +        return PyErr_SetFromErrno(xc_error);
  12.368 +    
  12.369 +    Py_INCREF(zero);
  12.370 +    return zero;
  12.371 +}
  12.372 +
  12.373 +static PyObject *pyxc_netbsd_build(PyObject *self,
  12.374 +                                   PyObject *args,
  12.375 +                                   PyObject *kwds)
  12.376 +{
  12.377 +    XcObject *xc = (XcObject *)self;
  12.378 +
  12.379 +    u32   dom;
  12.380 +    char *image, *ramdisk = NULL, *cmdline = "";
  12.381 +    int   control_evtchn;
  12.382 +
  12.383 +    static char *kwd_list[] = { "dom", "control_evtchn",
  12.384 +                                "image", "ramdisk", "cmdline", NULL };
  12.385 +
  12.386 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 
  12.387 +                                      &dom, &control_evtchn,
  12.388 +                                      &image, &ramdisk, &cmdline) )
  12.389 +        return NULL;
  12.390 +
  12.391 +    if ( xc_netbsd_build(xc->xc_handle, dom, image, 
  12.392 +                         cmdline, control_evtchn) != 0 )
  12.393 +        return PyErr_SetFromErrno(xc_error);
  12.394 +    
  12.395 +    Py_INCREF(zero);
  12.396 +    return zero;
  12.397 +}
  12.398 +
  12.399 +static PyObject *pyxc_bvtsched_global_set(PyObject *self,
  12.400 +                                          PyObject *args,
  12.401 +                                          PyObject *kwds)
  12.402 +{
  12.403 +    XcObject *xc = (XcObject *)self;
  12.404 +
  12.405 +    unsigned long ctx_allow;
  12.406 +
  12.407 +    static char *kwd_list[] = { "ctx_allow", NULL };
  12.408 +
  12.409 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "l", kwd_list, &ctx_allow) )
  12.410 +        return NULL;
  12.411 +
  12.412 +    if ( xc_bvtsched_global_set(xc->xc_handle, ctx_allow) != 0 )
  12.413 +        return PyErr_SetFromErrno(xc_error);
  12.414 +    
  12.415 +    Py_INCREF(zero);
  12.416 +    return zero;
  12.417 +}
  12.418 +
  12.419 +static PyObject *pyxc_bvtsched_global_get(PyObject *self,
  12.420 +                                          PyObject *args,
  12.421 +                                          PyObject *kwds)
  12.422 +{
  12.423 +    XcObject *xc = (XcObject *)self;
  12.424 +    
  12.425 +    unsigned long ctx_allow;
  12.426 +    
  12.427 +    if ( !PyArg_ParseTuple(args, "") )
  12.428 +        return NULL;
  12.429 +    
  12.430 +    if ( xc_bvtsched_global_get(xc->xc_handle, &ctx_allow) != 0 )
  12.431 +        return PyErr_SetFromErrno(xc_error);
  12.432 +    
  12.433 +    return Py_BuildValue("s:l", "ctx_allow", ctx_allow);
  12.434 +}
  12.435 +
  12.436 +static PyObject *pyxc_bvtsched_domain_set(PyObject *self,
  12.437 +                                          PyObject *args,
  12.438 +                                          PyObject *kwds)
  12.439 +{
  12.440 +    XcObject *xc = (XcObject *)self;
  12.441 +
  12.442 +    u32           dom;
  12.443 +    unsigned long mcuadv, warp, warpl, warpu;
  12.444 +
  12.445 +    static char *kwd_list[] = { "dom", "mcuadv", "warp", "warpl",
  12.446 +                                "warpu", NULL };
  12.447 +
  12.448 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illll", kwd_list,
  12.449 +                                      &dom, &mcuadv, &warp, &warpl, &warpu) )
  12.450 +        return NULL;
  12.451 +
  12.452 +    if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv, 
  12.453 +                                warp, warpl, warpu) != 0 )
  12.454 +        return PyErr_SetFromErrno(xc_error);
  12.455 +    
  12.456 +    Py_INCREF(zero);
  12.457 +    return zero;
  12.458 +}
  12.459 +
  12.460 +static PyObject *pyxc_bvtsched_domain_get(PyObject *self,
  12.461 +                                          PyObject *args,
  12.462 +                                          PyObject *kwds)
  12.463 +{
  12.464 +    XcObject *xc = (XcObject *)self;
  12.465 +    u32 dom;
  12.466 +    unsigned long mcuadv, warp, warpl, warpu;
  12.467 +    
  12.468 +    static char *kwd_list[] = { "dom", NULL };
  12.469 +
  12.470 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
  12.471 +        return NULL;
  12.472 +    
  12.473 +    if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warp,
  12.474 +                                &warpl, &warpu) != 0 )
  12.475 +        return PyErr_SetFromErrno(xc_error);
  12.476 +
  12.477 +    return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
  12.478 +                         "domain", dom,
  12.479 +                         "mcuadv", mcuadv,
  12.480 +                         "warp",   warp,
  12.481 +                         "warpl",  warpl,
  12.482 +                         "warpu",  warpu);
  12.483 +}
  12.484 +
  12.485 +static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
  12.486 +                                              PyObject *args,
  12.487 +                                              PyObject *kwds)
  12.488 +{
  12.489 +    XcObject *xc = (XcObject *)self;
  12.490 +
  12.491 +    u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF;
  12.492 +    int port1, port2;
  12.493 +
  12.494 +    static char *kwd_list[] = { "dom1", "dom2", NULL };
  12.495 +
  12.496 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, 
  12.497 +                                      &dom1, &dom2) )
  12.498 +        return NULL;
  12.499 +
  12.500 +    if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1, 
  12.501 +                                    dom2, &port1, &port2) != 0 )
  12.502 +        return PyErr_SetFromErrno(xc_error);
  12.503 +
  12.504 +    return Py_BuildValue("{s:i,s:i}", 
  12.505 +                         "port1", port1,
  12.506 +                         "port2", port2);
  12.507 +}
  12.508 +
  12.509 +static PyObject *pyxc_evtchn_bind_virq(PyObject *self,
  12.510 +                                       PyObject *args,
  12.511 +                                       PyObject *kwds)
  12.512 +{
  12.513 +    XcObject *xc = (XcObject *)self;
  12.514 +
  12.515 +    int virq, port;
  12.516 +
  12.517 +    static char *kwd_list[] = { "virq", NULL };
  12.518 +
  12.519 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) )
  12.520 +        return NULL;
  12.521 +
  12.522 +    if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 )
  12.523 +        return PyErr_SetFromErrno(xc_error);
  12.524 +
  12.525 +    return PyInt_FromLong(port);
  12.526 +}
  12.527 +
  12.528 +static PyObject *pyxc_evtchn_close(PyObject *self,
  12.529 +                                   PyObject *args,
  12.530 +                                   PyObject *kwds)
  12.531 +{
  12.532 +    XcObject *xc = (XcObject *)self;
  12.533 +
  12.534 +    u32 dom = DOMID_SELF;
  12.535 +    int port;
  12.536 +
  12.537 +    static char *kwd_list[] = { "port", "dom", NULL };
  12.538 +
  12.539 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
  12.540 +                                      &port, &dom) )
  12.541 +        return NULL;
  12.542 +
  12.543 +    if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 )
  12.544 +        return PyErr_SetFromErrno(xc_error);
  12.545 +
  12.546 +    Py_INCREF(zero);
  12.547 +    return zero;
  12.548 +}
  12.549 +
  12.550 +static PyObject *pyxc_evtchn_send(PyObject *self,
  12.551 +                                  PyObject *args,
  12.552 +                                  PyObject *kwds)
  12.553 +{
  12.554 +    XcObject *xc = (XcObject *)self;
  12.555 +
  12.556 +    int port;
  12.557 +
  12.558 +    static char *kwd_list[] = { "port", NULL };
  12.559 +
  12.560 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) )
  12.561 +        return NULL;
  12.562 +
  12.563 +    if ( xc_evtchn_send(xc->xc_handle, port) != 0 )
  12.564 +        return PyErr_SetFromErrno(xc_error);
  12.565 +
  12.566 +    Py_INCREF(zero);
  12.567 +    return zero;
  12.568 +}
  12.569 +
  12.570 +static PyObject *pyxc_evtchn_status(PyObject *self,
  12.571 +                                    PyObject *args,
  12.572 +                                    PyObject *kwds)
  12.573 +{
  12.574 +    XcObject *xc = (XcObject *)self;
  12.575 +    PyObject *dict;
  12.576 +
  12.577 +    u32 dom = DOMID_SELF;
  12.578 +    int port, ret;
  12.579 +    xc_evtchn_status_t status;
  12.580 +
  12.581 +    static char *kwd_list[] = { "port", "dom", NULL };
  12.582 +
  12.583 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
  12.584 +                                      &port, &dom) )
  12.585 +        return NULL;
  12.586 +
  12.587 +    ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
  12.588 +    if ( ret != 0 )
  12.589 +        return PyErr_SetFromErrno(xc_error);
  12.590 +
  12.591 +    switch ( status.status )
  12.592 +    {
  12.593 +    case EVTCHNSTAT_closed:
  12.594 +        dict = Py_BuildValue("{s:s}", 
  12.595 +                             "status", "closed");
  12.596 +        break;
  12.597 +    case EVTCHNSTAT_unbound:
  12.598 +        dict = Py_BuildValue("{s:s}", 
  12.599 +                             "status", "unbound");
  12.600 +        break;
  12.601 +    case EVTCHNSTAT_interdomain:
  12.602 +        dict = Py_BuildValue("{s:s,s:i,s:i}", 
  12.603 +                             "status", "interdomain",
  12.604 +                             "dom", status.u.interdomain.dom,
  12.605 +                             "port", status.u.interdomain.port);
  12.606 +        break;
  12.607 +    case EVTCHNSTAT_pirq:
  12.608 +        dict = Py_BuildValue("{s:s,s:i}", 
  12.609 +                             "status", "pirq",
  12.610 +                             "irq", status.u.pirq);
  12.611 +        break;
  12.612 +    case EVTCHNSTAT_virq:
  12.613 +        dict = Py_BuildValue("{s:s,s:i}", 
  12.614 +                             "status", "virq",
  12.615 +                             "irq", status.u.virq);
  12.616 +        break;
  12.617 +    default:
  12.618 +        dict = Py_BuildValue("{}");
  12.619 +        break;
  12.620 +    }
  12.621 +    
  12.622 +    return dict;
  12.623 +}
  12.624 +
  12.625 +static PyObject *pyxc_physdev_pci_access_modify(PyObject *self,
  12.626 +                                                PyObject *args,
  12.627 +                                                PyObject *kwds)
  12.628 +{
  12.629 +    XcObject *xc = (XcObject *)self;
  12.630 +    u32 dom;
  12.631 +    int bus, dev, func, enable, ret;
  12.632 +
  12.633 +    static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL };
  12.634 +
  12.635 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiii", kwd_list, 
  12.636 +                                      &dom, &bus, &dev, &func, &enable) )
  12.637 +        return NULL;
  12.638 +
  12.639 +    ret = xc_physdev_pci_access_modify(
  12.640 +        xc->xc_handle, dom, bus, dev, func, enable);
  12.641 +    if ( ret != 0 )
  12.642 +        return PyErr_SetFromErrno(xc_error);
  12.643 +
  12.644 +    Py_INCREF(zero);
  12.645 +    return zero;
  12.646 +}
  12.647 +
  12.648 +static PyObject *pyxc_readconsolering(PyObject *self,
  12.649 +                                      PyObject *args,
  12.650 +                                      PyObject *kwds)
  12.651 +{
  12.652 +    XcObject *xc = (XcObject *)self;
  12.653 +
  12.654 +    unsigned int clear = 0;
  12.655 +    char         str[32768];
  12.656 +    int          ret;
  12.657 +
  12.658 +    static char *kwd_list[] = { "clear", NULL };
  12.659 +
  12.660 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
  12.661 +        return NULL;
  12.662 +
  12.663 +    ret = xc_readconsolering(xc->xc_handle, str, sizeof(str), clear);
  12.664 +    if ( ret < 0 )
  12.665 +        return PyErr_SetFromErrno(xc_error);
  12.666 +
  12.667 +    return PyString_FromStringAndSize(str, ret);
  12.668 +}
  12.669 +
  12.670 +static PyObject *pyxc_physinfo(PyObject *self,
  12.671 +                               PyObject *args,
  12.672 +                               PyObject *kwds)
  12.673 +{
  12.674 +    XcObject *xc = (XcObject *)self;
  12.675 +    xc_physinfo_t info;
  12.676 +    
  12.677 +    if ( !PyArg_ParseTuple(args, "") )
  12.678 +        return NULL;
  12.679 +
  12.680 +    if ( xc_physinfo(xc->xc_handle, &info) != 0 )
  12.681 +        return PyErr_SetFromErrno(xc_error);
  12.682 +
  12.683 +    return Py_BuildValue("{s:i,s:i,s:l,s:l,s:l}",
  12.684 +                         "ht_per_core", info.ht_per_core,
  12.685 +                         "cores",       info.cores,
  12.686 +                         "total_pages", info.total_pages,
  12.687 +                         "free_pages",  info.free_pages,
  12.688 +                         "cpu_khz",     info.cpu_khz);
  12.689 +}
  12.690 +
  12.691 +static PyObject *pyxc_atropos_domain_set(PyObject *self,
  12.692 +                                         PyObject *args,
  12.693 +                                         PyObject *kwds)
  12.694 +{
  12.695 +    XcObject *xc = (XcObject *)self;
  12.696 +    u32 domid;
  12.697 +    u64 period, slice, latency;
  12.698 +    int xtratime;
  12.699 +
  12.700 +    static char *kwd_list[] = { "dom", "period", "slice", "latency",
  12.701 +                                "xtratime", NULL };
  12.702 +    
  12.703 +    if( !PyArg_ParseTupleAndKeywords(args, kwds, "iLLLi", kwd_list, &domid,
  12.704 +                                     &period, &slice, &latency, &xtratime) )
  12.705 +        return NULL;
  12.706 +   
  12.707 +    if ( xc_atropos_domain_set(xc->xc_handle, domid, period, slice,
  12.708 +                               latency, xtratime) != 0 )
  12.709 +        return PyErr_SetFromErrno(xc_error);
  12.710 +
  12.711 +    Py_INCREF(zero);
  12.712 +    return zero;
  12.713 +}
  12.714 +
  12.715 +static PyObject *pyxc_atropos_domain_get(PyObject *self,
  12.716 +                                         PyObject *args,
  12.717 +                                         PyObject *kwds)
  12.718 +{
  12.719 +    XcObject *xc = (XcObject *)self;
  12.720 +    u32 domid;
  12.721 +    u64 period, slice, latency;
  12.722 +    int xtratime;
  12.723 +    
  12.724 +    static char *kwd_list[] = { "dom", NULL };
  12.725 +
  12.726 +    if( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &domid) )
  12.727 +        return NULL;
  12.728 +    
  12.729 +    if ( xc_atropos_domain_get( xc->xc_handle, domid, &period,
  12.730 +                                &slice, &latency, &xtratime ) )
  12.731 +        return PyErr_SetFromErrno(xc_error);
  12.732 +
  12.733 +    return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}",
  12.734 +                         "domain",  domid,
  12.735 +                         "period",  period,
  12.736 +                         "slice",   slice,
  12.737 +                         "latency", latency,
  12.738 +                         "xtratime", xtratime);
  12.739 +}
  12.740 +
  12.741 +
  12.742 +static PyObject *pyxc_rrobin_global_set(PyObject *self,
  12.743 +                                        PyObject *args,
  12.744 +                                        PyObject *kwds)
  12.745 +{
  12.746 +    XcObject *xc = (XcObject *)self;
  12.747 +    u64 slice;
  12.748 +    
  12.749 +    static char *kwd_list[] = { "slice", NULL };
  12.750 +
  12.751 +    if( !PyArg_ParseTupleAndKeywords(args, kwds, "L", kwd_list, &slice) )
  12.752 +        return NULL;
  12.753 +    
  12.754 +    if ( xc_rrobin_global_set(xc->xc_handle, slice) != 0 )
  12.755 +        return PyErr_SetFromErrno(xc_error);
  12.756 +    
  12.757 +    Py_INCREF(zero);
  12.758 +    return zero;
  12.759 +}
  12.760 +
  12.761 +static PyObject *pyxc_shadow_control(PyObject *self,
  12.762 +                                     PyObject *args,
  12.763 +                                     PyObject *kwds)
  12.764 +{
  12.765 +    XcObject *xc = (XcObject *)self;
  12.766 +
  12.767 +    u32 dom;
  12.768 +    int op=0;
  12.769 +
  12.770 +    static char *kwd_list[] = { "dom", "op", NULL };
  12.771 +
  12.772 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, 
  12.773 +                                      &dom, &op) )
  12.774 +        return NULL;
  12.775 +
  12.776 +    if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 )
  12.777 +        return PyErr_SetFromErrno(xc_error);
  12.778 +    
  12.779 +    Py_INCREF(zero);
  12.780 +    return zero;
  12.781 +}
  12.782 +
  12.783 +static PyObject *pyxc_rrobin_global_get(PyObject *self,
  12.784 +                                        PyObject *args,
  12.785 +                                        PyObject *kwds)
  12.786 +{
  12.787 +    XcObject *xc = (XcObject *)self;
  12.788 +    u64 slice;
  12.789 +
  12.790 +    if ( !PyArg_ParseTuple(args, "") )
  12.791 +        return NULL;
  12.792 +
  12.793 +    if ( xc_rrobin_global_get(xc->xc_handle, &slice) != 0 )
  12.794 +        return PyErr_SetFromErrno(xc_error);
  12.795 +    
  12.796 +    return Py_BuildValue("{s:L}", "slice", slice);
  12.797 +}
  12.798 +
  12.799 +static PyObject *pyxc_domain_setname(PyObject *self,
  12.800 +                                     PyObject *args,
  12.801 +                                     PyObject *kwds)
  12.802 +{
  12.803 +    XcObject *xc = (XcObject *)self;
  12.804 +    u32 dom;
  12.805 +    char *name;
  12.806 +
  12.807 +    static char *kwd_list[] = { "dom", "name", NULL };
  12.808 +
  12.809 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list, 
  12.810 +                                      &dom, &name) )
  12.811 +        return NULL;
  12.812 +
  12.813 +    if ( xc_domain_setname(xc->xc_handle, dom, name) != 0 )
  12.814 +        return PyErr_SetFromErrno(xc_error);
  12.815 +    
  12.816 +    Py_INCREF(zero);
  12.817 +    return zero;
  12.818 +}
  12.819 +
  12.820 +static PyObject *pyxc_domain_setmaxmem(PyObject *self,
  12.821 +                                       PyObject *args,
  12.822 +                                       PyObject *kwds)
  12.823 +{
  12.824 +    XcObject *xc = (XcObject *)self;
  12.825 +
  12.826 +    u32 dom;
  12.827 +    unsigned long max_memkb;
  12.828 +
  12.829 +    static char *kwd_list[] = { "dom", "max_memkb", NULL };
  12.830 +
  12.831 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, 
  12.832 +                                      &dom, &max_memkb) )
  12.833 +        return NULL;
  12.834 +
  12.835 +    if ( xc_domain_setmaxmem(xc->xc_handle, dom, max_memkb) != 0 )
  12.836 +        return PyErr_SetFromErrno(xc_error);
  12.837 +    
  12.838 +    Py_INCREF(zero);
  12.839 +    return zero;
  12.840 +}
  12.841 +
  12.842 +
  12.843 +static PyMethodDef pyxc_methods[] = {
  12.844 +    { "domain_create", 
  12.845 +      (PyCFunction)pyxc_domain_create, 
  12.846 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.847 +      "Create a new domain.\n"
  12.848 +      " mem_kb [int, 0]:        Memory allocation, in kilobytes.\n"
  12.849 +      " name   [str, '(anon)']: Informative textual name.\n\n"
  12.850 +      "Returns: [int] new domain identifier; -1 on error.\n" },
  12.851 +
  12.852 +    { "domain_pause", 
  12.853 +      (PyCFunction)pyxc_domain_pause, 
  12.854 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.855 +      "Temporarily pause execution of a domain.\n"
  12.856 +      " dom [int]: Identifier of domain to be paused.\n\n"
  12.857 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.858 +
  12.859 +    { "domain_unpause", 
  12.860 +      (PyCFunction)pyxc_domain_unpause, 
  12.861 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.862 +      "(Re)start execution of a domain.\n"
  12.863 +      " dom [int]: Identifier of domain to be unpaused.\n\n"
  12.864 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.865 +
  12.866 +    { "domain_destroy", 
  12.867 +      (PyCFunction)pyxc_domain_destroy, 
  12.868 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.869 +      "Destroy a domain.\n"
  12.870 +      " dom [int]:    Identifier of domain to be destroyed.\n\n"
  12.871 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.872 +
  12.873 +    { "domain_pincpu", 
  12.874 +      (PyCFunction)pyxc_domain_pincpu, 
  12.875 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.876 +      "Pin a domain to a specified CPU.\n"
  12.877 +      " dom [int]:     Identifier of domain to be pinned.\n"
  12.878 +      " cpu [int, -1]: CPU to pin to, or -1 to unpin\n\n"
  12.879 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.880 +
  12.881 +    { "domain_getinfo", 
  12.882 +      (PyCFunction)pyxc_domain_getinfo, 
  12.883 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.884 +      "Get information regarding a set of domains, in increasing id order.\n"
  12.885 +      " first_dom [int, 0]:    First domain to retrieve info about.\n"
  12.886 +      " max_doms  [int, 1024]: Maximum number of domains to retrieve info"
  12.887 +      " about.\n\n"
  12.888 +      "Returns: [list of dicts] if list length is less than 'max_doms'\n"
  12.889 +      "         parameter then there was an error, or the end of the\n"
  12.890 +      "         domain-id space was reached.\n"
  12.891 +      " dom      [int]: Identifier of domain to which this info pertains\n"
  12.892 +      " cpu      [int]:  CPU to which this domain is bound\n"
  12.893 +      " dying    [int]:  Bool - is the domain dying?\n"
  12.894 +      " crashed  [int]:  Bool - has the domain crashed?\n"
  12.895 +      " shutdown [int]:  Bool - has the domain shut itself down?\n"
  12.896 +      " paused   [int]:  Bool - is the domain paused by control software?\n"
  12.897 +      " blocked  [int]:  Bool - is the domain blocked waiting for an event?\n"
  12.898 +      " running  [int]:  Bool - is the domain currently running?\n"
  12.899 +      " mem_kb   [int]:  Memory reservation, in kilobytes\n"
  12.900 +      " cpu_time [long]: CPU time consumed, in nanoseconds\n"
  12.901 +      " name     [str]:  Identifying name\n"
  12.902 +      " shutdown_reason [int]: Numeric code from guest OS, explaining "
  12.903 +      "reason why it shut itself down.\n" },
  12.904 +
  12.905 +    { "linux_save", 
  12.906 +      (PyCFunction)pyxc_linux_save, 
  12.907 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.908 +      "Save the CPU and memory state of a Linux guest OS.\n"
  12.909 +      " dom        [int]:    Identifier of domain to be saved.\n"
  12.910 +      " state_file [str]:    Name of state file. Must not currently exist.\n"
  12.911 +      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
  12.912 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.913 +
  12.914 +    { "linux_restore", 
  12.915 +      (PyCFunction)pyxc_linux_restore, 
  12.916 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.917 +      "Restore the CPU and memory state of a Linux guest OS.\n"
  12.918 +      " state_file [str]:    Name of state file. Must not currently exist.\n"
  12.919 +      " progress   [int, 1]: Bool - display a running progress indication?\n\n"
  12.920 +      "Returns: [int] new domain identifier on success; -1 on error.\n" },
  12.921 +
  12.922 +    { "linux_build", 
  12.923 +      (PyCFunction)pyxc_linux_build, 
  12.924 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.925 +      "Build a new Linux guest OS.\n"
  12.926 +      " dom     [int]:      Identifier of domain to build into.\n"
  12.927 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
  12.928 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
  12.929 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
  12.930 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.931 +
  12.932 +    { "netbsd_build", 
  12.933 +      (PyCFunction)pyxc_netbsd_build, 
  12.934 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.935 +      "Build a new NetBSD guest OS.\n"
  12.936 +      " dom     [int]:     Identifier of domain to build into.\n"
  12.937 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
  12.938 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
  12.939 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.940 +
  12.941 +    { "bvtsched_global_set",
  12.942 +      (PyCFunction)pyxc_bvtsched_global_set,
  12.943 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.944 +      "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
  12.945 +      " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
  12.946 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.947 +
  12.948 +    { "bvtsched_global_get",
  12.949 +      (PyCFunction)pyxc_bvtsched_global_get,
  12.950 +      METH_KEYWORDS, "\n"
  12.951 +      "Get global tuning parameters for BVT scheduler.\n"
  12.952 +      "Returns: [dict]:\n"
  12.953 +      " ctx_allow [int]: context switch allowance\n" },
  12.954 +
  12.955 +    { "bvtsched_domain_set",
  12.956 +      (PyCFunction)pyxc_bvtsched_domain_set,
  12.957 +      METH_VARARGS | METH_KEYWORDS, "\n"
  12.958 +      "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
  12.959 +      " dom    [int]: Identifier of domain to be tuned.\n"
  12.960 +      " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
  12.961 +      " warp   [int]: How far to warp domain's EVT on unblock.\n"
  12.962 +      " warpl  [int]: How long the domain can run warped.\n"
  12.963 +      " warpu  [int]: How long before the domain can warp again.\n\n"
  12.964 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.965 +
  12.966 +    { "bvtsched_domain_get",
  12.967 +      (PyCFunction)pyxc_bvtsched_domain_get,
  12.968 +      METH_KEYWORDS, "\n"
  12.969 +      "Get per-domain tuning parameters under the BVT scheduler.\n"
  12.970 +      " dom [int]: Identifier of domain to be queried.\n"
  12.971 +      "Returns [dict]:\n"
  12.972 +      " domain [int]:  Domain ID.\n"
  12.973 +      " mcuadv [long]: MCU Advance.\n"
  12.974 +      " warp   [long]: Warp.\n"
  12.975 +      " warpu  [long]: Unwarp requirement.\n"
  12.976 +      " warpl  [long]: Warp limit,\n"
  12.977 +    },
  12.978 +
  12.979 +    { "atropos_domain_set",
  12.980 +      (PyCFunction)pyxc_atropos_domain_set,
  12.981 +      METH_KEYWORDS, "\n"
  12.982 +      "Set the scheduling parameters for a domain when running with Atropos.\n"
  12.983 +      " dom      [int]:  domain to set\n"
  12.984 +      " period   [long]: domain's scheduling period\n"
  12.985 +      " slice    [long]: domain's slice per period\n"
  12.986 +      " latency  [long]: wakeup latency hint\n"
  12.987 +      " xtratime [int]: boolean\n"
  12.988 +      "Returns: [int] 0 on success; -1 on error.\n" },
  12.989 +
  12.990 +    { "atropos_domain_get",
  12.991 +      (PyCFunction)pyxc_atropos_domain_get,
  12.992 +      METH_KEYWORDS, "\n"
  12.993 +      "Get the current scheduling parameters for a domain when running with\n"
  12.994 +      "the Atropos scheduler."
  12.995 +      " dom      [int]: domain to query\n"
  12.996 +      "Returns:  [dict]\n"
  12.997 +      " domain   [int]: domain ID\n"
  12.998 +      " period   [long]: scheduler period\n"
  12.999 +      " slice    [long]: CPU reservation per period\n"
 12.1000 +      " latency  [long]: unblocking latency hint\n"
 12.1001 +      " xtratime [int] : 0 if not using slack time, nonzero otherwise\n" },
 12.1002 +
 12.1003 +    { "rrobin_global_set",
 12.1004 +      (PyCFunction)pyxc_rrobin_global_set,
 12.1005 +      METH_KEYWORDS, "\n"
 12.1006 +      "Set Round Robin scheduler slice.\n"
 12.1007 +      " slice [long]: Round Robin scheduler slice\n"
 12.1008 +      "Returns: [int] 0 on success, throws an exception on failure\n" },
 12.1009 +
 12.1010 +    { "rrobin_global_get",
 12.1011 +      (PyCFunction)pyxc_rrobin_global_get,
 12.1012 +      METH_KEYWORDS, "\n"
 12.1013 +      "Get Round Robin scheduler settings\n"
 12.1014 +      "Returns [dict]:\n"
 12.1015 +      " slice  [long]: Scheduler time slice.\n" },    
 12.1016 +
 12.1017 +    { "evtchn_bind_interdomain", 
 12.1018 +      (PyCFunction)pyxc_evtchn_bind_interdomain, 
 12.1019 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1020 +      "Open an event channel between two domains.\n"
 12.1021 +      " dom1 [int, SELF]: First domain to be connected.\n"
 12.1022 +      " dom2 [int, SELF]: Second domain to be connected.\n\n"
 12.1023 +      "Returns: [dict] dictionary is empty on failure.\n"
 12.1024 +      " port1 [int]: Port-id for endpoint at dom1.\n"
 12.1025 +      " port2 [int]: Port-id for endpoint at dom2.\n" },
 12.1026 +
 12.1027 +    { "evtchn_bind_virq", 
 12.1028 +      (PyCFunction)pyxc_evtchn_bind_virq, 
 12.1029 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1030 +      "Bind an event channel to the specified VIRQ.\n"
 12.1031 +      " virq [int]: VIRQ to bind.\n\n"
 12.1032 +      "Returns: [int] Bound event-channel port.\n" },
 12.1033 +
 12.1034 +    { "evtchn_close", 
 12.1035 +      (PyCFunction)pyxc_evtchn_close, 
 12.1036 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1037 +      "Close an event channel.\n"
 12.1038 +      " dom  [int, SELF]: Dom-id of one endpoint of the channel.\n"
 12.1039 +      " port [int]:       Port-id of one endpoint of the channel.\n\n"
 12.1040 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1041 +
 12.1042 +    { "evtchn_send", 
 12.1043 +      (PyCFunction)pyxc_evtchn_send, 
 12.1044 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1045 +      "Send an event along a locally-connected event channel.\n"
 12.1046 +      " port [int]: Port-id of a local channel endpoint.\n\n"
 12.1047 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1048 +
 12.1049 +    { "evtchn_status", 
 12.1050 +      (PyCFunction)pyxc_evtchn_status, 
 12.1051 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1052 +      "Query the status of an event channel.\n"
 12.1053 +      " dom  [int, SELF]: Dom-id of one endpoint of the channel.\n"
 12.1054 +      " port [int]:       Port-id of one endpoint of the channel.\n\n"
 12.1055 +      "Returns: [dict] dictionary is empty on failure.\n"
 12.1056 +      " status [str]:  'closed', 'unbound', 'interdomain', 'pirq',"
 12.1057 +      " or 'virq'.\n"
 12.1058 +      "The following are returned if 'status' is 'interdomain':\n"
 12.1059 +      " dom  [int]: Dom-id of remote endpoint.\n"
 12.1060 +      " port [int]: Port-id of remote endpoint.\n"
 12.1061 +      "The following are returned if 'status' is 'pirq' or 'virq':\n"
 12.1062 +      " irq  [int]: IRQ number.\n" },
 12.1063 +
 12.1064 +    { "physdev_pci_access_modify",
 12.1065 +      (PyCFunction)pyxc_physdev_pci_access_modify,
 12.1066 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1067 +      "Allow a domain access to a PCI device\n"
 12.1068 +      " dom    [int]: Identifier of domain to be allowed access.\n"
 12.1069 +      " bus    [int]: PCI bus\n"
 12.1070 +      " dev    [int]: PCI slot\n"
 12.1071 +      " func   [int]: PCI function\n"
 12.1072 +      " enable [int]: Non-zero means enable access; else disable access\n\n"
 12.1073 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1074 + 
 12.1075 +    { "readconsolering", 
 12.1076 +      (PyCFunction)pyxc_readconsolering, 
 12.1077 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1078 +      "Read Xen's console ring.\n"
 12.1079 +      " clear [int, 0]: Bool - clear the ring after reading from it?\n\n"
 12.1080 +      "Returns: [str] string is empty on failure.\n" },
 12.1081 +
 12.1082 +    { "physinfo",
 12.1083 +      (PyCFunction)pyxc_physinfo,
 12.1084 +      METH_VARARGS, "\n"
 12.1085 +      "Get information about the physical host machine\n"
 12.1086 +      "Returns [dict]: information about the hardware"
 12.1087 +      "        [None]: on failure.\n" },
 12.1088 +
 12.1089 +    { "shadow_control", 
 12.1090 +      (PyCFunction)pyxc_shadow_control, 
 12.1091 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1092 +      "Set parameter for shadow pagetable interface\n"
 12.1093 +      " dom [int]:   Identifier of domain.\n"
 12.1094 +      " op [int, 0]: operation\n\n"
 12.1095 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1096 +
 12.1097 +    { "domain_setname", 
 12.1098 +      (PyCFunction)pyxc_domain_setname, 
 12.1099 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1100 +      "Set domain informative textual name\n"
 12.1101 +      " dom [int]:  Identifier of domain.\n"
 12.1102 +      " name [str]: Text string.\n\n"
 12.1103 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1104 +
 12.1105 +    { "domain_setmaxmem", 
 12.1106 +      (PyCFunction)pyxc_domain_setmaxmem, 
 12.1107 +      METH_VARARGS | METH_KEYWORDS, "\n"
 12.1108 +      "Set a domain's memory limit\n"
 12.1109 +      " dom [int]: Identifier of domain.\n"
 12.1110 +      " max_memkb [long]: .\n"
 12.1111 +      "Returns: [int] 0 on success; -1 on error.\n" },
 12.1112 +
 12.1113 +    { NULL, NULL, 0, NULL }
 12.1114 +};
 12.1115 +
 12.1116 +
 12.1117 +/*
 12.1118 + * Definitions for the 'Xc' module wrapper.
 12.1119 + */
 12.1120 +
 12.1121 +staticforward PyTypeObject PyXcType;
 12.1122 +
 12.1123 +static PyObject *PyXc_new(PyObject *self, PyObject *args)
 12.1124 +{
 12.1125 +    XcObject *xc;
 12.1126 +
 12.1127 +    if ( !PyArg_ParseTuple(args, ":new") )
 12.1128 +        return NULL;
 12.1129 +
 12.1130 +    xc = PyObject_New(XcObject, &PyXcType);
 12.1131 +
 12.1132 +    if ( (xc->xc_handle = xc_interface_open()) == -1 )
 12.1133 +    {
 12.1134 +        PyObject_Del((PyObject *)xc);
 12.1135 +        return PyErr_SetFromErrno(xc_error);
 12.1136 +    }
 12.1137 +
 12.1138 +    return (PyObject *)xc;
 12.1139 +}
 12.1140 +
 12.1141 +static PyObject *PyXc_getattr(PyObject *obj, char *name)
 12.1142 +{
 12.1143 +    return Py_FindMethod(pyxc_methods, obj, name);
 12.1144 +}
 12.1145 +
 12.1146 +static void PyXc_dealloc(PyObject *self)
 12.1147 +{
 12.1148 +    XcObject *xc = (XcObject *)self;
 12.1149 +    (void)xc_interface_close(xc->xc_handle);
 12.1150 +    PyObject_Del(self);
 12.1151 +}
 12.1152 +
 12.1153 +static PyTypeObject PyXcType = {
 12.1154 +    PyObject_HEAD_INIT(&PyType_Type)
 12.1155 +    0,
 12.1156 +    "Xc",
 12.1157 +    sizeof(XcObject),
 12.1158 +    0,
 12.1159 +    PyXc_dealloc,    /* tp_dealloc     */
 12.1160 +    NULL,            /* tp_print       */
 12.1161 +    PyXc_getattr,    /* tp_getattr     */
 12.1162 +    NULL,            /* tp_setattr     */
 12.1163 +    NULL,            /* tp_compare     */
 12.1164 +    NULL,            /* tp_repr        */
 12.1165 +    NULL,            /* tp_as_number   */
 12.1166 +    NULL,            /* tp_as_sequence */
 12.1167 +    NULL,            /* tp_as_mapping  */
 12.1168 +    NULL             /* tp_hash        */
 12.1169 +};
 12.1170 +
 12.1171 +static PyMethodDef PyXc_methods[] = {
 12.1172 +    { "new", PyXc_new, METH_VARARGS, "Create a new " XENPKG " object." },
 12.1173 +    { NULL, NULL, 0, NULL }
 12.1174 +};
 12.1175 +
 12.1176 +PyMODINIT_FUNC initxc(void)
 12.1177 +{
 12.1178 +    PyObject *m, *d;
 12.1179 +
 12.1180 +    m = Py_InitModule(XENPKG, PyXc_methods);
 12.1181 +
 12.1182 +    d = PyModule_GetDict(m);
 12.1183 +    xc_error = PyErr_NewException(XENPKG ".error", NULL, NULL);
 12.1184 +    PyDict_SetItemString(d, "error", xc_error);
 12.1185 +
 12.1186 +    zero = PyInt_FromLong(0);
 12.1187 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/python/xen/lowlevel/xu/domain_controller.h	Wed Jun 30 09:52:59 2004 +0000
    14.3 @@ -0,0 +1,532 @@
    14.4 +/******************************************************************************
    14.5 + * domain_controller.h
    14.6 + * 
    14.7 + * Interface to server controller (e.g., 'xend'). This header file defines the 
    14.8 + * interface that is shared with guest OSes.
    14.9 + * 
   14.10 + * Copyright (c) 2004, K A Fraser
   14.11 + */
   14.12 +
   14.13 +#ifndef __DOMAIN_CONTROLLER_H__
   14.14 +#define __DOMAIN_CONTROLLER_H__
   14.15 +
   14.16 +
   14.17 +#ifndef BASIC_START_INFO
   14.18 +#error "Xen header file hypervisor-if.h must already be included here."
   14.19 +#endif
   14.20 +
   14.21 +
   14.22 +/*
   14.23 + * EXTENDED BOOTSTRAP STRUCTURE FOR NEW DOMAINS.
   14.24 + */
   14.25 +
   14.26 +typedef struct {
   14.27 +    BASIC_START_INFO;
   14.28 +    u16 domain_controller_evtchn; /* 320 */
   14.29 +} PACKED extended_start_info_t; /* 322 bytes */
   14.30 +#define SIF_BLK_BE_DOMAIN (1<<4)  /* Is this a block backend domain? */
   14.31 +#define SIF_NET_BE_DOMAIN (1<<5)  /* Is this a net backend domain? */
   14.32 +
   14.33 +
   14.34 +/*
   14.35 + * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be
   14.36 + * interpreted by control software to determine the appropriate action. These 
   14.37 + * are only really advisories: the controller can actually do as it likes.
   14.38 + */
   14.39 +#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
   14.40 +#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
   14.41 +#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
   14.42 +
   14.43 +
   14.44 +/*
   14.45 + * CONTROLLER MESSAGING INTERFACE.
   14.46 + */
   14.47 +
   14.48 +typedef struct {
   14.49 +    u8 type;     /*  0: echoed in response */
   14.50 +    u8 subtype;  /*  1: echoed in response */
   14.51 +    u8 id;       /*  2: echoed in response */
   14.52 +    u8 length;   /*  3: number of bytes in 'msg' */
   14.53 +    u8 msg[60];  /*  4: type-specific message data */
   14.54 +} PACKED control_msg_t; /* 64 bytes */
   14.55 +
   14.56 +#define CONTROL_RING_SIZE 8
   14.57 +typedef u32 CONTROL_RING_IDX;
   14.58 +#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1))
   14.59 +
   14.60 +typedef struct {
   14.61 +    control_msg_t tx_ring[CONTROL_RING_SIZE];   /*    0: guest -> controller */
   14.62 +    control_msg_t rx_ring[CONTROL_RING_SIZE];   /*  512: controller -> guest */
   14.63 +    CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */
   14.64 +    CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */
   14.65 +} PACKED control_if_t; /* 1040 bytes */
   14.66 +
   14.67 +/*
   14.68 + * Top-level command types.
   14.69 + */
   14.70 +#define CMSG_CONSOLE        0  /* Console                 */
   14.71 +#define CMSG_BLKIF_BE       1  /* Block-device backend    */
   14.72 +#define CMSG_BLKIF_FE       2  /* Block-device frontend   */
   14.73 +#define CMSG_NETIF_BE       3  /* Network-device backend  */
   14.74 +#define CMSG_NETIF_FE       4  /* Network-device frontend */
   14.75 +#define CMSG_SHUTDOWN       6  /* Shutdown messages       */
   14.76 +
   14.77 +
   14.78 +/******************************************************************************
   14.79 + * CONSOLE DEFINITIONS
   14.80 + */
   14.81 +
   14.82 +/*
   14.83 + * Subtypes for console messages.
   14.84 + */
   14.85 +#define CMSG_CONSOLE_DATA       0
   14.86 +
   14.87 +
   14.88 +/******************************************************************************
   14.89 + * BLOCK-INTERFACE FRONTEND DEFINITIONS
   14.90 + */
   14.91 +
   14.92 +/* Messages from domain controller to guest. */
   14.93 +#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED   0
   14.94 +
   14.95 +/* Messages from guest to domain controller. */
   14.96 +#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED     32
   14.97 +#define CMSG_BLKIF_FE_INTERFACE_CONNECT         33
   14.98 +#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT      34
   14.99 +
  14.100 +/* These are used by both front-end and back-end drivers. */
  14.101 +#define blkif_vdev_t   u16
  14.102 +#define blkif_pdev_t   u16
  14.103 +#define blkif_sector_t u64
  14.104 +
  14.105 +/*
  14.106 + * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
  14.107 + *  Notify a guest about a status change on one of its block interfaces.
  14.108 + *  If the interface is DESTROYED or DOWN then the interface is disconnected:
  14.109 + *   1. The shared-memory frame is available for reuse.
  14.110 + *   2. Any unacknowledged messgaes pending on the interface were dropped.
  14.111 + */
  14.112 +#define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
  14.113 +#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
  14.114 +#define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
  14.115 +typedef struct {
  14.116 +    u32 handle; /*  0 */
  14.117 +    u32 status; /*  4 */
  14.118 +    u16 evtchn; /*  8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
  14.119 +} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */
  14.120 +
  14.121 +/*
  14.122 + * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
  14.123 + *  Notify the domain controller that the front-end driver is DOWN or UP.
  14.124 + *  When the driver goes DOWN then the controller will send no more
  14.125 + *  status-change notifications. When the driver comes UP then the controller
  14.126 + *  will send a notification for each interface that currently exists.
  14.127 + *  If the driver goes DOWN while interfaces are still UP, the domain
  14.128 + *  will automatically take the interfaces DOWN.
  14.129 + */
  14.130 +#define BLKIF_DRIVER_STATUS_DOWN   0
  14.131 +#define BLKIF_DRIVER_STATUS_UP     1
  14.132 +typedef struct {
  14.133 +    /* IN */
  14.134 +    u32 status;        /*  0: BLKIF_DRIVER_STATUS_??? */
  14.135 +    /* OUT */
  14.136 +    /*
  14.137 +     * Tells driver how many interfaces it should expect to immediately
  14.138 +     * receive notifications about.
  14.139 +     */
  14.140 +    u32 nr_interfaces; /*  4 */
  14.141 +} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
  14.142 +
  14.143 +/*
  14.144 + * CMSG_BLKIF_FE_INTERFACE_CONNECT:
  14.145 + *  If successful, the domain controller will acknowledge with a
  14.146 + *  STATUS_CONNECTED message.
  14.147 + */
  14.148 +typedef struct {
  14.149 +    u32      handle;      /*  0 */
  14.150 +    u32      __pad;
  14.151 +    memory_t shmem_frame; /*  8 */
  14.152 +    MEMORY_PADDING;
  14.153 +} PACKED blkif_fe_interface_connect_t; /* 16 bytes */
  14.154 +
  14.155 +/*
  14.156 + * CMSG_BLKIF_FE_INTERFACE_DISCONNECT:
  14.157 + *  If successful, the domain controller will acknowledge with a
  14.158 + *  STATUS_DISCONNECTED message.
  14.159 + */
  14.160 +typedef struct {
  14.161 +    u32 handle; /*  0 */
  14.162 +} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */
  14.163 +
  14.164 +
  14.165 +/******************************************************************************
  14.166 + * BLOCK-INTERFACE BACKEND DEFINITIONS
  14.167 + */
  14.168 +
  14.169 +/* Messages from domain controller. */
  14.170 +#define CMSG_BLKIF_BE_CREATE      0  /* Create a new block-device interface. */
  14.171 +#define CMSG_BLKIF_BE_DESTROY     1  /* Destroy a block-device interface.    */
  14.172 +#define CMSG_BLKIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
  14.173 +#define CMSG_BLKIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
  14.174 +#define CMSG_BLKIF_BE_VBD_CREATE  4  /* Create a new VBD for an interface.   */
  14.175 +#define CMSG_BLKIF_BE_VBD_DESTROY 5  /* Delete a VBD from an interface.      */
  14.176 +#define CMSG_BLKIF_BE_VBD_GROW    6  /* Append an extent to a given VBD.     */
  14.177 +#define CMSG_BLKIF_BE_VBD_SHRINK  7  /* Remove last extent from a given VBD. */
  14.178 +
  14.179 +/* Messages to domain controller. */
  14.180 +#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
  14.181 +
  14.182 +/*
  14.183 + * Message request/response definitions for block-device messages.
  14.184 + */
  14.185 +
  14.186 +typedef struct {
  14.187 +    blkif_sector_t sector_start;   /*  0 */
  14.188 +    blkif_sector_t sector_length;  /*  8 */
  14.189 +    blkif_pdev_t   device;         /* 16 */
  14.190 +    u16            __pad;          /* 18 */
  14.191 +} PACKED blkif_extent_t; /* 20 bytes */
  14.192 +
  14.193 +/* Non-specific 'okay' return. */
  14.194 +#define BLKIF_BE_STATUS_OKAY                0
  14.195 +/* Non-specific 'error' return. */
  14.196 +#define BLKIF_BE_STATUS_ERROR               1
  14.197 +/* The following are specific error returns. */
  14.198 +#define BLKIF_BE_STATUS_INTERFACE_EXISTS    2
  14.199 +#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
  14.200 +#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4
  14.201 +#define BLKIF_BE_STATUS_VBD_EXISTS          5
  14.202 +#define BLKIF_BE_STATUS_VBD_NOT_FOUND       6
  14.203 +#define BLKIF_BE_STATUS_OUT_OF_MEMORY       7
  14.204 +#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND    8
  14.205 +#define BLKIF_BE_STATUS_MAPPING_ERROR       9
  14.206 +
  14.207 +/* This macro can be used to create an array of descriptive error strings. */
  14.208 +#define BLKIF_BE_STATUS_ERRORS {    \
  14.209 +    "Okay",                         \
  14.210 +    "Non-specific error",           \
  14.211 +    "Interface already exists",     \
  14.212 +    "Interface not found",          \
  14.213 +    "Interface is still connected", \
  14.214 +    "VBD already exists",           \
  14.215 +    "VBD not found",                \
  14.216 +    "Out of memory",                \
  14.217 +    "Extent not found for VBD",     \
  14.218 +    "Could not map domain memory" }
  14.219 +
  14.220 +/*
  14.221 + * CMSG_BLKIF_BE_CREATE:
  14.222 + *  When the driver sends a successful response then the interface is fully
  14.223 + *  created. The controller will send a DOWN notification to the front-end
  14.224 + *  driver.
  14.225 + */
  14.226 +typedef struct { 
  14.227 +    /* IN */
  14.228 +    domid_t    domid;         /*  0: Domain attached to new interface.   */
  14.229 +    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
  14.230 +    /* OUT */
  14.231 +    u32        status;        /*  8 */
  14.232 +} PACKED blkif_be_create_t; /* 12 bytes */
  14.233 +
  14.234 +/*
  14.235 + * CMSG_BLKIF_BE_DESTROY:
  14.236 + *  When the driver sends a successful response then the interface is fully
  14.237 + *  torn down. The controller will send a DESTROYED notification to the
  14.238 + *  front-end driver.
  14.239 + */
  14.240 +typedef struct { 
  14.241 +    /* IN */
  14.242 +    domid_t    domid;         /*  0: Identify interface to be destroyed. */
  14.243 +    u32        blkif_handle;  /*  4: ...ditto...                         */
  14.244 +    /* OUT */
  14.245 +    u32        status;        /*  8 */
  14.246 +} PACKED blkif_be_destroy_t; /* 12 bytes */
  14.247 +
  14.248 +/*
  14.249 + * CMSG_BLKIF_BE_CONNECT:
  14.250 + *  When the driver sends a successful response then the interface is fully
  14.251 + *  connected. The controller will send a CONNECTED notification to the
  14.252 + *  front-end driver.
  14.253 + */
  14.254 +typedef struct { 
  14.255 +    /* IN */
  14.256 +    domid_t    domid;         /*  0: Domain attached to new interface.   */
  14.257 +    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
  14.258 +    memory_t   shmem_frame;   /*  8: Page cont. shared comms window.     */
  14.259 +    MEMORY_PADDING;
  14.260 +    u32        evtchn;        /* 16: Event channel for notifications.    */
  14.261 +    /* OUT */
  14.262 +    u32        status;        /* 20 */
  14.263 +} PACKED blkif_be_connect_t;  /* 24 bytes */
  14.264 +
  14.265 +/*
  14.266 + * CMSG_BLKIF_BE_DISCONNECT:
  14.267 + *  When the driver sends a successful response then the interface is fully
  14.268 + *  disconnected. The controller will send a DOWN notification to the front-end
  14.269 + *  driver.
  14.270 + */
  14.271 +typedef struct { 
  14.272 +    /* IN */
  14.273 +    domid_t    domid;         /*  0: Domain attached to new interface.   */
  14.274 +    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
  14.275 +    /* OUT */
  14.276 +    u32        status;        /*  8 */
  14.277 +} PACKED blkif_be_disconnect_t; /* 12 bytes */
  14.278 +
  14.279 +/* CMSG_BLKIF_BE_VBD_CREATE */
  14.280 +typedef struct { 
  14.281 +    /* IN */
  14.282 +    domid_t    domid;         /*  0: Identify blkdev interface.          */
  14.283 +    u32        blkif_handle;  /*  4: ...ditto...                         */
  14.284 +    blkif_vdev_t vdevice;     /*  8: Interface-specific id for this VBD. */
  14.285 +    u16        readonly;      /* 10: Non-zero -> VBD isn't writeable.    */
  14.286 +    /* OUT */
  14.287 +    u32        status;        /* 12 */
  14.288 +} PACKED blkif_be_vbd_create_t; /* 16 bytes */
  14.289 +
  14.290 +/* CMSG_BLKIF_BE_VBD_DESTROY */
  14.291 +typedef struct {
  14.292 +    /* IN */
  14.293 +    domid_t    domid;         /*  0: Identify blkdev interface.          */
  14.294 +    u32        blkif_handle;  /*  4: ...ditto...                         */
  14.295 +    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
  14.296 +    u16        __pad;         /* 10 */
  14.297 +    /* OUT */
  14.298 +    u32        status;        /* 12 */
  14.299 +} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
  14.300 +
  14.301 +/* CMSG_BLKIF_BE_VBD_GROW */
  14.302 +typedef struct { 
  14.303 +    /* IN */
  14.304 +    domid_t    domid;         /*  0: Identify blkdev interface.          */
  14.305 +    u32        blkif_handle;  /*  4: ...ditto...                         */
  14.306 +    blkif_extent_t extent;    /*  8: Physical extent to append to VBD.   */
  14.307 +    blkif_vdev_t vdevice;     /* 28: Interface-specific id of the VBD.   */
  14.308 +    u16        __pad;         /* 30 */
  14.309 +    /* OUT */
  14.310 +    u32        status;        /* 32 */
  14.311 +} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
  14.312 +
  14.313 +/* CMSG_BLKIF_BE_VBD_SHRINK */
  14.314 +typedef struct { 
  14.315 +    /* IN */
  14.316 +    domid_t    domid;         /*  0: Identify blkdev interface.          */
  14.317 +    u32        blkif_handle;  /*  4: ...ditto...                         */
  14.318 +    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
  14.319 +    u16        __pad;         /* 10 */
  14.320 +    /* OUT */
  14.321 +    u32        status;        /* 12 */
  14.322 +} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
  14.323 +
  14.324 +/*
  14.325 + * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
  14.326 + *  Notify the domain controller that the back-end driver is DOWN or UP.
  14.327 + *  If the driver goes DOWN while interfaces are still UP, the controller
  14.328 + *  will automatically send DOWN notifications.
  14.329 + */
  14.330 +typedef struct {
  14.331 +    u32        status;        /*  0: BLKIF_DRIVER_STATUS_??? */
  14.332 +} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
  14.333 +
  14.334 +
  14.335 +/******************************************************************************
  14.336 + * NETWORK-INTERFACE FRONTEND DEFINITIONS
  14.337 + */
  14.338 +
  14.339 +/* Messages from domain controller to guest. */
  14.340 +#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED   0
  14.341 +
  14.342 +/* Messages from guest to domain controller. */
  14.343 +#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED     32
  14.344 +#define CMSG_NETIF_FE_INTERFACE_CONNECT         33
  14.345 +#define CMSG_NETIF_FE_INTERFACE_DISCONNECT      34
  14.346 +
  14.347 +/*
  14.348 + * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
  14.349 + *  Notify a guest about a status change on one of its network interfaces.
  14.350 + *  If the interface is DESTROYED or DOWN then the interface is disconnected:
  14.351 + *   1. The shared-memory frame is available for reuse.
  14.352 + *   2. Any unacknowledged messgaes pending on the interface were dropped.
  14.353 + */
  14.354 +#define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
  14.355 +#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
  14.356 +#define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
  14.357 +typedef struct {
  14.358 +    u32        handle; /*  0 */
  14.359 +    u32        status; /*  4 */
  14.360 +    u16        evtchn; /*  8: status == NETIF_INTERFACE_STATUS_CONNECTED */
  14.361 +    u8         mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
  14.362 +} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */
  14.363 +
  14.364 +/*
  14.365 + * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
  14.366 + *  Notify the domain controller that the front-end driver is DOWN or UP.
  14.367 + *  When the driver goes DOWN then the controller will send no more
  14.368 + *  status-change notifications. When the driver comes UP then the controller
  14.369 + *  will send a notification for each interface that currently exists.
  14.370 + *  If the driver goes DOWN while interfaces are still UP, the domain
  14.371 + *  will automatically take the interfaces DOWN.
  14.372 + */
  14.373 +#define NETIF_DRIVER_STATUS_DOWN   0
  14.374 +#define NETIF_DRIVER_STATUS_UP     1
  14.375 +typedef struct {
  14.376 +    /* IN */
  14.377 +    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
  14.378 +    /* OUT */
  14.379 +    /*
  14.380 +     * Tells driver how many interfaces it should expect to immediately
  14.381 +     * receive notifications about.
  14.382 +     */
  14.383 +    u32        nr_interfaces; /*  4 */
  14.384 +} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
  14.385 +
  14.386 +/*
  14.387 + * CMSG_NETIF_FE_INTERFACE_CONNECT:
  14.388 + *  If successful, the domain controller will acknowledge with a
  14.389 + *  STATUS_CONNECTED message.
  14.390 + */
  14.391 +typedef struct {
  14.392 +    u32        handle;         /*  0 */
  14.393 +    u32        __pad;          /*  4 */
  14.394 +    memory_t   tx_shmem_frame; /*  8 */
  14.395 +    MEMORY_PADDING;
  14.396 +    memory_t   rx_shmem_frame; /* 16 */
  14.397 +    MEMORY_PADDING;
  14.398 +} PACKED netif_fe_interface_connect_t; /* 24 bytes */
  14.399 +
  14.400 +/*
  14.401 + * CMSG_NETIF_FE_INTERFACE_DISCONNECT:
  14.402 + *  If successful, the domain controller will acknowledge with a
  14.403 + *  STATUS_DISCONNECTED message.
  14.404 + */
  14.405 +typedef struct {
  14.406 +    u32        handle;        /*  0 */
  14.407 +} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */
  14.408 +
  14.409 +
  14.410 +/******************************************************************************
  14.411 + * NETWORK-INTERFACE BACKEND DEFINITIONS
  14.412 + */
  14.413 +
  14.414 +/* Messages from domain controller. */
  14.415 +#define CMSG_NETIF_BE_CREATE      0  /* Create a new net-device interface. */
  14.416 +#define CMSG_NETIF_BE_DESTROY     1  /* Destroy a net-device interface.    */
  14.417 +#define CMSG_NETIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
  14.418 +#define CMSG_NETIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
  14.419 +
  14.420 +/* Messages to domain controller. */
  14.421 +#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
  14.422 +
  14.423 +/*
  14.424 + * Message request/response definitions for net-device messages.
  14.425 + */
  14.426 +
  14.427 +/* Non-specific 'okay' return. */
  14.428 +#define NETIF_BE_STATUS_OKAY                0
  14.429 +/* Non-specific 'error' return. */
  14.430 +#define NETIF_BE_STATUS_ERROR               1
  14.431 +/* The following are specific error returns. */
  14.432 +#define NETIF_BE_STATUS_INTERFACE_EXISTS    2
  14.433 +#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3
  14.434 +#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4
  14.435 +#define NETIF_BE_STATUS_OUT_OF_MEMORY       5
  14.436 +#define NETIF_BE_STATUS_MAPPING_ERROR       6
  14.437 +
  14.438 +/* This macro can be used to create an array of descriptive error strings. */
  14.439 +#define NETIF_BE_STATUS_ERRORS {    \
  14.440 +    "Okay",                         \
  14.441 +    "Non-specific error",           \
  14.442 +    "Interface already exists",     \
  14.443 +    "Interface not found",          \
  14.444 +    "Interface is still connected", \
  14.445 +    "Out of memory",                \
  14.446 +    "Could not map domain memory" }
  14.447 +
  14.448 +/*
  14.449 + * CMSG_NETIF_BE_CREATE:
  14.450 + *  When the driver sends a successful response then the interface is fully
  14.451 + *  created. The controller will send a DOWN notification to the front-end
  14.452 + *  driver.
  14.453 + */
  14.454 +typedef struct { 
  14.455 +    /* IN */
  14.456 +    domid_t    domid;         /*  0: Domain attached to new interface.   */
  14.457 +    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
  14.458 +    u8         mac[6];        /*  8 */
  14.459 +    u16        __pad;         /* 14 */
  14.460 +    /* OUT */
  14.461 +    u32        status;        /* 16 */
  14.462 +} PACKED netif_be_create_t; /* 20 bytes */
  14.463 +
  14.464 +/*
  14.465 + * CMSG_NETIF_BE_DESTROY:
  14.466 + *  When the driver sends a successful response then the interface is fully
  14.467 + *  torn down. The controller will send a DESTROYED notification to the
  14.468 + *  front-end driver.
  14.469 + */
  14.470 +typedef struct { 
  14.471 +    /* IN */
  14.472 +    domid_t    domid;         /*  0: Identify interface to be destroyed. */
  14.473 +    u32        netif_handle;  /*  4: ...ditto...                         */
  14.474 +    /* OUT */
  14.475 +    u32   status;             /*  8 */
  14.476 +} PACKED netif_be_destroy_t; /* 12 bytes */
  14.477 +
  14.478 +/*
  14.479 + * CMSG_NETIF_BE_CONNECT:
  14.480 + *  When the driver sends a successful response then the interface is fully
  14.481 + *  connected. The controller will send a CONNECTED notification to the
  14.482 + *  front-end driver.
  14.483 + */
  14.484 +typedef struct { 
  14.485 +    /* IN */
  14.486 +    domid_t    domid;          /*  0: Domain attached to new interface.   */
  14.487 +    u32        netif_handle;   /*  4: Domain-specific interface handle.   */
  14.488 +    memory_t   tx_shmem_frame; /*  8: Page cont. tx shared comms window.  */
  14.489 +    MEMORY_PADDING;
  14.490 +    memory_t   rx_shmem_frame; /* 16: Page cont. rx shared comms window.  */
  14.491 +    MEMORY_PADDING;
  14.492 +    u16        evtchn;         /* 24: Event channel for notifications.    */
  14.493 +    u16        __pad;          /* 26 */
  14.494 +    /* OUT */
  14.495 +    u32        status;         /* 28 */
  14.496 +} PACKED netif_be_connect_t; /* 32 bytes */
  14.497 +
  14.498 +/*
  14.499 + * CMSG_NETIF_BE_DISCONNECT:
  14.500 + *  When the driver sends a successful response then the interface is fully
  14.501 + *  disconnected. The controller will send a DOWN notification to the front-end
  14.502 + *  driver.
  14.503 + */
  14.504 +typedef struct { 
  14.505 +    /* IN */
  14.506 +    domid_t    domid;         /*  0: Domain attached to new interface.   */
  14.507 +    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
  14.508 +    /* OUT */
  14.509 +    u32        status;        /*  8 */
  14.510 +} PACKED netif_be_disconnect_t; /* 12 bytes */
  14.511 +
  14.512 +/*
  14.513 + * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
  14.514 + *  Notify the domain controller that the back-end driver is DOWN or UP.
  14.515 + *  If the driver goes DOWN while interfaces are still UP, the domain
  14.516 + *  will automatically send DOWN notifications.
  14.517 + */
  14.518 +typedef struct {
  14.519 +    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
  14.520 +} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
  14.521 +
  14.522 +
  14.523 +/******************************************************************************
  14.524 + * SHUTDOWN DEFINITIONS
  14.525 + */
  14.526 +
  14.527 +/*
  14.528 + * Subtypes for shutdown messages.
  14.529 + */
  14.530 +#define CMSG_SHUTDOWN_POWEROFF  0   /* Clean shutdown (SHUTDOWN_poweroff).   */
  14.531 +#define CMSG_SHUTDOWN_REBOOT    1   /* Clean shutdown (SHUTDOWN_reboot).     */
  14.532 +#define CMSG_SHUTDOWN_SUSPEND   2   /* Create suspend info, then             */
  14.533 +                                    /* SHUTDOWN_suspend.                     */
  14.534 +
  14.535 +#endif /* __DOMAIN_CONTROLLER_H__ */
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/python/xen/lowlevel/xu/xu.c	Wed Jun 30 09:52:59 2004 +0000
    15.3 @@ -0,0 +1,1386 @@
    15.4 +/******************************************************************************
    15.5 + * utils.c
    15.6 + * 
    15.7 + * Copyright (c) 2004, K A Fraser
    15.8 + */
    15.9 +
   15.10 +#include <Python.h>
   15.11 +#include <stdio.h>
   15.12 +#include <stdlib.h>
   15.13 +#include <string.h>
   15.14 +#include <sys/ioctl.h>
   15.15 +#include <sys/types.h>
   15.16 +#include <sys/wait.h>
   15.17 +#include <sys/stat.h>
   15.18 +#include <sys/socket.h>
   15.19 +#include <sys/mman.h>
   15.20 +#include <sys/poll.h>
   15.21 +#include <netinet/in.h>
   15.22 +#include <fcntl.h>
   15.23 +#include <unistd.h>
   15.24 +#include <errno.h>
   15.25 +#include <signal.h>
   15.26 +#include <xc.h>
   15.27 +
   15.28 +#include <hypervisor-if.h>
   15.29 +#include "domain_controller.h"
   15.30 +
   15.31 +#include <asm-xen/proc_cmd.h>
   15.32 +
   15.33 +#define XENPKG "xen.lowlevel.xu"
   15.34 +
   15.35 +/* Needed for Python versions earlier than 2.3. */
   15.36 +#ifndef PyMODINIT_FUNC
   15.37 +#define PyMODINIT_FUNC DL_EXPORT(void)
   15.38 +#endif
   15.39 +
   15.40 +/* NB. The following should be kept in sync with the kernel's evtchn driver. */
   15.41 +#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
   15.42 +#define EVTCHN_DEV_MAJOR 10
   15.43 +#define EVTCHN_DEV_MINOR 200
   15.44 +#define PORT_NORMAL     0x0000   /* A standard event notification.      */ 
   15.45 +#define PORT_EXCEPTION  0x8000   /* An exceptional notification.        */
   15.46 +#define PORTIDX_MASK    0x7fff   /* Strip subtype to obtain port index. */
   15.47 +/* /dev/xen/evtchn ioctls: */
   15.48 +/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
   15.49 +#define EVTCHN_RESET  _IO('E', 1)
   15.50 +/* EVTCHN_BIND: Bind to teh specified event-channel port. */
   15.51 +#define EVTCHN_BIND   _IO('E', 2)
   15.52 +/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
   15.53 +#define EVTCHN_UNBIND _IO('E', 3)
   15.54 +
   15.55 +/* Size of a machine page frame. */
   15.56 +#define PAGE_SIZE 4096
   15.57 +
   15.58 +
   15.59 +/*
   15.60 + * *********************** NOTIFIER ***********************
   15.61 + */
   15.62 +
   15.63 +typedef struct {
   15.64 +    PyObject_HEAD;
   15.65 +    int evtchn_fd;
   15.66 +} xu_notifier_object;
   15.67 +
   15.68 +static PyObject *xu_notifier_read(PyObject *self, PyObject *args)
   15.69 +{
   15.70 +    xu_notifier_object *xun = (xu_notifier_object *)self;
   15.71 +    u16 v;
   15.72 +    int bytes;
   15.73 +
   15.74 +    if ( !PyArg_ParseTuple(args, "") )
   15.75 +        return NULL;
   15.76 +    
   15.77 +    while ( (bytes = read(xun->evtchn_fd, &v, sizeof(v))) == -1 )
   15.78 +    {
   15.79 +        if ( errno == EINTR )
   15.80 +            continue;
   15.81 +        if ( errno == EAGAIN )
   15.82 +            goto none;
   15.83 +        return PyErr_SetFromErrno(PyExc_IOError);
   15.84 +    }
   15.85 +    
   15.86 +    if ( bytes == sizeof(v) )
   15.87 +        return Py_BuildValue("(i,i)", v&PORTIDX_MASK, v&~PORTIDX_MASK);
   15.88 +
   15.89 + none:
   15.90 +    Py_INCREF(Py_None);
   15.91 +    return Py_None;
   15.92 +}
   15.93 +
   15.94 +static PyObject *xu_notifier_unmask(PyObject *self, PyObject *args)
   15.95 +{
   15.96 +    xu_notifier_object *xun = (xu_notifier_object *)self;
   15.97 +    u16 v;
   15.98 +    int idx;
   15.99 +
  15.100 +    if ( !PyArg_ParseTuple(args, "i", &idx) )
  15.101 +        return NULL;
  15.102 +
  15.103 +    v = (u16)idx;
  15.104 +    
  15.105 +    (void)write(xun->evtchn_fd, &v, sizeof(v));
  15.106 +
  15.107 +    Py_INCREF(Py_None);
  15.108 +    return Py_None;
  15.109 +}
  15.110 +
  15.111 +static PyObject *xu_notifier_bind(PyObject *self, PyObject *args)
  15.112 +{
  15.113 +    xu_notifier_object *xun = (xu_notifier_object *)self;
  15.114 +    int idx;
  15.115 +
  15.116 +    if ( !PyArg_ParseTuple(args, "i", &idx) )
  15.117 +        return NULL;
  15.118 +
  15.119 +    if ( ioctl(xun->evtchn_fd, EVTCHN_BIND, idx) != 0 )
  15.120 +        return PyErr_SetFromErrno(PyExc_IOError);
  15.121 +
  15.122 +    Py_INCREF(Py_None);
  15.123 +    return Py_None;
  15.124 +}
  15.125 +
  15.126 +static PyObject *xu_notifier_unbind(PyObject *self, PyObject *args)
  15.127 +{
  15.128 +    xu_notifier_object *xun = (xu_notifier_object *)self;
  15.129 +    int idx;
  15.130 +
  15.131 +    if ( !PyArg_ParseTuple(args, "i", &idx) )
  15.132 +        return NULL;
  15.133 +
  15.134 +    if ( ioctl(xun->evtchn_fd, EVTCHN_UNBIND, idx) != 0 )
  15.135 +        return PyErr_SetFromErrno(PyExc_IOError);
  15.136 +
  15.137 +    Py_INCREF(Py_None);
  15.138 +    return Py_None;
  15.139 +}
  15.140 +
  15.141 +static PyObject *xu_notifier_fileno(PyObject *self, PyObject *args)
  15.142 +{
  15.143 +    xu_notifier_object *xun = (xu_notifier_object *)self;
  15.144 +    return PyInt_FromLong(xun->evtchn_fd);
  15.145 +}
  15.146 +
  15.147 +static PyMethodDef xu_notifier_methods[] = {
  15.148 +    { "read",
  15.149 +      (PyCFunction)xu_notifier_read,
  15.150 +      METH_VARARGS,
  15.151 +      "Read a (@port, @type) pair.\n" },
  15.152 +
  15.153 +    { "unmask", 
  15.154 +      (PyCFunction)xu_notifier_unmask,
  15.155 +      METH_VARARGS,
  15.156 +      "Unmask notifications for a @port.\n" },
  15.157 +
  15.158 +    { "bind", 
  15.159 +      (PyCFunction)xu_notifier_bind,
  15.160 +      METH_VARARGS,
  15.161 +      "Get notifications for a @port.\n" },
  15.162 +
  15.163 +    { "unbind", 
  15.164 +      (PyCFunction)xu_notifier_unbind,
  15.165 +      METH_VARARGS,
  15.166 +      "No longer get notifications for a @port.\n" },
  15.167 +
  15.168 +    { "fileno", 
  15.169 +      (PyCFunction)xu_notifier_fileno,
  15.170 +      METH_VARARGS,
  15.171 +      "Return the file descriptor for the notification channel.\n" },
  15.172 +
  15.173 +    { NULL, NULL, 0, NULL }
  15.174 +};
  15.175 +
  15.176 +staticforward PyTypeObject xu_notifier_type;
  15.177 +
  15.178 +static PyObject *xu_notifier_new(PyObject *self, PyObject *args)
  15.179 +{
  15.180 +    xu_notifier_object *xun;
  15.181 +
  15.182 +    if ( !PyArg_ParseTuple(args, "") )
  15.183 +        return NULL;
  15.184 +
  15.185 +    xun = PyObject_New(xu_notifier_object, &xu_notifier_type);
  15.186 +
  15.187 + reopen:
  15.188 +    xun->evtchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
  15.189 +    if ( xun->evtchn_fd == -1 )
  15.190 +    {
  15.191 +        if ( (errno == ENOENT) &&
  15.192 +             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
  15.193 +             (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, 
  15.194 +                    (EVTCHN_DEV_MAJOR << 8) | EVTCHN_DEV_MINOR) == 0) )
  15.195 +            goto reopen;
  15.196 +        PyObject_Del((PyObject *)xun);
  15.197 +        return PyErr_SetFromErrno(PyExc_IOError);
  15.198 +    }
  15.199 +
  15.200 +    return (PyObject *)xun;
  15.201 +}
  15.202 +
  15.203 +static PyObject *xu_notifier_getattr(PyObject *obj, char *name)
  15.204 +{
  15.205 +    if ( strcmp(name, "EXCEPTION") == 0 )
  15.206 +        return PyInt_FromLong(PORT_EXCEPTION);
  15.207 +    if ( strcmp(name, "NORMAL") == 0 )
  15.208 +        return PyInt_FromLong(PORT_NORMAL);
  15.209 +    return Py_FindMethod(xu_notifier_methods, obj, name);
  15.210 +}
  15.211 +
  15.212 +static void xu_notifier_dealloc(PyObject *self)
  15.213 +{
  15.214 +    xu_notifier_object *xun = (xu_notifier_object *)self;
  15.215 +    (void)close(xun->evtchn_fd);
  15.216 +    PyObject_Del(self);
  15.217 +}
  15.218 +
  15.219 +static PyTypeObject xu_notifier_type = {
  15.220 +    PyObject_HEAD_INIT(&PyType_Type)
  15.221 +    0,
  15.222 +    "notifier",
  15.223 +    sizeof(xu_notifier_object),
  15.224 +    0,
  15.225 +    xu_notifier_dealloc, /* tp_dealloc     */
  15.226 +    NULL,                /* tp_print       */
  15.227 +    xu_notifier_getattr, /* tp_getattr     */
  15.228 +    NULL,                /* tp_setattr     */
  15.229 +    NULL,                /* tp_compare     */
  15.230 +    NULL,                /* tp_repr        */
  15.231 +    NULL,                /* tp_as_number   */
  15.232 +    NULL,                /* tp_as_sequence */
  15.233 +    NULL,                /* tp_as_mapping  */
  15.234 +    NULL                 /* tp_hash        */
  15.235 +};
  15.236 +
  15.237 +
  15.238 +
  15.239 +/*
  15.240 + * *********************** MESSAGE ***********************
  15.241 + */
  15.242 +
  15.243 +#define TYPE(_x,_y) (((_x)<<8)|(_y))
  15.244 +#define P2C(_struct, _field, _ctype)                                      \
  15.245 +    do {                                                                  \
  15.246 +        PyObject *obj;                                                    \
  15.247 +        if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL )     \
  15.248 +        {                                                                 \
  15.249 +            if ( PyInt_Check(obj) )                                       \
  15.250 +            {                                                             \
  15.251 +                ((_struct *)&xum->msg.msg[0])->_field =                   \
  15.252 +                  (_ctype)PyInt_AsLong(obj);                              \
  15.253 +                dict_items_parsed++;                                      \
  15.254 +            }                                                             \
  15.255 +            else if ( PyLong_Check(obj) )                                 \
  15.256 +            {                                                             \
  15.257 +                ((_struct *)&xum->msg.msg[0])->_field =                   \
  15.258 +                  (_ctype)PyLong_AsUnsignedLongLong(obj);                 \
  15.259 +                dict_items_parsed++;                                      \
  15.260 +            }                                                             \
  15.261 +        }                                                                 \
  15.262 +        xum->msg.length = sizeof(_struct);                                \
  15.263 +    } while ( 0 )
  15.264 +#define C2P(_struct, _field, _pytype, _ctype)                             \
  15.265 +    do {                                                                  \
  15.266 +        PyObject *obj = Py ## _pytype ## _From ## _ctype                  \
  15.267 +                        (((_struct *)&xum->msg.msg[0])->_field);          \
  15.268 +        if ( dict == NULL ) dict = PyDict_New();                          \
  15.269 +        PyDict_SetItemString(dict, #_field, obj);                         \
  15.270 +    } while ( 0 )
  15.271 +
  15.272 +typedef struct {
  15.273 +    PyObject_HEAD;
  15.274 +    control_msg_t msg;
  15.275 +} xu_message_object;
  15.276 +
  15.277 +static PyObject *xu_message_append_payload(PyObject *self, PyObject *args)
  15.278 +{
  15.279 +    xu_message_object *xum = (xu_message_object *)self;
  15.280 +    char *str;
  15.281 +    int len;
  15.282 +
  15.283 +    if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
  15.284 +        return NULL;
  15.285 +
  15.286 +    if ( (len + xum->msg.length) > sizeof(xum->msg.msg) )
  15.287 +    {
  15.288 +        PyErr_SetString(PyExc_RuntimeError, "out of space in control message");
  15.289 +        return NULL;
  15.290 +    }
  15.291 +
  15.292 +    memcpy(&xum->msg.msg[xum->msg.length], str, len);
  15.293 +    xum->msg.length += len;
  15.294 +
  15.295 +    Py_INCREF(Py_None);
  15.296 +    return Py_None;
  15.297 +}
  15.298 +
  15.299 +static PyObject *xu_message_set_response_fields(PyObject *self, PyObject *args)
  15.300 +{
  15.301 +    xu_message_object *xum = (xu_message_object *)self;
  15.302 +    PyObject *payload;
  15.303 +    int dict_items_parsed = 0;
  15.304 +
  15.305 +    if ( !PyArg_ParseTuple(args, "O", &payload) )
  15.306 +        return NULL;
  15.307 +
  15.308 +    if ( !PyDict_Check(payload) )
  15.309 +    {
  15.310 +        PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
  15.311 +        return NULL;
  15.312 +    }
  15.313 +
  15.314 +    switch ( TYPE(xum->msg.type, xum->msg.subtype) )
  15.315 +    {
  15.316 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
  15.317 +        P2C(blkif_fe_driver_status_changed_t, nr_interfaces, u32);
  15.318 +        break;
  15.319 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  15.320 +        P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
  15.321 +        break;
  15.322 +    }
  15.323 +
  15.324 +    if ( dict_items_parsed != PyDict_Size(payload) )
  15.325 +    {
  15.326 +        PyErr_SetString(PyExc_TypeError, "payload contains bad items");
  15.327 +        return NULL;
  15.328 +    }
  15.329 +
  15.330 +    Py_INCREF(Py_None);
  15.331 +    return Py_None;
  15.332 +}
  15.333 +
  15.334 +static PyObject *xu_message_get_payload(PyObject *self, PyObject *args)
  15.335 +{
  15.336 +    xu_message_object *xum = (xu_message_object *)self;
  15.337 +    PyObject *dict = NULL;
  15.338 +
  15.339 +    if ( !PyArg_ParseTuple(args, "") )
  15.340 +        return NULL;
  15.341 +
  15.342 +    switch ( TYPE(xum->msg.type, xum->msg.subtype) )
  15.343 +    {
  15.344 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
  15.345 +        C2P(blkif_fe_interface_status_changed_t, handle, Int, Long);
  15.346 +        C2P(blkif_fe_interface_status_changed_t, status, Int, Long);
  15.347 +        C2P(blkif_fe_interface_status_changed_t, evtchn, Int, Long);
  15.348 +        return dict;
  15.349 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED):
  15.350 +        C2P(blkif_fe_driver_status_changed_t, status, Int, Long);
  15.351 +        return dict;
  15.352 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_CONNECT):
  15.353 +        C2P(blkif_fe_interface_connect_t, handle,      Int, Long);
  15.354 +        C2P(blkif_fe_interface_connect_t, shmem_frame, Int, Long);
  15.355 +        return dict;
  15.356 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_DISCONNECT):
  15.357 +        C2P(blkif_fe_interface_disconnect_t, handle, Int, Long);
  15.358 +        return dict;
  15.359 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
  15.360 +        C2P(blkif_be_create_t, domid,        Int, Long);
  15.361 +        C2P(blkif_be_create_t, blkif_handle, Int, Long);
  15.362 +        C2P(blkif_be_create_t, status,       Int, Long);
  15.363 +        return dict;
  15.364 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
  15.365 +        C2P(blkif_be_destroy_t, domid,        Int, Long);
  15.366 +        C2P(blkif_be_destroy_t, blkif_handle, Int, Long);
  15.367 +        C2P(blkif_be_destroy_t, status,       Int, Long);
  15.368 +        return dict;
  15.369 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
  15.370 +        C2P(blkif_be_connect_t, domid,        Int, Long);
  15.371 +        C2P(blkif_be_connect_t, blkif_handle, Int, Long);
  15.372 +        C2P(blkif_be_connect_t, shmem_frame,  Int, Long);
  15.373 +        C2P(blkif_be_connect_t, evtchn,       Int, Long);
  15.374 +        C2P(blkif_be_connect_t, status,       Int, Long);
  15.375 +        return dict;
  15.376 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
  15.377 +        C2P(blkif_be_disconnect_t, domid,        Int, Long);
  15.378 +        C2P(blkif_be_disconnect_t, blkif_handle, Int, Long);
  15.379 +        C2P(blkif_be_disconnect_t, status,       Int, Long);
  15.380 +        return dict;
  15.381 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
  15.382 +        C2P(blkif_be_vbd_create_t, domid,        Int, Long);
  15.383 +        C2P(blkif_be_vbd_create_t, blkif_handle, Int, Long);
  15.384 +        C2P(blkif_be_vbd_create_t, vdevice,      Int, Long);
  15.385 +        C2P(blkif_be_vbd_create_t, readonly,     Int, Long);
  15.386 +        C2P(blkif_be_vbd_create_t, status,       Int, Long);
  15.387 +        return dict;
  15.388 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
  15.389 +        C2P(blkif_be_vbd_destroy_t, domid,        Int, Long);
  15.390 +        C2P(blkif_be_vbd_destroy_t, blkif_handle, Int, Long);
  15.391 +        C2P(blkif_be_vbd_destroy_t, vdevice,      Int, Long);
  15.392 +        C2P(blkif_be_vbd_destroy_t, status,       Int, Long);
  15.393 +        return dict;
  15.394 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
  15.395 +        C2P(blkif_be_vbd_grow_t, domid,         Int, Long);
  15.396 +        C2P(blkif_be_vbd_grow_t, blkif_handle,  Int, Long);
  15.397 +        C2P(blkif_be_vbd_grow_t, vdevice,       Int, Long);
  15.398 +        C2P(blkif_be_vbd_grow_t, extent.sector_start, 
  15.399 +             Long, UnsignedLongLong);
  15.400 +        C2P(blkif_be_vbd_grow_t, extent.sector_length, 
  15.401 +             Long, UnsignedLongLong);
  15.402 +        C2P(blkif_be_vbd_grow_t, extent.device, Int, Long);
  15.403 +        C2P(blkif_be_vbd_grow_t, status,        Int, Long);
  15.404 +        return dict;
  15.405 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
  15.406 +        C2P(blkif_be_vbd_shrink_t, domid,        Int, Long);
  15.407 +        C2P(blkif_be_vbd_shrink_t, blkif_handle, Int, Long);
  15.408 +        C2P(blkif_be_vbd_shrink_t, vdevice,      Int, Long);
  15.409 +        C2P(blkif_be_vbd_shrink_t, status,       Int, Long);
  15.410 +        return dict;
  15.411 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED):
  15.412 +        C2P(blkif_be_driver_status_changed_t, status, Int, Long);
  15.413 +        return dict;
  15.414 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
  15.415 +        C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
  15.416 +        C2P(netif_fe_interface_status_changed_t, status, Int, Long);
  15.417 +        C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
  15.418 +        return dict;
  15.419 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  15.420 +        C2P(netif_fe_driver_status_changed_t, status,        Int, Long);
  15.421 +        C2P(netif_fe_driver_status_changed_t, nr_interfaces, Int, Long);
  15.422 +        return dict;
  15.423 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT):
  15.424 +        C2P(netif_fe_interface_connect_t, handle,         Int, Long);
  15.425 +        C2P(netif_fe_interface_connect_t, tx_shmem_frame, Int, Long);
  15.426 +        C2P(netif_fe_interface_connect_t, rx_shmem_frame, Int, Long);
  15.427 +        return dict;
  15.428 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_DISCONNECT):
  15.429 +        C2P(netif_fe_interface_disconnect_t, handle, Int, Long);
  15.430 +        return dict;
  15.431 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
  15.432 +        C2P(netif_be_create_t, domid,        Int, Long);
  15.433 +        C2P(netif_be_create_t, netif_handle, Int, Long);
  15.434 +        C2P(netif_be_create_t, status,       Int, Long);
  15.435 +        return dict;
  15.436 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
  15.437 +        C2P(netif_be_destroy_t, domid,        Int, Long);
  15.438 +        C2P(netif_be_destroy_t, netif_handle, Int, Long);
  15.439 +        C2P(netif_be_destroy_t, status,       Int, Long);
  15.440 +        return dict;
  15.441 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
  15.442 +        C2P(netif_be_connect_t, domid,          Int, Long);
  15.443 +        C2P(netif_be_connect_t, netif_handle,   Int, Long);
  15.444 +        C2P(netif_be_connect_t, tx_shmem_frame, Int, Long);
  15.445 +        C2P(netif_be_connect_t, rx_shmem_frame, Int, Long);
  15.446 +        C2P(netif_be_connect_t, evtchn,         Int, Long);
  15.447 +        C2P(netif_be_connect_t, status,         Int, Long);
  15.448 +        return dict;
  15.449 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
  15.450 +        C2P(netif_be_disconnect_t, domid,        Int, Long);
  15.451 +        C2P(netif_be_disconnect_t, netif_handle, Int, Long);
  15.452 +        C2P(netif_be_disconnect_t, status,       Int, Long);
  15.453 +        return dict;
  15.454 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DRIVER_STATUS_CHANGED):
  15.455 +        C2P(netif_be_driver_status_changed_t, status, Int, Long);
  15.456 +        return dict;
  15.457 +    }
  15.458 +
  15.459 +    return PyString_FromStringAndSize(xum->msg.msg, xum->msg.length);
  15.460 +}
  15.461 +
  15.462 +static PyObject *xu_message_get_header(PyObject *self, PyObject *args)
  15.463 +{
  15.464 +    xu_message_object *xum = (xu_message_object *)self;
  15.465 +
  15.466 +    if ( !PyArg_ParseTuple(args, "") )
  15.467 +        return NULL;
  15.468 +
  15.469 +    return Py_BuildValue("{s:i,s:i,s:i}",
  15.470 +                         "type",    xum->msg.type,
  15.471 +                         "subtype", xum->msg.subtype,
  15.472 +                         "id",      xum->msg.id);
  15.473 +}
  15.474 +
  15.475 +static PyMethodDef xu_message_methods[] = {
  15.476 +    { "append_payload", 
  15.477 +      (PyCFunction)xu_message_append_payload,
  15.478 +      METH_VARARGS,
  15.479 +      "Append @str to the message payload.\n" },
  15.480 +
  15.481 +    { "set_response_fields",
  15.482 +      (PyCFunction)xu_message_set_response_fields,
  15.483 +      METH_VARARGS,
  15.484 +      "Fill in the response fields in a message that was passed to us.\n" },
  15.485 +
  15.486 +    { "get_payload",
  15.487 +      (PyCFunction)xu_message_get_payload,
  15.488 +      METH_VARARGS,
  15.489 +      "Return the message payload in string form.\n" },
  15.490 +
  15.491 +    { "get_header",
  15.492 +      (PyCFunction)xu_message_get_header,
  15.493 +      METH_VARARGS,
  15.494 +      "Returns a dictionary of values for @type, @subtype, and @id.\n" },
  15.495 +
  15.496 +    { NULL, NULL, 0, NULL }
  15.497 +};
  15.498 +
  15.499 +staticforward PyTypeObject xu_message_type;
  15.500 +
  15.501 +static PyObject *xu_message_new(PyObject *self, PyObject *args)
  15.502 +{
  15.503 +    xu_message_object *xum;
  15.504 +    int type, subtype, id, dict_items_parsed = 0;
  15.505 +    PyObject *payload = NULL;
  15.506 +
  15.507 +    if ( !PyArg_ParseTuple(args, "iii|O", &type, &subtype, &id, &payload) )
  15.508 +        return NULL;
  15.509 +
  15.510 +    xum = PyObject_New(xu_message_object, &xu_message_type);
  15.511 +
  15.512 +    xum->msg.type    = type;
  15.513 +    xum->msg.subtype = subtype;
  15.514 +    xum->msg.id      = id;
  15.515 +    xum->msg.length  = 0;
  15.516 +
  15.517 +    if ( payload == NULL )
  15.518 +        return (PyObject *)xum;
  15.519 +
  15.520 +    if ( !PyDict_Check(payload) )
  15.521 +    {
  15.522 +        PyErr_SetString(PyExc_TypeError, "payload is not a dictionary");
  15.523 +        PyObject_Del((PyObject *)xum);
  15.524 +        return NULL;
  15.525 +    }
  15.526 +
  15.527 +    switch ( TYPE(type, subtype) )
  15.528 +    {
  15.529 +    case TYPE(CMSG_BLKIF_FE, CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED):
  15.530 +        P2C(blkif_fe_interface_status_changed_t, handle, u32);
  15.531 +        P2C(blkif_fe_interface_status_changed_t, status, u32);
  15.532 +        P2C(blkif_fe_interface_status_changed_t, evtchn, u16);
  15.533 +        break;
  15.534 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CREATE):
  15.535 +        P2C(blkif_be_create_t, domid,        u32);
  15.536 +        P2C(blkif_be_create_t, blkif_handle, u32);
  15.537 +        break;
  15.538 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DESTROY):
  15.539 +        P2C(blkif_be_destroy_t, domid,        u32);
  15.540 +        P2C(blkif_be_destroy_t, blkif_handle, u32);
  15.541 +        break;
  15.542 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_CONNECT):
  15.543 +        P2C(blkif_be_connect_t, domid,        u32);
  15.544 +        P2C(blkif_be_connect_t, blkif_handle, u32);
  15.545 +        P2C(blkif_be_connect_t, shmem_frame,  memory_t);
  15.546 +        P2C(blkif_be_connect_t, evtchn,       u16);
  15.547 +        break;
  15.548 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DISCONNECT):
  15.549 +        P2C(blkif_be_disconnect_t, domid,        u32);
  15.550 +        P2C(blkif_be_disconnect_t, blkif_handle, u32);
  15.551 +        break;
  15.552 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
  15.553 +        P2C(blkif_be_vbd_create_t, domid,        u32);
  15.554 +        P2C(blkif_be_vbd_create_t, blkif_handle, u32);
  15.555 +        P2C(blkif_be_vbd_create_t, vdevice,      blkif_vdev_t);
  15.556 +        P2C(blkif_be_vbd_create_t, readonly,     u16);
  15.557 +        break;
  15.558 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY):
  15.559 +        P2C(blkif_be_vbd_destroy_t, domid,        u32);
  15.560 +        P2C(blkif_be_vbd_destroy_t, blkif_handle, u32);
  15.561 +        P2C(blkif_be_vbd_destroy_t, vdevice,      blkif_vdev_t);
  15.562 +        break;
  15.563 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
  15.564 +        P2C(blkif_be_vbd_grow_t, domid,                u32);
  15.565 +        P2C(blkif_be_vbd_grow_t, blkif_handle,         u32);
  15.566 +        P2C(blkif_be_vbd_grow_t, vdevice,              blkif_vdev_t);
  15.567 +        P2C(blkif_be_vbd_grow_t, extent.sector_start,  blkif_sector_t);
  15.568 +        P2C(blkif_be_vbd_grow_t, extent.sector_length, blkif_sector_t);
  15.569 +        P2C(blkif_be_vbd_grow_t, extent.device,        blkif_pdev_t);
  15.570 +        break;
  15.571 +    case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
  15.572 +        P2C(blkif_be_vbd_shrink_t, domid,        u32);
  15.573 +        P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
  15.574 +        P2C(blkif_be_vbd_shrink_t, vdevice,      blkif_vdev_t);
  15.575 +        break;
  15.576 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED):
  15.577 +        P2C(netif_fe_interface_status_changed_t, handle, u32);
  15.578 +        P2C(netif_fe_interface_status_changed_t, status, u32);
  15.579 +        P2C(netif_fe_interface_status_changed_t, evtchn, u16);
  15.580 +        P2C(netif_fe_interface_status_changed_t, mac[0], u8);
  15.581 +        P2C(netif_fe_interface_status_changed_t, mac[1], u8);
  15.582 +        P2C(netif_fe_interface_status_changed_t, mac[2], u8);
  15.583 +        P2C(netif_fe_interface_status_changed_t, mac[3], u8);
  15.584 +        P2C(netif_fe_interface_status_changed_t, mac[4], u8);
  15.585 +        P2C(netif_fe_interface_status_changed_t, mac[5], u8);
  15.586 +        break;
  15.587 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CREATE):
  15.588 +        P2C(netif_be_create_t, domid,        u32);
  15.589 +        P2C(netif_be_create_t, netif_handle, u32);
  15.590 +        P2C(netif_be_create_t, mac[0],       u8);
  15.591 +        P2C(netif_be_create_t, mac[1],       u8);
  15.592 +        P2C(netif_be_create_t, mac[2],       u8);
  15.593 +        P2C(netif_be_create_t, mac[3],       u8);
  15.594 +        P2C(netif_be_create_t, mac[4],       u8);
  15.595 +        P2C(netif_be_create_t, mac[5],       u8);
  15.596 +        break;
  15.597 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY):
  15.598 +        P2C(netif_be_destroy_t, domid,        u32);
  15.599 +        P2C(netif_be_destroy_t, netif_handle, u32);
  15.600 +        break;
  15.601 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_CONNECT):
  15.602 +        P2C(netif_be_connect_t, domid,          u32);
  15.603 +        P2C(netif_be_connect_t, netif_handle,   u32);
  15.604 +        P2C(netif_be_connect_t, tx_shmem_frame, memory_t);
  15.605 +        P2C(netif_be_connect_t, rx_shmem_frame, memory_t);
  15.606 +        P2C(netif_be_connect_t, evtchn,         u16);
  15.607 +        break;
  15.608 +    case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT):
  15.609 +        P2C(netif_be_disconnect_t, domid,        u32);
  15.610 +        P2C(netif_be_disconnect_t, netif_handle, u32);
  15.611 +        break;
  15.612 +    case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
  15.613 +        P2C(netif_fe_driver_status_changed_t, status,        u32);
  15.614 +        P2C(netif_fe_driver_status_changed_t, nr_interfaces, u32);
  15.615 +        break;
  15.616 +    }
  15.617 +
  15.618 +    if ( dict_items_parsed != PyDict_Size(payload) )
  15.619 +    {
  15.620 +        PyErr_SetString(PyExc_TypeError, "payload contains bad items");
  15.621 +        PyObject_Del((PyObject *)xum);
  15.622 +        return NULL;
  15.623 +    }
  15.624 +
  15.625 +    return (PyObject *)xum;
  15.626 +}
  15.627 +
  15.628 +static PyObject *xu_message_getattr(PyObject *obj, char *name)
  15.629 +{
  15.630 +    xu_message_object *xum;
  15.631 +    if ( strcmp(name, "MAX_PAYLOAD") == 0 )
  15.632 +        return PyInt_FromLong(sizeof(xum->msg.msg));
  15.633 +    return Py_FindMethod(xu_message_methods, obj, name);
  15.634 +}
  15.635 +
  15.636 +static void xu_message_dealloc(PyObject *self)
  15.637 +{
  15.638 +    PyObject_Del(self);
  15.639 +}
  15.640 +
  15.641 +static PyTypeObject xu_message_type = {
  15.642 +    PyObject_HEAD_INIT(&PyType_Type)
  15.643 +    0,
  15.644 +    "message",
  15.645 +    sizeof(xu_message_object),
  15.646 +    0,
  15.647 +    xu_message_dealloc,   /* tp_dealloc     */
  15.648 +    NULL,                /* tp_print       */
  15.649 +    xu_message_getattr,   /* tp_getattr     */
  15.650 +    NULL,                /* tp_setattr     */
  15.651 +    NULL,                /* tp_compare     */
  15.652 +    NULL,                /* tp_repr        */
  15.653 +    NULL,                /* tp_as_number   */
  15.654 +    NULL,                /* tp_as_sequence */
  15.655 +    NULL,                /* tp_as_mapping  */
  15.656 +    NULL                 /* tp_hash        */
  15.657 +};
  15.658 +
  15.659 +
  15.660 +
  15.661 +/*
  15.662 + * *********************** PORT ***********************
  15.663 + */
  15.664 +
  15.665 +static control_if_t *map_control_interface(int fd, unsigned long pfn)
  15.666 +{
  15.667 +    char *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
  15.668 +                       MAP_SHARED, fd, pfn * PAGE_SIZE);
  15.669 +    if ( vaddr == MAP_FAILED )
  15.670 +        return NULL;
  15.671 +    return (control_if_t *)(vaddr + 2048);
  15.672 +}
  15.673 +static void unmap_control_interface(int fd, control_if_t *c)
  15.674 +{
  15.675 +    char *vaddr = (char *)c - 2048;
  15.676 +    (void)munmap(vaddr, PAGE_SIZE);
  15.677 +}
  15.678 +
  15.679 +typedef struct xu_port_object {
  15.680 +    PyObject_HEAD;
  15.681 +    int mem_fd;
  15.682 +    int xc_handle;
  15.683 +    u32 remote_dom;
  15.684 +    int local_port, remote_port;
  15.685 +    control_if_t    *interface;
  15.686 +    CONTROL_RING_IDX tx_req_cons, tx_resp_prod;
  15.687 +    CONTROL_RING_IDX rx_req_prod, rx_resp_cons;
  15.688 +} xu_port_object;
  15.689 +
  15.690 +static PyObject *port_error;
  15.691 +
  15.692 +static int xup_connect(xu_port_object *xup, domid_t dom,
  15.693 +                       int local_port, int remote_port){
  15.694 +    // From our prespective rx = producer, tx = consumer.
  15.695 +    int err = 0;
  15.696 +    printf("%s> dom=%u %d:%d\n", __FUNCTION__, (unsigned int)dom, 
  15.697 +           local_port, remote_port);
  15.698 +
  15.699 +    // Consumer = tx.
  15.700 +    //xup->interface->tx_resp_prod = 0;
  15.701 +    //xup->interface->tx_req_prod = 0;
  15.702 +    xup->tx_resp_prod = xup->interface->tx_resp_prod;
  15.703 +    xup->tx_req_cons = xup->interface->tx_resp_prod;
  15.704 +    printf("%s> tx: %u %u : %u %u\n", __FUNCTION__,
  15.705 +           (unsigned int)xup->interface->tx_resp_prod,
  15.706 +           (unsigned int)xup->tx_resp_prod,
  15.707 +           (unsigned int)xup->tx_req_cons,
  15.708 +           (unsigned int)xup->interface->tx_req_prod);
  15.709 +
  15.710 +    // Producer = rx.
  15.711 +    //xup->interface->rx_req_prod  = 0;
  15.712 +    //xup->interface->rx_resp_prod = 0;
  15.713 +    xup->rx_req_prod  = xup->interface->rx_req_prod;
  15.714 +    xup->rx_resp_cons = xup->interface->rx_resp_prod;
  15.715 +    printf("%s> rx: %u %u : %u %u\n", __FUNCTION__,
  15.716 +           (unsigned int)xup->rx_resp_cons,
  15.717 +           (unsigned int)xup->interface->rx_resp_prod,
  15.718 +           (unsigned int)xup->interface->rx_req_prod,
  15.719 +           (unsigned int)xup->rx_req_prod);
  15.720 +
  15.721 +    xup->remote_dom   = dom;
  15.722 +    xup->local_port   = local_port;
  15.723 +    xup->remote_port  = remote_port;
  15.724 +
  15.725 +    printf("%s< err=%d\n", __FUNCTION__, err);
  15.726 +    return err;
  15.727 +}
  15.728 +
  15.729 +static PyObject *xu_port_notify(PyObject *self, PyObject *args)
  15.730 +{
  15.731 +    xu_port_object *xup = (xu_port_object *)self;
  15.732 +
  15.733 +    if ( !PyArg_ParseTuple(args, "") )
  15.734 +        return NULL;
  15.735 +
  15.736 +    (void)xc_evtchn_send(xup->xc_handle, xup->local_port);
  15.737 +
  15.738 +    Py_INCREF(Py_None);
  15.739 +    return Py_None;
  15.740 +}
  15.741 +
  15.742 +static PyObject *xu_port_read_request(PyObject *self, PyObject *args)
  15.743 +{
  15.744 +    xu_port_object    *xup = (xu_port_object *)self;
  15.745 +    xu_message_object *xum;
  15.746 +    CONTROL_RING_IDX   c = xup->tx_req_cons;
  15.747 +    control_if_t      *cif = xup->interface;
  15.748 +    control_msg_t     *cmsg;
  15.749 +
  15.750 +    if ( !PyArg_ParseTuple(args, "") )
  15.751 +        return NULL;
  15.752 +
  15.753 +    if ( (c == cif->tx_req_prod) || 
  15.754 +         ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
  15.755 +    {
  15.756 +        PyErr_SetString(port_error, "no request to read");
  15.757 +        return NULL;
  15.758 +    }
  15.759 +
  15.760 +    cmsg = &cif->tx_ring[MASK_CONTROL_IDX(c)];
  15.761 +    xum = PyObject_New(xu_message_object, &xu_message_type);
  15.762 +    memcpy(&xum->msg, cmsg, sizeof(*cmsg));
  15.763 +    if ( xum->msg.length > sizeof(xum->msg.msg) )
  15.764 +        xum->msg.length = sizeof(xum->msg.msg);
  15.765 +    xup->tx_req_cons++;
  15.766 +    return (PyObject *)xum;
  15.767 +}
  15.768 +
  15.769 +static PyObject *xu_port_write_request(PyObject *self, PyObject *args)
  15.770 +{
  15.771 +    xu_port_object    *xup = (xu_port_object *)self;
  15.772 +    xu_message_object *xum;
  15.773 +    CONTROL_RING_IDX   p = xup->rx_req_prod;
  15.774 +    control_if_t      *cif = xup->interface;
  15.775 +    control_msg_t     *cmsg;
  15.776 +
  15.777 +    if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
  15.778 +        return NULL;
  15.779 +
  15.780 +    if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
  15.781 +    {
  15.782 +        PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
  15.783 +        return NULL;        
  15.784 +    }
  15.785 +
  15.786 +    if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
  15.787 +    {
  15.788 +        PyErr_SetString(port_error, "no space to write request");
  15.789 +        return NULL;
  15.790 +    }
  15.791 +
  15.792 +    cmsg = &cif->rx_ring[MASK_CONTROL_IDX(p)];
  15.793 +    memcpy(cmsg, &xum->msg, sizeof(*cmsg));
  15.794 +
  15.795 +    xup->rx_req_prod = cif->rx_req_prod = p + 1;
  15.796 +
  15.797 +    Py_INCREF(Py_None);
  15.798 +    return Py_None;
  15.799 +}
  15.800 +
  15.801 +static PyObject *xu_port_read_response(PyObject *self, PyObject *args)
  15.802 +{
  15.803 +    xu_port_object    *xup = (xu_port_object *)self;
  15.804 +    xu_message_object *xum;
  15.805 +    CONTROL_RING_IDX   c = xup->rx_resp_cons;
  15.806 +    control_if_t      *cif = xup->interface;
  15.807 +    control_msg_t     *cmsg;
  15.808 +
  15.809 +    if ( !PyArg_ParseTuple(args, "") )
  15.810 +        return NULL;
  15.811 +
  15.812 +    if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
  15.813 +    {
  15.814 +        PyErr_SetString(port_error, "no response to read");
  15.815 +        return NULL;
  15.816 +    }
  15.817 +
  15.818 +    cmsg = &cif->rx_ring[MASK_CONTROL_IDX(c)];
  15.819 +    xum = PyObject_New(xu_message_object, &xu_message_type);
  15.820 +    memcpy(&xum->msg, cmsg, sizeof(*cmsg));
  15.821 +    if ( xum->msg.length > sizeof(xum->msg.msg) )
  15.822 +        xum->msg.length = sizeof(xum->msg.msg);
  15.823 +    xup->rx_resp_cons++;
  15.824 +    return (PyObject *)xum;
  15.825 +}
  15.826 +
  15.827 +static PyObject *xu_port_write_response(PyObject *self, PyObject *args)
  15.828 +{
  15.829 +    xu_port_object    *xup = (xu_port_object *)self;
  15.830 +    xu_message_object *xum;
  15.831 +    CONTROL_RING_IDX   p = xup->tx_resp_prod;
  15.832 +    control_if_t      *cif = xup->interface;
  15.833 +    control_msg_t     *cmsg;
  15.834 +
  15.835 +    if ( !PyArg_ParseTuple(args, "O", (PyObject **)&xum) )
  15.836 +        return NULL;
  15.837 +
  15.838 +    if ( !PyObject_TypeCheck((PyObject *)xum, &xu_message_type) )
  15.839 +    {
  15.840 +        PyErr_SetString(PyExc_TypeError, "expected a " XENPKG ".message");
  15.841 +        return NULL;        
  15.842 +    }
  15.843 +
  15.844 +    if ( p == xup->tx_req_cons )
  15.845 +    {
  15.846 +        PyErr_SetString(port_error, "no space to write response");
  15.847 +        return NULL;
  15.848 +    }
  15.849 +
  15.850 +    cmsg = &cif->tx_ring[MASK_CONTROL_IDX(p)];
  15.851 +    memcpy(cmsg, &xum->msg, sizeof(*cmsg));
  15.852 +
  15.853 +    xup->tx_resp_prod = cif->tx_resp_prod = p + 1;
  15.854 +
  15.855 +    Py_INCREF(Py_None);
  15.856 +    return Py_None;
  15.857 +}
  15.858 +
  15.859 +static PyObject *xu_port_request_to_read(PyObject *self, PyObject *args)
  15.860 +{
  15.861 +    xu_port_object    *xup = (xu_port_object *)self;
  15.862 +    CONTROL_RING_IDX   c = xup->tx_req_cons;
  15.863 +    control_if_t      *cif = xup->interface;
  15.864 +
  15.865 +    if ( !PyArg_ParseTuple(args, "") )
  15.866 +        return NULL;
  15.867 +
  15.868 +    if ( (c == cif->tx_req_prod) || 
  15.869 +         ((c - xup->tx_resp_prod) == CONTROL_RING_SIZE) )
  15.870 +        return PyInt_FromLong(0);
  15.871 +
  15.872 +    return PyInt_FromLong(1);
  15.873 +}
  15.874 +
  15.875 +static PyObject *xu_port_space_to_write_request(PyObject *self, PyObject *args)
  15.876 +{
  15.877 +    xu_port_object    *xup = (xu_port_object *)self;
  15.878 +    CONTROL_RING_IDX   p = xup->rx_req_prod;
  15.879 +
  15.880 +    if ( !PyArg_ParseTuple(args, "") )
  15.881 +        return NULL;
  15.882 +
  15.883 +    if ( ((p - xup->rx_resp_cons) == CONTROL_RING_SIZE) )
  15.884 +        return PyInt_FromLong(0);
  15.885 +
  15.886 +    return PyInt_FromLong(1);
  15.887 +}
  15.888 +
  15.889 +static PyObject *xu_port_response_to_read(PyObject *self, PyObject *args)
  15.890 +{
  15.891 +    xu_port_object    *xup = (xu_port_object *)self;
  15.892 +    CONTROL_RING_IDX   c = xup->rx_resp_cons;
  15.893 +    control_if_t      *cif = xup->interface;
  15.894 +
  15.895 +    if ( !PyArg_ParseTuple(args, "") )
  15.896 +        return NULL;
  15.897 +
  15.898 +    if ( (c == cif->rx_resp_prod) || (c == xup->rx_req_prod) )
  15.899 +        return PyInt_FromLong(0);
  15.900 +
  15.901 +    return PyInt_FromLong(1);
  15.902 +}
  15.903 +
  15.904 +static PyObject *xu_port_space_to_write_response(
  15.905 +    PyObject *self, PyObject *args)
  15.906 +{
  15.907 +    xu_port_object    *xup = (xu_port_object *)self;
  15.908 +    CONTROL_RING_IDX   p = xup->tx_resp_prod;
  15.909 +
  15.910 +    if ( !PyArg_ParseTuple(args, "") )
  15.911 +        return NULL;
  15.912 +
  15.913 +    if ( p == xup->tx_req_cons )
  15.914 +        return PyInt_FromLong(0);
  15.915 +
  15.916 +    return PyInt_FromLong(1);
  15.917 +}
  15.918 +
  15.919 +static PyMethodDef xu_port_methods[] = {
  15.920 +    { "notify",
  15.921 +      (PyCFunction)xu_port_notify,
  15.922 +      METH_VARARGS,
  15.923 +      "Send a notification to the remote end.\n" },
  15.924 +
  15.925 +    { "read_request",
  15.926 +      (PyCFunction)xu_port_read_request,
  15.927 +      METH_VARARGS,
  15.928 +      "Read a request message from the control interface.\n" },
  15.929 +
  15.930 +    { "write_request",
  15.931 +      (PyCFunction)xu_port_write_request,
  15.932 +      METH_VARARGS,
  15.933 +      "Write a request message to the control interface.\n" },
  15.934 +
  15.935 +    { "read_response",
  15.936 +      (PyCFunction)xu_port_read_response,
  15.937 +      METH_VARARGS,
  15.938 +      "Read a response message from the control interface.\n" },
  15.939 +
  15.940 +    { "write_response",
  15.941 +      (PyCFunction)xu_port_write_response,
  15.942 +      METH_VARARGS,
  15.943 +      "Write a response message to the control interface.\n" },
  15.944 +
  15.945 +    { "request_to_read",
  15.946 +      (PyCFunction)xu_port_request_to_read,
  15.947 +      METH_VARARGS,
  15.948 +      "Returns TRUE if there is a request message to read.\n" },
  15.949 +
  15.950 +    { "space_to_write_request",
  15.951 +      (PyCFunction)xu_port_space_to_write_request,
  15.952 +      METH_VARARGS,
  15.953 +      "Returns TRUE if there is space to write a request message.\n" },
  15.954 +
  15.955 +    { "response_to_read",
  15.956 +      (PyCFunction)xu_port_response_to_read,
  15.957 +      METH_VARARGS,
  15.958 +      "Returns TRUE if there is a response message to read.\n" },
  15.959 +
  15.960 +    { "space_to_write_response",
  15.961 +      (PyCFunction)xu_port_space_to_write_response,
  15.962 +      METH_VARARGS,
  15.963 +      "Returns TRUE if there is space to write a response message.\n" },
  15.964 +
  15.965 +    { NULL, NULL, 0, NULL }
  15.966 +};
  15.967 +
  15.968 +staticforward PyTypeObject xu_port_type;
  15.969 +
  15.970 +static PyObject *xu_port_new(PyObject *self, PyObject *args)
  15.971 +{
  15.972 +    xu_port_object *xup;
  15.973 +    u32 dom;
  15.974 +    int port1, port2;
  15.975 +    xc_dominfo_t info;
  15.976 +
  15.977 +    if ( !PyArg_ParseTuple(args, "i", &dom) )
  15.978 +        return NULL;
  15.979 +
  15.980 +    xup = PyObject_New(xu_port_object, &xu_port_type);
  15.981 +
  15.982 +    if ( (xup->mem_fd = open("/dev/mem", O_RDWR)) == -1 )
  15.983 +    {
  15.984 +        PyErr_SetString(port_error, "Could not open '/dev/mem'");
  15.985 +        goto fail1;
  15.986 +    }
  15.987 +
  15.988 +    /* Set the General-Purpose Subject whose page frame will be mapped. */
  15.989 +    (void)ioctl(xup->mem_fd, _IO('M', 1), (unsigned long)dom);
  15.990 +
  15.991 +    if ( (xup->xc_handle = xc_interface_open()) == -1 )
  15.992 +    {
  15.993 +        PyErr_SetString(port_error, "Could not open Xen control interface");
  15.994 +        goto fail2;
  15.995 +    }
  15.996 +
  15.997 +    if ( dom == 0 )
  15.998 +    {
  15.999 +        /*
 15.1000 +         * The control-interface event channel for DOM0 is already set up.
 15.1001 +         * We use an ioctl to discover the port at our end of the channel.
 15.1002 +         */
 15.1003 +        port1 = ioctl(xup->xc_handle, IOCTL_PRIVCMD_INITDOMAIN_EVTCHN, NULL);
 15.1004 +        port2 = -1; /* We don't need the remote end of the DOM0 link. */
 15.1005 +        if ( port1 < 0 )
 15.1006 +        {
 15.1007 +            PyErr_SetString(port_error, "Could not open channel to DOM0");
 15.1008 +            goto fail3;
 15.1009 +        }
 15.1010 +    }
 15.1011 +    else if ( xc_evtchn_bind_interdomain(xup->xc_handle, 
 15.1012 +                                         DOMID_SELF, dom, 
 15.1013 +                                         &port1, &port2) != 0 )
 15.1014 +    {
 15.1015 +        PyErr_SetString(port_error, "Could not open channel to domain");
 15.1016 +        goto fail3;
 15.1017 +    }
 15.1018 +
 15.1019 +    if ( (xc_domain_getinfo(xup->xc_handle, dom, 1, &info) != 1) ||
 15.1020 +         (info.domid != dom) )
 15.1021 +    {
 15.1022 +        PyErr_SetString(port_error, "Failed to obtain domain status");
 15.1023 +        goto fail4;
 15.1024 +    }
 15.1025 +
 15.1026 +    xup->interface = 
 15.1027 +        map_control_interface(xup->mem_fd, info.shared_info_frame);
 15.1028 +    if ( xup->interface == NULL )
 15.1029 +    {
 15.1030 +        PyErr_SetString(port_error, "Failed to map domain control interface");
 15.1031 +        goto fail4;
 15.1032 +    }
 15.1033 +
 15.1034 +    xup_connect(xup, dom, port1, port2);
 15.1035 +    return (PyObject *)xup;
 15.1036 +
 15.1037 +    
 15.1038 + fail4:
 15.1039 +    (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, port1);
 15.1040 + fail3:
 15.1041 +    (void)xc_interface_close(xup->xc_handle);
 15.1042 + fail2:
 15.1043 +    (void)close(xup->mem_fd);
 15.1044 + fail1:
 15.1045 +    PyObject_Del((PyObject *)xup);
 15.1046 +    return NULL;        
 15.1047 +}
 15.1048 +
 15.1049 +static PyObject *xu_port_getattr(PyObject *obj, char *name)
 15.1050 +{
 15.1051 +    xu_port_object *xup = (xu_port_object *)obj;
 15.1052 +    if ( strcmp(name, "local_port") == 0 )
 15.1053 +        return PyInt_FromLong(xup->local_port);
 15.1054 +    if ( strcmp(name, "remote_port") == 0 )
 15.1055 +        return PyInt_FromLong(xup->remote_port);
 15.1056 +    if ( strcmp(name, "remote_dom") == 0 )
 15.1057 +        return PyInt_FromLong(xup->remote_dom);
 15.1058 +    return Py_FindMethod(xu_port_methods, obj, name);
 15.1059 +}
 15.1060 +
 15.1061 +static void xu_port_dealloc(PyObject *self)
 15.1062 +{
 15.1063 +    xu_port_object *xup = (xu_port_object *)self;
 15.1064 +    unmap_control_interface(xup->mem_fd, xup->interface);
 15.1065 +    if ( xup->remote_dom != 0 )
 15.1066 +        (void)xc_evtchn_close(xup->xc_handle, DOMID_SELF, xup->local_port);
 15.1067 +    (void)xc_interface_close(xup->xc_handle);
 15.1068 +    (void)close(xup->mem_fd);
 15.1069 +    PyObject_Del(self);
 15.1070 +}
 15.1071 +
 15.1072 +static PyTypeObject xu_port_type = {
 15.1073 +    PyObject_HEAD_INIT(&PyType_Type)
 15.1074 +    0,
 15.1075 +    "port",
 15.1076 +    sizeof(xu_port_object),
 15.1077 +    0,
 15.1078 +    xu_port_dealloc,     /* tp_dealloc     */
 15.1079 +    NULL,                /* tp_print       */
 15.1080 +    xu_port_getattr,     /* tp_getattr     */
 15.1081 +    NULL,                /* tp_setattr     */
 15.1082 +    NULL,                /* tp_compare     */
 15.1083 +    NULL,                /* tp_repr        */
 15.1084 +    NULL,                /* tp_as_number   */
 15.1085 +    NULL,                /* tp_as_sequence */
 15.1086 +    NULL,                /* tp_as_mapping  */
 15.1087 +    NULL                 /* tp_hash        */
 15.1088 +};
 15.1089 +
 15.1090 +
 15.1091 +
 15.1092 +/*
 15.1093 + * *********************** BUFFER ***********************
 15.1094 + */
 15.1095 +
 15.1096 +#define BUFSZ 65536
 15.1097 +#define MASK_BUF_IDX(_i) ((_i)&(BUFSZ-1))
 15.1098 +typedef unsigned int BUF_IDX;
 15.1099 +
 15.1100 +typedef struct {
 15.1101 +    PyObject_HEAD;
 15.1102 +    char        *buf;
 15.1103 +    unsigned int prod, cons;
 15.1104 +} xu_buffer_object;
 15.1105 +
 15.1106 +static PyObject *__xu_buffer_peek(xu_buffer_object *xub, int max)
 15.1107 +{
 15.1108 +    PyObject *str1, *str2;
 15.1109 +    int len1, len2, c = MASK_BUF_IDX(xub->cons);
 15.1110 +
 15.1111 +    len1 = xub->prod - xub->cons;
 15.1112 +    if ( len1 > (BUFSZ - c) ) /* clip to ring wrap */
 15.1113 +        len1 = BUFSZ - c;
 15.1114 +    if ( len1 > max )         /* clip to specified maximum */
 15.1115 +        len1 = max;
 15.1116 +    if ( len1 < 0 )           /* sanity */
 15.1117 +        len1 = 0;
 15.1118 +
 15.1119 +    if ( (str1 = PyString_FromStringAndSize(&xub->buf[c], len1)) == NULL )
 15.1120 +        return NULL;
 15.1121 +
 15.1122 +    if ( (len1 < (xub->prod - xub->cons)) && (len1 < max) )
 15.1123 +    {
 15.1124 +        len2 = max - len1;
 15.1125 +        if ( len2 > MASK_BUF_IDX(xub->prod) )
 15.1126 +            len2 = MASK_BUF_IDX(xub->prod);
 15.1127 +        if ( len2 > 0 )
 15.1128 +        {
 15.1129 +            str2 = PyString_FromStringAndSize(&xub->buf[0], len2);
 15.1130 +            if ( str2 == NULL )
 15.1131 +                return NULL;
 15.1132 +            PyString_ConcatAndDel(&str1, str2);
 15.1133 +            if ( str1 == NULL )
 15.1134 +                return NULL;
 15.1135 +        }
 15.1136 +    }
 15.1137 +
 15.1138 +    return str1;
 15.1139 +}
 15.1140 +
 15.1141 +static PyObject *xu_buffer_peek(PyObject *self, PyObject *args)
 15.1142 +{
 15.1143 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1144 +    int max = 1024;
 15.1145 +
 15.1146 +    if ( !PyArg_ParseTuple(args, "|i", &max) )
 15.1147 +        return NULL;
 15.1148 +    
 15.1149 +    return __xu_buffer_peek(xub, max);
 15.1150 +}
 15.1151 +
 15.1152 +static PyObject *xu_buffer_read(PyObject *self, PyObject *args)
 15.1153 +{
 15.1154 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1155 +    PyObject *str;
 15.1156 +    int max = 1024;
 15.1157 +
 15.1158 +    if ( !PyArg_ParseTuple(args, "|i", &max) )
 15.1159 +        return NULL;
 15.1160 +
 15.1161 +    if ( (str = __xu_buffer_peek(xub, max)) != NULL )
 15.1162 +        xub->cons += PyString_Size(str);
 15.1163 +
 15.1164 +    return str;
 15.1165 +}
 15.1166 +
 15.1167 +static PyObject *xu_buffer_discard(PyObject *self, PyObject *args)
 15.1168 +{
 15.1169 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1170 +    int max, len;
 15.1171 +
 15.1172 +    if ( !PyArg_ParseTuple(args, "i", &max) )
 15.1173 +        return NULL;
 15.1174 +
 15.1175 +    len = xub->prod - xub->cons;
 15.1176 +    if ( len > max )
 15.1177 +        len = max;
 15.1178 +    if ( len < 0 )
 15.1179 +        len = 0;
 15.1180 +
 15.1181 +    xub->cons += len;
 15.1182 +
 15.1183 +    return PyInt_FromLong(len);
 15.1184 +}
 15.1185 +
 15.1186 +static PyObject *xu_buffer_write(PyObject *self, PyObject *args)
 15.1187 +{
 15.1188 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1189 +    char *str;
 15.1190 +    int len, len1, len2;
 15.1191 +
 15.1192 +    if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
 15.1193 +        return NULL;
 15.1194 +
 15.1195 +    len1 = len;
 15.1196 +    if ( len1 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
 15.1197 +        len1 = BUFSZ - MASK_BUF_IDX(xub->prod);
 15.1198 +    if ( len1 > (BUFSZ - (xub->prod - xub->cons)) )
 15.1199 +        len1 = BUFSZ - (xub->prod - xub->cons);
 15.1200 +
 15.1201 +    if ( len1 == 0 )
 15.1202 +        return PyInt_FromLong(0);
 15.1203 +
 15.1204 +    memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[0], len1);
 15.1205 +    xub->prod += len1;
 15.1206 +
 15.1207 +    if ( len1 < len )
 15.1208 +    {
 15.1209 +        len2 = len - len1;
 15.1210 +        if ( len2 > (BUFSZ - MASK_BUF_IDX(xub->prod)) )
 15.1211 +            len2 = BUFSZ - MASK_BUF_IDX(xub->prod);
 15.1212 +        if ( len2 > (BUFSZ - (xub->prod - xub->cons)) )
 15.1213 +            len2 = BUFSZ - (xub->prod - xub->cons);
 15.1214 +        if ( len2 != 0 )
 15.1215 +        {
 15.1216 +            memcpy(&xub->buf[MASK_BUF_IDX(xub->prod)], &str[len1], len2);
 15.1217 +            xub->prod += len2;
 15.1218 +            return PyInt_FromLong(len1 + len2);
 15.1219 +        }
 15.1220 +    }
 15.1221 +
 15.1222 +    return PyInt_FromLong(len1);
 15.1223 +}
 15.1224 +
 15.1225 +static PyObject *xu_buffer_empty(PyObject *self, PyObject *args)
 15.1226 +{
 15.1227 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1228 +
 15.1229 +    if ( !PyArg_ParseTuple(args, "") )
 15.1230 +        return NULL;
 15.1231 +
 15.1232 +    if ( xub->cons == xub->prod )
 15.1233 +        return PyInt_FromLong(1);
 15.1234 +
 15.1235 +    return PyInt_FromLong(0);
 15.1236 +}
 15.1237 +
 15.1238 +static PyObject *xu_buffer_full(PyObject *self, PyObject *args)
 15.1239 +{
 15.1240 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1241 +
 15.1242 +    if ( !PyArg_ParseTuple(args, "") )
 15.1243 +        return NULL;
 15.1244 +
 15.1245 +    if ( (xub->prod - xub->cons) == BUFSZ )
 15.1246 +        return PyInt_FromLong(1);
 15.1247 +
 15.1248 +    return PyInt_FromLong(0);
 15.1249 +}
 15.1250 +
 15.1251 +static PyMethodDef xu_buffer_methods[] = {
 15.1252 +    { "peek", 
 15.1253 +      (PyCFunction)xu_buffer_peek,
 15.1254 +      METH_VARARGS,
 15.1255 +      "Peek up to @max bytes from the buffer. Returns a string.\n" },
 15.1256 +
 15.1257 +    { "read", 
 15.1258 +      (PyCFunction)xu_buffer_read,
 15.1259 +      METH_VARARGS,
 15.1260 +      "Read up to @max bytes from the buffer. Returns a string.\n" },
 15.1261 +
 15.1262 +    { "discard", 
 15.1263 +      (PyCFunction)xu_buffer_discard,
 15.1264 +      METH_VARARGS,
 15.1265 +      "Discard up to @max bytes from the buffer. Returns number of bytes.\n" },
 15.1266 +
 15.1267 +    { "write", 
 15.1268 +      (PyCFunction)xu_buffer_write,
 15.1269 +      METH_VARARGS,
 15.1270 +      "Write @string into buffer. Return number of bytes written.\n" },
 15.1271 +
 15.1272 +    { "empty", 
 15.1273 +      (PyCFunction)xu_buffer_empty,
 15.1274 +      METH_VARARGS,
 15.1275 +      "Return TRUE if the buffer is empty.\n" },
 15.1276 +
 15.1277 +    { "full", 
 15.1278 +      (PyCFunction)xu_buffer_full,
 15.1279 +      METH_VARARGS,
 15.1280 +      "Return TRUE if the buffer is full.\n" },
 15.1281 +
 15.1282 +    { NULL, NULL, 0, NULL }
 15.1283 +};
 15.1284 +
 15.1285 +staticforward PyTypeObject xu_buffer_type;
 15.1286 +
 15.1287 +static PyObject *xu_buffer_new(PyObject *self, PyObject *args)
 15.1288 +{
 15.1289 +    xu_buffer_object *xub;
 15.1290 +
 15.1291 +    if ( !PyArg_ParseTuple(args, "") )
 15.1292 +        return NULL;
 15.1293 +
 15.1294 +    xub = PyObject_New(xu_buffer_object, &xu_buffer_type);
 15.1295 +
 15.1296 +    if ( (xub->buf = malloc(BUFSZ)) == NULL )
 15.1297 +    {
 15.1298 +        PyObject_Del((PyObject *)xub);
 15.1299 +        return NULL;
 15.1300 +    }
 15.1301 +
 15.1302 +    xub->prod = xub->cons = 0;
 15.1303 +
 15.1304 +    return (PyObject *)xub;
 15.1305 +}
 15.1306 +
 15.1307 +static PyObject *xu_buffer_getattr(PyObject *obj, char *name)
 15.1308 +{
 15.1309 +    return Py_FindMethod(xu_buffer_methods, obj, name);
 15.1310 +}
 15.1311 +
 15.1312 +static void xu_buffer_dealloc(PyObject *self)
 15.1313 +{
 15.1314 +    xu_buffer_object *xub = (xu_buffer_object *)self;
 15.1315 +    free(xub->buf);
 15.1316 +    PyObject_Del(self);
 15.1317 +}
 15.1318 +
 15.1319 +static PyTypeObject xu_buffer_type = {
 15.1320 +    PyObject_HEAD_INIT(&PyType_Type)
 15.1321 +    0,
 15.1322 +    "buffer",
 15.1323 +    sizeof(xu_buffer_object),
 15.1324 +    0,
 15.1325 +    xu_buffer_dealloc,   /* tp_dealloc     */
 15.1326 +    NULL,                /* tp_print       */
 15.1327 +    xu_buffer_getattr,   /* tp_getattr     */
 15.1328 +    NULL,                /* tp_setattr     */
 15.1329 +    NULL,                /* tp_compare     */
 15.1330 +    NULL,                /* tp_repr        */
 15.1331 +    NULL,                /* tp_as_number   */
 15.1332 +    NULL,                /* tp_as_sequence */
 15.1333 +    NULL,                /* tp_as_mapping  */
 15.1334 +    NULL                 /* tp_hash        */
 15.1335 +};
 15.1336 +
 15.1337 +
 15.1338 +
 15.1339 +/*
 15.1340 + * *********************** MODULE WRAPPER ***********************
 15.1341 + */
 15.1342 +
 15.1343 +static void handle_child_death(int dummy)
 15.1344 +{
 15.1345 +    while ( waitpid(-1, NULL, WNOHANG) > 0 )
 15.1346 +        continue;
 15.1347 +}
 15.1348 +
 15.1349 +static PyObject *xu_autoreap(PyObject *self, PyObject *args)
 15.1350 +{
 15.1351 +    struct sigaction sa;
 15.1352 +
 15.1353 +    if ( !PyArg_ParseTuple(args, "") )
 15.1354 +        return NULL;
 15.1355 +
 15.1356 +    memset(&sa, 0, sizeof(sa));
 15.1357 +    sa.sa_handler = handle_child_death;
 15.1358 +    sigemptyset(&sa.sa_mask);
 15.1359 +    sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
 15.1360 +    (void)sigaction(SIGCHLD, &sa, NULL);
 15.1361 +
 15.1362 +    Py_INCREF(Py_None);
 15.1363 +    return Py_None;
 15.1364 +}
 15.1365 +
 15.1366 +static PyMethodDef xu_methods[] = {
 15.1367 +    { "notifier", xu_notifier_new, METH_VARARGS, 
 15.1368 +      "Create a new notifier." },
 15.1369 +    { "message", xu_message_new, METH_VARARGS, 
 15.1370 +      "Create a new communications message." },
 15.1371 +    { "port", xu_port_new, METH_VARARGS, 
 15.1372 +      "Create a new communications port." },
 15.1373 +    { "buffer", xu_buffer_new, METH_VARARGS, 
 15.1374 +      "Create a new ring buffer." },
 15.1375 +    { "autoreap", xu_autoreap, METH_VARARGS,
 15.1376 +      "Ensure that zombie children are automatically reaped by the OS." },
 15.1377 +    { NULL, NULL, 0, NULL }
 15.1378 +};
 15.1379 +
 15.1380 +PyMODINIT_FUNC initxu(void)
 15.1381 +{
 15.1382 +    PyObject *m, *d;
 15.1383 +
 15.1384 +    m = Py_InitModule(XENPKG, xu_methods);
 15.1385 +
 15.1386 +    d = PyModule_GetDict(m);
 15.1387 +    port_error = PyErr_NewException(XENPKG ".PortError", NULL, NULL);
 15.1388 +    PyDict_SetItemString(d, "PortError", port_error);
 15.1389 +}
    16.1 --- a/tools/python/xen/xend/XendConsole.py	Tue Jun 29 21:08:51 2004 +0000
    16.2 +++ b/tools/python/xen/xend/XendConsole.py	Wed Jun 30 09:52:59 2004 +0000
    16.3 @@ -1,8 +1,8 @@
    16.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    16.5  
    16.6  import socket
    16.7 -import xen.ext.xc
    16.8 -xc = xen.ext.xc.new()
    16.9 +import xen.lowlevel.xc
   16.10 +xc = xen.lowlevel.xc.new()
   16.11  
   16.12  import sxp
   16.13  import XendRoot
    17.1 --- a/tools/python/xen/xend/XendDomain.py	Tue Jun 29 21:08:51 2004 +0000
    17.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Jun 30 09:52:59 2004 +0000
    17.3 @@ -8,7 +8,7 @@ import sys
    17.4  
    17.5  from twisted.internet import defer
    17.6  
    17.7 -import xen.ext.xc; xc = xen.ext.xc.new()
    17.8 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    17.9  
   17.10  import sxp
   17.11  import XendRoot
   17.12 @@ -36,7 +36,6 @@ class XendDomain:
   17.13          self.xconsole = XendConsole.instance()
   17.14          # Table of domain info indexed by domain id.
   17.15          self.db = XendDB.XendDB(self.dbpath)
   17.16 -        #self.domain = {}
   17.17          self.domain_db = self.db.fetchall("")
   17.18          if xroot.get_rebooted():
   17.19              print 'XendDomain> rebooted: removing all domain info'
   17.20 @@ -45,6 +44,8 @@ class XendDomain:
   17.21          self.initial_refresh()
   17.22  
   17.23      def onVirq(self, event, val):
   17.24 +        """Event handler for virq.
   17.25 +        """
   17.26          print 'XendDomain> virq', val
   17.27          self.reap()
   17.28  
   17.29 @@ -102,28 +103,12 @@ class XendDomain:
   17.30  
   17.31      def _new_domain(self, savedinfo, info):
   17.32          """Create a domain entry from saved info.
   17.33 +
   17.34 +        savedinfo saved info from the db
   17.35 +        info      domain info from xen
   17.36 +
   17.37 +        returns deferred
   17.38          """
   17.39 -##         console = None
   17.40 -##         kernel = None
   17.41 -##         id = sxp.child_value(info, 'id')
   17.42 -##         dom = int(id)
   17.43 -##         name = sxp.child_value(info, 'name')
   17.44 -##         memory = int(sxp.child_value(info, 'memory'))
   17.45 -##         consoleinfo = sxp.child(info, 'console')
   17.46 -##         if consoleinfo:
   17.47 -##             consoleid = sxp.child_value(consoleinfo, 'id')
   17.48 -##             console = self.xconsole.console_get(consoleid)
   17.49 -##         if dom and console is None:
   17.50 -##             # Try to connect a console.
   17.51 -##             console = self.xconsole.console_create(dom)
   17.52 -##         config = sxp.child(info, 'config')
   17.53 -##         if config:
   17.54 -##             image = sxp.child(info, 'image')
   17.55 -##             if image:
   17.56 -##                 image = sxp.child0(image)
   17.57 -##                 kernel = sxp.child_value(image, 'kernel')
   17.58 -##         dominfo = XendDomainInfo.XendDomainInfo(
   17.59 -##             config, dom, name, memory, kernel, console)
   17.60          config = sxp.child_value(savedinfo, 'config')
   17.61          deferred = XendDomainInfo.vm_recreate(config, info)
   17.62          def fn(dominfo):
   17.63 @@ -132,12 +117,23 @@ class XendDomain:
   17.64          return deferred
   17.65  
   17.66      def _add_domain(self, id, info, notify=1):
   17.67 +        """Add a domain entry to the tables.
   17.68 +
   17.69 +        id     domain id
   17.70 +        info   domain info object
   17.71 +        notify send a domain created event if true
   17.72 +        """
   17.73          self.domain[id] = info
   17.74          self.domain_db[id] = info.sxpr()
   17.75          self.sync_domain(id)
   17.76          if notify: eserver.inject('xend.domain.created', id)
   17.77  
   17.78      def _delete_domain(self, id, notify=1):
   17.79 +        """Remove a domain from the tables.
   17.80 +
   17.81 +        id     domain id
   17.82 +        notify send a domain died event if true
   17.83 +        """
   17.84          if id in self.domain:
   17.85              if notify: eserver.inject('xend.domain.died', id)
   17.86              del self.domain[id]
   17.87 @@ -146,14 +142,13 @@ class XendDomain:
   17.88              self.db.delete(id)
   17.89  
   17.90      def reap(self):
   17.91 -        """Go through the domains looking for ones that have crashed or stopped.
   17.92 +        """Look for domains that have crashed or stopped.
   17.93          Tidy them up.
   17.94          """
   17.95          print 'XendDomain>reap>'
   17.96          domlist = xc.domain_getinfo()
   17.97          casualties = []
   17.98          for d in domlist:
   17.99 -            #print 'dom', d
  17.100              dead = 0
  17.101              dead = dead or (d['crashed'] or d['shutdown'])
  17.102              dead = dead or (d['dying'] and
  17.103 @@ -163,9 +158,6 @@ class XendDomain:
  17.104          for d in casualties:
  17.105              id = str(d['dom'])
  17.106              print 'XendDomain>reap> died id=', id, d
  17.107 -            dominfo = self.domain.get(id)
  17.108 -            if not dominfo: continue
  17.109 -            dominfo.died()
  17.110              self.domain_destroy(id, refresh=0)
  17.111          print 'XendDomain>reap<'
  17.112  
  17.113 @@ -181,9 +173,6 @@ class XendDomain:
  17.114              doms[id] = d
  17.115              if id not in self.domain:
  17.116                  config = None
  17.117 -                #image = None
  17.118 -                #newinfo = XendDomainInfo.XendDomainInfo(
  17.119 -                #    config, d['dom'], d['name'], d['mem_kb']/1024, image=image, info=d)
  17.120                  deferred = XendDomainInfo.vm_recreate(config, d)
  17.121                  def fn(dominfo):
  17.122                      self._add_domain(dominfo.id, dominfo)
  17.123 @@ -198,6 +187,10 @@ class XendDomain:
  17.124          self.reap()
  17.125  
  17.126      def refresh_domain(self, id):
  17.127 +        """Refresh information for a single domain.
  17.128 +
  17.129 +        id domain id
  17.130 +        """
  17.131          dom = int(id)
  17.132          dominfo = xc.domain_getinfo(dom, 1)
  17.133          if dominfo == [] or dominfo[0]['dom'] != dom:
  17.134 @@ -213,17 +206,28 @@ class XendDomain:
  17.135                  d.update(dominfo[0])
  17.136  
  17.137      def domain_ls(self):
  17.138 -        # List domains.
  17.139 -        # Update info from kernel first.
  17.140 +        """Get list of domain ids.
  17.141 +
  17.142 +        return domain ids
  17.143 +        """
  17.144          self.refresh()
  17.145          return self.domain.keys()
  17.146  
  17.147      def domains(self):
  17.148 +        """Get list of domain objects.
  17.149 +
  17.150 +        return domain objects
  17.151 +        """
  17.152          self.refresh()
  17.153          return self.domain.values()
  17.154      
  17.155      def domain_create(self, config):
  17.156 -        # Create domain, log it.
  17.157 +        """Create a domain from a configuration.
  17.158 +
  17.159 +        config configuration
  17.160 +
  17.161 +        returns deferred
  17.162 +        """
  17.163          deferred = XendDomainInfo.vm_create(config)
  17.164          def fn(dominfo):
  17.165              self._add_domain(dominfo.id, dominfo)
  17.166 @@ -232,12 +236,19 @@ class XendDomain:
  17.167          return deferred
  17.168      
  17.169      def domain_get(self, id):
  17.170 +        """Get up-to-date info about a domain.
  17.171 +
  17.172 +        id domain id
  17.173 +        returns domain object (or None)
  17.174 +        """
  17.175          id = str(id)
  17.176          self.refresh_domain(id)
  17.177          return self.domain.get(id)
  17.178      
  17.179      def domain_unpause(self, id):
  17.180 -        """(Re)start domain running.
  17.181 +        """Unpause domain execution.
  17.182 +
  17.183 +        id domain id
  17.184          """
  17.185          dom = int(id)
  17.186          eserver.inject('xend.domain.unpause', id)
  17.187 @@ -245,6 +256,8 @@ class XendDomain:
  17.188      
  17.189      def domain_pause(self, id):
  17.190          """Pause domain execution.
  17.191 +
  17.192 +        id domain id
  17.193          """
  17.194          dom = int(id)
  17.195          eserver.inject('xend.domain.pause', id)
  17.196 @@ -252,6 +265,9 @@ class XendDomain:
  17.197      
  17.198      def domain_shutdown(self, id, reason='poweroff'):
  17.199          """Shutdown domain (nicely).
  17.200 +
  17.201 +        id     domain id
  17.202 +        reason shutdown type: poweroff, reboot, halt
  17.203          """
  17.204          dom = int(id)
  17.205          if dom <= 0:
  17.206 @@ -263,23 +279,37 @@ class XendDomain:
  17.207      
  17.208      def domain_destroy(self, id, refresh=1):
  17.209          """Terminate domain immediately.
  17.210 +
  17.211 +        id domain id
  17.212 +        refresh send a domain destroy event if true
  17.213          """
  17.214          dom = int(id)
  17.215          if dom <= 0:
  17.216              return 0
  17.217          eserver.inject('xend.domain.destroy', id)
  17.218 -        val = xc.domain_destroy(dom=dom)
  17.219 +        dominfo = self.domain.get(id)
  17.220 +        if dominfo:
  17.221 +            val = dominfo.destroy()
  17.222 +        else:
  17.223 +            val = xc.domain_destroy(dom=dom)
  17.224          if refresh: self.refresh()
  17.225          return val       
  17.226  
  17.227      def domain_migrate(self, id, dst):
  17.228          """Start domain migration.
  17.229 +
  17.230 +        id domain id
  17.231          """
  17.232          # Need a cancel too?
  17.233          pass
  17.234  
  17.235      def domain_save(self, id, dst, progress=0):
  17.236 -        """Save domain state to file, destroy domain.
  17.237 +        """Save domain state to file, destroy domain on success.
  17.238 +        Leave domain running on error.
  17.239 +
  17.240 +        id       domain id
  17.241 +        dst      destination file
  17.242 +        progress output progress if true
  17.243          """
  17.244          dom = int(id)
  17.245          dominfo = self.domain_get(id)
  17.246 @@ -288,79 +318,140 @@ class XendDomain:
  17.247          vmconfig = sxp.to_string(dominfo.sxpr())
  17.248          self.domain_pause(id)
  17.249          eserver.inject('xend.domain.save', id)
  17.250 -        rc = xc.linux_save(dom=dom, state_file=dst, vmconfig=vmconfig, progress=progress)
  17.251 +        try:
  17.252 +            rc = xc.linux_save(dom=dom, state_file=dst,
  17.253 +                               vmconfig=vmconfig, progress=progress)
  17.254 +        except:
  17.255 +            rc = -1
  17.256          if rc == 0:
  17.257              self.domain_destroy(id)
  17.258 +        else:
  17.259 +            self.domain_unpause(id)
  17.260          return rc
  17.261      
  17.262      def domain_restore(self, src, progress=0):
  17.263          """Restore domain from file.
  17.264 +
  17.265 +        src      source file
  17.266 +        progress output progress if true
  17.267 +
  17.268 +        returns domain object
  17.269          """
  17.270          dominfo = XendDomainInfo.vm_restore(src, progress=progress)
  17.271          self._add_domain(dominfo.id, dominfo)
  17.272          return dominfo
  17.273      
  17.274 -    #============================================================================
  17.275 -    # Backward compatibility stuff from here on.
  17.276 +    def domain_pincpu(self, dom, cpu):
  17.277 +        """Pin a domain to a cpu.
  17.278  
  17.279 -    def domain_pincpu(self, dom, cpu):
  17.280 +        dom domain
  17.281 +        cpu cpu number
  17.282 +        """
  17.283          dom = int(dom)
  17.284          return xc.domain_pincpu(dom, cpu)
  17.285  
  17.286      def domain_cpu_bvt_set(self, dom, mcuadv, warp, warpl, warpu):
  17.287 +        """Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
  17.288 +        """
  17.289          dom = int(dom)
  17.290          return xc.bvtsched_domain_set(dom=dom, mcuadv=mcuadv,
  17.291                                        warp=warp, warpl=warpl, warpu=warpu)
  17.292  
  17.293      def domain_cpu_bvt_get(self, dom):
  17.294 +        """Get BVT (Borrowed Virtual Time) scheduler parameters for a domain.
  17.295 +        """
  17.296          dom = int(dom)
  17.297          return xc.bvtsched_domain_get(dom)
  17.298      
  17.299      def domain_cpu_atropos_set(self, dom, period, slice, latency, xtratime):
  17.300 +        """Set Atropos scheduler parameters for a domain.
  17.301 +        """
  17.302          dom = int(dom)
  17.303          return xc.atropos_domain_set(dom, period, slice, latency, xtratime)
  17.304  
  17.305      def domain_cpu_atropos_get(self, dom):
  17.306 +        """Get Atropos scheduler parameters for a domain.
  17.307 +        """
  17.308          dom = int(dom)
  17.309          return xc.atropos_domain_get(dom)
  17.310  
  17.311 -    def domain_vif_ls(self, dom):
  17.312 +    def domain_devtype_ls(self, dom, type):
  17.313 +        """Get list of device indexes for a domain.
  17.314 +
  17.315 +        dom  domain
  17.316 +        type device type
  17.317 +
  17.318 +        returns device indexes
  17.319 +        """
  17.320          dominfo = self.domain_get(dom)
  17.321          if not dominfo: return None
  17.322 -        devs = dominfo.get_devices('vif')
  17.323 +        devs = dominfo.get_devices(type)
  17.324          return range(0, len(devs))
  17.325  
  17.326 +    def domain_devtype_get(self, dom, type, idx):
  17.327 +        """Get a device from a domain.
  17.328 +
  17.329 +        dom  domain
  17.330 +        type device type
  17.331 +        idx  device index
  17.332 +
  17.333 +        returns device object (or None)
  17.334 +        """
  17.335 +        dominfo = self.domain_get(dom)
  17.336 +        if not dominfo: return None
  17.337 +        return dominfo.get_device_by_index(type, idx)
  17.338 +
  17.339 +    def domain_vif_ls(self, dom):
  17.340 +        """Get list of virtual network interface (vif) indexes for a domain.
  17.341 +
  17.342 +        dom domain
  17.343 +
  17.344 +        returns vif indexes
  17.345 +        """
  17.346 +        return self.domain_devtype_ls(dom, 'vif')
  17.347 +
  17.348      def domain_vif_get(self, dom, vif):
  17.349 -        dominfo = self.domain_get(dom)
  17.350 -        if not dominfo: return None
  17.351 -        return dominfo.get_device_by_index(vif)
  17.352 +        """Get a virtual network interface (vif) from a domain.
  17.353  
  17.354 -##     def domain_vif_ip_add(self, dom, vif, ip):
  17.355 -##         dom = int(dom)
  17.356 -##         return xenctl.ip.setup_vfr_rules_for_vif(dom, vif, ip)
  17.357 +        dom domain
  17.358 +        vif vif index
  17.359 +
  17.360 +        returns vif device object (or None)
  17.361 +        """
  17.362 +        return self.domain_devtype_get(dom, 'vif', vif)
  17.363  
  17.364      def domain_vbd_ls(self, dom):
  17.365 -        dominfo = self.domain_get(dom)
  17.366 -        if not dominfo: return []
  17.367 -        devs = dominfo.get_devices('vbd')
  17.368 -        return [ sxp.child_value(v, 'dev') for v in devs ]
  17.369 +        """Get list of virtual block device (vbd) indexes for a domain.
  17.370 +
  17.371 +        dom domain
  17.372 +
  17.373 +        returns vbd indexes
  17.374 +        """
  17.375 +        return self.domain_devtype_ls(dom, 'vbd')
  17.376  
  17.377      def domain_vbd_get(self, dom, vbd):
  17.378 -        dominfo = self.domain_get(dom)
  17.379 -        if not dominfo: return None
  17.380 -        devs = dominfo.get_devices('vbd')
  17.381 -        for v in devs:
  17.382 -            if sxp.child_value(v, 'dev') == vbd:
  17.383 -                return v
  17.384 -        return None
  17.385 +        """Get a virtual block device (vbd) from a domain.
  17.386 +
  17.387 +        dom domain
  17.388 +        vbd vbd index
  17.389 +
  17.390 +        returns vbd device (or None)
  17.391 +        """
  17.392 +        return self.domain_devtype_get(dom, 'vbd', vbd)
  17.393  
  17.394      def domain_shadow_control(self, dom, op):
  17.395 +        """Shadow page control.
  17.396 +
  17.397 +        dom domain
  17.398 +        op  operation
  17.399 +        """
  17.400          dom = int(dom)
  17.401          return xc.shadow_control(dom, op)
  17.402  
  17.403 -    #============================================================================
  17.404  
  17.405  def instance():
  17.406 +    """Singleton constructor. Use this instead of the class constructor.
  17.407 +    """
  17.408      global inst
  17.409      try:
  17.410          inst
    18.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Tue Jun 29 21:08:51 2004 +0000
    18.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jun 30 09:52:59 2004 +0000
    18.3 @@ -1,4 +1,3 @@
    18.4 -#!/usr/bin/python
    18.5  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    18.6  
    18.7  """Representation of a single domain.
    18.8 @@ -16,7 +15,7 @@ import os
    18.9  
   18.10  from twisted.internet import defer
   18.11  
   18.12 -import xen.ext.xc; xc = xen.ext.xc.new()
   18.13 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
   18.14  import xen.util.ip
   18.15  
   18.16  import sxp
   18.17 @@ -333,6 +332,9 @@ def _vm_configure2(val, vm):
   18.18  class XendDomainInfo:
   18.19      """Virtual machine object."""
   18.20  
   18.21 +    STATE_OK = "ok"
   18.22 +    STATE_TERMINATED = "terminated"
   18.23 +
   18.24      def __init__(self):
   18.25          self.recreate = 0
   18.26          self.config = None
   18.27 @@ -351,7 +353,7 @@ class XendDomainInfo:
   18.28          self.blkif_backend = 0
   18.29          self.netif_backend = 0
   18.30          #todo: state: running, suspended
   18.31 -        self.state = 'running'
   18.32 +        self.state = self.STATE_OK
   18.33          #todo: set to migrate info if migrating
   18.34          self.migrate = None
   18.35  
   18.36 @@ -490,21 +492,42 @@ class XendDomainInfo:
   18.37          self.configs.append(val)
   18.38  
   18.39      def destroy(self):
   18.40 -        if self.dom <= 0:
   18.41 -            return 0
   18.42 +        """Completely destroy the vm.
   18.43 +        """
   18.44 +        self.cleanup()
   18.45 +        return self.destroy_domain()
   18.46 +
   18.47 +    def destroy_domain(self):
   18.48 +        """Destroy the vm's domain.
   18.49 +        The domain will not finally go away unless all vm
   18.50 +        devices have been released.
   18.51 +        """
   18.52 +        if self.dom is None: return 0
   18.53          return xc.domain_destroy(dom=self.dom)
   18.54  
   18.55 -    def died(self):
   18.56 -        print 'died>', self.dom
   18.57 +    def cleanup(self):
   18.58 +        """Cleanup vm resources: release devices.
   18.59 +        """
   18.60 +        print 'cleanup>', self.dom
   18.61 +        self.state = self.STATE_TERMINATED
   18.62          self.release_devices()
   18.63  
   18.64 +    def is_terminated(self):
   18.65 +        """Check if a domain has been terminated.
   18.66 +        """
   18.67 +        return self.state == self.STATE_TERMINATED
   18.68 +
   18.69      def release_devices(self):
   18.70 +        """Release all vm devices.
   18.71 +        """
   18.72          print 'release_devices>', self.dom
   18.73          self.release_vifs()
   18.74          self.release_vbds()
   18.75          self.devices = {}
   18.76  
   18.77      def release_vifs(self):
   18.78 +        """Release vm virtual network devices (vifs).
   18.79 +        """
   18.80          print 'release_vifs>', self.dom
   18.81          if self.dom is None: return
   18.82          ctrl = xend.netif_get(self.dom)
   18.83 @@ -512,6 +535,8 @@ class XendDomainInfo:
   18.84              ctrl.destroy()
   18.85  
   18.86      def release_vbds(self):
   18.87 +        """Release vm virtual block devices (vbds).
   18.88 +        """
   18.89          print 'release_vbds>', self.dom
   18.90          if self.dom is None: return
   18.91          ctrl = xend.blkif_get(self.dom)
    19.1 --- a/tools/python/xen/xend/XendNode.py	Tue Jun 29 21:08:51 2004 +0000
    19.2 +++ b/tools/python/xen/xend/XendNode.py	Wed Jun 30 09:52:59 2004 +0000
    19.3 @@ -8,12 +8,12 @@
    19.4  """
    19.5  
    19.6  import os
    19.7 -import xen.ext.xc
    19.8 +import xen.lowlevel.xc
    19.9  
   19.10  class XendNode:
   19.11  
   19.12      def __init__(self):
   19.13 -        self.xc = xen.ext.xc.new()
   19.14 +        self.xc = xen.lowlevel.xc.new()
   19.15  
   19.16      def shutdown(self):
   19.17          return 0
    20.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Tue Jun 29 21:08:51 2004 +0000
    20.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Jun 30 09:52:59 2004 +0000
    20.3 @@ -23,7 +23,7 @@ from twisted.internet import protocol
    20.4  from twisted.internet import abstract
    20.5  from twisted.internet import defer
    20.6  
    20.7 -from xen.ext import xu
    20.8 +from xen.lowlevel import xu
    20.9  
   20.10  from xen.xend import sxp
   20.11  from xen.xend import PrettyPrint
    21.1 --- a/tools/python/xen/xend/server/channel.py	Tue Jun 29 21:08:51 2004 +0000
    21.2 +++ b/tools/python/xen/xend/server/channel.py	Wed Jun 30 09:52:59 2004 +0000
    21.3 @@ -1,5 +1,5 @@
    21.4 -import xen.ext.xc; xc = xen.ext.xc.new()
    21.5 -from xen.ext import xu
    21.6 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    21.7 +from xen.lowlevel import xu
    21.8  from messages import msgTypeName
    21.9  
   21.10  VIRQ_MISDIRECT  = 0  # Catch-all interrupt for unbound VIRQs.
    22.1 --- a/tools/python/xen/xend/server/console.py	Tue Jun 29 21:08:51 2004 +0000
    22.2 +++ b/tools/python/xen/xend/server/console.py	Wed Jun 30 09:52:59 2004 +0000
    22.3 @@ -3,7 +3,7 @@ from twisted.internet import reactor
    22.4  from twisted.internet import protocol
    22.5  from twisted.protocols import telnet
    22.6  
    22.7 -from xen.ext import xu
    22.8 +from xen.lowlevel import xu
    22.9  
   22.10  from xen.xend import EventServer
   22.11  eserver = EventServer.instance()
    23.1 --- a/tools/python/xen/xend/server/messages.py	Tue Jun 29 21:08:51 2004 +0000
    23.2 +++ b/tools/python/xen/xend/server/messages.py	Wed Jun 30 09:52:59 2004 +0000
    23.3 @@ -1,6 +1,6 @@
    23.4  import struct
    23.5  
    23.6 -from xen.ext import xu
    23.7 +from xen.lowlevel import xu
    23.8  
    23.9  DEBUG = 0
   23.10