diff options
-rw-r--r-- | .hgignore | 2 | ||||
-rw-r--r-- | tools/python/Makefile | 9 | ||||
-rw-r--r-- | tools/python/genwrap.py | 282 | ||||
-rw-r--r-- | tools/python/setup.py | 19 | ||||
-rw-r--r-- | tools/python/xen/lowlevel/xl/xl.c | 615 |
5 files changed, 924 insertions, 3 deletions
@@ -211,6 +211,8 @@ ^tools/pygrub/build/.*$ ^tools/python/build/.*$ ^tools/python/xen/util/path\.py$ +^tools/python/xen/lowlevel/xl/_pyxl_types.c +^tools/python/xen/lowlevel/xl/_pyxl_types.h ^tools/remus/imqebt/imqebt$ ^tools/remus/kmod/.*(\.cmd|\.mod|\.ko|\.mod\.c|\.symvers|\.xen)$ ^tools/security/secpol_tool$ diff --git a/tools/python/Makefile b/tools/python/Makefile index 7dfc45948d..ee7e62564c 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -19,7 +19,12 @@ genpath-target = $(call buildmakevars2file,$(XENPATH)) $(eval $(genpath-target)) .PHONY: build buildpy -buildpy: genpath +buildpy: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl.idl \ + $(XEN_ROOT)/tools/libxl/libxltypes.py + PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \ + $(XEN_ROOT)/tools/libxl/libxl.idl \ + xen/lowlevel/xl/_pyxl_types.h \ + xen/lowlevel/xl/_pyxl_types.c CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py build build: buildpy refresh-pot refresh-po $(CATALOGS) @@ -85,6 +90,8 @@ test: clean: rm -f $(XENPATH) rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/auxbin.pyc + rm -f xen/lowlevel/xl/_pyxl_types.h + rm -f xen/lowlevel/xl/_pyxl_types.c rm -f $(DEPS) -include $(DEPS) diff --git a/tools/python/genwrap.py b/tools/python/genwrap.py new file mode 100644 index 0000000000..7875d46522 --- /dev/null +++ b/tools/python/genwrap.py @@ -0,0 +1,282 @@ +#!/usr/bin/python + +import sys,os + +import libxltypes + +(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING) = range(4) + +def py_type(ty): + if ty == libxltypes.bool or isinstance(ty, libxltypes.BitField) and ty.width == 1: + return TYPE_BOOL + if isinstance(ty, libxltypes.Number): + if ty.signed: + return TYPE_INT + else: + return TYPE_UINT + if ty == libxltypes.string: + return TYPE_STRING + return None + +def py_wrapstruct(ty): + l = [] + l.append('typedef struct {') + l.append(' PyObject_HEAD;') + l.append(' %s obj;'%ty.typename); + l.append('}Py_%s;'%ty.rawname) + l.append('') + return "\n".join(l) + "\n" + +def fsanitize(name): + "Sanitise a function name given a C type" + ret = '_'.join(name.split()) + return ret.replace('*', 'ptr') + +def py_decls(ty): + l = [] + l.append('_hidden Py_%s *Py%s_New(void);\n'%(ty.rawname, ty.rawname)) + l.append('_hidden int Py%s_Check(PyObject *self);\n'%ty.rawname) + for f in ty.fields: + if py_type(f.type) is not None: + continue + l.append('_hidden PyObject *attrib__%s_get(%s *%s);'%(\ + fsanitize(f.type.typename), f.type.typename, f.name)) + l.append('_hidden int attrib__%s_set(PyObject *v, %s *%s);'%(\ + fsanitize(f.type.typename), f.type.typename, f.name)) + return '\n'.join(l) + "\n" + +def py_attrib_get(ty, f): + t = py_type(f.type) + l = [] + l.append('static PyObject *py_%s_%s_get(Py_%s *self, void *priv)'%(ty.rawname, f.name, ty.rawname)) + l.append('{') + if t == TYPE_BOOL: + l.append(' return (self->obj.%s) ? Py_True : Py_False;'%f.name) + elif t == TYPE_INT: + l.append(' return genwrap__ll_get(self->obj.%s);'%f.name) + elif t == TYPE_UINT: + l.append(' return genwrap__ull_get(self->obj.%s);'%f.name) + elif t == TYPE_STRING: + l.append(' return genwrap__string_get(&self->obj.%s);'%f.name) + else: + tn = f.type.typename + l.append(' return attrib__%s_get((%s *)&self->obj.%s);'%(fsanitize(tn), tn, f.name)) + l.append('}') + return '\n'.join(l) + "\n\n" + +def py_attrib_set(ty, f): + t = py_type(f.type) + l = [] + l.append('static int py_%s_%s_set(Py_%s *self, PyObject *v, void *priv)'%(ty.rawname, f.name, ty.rawname)) + l.append('{') + if t == TYPE_BOOL: + l.append(' self->obj.%s = (NULL == v || Py_None == v || Py_False == v) ? 0 : 1;'%f.name) + l.append(' return 0;') + elif t == TYPE_UINT or t == TYPE_INT: + l.append(' %slong long tmp;'%(t == TYPE_UINT and 'unsigned ' or '')) + l.append(' int ret;') + if t == TYPE_UINT: + l.append(' ret = genwrap__ull_set(v, &tmp, (%s)~0);'%f.type.typename) + else: + l.append(' ret = genwrap__ll_set(v, &tmp, (%s)~0);'%f.type.typename) + l.append(' if ( ret >= 0 )') + l.append(' self->obj.%s = tmp;'%f.name) + l.append(' return ret;') + elif t == TYPE_STRING: + l.append(' return genwrap__string_set(v, &self->obj.%s);'%f.name) + else: + tn = f.type.typename + l.append(' return attrib__%s_set(v, (%s *)&self->obj.%s);'%(fsanitize(tn), tn, f.name)) + l.append('}') + return '\n'.join(l) + "\n\n" + +def py_object_def(ty): + l = [] + if ty.destructor_fn is not None: + dtor = ' %s(&self->obj);\n'%ty.destructor_fn + else: + dtor = '' + + funcs="""static void Py%(rawname)s_dealloc(Py_%(rawname)s *self) +{ +%(dtor)s self->ob_type->tp_free((PyObject *)self); +} + +static int Py%(rawname)s_init(Py_%(rawname)s *self, PyObject *args, PyObject *kwds) +{ + memset(&self->obj, 0, sizeof(self->obj)); + return genwrap__obj_init((PyObject *)self, args, kwds); +} + +static PyObject *Py%(rawname)s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + Py_%(rawname)s *self = (Py_%(rawname)s *)type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + memset(&self->obj, 0, sizeof(self->obj)); + return (PyObject *)self; +} + +"""%{'rawname': ty.rawname, 'dtor': dtor} + + l.append('static PyGetSetDef Py%s_getset[] = {'%ty.rawname) + for f in ty.fields: + l.append(' { .name = "%s", '%f.name) + l.append(' .get = (getter)py_%s_%s_get, '%(ty.rawname, f.name)) + l.append(' .set = (setter)py_%s_%s_set },'%(ty.rawname, f.name)) + l.append(' { .name = NULL }') + l.append('};') + struct=""" +static PyTypeObject Py%s_Type= { + PyObject_HEAD_INIT(NULL) + 0, + PKG ".%s", + sizeof(Py_%s), + 0, + (destructor)Py%s_dealloc, /* tp_dealloc */ + NULL, /* tp_print */ + NULL, /* tp_getattr */ + NULL, /* tp_setattr */ + NULL, /* tp_compare */ + NULL, /* tp_repr */ + NULL, /* tp_as_number */ + NULL, /* tp_as_sequence */ + NULL, /* tp_as_mapping */ + NULL, /* tp_hash */ + NULL, /* tp_call */ + NULL, /* tp_str */ + NULL, /* tp_getattro */ + NULL, /* tp_setattro */ + NULL, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "%s", /* tp_doc */ + NULL, /* tp_traverse */ + NULL, /* tp_clear */ + NULL, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + NULL, /* tp_iter */ + NULL, /* tp_iternext */ + NULL, /* tp_methods */ + NULL, /* tp_members */ + Py%s_getset, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + NULL, /* tp_descr_get */ + NULL, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)Py%s_init, /* tp_init */ + NULL, /* tp_alloc */ + Py%s_new, /* tp_new */ +}; + +Py_%s *Py%s_New(void) +{ + return (Py_%s *)Py%s_new(&Py%s_Type, NULL, NULL); +} + +int Py%s_Check(PyObject *self) +{ + return (self->ob_type == &Py%s_Type); +} +"""%tuple(ty.rawname for x in range(15)) + return funcs + '\n'.join(l) + "\n" + struct + +def py_initfuncs(types): + l = [] + l.append('void genwrap__init(PyObject *m)') + l.append('{') + for ty in types: + l.append(' if (PyType_Ready(&Py%s_Type) >= 0) {'%ty.rawname) + l.append(' Py_INCREF(&Py%s_Type);'%ty.rawname) + l.append(' PyModule_AddObject(m, "%s", (PyObject *)&Py%s_Type);'%(ty.rawname, ty.rawname)) + l.append(' }') + l.append('}') + return '\n'.join(l) + "\n\n" + +def tree_frob(types): + ret = types[:] + for ty in ret: + ty.fields = filter(lambda f:f.name is not None and f.type.typename is not None, ty.fields) + return ret + +if __name__ == '__main__': + if len(sys.argv) < 4: + print >>sys.stderr, "Usage: genwrap.py <idl> <decls> <defns>" + sys.exit(1) + + idl = sys.argv[1] + (_,types) = libxltypes.parse(idl) + + types = tree_frob(types) + + decls = sys.argv[2] + f = open(decls, 'w') + f.write("""#ifndef __PYXL_TYPES_H +#define __PYXL_TYPES_H + +/* + * DO NOT EDIT. + * + * This file is autogenerated by + * "%s" + */ + +#define PKG "xen.lowlevel.xl" + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define _hidden __attribute__((visibility("hidden"))) +#define _protected __attribute__((visibility("protected"))) +#else +#define _hidden +#define _protected +#endif + +/* Initialise all types */ +_hidden void genwrap__init(PyObject *m); + +/* Generic type initialiser */ +_hidden int genwrap__obj_init(PyObject *self, PyObject *args, PyObject *kwds); + +/* Auto-generated get/set functions for simple data-types */ +_hidden int genwrap__string_set(PyObject *v, char **str); +_hidden PyObject *genwrap__string_get(char **str); +_hidden PyObject *genwrap__ull_get(unsigned long long val); +_hidden int genwrap__ull_set(PyObject *v, unsigned long long *val, unsigned long long mask); +_hidden PyObject *genwrap__ll_get(long long val); +_hidden int genwrap__ll_set(PyObject *v, long long *val, long long mask); + +""" % " ".join(sys.argv)) + for ty in types: + f.write('/* Internal APU for %s wrapper */\n'%ty.typename) + f.write(py_wrapstruct(ty)) + f.write(py_decls(ty)) + f.write('\n') + f.write('#endif /* __PYXL_TYPES_H */\n') + f.close() + + defns = sys.argv[3] + f = open(defns, 'w') + f.write("""/* + * DO NOT EDIT. + * + * This file is autogenerated by + * "%s" + */ + +#include <Python.h> +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include "libxl.h" /* gah */ +#include "%s" + +""" % tuple((' '.join(sys.argv),) + (os.path.split(decls)[-1:]),)) + for ty in types: + f.write('/* Attribute get/set functions for %s */\n'%ty.typename) + for a in ty.fields: + f.write(py_attrib_get(ty,a)) + f.write(py_attrib_set(ty,a)) + f.write(py_object_def(ty)) + f.write(py_initfuncs(types)) + f.close() diff --git a/tools/python/setup.py b/tools/python/setup.py index 689188e4e6..fc8330e252 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -9,14 +9,23 @@ extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ] include_dirs = [ XEN_ROOT + "/tools/libxc", XEN_ROOT + "/tools/xenstore", XEN_ROOT + "/tools/include", + XEN_ROOT + "/tools/libxl", ] library_dirs = [ XEN_ROOT + "/tools/libxc", XEN_ROOT + "/tools/xenstore", + XEN_ROOT + "/tools/libxl", + XEN_ROOT + "/tools/blktap2/control", ] libraries = [ "xenctrl", "xenguest", "xenstore" ] +plat = os.uname()[0] +if plat == 'Linux': + uuid_libs = ["uuid"] +else: + uuid_libs = [] + xc = Extension("xc", extra_compile_args = extra_compile_args, include_dirs = include_dirs + [ "xen/lowlevel/xc" ], @@ -83,8 +92,14 @@ netlink = Extension("netlink", sources = [ "xen/lowlevel/netlink/netlink.c", "xen/lowlevel/netlink/libnetlink.c"]) -modules = [ xc, xs, ptsname, acm, flask ] -plat = os.uname()[0] +xl = Extension("xl", + extra_compile_args = extra_compile_args, + include_dirs = include_dirs + [ "xen/lowlevel/xl" ], + library_dirs = library_dirs, + libraries = libraries + ["xenlight", "blktapctl" ] + uuid_libs, + sources = [ "xen/lowlevel/xl/xl.c", "xen/lowlevel/xl/_pyxl_types.c" ]) + +modules = [ xc, xs, ptsname, acm, flask, xl ] if plat == 'SunOS': modules.extend([ scf, process ]) if plat == 'Linux': diff --git a/tools/python/xen/lowlevel/xl/xl.c b/tools/python/xen/lowlevel/xl/xl.c new file mode 100644 index 0000000000..49370822d1 --- /dev/null +++ b/tools/python/xen/lowlevel/xl/xl.c @@ -0,0 +1,615 @@ +/****************************************************************************** + * xl.c + * + * Copyright (c) 2010 Citrix Ltd. + * Author: Gianni Tedesco + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <Python.h> +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <getopt.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <arpa/inet.h> +#include <xenctrl.h> +#include <ctype.h> +#include <inttypes.h> + +#include <libxl.h> +#include <libxl_utils.h> + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* Needed for Python versions earlier than 2.3. */ +#ifndef PyMODINIT_FUNC +#define PyMODINIT_FUNC DL_EXPORT(void) +#endif + +#define CLS "ctx" + +static PyObject *xl_error_obj; + +int genwrap__obj_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *key, *value; + Py_ssize_t pos = 0; + + if ( NULL == kwds ) + return 0; + + while (PyDict_Next(kwds, &pos, &key, &value)) { + if ( PyObject_SetAttr(self, key, value) < 0 ) + return -1; + } + + return 0; +} + +int genwrap__string_set(PyObject *v, char **str) +{ + char *tmp; + if ( NULL == v ) { + free(*str); + *str = NULL; + return 0; + } + if ( !PyString_Check(v) ) { + PyErr_SetString(PyExc_TypeError, "Attribute expected string"); + return -1; + } + tmp = strdup(PyString_AsString(v)); + if ( NULL == tmp ) { + PyErr_SetString(PyExc_MemoryError, "Allocating string attribute"); + return -1; + } + free(*str); + *str = tmp; + return 0; +} + +PyObject *genwrap__string_get(char **str) +{ + if ( NULL == *str ) + return Py_None; + return PyString_FromString(*str); +} + +PyObject *genwrap__ull_get(unsigned long long val) +{ + return PyLong_FromUnsignedLongLong(val); +} + +int genwrap__ull_set(PyObject *v, unsigned long long *val, unsigned long long mask) +{ + unsigned long long tmp; + if ( NULL == v ) { + *val = 0; + return 0; + } + if ( PyLong_Check(v) ) { + tmp = PyLong_AsUnsignedLongLong(v); + }else if ( PyInt_Check(v) ) { + tmp = (unsigned long long)PyInt_AsLong(v); + }else{ + PyErr_SetString(PyExc_TypeError, "Attribute expected int or long"); + return -1; + } + if ( tmp & ~mask ) { + PyErr_SetString(PyExc_ValueError, "Integer overflow"); + return -1; + } + *val = tmp; + return 0; +} + +PyObject *genwrap__ll_get(long long val) +{ + return PyLong_FromLongLong(val); +} + +int genwrap__ll_set(PyObject *v, long long *val, long long mask) +{ + long long tmp; + if ( NULL == v ) { + *val = 0; + return 0; + } + if ( PyLong_Check(v) ) { + tmp = PyLong_AsLongLong(v); + }else{ + tmp = (long long)PyInt_AsLong(v); + } + if ( tmp & ~mask ) { + PyErr_SetString(PyExc_ValueError, "Integer overflow"); + return -1; + } + *val = tmp; + return 0; +} +static int fixed_bytearray_set(PyObject *v, uint8_t *ptr, size_t len) +{ + char *tmp; + size_t sz; + + if ( NULL == v ) { + memset(ptr, 0, len); + return 0; + } + +#ifdef PyByteArray_Check + if ( PyByteArray_Check(v) ) { + sz = PyByteArray_Size(v); + tmp = PyByteArray_AsString(v); + }else +#endif + if ( PyString_Check(v) ) { + Py_ssize_t ssz; + if ( PyString_AsStringAndSize(v, &tmp, &ssz) ) + return -1; + if ( ssz < 0 ) + tmp = NULL; + sz = ssz; + }else{ + PyErr_SetString(PyExc_TypeError, "Attribute expected bytearray or string"); + return -1; + } + + if ( NULL == tmp ) { + memset(ptr, 0, len); + return 0; + } + if ( sz != len ) { + PyErr_SetString(PyExc_ValueError, + (sz < len) ? "Buffer underflow" : "Buffer overflow"); + return -1; + } + + memcpy(ptr, tmp, sz); + return 0; +} + +static PyObject *fixed_bytearray_get(const uint8_t *ptr, size_t len) +{ +#ifdef PyByteArray_Check + return PyByteArray_FromStringAndSize((const char *)ptr, len); +#else + return PyString_FromStringAndSize((const char *)ptr, len); +#endif +} + +#include "_pyxl_types.h" + +int attrib__libxl_cpumap_set(PyObject *v, libxl_cpumap *pptr) +{ + return -1; +} + +int attrib__libxl_domain_build_state_ptr_set(PyObject *v, libxl_domain_build_state **pptr) +{ + return -1; +} + +int attrib__libxl_file_reference_set(PyObject *v, libxl_file_reference *pptr) +{ + return -1; +} + +int attrib__libxl_hwcap_set(PyObject *v, libxl_hwcap *pptr) +{ + return -1; +} + +int attrib__libxl_key_value_list_set(PyObject *v, libxl_key_value_list *pptr) +{ + return -1; +} + +int attrib__libxl_mac_set(PyObject *v, libxl_mac *pptr) +{ + return fixed_bytearray_set(v, *pptr, 6); +} + +int attrib__libxl_string_list_set(PyObject *v, libxl_string_list *pptr) +{ + return -1; +} + +int attrib__libxl_uuid_set(PyObject *v, libxl_uuid *pptr) +{ + return fixed_bytearray_set(v, libxl_uuid_bytearray(pptr), 16); +} + +int attrib__struct_in_addr_set(PyObject *v, struct in_addr *pptr) +{ + return -1; +} + +PyObject *attrib__libxl_cpumap_get(libxl_cpumap *pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_domain_build_state_ptr_get(libxl_domain_build_state **pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_file_reference_get(libxl_file_reference *pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_hwcap_get(libxl_hwcap *pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_key_value_list_get(libxl_key_value_list *pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_mac_get(libxl_mac *pptr) +{ + return fixed_bytearray_get(*pptr, 6); +} + +PyObject *attrib__libxl_string_list_get(libxl_string_list *pptr) +{ + return NULL; +} + +PyObject *attrib__libxl_uuid_get(libxl_uuid *pptr) +{ + return fixed_bytearray_get(libxl_uuid_bytearray(pptr), 16); +} + +PyObject *attrib__struct_in_addr_get(struct in_addr *pptr) +{ + return NULL; +} + +typedef struct { + PyObject_HEAD; + libxl_ctx ctx; + xentoollog_logger_stdiostream *logger; + xentoollog_level minmsglevel; +} XlObject; + +static PyObject *pyxl_list_domains(XlObject *self) +{ + libxl_dominfo *cur, *info; + PyObject *list; + int nr_dom, i; + + info = libxl_list_domain(&self->ctx, &nr_dom); + if ( NULL == info ) + return PyList_New(0); + + list = PyList_New(nr_dom); + if ( NULL == list ) + goto err_mem; + + for(i = 0, cur = info; i < nr_dom; i++, cur++) { + Py_dominfo *di; + di = Pydominfo_New(); + if ( NULL == di ) + goto err_mem; + memcpy(&di->obj, cur, sizeof(di->obj)); + PyList_SetItem(list, i, (PyObject *)di); + } + + free(info); + return list; +err_mem: + Py_DECREF(list); + PyErr_SetString(PyExc_MemoryError, "Allocating domain list"); + return NULL; +} + +static PyObject *pyxl_domid_to_name(XlObject *self, PyObject *args) +{ + char *domname; + int domid; + PyObject *ret; + + if ( !PyArg_ParseTuple(args, "i", &domid) ) + return NULL; + + domname = libxl_domid_to_name(&self->ctx, domid); + ret = PyString_FromString(domname); + free(domname); + + return ret; +} + +static PyObject *pyxl_domain_shutdown(XlObject *self, PyObject *args) +{ + int domid, req = 0; + if ( !PyArg_ParseTuple(args, "i|i", &domid, &req) ) + return NULL; + if ( libxl_domain_shutdown(&self->ctx, domid, req) ) { + PyErr_SetString(xl_error_obj, "cannot shutdown domain"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_domain_destroy(XlObject *self, PyObject *args) +{ + int domid, force = 1; + if ( !PyArg_ParseTuple(args, "i|i", &domid, &force) ) + return NULL; + if ( libxl_domain_destroy(&self->ctx, domid, force) ) { + PyErr_SetString(xl_error_obj, "cannot destroy domain"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_domain_pause(XlObject *self, PyObject *args) +{ + int domid; + if ( !PyArg_ParseTuple(args, "i", &domid) ) + return NULL; + if ( libxl_domain_pause(&self->ctx, domid) ) { + PyErr_SetString(xl_error_obj, "cannot pause domain"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_domain_unpause(XlObject *self, PyObject *args) +{ + int domid; + if ( !PyArg_ParseTuple(args, "i", &domid) ) + return NULL; + if ( libxl_domain_unpause(&self->ctx, domid) ) { + PyErr_SetString(xl_error_obj, "cannot unpause domain"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_domain_rename(XlObject *self, PyObject *args) +{ + char *old_name = NULL, *new_name; + int domid; + if ( !PyArg_ParseTuple(args, "is|s", &domid, &new_name, &old_name) ) + return NULL; + if ( libxl_domain_rename(&self->ctx, domid, old_name, new_name, 0) ) { + PyErr_SetString(xl_error_obj, "cannot rename domain"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_pci_add(XlObject *self, PyObject *args) +{ + Py_device_pci *pci; + PyObject *obj; + int domid; + if ( !PyArg_ParseTuple(args, "iO", &domid, &obj) ) + return NULL; + if ( !Pydevice_pci_Check(obj) ) { + PyErr_SetString(PyExc_TypeError, "Xxpected xl.device_pci"); + return NULL; + } + pci = (Py_device_pci *)obj; + if ( libxl_device_pci_add(&self->ctx, domid, &pci->obj) ) { + PyErr_SetString(xl_error_obj, "cannot add pci device"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_pci_del(XlObject *self, PyObject *args) +{ + Py_device_pci *pci; + PyObject *obj; + int domid; + if ( !PyArg_ParseTuple(args, "iO", &domid, &obj) ) + return NULL; + if ( !Pydevice_pci_Check(obj) ) { + PyErr_SetString(PyExc_TypeError, "Xxpected xl.device_pci"); + return NULL; + } + pci = (Py_device_pci *)obj; + if ( libxl_device_pci_remove(&self->ctx, domid, &pci->obj) ) { + PyErr_SetString(xl_error_obj, "cannot remove pci device"); + return NULL; + } + return Py_None; +} + +static PyObject *pyxl_pci_parse(XlObject *self, PyObject *args) +{ + Py_device_pci *pci; + char *str; + + if ( !PyArg_ParseTuple(args, "s", &str) ) + return NULL; + + pci = Pydevice_pci_New(); + if ( NULL == pci ) { + PyErr_SetString(PyExc_MemoryError, "Allocating domain list"); + return NULL; + } + + if ( libxl_device_pci_parse_bdf(&self->ctx, &pci->obj, str) ) { + PyErr_SetString(xl_error_obj, "cannot parse pci device spec (BDF)"); + Py_DECREF(pci); + return NULL; + } + + return (PyObject *)pci; +} + +static PyMethodDef pyxl_methods[] = { + {"list_domains", (PyCFunction)pyxl_list_domains, METH_NOARGS, + "List domains"}, + {"domid_to_name", (PyCFunction)pyxl_domid_to_name, METH_VARARGS, + "Retrieve name from domain-id"}, + {"domain_shutdown", (PyCFunction)pyxl_domain_shutdown, METH_VARARGS, + "Shutdown a domain"}, + {"domain_destroy", (PyCFunction)pyxl_domain_destroy, METH_VARARGS, + "Destroy a domain"}, + {"domain_pause", (PyCFunction)pyxl_domain_unpause, METH_VARARGS, + "Pause a domain"}, + {"domain_unpause", (PyCFunction)pyxl_domain_pause, METH_VARARGS, + "Unpause a domain"}, + {"domain_rename", (PyCFunction)pyxl_domain_rename, METH_VARARGS, + "Rename a domain"}, + {"device_pci_add", (PyCFunction)pyxl_pci_add, METH_VARARGS, + "Insert a pass-through PCI device"}, + {"device_pci_del", (PyCFunction)pyxl_pci_del, METH_VARARGS, + "Remove a pass-through PCI device"}, + {"device_pci_parse_bdf", (PyCFunction)pyxl_pci_parse, METH_VARARGS, + "Parse pass-through PCI device spec (BDF)"}, + { NULL, NULL, 0, NULL } +}; + +static PyObject *PyXl_getattr(PyObject *obj, char *name) +{ + return Py_FindMethod(pyxl_methods, obj, name); +} + +static PyObject *PyXl_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + XlObject *self = (XlObject *)type->tp_alloc(type, 0); + + if (self == NULL) + return NULL; + + memset(&self->ctx, 0, sizeof(self->ctx)); + self->logger = NULL; + self->minmsglevel = XTL_PROGRESS; + + return (PyObject *)self; +} + +static int +PyXl_init(XlObject *self, PyObject *args, PyObject *kwds) +{ + self->logger = xtl_createlogger_stdiostream(stderr, self->minmsglevel, 0); + if (!self->logger) { + PyErr_SetString(xl_error_obj, "cannot init xl logger"); + return -1; + } + + if ( libxl_ctx_init(&self->ctx, LIBXL_VERSION, + (xentoollog_logger*)self->logger) ) { + PyErr_SetString(xl_error_obj, "cannot init xl context"); + return -1; + } + + return 0; +} + +static void PyXl_dealloc(XlObject *self) +{ + libxl_ctx_free(&self->ctx); + if ( self->logger ) + xtl_logger_destroy((xentoollog_logger*)self->logger); + + self->ob_type->tp_free((PyObject *)self); +} + +static PyTypeObject PyXlType = { + PyObject_HEAD_INIT(NULL) + 0, + PKG "." CLS, + sizeof(XlObject), + 0, + (destructor)PyXl_dealloc, /* tp_dealloc */ + NULL, /* tp_print */ + PyXl_getattr, /* tp_getattr */ + NULL, /* tp_setattr */ + NULL, /* tp_compare */ + NULL, /* tp_repr */ + NULL, /* tp_as_number */ + NULL, /* tp_as_sequence */ + NULL, /* tp_as_mapping */ + NULL, /* tp_hash */ + NULL, /* tp_call */ + NULL, /* tp_str */ + NULL, /* tp_getattro */ + NULL, /* tp_setattro */ + NULL, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "libxenlight connection", /* tp_doc */ + NULL, /* tp_traverse */ + NULL, /* tp_clear */ + NULL, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + NULL, /* tp_iter */ + NULL, /* tp_iternext */ + pyxl_methods, /* tp_methods */ + NULL, /* tp_members */ + NULL, /* tp_getset */ + NULL, /* tp_base */ + NULL, /* tp_dict */ + NULL, /* tp_descr_get */ + NULL, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyXl_init, /* tp_init */ + NULL, /* tp_alloc */ + PyXl_new, /* tp_new */ +}; + +static PyMethodDef xl_methods[] = { { NULL } }; + +PyMODINIT_FUNC initxl(void) +{ + PyObject *m; + + if (PyType_Ready(&PyXlType) < 0) + return; + + m = Py_InitModule(PKG, xl_methods); + + if (m == NULL) + return; + + xl_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL); + + Py_INCREF(&PyXlType); + PyModule_AddObject(m, CLS, (PyObject *)&PyXlType); + + Py_INCREF(xl_error_obj); + PyModule_AddObject(m, "Error", xl_error_obj); + + genwrap__init(m); +} + + +/* + * Local variables: + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ |