aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore2
-rw-r--r--tools/python/Makefile9
-rw-r--r--tools/python/genwrap.py282
-rw-r--r--tools/python/setup.py19
-rw-r--r--tools/python/xen/lowlevel/xl/xl.c615
5 files changed, 924 insertions, 3 deletions
diff --git a/.hgignore b/.hgignore
index 2ab5724a29..965992d787 100644
--- a/.hgignore
+++ b/.hgignore
@@ -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:
+ */