* [PATCH 0 of 4] Domain creation for python libxl binding v2
@ 2011-01-12 14:18 Gianni Tedesco
2011-01-12 14:18 ` [PATCH 1 of 4] pyxl: Recursively scan type-tree to produce complete binding boilerplate Gianni Tedesco
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Gianni Tedesco @ 2011-01-12 14:18 UTC (permalink / raw)
To: xen-devel; +Cc: Ian Campbell, Ian Jackson
This is a repost of patches 7 through 10 from 'libxl python binding updates'.
The main change is to remove an undocumented change to libxl API regarding the
const char *features field in domain_build_info struct. These are now handled
correctly in the python binding without changing the libxl API. The patches
have also been tidied up and some parts re-based relative to each other so that
redundant changes are removed and the split is more logical.
Below is the diff between all libxl C code before and after applying this series.
Gianni
--
diff -purN libxl.1/libxl_create.c libxl.2/libxl_create.c
--- libxl.1/libxl_create.c 2011-01-12 14:08:36.651279949 +0000
+++ libxl.2/libxl_create.c 2011-01-12 14:16:34.226240348 +0000
@@ -27,39 +27,6 @@
#include "libxl_internal.h"
#include "flexarray.h"
-void libxl_domain_config_destroy(libxl_domain_config *d_config)
-{
- int i;
-
- for (i=0; i<d_config->num_disks; i++)
- libxl_device_disk_destroy(&d_config->disks[i]);
- free(d_config->disks);
-
- for (i=0; i<d_config->num_vifs; i++)
- libxl_device_nic_destroy(&d_config->vifs[i]);
- free(d_config->vifs);
-
- for (i=0; i<d_config->num_vif2s; i++)
- libxl_device_net2_destroy(&d_config->vif2s[i]);
- free(d_config->vif2s);
-
- for (i=0; i<d_config->num_pcidevs; i++)
- libxl_device_pci_destroy(&d_config->pcidevs[i]);
- free(d_config->pcidevs);
-
- for (i=0; i<d_config->num_vfbs; i++)
- libxl_device_vfb_destroy(&d_config->vfbs[i]);
- free(d_config->vfbs);
-
- for (i=0; i<d_config->num_vkbs; i++)
- libxl_device_vkb_destroy(&d_config->vkbs[i]);
- free(d_config->vkbs);
-
- libxl_domain_create_info_destroy(&d_config->c_info);
- libxl_domain_build_info_destroy(&d_config->b_info);
- libxl_device_model_info_destroy(&d_config->dm_info);
-}
-
void libxl_init_create_info(libxl_domain_create_info *c_info)
{
memset(c_info, '\0', sizeof(*c_info));
diff -purN libxl.1/libxl.h libxl.2/libxl.h
--- libxl.1/libxl.h 2011-01-12 14:08:36.651279949 +0000
+++ libxl.2/libxl.h 2011-01-12 14:16:34.226240348 +0000
@@ -205,6 +205,18 @@ typedef struct libxl__cpuid_policy libxl
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_destroy(libxl_cpuid_policy_list *cpuid_list);
+enum libxl_action_on_shutdown {
+ LIBXL_ACTION_DESTROY,
+
+ LIBXL_ACTION_RESTART,
+ LIBXL_ACTION_RESTART_RENAME,
+
+ LIBXL_ACTION_PRESERVE,
+
+ LIBXL_ACTION_COREDUMP_DESTROY,
+ LIBXL_ACTION_COREDUMP_RESTART,
+};
+
#define LIBXL_PCI_FUNC_ALL (~0U)
#include "_libxl_types.h"
@@ -241,38 +253,6 @@ enum {
#define LIBXL_VERSION 0
-enum libxl_action_on_shutdown {
- LIBXL_ACTION_DESTROY,
-
- LIBXL_ACTION_RESTART,
- LIBXL_ACTION_RESTART_RENAME,
-
- LIBXL_ACTION_PRESERVE,
-
- LIBXL_ACTION_COREDUMP_DESTROY,
- LIBXL_ACTION_COREDUMP_RESTART,
-};
-
-typedef struct {
- libxl_domain_create_info c_info;
- libxl_domain_build_info b_info;
- libxl_device_model_info dm_info;
-
- int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
-
- libxl_device_disk *disks;
- libxl_device_nic *vifs;
- libxl_device_net2 *vif2s;
- libxl_device_pci *pcidevs;
- libxl_device_vfb *vfbs;
- libxl_device_vkb *vkbs;
-
- enum libxl_action_on_shutdown on_poweroff;
- enum libxl_action_on_shutdown on_reboot;
- enum libxl_action_on_shutdown on_watchdog;
- enum libxl_action_on_shutdown on_crash;
-} libxl_domain_config;
-
/* context functions */
int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*);
int libxl_ctx_free(libxl_ctx *ctx);
@@ -286,7 +266,6 @@ void libxl_init_dm_info(libxl_device_mod
typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid);
int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
-void libxl_domain_config_destroy(libxl_domain_config *d_config);
int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
uint32_t domid, int fd);
int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
diff -purN libxl.1/_libxl_types.c libxl.2/_libxl_types.c
--- libxl.1/_libxl_types.c 2011-01-12 14:08:36.661284022 +0000
+++ libxl.2/_libxl_types.c 2011-01-12 14:16:34.226240348 +0000
@@ -159,3 +159,30 @@ void libxl_net2info_destroy(libxl_net2in
memset(p, LIBXL_DTOR_POISON, sizeof(*p));
}
+void libxl_domain_config_destroy(libxl_domain_config *p)
+{
+ int i;
+ libxl_domain_create_info_destroy(&p->c_info);
+ libxl_domain_build_info_destroy(&p->b_info);
+ libxl_device_model_info_destroy(&p->dm_info);
+ for(i = 0; i < p->num_disks; i++)
+ libxl_device_disk_destroy(&p->disks[i]);
+ free(p->disks);
+ for(i = 0; i < p->num_vifs; i++)
+ libxl_device_nic_destroy(&p->vifs[i]);
+ free(p->vifs);
+ for(i = 0; i < p->num_vif2s; i++)
+ libxl_device_net2_destroy(&p->vif2s[i]);
+ free(p->vif2s);
+ for(i = 0; i < p->num_pcidevs; i++)
+ libxl_device_pci_destroy(&p->pcidevs[i]);
+ free(p->pcidevs);
+ for(i = 0; i < p->num_vfbs; i++)
+ libxl_device_vfb_destroy(&p->vfbs[i]);
+ free(p->vfbs);
+ for(i = 0; i < p->num_vkbs; i++)
+ libxl_device_vkb_destroy(&p->vkbs[i]);
+ free(p->vkbs);
+ memset(p, LIBXL_DTOR_POISON, sizeof(*p));
+}
+
diff -purN libxl.1/_libxl_types.h libxl.2/_libxl_types.h
--- libxl.1/_libxl_types.h 2011-01-12 14:08:36.661284022 +0000
+++ libxl.2/_libxl_types.h 2011-01-12 14:16:34.226240348 +0000
@@ -453,4 +453,27 @@ typedef struct {
} libxl_net2info;
void libxl_net2info_destroy(libxl_net2info *p);
+typedef struct {
+ libxl_domain_create_info c_info;
+ libxl_domain_build_info b_info;
+ libxl_device_model_info dm_info;
+ int num_disks;
+ libxl_device_disk * disks;
+ int num_vifs;
+ libxl_device_nic * vifs;
+ int num_vif2s;
+ libxl_device_net2 * vif2s;
+ int num_pcidevs;
+ libxl_device_pci * pcidevs;
+ int num_vfbs;
+ libxl_device_vfb * vfbs;
+ int num_vkbs;
+ libxl_device_vkb * vkbs;
+ enum libxl_action_on_shutdown on_poweroff;
+ enum libxl_action_on_shutdown on_reboot;
+ enum libxl_action_on_shutdown on_watchdog;
+ enum libxl_action_on_shutdown on_crash;
+} libxl_domain_config;
+void libxl_domain_config_destroy(libxl_domain_config *p);
+
#endif /* __LIBXL_TYPES_H */
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1 of 4] pyxl: Recursively scan type-tree to produce complete binding boilerplate
2011-01-12 14:18 [PATCH 0 of 4] Domain creation for python libxl binding v2 Gianni Tedesco
@ 2011-01-12 14:18 ` Gianni Tedesco
2011-01-12 14:19 ` [PATCH 2 of 4] xl: support array types in IDL Gianni Tedesco
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Gianni Tedesco @ 2011-01-12 14:18 UTC (permalink / raw)
To: xen-devel; +Cc: Ian Campbell, Ian Jackson
tools/python/genwrap.py | 195 ++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 163 insertions(+), 32 deletions(-)
# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294841272 0
# Node ID 787e699871a3d052b0f30bee4ec1dc555c0c3540
# Parent c3e478eafabce2840a170da0fbc92458afb95386
pyxl: Recursively scan type-tree to produce complete binding boilerplate
Currently the python wrapper generator ignores non-toplevel types in the IDL.
The KeyedUnion implementation is trivial but for structures embedded in
structures the code becomes more complex. The problem is that when assigning to
a structure (a.b = x) either we:
- copy the c structure from x in to a.b which is unexpected for python
programmers since everything is by reference not by value.
- keep a reference to x which 'shadows' a.b and do the copy just before we
pass the wrapped C structure across the libxl C API boundary.
The latter approach is chosen. The tree of shadow references is maintained in
the auto-generated code and Py_foo_Unshadow() functions are also generated and
exposed for the hand-written part of the xl wrapper to use.
Finally, for anonymous types, a name mangling system is used to translate names
like x.u.hvm.acpi. To support such constructs in python we would need to export
python types for x.u.hvm such as 'xl.anonymous_hvm_0'. Instead of dealing with
this we simply flatten the type tree so that such a field is named
x.u_hvm_apic.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
diff -r c3e478eafabc -r 787e699871a3 tools/python/genwrap.py
--- a/tools/python/genwrap.py Wed Jan 12 10:53:56 2011 +0000
+++ b/tools/python/genwrap.py Wed Jan 12 14:07:52 2011 +0000
@@ -4,7 +4,7 @@ import sys,os
import libxltypes
-(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING) = range(4)
+(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING) = xrange(4)
def py_type(ty):
if ty == libxltypes.bool or isinstance(ty, libxltypes.BitField) and ty.width == 1:
@@ -18,11 +18,16 @@ def py_type(ty):
return TYPE_STRING
return None
+def shadow_fields(ty):
+ return filter(lambda x:x.shadow_type is True, ty.fields)
+
def py_wrapstruct(ty):
l = []
l.append('typedef struct {')
l.append(' PyObject_HEAD;')
l.append(' %s obj;'%ty.typename);
+ for f in shadow_fields(ty):
+ l.append(' Py_%s *%s_ref;'%(f.type.rawname, f.python_name))
l.append('}Py_%s;'%ty.rawname)
l.append('')
return "\n".join(l) + "\n"
@@ -36,33 +41,59 @@ 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)
+ if len(shadow_fields(ty)) > 0:
+ l.append('_hidden void Py%s_Unshadow(Py_%s *self);\n'%(ty.rawname, 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))
+ l.append('_hidden PyObject *attrib__%s_get(%s *val);'%(\
+ fsanitize(f.type.typename), f.type.typename))
+ l.append('_hidden int attrib__%s_set(PyObject *v, %s *val);'%(\
+ fsanitize(f.type.typename), f.type.typename))
return '\n'.join(l) + "\n"
+def union_check(f, ret, prefix = 'self->obj.'):
+ u_check = []
+ if len(f.condlist):
+ cond = '||'.join(map(lambda (expr,name):('!(' + expr + ')')%('%s%s'%(prefix,name)), f.condlist))
+ u_check.append(' if ( %s ) {'%cond)
+ u_check.append(' PyErr_SetString(PyExc_AttributeError, "Union key not selected");')
+ u_check.append(' return %s;'%ret)
+ u_check.append(' }')
+ return u_check
+
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('static PyObject *py_%s_%s_get(Py_%s *self, void *priv)'%(ty.rawname, f.python_name, ty.rawname))
l.append('{')
+
+ u_check = union_check(f, 'NULL')
+
if t == TYPE_BOOL:
l.append(' PyObject *ret;')
+ l.extend(u_check)
l.append(' ret = (self->obj.%s) ? Py_True : Py_False;'%f.name)
l.append(' Py_INCREF(ret);')
l.append(' return ret;')
elif t == TYPE_INT:
+ l.extend(u_check)
l.append(' return genwrap__ll_get(self->obj.%s);'%f.name)
elif t == TYPE_UINT:
+ l.extend(u_check)
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)
+ l.extend(u_check)
+ l.append(' return genwrap__string_get((char **)&self->obj.%s);'%f.name)
+ elif f.shadow_type is True:
+ l.append(' PyObject *ret;')
+ l.extend(u_check)
+ l.append(' ret = (self->%s_ref == NULL) ? Py_None : (PyObject *)self->%s_ref;'%(f.python_name, f.python_name))
+ l.append(' Py_INCREF(ret);')
+ l.append(' return ret;')
else:
tn = f.type.typename
+ l.extend(u_check)
l.append(' return attrib__%s_get((%s *)&self->obj.%s);'%(fsanitize(tn), tn, f.name))
l.append('}')
return '\n'.join(l) + "\n\n"
@@ -70,14 +101,17 @@ def py_attrib_get(ty, f):
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('static int py_%s_%s_set(Py_%s *self, PyObject *v, void *priv)'%(ty.rawname, f.python_name, ty.rawname))
l.append('{')
+ u_check = union_check(f, '-1')
if t == TYPE_BOOL:
+ l.extend(u_check)
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;')
+ l.extend(u_check)
if t == TYPE_UINT:
l.append(' ret = genwrap__ull_set(v, &tmp, (%s)~0);'%f.type.typename)
else:
@@ -86,47 +120,94 @@ def py_attrib_set(ty, f):
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)
+ l.extend(u_check)
+ l.append(' return genwrap__string_set(v, (char **)&self->obj.%s);'%f.name)
+ elif f.shadow_type is True:
+ l.extend(u_check)
+ l.append(' if ( !Py%s_Check(v) ) {'%f.type.rawname)
+ l.append(' PyErr_SetString(PyExc_TypeError, "Expected xl.%s");'%f.type.rawname)
+ l.append(' return -1;')
+ l.append(' }')
+ l.append(' if ( self->%s_ref ) {'%f.python_name)
+ l.append(' Py_DECREF(self->%s_ref);'%f.python_name)
+ l.append(' }')
+ l.append(' self->%s_ref = (Py_%s *)v;'%(f.python_name, f.type.rawname))
+ l.append(' Py_INCREF(self->%s_ref);'%f.python_name)
+ l.append(' return 0;')
else:
tn = f.type.typename
+ l.extend(u_check)
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 unshadow_func(ty):
+ pf = shadow_fields(ty)
+ if len(pf) == 0:
+ return ''
+ l = []
+
+ l.append('void Py%s_Unshadow(Py_%s*self)\n'%(ty.rawname, ty.rawname))
+ l.append('{')
+ for f in pf:
+ l.append(' if ( self->%s_ref ) {'%f.python_name)
+ l.append(' Py_%s *x = (Py_%s *)self->%s_ref;'%(f.type.rawname, f.type.rawname, f.python_name))
+ if len(shadow_fields(f.type)):
+ l.append(' Py%s_Unshadow(x);'%f.type.rawname)
+ l.append(' memcpy(&self->obj.%s, &x->obj, sizeof(self->obj.%s));'%(f.name, f.name))
+ l.append(' }else{')
+ l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
+ l.append(' }')
+ l.append('}')
+ l.append('')
+ return '\n'.join(l)
+
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)
+ funcs="""static int Py%s_init(Py_%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)
+static PyObject *Py%s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- Py_%(rawname)s *self = (Py_%(rawname)s *)type->tp_alloc(type, 0);
+ Py_%s *self = (Py_%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}
+"""%tuple(ty.rawname for x in range(5))
+
+ funcs += unshadow_func(ty)
+
+ l.append('static void Py%s_dealloc(Py_%s *self)'%(ty.rawname, ty.rawname))
+ l.append('{')
+ for f in ty.fields:
+ if py_type(f.type) == TYPE_STRING and f.const:
+ l.append(' free((char *)self->obj.%s);'%f.name)
+
+ for f in shadow_fields(ty):
+ l.append(' if ( self->%s_ref ) {'%f.python_name)
+ l.append(' Py_DECREF(self->%s_ref);'%f.python_name)
+ l.append(' }')
+ # prevent libxl destructor from double freeing shadowed struct
+ l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
+
+ if ty.destructor_fn is not None:
+ l.append(' %s(&self->obj);'%ty.destructor_fn)
+
+ l.append(' self->ob_type->tp_free((PyObject *)self);')
+ l.append('}')
+ l.append('')
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 = "%s", '%f.python_name)
+ l.append(' .get = (getter)py_%s_%s_get, '%(ty.rawname, f.python_name))
+ l.append(' .set = (setter)py_%s_%s_set },'%(ty.rawname, f.python_name))
l.append(' { .name = NULL }')
l.append('};')
struct="""
@@ -196,12 +277,62 @@ def py_initfuncs(types):
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)
+def dbg_tree(str, indent=0):
+ do_dbg = False
+ if not do_dbg:
+ return
+ print '%s%s'%(''.join(' ' for i in xrange(indent)), str)
+
+# We don't have a good translation for anonymous structures so we just
+# flatten them out recursively and replace '.' with '_'. For example
+# domain_build_info.u.hvm.pae becomes domain_build_info.u_hvm_pae
+def flatten_type(ty, path = None, depth = 0, condvar = []):
+ if not isinstance(ty, libxltypes.Aggregate):
+ return ty.fields
+
+ if path is None:
+ path = ''
+ else:
+ path = path + '.'
+
+ ret = []
+ for f in ty.fields:
+ f.name = path + f.name
+ f.python_name = f.name.replace('.', '_')
+ if isinstance(f.type, libxltypes.Aggregate) and \
+ f.type.typename is not None:
+ f.shadow_type = True
+ else:
+ f.shadow_type = False
+
+ if isinstance(f.type, libxltypes.KeyedUnion):
+ f.type.keyvar_name = path + f.type.keyvar_name
+
+ f.condlist = condvar[:]
+
+ if isinstance(f.type, libxltypes.Aggregate) and \
+ f.type.typename is None:
+ dbg_tree('(%s)'%(f.name), depth + 1)
+ if isinstance(ty, libxltypes.KeyedUnion):
+ condvar.append((f.keyvar_expr, ty.keyvar_name))
+ ret.extend(flatten_type(f.type, f.name, depth + 1, condvar))
+ if isinstance(ty, libxltypes.KeyedUnion):
+ condvar.pop()
+ else:
+ dbg_tree('%s - %s'%(f.name, f.python_name), depth + 1)
+ ret.append(f)
+
+
return ret
+def frob_type(type):
+ dbg_tree('[%s]'%type.typename)
+ type.fields = flatten_type(type)
+ return type
+
+def frob_types(types):
+ return map(frob_type, types)
+
if __name__ == '__main__':
if len(sys.argv) < 4:
print >>sys.stderr, "Usage: genwrap.py <idl> <decls> <defns>"
@@ -210,7 +341,7 @@ if __name__ == '__main__':
idl = sys.argv[1]
(_,types) = libxltypes.parse(idl)
- types = tree_frob(types)
+ types = frob_types(types)
decls = sys.argv[2]
f = open(decls, 'w')
@@ -250,7 +381,7 @@ _hidden int genwrap__ll_set(PyObject *v,
""" % " ".join(sys.argv))
for ty in types:
- f.write('/* Internal APU for %s wrapper */\n'%ty.typename)
+ f.write('/* Internal API for %s wrapper */\n'%ty.typename)
f.write(py_wrapstruct(ty))
f.write(py_decls(ty))
f.write('\n')
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2 of 4] xl: support array types in IDL
2011-01-12 14:18 [PATCH 0 of 4] Domain creation for python libxl binding v2 Gianni Tedesco
2011-01-12 14:18 ` [PATCH 1 of 4] pyxl: Recursively scan type-tree to produce complete binding boilerplate Gianni Tedesco
@ 2011-01-12 14:19 ` Gianni Tedesco
2011-01-12 14:19 ` [PATCH 3 of 4] xl: Implement enum " Gianni Tedesco
2011-01-12 14:19 ` [PATCH 4 of 4] pyxl: Export libxl_domain_create_new() to python binding Gianni Tedesco
3 siblings, 0 replies; 5+ messages in thread
From: Gianni Tedesco @ 2011-01-12 14:19 UTC (permalink / raw)
To: xen-devel; +Cc: Ian Campbell, Ian Jackson
tools/libxl/gentypes.py | 30 +++++++-
tools/libxl/libxltypes.py | 6 +
tools/python/genwrap.py | 147 ++++++++++++++++++++++++++++++++-----
tools/python/xen/lowlevel/xl/xl.c | 19 ++++
4 files changed, 178 insertions(+), 24 deletions(-)
# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294841273 0
# Node ID f630610c99f076ce3ceee52d888b516e70ef569a
# Parent 787e699871a3d052b0f30bee4ec1dc555c0c3540
xl: support array types in IDL
This is required to auto-generate language bindings for libxl_domain_config.
An Array() types is implemented which causes the IDL header generator to output
a pointer and a count variable for each instance. C destructor functions are
also correctly generated.
They python wrapper part of this patch builds on the 'shadow' references
introduced in the previous patch 'pyxl: Recursively scan type-tree to produce
complete binding boilerplate' This means that array fields remain as python
lists and present with the expected 'by-reference' semantics. The C array is
built during the 'unshadow' process before the wrapped structure is passed
accross the C API boundary in to libxl.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
diff -r 787e699871a3 -r f630610c99f0 tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py Wed Jan 12 14:07:52 2011 +0000
+++ b/tools/libxl/gentypes.py Wed Jan 12 14:07:53 2011 +0000
@@ -32,6 +32,16 @@ def libxl_C_instance_of(ty, instancename
else:
return libxl_C_type_of(ty) + " " + instancename
+def flatten_arrays(ty):
+ ret = []
+ for f in ty.fields:
+ if isinstance(f.type, libxltypes.Array):
+ ret.append(libxltypes.Field(libxltypes.integer, "num_%s"%f.name))
+ ret.append(libxltypes.Field(libxltypes.Reference(f.type.array_type), f.name))
+ else:
+ ret.append(f)
+ return ret
+
def libxl_C_type_define(ty, indent = ""):
s = ""
if isinstance(ty, libxltypes.Aggregate):
@@ -43,7 +53,7 @@ def libxl_C_type_define(ty, indent = "")
else:
s += "typedef %s {\n" % ty.kind
- for f in ty.fields:
+ for f in flatten_arrays(ty):
if f.comment is not None:
s += format_comment(4, f.comment)
x = libxl_C_instance_of(f.type, f.name)
@@ -59,6 +69,15 @@ def libxl_C_type_define(ty, indent = "")
raise NotImplementedError("%s" % type(ty))
return s.replace("\n", "\n%s" % indent)
+def contains_array_dtor(ty, parent = None):
+ if isinstance(ty, libxltypes.Struct) and (parent is None or ty.destructor_fn is None):
+ for f in [f for f in ty.fields if not f.const]:
+ if isinstance(f.type, libxltypes.Array) and f.type.array_type.destructor_fn:
+ return True
+ if contains_array_dtor(f.type, True):
+ return True
+ return False
+
def libxl_C_type_destroy(ty, v, reference, indent = " ", parent = None):
if reference:
deref = v + "->"
@@ -85,6 +104,13 @@ def libxl_C_type_destroy(ty, v, referenc
s += "%s(%s);\n" % (ty.destructor_fn, makeref + v)
elif isinstance(ty, libxltypes.Struct) and (parent is None or ty.destructor_fn is None):
for f in [f for f in ty.fields if not f.const]:
+ if isinstance(f.type, libxltypes.Array):
+ at = f.type.array_type
+ if at.destructor_fn:
+ s += "for(i = 0; i < %s; i++)\n"%(deref + "num_" + f.name)
+ s += "%s%s(&%s%s[i]);\n"%(indent, at.destructor_fn, deref, f.name)
+ s += "free(%s%s);\n"%(deref, f.name)
+ continue
if f.name is None: # Anonynous struct
s += libxl_C_type_destroy(f.type, deref, False, "", deref)
@@ -158,6 +184,8 @@ if __name__ == '__main__':
for ty in [t for t in types if t.destructor_fn is not None and t.autogenerate_destructor]:
f.write("void %s(%s *p)\n" % (ty.destructor_fn, ty.typename))
f.write("{\n")
+ if contains_array_dtor(ty):
+ f.write(" int i;\n")
f.write(libxl_C_type_destroy(ty, "p", True))
f.write(" memset(p, LIBXL_DTOR_POISON, sizeof(*p));\n")
f.write("}\n")
diff -r 787e699871a3 -r f630610c99f0 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Wed Jan 12 14:07:52 2011 +0000
+++ b/tools/libxl/libxltypes.py Wed Jan 12 14:07:53 2011 +0000
@@ -69,6 +69,12 @@ class Field(object):
self.comment = kwargs.setdefault('comment', None)
self.keyvar_expr = kwargs.setdefault('keyvar_expr', None)
+class Array(Type):
+ """A counted array of elements"""
+ def __init__(self, type):
+ Type.__init__(self, None)
+ self.array_type = type
+
class Aggregate(Type):
"""A type containing a collection of other types"""
def __init__(self, kind, typename, fields, **kwargs):
diff -r 787e699871a3 -r f630610c99f0 tools/python/genwrap.py
--- a/tools/python/genwrap.py Wed Jan 12 14:07:52 2011 +0000
+++ b/tools/python/genwrap.py Wed Jan 12 14:07:53 2011 +0000
@@ -4,9 +4,11 @@ import sys,os
import libxltypes
-(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING) = xrange(4)
+(TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_STRING, TYPE_LIST) = xrange(5)
def py_type(ty):
+ if isinstance(ty, libxltypes.Array):
+ return TYPE_LIST
if ty == libxltypes.bool or isinstance(ty, libxltypes.BitField) and ty.width == 1:
return TYPE_BOOL
if isinstance(ty, libxltypes.Number):
@@ -27,7 +29,10 @@ def py_wrapstruct(ty):
l.append(' PyObject_HEAD;')
l.append(' %s obj;'%ty.typename);
for f in shadow_fields(ty):
- l.append(' Py_%s *%s_ref;'%(f.type.rawname, f.python_name))
+ if isinstance(f.type, libxltypes.Array):
+ l.append(' PyObject *%s_ref;'%f.python_name)
+ else:
+ l.append(' Py_%s *%s_ref;'%(f.type.rawname, f.python_name))
l.append('}Py_%s;'%ty.rawname)
l.append('')
return "\n".join(l) + "\n"
@@ -42,7 +47,7 @@ def py_decls(ty):
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)
if len(shadow_fields(ty)) > 0:
- l.append('_hidden void Py%s_Unshadow(Py_%s *self);\n'%(ty.rawname, ty.rawname))
+ l.append('_hidden int Py%s_Unshadow(Py_%s *self);\n'%(ty.rawname, ty.rawname))
for f in ty.fields:
if py_type(f.type) is not None:
continue
@@ -62,6 +67,15 @@ def union_check(f, ret, prefix = 'self->
u_check.append(' }')
return u_check
+def num_var(fname):
+ "Determine the name of the count variable for an array with given name"
+ # Yes, it's a bit of a hacky way to do it
+ try:
+ i = fname.rindex('.')
+ except ValueError:
+ return 'num_%s'%fname
+ return fname[:i] + 'num_' + fname[i:]
+
def py_attrib_get(ty, f):
t = py_type(f.type)
l = []
@@ -124,14 +138,22 @@ def py_attrib_set(ty, f):
l.append(' return genwrap__string_set(v, (char **)&self->obj.%s);'%f.name)
elif f.shadow_type is True:
l.extend(u_check)
- l.append(' if ( !Py%s_Check(v) ) {'%f.type.rawname)
- l.append(' PyErr_SetString(PyExc_TypeError, "Expected xl.%s");'%f.type.rawname)
+ if isinstance(f.type, libxltypes.Array):
+ at = f.type.array_type
+ l.append(' if ( !genwrap__list_check(v, Py%s_Check) ) {'%at.rawname)
+ l.append(' PyErr_SetString(PyExc_TypeError, "Expected list of xl.%s");'%at.rawname)
+ else:
+ l.append(' if ( !Py%s_Check(v) ) {'%f.type.rawname)
+ l.append(' PyErr_SetString(PyExc_TypeError, "Expected xl.%s");'%f.type.rawname)
l.append(' return -1;')
l.append(' }')
l.append(' if ( self->%s_ref ) {'%f.python_name)
l.append(' Py_DECREF(self->%s_ref);'%f.python_name)
l.append(' }')
- l.append(' self->%s_ref = (Py_%s *)v;'%(f.python_name, f.type.rawname))
+ if isinstance(f.type, libxltypes.Array):
+ l.append(' self->%s_ref = v;'%f.python_name)
+ else:
+ l.append(' self->%s_ref = (Py_%s *)v;'%(f.python_name, f.type.rawname))
l.append(' Py_INCREF(self->%s_ref);'%f.python_name)
l.append(' return 0;')
else:
@@ -141,23 +163,88 @@ def py_attrib_set(ty, f):
l.append('}')
return '\n'.join(l) + "\n\n"
+def list_unshadow_func(ty):
+ if len(shadow_fields(ty)):
+ uncall = ' Py%s_Unshadow(val)\n'%ty.rawname
+ else:
+ uncall = ''
+
+ if ty.destructor_fn:
+ fcall = """
+ for(i = 0; i < *len; i++) {
+ %s((*ret) + i);
+ }
+
+"""%ty.destructor_fn
+ else:
+ fcall = ''
+
+ return """/* list of %s */
+static int %s_list_unshadow(PyObject *list, %s **ret, int *len)
+{
+ Py_ssize_t sz = 0, i;
+ %s *arr = NULL;
+
+ if ( list == Py_None || list == NULL )
+ goto out;
+
+ if ( !PyList_Check(list) ) {
+ PyErr_SetString(PyExc_TypeError, "Expected list of xl.%s");
+ return 0;
+ }
+
+ sz = PyList_Size(list);
+ if ( sz <= 0 )
+ goto out;
+
+ arr = calloc(sz, sizeof(*arr));
+ if ( NULL == arr ) {
+ PyErr_SetString(PyExc_MemoryError, "Allocating array of %s");
+ return 0;
+ }
+
+out:
+ for(i = 0; i < sz; i++) {
+ Py_%s *val;
+ val = (Py_%s *)PyList_GetItem(list, i);
+%s memcpy(arr + i, &val->obj, sizeof(val->obj));
+ }
+%s
+ free(*ret);
+ *ret = arr;
+ *len = sz;
+ return 1;
+}
+
+"""%tuple([ty.typename for x in xrange(4)] + [ty.rawname for x in xrange(4)] + [uncall, fcall])
+
def unshadow_func(ty):
pf = shadow_fields(ty)
if len(pf) == 0:
return ''
l = []
- l.append('void Py%s_Unshadow(Py_%s*self)\n'%(ty.rawname, ty.rawname))
+ l.append('int Py%s_Unshadow(Py_%s*self)\n'%(ty.rawname, ty.rawname))
l.append('{')
+ l.append(' int ret = 1;')
for f in pf:
- l.append(' if ( self->%s_ref ) {'%f.python_name)
- l.append(' Py_%s *x = (Py_%s *)self->%s_ref;'%(f.type.rawname, f.type.rawname, f.python_name))
- if len(shadow_fields(f.type)):
- l.append(' Py%s_Unshadow(x);'%f.type.rawname)
- l.append(' memcpy(&self->obj.%s, &x->obj, sizeof(self->obj.%s));'%(f.name, f.name))
- l.append(' }else{')
- l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
- l.append(' }')
+ if isinstance(f.type, libxltypes.Array):
+ at = f.type.array_type
+ l.append(' if ( !%s_list_unshadow(self->%s_ref, '%(at.typename, f.python_name))
+ l.append(' &self->obj.%s, '%f.name)
+ l.append(' &self->obj.%s) )'%num_var(f.name))
+ l.append(' ret = 0;')
+ else:
+ l.append(' if ( self->%s_ref ) {'%f.python_name)
+ l.append(' Py_%s *x = (Py_%s *)self->%s_ref;'%(f.type.rawname, f.type.rawname, f.python_name))
+ if len(shadow_fields(f.type)):
+ l.append(' if ( !Py%s_Unshadow(x) )'%f.type.rawname)
+ l.append(' ret = 0;')
+ l.append(' memcpy(&self->obj.%s, &x->obj, sizeof(self->obj.%s));'%(f.name, f.name))
+ l.append(' }else{')
+ l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
+ l.append(' }')
+ l.append(' return ret;')
l.append('}')
l.append('')
return '\n'.join(l)
@@ -183,6 +270,7 @@ static PyObject *Py%s_new(PyTypeObject *
funcs += unshadow_func(ty)
+ l.append('')
l.append('static void Py%s_dealloc(Py_%s *self)'%(ty.rawname, ty.rawname))
l.append('{')
for f in ty.fields:
@@ -193,8 +281,12 @@ static PyObject *Py%s_new(PyTypeObject *
l.append(' if ( self->%s_ref ) {'%f.python_name)
l.append(' Py_DECREF(self->%s_ref);'%f.python_name)
l.append(' }')
- # prevent libxl destructor from double freeing shadowed struct
- l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
+ if isinstance(f.type, libxltypes.Array):
+ l.append(' self->obj.%s = NULL;'%f.name)
+ l.append(' self->obj.%s = 0;'%num_var(f.name))
+ else:
+ # prevent libxl destructor from double freeing shadowed struct
+ l.append(' memset(&self->obj.%s, 0, sizeof(self->obj.%s));'%(f.name, f.name))
if ty.destructor_fn is not None:
l.append(' %s(&self->obj);'%ty.destructor_fn)
@@ -286,7 +378,7 @@ def dbg_tree(str, indent=0):
# We don't have a good translation for anonymous structures so we just
# flatten them out recursively and replace '.' with '_'. For example
# domain_build_info.u.hvm.pae becomes domain_build_info.u_hvm_pae
-def flatten_type(ty, path = None, depth = 0, condvar = []):
+def flatten_type(ty, sdict, path = None, depth = 0, condvar = []):
if not isinstance(ty, libxltypes.Aggregate):
return ty.fields
@@ -302,6 +394,9 @@ def flatten_type(ty, path = None, depth
if isinstance(f.type, libxltypes.Aggregate) and \
f.type.typename is not None:
f.shadow_type = True
+ elif isinstance(f.type, libxltypes.Array):
+ sdict[f.type.array_type] = None
+ f.shadow_type = True
else:
f.shadow_type = False
@@ -315,7 +410,7 @@ def flatten_type(ty, path = None, depth
dbg_tree('(%s)'%(f.name), depth + 1)
if isinstance(ty, libxltypes.KeyedUnion):
condvar.append((f.keyvar_expr, ty.keyvar_name))
- ret.extend(flatten_type(f.type, f.name, depth + 1, condvar))
+ ret.extend(flatten_type(f.type, sdict, f.name, depth + 1, condvar))
if isinstance(ty, libxltypes.KeyedUnion):
condvar.pop()
else:
@@ -325,13 +420,14 @@ def flatten_type(ty, path = None, depth
return ret
-def frob_type(type):
+def frob_type(type, sdict):
dbg_tree('[%s]'%type.typename)
- type.fields = flatten_type(type)
+ type.fields = flatten_type(type, sdict)
return type
def frob_types(types):
- return map(frob_type, types)
+ sdict = {}
+ return (map(lambda x:frob_type(x, sdict), types), sdict)
if __name__ == '__main__':
if len(sys.argv) < 4:
@@ -341,7 +437,7 @@ if __name__ == '__main__':
idl = sys.argv[1]
(_,types) = libxltypes.parse(idl)
- types = frob_types(types)
+ (types, sdict) = frob_types(types)
decls = sys.argv[2]
f = open(decls, 'w')
@@ -371,6 +467,9 @@ _hidden void genwrap__init(PyObject *m);
/* Generic type initialiser */
_hidden int genwrap__obj_init(PyObject *self, PyObject *args, PyObject *kwds);
+/* Generic checker for list wrapper */
+_hidden int genwrap__list_check(PyObject *list, int(*cbfn)(PyObject *obj));
+
/* 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);
@@ -406,6 +505,8 @@ _hidden int genwrap__ll_set(PyObject *v,
#include "%s"
""" % tuple((' '.join(sys.argv),) + (os.path.split(decls)[-1:]),))
+ for ty in sdict.keys():
+ f.write(list_unshadow_func(ty))
for ty in types:
f.write('/* Attribute get/set functions for %s */\n'%ty.typename)
for a in ty.fields:
diff -r 787e699871a3 -r f630610c99f0 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Wed Jan 12 14:07:52 2011 +0000
+++ b/tools/python/xen/lowlevel/xl/xl.c Wed Jan 12 14:07:53 2011 +0000
@@ -73,6 +73,25 @@ int genwrap__obj_init(PyObject *self, Py
return 0;
}
+int genwrap__list_check(PyObject *list, int(*cbfn)(PyObject *obj))
+{
+ Py_ssize_t i, len;
+
+ if ( list == Py_None )
+ return 1;
+
+ if ( !PyList_Check(list) )
+ return 0;
+
+ len = PyList_Size(list);
+ for(i = 0; i < len; i++) {
+ if ( !(*cbfn)(PyList_GetItem(list, i)) )
+ return 0;
+ }
+
+ return 1;
+}
+
int genwrap__string_set(PyObject *v, char **str)
{
char *tmp;
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3 of 4] xl: Implement enum types in IDL
2011-01-12 14:18 [PATCH 0 of 4] Domain creation for python libxl binding v2 Gianni Tedesco
2011-01-12 14:18 ` [PATCH 1 of 4] pyxl: Recursively scan type-tree to produce complete binding boilerplate Gianni Tedesco
2011-01-12 14:19 ` [PATCH 2 of 4] xl: support array types in IDL Gianni Tedesco
@ 2011-01-12 14:19 ` Gianni Tedesco
2011-01-12 14:19 ` [PATCH 4 of 4] pyxl: Export libxl_domain_create_new() to python binding Gianni Tedesco
3 siblings, 0 replies; 5+ messages in thread
From: Gianni Tedesco @ 2011-01-12 14:19 UTC (permalink / raw)
To: xen-devel; +Cc: Ian Campbell, Ian Jackson
tools/libxl/libxltypes.py | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294841273 0
# Node ID 7049135bb6b7c0ec9f1c7a4f616b3c6c0a035693
# Parent f630610c99f076ce3ceee52d888b516e70ef569a
xl: Implement enum types in IDL
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
diff -r f630610c99f0 -r 7049135bb6b7 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Wed Jan 12 14:07:53 2011 +0000
+++ b/tools/libxl/libxltypes.py Wed Jan 12 14:07:53 2011 +0000
@@ -44,6 +44,10 @@ class Number(Builtin):
self.signed = kwargs['signed']
Builtin.__init__(self, ctype, **kwargs)
+class Enum(Number):
+ def __init__(self, w, **kwargs):
+ Number.__init__(self, 'enum %s'%w, **kwargs)
+
class UInt(Number):
def __init__(self, w, **kwargs):
kwargs.setdefault('namespace', None)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4 of 4] pyxl: Export libxl_domain_create_new() to python binding
2011-01-12 14:18 [PATCH 0 of 4] Domain creation for python libxl binding v2 Gianni Tedesco
` (2 preceding siblings ...)
2011-01-12 14:19 ` [PATCH 3 of 4] xl: Implement enum " Gianni Tedesco
@ 2011-01-12 14:19 ` Gianni Tedesco
3 siblings, 0 replies; 5+ messages in thread
From: Gianni Tedesco @ 2011-01-12 14:19 UTC (permalink / raw)
To: xen-devel; +Cc: Ian Campbell, Ian Jackson
tools/libxl/libxl.h | 45 ++++++----------------
tools/libxl/libxl.idl | 16 ++++++++
tools/libxl/libxl_create.c | 33 ----------------
tools/python/xen/lowlevel/xl/xl.c | 76 +++++++++++++++++++++++++++++++++++++-
4 files changed, 102 insertions(+), 68 deletions(-)
# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294841273 0
# Node ID 7bf63de9fcdc67e5ad7579f0f2837373fdbab6e3
# Parent 7049135bb6b7c0ec9f1c7a4f616b3c6c0a035693
pyxl: Export libxl_domain_create_new() to python binding
This also moves struct libxl_domain_config to be an IDL generated type.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Wed Jan 12 14:07:53 2011 +0000
+++ b/tools/libxl/libxl.h Wed Jan 12 14:07:53 2011 +0000
@@ -205,6 +205,18 @@ typedef struct libxl__cpuid_policy libxl
typedef libxl_cpuid_policy * libxl_cpuid_policy_list;
void libxl_cpuid_destroy(libxl_cpuid_policy_list *cpuid_list);
+enum libxl_action_on_shutdown {
+ LIBXL_ACTION_DESTROY,
+
+ LIBXL_ACTION_RESTART,
+ LIBXL_ACTION_RESTART_RENAME,
+
+ LIBXL_ACTION_PRESERVE,
+
+ LIBXL_ACTION_COREDUMP_DESTROY,
+ LIBXL_ACTION_COREDUMP_RESTART,
+};
+
#define LIBXL_PCI_FUNC_ALL (~0U)
#include "_libxl_types.h"
@@ -241,38 +253,6 @@ enum {
#define LIBXL_VERSION 0
-enum libxl_action_on_shutdown {
- LIBXL_ACTION_DESTROY,
-
- LIBXL_ACTION_RESTART,
- LIBXL_ACTION_RESTART_RENAME,
-
- LIBXL_ACTION_PRESERVE,
-
- LIBXL_ACTION_COREDUMP_DESTROY,
- LIBXL_ACTION_COREDUMP_RESTART,
-};
-
-typedef struct {
- libxl_domain_create_info c_info;
- libxl_domain_build_info b_info;
- libxl_device_model_info dm_info;
-
- int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
-
- libxl_device_disk *disks;
- libxl_device_nic *vifs;
- libxl_device_net2 *vif2s;
- libxl_device_pci *pcidevs;
- libxl_device_vfb *vfbs;
- libxl_device_vkb *vkbs;
-
- enum libxl_action_on_shutdown on_poweroff;
- enum libxl_action_on_shutdown on_reboot;
- enum libxl_action_on_shutdown on_watchdog;
- enum libxl_action_on_shutdown on_crash;
-} libxl_domain_config;
-
/* context functions */
int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*);
int libxl_ctx_free(libxl_ctx *ctx);
@@ -286,7 +266,6 @@ void libxl_init_dm_info(libxl_device_mod
typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid);
int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
-void libxl_domain_config_destroy(libxl_domain_config *d_config);
int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
uint32_t domid, int fd);
int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Wed Jan 12 14:07:53 2011 +0000
+++ b/tools/libxl/libxl.idl Wed Jan 12 14:07:53 2011 +0000
@@ -328,3 +328,19 @@ libxl_net2info = Struct("net2info", [
("back_mac", libxl_mac),
("filter_mac", integer),
])
+
+libxl_domain_config = Struct("domain_config", [
+ ("c_info", libxl_domain_create_info),
+ ("b_info", libxl_domain_build_info),
+ ("dm_info", libxl_device_model_info),
+ ("disks", Array(libxl_device_disk)),
+ ("vifs", Array(libxl_device_nic)),
+ ("vif2s", Array(libxl_device_net2)),
+ ("pcidevs", Array(libxl_device_pci)),
+ ("vfbs", Array(libxl_device_vfb)),
+ ("vkbs", Array(libxl_device_vkb)),
+ ("on_poweroff", Enum("libxl_action_on_shutdown")),
+ ("on_reboot", Enum("libxl_action_on_shutdown")),
+ ("on_watchdog", Enum("libxl_action_on_shutdown")),
+ ("on_crash", Enum("libxl_action_on_shutdown")),
+ ])
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c Wed Jan 12 14:07:53 2011 +0000
+++ b/tools/libxl/libxl_create.c Wed Jan 12 14:07:53 2011 +0000
@@ -27,39 +27,6 @@
#include "libxl_internal.h"
#include "flexarray.h"
-void libxl_domain_config_destroy(libxl_domain_config *d_config)
-{
- int i;
-
- for (i=0; i<d_config->num_disks; i++)
- libxl_device_disk_destroy(&d_config->disks[i]);
- free(d_config->disks);
-
- for (i=0; i<d_config->num_vifs; i++)
- libxl_device_nic_destroy(&d_config->vifs[i]);
- free(d_config->vifs);
-
- for (i=0; i<d_config->num_vif2s; i++)
- libxl_device_net2_destroy(&d_config->vif2s[i]);
- free(d_config->vif2s);
-
- for (i=0; i<d_config->num_pcidevs; i++)
- libxl_device_pci_destroy(&d_config->pcidevs[i]);
- free(d_config->pcidevs);
-
- for (i=0; i<d_config->num_vfbs; i++)
- libxl_device_vfb_destroy(&d_config->vfbs[i]);
- free(d_config->vfbs);
-
- for (i=0; i<d_config->num_vkbs; i++)
- libxl_device_vkb_destroy(&d_config->vkbs[i]);
- free(d_config->vkbs);
-
- libxl_domain_create_info_destroy(&d_config->c_info);
- libxl_domain_build_info_destroy(&d_config->b_info);
- libxl_device_model_info_destroy(&d_config->dm_info);
-}
-
void libxl_init_create_info(libxl_domain_create_info *c_info)
{
memset(c_info, '\0', sizeof(*c_info));
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Wed Jan 12 14:07:53 2011 +0000
+++ b/tools/python/xen/lowlevel/xl/xl.c Wed Jan 12 14:07:53 2011 +0000
@@ -443,6 +443,68 @@ static PyObject *pyxl_domid_to_name(XlOb
return ret;
}
+struct cb_priv {
+ PyObject *xl_ctx, *cb, *cb_priv;
+};
+
+static int console_ready(libxl_ctx *ctx, uint32_t domid, void *priv)
+{
+ struct cb_priv *p = priv;
+ PyObject *d;
+
+ /* no callback provided, succeed */
+ if ( p->cb == Py_None )
+ return 0;
+
+ d = PyInt_FromLong(domid);
+ if ( d == NULL )
+ return -1;
+
+ if ( PyObject_CallFunctionObjArgs(p->cb, p->xl_ctx, d, p->cb_priv, NULL) ) {
+ Py_DECREF(d);
+ return 0;
+ }
+
+ Py_DECREF(d);
+ return -1;
+}
+
+static PyObject *pyxl_domain_create(XlObject *self, PyObject *args)
+{
+ PyObject *console_cb, *cb_priv, *rfile = NULL;
+ Py_domain_config *d_config;
+ struct cb_priv priv;
+ uint32_t domid;
+
+ if ( !PyArg_ParseTuple(args, "OOO|O", &d_config, &console_cb, &cb_priv, &rfile) )
+ return NULL;
+
+ if ( !Pydomain_config_Check((PyObject *)d_config) ) {
+ PyErr_SetString(PyExc_TypeError, "Expected xl.domain_config");
+ return NULL;
+ }
+
+ if ( console_cb != Py_None && !PyCallable_Check(console_cb) ) {
+ PyErr_SetString(PyExc_TypeError, "Expected callable console callback");
+ return NULL;
+ }
+
+ if ( !Pydomain_config_Unshadow(d_config) )
+ return NULL;
+
+ priv.xl_ctx = (PyObject *)self;
+ priv.cb = console_cb;
+ priv.cb_priv = cb_priv;
+
+ if ( libxl_domain_create_new(&self->ctx, &d_config->obj,
+ console_ready, &priv, &domid) ) {
+ PyErr_SetString(xl_error_obj, "Error creating domain");
+ return NULL;
+ }
+
+ return PyInt_FromLong(domid);
+}
+
static PyObject *pyxl_domain_shutdown(XlObject *self, PyObject *args)
{
int domid, req = 0;
@@ -517,7 +579,7 @@ static PyObject *pyxl_pci_add(XlObject *
if ( !PyArg_ParseTuple(args, "iO", &domid, &obj) )
return NULL;
if ( !Pydevice_pci_Check(obj) ) {
- PyErr_SetString(PyExc_TypeError, "Xxpected xl.device_pci");
+ PyErr_SetString(PyExc_TypeError, "Expected xl.device_pci");
return NULL;
}
pci = (Py_device_pci *)obj;
@@ -538,7 +600,7 @@ static PyObject *pyxl_pci_del(XlObject *
if ( !PyArg_ParseTuple(args, "iO|i", &domid, &obj, &force) )
return NULL;
if ( !Pydevice_pci_Check(obj) ) {
- PyErr_SetString(PyExc_TypeError, "Xxpected xl.device_pci");
+ PyErr_SetString(PyExc_TypeError, "Expected xl.device_pci");
return NULL;
}
pci = (Py_device_pci *)obj;
@@ -649,6 +711,8 @@ static PyMethodDef pyxl_methods[] = {
"Retrieve name from domain-id"},
{"domain_shutdown", (PyCFunction)pyxl_domain_shutdown, METH_VARARGS,
"Shutdown a domain"},
+ {"domain_create", (PyCFunction)pyxl_domain_create, METH_VARARGS,
+ "Create or restore a domain"},
{"domain_destroy", (PyCFunction)pyxl_domain_destroy, METH_VARARGS,
"Destroy a domain"},
{"domain_pause", (PyCFunction)pyxl_domain_pause, METH_VARARGS,
@@ -813,6 +877,14 @@ PyMODINIT_FUNC initxl(void)
_INT_CONST(m, POWER_BUTTON);
_INT_CONST(m, SLEEP_BUTTON);
+
+ _INT_CONST_LIBXL(m, ACTION_DESTROY);
+ _INT_CONST_LIBXL(m, ACTION_RESTART);
+ _INT_CONST_LIBXL(m, ACTION_RESTART_RENAME);
+ _INT_CONST_LIBXL(m, ACTION_PRESERVE);
+ _INT_CONST_LIBXL(m, ACTION_COREDUMP_DESTROY);
+ _INT_CONST_LIBXL(m, ACTION_COREDUMP_RESTART);
+
genwrap__init(m);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-01-12 14:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-12 14:18 [PATCH 0 of 4] Domain creation for python libxl binding v2 Gianni Tedesco
2011-01-12 14:18 ` [PATCH 1 of 4] pyxl: Recursively scan type-tree to produce complete binding boilerplate Gianni Tedesco
2011-01-12 14:19 ` [PATCH 2 of 4] xl: support array types in IDL Gianni Tedesco
2011-01-12 14:19 ` [PATCH 3 of 4] xl: Implement enum " Gianni Tedesco
2011-01-12 14:19 ` [PATCH 4 of 4] pyxl: Export libxl_domain_create_new() to python binding Gianni Tedesco
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.