Skip to contentSkip to conversation

Domain creation for python libxl binding v2

PATCH New Gianni Tedesco 1 participant 5 messages Jan 12, 2011 Arm/actions semi architecture

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Domain creation for python libxl binding v2

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

--

libxl_create.c 2011-01-12 14:16:34.226240348 +0000 renamed from libxl_create.c 2011-01-12 14:08:36.651279949 +0000 +0 -33
diff -purN libxl.1/libxl_create.c libxl.2/libxl_create.c
@@ -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));
libxl.h 2011-01-12 14:16:34.226240348 +0000 renamed from libxl.h 2011-01-12 14:08:36.651279949 +0000 +12 -33

63 lines not on this page · raw message

_libxl_types.c 2011-01-12 14:16:34.226240348 +0000 renamed from _libxl_types.c 2011-01-12 14:08:36.661284022 +0000 +27 -0
diff -purN libxl.1/_libxl_types.c libxl.2/_libxl_types.c
@@ -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));
+}
+
_libxl_types.h 2011-01-12 14:16:34.226240348 +0000 renamed from _libxl_types.h 2011-01-12 14:08:36.661284022 +0000 +23 -0
diff -purN libxl.1/_libxl_types.h libxl.2/_libxl_types.h
@@ -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 */
#1 lore raw

PATCH 1/1 pyxl: Recursively scan type-tree to produce complete binding boilerplate

 tools/python/genwrap.py |  195 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 163 insertions(+), 32 deletions(-)

# HG changeset patch
# User Gianni Tedesco <[email protected]>
# 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.

tools/python/genwrap.py +163 -32
diff -r c3e478eafabc -r 787e699871a3 tools/python/genwrap.py
@@ -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')
#2 lore raw

PATCH 1/1 xl: support array types in IDL

In reply to Gianni Tedesco
 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 <[email protected]> # 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.

tools/libxl/gentypes.py +29 -1
diff -r 787e699871a3 -r f630610c99f0 tools/libxl/gentypes.py
@@ -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")
tools/libxl/libxltypes.py +6 -0
diff -r 787e699871a3 -r f630610c99f0 tools/libxl/libxltypes.py
@@ -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):
tools/python/genwrap.py +124 -23

256 lines not on this page · raw message

tools/python/xen/lowlevel/xl/xl.c +19 -0
diff -r 787e699871a3 -r f630610c99f0 tools/python/xen/lowlevel/xl/xl.c
@@ -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;
#3 lore raw

PATCH 1/1 xl: Implement enum types in IDL

In reply to Gianni Tedesco
 tools/libxl/libxltypes.py |  4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

# HG changeset patch
# User Gianni Tedesco <[email protected]> # Date 1294841273 0
# Node ID 7049135bb6b7c0ec9f1c7a4f616b3c6c0a035693 # Parent f630610c99f076ce3ceee52d888b516e70ef569a
xl: Implement enum types in IDL

tools/libxl/libxltypes.py +4 -0
diff -r f630610c99f0 -r 7049135bb6b7 tools/libxl/libxltypes.py
@@ -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)
#4 lore raw

PATCH 1/1 pyxl: Export libxl_domain_create_new() to python binding

In reply to Gianni Tedesco
 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 <[email protected]> # 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.

tools/libxl/libxl.h +12 -33
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl.h
@@ -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);
tools/libxl/libxl.idl +16 -0
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl.idl
@@ -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")),
+    ])
tools/libxl/libxl_create.c +0 -33
diff -r 7049135bb6b7 -r 7bf63de9fcdc tools/libxl/libxl_create.c
@@ -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));
tools/python/xen/lowlevel/xl/xl.c +74 -2

105 lines not on this page · raw message