Gianni Tedesco
2011-Jan-12 14:18 UTC
[Xen-devel] [PATCH 0 of 4] 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
--
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 */
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Gianni Tedesco
2011-Jan-12 14:18 UTC
[Xen-devel] [PATCH 1 of 4] 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 <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'')
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Gianni Tedesco
2011-Jan-12 14:19 UTC
[Xen-devel] [PATCH 2 of 4] xl: support array types in IDL
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;
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Gianni Tedesco
2011-Jan-12 14:19 UTC
[Xen-devel] [PATCH 3 of 4] xl: Implement enum types in IDL
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)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Gianni Tedesco
2011-Jan-12 14:19 UTC
[Xen-devel] [PATCH 4 of 4] pyxl: Export libxl_domain_create_new() to python binding
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);
}
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel