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