All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 4] Refactor libxl domain creation, v2
@ 2011-01-05 13:41 Gianni Tedesco
  2011-01-05 13:41 ` [PATCH 1 of 4] xl: idl: Abolish keyed union types Gianni Tedesco
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-05 13:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

Introduce libxl_domain_create_new() and libxl_domain_create_restore() rendering
redundant several other, more complex, API's and simplifying the xl create
implementation.

Also included patch implementing flexarray_append(), it's kind of unrelated but
it's in my queue and based on top of the prior patches in the series. :)

Changes since v1:
 - fix re-base mixup wrt. libxl_need_xenpv_qemu()
 - always return 0 on success from do_domain_create()
 - add patch to move dm functions to libxl_dm.c
 - add the flexarray_append() patcho

Gianni

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1 of 4] xl: idl: Abolish keyed union types
  2011-01-05 13:41 [PATCH 0 of 4] Refactor libxl domain creation, v2 Gianni Tedesco
@ 2011-01-05 13:41 ` Gianni Tedesco
  2011-01-06 17:56   ` Ian Jackson
  2011-01-05 13:41 ` [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-05 13:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/gentypes.py        |  10 +----
 tools/libxl/libxl.c            |  44 +++++++++++-----------
 tools/libxl/libxl.idl          |  42 ++++++++++-----------
 tools/libxl/libxl_bootloader.c |  30 +++++++-------
 tools/libxl/libxl_dom.c        |  32 ++++++++--------
 tools/libxl/libxltypes.py      |  15 -------
 tools/libxl/xl_cmdimpl.c       |  80 +++++++++++++++++++++---------------------
 tools/ocaml/libs/xl/xl_stubs.c |  26 ++++++------
 8 files changed, 127 insertions(+), 152 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294231757 0
# Node ID 5a8c843ab94a38df32e5f9dc042619a439c6f124
# Parent  39194f457534e07e5d5cc54376c4df28e0acb63c
xl: idl: Abolish keyed union types

Since the IDL file has become useful for generating language bindings it has
become apparent that the KeyedUnion type has no straightforward translation to
scripting languages which have no notion of unions.

Turns out this is only used in domain_build_info which is hardly a memory
criticial structure.

This patch simply abolishes the notion replacing it in domain_build_info with
hvm and pv structures and renaming the key to 'is_hvm'.

Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>

diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/gentypes.py	Wed Jan 05 12:49:17 2011 +0000
@@ -71,15 +71,7 @@ def libxl_C_type_destroy(ty, v, referenc
         makeref = ""
 
     s = ""
-    if isinstance(ty, libxltypes.KeyedUnion):
-        if parent is None:
-            raise Exception("KeyedUnion type must have a parent")
-        for f in ty.fields:
-            keyvar_expr = f.keyvar_expr % (parent + ty.keyvar_name)
-            s += "if (" + keyvar_expr + ") {\n"
-            s += libxl_C_type_destroy(f.type, deref + f.name, False, indent + "    ", deref)
-            s += "}\n"
-    elif isinstance(ty, libxltypes.Reference):
+    if isinstance(ty, libxltypes.Reference):
         s += libxl_C_type_destroy(ty.ref_type, v, True, indent, v)
         if ty.destructor_fn is not None:
             s += "%s(%s);\n" % (ty.destructor_fn, makeref + v)
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/libxl.c	Wed Jan 05 12:49:17 2011 +0000
@@ -306,14 +306,14 @@ int libxl_domain_build(libxl_ctx *ctx, l
 
     gettimeofday(&start_time, NULL);
 
-    if (info->hvm) {
+    if (info->is_hvm) {
         ret = libxl__build_hvm(ctx, domid, info, state);
         if (ret)
             goto out;
 
         vments = libxl__calloc(&gc, 7, sizeof(char *));
         vments[0] = "rtc/timeoffset";
-        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
+        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
         vments[2] = "image/ostype";
         vments[3] = "hvm";
         vments[4] = "start_time";
@@ -331,20 +331,20 @@ int libxl_domain_build(libxl_ctx *ctx, l
         vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk.path) {
+        if (info->pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk.path;
+            vments[i++] = (char*) info->pv.ramdisk.path;
         }
-        if (info->u.pv.cmdline) {
+        if (info->pv.cmdline) {
             vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->u.pv.cmdline;
+            vments[i++] = (char*) info->pv.cmdline;
         }
     }
     ret = libxl__build_post(ctx, domid, info, state, vments, localents);
 out:
     libxl__file_reference_unmap(&info->kernel);
-    if (!info->hvm)
-	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
+    if (!info->is_hvm)
+	    libxl__file_reference_unmap(&info->pv.ramdisk);
 
     libxl__free_all(&gc);
     return ret;
@@ -369,10 +369,10 @@ int libxl_domain_restore(libxl_ctx *ctx,
 
     gettimeofday(&start_time, NULL);
 
-    if (info->hvm) {
+    if (info->is_hvm) {
         vments = libxl__calloc(&gc, 7, sizeof(char *));
         vments[0] = "rtc/timeoffset";
-        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
+        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
         vments[2] = "image/ostype";
         vments[3] = "hvm";
         vments[4] = "start_time";
@@ -386,13 +386,13 @@ int libxl_domain_restore(libxl_ctx *ctx,
         vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
         vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->u.pv.ramdisk.path) {
+        if (info->pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->u.pv.ramdisk.path;
+            vments[i++] = (char*) info->pv.ramdisk.path;
         }
-        if (info->u.pv.cmdline) {
+        if (info->pv.cmdline) {
             vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->u.pv.cmdline;
+            vments[i++] = (char*) info->pv.cmdline;
         }
     }
     ret = libxl__build_post(ctx, domid, info, state, vments, localents);
@@ -400,7 +400,7 @@ int libxl_domain_restore(libxl_ctx *ctx,
         goto out;
 
     dm_info->saved_state = NULL;
-    if (info->hvm) {
+    if (info->is_hvm) {
         ret = asprintf(&dm_info->saved_state,
                        "/var/lib/xen/qemu-save.%d", domid);
         ret = (ret < 0) ? ERROR_FAIL : 0;
@@ -408,8 +408,8 @@ int libxl_domain_restore(libxl_ctx *ctx,
 
 out:
     libxl__file_reference_unmap(&info->kernel);
-    if (!info->hvm)
-	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
+    if (!info->is_hvm)
+	    libxl__file_reference_unmap(&info->pv.ramdisk);
 
     esave = errno;
 
@@ -1560,10 +1560,10 @@ static int libxl_create_stubdom(libxl_ct
     b_info.max_memkb = 32 * 1024;
     b_info.target_memkb = b_info.max_memkb;
     b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
-    b_info.u.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
-    b_info.u.pv.ramdisk.path = "";
-    b_info.u.pv.features = "";
-    b_info.hvm = 0;
+    b_info.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
+    b_info.pv.ramdisk.path = "";
+    b_info.pv.features = "";
+    b_info.is_hvm = 0;
 
     ret = libxl_domain_make(ctx, &c_info, &domid);
     if (ret)
@@ -3088,7 +3088,7 @@ int libxl_domain_need_memory(libxl_ctx *
         libxl_device_model_info *dm_info, uint32_t *need_memkb)
 {
     *need_memkb = b_info->target_memkb;
-    if (b_info->hvm) {
+    if (b_info->is_hvm) {
         *need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
         if (strstr(dm_info->device_model, "stubdom-dm"))
             *need_memkb += 32 * 1024;
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/libxl.idl	Wed Jan 05 12:49:17 2011 +0000
@@ -96,28 +96,26 @@ libxl_domain_build_info = Struct("domain
     ("disable_migrate", bool),
     ("kernel",          libxl_file_reference),
     ("cpuid",           libxl_cpuid_policy_list),
-    ("hvm",             integer),
-    ("u", KeyedUnion(None, "hvm",
-                [("hvm", "%s", Struct(None,
-                                       [("pae", bool),
-                                        ("apic", bool),
-                                        ("acpi", bool),
-                                        ("nx", bool),
-                                        ("viridian", bool),
-                                        ("timeoffset", string),
-                                        ("hpet", bool),
-                                        ("vpt_align", bool),
-                                        ("timer_mode", integer),
-                                        ])),
-                 ("pv", "!%s", Struct(None,
-                                       [("slack_memkb", uint32),
-                                        ("bootloader", string),
-                                        ("bootloader_args", string),
-                                        ("cmdline", string),
-                                        ("ramdisk", libxl_file_reference),
-                                        ("features", string, True),
-                                        ])),
-                 ])),
+    ("is_hvm",          bool),
+    ("hvm", Struct(None,
+                           [("pae", bool),
+                            ("apic", bool),
+                            ("acpi", bool),
+                            ("nx", bool),
+                            ("viridian", bool),
+                            ("timeoffset", string),
+                            ("hpet", bool),
+                            ("vpt_align", bool),
+                            ("timer_mode", integer),
+                            ])),
+     ("pv", Struct(None,
+                           [("slack_memkb", uint32),
+                            ("bootloader", string),
+                            ("bootloader_args", string),
+                            ("cmdline", string),
+                            ("ramdisk", libxl_file_reference),
+                            ("features", string, True),
+                            ])),
     ],
     comment =
 """Instances of libxl_file_reference contained in this struct which
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/libxl_bootloader.c
--- a/tools/libxl/libxl_bootloader.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/libxl_bootloader.c	Wed Jan 05 12:49:17 2011 +0000
@@ -42,23 +42,23 @@ static char **make_bootloader_args(libxl
     if (!args)
         return NULL;
 
-    flexarray_set(args, nr++, (char *)info->u.pv.bootloader);
+    flexarray_set(args, nr++, (char *)info->pv.bootloader);
 
     if (info->kernel.path)
         flexarray_set(args, nr++, libxl__sprintf(gc, "--kernel=%s", info->kernel.path));
-    if (info->u.pv.ramdisk.path)
-        flexarray_set(args, nr++, libxl__sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk.path));
-    if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
-        flexarray_set(args, nr++, libxl__sprintf(gc, "--args=%s", info->u.pv.cmdline));
+    if (info->pv.ramdisk.path)
+        flexarray_set(args, nr++, libxl__sprintf(gc, "--ramdisk=%s", info->pv.ramdisk.path));
+    if (info->pv.cmdline && *info->pv.cmdline != '\0')
+        flexarray_set(args, nr++, libxl__sprintf(gc, "--args=%s", info->pv.cmdline));
 
     flexarray_set(args, nr++, libxl__sprintf(gc, "--output=%s", fifo));
     flexarray_set(args, nr++, "--output-format=simple0");
     flexarray_set(args, nr++, libxl__sprintf(gc, "--output-directory=%s", "/var/run/libxl/"));
 
-    if (info->u.pv.bootloader_args) {
+    if (info->pv.bootloader_args) {
         char *saveptr;
         /* Operate on a duplicate since strtok modifes the argument */
-        char *dup = libxl__strdup(gc, info->u.pv.bootloader_args);
+        char *dup = libxl__strdup(gc, info->pv.bootloader_args);
         char *t = strtok_r(dup, " \t\n", &saveptr);
         do {
             flexarray_set(args, nr++, t);
@@ -282,13 +282,13 @@ static void parse_bootloader_result(libx
             libxl__file_reference_map(&info->kernel);
             unlink(info->kernel.path);
         } else if (strncmp("ramdisk ", o, strlen("ramdisk ")) == 0) {
-            free(info->u.pv.ramdisk.path);
-            info->u.pv.ramdisk.path = strdup(o + strlen("ramdisk "));
-            libxl__file_reference_map(&info->u.pv.ramdisk);
-            unlink(info->u.pv.ramdisk.path);
+            free(info->pv.ramdisk.path);
+            info->pv.ramdisk.path = strdup(o + strlen("ramdisk "));
+            libxl__file_reference_map(&info->pv.ramdisk);
+            unlink(info->pv.ramdisk.path);
         } else if (strncmp("args ", o, strlen("args ")) == 0) {
-            free(info->u.pv.cmdline);
-            info->u.pv.cmdline = strdup(o + strlen("args "));
+            free(info->pv.cmdline);
+            info->pv.cmdline = strdup(o + strlen("args "));
         }
 
         o = o + strlen(o) + 1;
@@ -321,7 +321,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
 
     struct stat st_buf;
 
-    if (info->hvm || !info->u.pv.bootloader)
+    if (info->is_hvm || !info->pv.bootloader)
         goto out;
 
     rc = ERROR_INVAL;
@@ -386,7 +386,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
     dom_console_xs_path = libxl__sprintf(&gc, "%s/console/tty", libxl__xs_get_dompath(&gc, domid));
     libxl__xs_write(&gc, XBT_NULL, dom_console_xs_path, "%s", dom_console_slave_tty_path);
 
-    pid = fork_exec_bootloader(&bootloader_fd, info->u.pv.bootloader, args);
+    pid = fork_exec_bootloader(&bootloader_fd, info->pv.bootloader, args);
     if (pid < 0) {
         goto out_close;
     }
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/libxl_dom.c	Wed Jan 05 12:49:17 2011 +0000
@@ -70,13 +70,13 @@ int libxl__build_pre(libxl_ctx *ctx, uin
     xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus);
     xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + LIBXL_MAXMEM_CONSTANT);
     xc_domain_set_memmap_limit(ctx->xch, domid, 
-            (info->hvm) ? info->max_memkb : 
-            (info->max_memkb + info->u.pv.slack_memkb));
+            (info->is_hvm) ? info->max_memkb : 
+            (info->max_memkb + info->pv.slack_memkb));
     xc_domain_set_tsc_info(ctx->xch, domid, info->tsc_mode, 0, 0, 0);
     if ( info->disable_migrate )
         xc_domain_disable_migrate(ctx->xch, domid);
 
-    if (info->hvm) {
+    if (info->is_hvm) {
         unsigned long shadow;
         shadow = (info->shadow_memkb + 1023) / 1024;
         xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL);
@@ -152,7 +152,7 @@ int libxl__build_pv(libxl_ctx *ctx, uint
 
     xc_dom_loginit(ctx->xch);
 
-    dom = xc_dom_allocate(ctx->xch, info->u.pv.cmdline, info->u.pv.features);
+    dom = xc_dom_allocate(ctx->xch, info->pv.cmdline, info->pv.features);
     if (!dom) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_allocate failed");
         return ERROR_FAIL;
@@ -170,14 +170,14 @@ int libxl__build_pv(libxl_ctx *ctx, uint
         }
     }
 
-    if ( info->u.pv.ramdisk.path && strlen(info->u.pv.ramdisk.path) ) {
-        if (info->u.pv.ramdisk.mapped) {
-            if ( (ret = xc_dom_ramdisk_mem(dom, info->u.pv.ramdisk.data, info->u.pv.ramdisk.size)) != 0 ) {
+    if ( info->pv.ramdisk.path && strlen(info->pv.ramdisk.path) ) {
+        if (info->pv.ramdisk.mapped) {
+            if ( (ret = xc_dom_ramdisk_mem(dom, info->pv.ramdisk.data, info->pv.ramdisk.size)) != 0 ) {
                 LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_ramdisk_mem failed");
                 goto out;
             }
         } else {
-            if ( (ret = xc_dom_ramdisk_file(dom, info->u.pv.ramdisk.path)) != 0 ) {
+            if ( (ret = xc_dom_ramdisk_file(dom, info->pv.ramdisk.path)) != 0 ) {
                 LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_ramdisk_file failed");
                 goto out;
             }
@@ -238,8 +238,8 @@ static int hvm_build_set_params(xc_inter
         return -1;
 
     va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
-    va_hvm->acpi_enabled = info->u.hvm.acpi;
-    va_hvm->apic_mode = info->u.hvm.apic;
+    va_hvm->acpi_enabled = info->hvm.acpi;
+    va_hvm->apic_mode = info->hvm.apic;
     va_hvm->nr_vcpus = info->max_vcpus;
     memcpy(va_hvm->vcpu_online, &info->cur_vcpus, sizeof(info->cur_vcpus));
     for (i = 0, sum = 0; i < va_hvm->length; i++)
@@ -249,13 +249,13 @@ static int hvm_build_set_params(xc_inter
 
     xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn);
     xc_get_hvm_param(handle, domid, HVM_PARAM_CONSOLE_PFN, console_mfn);
-    xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, info->u.hvm.pae);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, info->hvm.pae);
 #if defined(__i386__) || defined(__x86_64__)
-    xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, info->u.hvm.viridian);
-    xc_set_hvm_param(handle, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) info->u.hvm.hpet);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, info->hvm.viridian);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) info->hvm.hpet);
 #endif
-    xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->u.hvm.timer_mode);
-    xc_set_hvm_param(handle, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->u.hvm.vpt_align);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_TIMER_MODE, (unsigned long) info->hvm.timer_mode);
+    xc_set_hvm_param(handle, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->hvm.vpt_align);
     xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
     xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn);
     return 0;
@@ -305,7 +305,7 @@ int libxl__domain_restore_common(libxl_c
     rc = xc_domain_restore(ctx->xch, fd, domid,
                              state->store_port, &state->store_mfn,
                              state->console_port, &state->console_mfn,
-                             info->hvm, info->u.hvm.pae, 0);
+                             info->is_hvm, info->hvm.pae, 0);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain");
         return ERROR_FAIL;
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/libxltypes.py	Wed Jan 05 12:49:17 2011 +0000
@@ -104,21 +104,6 @@ class Union(Aggregate):
         kwargs.setdefault('destructor_fn', None)
         Aggregate.__init__(self, "union", name, fields, **kwargs)
 
-class KeyedUnion(Aggregate):
-    """A union which is keyed of another variable in the parent structure"""
-    def __init__(self, name, keyvar_name, fields, **kwargs):
-        Aggregate.__init__(self, "union", name, [], **kwargs)
-
-        self.keyvar_name = keyvar_name
-
-        for f in fields:
-            # (name, keyvar_expr, type)
-
-            # keyvar_expr must contain exactly one %s which will be replaced with the keyvar_name
-
-            n, kve, ty = f
-            self.fields.append(Field(ty, n, keyvar_expr=kve))
-
 class Reference(Type):
     """A reference to another type"""
     def __init__(self, ty, **kwargs):
diff -r 39194f457534 -r 5a8c843ab94a tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Wed Jan 05 12:49:17 2011 +0000
@@ -336,17 +336,17 @@ static void init_build_info(libxl_domain
     if (c_info->hvm) {
         b_info->video_memkb = 8 * 1024;
         b_info->kernel.path = strdup("hvmloader");
-        b_info->hvm = 1;
-        b_info->u.hvm.pae = 1;
-        b_info->u.hvm.apic = 1;
-        b_info->u.hvm.acpi = 1;
-        b_info->u.hvm.nx = 1;
-        b_info->u.hvm.viridian = 0;
-        b_info->u.hvm.hpet = 1;
-        b_info->u.hvm.vpt_align = 1;
-        b_info->u.hvm.timer_mode = 1;
+        b_info->is_hvm = 1;
+        b_info->hvm.pae = 1;
+        b_info->hvm.apic = 1;
+        b_info->hvm.acpi = 1;
+        b_info->hvm.nx = 1;
+        b_info->hvm.viridian = 0;
+        b_info->hvm.hpet = 1;
+        b_info->hvm.vpt_align = 1;
+        b_info->hvm.timer_mode = 1;
     } else {
-        b_info->u.pv.slack_memkb = 8 * 1024;
+        b_info->pv.slack_memkb = 8 * 1024;
     }
 }
 
@@ -360,7 +360,7 @@ static void init_dm_info(libxl_device_mo
     dm_info->dom_name = strdup(c_info->name);
     dm_info->device_model = strdup("qemu-dm");
     dm_info->videoram = b_info->video_memkb / 1024;
-    dm_info->apic = b_info->u.hvm.apic;
+    dm_info->apic = b_info->hvm.apic;
     dm_info->vcpus = b_info->max_vcpus;
     dm_info->vcpu_avail = b_info->cur_vcpus;
 
@@ -512,10 +512,10 @@ static void printf_info(int domid,
     printf("\t(target_memkb %d)\n", b_info->target_memkb);
     printf("\t(nomigrate %d)\n", b_info->disable_migrate);
 
-    if (!c_info->hvm && b_info->u.pv.bootloader) {
-        printf("\t(bootloader %s)\n", b_info->u.pv.bootloader);
-        if (b_info->u.pv.bootloader_args)
-            printf("\t(bootloader_args %s)\n", b_info->u.pv.bootloader_args);
+    if (!c_info->hvm && b_info->pv.bootloader) {
+        printf("\t(bootloader %s)\n", b_info->pv.bootloader);
+        if (b_info->pv.bootloader_args)
+            printf("\t(bootloader_args %s)\n", b_info->pv.bootloader_args);
     }
 
     printf("\t(image\n");
@@ -524,14 +524,14 @@ static void printf_info(int domid,
         printf("\t\t\t(loader %s)\n", b_info->kernel.path);
         printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
         printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
-        printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
-        printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic);
-        printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi);
-        printf("\t\t\t(nx %d)\n", b_info->u.hvm.nx);
-        printf("\t\t\t(viridian %d)\n", b_info->u.hvm.viridian);
-        printf("\t\t\t(hpet %d)\n", b_info->u.hvm.hpet);
-        printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align);
-        printf("\t\t\t(timer_mode %d)\n", b_info->u.hvm.timer_mode);
+        printf("\t\t\t(pae %d)\n", b_info->hvm.pae);
+        printf("\t\t\t(apic %d)\n", b_info->hvm.apic);
+        printf("\t\t\t(acpi %d)\n", b_info->hvm.acpi);
+        printf("\t\t\t(nx %d)\n", b_info->hvm.nx);
+        printf("\t\t\t(viridian %d)\n", b_info->hvm.viridian);
+        printf("\t\t\t(hpet %d)\n", b_info->hvm.hpet);
+        printf("\t\t\t(vpt_align %d)\n", b_info->hvm.vpt_align);
+        printf("\t\t\t(timer_mode %d)\n", b_info->hvm.timer_mode);
 
         printf("\t\t\t(device_model %s)\n", dm_info->device_model);
         printf("\t\t\t(videoram %d)\n", dm_info->videoram);
@@ -551,10 +551,10 @@ static void printf_info(int domid,
         printf("\t\t\t(apic %d)\n", dm_info->apic);
         printf("\t\t)\n");
     } else {
-        printf("\t\t(linux %d)\n", b_info->hvm);
+        printf("\t\t(linux %d)\n", b_info->is_hvm);
         printf("\t\t\t(kernel %s)\n", b_info->kernel.path);
-        printf("\t\t\t(cmdline %s)\n", b_info->u.pv.cmdline);
-        printf("\t\t\t(ramdisk %s)\n", b_info->u.pv.ramdisk.path);
+        printf("\t\t\t(cmdline %s)\n", b_info->pv.cmdline);
+        printf("\t\t\t(ramdisk %s)\n", b_info->pv.ramdisk.path);
         printf("\t\t)\n");
     }
     printf("\t)\n");
@@ -774,21 +774,21 @@ static void parse_config_data(const char
 
     if (c_info->hvm == 1) {
         if (!xlu_cfg_get_long (config, "pae", &l))
-            b_info->u.hvm.pae = l;
+            b_info->hvm.pae = l;
         if (!xlu_cfg_get_long (config, "apic", &l))
-            b_info->u.hvm.apic = l;
+            b_info->hvm.apic = l;
         if (!xlu_cfg_get_long (config, "acpi", &l))
-            b_info->u.hvm.acpi = l;
+            b_info->hvm.acpi = l;
         if (!xlu_cfg_get_long (config, "nx", &l))
-            b_info->u.hvm.nx = l;
+            b_info->hvm.nx = l;
         if (!xlu_cfg_get_long (config, "viridian", &l))
-            b_info->u.hvm.viridian = l;
+            b_info->hvm.viridian = l;
         if (!xlu_cfg_get_long (config, "hpet", &l))
-            b_info->u.hvm.hpet = l;
+            b_info->hvm.hpet = l;
         if (!xlu_cfg_get_long (config, "vpt_align", &l))
-            b_info->u.hvm.vpt_align = l;
+            b_info->hvm.vpt_align = l;
         if (!xlu_cfg_get_long (config, "timer_mode", &l))
-            b_info->u.hvm.timer_mode = l;
+            b_info->hvm.timer_mode = l;
     } else {
         char *cmdline = NULL;
         const char *root = NULL, *extra = "";
@@ -808,16 +808,16 @@ static void parse_config_data(const char
             exit(1);
         }
 
-        xlu_cfg_replace_string (config, "bootloader", &b_info->u.pv.bootloader);
-        xlu_cfg_replace_string (config, "bootloader_args", &b_info->u.pv.bootloader_args);
-
-        if (!b_info->u.pv.bootloader && !b_info->kernel.path) {
+        xlu_cfg_replace_string (config, "bootloader", &b_info->pv.bootloader);
+        xlu_cfg_replace_string (config, "bootloader_args", &b_info->pv.bootloader_args);
+
+        if (!b_info->pv.bootloader && !b_info->kernel.path) {
             fprintf(stderr, "Neither kernel nor bootloader specified\n");
             exit(1);
         }
 
-        b_info->u.pv.cmdline = cmdline;
-        xlu_cfg_replace_string (config, "ramdisk", &b_info->u.pv.ramdisk.path);
+        b_info->pv.cmdline = cmdline;
+        xlu_cfg_replace_string (config, "ramdisk", &b_info->pv.ramdisk.path);
     }
 
     if (!xlu_cfg_get_list (config, "disk", &vbds, 0, 0)) {
diff -r 39194f457534 -r 5a8c843ab94a tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/tools/ocaml/libs/xl/xl_stubs.c	Wed Jan 05 12:49:17 2011 +0000
@@ -166,20 +166,20 @@ static int domain_build_info_val (caml_g
 	c_val->hvm = Tag_val(Field(v, 7)) == 0;
 	infopriv = Field(Field(v, 7), 0);
 	if (c_val->hvm) {
-		c_val->u.hvm.pae = Bool_val(Field(infopriv, 0));
-		c_val->u.hvm.apic = Bool_val(Field(infopriv, 1));
-		c_val->u.hvm.acpi = Bool_val(Field(infopriv, 2));
-		c_val->u.hvm.nx = Bool_val(Field(infopriv, 3));
-		c_val->u.hvm.viridian = Bool_val(Field(infopriv, 4));
-		c_val->u.hvm.timeoffset = dup_String_val(gc, Field(infopriv, 5));
-		c_val->u.hvm.timer_mode = Int_val(Field(infopriv, 6));
-		c_val->u.hvm.hpet = Int_val(Field(infopriv, 7));
-		c_val->u.hvm.vpt_align = Int_val(Field(infopriv, 8));
+		c_val->hvm.pae = Bool_val(Field(infopriv, 0));
+		c_val->hvm.apic = Bool_val(Field(infopriv, 1));
+		c_val->hvm.acpi = Bool_val(Field(infopriv, 2));
+		c_val->hvm.nx = Bool_val(Field(infopriv, 3));
+		c_val->hvm.viridian = Bool_val(Field(infopriv, 4));
+		c_val->hvm.timeoffset = dup_String_val(gc, Field(infopriv, 5));
+		c_val->hvm.timer_mode = Int_val(Field(infopriv, 6));
+		c_val->hvm.hpet = Int_val(Field(infopriv, 7));
+		c_val->hvm.vpt_align = Int_val(Field(infopriv, 8));
 	} else {
-		c_val->u.pv.slack_memkb = Int64_val(Field(infopriv, 0));
-		c_val->u.pv.cmdline = dup_String_val(gc, Field(infopriv, 1));
-		c_val->u.pv.ramdisk.path = dup_String_val(gc, Field(infopriv, 2));
-		c_val->u.pv.features = dup_String_val(gc, Field(infopriv, 3));
+		c_val->pv.slack_memkb = Int64_val(Field(infopriv, 0));
+		c_val->pv.cmdline = dup_String_val(gc, Field(infopriv, 1));
+		c_val->pv.ramdisk.path = dup_String_val(gc, Field(infopriv, 2));
+		c_val->pv.features = dup_String_val(gc, Field(infopriv, 3));
 	}
 
 	CAMLreturn(0);

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
  2011-01-05 13:41 [PATCH 0 of 4] Refactor libxl domain creation, v2 Gianni Tedesco
  2011-01-05 13:41 ` [PATCH 1 of 4] xl: idl: Abolish keyed union types Gianni Tedesco
@ 2011-01-05 13:41 ` Gianni Tedesco
  2011-01-06 17:58   ` Ian Jackson
  2011-01-05 13:41 ` [PATCH 3 of 4] xl: Move device model functions in to a separate file Gianni Tedesco
  2011-01-05 13:41 ` [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend() Gianni Tedesco
  3 siblings, 1 reply; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-05 13:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/Makefile           |    4 +-
 tools/libxl/libxl.c            |  286 +----------------------
 tools/libxl/libxl.h            |   62 +++--
 tools/libxl/libxl_create.c     |  482 +++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_exec.c       |    2 +-
 tools/libxl/libxl_internal.h   |   29 ++-
 tools/libxl/xl_cmdimpl.c       |  328 ++++++---------------------
 tools/ocaml/libs/xl/xl_stubs.c |   85 +------
 8 files changed, 657 insertions(+), 621 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294231811 0
# Node ID c6e3c9a8029db76295c5a3c2c4abc77ce9da5cae
# Parent  5a8c843ab94a38df32e5f9dc042619a439c6f124
xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()

These functions are introduced as the new way to create domains with libxl they
prevent the callers from needing to know about low-level implementation details
such as:
 - libxl_domain_make()
 - libxl_domain_build()
 - libxl_domain_restore()
 - when to attach the console
 - how to start the device model

Above mentioned functions and all API's for the device model, which are now
redundant, have been made internal to libxl and no longer accessible.

The ocaml binding for libxl has not been properly updated to reflect the
changes, wrappers for the old functions have been removed but the code to wrap
the new functions has not been added.

Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>

diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/Makefile
--- a/tools/libxl/Makefile	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/Makefile	Wed Jan 05 12:50:11 2011 +0000
@@ -20,7 +20,7 @@ ifeq ($(CONFIG_Linux),y)
 LIBS += -luuid
 endif
 
-LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
+LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o
 ifeq ($(LIBXL_BLKTAP),y)
 LIBXL_OBJS-y += libxl_blktap2.o
 else
@@ -29,7 +29,7 @@ endif
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
-LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
+LIBXL_OBJS = libxl.o libxl_create.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/libxl.c	Wed Jan 05 12:50:11 2011 +0000
@@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_
 
 /******************************************************************************/
 
-int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
-                       uint32_t *domid)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    int flags, ret, i, rc;
-    char *uuid_string;
-    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
-    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
-                         "control", "attr", "messages" };
-    char *dom_path, *vm_path;
-    struct xs_permissions roperm[2];
-    struct xs_permissions rwperm[1];
-    xs_transaction_t t;
-    xen_domain_handle_t handle;
-
-    uuid_string = libxl__uuid2string(&gc, info->uuid);
-    if (!uuid_string) {
-        libxl__free_all(&gc);
-        return ERROR_NOMEM;
-    }
-
-    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
-    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
-    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
-    *domid = -1;
-
-    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
-    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
-
-    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
-    if (ret < 0) {
-        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
-    if (ret < 0) {
-        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    dom_path = libxl__xs_get_dompath(&gc, *domid);
-    if (!dom_path) {
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
-    if (!vm_path) {
-        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
-    }
-
-    roperm[0].id = 0;
-    roperm[0].perms = XS_PERM_NONE;
-    roperm[1].id = *domid;
-    roperm[1].perms = XS_PERM_READ;
-    rwperm[0].id = *domid;
-    rwperm[0].perms = XS_PERM_NONE;
-
-retry_transaction:
-    t = xs_transaction_start(ctx->xsh);
-    xs_rm(ctx->xsh, t, dom_path);
-    xs_mkdir(ctx->xsh, t, dom_path);
-    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
-
-    xs_rm(ctx->xsh, t, vm_path);
-    xs_mkdir(ctx->xsh, t, vm_path);
-    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
-    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
-    if (rc) {
-        libxl__free_all(&gc);
-        return rc;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
-        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
-        xs_mkdir(ctx->xsh, t, path);
-        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
-    }
-    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
-        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
-        xs_mkdir(ctx->xsh, t, path);
-        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
-    }
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name));
-    if (info->poolname)
-        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname));
-
-    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
-    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata);
-
-    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
-
-    if (!xs_transaction_end(ctx->xsh, t, 0))
-        if (errno == EAGAIN)
-            goto retry_transaction;
-
-    libxl__free_all(&gc);
-    return 0;
-}
 
 int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
                         const char *old_name, const char *new_name,
@@ -293,141 +185,6 @@ int libxl_domain_rename(libxl_ctx *ctx, 
  x_nomem: rc = ERROR_NOMEM; goto x_rc;
 }
 
-int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char **vments = NULL, **localents = NULL;
-    struct timeval start_time;
-    int i, ret;
-
-    ret = libxl__build_pre(ctx, domid, info, state);
-    if (ret)
-        goto out;
-
-    gettimeofday(&start_time, NULL);
-
-    if (info->is_hvm) {
-        ret = libxl__build_hvm(ctx, domid, info, state);
-        if (ret)
-            goto out;
-
-        vments = libxl__calloc(&gc, 7, sizeof(char *));
-        vments[0] = "rtc/timeoffset";
-        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
-        vments[2] = "image/ostype";
-        vments[3] = "hvm";
-        vments[4] = "start_time";
-        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-    } else {
-        ret = libxl__build_pv(ctx, domid, info, state);
-        if (ret)
-            goto out;
-
-        vments = libxl__calloc(&gc, 11, sizeof(char *));
-        i = 0;
-        vments[i++] = "image/ostype";
-        vments[i++] = "linux";
-        vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
-        vments[i++] = "start_time";
-        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->pv.ramdisk.path) {
-            vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->pv.ramdisk.path;
-        }
-        if (info->pv.cmdline) {
-            vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->pv.cmdline;
-        }
-    }
-    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
-out:
-    libxl__file_reference_unmap(&info->kernel);
-    if (!info->is_hvm)
-	    libxl__file_reference_unmap(&info->pv.ramdisk);
-
-    libxl__free_all(&gc);
-    return ret;
-}
-
-int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
-                         uint32_t domid, int fd, libxl_domain_build_state *state,
-                         libxl_device_model_info *dm_info)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char **vments = NULL, **localents = NULL;
-    struct timeval start_time;
-    int i, ret, esave, flags;
-
-    ret = libxl__build_pre(ctx, domid, info, state);
-    if (ret)
-        goto out;
-
-    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
-    if (ret)
-        goto out;
-
-    gettimeofday(&start_time, NULL);
-
-    if (info->is_hvm) {
-        vments = libxl__calloc(&gc, 7, sizeof(char *));
-        vments[0] = "rtc/timeoffset";
-        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
-        vments[2] = "image/ostype";
-        vments[3] = "hvm";
-        vments[4] = "start_time";
-        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-    } else {
-        vments = libxl__calloc(&gc, 11, sizeof(char *));
-        i = 0;
-        vments[i++] = "image/ostype";
-        vments[i++] = "linux";
-        vments[i++] = "image/kernel";
-        vments[i++] = (char*) info->kernel.path;
-        vments[i++] = "start_time";
-        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
-        if (info->pv.ramdisk.path) {
-            vments[i++] = "image/ramdisk";
-            vments[i++] = (char*) info->pv.ramdisk.path;
-        }
-        if (info->pv.cmdline) {
-            vments[i++] = "image/cmdline";
-            vments[i++] = (char*) info->pv.cmdline;
-        }
-    }
-    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
-    if (ret)
-        goto out;
-
-    dm_info->saved_state = NULL;
-    if (info->is_hvm) {
-        ret = asprintf(&dm_info->saved_state,
-                       "/var/lib/xen/qemu-save.%d", domid);
-        ret = (ret < 0) ? ERROR_FAIL : 0;
-    }
-
-out:
-    libxl__file_reference_unmap(&info->kernel);
-    if (!info->is_hvm)
-	    libxl__file_reference_unmap(&info->pv.ramdisk);
-
-    esave = errno;
-
-    flags = fcntl(fd, F_GETFL);
-    if (flags == -1) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd");
-    } else {
-        flags &= ~O_NONBLOCK;
-        if (fcntl(fd, F_SETFL, flags) == -1)
-            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
-                         " back to blocking mode");
-    }
-
-    errno = esave;
-    libxl__free_all(&gc);
-    return ret;
-}
-
 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
@@ -1427,7 +1184,7 @@ static char ** libxl_build_device_model_
 
 static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
 {
-    libxl_device_model_starting *starting = for_spawn;
+    libxl__device_model_starting *starting = for_spawn;
     struct xs_handle *xsh;
     char *path = NULL, *pid = NULL;
     int len;
@@ -1529,7 +1286,7 @@ static int libxl_create_stubdom(libxl_ct
                                 libxl_device_nic *vifs, int num_vifs,
                                 libxl_device_vfb *vfb,
                                 libxl_device_vkb *vkb,
-                                libxl_device_model_starting **starting_r)
+                                libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     int i, num_console = 1, ret;
@@ -1541,7 +1298,7 @@ static int libxl_create_stubdom(libxl_ct
     char **args;
     struct xs_permissions perm[2];
     xs_transaction_t t;
-    libxl_device_model_starting *dm_starting = 0;
+    libxl__device_model_starting *dm_starting = 0;
 
     args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
     if (!args) {
@@ -1565,10 +1322,10 @@ static int libxl_create_stubdom(libxl_ct
     b_info.pv.features = "";
     b_info.is_hvm = 0;
 
-    ret = libxl_domain_make(ctx, &c_info, &domid);
+    ret = libxl__domain_make(ctx, &c_info, &domid);
     if (ret)
         goto out_free;
-    ret = libxl_domain_build(ctx, &b_info, domid, &state);
+    ret = libxl__domain_build(ctx, &b_info, domid, &state);
     if (ret)
         goto out_free;
 
@@ -1648,11 +1405,11 @@ retry_transaction:
         if (ret)
             goto out_free;
     }
-    if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
+    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
         ret = ERROR_FAIL;
         goto out_free;
     }
-    if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) {
+    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
         ret = ERROR_FAIL;
         goto out_free;
     }
@@ -1660,7 +1417,7 @@ retry_transaction:
     libxl_domain_unpause(ctx, domid);
 
     if (starting_r) {
-        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
         (*starting_r)->domid = info->domid;
         (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
         (*starting_r)->for_spawn = NULL;
@@ -1675,18 +1432,18 @@ out:
     return ret;
 }
 
-int libxl_create_device_model(libxl_ctx *ctx,
+int libxl__create_device_model(libxl_ctx *ctx,
                               libxl_device_model_info *info,
                               libxl_device_disk *disks, int num_disks,
                               libxl_device_nic *vifs, int num_vifs,
-                              libxl_device_model_starting **starting_r)
+                              libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     char *path, *logfile;
     int logfile_w, null;
     int rc;
     char **args;
-    libxl_device_model_starting buf_starting, *p;
+    libxl__device_model_starting buf_starting, *p;
     xs_transaction_t t; 
     char *vm_path;
     char **pass_stuff;
@@ -1717,7 +1474,7 @@ int libxl_create_device_model(libxl_ctx 
 
     if (starting_r) {
         rc = ERROR_NOMEM;
-        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
         if (!*starting_r)
             goto out_close;
         p = *starting_r;
@@ -1771,8 +1528,9 @@ out:
     return rc;
 }
 
-int libxl_detach_device_model(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting)
+/* DM is detached even if error is returned */
+static int detach_device_model(libxl_ctx *ctx,
+                              libxl__device_model_starting *starting)
 {
     int rc;
     rc = libxl__spawn_detach(ctx, starting->for_spawn);
@@ -1783,14 +1541,14 @@ int libxl_detach_device_model(libxl_ctx 
 }
 
 
-int libxl_confirm_device_model_startup(libxl_ctx *ctx,
-                                       libxl_device_model_starting *starting)
+int libxl__confirm_device_model_startup(libxl_ctx *ctx,
+                                       libxl__device_model_starting *starting)
 {
     int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
     int detach;
     if ( !problem )
         problem = libxl__spawn_check(ctx, starting->for_spawn);
-    detach = libxl_detach_device_model(ctx, starting);
+    detach = detach_device_model(ctx, starting);
     return problem ? problem : detach;
 }
 
@@ -2654,7 +2412,7 @@ static int libxl_build_xenpv_qemu_args(l
     return 0;
 }
 
-int libxl_need_xenpv_qemu(libxl_ctx *ctx,
+int libxl__need_xenpv_qemu(libxl_ctx *ctx,
         int nr_consoles, libxl_device_console *consoles,
         int nr_vfbs, libxl_device_vfb *vfbs,
         int nr_disks, libxl_device_disk *disks)
@@ -2687,14 +2445,14 @@ out:
     return ret;
 }
 
-int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
-                            libxl_device_model_starting **starting_r)
+int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
+                            libxl__device_model_starting **starting_r)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     libxl_device_model_info info;
 
     libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
-    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
+    libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
     libxl__free_all(&gc);
     return 0;
 }
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/libxl.h	Wed Jan 05 12:50:11 2011 +0000
@@ -241,6 +241,38 @@ 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);
@@ -248,11 +280,10 @@ int libxl_ctx_set_log(libxl_ctx *ctx, xe
 int libxl_ctx_postfork(libxl_ctx *ctx);
 
 /* domain related functions */
-int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid);
-int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state);
-int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
-                         uint32_t domid, int fd, libxl_domain_build_state *state,
-                         libxl_device_model_info *dm_info);
+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);
@@ -375,27 +406,6 @@ libxl_dominfo * libxl_list_domain(libxl_
 libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool);
 libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm);
 
-typedef struct libxl__device_model_starting libxl_device_model_starting;
-int libxl_create_device_model(libxl_ctx *ctx,
-                              libxl_device_model_info *info,
-                              libxl_device_disk *disk, int num_disks,
-                              libxl_device_nic *vifs, int num_vifs,
-                              libxl_device_model_starting **starting_r);
-int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
-                            libxl_device_model_starting **starting_r);
-int libxl_need_xenpv_qemu(libxl_ctx *ctx,
-        int nr_consoles, libxl_device_console *consoles,
-        int nr_vfbs, libxl_device_vfb *vfbs,
-        int nr_disks, libxl_device_disk *disks);
-  /* Caller must either: pass starting_r==0, or on successful
-   * return pass *starting_r (which will be non-0) to
-   * libxl_confirm_device_model or libxl_detach_device_model. */
-int libxl_confirm_device_model_startup(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting);
-int libxl_detach_device_model(libxl_ctx *ctx,
-                              libxl_device_model_starting *starting);
-  /* DM is detached even if error is returned */
-
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk);
 int libxl_device_disk_del(libxl_ctx *ctx, libxl_device_disk *disk, int wait);
 libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num);
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/libxl_create.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_create.c	Wed Jan 05 12:50:11 2011 +0000
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+ * Author Gianni Tedesco <gianni.tedesco@citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "libxl.h"
+#include "libxl_utils.h"
+#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);
+}
+
+static int init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
+{
+    memset(console, 0x00, sizeof(libxl_device_console));
+    console->devid = dev_num;
+    console->consback = LIBXL_CONSBACK_XENCONSOLED;
+    console->output = strdup("pty");
+    if ( NULL == console->output )
+        return ERROR_NOMEM;
+    if (state)
+        console->build_state = state;
+    return 0;
+}
+
+int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char **vments = NULL, **localents = NULL;
+    struct timeval start_time;
+    int i, ret;
+
+    ret = libxl__build_pre(ctx, domid, info, state);
+    if (ret)
+        goto out;
+
+    gettimeofday(&start_time, NULL);
+
+    if (info->is_hvm) {
+        ret = libxl__build_hvm(ctx, domid, info, state);
+        if (ret)
+            goto out;
+
+        vments = libxl__calloc(&gc, 7, sizeof(char *));
+        vments[0] = "rtc/timeoffset";
+        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
+        vments[2] = "image/ostype";
+        vments[3] = "hvm";
+        vments[4] = "start_time";
+        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
+    } else {
+        ret = libxl__build_pv(ctx, domid, info, state);
+        if (ret)
+            goto out;
+
+        vments = libxl__calloc(&gc, 11, sizeof(char *));
+        i = 0;
+        vments[i++] = "image/ostype";
+        vments[i++] = "linux";
+        vments[i++] = "image/kernel";
+        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = "start_time";
+        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
+        if (info->pv.ramdisk.path) {
+            vments[i++] = "image/ramdisk";
+            vments[i++] = (char*) info->pv.ramdisk.path;
+        }
+        if (info->pv.cmdline) {
+            vments[i++] = "image/cmdline";
+            vments[i++] = (char*) info->pv.cmdline;
+        }
+    }
+    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
+out:
+    libxl__file_reference_unmap(&info->kernel);
+    if (!info->is_hvm)
+	    libxl__file_reference_unmap(&info->pv.ramdisk);
+
+    libxl__free_all(&gc);
+    return ret;
+}
+
+static int domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
+                         uint32_t domid, int fd, libxl_domain_build_state *state,
+                         libxl_device_model_info *dm_info)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char **vments = NULL, **localents = NULL;
+    struct timeval start_time;
+    int i, ret, esave, flags;
+
+    ret = libxl__build_pre(ctx, domid, info, state);
+    if (ret)
+        goto out;
+
+    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
+    if (ret)
+        goto out;
+
+    gettimeofday(&start_time, NULL);
+
+    if (info->is_hvm) {
+        vments = libxl__calloc(&gc, 7, sizeof(char *));
+        vments[0] = "rtc/timeoffset";
+        vments[1] = (info->hvm.timeoffset) ? info->hvm.timeoffset : "";
+        vments[2] = "image/ostype";
+        vments[3] = "hvm";
+        vments[4] = "start_time";
+        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
+    } else {
+        vments = libxl__calloc(&gc, 11, sizeof(char *));
+        i = 0;
+        vments[i++] = "image/ostype";
+        vments[i++] = "linux";
+        vments[i++] = "image/kernel";
+        vments[i++] = (char*) info->kernel.path;
+        vments[i++] = "start_time";
+        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
+        if (info->pv.ramdisk.path) {
+            vments[i++] = "image/ramdisk";
+            vments[i++] = (char*) info->pv.ramdisk.path;
+        }
+        if (info->pv.cmdline) {
+            vments[i++] = "image/cmdline";
+            vments[i++] = (char*) info->pv.cmdline;
+        }
+    }
+    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
+    if (ret)
+        goto out;
+
+    dm_info->saved_state = NULL;
+    if (info->is_hvm) {
+        ret = asprintf(&dm_info->saved_state,
+                       "/var/lib/xen/qemu-save.%d", domid);
+        ret = (ret < 0) ? ERROR_FAIL : 0;
+    }
+
+out:
+    libxl__file_reference_unmap(&info->kernel);
+    if (!info->is_hvm)
+	    libxl__file_reference_unmap(&info->pv.ramdisk);
+
+    esave = errno;
+
+    flags = fcntl(fd, F_GETFL);
+    if (flags == -1) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd");
+    } else {
+        flags &= ~O_NONBLOCK;
+        if (fcntl(fd, F_SETFL, flags) == -1)
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
+                         " back to blocking mode");
+    }
+
+    errno = esave;
+    libxl__free_all(&gc);
+    return ret;
+}
+
+int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
+                       uint32_t *domid)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int flags, ret, i, rc;
+    char *uuid_string;
+    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
+    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
+                         "control", "attr", "messages" };
+    char *dom_path, *vm_path;
+    struct xs_permissions roperm[2];
+    struct xs_permissions rwperm[1];
+    xs_transaction_t t;
+    xen_domain_handle_t handle;
+
+    uuid_string = libxl__uuid2string(&gc, info->uuid);
+    if (!uuid_string) {
+        libxl__free_all(&gc);
+        return ERROR_NOMEM;
+    }
+
+    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
+    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
+    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
+    *domid = -1;
+
+    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
+    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
+
+    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
+    if (ret < 0) {
+        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
+    if (ret < 0) {
+        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    dom_path = libxl__xs_get_dompath(&gc, *domid);
+    if (!dom_path) {
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
+    if (!vm_path) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
+        libxl__free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    roperm[0].id = 0;
+    roperm[0].perms = XS_PERM_NONE;
+    roperm[1].id = *domid;
+    roperm[1].perms = XS_PERM_READ;
+    rwperm[0].id = *domid;
+    rwperm[0].perms = XS_PERM_NONE;
+
+retry_transaction:
+    t = xs_transaction_start(ctx->xsh);
+    xs_rm(ctx->xsh, t, dom_path);
+    xs_mkdir(ctx->xsh, t, dom_path);
+    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
+
+    xs_rm(ctx->xsh, t, vm_path);
+    xs_mkdir(ctx->xsh, t, vm_path);
+    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
+    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
+    if (rc) {
+        libxl__free_all(&gc);
+        return rc;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
+        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
+        xs_mkdir(ctx->xsh, t, path);
+        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
+    }
+    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
+        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
+        xs_mkdir(ctx->xsh, t, path);
+        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
+    }
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name));
+    if (info->poolname)
+        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname));
+
+    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
+    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata);
+
+    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
+    if (!xs_transaction_end(ctx->xsh, t, 0))
+        if (errno == EAGAIN)
+            goto retry_transaction;
+
+    libxl__free_all(&gc);
+    return 0;
+}
+
+static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config,
+                            libxl_console_ready cb, void *priv,
+                            uint32_t *domid_out, int restore_fd)
+{
+    libxl__device_model_starting *dm_starting = 0;
+    libxl_device_model_info *dm_info = &d_config->dm_info;
+    libxl_domain_build_state state;
+    uint32_t domid;
+    int i, ret;
+
+    domid = 0;
+
+    ret = libxl__domain_make(ctx, &d_config->c_info, &domid);
+    if (ret) {
+        fprintf(stderr, "cannot make domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    if ( !d_config->c_info.hvm && cb ) {
+        if ( (*cb)(ctx, domid, priv) )
+            goto error_out;
+    }
+
+    if ( restore_fd < 0 ) {
+        ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks > 0 ? &d_config->disks[0] : NULL, domid);
+        if (ret) {
+            fprintf(stderr, "failed to run bootloader: %d\n", ret);
+            goto error_out;
+        }
+    }
+
+    if ( restore_fd >= 0 ) {
+        ret = domain_restore(ctx, &d_config->b_info, domid, restore_fd, &state, dm_info);
+    } else {
+        if (dm_info->saved_state) {
+            free(dm_info->saved_state);
+            dm_info->saved_state = NULL;
+        }
+        ret = libxl__domain_build(ctx, &d_config->b_info, domid, &state);
+    }
+
+    if (ret) {
+        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    for (i = 0; i < d_config->num_disks; i++) {
+        d_config->disks[i].domid = domid;
+        ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    for (i = 0; i < d_config->num_vifs; i++) {
+        d_config->vifs[i].domid = domid;
+        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    if (!d_config->c_info.hvm) {
+        for (i = 0; i < d_config->num_vif2s; i++) {
+            d_config->vif2s[i].domid = domid;
+            ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]);
+            if (ret) {
+                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
+                ret = ERROR_FAIL;
+                goto error_out;
+            }
+        }
+    }
+    if (d_config->c_info.hvm) {
+        libxl_device_console console;
+
+        ret = init_console_info(&console, 0, &state);
+        if ( ret )
+            goto error_out;
+        console.domid = domid;
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        dm_info->domid = domid;
+        ret = libxl__create_device_model(ctx, dm_info,
+                                        d_config->disks, d_config->num_disks,
+                                        d_config->vifs, d_config->num_vifs,
+                                        &dm_starting);
+        if (ret < 0) {
+            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__create_device_model\n",
+                    __FILE__,__LINE__, ret);
+            goto error_out;
+        }
+    } else {
+        int need_qemu = 0;
+        libxl_device_console console;
+
+        for (i = 0; i < d_config->num_vfbs; i++) {
+            d_config->vfbs[i].domid = domid;
+            libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]);
+            d_config->vkbs[i].domid = domid;
+            libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]);
+        }
+
+        ret = init_console_info(&console, 0, &state);
+        if ( ret )
+            goto error_out;
+        console.domid = domid;
+
+        need_qemu = libxl__need_xenpv_qemu(ctx, 1, &console,
+                d_config->num_vfbs, d_config->vfbs,
+                d_config->num_disks, &d_config->disks[0]);
+
+        if (need_qemu)
+             console.consback = LIBXL_CONSBACK_IOEMU;
+
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        if (need_qemu)
+            libxl__create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting);
+    }
+
+    if (dm_starting) {
+        ret = libxl__confirm_device_model_startup(ctx, dm_starting);
+        if (ret < 0) {
+            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__confirm_device_model_startup\n",
+                    __FILE__,__LINE__, ret);
+            goto error_out;
+        }
+    }
+
+    for (i = 0; i < d_config->num_pcidevs; i++)
+        libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]);
+
+    if ( d_config->c_info.hvm && cb ) {
+        if ( (*cb)(ctx, domid, priv) )
+            goto error_out;
+    }
+
+    *domid_out = domid;
+    return 0;
+
+error_out:
+    if (domid)
+        libxl_domain_destroy(ctx, domid, 0);
+
+    return ret;
+}
+int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
+                            libxl_console_ready cb, void *priv, uint32_t *domid)
+{
+    return do_domain_create(ctx, d_config, cb, priv, domid, -1);
+}
+
+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)
+{
+    return do_domain_create(ctx, d_config, cb, priv, domid, restore_fd);
+}
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/libxl_exec.c	Wed Jan 05 12:50:11 2011 +0000
@@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl
 }
 
 int libxl__spawn_spawn(libxl_ctx *ctx,
-                      libxl_device_model_starting *starting,
+                      libxl__device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn,
                                                 pid_t innerchild))
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/libxl_internal.h	Wed Jan 05 12:50:11 2011 +0000
@@ -194,14 +194,37 @@ typedef struct {
     char *what; /* malloc'd in spawn_spawn */
 } libxl__spawn_starting;
 
-struct libxl__device_model_starting {
+typedef struct {
     libxl__spawn_starting *for_spawn; /* first! */
     char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */
     int domid;
-};
+} libxl__device_model_starting;
+
+/* from xl_create */
+_hidden int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid);
+_hidden int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state);
+
+/* for device model creation */
+_hidden int libxl__create_device_model(libxl_ctx *ctx,
+                              libxl_device_model_info *info,
+                              libxl_device_disk *disk, int num_disks,
+                              libxl_device_nic *vifs, int num_vifs,
+                              libxl__device_model_starting **starting_r);
+_hidden int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
+                            libxl__device_model_starting **starting_r);
+_hidden int libxl__need_xenpv_qemu(libxl_ctx *ctx,
+        int nr_consoles, libxl_device_console *consoles,
+        int nr_vfbs, libxl_device_vfb *vfbs,
+        int nr_disks, libxl_device_disk *disks);
+
+  /* Caller must either: pass starting_r==0, or on successful
+   * return pass *starting_r (which will be non-0) to
+   * libxl_confirm_device_model or libxl_detach_device_model. */
+_hidden int libxl__confirm_device_model_startup(libxl_ctx *ctx,
+                              libxl__device_model_starting *starting);
 
 _hidden int libxl__spawn_spawn(libxl_ctx *ctx,
-                      libxl_device_model_starting *starting,
+                      libxl__device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn, pid_t innerchild));
   /* Logs errors.  A copy of "what" is taken.  Return values:
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Wed Jan 05 12:50:11 2011 +0000
@@ -100,81 +100,18 @@ struct save_file_header {
 };
 
 
-enum action_on_shutdown {
-    ACTION_DESTROY,
-
-    ACTION_RESTART,
-    ACTION_RESTART_RENAME,
-
-    ACTION_PRESERVE,
-
-    ACTION_COREDUMP_DESTROY,
-    ACTION_COREDUMP_RESTART,
+static const char *action_on_shutdown_names[] = {
+    [LIBXL_ACTION_DESTROY] = "destroy",
+
+    [LIBXL_ACTION_RESTART] = "restart",
+    [LIBXL_ACTION_RESTART_RENAME] = "rename-restart",
+
+    [LIBXL_ACTION_PRESERVE] = "preserve",
+
+    [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy",
+    [LIBXL_ACTION_COREDUMP_RESTART] = "coredump-restart",
 };
 
-static const char *action_on_shutdown_names[] = {
-    [ACTION_DESTROY] = "destroy",
-
-    [ACTION_RESTART] = "restart",
-    [ACTION_RESTART_RENAME] = "rename-restart",
-
-    [ACTION_PRESERVE] = "preserve",
-
-    [ACTION_COREDUMP_DESTROY] = "coredump-destroy",
-    [ACTION_COREDUMP_RESTART] = "coredump-restart",
-};
-
-struct domain_config {
-    libxl_domain_create_info c_info;
-    libxl_domain_build_info b_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 action_on_shutdown on_poweroff;
-    enum action_on_shutdown on_reboot;
-    enum action_on_shutdown on_watchdog;
-    enum action_on_shutdown on_crash;
-};
-
-static void free_domain_config(struct 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);
-}
-
 /* Optional data, in order:
  *   4 bytes uint32_t  config file size
  *   n bytes           config file in Unix text file format
@@ -457,18 +394,8 @@ static void init_vkb_info(libxl_device_v
     vkb->devid = dev_num;
 }
 
-static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
-{
-    memset(console, 0x00, sizeof(libxl_device_console));
-    console->devid = dev_num;
-    console->consback = LIBXL_CONSBACK_XENCONSOLED;
-    console->output = strdup("pty");
-    if (state)
-        console->build_state = state;
-}
-
 static void printf_info(int domid,
-                        struct domain_config *d_config,
+                        libxl_domain_config *d_config,
                         libxl_device_model_info *dm_info)
 {
     int i;
@@ -625,7 +552,7 @@ static void printf_info(int domid,
        printf(")\n");
 }
 
-static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a)
+static int parse_action_on_shutdown(const char *buf, enum libxl_action_on_shutdown *a)
 {
     int i;
     const char *n;
@@ -644,7 +571,7 @@ static int parse_action_on_shutdown(cons
 static void parse_config_data(const char *configfile_filename_report,
                               const char *configfile_data,
                               int configfile_len,
-                              struct domain_config *d_config,
+                              libxl_domain_config *d_config,
                               libxl_device_model_info *dm_info)
 {
     const char *buf;
@@ -1233,32 +1160,12 @@ static void *xrealloc(void *ptr, size_t 
     return r;
 }
 
-static pid_t autoconnect_console(void)
-{
-    pid_t pid;
-
-    pid = fork();
-    if (pid < 0) {
-        perror("unable to fork xenconsole");
-        return ERROR_FAIL;
-    } else if (pid > 0)
-        return pid;
-
-    libxl_ctx_postfork(&ctx);
-
-    sleep(1);
-    libxl_primary_console_exec(&ctx, domid);
-    /* Do not return. xl continued in child process */
-    fprintf(stderr, "Unable to attach console\n");
-    _exit(1);
-}
-
 /* Returns 1 if domain should be restarted, 2 if domain should be renamed then restarted  */
 static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
-                               struct domain_config *d_config, libxl_dominfo *info)
+                               libxl_domain_config *d_config, libxl_dominfo *info)
 {
     int restart = 0;
-    enum action_on_shutdown action;
+    enum libxl_action_on_shutdown action;
 
     switch (info->shutdown_reason) {
     case SHUTDOWN_poweroff:
@@ -1277,12 +1184,12 @@ static int handle_domain_death(libxl_ctx
         break;
     default:
         LOG("Unknown shutdown reason code %d. Destroying domain.", info->shutdown_reason);
-        action = ACTION_DESTROY;
+        action = LIBXL_ACTION_DESTROY;
     }
 
     LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, action_on_shutdown_names[action]);
 
-    if (action == ACTION_COREDUMP_DESTROY || action == ACTION_COREDUMP_RESTART) {
+    if (action == LIBXL_ACTION_COREDUMP_DESTROY || action == LIBXL_ACTION_COREDUMP_RESTART) {
         char *corefile;
         int rc;
 
@@ -1295,30 +1202,30 @@ static int handle_domain_death(libxl_ctx
         }
         /* No point crying over spilled milk, continue on failure. */
 
-        if (action == ACTION_COREDUMP_DESTROY)
-            action = ACTION_DESTROY;
+        if (action == LIBXL_ACTION_COREDUMP_DESTROY)
+            action = LIBXL_ACTION_DESTROY;
         else
-            action = ACTION_RESTART;
+            action = LIBXL_ACTION_RESTART;
     }
 
     switch (action) {
-    case ACTION_PRESERVE:
+    case LIBXL_ACTION_PRESERVE:
         break;
 
-    case ACTION_RESTART_RENAME:
+    case LIBXL_ACTION_RESTART_RENAME:
         restart = 2;
         break;
 
-    case ACTION_RESTART:
+    case LIBXL_ACTION_RESTART:
         restart = 1;
         /* fall-through */
-    case ACTION_DESTROY:
+    case LIBXL_ACTION_DESTROY:
         LOG("Domain %d needs to be cleaned up: destroying the domain", domid);
         libxl_domain_destroy(ctx, domid, 0);
         break;
 
-    case ACTION_COREDUMP_DESTROY:
-    case ACTION_COREDUMP_RESTART:
+    case LIBXL_ACTION_COREDUMP_DESTROY:
+    case LIBXL_ACTION_COREDUMP_RESTART:
         /* Already handled these above. */
         abort();
     }
@@ -1327,7 +1234,7 @@ static int handle_domain_death(libxl_ctx
 }
 
 static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
-                           struct domain_config *d_config, libxl_dominfo *info)
+                           libxl_domain_config *d_config, libxl_dominfo *info)
 {
     time_t now;
     struct tm tm;
@@ -1418,12 +1325,29 @@ static int freemem(libxl_domain_build_in
     return ERROR_NOMEM;
 }
 
+static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv)
+{
+    pid_t *pid = priv;
+
+    *pid = fork();
+    if (*pid < 0) {
+        perror("unable to fork xenconsole");
+        return ERROR_FAIL;
+    } else if (*pid > 0)
+        return 0;
+
+    libxl_ctx_postfork(ctx);
+
+    sleep(1);
+    libxl_primary_console_exec(ctx, domid);
+    /* Do not return. xl continued in child process */
+    fprintf(stderr, "Unable to attach console\n");
+    _exit(1);
+}
+
 static int create_domain(struct domain_create *dom_info)
 {
-    struct domain_config d_config;
-
-    libxl_domain_build_state state;
-    libxl_device_model_info dm_info;
+    libxl_domain_config d_config;
 
     int debug = dom_info->debug;
     int daemonize = dom_info->daemonize;
@@ -1433,20 +1357,19 @@ static int create_domain(struct domain_c
     const char *restore_file = dom_info->restore_file;
     int migrate_fd = dom_info->migrate_fd;
 
-    int i, fd;
+    int fd;
     int need_daemon = 1;
     int ret, rc;
-    libxl_device_model_starting *dm_starting = 0;
     libxl_waiter *w1 = NULL, *w2 = NULL;
     void *config_data = 0;
     int config_len = 0;
     int restore_fd = -1;
+    int status = 0;
+    libxl_console_ready cb;
+    pid_t child_console_pid = -1;
     struct save_file_header hdr;
-    pid_t child_console_pid = -1;
-    int status = 0;
 
     memset(&d_config, 0x00, sizeof(d_config));
-    memset(&dm_info, 0x00, sizeof(dm_info));
 
     if (restore_file) {
         uint8_t *optdata_begin = 0;
@@ -1546,7 +1469,7 @@ static int create_domain(struct domain_c
     if (!dom_info->quiet)
         printf("Parsing config file %s\n", config_file);
 
-    parse_config_data(config_file, config_data, config_len, &d_config, &dm_info);
+    parse_config_data(config_file, config_data, config_len, &d_config, &d_config.dm_info);
 
     ret = 0;
     if (dom_info->dryrun)
@@ -1571,7 +1494,7 @@ static int create_domain(struct domain_c
     }
 
     if (debug)
-        printf_info(-1, &d_config, &dm_info);
+        printf_info(-1, &d_config, &d_config.dm_info);
 
 start:
     domid = 0;
@@ -1580,20 +1503,13 @@ start:
     if (rc < 0)
         goto error_out;
 
-    ret = freemem(&d_config.b_info, &dm_info);
+    ret = freemem(&d_config.b_info, &d_config.dm_info);
     if (ret < 0) {
         fprintf(stderr, "failed to free memory for the domain\n");
         ret = ERROR_FAIL;
         goto error_out;
     }
 
-    ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
-    if (ret) {
-        fprintf(stderr, "cannot make domain: %d\n", ret);
-        ret = ERROR_FAIL;
-        goto error_out;
-    }
-
     ret = libxl_userdata_store(&ctx, domid, "xl",
                                     config_data, config_len);
     if (ret) {
@@ -1602,116 +1518,22 @@ start:
         goto error_out;
     }
 
-    if (dom_info->console_autoconnect && !d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
-
-    if (!restore_file) {
-        ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks > 0 ? &d_config.disks[0] : NULL, domid);
-        if (ret) {
-            fprintf(stderr, "failed to run bootloader: %d\n", ret);
-            goto error_out;
-        }
-    }
-
-    if (!restore_file || !need_daemon) {
-        if (dm_info.saved_state) {
-            free(dm_info.saved_state);
-            dm_info.saved_state = NULL;
-        }
-        ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state);
-    } else {
-        ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, &state, &dm_info);
-    }
-
-    if (ret) {
-        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
-        ret = ERROR_FAIL;
+    if ( dom_info->console_autoconnect ) {
+        cb = autoconnect_console;
+    }else{
+        cb = NULL;
+    }
+
+    if ( restore_file ) {
+        ret = libxl_domain_create_restore(&ctx, &d_config,
+                                            cb, &child_console_pid,
+                                            &domid, restore_fd);
+    }else{
+        ret = libxl_domain_create_new(&ctx, &d_config,
+                                        cb, &child_console_pid, &domid);
+    }
+    if ( ret )
         goto error_out;
-    }
-
-    for (i = 0; i < d_config.num_disks; i++) {
-        d_config.disks[i].domid = domid;
-        ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    for (i = 0; i < d_config.num_vifs; i++) {
-        d_config.vifs[i].domid = domid;
-        ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    if (!d_config.c_info.hvm) {
-        for (i = 0; i < d_config.num_vif2s; i++) {
-            d_config.vif2s[i].domid = domid;
-            ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]);
-            if (ret) {
-                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
-                ret = ERROR_FAIL;
-                goto error_out;
-            }
-        }
-    }
-    if (d_config.c_info.hvm) {
-        libxl_device_console console;
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        dm_info.domid = domid;
-        MUST( libxl_create_device_model(&ctx, &dm_info,
-                                        d_config.disks, d_config.num_disks,
-                                        d_config.vifs, d_config.num_vifs,
-                                        &dm_starting) );
-    } else {
-        int need_qemu = 0;
-        libxl_device_console console;
-
-        for (i = 0; i < d_config.num_vfbs; i++) {
-            d_config.vfbs[i].domid = domid;
-            libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]);
-            d_config.vkbs[i].domid = domid;
-            libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]);
-        }
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-
-        need_qemu = libxl_need_xenpv_qemu(&ctx, 1, &console,
-                d_config.num_vfbs, d_config.vfbs,
-                d_config.num_disks, &d_config.disks[0]);
-
-        if (need_qemu)
-             console.consback = LIBXL_CONSBACK_IOEMU;
-
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        if (need_qemu)
-            libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting);
-    }
-
-    if (dm_starting)
-        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
-    for (i = 0; i < d_config.num_pcidevs; i++)
-        libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]);
-
-    if (dom_info->console_autoconnect && d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
 
     release_lock();
 
@@ -1729,6 +1551,8 @@ start:
 
         child1 = libxl_fork(&ctx);
         if (child1) {
+            printf("Daemon running with PID %d\n", child1);
+
             for (;;) {
                 got_child = waitpid(child1, &status, 0);
                 if (got_child == child1) break;
@@ -1870,9 +1694,7 @@ out:
     if (logfile != 2)
         close(logfile);
 
-    libxl_device_model_info_destroy(&dm_info);
-
-    free_domain_config(&d_config);
+    libxl_domain_config_destroy(&d_config);
 
     free(config_data);
 
@@ -2467,7 +2289,7 @@ static void reboot_domain(const char *p)
 
 static void list_domains_details(const libxl_dominfo *info, int nb_domain)
 {
-    struct domain_config d_config;
+    libxl_domain_config d_config;
 
     char *config_file;
     uint8_t *data;
@@ -2485,7 +2307,7 @@ static void list_domains_details(const l
         memset(&d_config, 0x00, sizeof(d_config));
         parse_config_data(config_file, (char *)data, len, &d_config, &dm_info);
         printf_info(info[i].domid, &d_config, &dm_info);
-        free_domain_config(&d_config);
+        libxl_domain_config_destroy(&d_config);
         free(data);
         free(config_file);
     }
diff -r 5a8c843ab94a -r c6e3c9a8029d tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c	Wed Jan 05 12:49:17 2011 +0000
+++ b/tools/ocaml/libs/xl/xl_stubs.c	Wed Jan 05 12:50:11 2011 +0000
@@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logge
 	caml_leave_blocking_section(); \
 	libxl_ctx_free(&ctx)
 
-static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
-{
-	void *ptr;
-	ptr = calloc(nmemb, size);
-	if (!ptr)
-		caml_raise_out_of_memory();
-	gc->ptrs[gc->offset++] = ptr;
-	return ptr;
-}
-
 static char * dup_String_val(caml_gc *gc, value s)
 {
 	int len;
@@ -106,6 +96,17 @@ void failwith_xl(char *fname, struct cam
 	caml_raise_with_string(*caml_named_value("xl.error"), s);
 }
 
+#if 0 /* TODO: wrap libxl_domain_create(), these functions will be needed then */
+static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
+{
+	void *ptr;
+	ptr = calloc(nmemb, size);
+	if (!ptr)
+		caml_raise_out_of_memory();
+	gc->ptrs[gc->offset++] = ptr;
+	return ptr;
+}
+
 static int string_string_tuple_array_val (caml_gc *gc, char ***c_val, value v)
 {
 	CAMLparam1(v);
@@ -163,7 +164,7 @@ static int domain_build_info_val (caml_g
 	c_val->video_memkb = Int64_val(Field(v, 4));
 	c_val->shadow_memkb = Int64_val(Field(v, 5));
 	c_val->kernel.path = dup_String_val(gc, Field(v, 6));
-	c_val->hvm = Tag_val(Field(v, 7)) == 0;
+	c_val->is_hvm = Tag_val(Field(v, 7)) == 0;
 	infopriv = Field(Field(v, 7), 0);
 	if (c_val->hvm) {
 		c_val->hvm.pae = Bool_val(Field(infopriv, 0));
@@ -184,6 +185,7 @@ static int domain_build_info_val (caml_g
 
 	CAMLreturn(0);
 }
+#endif
 
 static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v)
 {
@@ -332,21 +334,6 @@ static value Val_sched_credit(libxl_sche
 	CAMLreturn(v);
 }
 
-static value Val_domain_build_state(libxl_domain_build_state *c_val)
-{
-	CAMLparam0();
-	CAMLlocal1(v);
-
-	v = caml_alloc_tuple(4);
-
-	Store_field(v, 0, Val_int(c_val->store_port));
-	Store_field(v, 1, caml_copy_int64(c_val->store_mfn));
-	Store_field(v, 2, Val_int(c_val->console_port));
-	Store_field(v, 3, caml_copy_int64(c_val->console_mfn));
-
-	CAMLreturn(v);
-}
-
 static value Val_physinfo(libxl_physinfo *c_val)
 {
 	CAMLparam0();
@@ -373,52 +360,6 @@ static value Val_physinfo(libxl_physinfo
 	CAMLreturn(v);
 }
 
-value stub_xl_domain_make(value info)
-{
-	CAMLparam1(info);
-	uint32_t domid;
-	libxl_domain_create_info c_info;
-	int ret;
-	INIT_STRUCT();
-
-	domain_create_info_val (&gc, &c_info, info);
-
-	INIT_CTX();
-
-	ret = libxl_domain_make(&ctx, &c_info, &domid);
-	if (ret != 0)
-		failwith_xl("domain make", &lg);
-
-	FREE_CTX();
-
-	CAMLreturn(Val_int(domid));
-}
-
-value stub_xl_domain_build(value info, value domid)
-{
-	CAMLparam2(info, domid);
-	CAMLlocal1(result);
-	libxl_domain_build_info c_info;
-	libxl_domain_build_state c_state;
-	int ret;
-	int c_domid;
-	INIT_STRUCT();
-
-	domain_build_info_val (&gc, &c_info, info);
-	c_domid = Int_val(domid);
-
-	INIT_CTX();
-
-	ret = libxl_domain_build(&ctx, &c_info, c_domid, &c_state);
-	if (ret != 0)
-		failwith_xl("domain_build", &lg);
-
-	result = Val_domain_build_state(&c_state);
-	FREE_CTX();
-
-	CAMLreturn(result);
-}
-
 value stub_xl_disk_add(value info, value domid)
 {
 	CAMLparam2(info, domid);

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3 of 4] xl: Move device model functions in to a separate file
  2011-01-05 13:41 [PATCH 0 of 4] Refactor libxl domain creation, v2 Gianni Tedesco
  2011-01-05 13:41 ` [PATCH 1 of 4] xl: idl: Abolish keyed union types Gianni Tedesco
  2011-01-05 13:41 ` [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
@ 2011-01-05 13:41 ` Gianni Tedesco
  2011-01-06 18:00   ` [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages] Ian Jackson
  2011-01-05 13:41 ` [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend() Gianni Tedesco
  3 siblings, 1 reply; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-05 13:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/Makefile         |    2 +-
 tools/libxl/libxl.c          |  807 +-----------------------------------------
 tools/libxl/libxl_dm.c       |  831 +++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |    2 +
 4 files changed, 836 insertions(+), 806 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294231842 0
# Node ID 2f8749c5e015463317f4c81e71d23be52bec4e06
# Parent  c6e3c9a8029db76295c5a3c2c4abc77ce9da5cae
xl: Move device model functions in to a separate file

No functional changes.

diff -r c6e3c9a8029d -r 2f8749c5e015 tools/libxl/Makefile
--- a/tools/libxl/Makefile	Wed Jan 05 12:50:11 2011 +0000
+++ b/tools/libxl/Makefile	Wed Jan 05 12:50:42 2011 +0000
@@ -29,7 +29,7 @@ endif
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
-LIBXL_OBJS = libxl.o libxl_create.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
+LIBXL_OBJS = libxl.o libxl_create.o libxl_dm.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
diff -r c6e3c9a8029d -r 2f8749c5e015 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Wed Jan 05 12:50:11 2011 +0000
+++ b/tools/libxl/libxl.c	Wed Jan 05 12:50:42 2011 +0000
@@ -659,46 +659,6 @@ int libxl_event_get_disk_eject_info(libx
     return 1;
 }
 
-static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char *pid;
-    int ret;
-
-    pid = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid));
-    if (!pid) {
-        int stubdomid = libxl_get_stubdom_id(ctx, domid);
-        if (!stubdomid) {
-            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't find device model's pid");
-            ret = ERROR_INVAL;
-            goto out;
-        }
-        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device model is a stubdom, domid=%d\n", stubdomid);
-        ret = libxl_domain_destroy(ctx, stubdomid, 0);
-        if (ret)
-            goto out;
-    } else {
-        ret = kill(atoi(pid), SIGHUP);
-        if (ret < 0 && errno == ESRCH) {
-            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model already exited");
-            ret = 0;
-        } else if (ret == 0) {
-            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model signaled");
-            ret = 0;
-        } else {
-            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to kill Device Model [%d]",
-                    atoi(pid));
-            ret = ERROR_FAIL;
-            goto out;
-        }
-    }
-    xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", domid));
-
-out:
-    libxl__free_all(&gc);
-    return ret;
-}
-
 int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
@@ -732,8 +692,8 @@ int libxl_domain_destroy(libxl_ctx *ctx,
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "xc_domain_pause failed for %d", domid);
     }
     if (dm_present) {
-        if (libxl_destroy_device_model(ctx, domid) < 0)
-            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl_destroy_device_model failed for %d", domid);
+        if (libxl__destroy_device_model(ctx, domid) < 0)
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid);
     }
     if (libxl__devices_destroy(ctx, domid, force) < 0)
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl_destroy_devices failed for %d", domid);
@@ -864,695 +824,6 @@ skip_autopass:
     return 0;
 }
 
-static char ** libxl_build_device_model_args_old(libxl__gc *gc,
-                                             libxl_device_model_info *info,
-                                             libxl_device_nic *vifs,
-                                             int num_vifs)
-{
-    int num = 0, i;
-    flexarray_t *dm_args;
-    dm_args = flexarray_make(16, 1);
-
-    if (!dm_args)
-        return NULL;
-
-    flexarray_set(dm_args, num++, "qemu-dm");
-    flexarray_set(dm_args, num++, "-d");
-
-    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
-
-    if (info->dom_name) {
-        flexarray_set(dm_args, num++, "-domain-name");
-        flexarray_set(dm_args, num++, info->dom_name);
-    }
-    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
-        flexarray_set(dm_args, num++, "-vnc");
-        if (info->vncdisplay) {
-            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
-                flexarray_set(
-                    dm_args, num++,
-                    libxl__sprintf(gc, "%s:%d%s",
-                                  info->vnclisten,
-                                  info->vncdisplay,
-                                  info->vncpasswd ? ",password" : ""));
-            } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
-            }
-        } else if (info->vnclisten) {
-            if (strchr(info->vnclisten, ':') != NULL) {
-                flexarray_set(dm_args, num++, info->vnclisten);
-            } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%s:0", info->vnclisten));
-            }
-        } else {
-            flexarray_set(dm_args, num++, "127.0.0.1:0");
-        }
-        if (info->vncunused) {
-            flexarray_set(dm_args, num++, "-vncunused");
-        }
-    }
-    if (info->sdl) {
-        flexarray_set(dm_args, num++, "-sdl");
-        if (!info->opengl) {
-            flexarray_set(dm_args, num++, "-disable-opengl");
-        }
-    }
-    if (info->keymap) {
-        flexarray_set(dm_args, num++, "-k");
-        flexarray_set(dm_args, num++, info->keymap);
-    }
-    if (info->nographic && (!info->sdl && !info->vnc)) {
-        flexarray_set(dm_args, num++, "-nographic");
-    }
-    if (info->serial) {
-        flexarray_set(dm_args, num++, "-serial");
-        flexarray_set(dm_args, num++, info->serial);
-    }
-    if (info->type == XENFV) {
-        int ioemu_vifs = 0;
-
-        if (info->videoram) {
-            flexarray_set(dm_args, num++, "-videoram");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->videoram));
-        }
-        if (info->stdvga) {
-            flexarray_set(dm_args, num++, "-std-vga");
-        }
-
-        if (info->boot) {
-            flexarray_set(dm_args, num++, "-boot");
-            flexarray_set(dm_args, num++, info->boot);
-        }
-        if (info->usb || info->usbdevice) {
-            flexarray_set(dm_args, num++, "-usb");
-            if (info->usbdevice) {
-                flexarray_set(dm_args, num++, "-usbdevice");
-                flexarray_set(dm_args, num++, info->usbdevice);
-            }
-        }
-        if (info->soundhw) {
-            flexarray_set(dm_args, num++, "-soundhw");
-            flexarray_set(dm_args, num++, info->soundhw);
-        }
-        if (info->apic) {
-            flexarray_set(dm_args, num++, "-acpi");
-        }
-        if (info->vcpus > 1) {
-            flexarray_set(dm_args, num++, "-vcpus");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
-        }
-        if (info->vcpu_avail) {
-            flexarray_set(dm_args, num++, "-vcpu_avail");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "0x%x", info->vcpu_avail));
-        }
-        for (i = 0; i < num_vifs; i++) {
-            if (vifs[i].nictype == NICTYPE_IOEMU) {
-                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
-                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
-                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
-                char *ifname;
-                if (!vifs[i].ifname)
-                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
-                else
-                    ifname = vifs[i].ifname;
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
-                            vifs[i].devid, smac, vifs[i].model));
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
-                            vifs[i].devid, ifname, vifs[i].bridge));
-                ioemu_vifs++;
-            }
-        }
-        /* If we have no emulated nics, tell qemu not to create any */
-        if ( ioemu_vifs == 0 ) {
-            flexarray_set(dm_args, num++, "-net");
-            flexarray_set(dm_args, num++, "none");
-        }
-    }
-    if (info->saved_state) {
-        flexarray_set(dm_args, num++, "-loadvm");
-        flexarray_set(dm_args, num++, info->saved_state);
-    }
-    for (i = 0; info->extra && info->extra[i] != NULL; i++)
-        flexarray_set(dm_args, num++, info->extra[i]);
-    flexarray_set(dm_args, num++, "-M");
-    if (info->type == XENPV)
-        flexarray_set(dm_args, num++, "xenpv");
-    else
-        flexarray_set(dm_args, num++, "xenfv");
-    flexarray_set(dm_args, num++, NULL);
-    return (char **) flexarray_contents(dm_args);
-}
-
-static char ** libxl_build_device_model_args_new(libxl__gc *gc,
-                                             libxl_device_model_info *info,
-                                             libxl_device_nic *vifs,
-                                             int num_vifs)
-{
-    int num = 0, i;
-    flexarray_t *dm_args;
-    int nb;
-    libxl_device_disk *disks;
-
-    dm_args = flexarray_make(16, 1);
-    if (!dm_args)
-        return NULL;
-
-    flexarray_set(dm_args, num++, libxl__strdup(gc, info->device_model));
-
-    flexarray_set(dm_args, num++, "-xen-domid");
-    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
-
-    if (info->type == XENPV) {
-        flexarray_set(dm_args, num++, "-xen-attach");
-    }
-
-    if (info->dom_name) {
-        flexarray_set(dm_args, num++, "-name");
-        flexarray_set(dm_args, num++, info->dom_name);
-    }
-    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
-        int display = 0;
-        const char *listen = "127.0.0.1";
-
-        flexarray_set(dm_args, num++, "-vnc");
-
-        if (info->vncdisplay) {
-            display = info->vncdisplay;
-            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
-                listen = info->vnclisten;
-            }
-        } else if (info->vnclisten) {
-            listen = info->vnclisten;
-        }
-
-        if (strchr(listen, ':') != NULL)
-            flexarray_set(dm_args, num++,
-                    libxl__sprintf(gc, "%s%s", listen,
-                        info->vncunused ? ",to=99" : ""));
-        else
-            flexarray_set(dm_args, num++,
-                    libxl__sprintf(gc, "%s:%d%s", listen, display,
-                        info->vncunused ? ",to=99" : ""));
-    }
-    if (info->sdl) {
-        flexarray_set(dm_args, num++, "-sdl");
-    }
-
-    if (info->type == XENPV && !info->nographic) {
-        flexarray_set(dm_args, num++, "-vga");
-        flexarray_set(dm_args, num++, "xenfb");
-    }
-
-    if (info->keymap) {
-        flexarray_set(dm_args, num++, "-k");
-        flexarray_set(dm_args, num++, info->keymap);
-    }
-    if (info->nographic && (!info->sdl && !info->vnc)) {
-        flexarray_set(dm_args, num++, "-nographic");
-    }
-    if (info->serial) {
-        flexarray_set(dm_args, num++, "-serial");
-        flexarray_set(dm_args, num++, info->serial);
-    }
-    if (info->type == XENFV) {
-        int ioemu_vifs = 0;
-
-        if (info->stdvga) {
-                flexarray_set(dm_args, num++, "-vga");
-                flexarray_set(dm_args, num++, "std");
-        }
-
-        if (info->boot) {
-            flexarray_set(dm_args, num++, "-boot");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "order=%s", info->boot));
-        }
-        if (info->usb || info->usbdevice) {
-            flexarray_set(dm_args, num++, "-usb");
-            if (info->usbdevice) {
-                flexarray_set(dm_args, num++, "-usbdevice");
-                flexarray_set(dm_args, num++, info->usbdevice);
-            }
-        }
-        if (info->soundhw) {
-            flexarray_set(dm_args, num++, "-soundhw");
-            flexarray_set(dm_args, num++, info->soundhw);
-        }
-        if (!info->apic) {
-            flexarray_set(dm_args, num++, "-no-acpi");
-        }
-        if (info->vcpus > 1) {
-            flexarray_set(dm_args, num++, "-smp");
-            if (info->vcpu_avail)
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
-            else
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
-        }
-        for (i = 0; i < num_vifs; i++) {
-            if (vifs[i].nictype == NICTYPE_IOEMU) {
-                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
-                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
-                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
-                char *ifname;
-                if (!vifs[i].ifname) {
-                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
-                } else {
-                    ifname = vifs[i].ifname;
-                }
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
-                            vifs[i].devid, smac, vifs[i].model));
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
-                            vifs[i].devid, ifname));
-                ioemu_vifs++;
-            }
-        }
-        /* If we have no emulated nics, tell qemu not to create any */
-        if ( ioemu_vifs == 0 ) {
-            flexarray_set(dm_args, num++, "-net");
-            flexarray_set(dm_args, num++, "none");
-        }
-    }
-    if (info->saved_state) {
-        flexarray_set(dm_args, num++, "-loadvm");
-        flexarray_set(dm_args, num++, info->saved_state);
-    }
-    for (i = 0; info->extra && info->extra[i] != NULL; i++)
-        flexarray_set(dm_args, num++, info->extra[i]);
-    flexarray_set(dm_args, num++, "-M");
-    if (info->type == XENPV)
-        flexarray_set(dm_args, num++, "xenpv");
-    else
-        flexarray_set(dm_args, num++, "xenfv");
-
-    if (info->type == XENFV) {
-        disks = libxl_device_disk_list(libxl__gc_owner(gc), info->domid, &nb);
-        for (i; i < nb; i++) {
-            if (disks[i].is_cdrom) {
-                flexarray_set(dm_args, num++, "-cdrom");
-                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
-            } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "-%s", disks[i].virtpath));
-                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
-            }
-            libxl_device_disk_destroy(&disks[i]);
-        }
-    }
-    free(disks);
-    flexarray_set(dm_args, num++, NULL);
-    return (char **) flexarray_contents(dm_args);
-}
-
-static char ** libxl_build_device_model_args(libxl__gc *gc,
-                                             libxl_device_model_info *info,
-                                             libxl_device_nic *vifs,
-                                             int num_vifs)
-{
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-    int new_qemu;
-
-    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
-
-    if (new_qemu == 1) {
-        return libxl_build_device_model_args_new(gc, info, vifs, num_vifs);
-    } else {
-        return libxl_build_device_model_args_old(gc, info, vifs, num_vifs);
-    }
-}
-
-static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
-{
-    libxl__device_model_starting *starting = for_spawn;
-    struct xs_handle *xsh;
-    char *path = NULL, *pid = NULL;
-    int len;
-
-    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
-        goto out;
-
-    len = asprintf(&pid, "%d", innerchild);
-    if (len < 0)
-        goto out;
-
-    /* we mustn't use the parent's handle in the child */
-    xsh = xs_daemon_open();
-
-    xs_write(xsh, XBT_NULL, path, pid, len);
-
-    xs_daemon_close(xsh);
-out:
-    free(path);
-    free(pid);
-}
-
-static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx,
-                                                    libxl_device_model_info *info,
-                                                    libxl_device_vfb *vfb,
-                                                    libxl_device_vkb *vkb)
-{
-    memset(vfb, 0x00, sizeof(libxl_device_vfb));
-    memset(vkb, 0x00, sizeof(libxl_device_vkb));
-
-    vfb->backend_domid = 0;
-    vfb->devid = 0;
-    vfb->vnc = info->vnc;
-    vfb->vnclisten = info->vnclisten;
-    vfb->vncdisplay = info->vncdisplay;
-    vfb->vncunused = info->vncunused;
-    vfb->vncpasswd = info->vncpasswd;
-    vfb->keymap = info->keymap;
-    vfb->sdl = info->sdl;
-    vfb->opengl = info->opengl;
-
-    vkb->backend_domid = 0;
-    vkb->devid = 0;
-    return 0;
-}
-
-static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    int i;
-    char *vm_path;
-    char *dmargs, *path;
-    int dmargs_size;
-    struct xs_permissions roperm[2];
-    xs_transaction_t t;
-
-    roperm[0].id = 0;
-    roperm[0].perms = XS_PERM_NONE;
-    roperm[1].id = domid;
-    roperm[1].perms = XS_PERM_READ;
-
-    vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/vm", guest_domid));
-
-    i = 0;
-    dmargs_size = 0;
-    while (args[i] != NULL) {
-        dmargs_size = dmargs_size + strlen(args[i]) + 1;
-        i++;
-    }
-    dmargs_size++;
-    dmargs = (char *) malloc(dmargs_size);
-    i = 1;
-    dmargs[0] = '\0';
-    while (args[i] != NULL) {
-        if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) {
-            strcat(dmargs, " ");
-            strcat(dmargs, args[i]);
-        }
-        i++;
-    }
-    path = libxl__sprintf(&gc, "%s/image/dmargs", vm_path);
-
-retry_transaction:
-    t = xs_transaction_start(ctx->xsh);
-    xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
-    xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
-    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm));
-    if (!xs_transaction_end(ctx->xsh, t, 0))
-        if (errno == EAGAIN)
-            goto retry_transaction;
-    free(dmargs);
-    libxl__free_all(&gc);
-    return 0;
-}
-
-static int libxl_create_stubdom(libxl_ctx *ctx,
-                                libxl_device_model_info *info,
-                                libxl_device_disk *disks, int num_disks,
-                                libxl_device_nic *vifs, int num_vifs,
-                                libxl_device_vfb *vfb,
-                                libxl_device_vkb *vkb,
-                                libxl__device_model_starting **starting_r)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    int i, num_console = 1, ret;
-    libxl_device_console *console;
-    libxl_domain_create_info c_info;
-    libxl_domain_build_info b_info;
-    libxl_domain_build_state state;
-    uint32_t domid;
-    char **args;
-    struct xs_permissions perm[2];
-    xs_transaction_t t;
-    libxl__device_model_starting *dm_starting = 0;
-
-    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
-    if (!args) {
-        ret = ERROR_FAIL;
-        goto out;
-    }
-
-    memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
-    c_info.hvm = 0;
-    c_info.name = libxl__sprintf(&gc, "%s-dm", libxl__domid_to_name(&gc, info->domid));
-
-    libxl_uuid_copy(&c_info.uuid, &info->uuid);
-
-    memset(&b_info, 0x00, sizeof(libxl_domain_build_info));
-    b_info.max_vcpus = 1;
-    b_info.max_memkb = 32 * 1024;
-    b_info.target_memkb = b_info.max_memkb;
-    b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
-    b_info.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
-    b_info.pv.ramdisk.path = "";
-    b_info.pv.features = "";
-    b_info.is_hvm = 0;
-
-    ret = libxl__domain_make(ctx, &c_info, &domid);
-    if (ret)
-        goto out_free;
-    ret = libxl__domain_build(ctx, &b_info, domid, &state);
-    if (ret)
-        goto out_free;
-
-    libxl_write_dmargs(ctx, domid, info->domid, args);
-    libxl__xs_write(&gc, XBT_NULL,
-                   libxl__sprintf(&gc, "%s/image/device-model-domid", libxl__xs_get_dompath(&gc, info->domid)),
-                   "%d", domid);
-    libxl__xs_write(&gc, XBT_NULL,
-                   libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)),
-                   "%d", info->domid);
-    ret = xc_domain_set_target(ctx->xch, domid, info->domid);
-    if (ret<0) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting target domain %d -> %d", domid, info->domid);
-        ret = ERROR_FAIL;
-        goto out_free;
-    }
-    xs_set_target(ctx->xsh, domid, info->domid);
-
-    perm[0].id = domid;
-    perm[0].perms = XS_PERM_NONE;
-    perm[1].id = info->domid;
-    perm[1].perms = XS_PERM_READ;
-retry_transaction:
-    t = xs_transaction_start(ctx->xsh);
-    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid));
-    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
-    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs", domid));
-    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
-    if (!xs_transaction_end(ctx->xsh, t, 0))
-        if (errno == EAGAIN)
-            goto retry_transaction;
-
-    for (i = 0; i < num_disks; i++) {
-        disks[i].domid = domid;
-        ret = libxl_device_disk_add(ctx, domid, &disks[i]);
-        if (ret)
-            goto out_free;
-    }
-    for (i = 0; i < num_vifs; i++) {
-        vifs[i].domid = domid;
-        ret = libxl_device_nic_add(ctx, domid, &vifs[i]);
-        if (ret)
-            goto out_free;
-    }
-    vfb->domid = domid;
-    ret = libxl_device_vfb_add(ctx, domid, vfb);
-    if (ret)
-        goto out_free;
-    vkb->domid = domid;
-    ret = libxl_device_vkb_add(ctx, domid, vkb);
-    if (ret)
-        goto out_free;
-
-    if (info->serial)
-        num_console++;
-
-    console = libxl__calloc(&gc, num_console, sizeof(libxl_device_console));
-    if (!console) {
-        ret = ERROR_NOMEM;
-        goto out_free;
-    }
-
-    for (i = 0; i < num_console; i++) {
-        console[i].devid = i;
-        console[i].consback = LIBXL_CONSBACK_IOEMU;
-        console[i].domid = domid;
-        if (!i) {
-            char *filename;
-            char *name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
-            libxl_create_logfile(ctx, name, &filename);
-            console[i].output = libxl__sprintf(&gc, "file:%s", filename);
-            console[i].build_state = &state;
-            free(filename);
-        } else
-            console[i].output = "pty";
-        ret = libxl_device_console_add(ctx, domid, &console[i]);
-        if (ret)
-            goto out_free;
-    }
-    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
-        ret = ERROR_FAIL;
-        goto out_free;
-    }
-    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
-        ret = ERROR_FAIL;
-        goto out_free;
-    }
-
-    libxl_domain_unpause(ctx, domid);
-
-    if (starting_r) {
-        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
-        (*starting_r)->domid = info->domid;
-        (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
-        (*starting_r)->for_spawn = NULL;
-    }
-
-    ret = 0;
-
-out_free:
-    free(args);
-out:
-    libxl__free_all(&gc);
-    return ret;
-}
-
-int libxl__create_device_model(libxl_ctx *ctx,
-                              libxl_device_model_info *info,
-                              libxl_device_disk *disks, int num_disks,
-                              libxl_device_nic *vifs, int num_vifs,
-                              libxl__device_model_starting **starting_r)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char *path, *logfile;
-    int logfile_w, null;
-    int rc;
-    char **args;
-    libxl__device_model_starting buf_starting, *p;
-    xs_transaction_t t; 
-    char *vm_path;
-    char **pass_stuff;
-
-    if (strstr(info->device_model, "stubdom-dm")) {
-        libxl_device_vfb vfb;
-        libxl_device_vkb vkb;
-
-        libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb);
-        rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r);
-        goto out;
-    }
-
-    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
-    if (!args) {
-        rc = ERROR_FAIL;
-        goto out;
-    }
-
-    path = libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid);
-    xs_mkdir(ctx->xsh, XBT_NULL, path);
-    libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci);
-
-    libxl_create_logfile(ctx, libxl__sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile);
-    logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
-    free(logfile);
-    null = open("/dev/null", O_RDONLY);
-
-    if (starting_r) {
-        rc = ERROR_NOMEM;
-        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
-        if (!*starting_r)
-            goto out_close;
-        p = *starting_r;
-        p->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
-    } else {
-        p = &buf_starting;
-        p->for_spawn = NULL;
-    }
-
-    p->domid = info->domid;
-    p->dom_path = libxl__xs_get_dompath(&gc, info->domid);
-    if (!p->dom_path) {
-        rc = ERROR_FAIL;
-        goto out_close;
-    }
-
-    if (info->vncpasswd) {
-retry_transaction:
-        /* Find uuid and the write the vnc password to xenstore for qemu. */
-        t = xs_transaction_start(ctx->xsh);
-        vm_path = libxl__xs_read(&gc,t,libxl__sprintf(&gc, "%s/vm", p->dom_path));
-        if (vm_path) {
-            /* Now write the vncpassword into it. */
-            pass_stuff = libxl__calloc(&gc, 3, sizeof(char *));
-            pass_stuff[0] = "vncpasswd";
-            pass_stuff[1] = info->vncpasswd;
-            libxl__xs_writev(&gc,t,vm_path,pass_stuff);
-            if (!xs_transaction_end(ctx->xsh, t, 0))
-                if (errno == EAGAIN)
-                    goto retry_transaction;
-        }
-    }
-
-    rc = libxl__spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid);
-    if (rc < 0)
-        goto out_close;
-    if (!rc) { /* inner child */
-        libxl__exec(null, logfile_w, logfile_w,
-                   libxl__abs_path(&gc, info->device_model, libxl_libexec_path()),
-                   args);
-    }
-
-    rc = 0;
-
-out_close:
-    close(null);
-    close(logfile_w);
-    free(args);
-out:
-    libxl__free_all(&gc);
-    return rc;
-}
-
-/* DM is detached even if error is returned */
-static int detach_device_model(libxl_ctx *ctx,
-                              libxl__device_model_starting *starting)
-{
-    int rc;
-    rc = libxl__spawn_detach(ctx, starting->for_spawn);
-    if (starting->for_spawn)
-        free(starting->for_spawn);
-    free(starting);
-    return rc;
-}
-
-
-int libxl__confirm_device_model_startup(libxl_ctx *ctx,
-                                       libxl__device_model_starting *starting)
-{
-    int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
-    int detach;
-    if ( !problem )
-        problem = libxl__spawn_check(ctx, starting->for_spawn);
-    detach = detach_device_model(ctx, starting);
-    return problem ? problem : detach;
-}
-
-
 /******************************************************************************/
 
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk)
@@ -2383,80 +1654,6 @@ out:
 }
 
 /******************************************************************************/
-static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
-                                       uint32_t domid,
-                                       libxl_device_vfb *vfb,
-                                       libxl_device_model_info *info)
-{
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-    memset(info, 0x00, sizeof(libxl_device_model_info));
-
-    if (vfb != NULL) {
-        info->vnc = vfb->vnc;
-        if (vfb->vnclisten)
-            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
-        info->vncdisplay = vfb->vncdisplay;
-        info->vncunused = vfb->vncunused;
-        if (vfb->vncpasswd)
-            info->vncpasswd = vfb->vncpasswd;
-        if (vfb->keymap)
-            info->keymap = libxl__strdup(gc, vfb->keymap);
-        info->sdl = vfb->sdl;
-        info->opengl = vfb->opengl;
-    } else
-        info->nographic = 1;
-    info->domid = domid;
-    info->dom_name = libxl_domid_to_name(ctx, domid);
-    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
-    info->type = XENPV;
-    return 0;
-}
-
-int libxl__need_xenpv_qemu(libxl_ctx *ctx,
-        int nr_consoles, libxl_device_console *consoles,
-        int nr_vfbs, libxl_device_vfb *vfbs,
-        int nr_disks, libxl_device_disk *disks)
-{
-    int i, ret = 0;
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-
-    if (nr_consoles > 1) {
-        ret = 1;
-        goto out;
-    }
-
-    for (i = 0; i < nr_consoles; i++) {
-        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
-            ret = 1;
-            goto out;
-        }
-    }
-
-    if (nr_vfbs > 0) {
-        ret = 1;
-        goto out;
-    }
-
-    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
-        ret = 1;
-
-out:
-    libxl__free_all(&gc);
-    return ret;
-}
-
-int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
-                            libxl__device_model_starting **starting_r)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    libxl_device_model_info info;
-
-    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
-    libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
-    libxl__free_all(&gc);
-    return 0;
-}
-
 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
diff -r c6e3c9a8029d -r 2f8749c5e015 tools/libxl/libxl_dm.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_dm.c	Wed Jan 05 12:50:42 2011 +0000
@@ -0,0 +1,831 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+ * Author Gianni Tedesco <gianni.tedesco@citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "libxl.h"
+#include "libxl_utils.h"
+#include "libxl_internal.h"
+#include "flexarray.h"
+
+static char ** libxl_build_device_model_args_old(libxl__gc *gc,
+                                             libxl_device_model_info *info,
+                                             libxl_device_nic *vifs,
+                                             int num_vifs)
+{
+    int num = 0, i;
+    flexarray_t *dm_args;
+    dm_args = flexarray_make(16, 1);
+
+    if (!dm_args)
+        return NULL;
+
+    flexarray_set(dm_args, num++, "qemu-dm");
+    flexarray_set(dm_args, num++, "-d");
+
+    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
+
+    if (info->dom_name) {
+        flexarray_set(dm_args, num++, "-domain-name");
+        flexarray_set(dm_args, num++, info->dom_name);
+    }
+    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
+        flexarray_set(dm_args, num++, "-vnc");
+        if (info->vncdisplay) {
+            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
+                flexarray_set(
+                    dm_args, num++,
+                    libxl__sprintf(gc, "%s:%d%s",
+                                  info->vnclisten,
+                                  info->vncdisplay,
+                                  info->vncpasswd ? ",password" : ""));
+            } else {
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
+            }
+        } else if (info->vnclisten) {
+            if (strchr(info->vnclisten, ':') != NULL) {
+                flexarray_set(dm_args, num++, info->vnclisten);
+            } else {
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%s:0", info->vnclisten));
+            }
+        } else {
+            flexarray_set(dm_args, num++, "127.0.0.1:0");
+        }
+        if (info->vncunused) {
+            flexarray_set(dm_args, num++, "-vncunused");
+        }
+    }
+    if (info->sdl) {
+        flexarray_set(dm_args, num++, "-sdl");
+        if (!info->opengl) {
+            flexarray_set(dm_args, num++, "-disable-opengl");
+        }
+    }
+    if (info->keymap) {
+        flexarray_set(dm_args, num++, "-k");
+        flexarray_set(dm_args, num++, info->keymap);
+    }
+    if (info->nographic && (!info->sdl && !info->vnc)) {
+        flexarray_set(dm_args, num++, "-nographic");
+    }
+    if (info->serial) {
+        flexarray_set(dm_args, num++, "-serial");
+        flexarray_set(dm_args, num++, info->serial);
+    }
+    if (info->type == XENFV) {
+        int ioemu_vifs = 0;
+
+        if (info->videoram) {
+            flexarray_set(dm_args, num++, "-videoram");
+            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->videoram));
+        }
+        if (info->stdvga) {
+            flexarray_set(dm_args, num++, "-std-vga");
+        }
+
+        if (info->boot) {
+            flexarray_set(dm_args, num++, "-boot");
+            flexarray_set(dm_args, num++, info->boot);
+        }
+        if (info->usb || info->usbdevice) {
+            flexarray_set(dm_args, num++, "-usb");
+            if (info->usbdevice) {
+                flexarray_set(dm_args, num++, "-usbdevice");
+                flexarray_set(dm_args, num++, info->usbdevice);
+            }
+        }
+        if (info->soundhw) {
+            flexarray_set(dm_args, num++, "-soundhw");
+            flexarray_set(dm_args, num++, info->soundhw);
+        }
+        if (info->apic) {
+            flexarray_set(dm_args, num++, "-acpi");
+        }
+        if (info->vcpus > 1) {
+            flexarray_set(dm_args, num++, "-vcpus");
+            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
+        }
+        if (info->vcpu_avail) {
+            flexarray_set(dm_args, num++, "-vcpu_avail");
+            flexarray_set(dm_args, num++, libxl__sprintf(gc, "0x%x", info->vcpu_avail));
+        }
+        for (i = 0; i < num_vifs; i++) {
+            if (vifs[i].nictype == NICTYPE_IOEMU) {
+                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
+                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
+                char *ifname;
+                if (!vifs[i].ifname)
+                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
+                else
+                    ifname = vifs[i].ifname;
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
+                            vifs[i].devid, smac, vifs[i].model));
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
+                            vifs[i].devid, ifname, vifs[i].bridge));
+                ioemu_vifs++;
+            }
+        }
+        /* If we have no emulated nics, tell qemu not to create any */
+        if ( ioemu_vifs == 0 ) {
+            flexarray_set(dm_args, num++, "-net");
+            flexarray_set(dm_args, num++, "none");
+        }
+    }
+    if (info->saved_state) {
+        flexarray_set(dm_args, num++, "-loadvm");
+        flexarray_set(dm_args, num++, info->saved_state);
+    }
+    for (i = 0; info->extra && info->extra[i] != NULL; i++)
+        flexarray_set(dm_args, num++, info->extra[i]);
+    flexarray_set(dm_args, num++, "-M");
+    if (info->type == XENPV)
+        flexarray_set(dm_args, num++, "xenpv");
+    else
+        flexarray_set(dm_args, num++, "xenfv");
+    flexarray_set(dm_args, num++, NULL);
+    return (char **) flexarray_contents(dm_args);
+}
+
+static char ** libxl_build_device_model_args_new(libxl__gc *gc,
+                                             libxl_device_model_info *info,
+                                             libxl_device_nic *vifs,
+                                             int num_vifs)
+{
+    int num = 0, i;
+    flexarray_t *dm_args;
+    int nb;
+    libxl_device_disk *disks;
+
+    dm_args = flexarray_make(16, 1);
+    if (!dm_args)
+        return NULL;
+
+    flexarray_set(dm_args, num++, libxl__strdup(gc, info->device_model));
+
+    flexarray_set(dm_args, num++, "-xen-domid");
+    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
+
+    if (info->type == XENPV) {
+        flexarray_set(dm_args, num++, "-xen-attach");
+    }
+
+    if (info->dom_name) {
+        flexarray_set(dm_args, num++, "-name");
+        flexarray_set(dm_args, num++, info->dom_name);
+    }
+    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
+        int display = 0;
+        const char *listen = "127.0.0.1";
+
+        flexarray_set(dm_args, num++, "-vnc");
+
+        if (info->vncdisplay) {
+            display = info->vncdisplay;
+            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
+                listen = info->vnclisten;
+            }
+        } else if (info->vnclisten) {
+            listen = info->vnclisten;
+        }
+
+        if (strchr(listen, ':') != NULL)
+            flexarray_set(dm_args, num++,
+                    libxl__sprintf(gc, "%s%s", listen,
+                        info->vncunused ? ",to=99" : ""));
+        else
+            flexarray_set(dm_args, num++,
+                    libxl__sprintf(gc, "%s:%d%s", listen, display,
+                        info->vncunused ? ",to=99" : ""));
+    }
+    if (info->sdl) {
+        flexarray_set(dm_args, num++, "-sdl");
+    }
+
+    if (info->type == XENPV && !info->nographic) {
+        flexarray_set(dm_args, num++, "-vga");
+        flexarray_set(dm_args, num++, "xenfb");
+    }
+
+    if (info->keymap) {
+        flexarray_set(dm_args, num++, "-k");
+        flexarray_set(dm_args, num++, info->keymap);
+    }
+    if (info->nographic && (!info->sdl && !info->vnc)) {
+        flexarray_set(dm_args, num++, "-nographic");
+    }
+    if (info->serial) {
+        flexarray_set(dm_args, num++, "-serial");
+        flexarray_set(dm_args, num++, info->serial);
+    }
+    if (info->type == XENFV) {
+        int ioemu_vifs = 0;
+
+        if (info->stdvga) {
+                flexarray_set(dm_args, num++, "-vga");
+                flexarray_set(dm_args, num++, "std");
+        }
+
+        if (info->boot) {
+            flexarray_set(dm_args, num++, "-boot");
+            flexarray_set(dm_args, num++, libxl__sprintf(gc, "order=%s", info->boot));
+        }
+        if (info->usb || info->usbdevice) {
+            flexarray_set(dm_args, num++, "-usb");
+            if (info->usbdevice) {
+                flexarray_set(dm_args, num++, "-usbdevice");
+                flexarray_set(dm_args, num++, info->usbdevice);
+            }
+        }
+        if (info->soundhw) {
+            flexarray_set(dm_args, num++, "-soundhw");
+            flexarray_set(dm_args, num++, info->soundhw);
+        }
+        if (!info->apic) {
+            flexarray_set(dm_args, num++, "-no-acpi");
+        }
+        if (info->vcpus > 1) {
+            flexarray_set(dm_args, num++, "-smp");
+            if (info->vcpu_avail)
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
+            else
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
+        }
+        for (i = 0; i < num_vifs; i++) {
+            if (vifs[i].nictype == NICTYPE_IOEMU) {
+                char *smac = libxl__sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+                                           vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2],
+                                           vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
+                char *ifname;
+                if (!vifs[i].ifname) {
+                    ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
+                } else {
+                    ifname = vifs[i].ifname;
+                }
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
+                            vifs[i].devid, smac, vifs[i].model));
+                flexarray_set(dm_args, num++, "-net");
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
+                            vifs[i].devid, ifname));
+                ioemu_vifs++;
+            }
+        }
+        /* If we have no emulated nics, tell qemu not to create any */
+        if ( ioemu_vifs == 0 ) {
+            flexarray_set(dm_args, num++, "-net");
+            flexarray_set(dm_args, num++, "none");
+        }
+    }
+    if (info->saved_state) {
+        flexarray_set(dm_args, num++, "-loadvm");
+        flexarray_set(dm_args, num++, info->saved_state);
+    }
+    for (i = 0; info->extra && info->extra[i] != NULL; i++)
+        flexarray_set(dm_args, num++, info->extra[i]);
+    flexarray_set(dm_args, num++, "-M");
+    if (info->type == XENPV)
+        flexarray_set(dm_args, num++, "xenpv");
+    else
+        flexarray_set(dm_args, num++, "xenfv");
+
+    if (info->type == XENFV) {
+        disks = libxl_device_disk_list(libxl__gc_owner(gc), info->domid, &nb);
+        for (i; i < nb; i++) {
+            if (disks[i].is_cdrom) {
+                flexarray_set(dm_args, num++, "-cdrom");
+                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
+            } else {
+                flexarray_set(dm_args, num++, libxl__sprintf(gc, "-%s", disks[i].virtpath));
+                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
+            }
+            libxl_device_disk_destroy(&disks[i]);
+        }
+    }
+    free(disks);
+    flexarray_set(dm_args, num++, NULL);
+    return (char **) flexarray_contents(dm_args);
+}
+
+static char ** libxl_build_device_model_args(libxl__gc *gc,
+                                             libxl_device_model_info *info,
+                                             libxl_device_nic *vifs,
+                                             int num_vifs)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    int new_qemu;
+
+    new_qemu = libxl_check_device_model_version(ctx, info->device_model);
+
+    if (new_qemu == 1) {
+        return libxl_build_device_model_args_new(gc, info, vifs, num_vifs);
+    } else {
+        return libxl_build_device_model_args_old(gc, info, vifs, num_vifs);
+    }
+}
+
+static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
+{
+    libxl__device_model_starting *starting = for_spawn;
+    struct xs_handle *xsh;
+    char *path = NULL, *pid = NULL;
+    int len;
+
+    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
+        goto out;
+
+    len = asprintf(&pid, "%d", innerchild);
+    if (len < 0)
+        goto out;
+
+    /* we mustn't use the parent's handle in the child */
+    xsh = xs_daemon_open();
+
+    xs_write(xsh, XBT_NULL, path, pid, len);
+
+    xs_daemon_close(xsh);
+out:
+    free(path);
+    free(pid);
+}
+
+static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx,
+                                                    libxl_device_model_info *info,
+                                                    libxl_device_vfb *vfb,
+                                                    libxl_device_vkb *vkb)
+{
+    memset(vfb, 0x00, sizeof(libxl_device_vfb));
+    memset(vkb, 0x00, sizeof(libxl_device_vkb));
+
+    vfb->backend_domid = 0;
+    vfb->devid = 0;
+    vfb->vnc = info->vnc;
+    vfb->vnclisten = info->vnclisten;
+    vfb->vncdisplay = info->vncdisplay;
+    vfb->vncunused = info->vncunused;
+    vfb->vncpasswd = info->vncpasswd;
+    vfb->keymap = info->keymap;
+    vfb->sdl = info->sdl;
+    vfb->opengl = info->opengl;
+
+    vkb->backend_domid = 0;
+    vkb->devid = 0;
+    return 0;
+}
+
+static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char **args)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int i;
+    char *vm_path;
+    char *dmargs, *path;
+    int dmargs_size;
+    struct xs_permissions roperm[2];
+    xs_transaction_t t;
+
+    roperm[0].id = 0;
+    roperm[0].perms = XS_PERM_NONE;
+    roperm[1].id = domid;
+    roperm[1].perms = XS_PERM_READ;
+
+    vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/vm", guest_domid));
+
+    i = 0;
+    dmargs_size = 0;
+    while (args[i] != NULL) {
+        dmargs_size = dmargs_size + strlen(args[i]) + 1;
+        i++;
+    }
+    dmargs_size++;
+    dmargs = (char *) malloc(dmargs_size);
+    i = 1;
+    dmargs[0] = '\0';
+    while (args[i] != NULL) {
+        if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) {
+            strcat(dmargs, " ");
+            strcat(dmargs, args[i]);
+        }
+        i++;
+    }
+    path = libxl__sprintf(&gc, "%s/image/dmargs", vm_path);
+
+retry_transaction:
+    t = xs_transaction_start(ctx->xsh);
+    xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
+    xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
+    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm));
+    if (!xs_transaction_end(ctx->xsh, t, 0))
+        if (errno == EAGAIN)
+            goto retry_transaction;
+    free(dmargs);
+    libxl__free_all(&gc);
+    return 0;
+}
+
+static int libxl_create_stubdom(libxl_ctx *ctx,
+                                libxl_device_model_info *info,
+                                libxl_device_disk *disks, int num_disks,
+                                libxl_device_nic *vifs, int num_vifs,
+                                libxl_device_vfb *vfb,
+                                libxl_device_vkb *vkb,
+                                libxl__device_model_starting **starting_r)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int i, num_console = 1, ret;
+    libxl_device_console *console;
+    libxl_domain_create_info c_info;
+    libxl_domain_build_info b_info;
+    libxl_domain_build_state state;
+    uint32_t domid;
+    char **args;
+    struct xs_permissions perm[2];
+    xs_transaction_t t;
+    libxl__device_model_starting *dm_starting = 0;
+
+    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
+    if (!args) {
+        ret = ERROR_FAIL;
+        goto out;
+    }
+
+    memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
+    c_info.hvm = 0;
+    c_info.name = libxl__sprintf(&gc, "%s-dm", libxl__domid_to_name(&gc, info->domid));
+
+    libxl_uuid_copy(&c_info.uuid, &info->uuid);
+
+    memset(&b_info, 0x00, sizeof(libxl_domain_build_info));
+    b_info.max_vcpus = 1;
+    b_info.max_memkb = 32 * 1024;
+    b_info.target_memkb = b_info.max_memkb;
+    b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
+    b_info.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
+    b_info.pv.ramdisk.path = "";
+    b_info.pv.features = "";
+    b_info.is_hvm = 0;
+
+    ret = libxl__domain_make(ctx, &c_info, &domid);
+    if (ret)
+        goto out_free;
+    ret = libxl__domain_build(ctx, &b_info, domid, &state);
+    if (ret)
+        goto out_free;
+
+    libxl_write_dmargs(ctx, domid, info->domid, args);
+    libxl__xs_write(&gc, XBT_NULL,
+                   libxl__sprintf(&gc, "%s/image/device-model-domid", libxl__xs_get_dompath(&gc, info->domid)),
+                   "%d", domid);
+    libxl__xs_write(&gc, XBT_NULL,
+                   libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)),
+                   "%d", info->domid);
+    ret = xc_domain_set_target(ctx->xch, domid, info->domid);
+    if (ret<0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting target domain %d -> %d", domid, info->domid);
+        ret = ERROR_FAIL;
+        goto out_free;
+    }
+    xs_set_target(ctx->xsh, domid, info->domid);
+
+    perm[0].id = domid;
+    perm[0].perms = XS_PERM_NONE;
+    perm[1].id = info->domid;
+    perm[1].perms = XS_PERM_READ;
+retry_transaction:
+    t = xs_transaction_start(ctx->xsh);
+    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid));
+    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
+    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs", domid));
+    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
+    if (!xs_transaction_end(ctx->xsh, t, 0))
+        if (errno == EAGAIN)
+            goto retry_transaction;
+
+    for (i = 0; i < num_disks; i++) {
+        disks[i].domid = domid;
+        ret = libxl_device_disk_add(ctx, domid, &disks[i]);
+        if (ret)
+            goto out_free;
+    }
+    for (i = 0; i < num_vifs; i++) {
+        vifs[i].domid = domid;
+        ret = libxl_device_nic_add(ctx, domid, &vifs[i]);
+        if (ret)
+            goto out_free;
+    }
+    vfb->domid = domid;
+    ret = libxl_device_vfb_add(ctx, domid, vfb);
+    if (ret)
+        goto out_free;
+    vkb->domid = domid;
+    ret = libxl_device_vkb_add(ctx, domid, vkb);
+    if (ret)
+        goto out_free;
+
+    if (info->serial)
+        num_console++;
+
+    console = libxl__calloc(&gc, num_console, sizeof(libxl_device_console));
+    if (!console) {
+        ret = ERROR_NOMEM;
+        goto out_free;
+    }
+
+    for (i = 0; i < num_console; i++) {
+        console[i].devid = i;
+        console[i].consback = LIBXL_CONSBACK_IOEMU;
+        console[i].domid = domid;
+        if (!i) {
+            char *filename;
+            char *name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
+            libxl_create_logfile(ctx, name, &filename);
+            console[i].output = libxl__sprintf(&gc, "file:%s", filename);
+            console[i].build_state = &state;
+            free(filename);
+        } else
+            console[i].output = "pty";
+        ret = libxl_device_console_add(ctx, domid, &console[i]);
+        if (ret)
+            goto out_free;
+    }
+    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
+        ret = ERROR_FAIL;
+        goto out_free;
+    }
+    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
+        ret = ERROR_FAIL;
+        goto out_free;
+    }
+
+    libxl_domain_unpause(ctx, domid);
+
+    if (starting_r) {
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
+        (*starting_r)->domid = info->domid;
+        (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
+        (*starting_r)->for_spawn = NULL;
+    }
+
+    ret = 0;
+
+out_free:
+    free(args);
+out:
+    libxl__free_all(&gc);
+    return ret;
+}
+
+int libxl__create_device_model(libxl_ctx *ctx,
+                              libxl_device_model_info *info,
+                              libxl_device_disk *disks, int num_disks,
+                              libxl_device_nic *vifs, int num_vifs,
+                              libxl__device_model_starting **starting_r)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char *path, *logfile;
+    int logfile_w, null;
+    int rc;
+    char **args;
+    libxl__device_model_starting buf_starting, *p;
+    xs_transaction_t t; 
+    char *vm_path;
+    char **pass_stuff;
+
+    if (strstr(info->device_model, "stubdom-dm")) {
+        libxl_device_vfb vfb;
+        libxl_device_vkb vkb;
+
+        libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb);
+        rc = libxl_create_stubdom(ctx, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r);
+        goto out;
+    }
+
+    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
+    if (!args) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    path = libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid);
+    xs_mkdir(ctx->xsh, XBT_NULL, path);
+    libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/disable_pf", path), "%d", !info->xen_platform_pci);
+
+    libxl_create_logfile(ctx, libxl__sprintf(&gc, "qemu-dm-%s", info->dom_name), &logfile);
+    logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
+    free(logfile);
+    null = open("/dev/null", O_RDONLY);
+
+    if (starting_r) {
+        rc = ERROR_NOMEM;
+        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
+        if (!*starting_r)
+            goto out_close;
+        p = *starting_r;
+        p->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
+    } else {
+        p = &buf_starting;
+        p->for_spawn = NULL;
+    }
+
+    p->domid = info->domid;
+    p->dom_path = libxl__xs_get_dompath(&gc, info->domid);
+    if (!p->dom_path) {
+        rc = ERROR_FAIL;
+        goto out_close;
+    }
+
+    if (info->vncpasswd) {
+retry_transaction:
+        /* Find uuid and the write the vnc password to xenstore for qemu. */
+        t = xs_transaction_start(ctx->xsh);
+        vm_path = libxl__xs_read(&gc,t,libxl__sprintf(&gc, "%s/vm", p->dom_path));
+        if (vm_path) {
+            /* Now write the vncpassword into it. */
+            pass_stuff = libxl__calloc(&gc, 3, sizeof(char *));
+            pass_stuff[0] = "vncpasswd";
+            pass_stuff[1] = info->vncpasswd;
+            libxl__xs_writev(&gc,t,vm_path,pass_stuff);
+            if (!xs_transaction_end(ctx->xsh, t, 0))
+                if (errno == EAGAIN)
+                    goto retry_transaction;
+        }
+    }
+
+    rc = libxl__spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid);
+    if (rc < 0)
+        goto out_close;
+    if (!rc) { /* inner child */
+        libxl__exec(null, logfile_w, logfile_w,
+                   libxl__abs_path(&gc, info->device_model, libxl_libexec_path()),
+                   args);
+    }
+
+    rc = 0;
+
+out_close:
+    close(null);
+    close(logfile_w);
+    free(args);
+out:
+    libxl__free_all(&gc);
+    return rc;
+}
+
+/* DM is detached even if error is returned */
+static int detach_device_model(libxl_ctx *ctx,
+                              libxl__device_model_starting *starting)
+{
+    int rc;
+    rc = libxl__spawn_detach(ctx, starting->for_spawn);
+    if (starting->for_spawn)
+        free(starting->for_spawn);
+    free(starting);
+    return rc;
+}
+
+
+int libxl__confirm_device_model_startup(libxl_ctx *ctx,
+                                       libxl__device_model_starting *starting)
+{
+    int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
+    int detach;
+    if ( !problem )
+        problem = libxl__spawn_check(ctx, starting->for_spawn);
+    detach = detach_device_model(ctx, starting);
+    return problem ? problem : detach;
+}
+
+static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
+                                       uint32_t domid,
+                                       libxl_device_vfb *vfb,
+                                       libxl_device_model_info *info)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    memset(info, 0x00, sizeof(libxl_device_model_info));
+
+    if (vfb != NULL) {
+        info->vnc = vfb->vnc;
+        if (vfb->vnclisten)
+            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
+        info->vncdisplay = vfb->vncdisplay;
+        info->vncunused = vfb->vncunused;
+        if (vfb->vncpasswd)
+            info->vncpasswd = vfb->vncpasswd;
+        if (vfb->keymap)
+            info->keymap = libxl__strdup(gc, vfb->keymap);
+        info->sdl = vfb->sdl;
+        info->opengl = vfb->opengl;
+    } else
+        info->nographic = 1;
+    info->domid = domid;
+    info->dom_name = libxl_domid_to_name(ctx, domid);
+    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
+    info->type = XENPV;
+    return 0;
+}
+
+int libxl__need_xenpv_qemu(libxl_ctx *ctx,
+        int nr_consoles, libxl_device_console *consoles,
+        int nr_vfbs, libxl_device_vfb *vfbs,
+        int nr_disks, libxl_device_disk *disks)
+{
+    int i, ret = 0;
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+
+    if (nr_consoles > 1) {
+        ret = 1;
+        goto out;
+    }
+
+    for (i = 0; i < nr_consoles; i++) {
+        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
+            ret = 1;
+            goto out;
+        }
+    }
+
+    if (nr_vfbs > 0) {
+        ret = 1;
+        goto out;
+    }
+
+    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
+        ret = 1;
+
+out:
+    libxl__free_all(&gc);
+    return ret;
+}
+
+int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
+                            libxl__device_model_starting **starting_r)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    libxl_device_model_info info;
+
+    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
+    libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
+    libxl__free_all(&gc);
+    return 0;
+}
+
+int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char *pid;
+    int ret;
+
+    pid = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid));
+    if (!pid) {
+        int stubdomid = libxl_get_stubdom_id(ctx, domid);
+        if (!stubdomid) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't find device model's pid");
+            ret = ERROR_INVAL;
+            goto out;
+        }
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device model is a stubdom, domid=%d\n", stubdomid);
+        ret = libxl_domain_destroy(ctx, stubdomid, 0);
+        if (ret)
+            goto out;
+    } else {
+        ret = kill(atoi(pid), SIGHUP);
+        if (ret < 0 && errno == ESRCH) {
+            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model already exited");
+            ret = 0;
+        } else if (ret == 0) {
+            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model signaled");
+            ret = 0;
+        } else {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to kill Device Model [%d]",
+                    atoi(pid));
+            ret = ERROR_FAIL;
+            goto out;
+        }
+    }
+    xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", domid));
+
+out:
+    libxl__free_all(&gc);
+    return ret;
+}
+
diff -r c6e3c9a8029d -r 2f8749c5e015 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Wed Jan 05 12:50:11 2011 +0000
+++ b/tools/libxl/libxl_internal.h	Wed Jan 05 12:50:42 2011 +0000
@@ -227,6 +227,8 @@ _hidden int libxl__spawn_spawn(libxl_ctx
                       libxl__device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn, pid_t innerchild));
+_hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid);
+
   /* Logs errors.  A copy of "what" is taken.  Return values:
    *  < 0   error, for_spawn need not be detached
    *   +1   caller is the parent, must call detach on *for_spawn eventually

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend()
  2011-01-05 13:41 [PATCH 0 of 4] Refactor libxl domain creation, v2 Gianni Tedesco
                   ` (2 preceding siblings ...)
  2011-01-05 13:41 ` [PATCH 3 of 4] xl: Move device model functions in to a separate file Gianni Tedesco
@ 2011-01-05 13:41 ` Gianni Tedesco
  2011-01-07 13:37   ` Gianni Tedesco
  3 siblings, 1 reply; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-05 13:41 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/flexarray.c |   24 +++
 tools/libxl/flexarray.h |    3 +
 tools/libxl/libxl.c     |  341 ++++++++++++++++++++++-------------------------
 tools/libxl/libxl_dm.c  |  180 ++++++++++--------------
 tools/libxl/libxl_pci.c |   73 +++------
 5 files changed, 292 insertions(+), 329 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294231910 0
# Node ID 3feb91094abba05f5fd735717de7316101ea6c27
# Parent  2f8749c5e015463317f4c81e71d23be52bec4e06
xl: Implement flexarray_append() and flexarray_vappend()

Makes a lot of code simpler and nice and saves a fair amount of screen
real-estate

Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>

diff -r 2f8749c5e015 -r 3feb91094abb tools/libxl/flexarray.c
--- a/tools/libxl/flexarray.c	Wed Jan 05 12:50:42 2011 +0000
+++ b/tools/libxl/flexarray.c	Wed Jan 05 12:51:50 2011 +0000
@@ -14,6 +14,7 @@
  */
 
 #include "libxl_internal.h"
+#include <stdarg.h>
 
 flexarray_t *flexarray_make(int size, int autogrow)
 {
@@ -21,6 +22,7 @@ flexarray_t *flexarray_make(int size, in
     if (array) {
         array->size = size;
         array->autogrow = autogrow;
+        array->count = 0;
         array->data = calloc(size, sizeof(void *));
     }
     return array;
@@ -56,10 +58,32 @@ int flexarray_set(flexarray_t *array, un
         if (flexarray_grow(array, newsize - array->size))
             return 2;
     }
+    if ( index + 1 > array->count )
+        array->count = index + 1;
     array->data[index] = ptr;
     return 0;
 }
 
+int flexarray_append(flexarray_t *array, void *ptr)
+{
+    return flexarray_set(array, array->count, ptr);
+}
+
+int flexarray_vappend(flexarray_t *array, ...)
+{
+    va_list va;
+    void *ptr;
+    int ret;
+
+    va_start(va, array);
+    for(ret = 0; (ptr = va_arg(va, void *)); ret++) {
+        if ( flexarray_append(array, ptr) )
+            break;
+    }
+    va_end(va);
+    return ret;
+}
+
 int flexarray_get(flexarray_t *array, int index, void **ptr)
 {
     if (index >= array->size)
diff -r 2f8749c5e015 -r 3feb91094abb tools/libxl/flexarray.h
--- a/tools/libxl/flexarray.h	Wed Jan 05 12:50:42 2011 +0000
+++ b/tools/libxl/flexarray.h	Wed Jan 05 12:51:50 2011 +0000
@@ -19,6 +19,7 @@
 typedef struct flexarray {
     int size;
     int autogrow;
+    unsigned int count;
     void **data; /* array of pointer */
 } flexarray_t;
 
@@ -26,6 +27,8 @@ _hidden flexarray_t *flexarray_make(int 
 _hidden void flexarray_free(flexarray_t *array);
 _hidden int flexarray_grow(flexarray_t *array, int extents);
 _hidden int flexarray_set(flexarray_t *array, unsigned int index, void *ptr);
+_hidden int flexarray_append(flexarray_t *array, void *ptr);
+_hidden int flexarray_vappend(flexarray_t *array, ...);
 _hidden int flexarray_get(flexarray_t *array, int index, void **ptr);
 
 _hidden void **flexarray_contents(flexarray_t *array);
diff -r 2f8749c5e015 -r 3feb91094abb tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Wed Jan 05 12:50:42 2011 +0000
+++ b/tools/libxl/libxl.c	Wed Jan 05 12:51:50 2011 +0000
@@ -868,11 +868,11 @@ int libxl_device_disk_add(libxl_ctx *ctx
         case PHYSTYPE_PHY: {
 
             libxl__device_physdisk_major_minor(disk->physpath, &major, &minor);
-            flexarray_set(back, boffset++, "physical-device");
-            flexarray_set(back, boffset++, libxl__sprintf(&gc, "%x:%x", major, minor));
-
-            flexarray_set(back, boffset++, "params");
-            flexarray_set(back, boffset++, disk->physpath);
+            flexarray_append(back, "physical-device");
+            flexarray_append(back, libxl__sprintf(&gc, "%x:%x", major, minor));
+
+            flexarray_append(back, "params");
+            flexarray_append(back, disk->physpath);
 
             device.backend_kind = DEVICE_VBD;
             break;
@@ -891,20 +891,20 @@ int libxl_device_disk_add(libxl_ctx *ctx
                     rc = ERROR_FAIL;
                     goto out_free;
                 }
-                flexarray_set(back, boffset++, "tapdisk-params");
-                flexarray_set(back, boffset++, libxl__sprintf(&gc, "%s:%s", libxl__device_disk_string_of_phystype(disk->phystype), disk->physpath));
-                flexarray_set(back, boffset++, "params");
-                flexarray_set(back, boffset++, libxl__strdup(&gc, dev));
+                flexarray_append(back, "tapdisk-params");
+                flexarray_append(back, libxl__sprintf(&gc, "%s:%s", libxl__device_disk_string_of_phystype(disk->phystype), disk->physpath));
+                flexarray_append(back, "params");
+                flexarray_append(back, libxl__strdup(&gc, dev));
                 backend_type = "phy";
                 libxl__device_physdisk_major_minor(dev, &major, &minor);
-                flexarray_set(back, boffset++, "physical-device");
-                flexarray_set(back, boffset++, libxl__sprintf(&gc, "%x:%x", major, minor));
+                flexarray_append(back, "physical-device");
+                flexarray_append(back, libxl__sprintf(&gc, "%x:%x", major, minor));
                 device.backend_kind = DEVICE_VBD;
 
                 break;
             }
-            flexarray_set(back, boffset++, "params");
-            flexarray_set(back, boffset++, libxl__sprintf(&gc, "%s:%s",
+            flexarray_append(back, "params");
+            flexarray_append(back, libxl__sprintf(&gc, "%s:%s",
                           libxl__device_disk_string_of_phystype(disk->phystype), disk->physpath));
 
             if (libxl__blktap_enabled(&gc))
@@ -919,35 +919,35 @@ int libxl_device_disk_add(libxl_ctx *ctx
             goto out_free;
     }
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", disk->domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "removable");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 0));
-    flexarray_set(back, boffset++, "bootable");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "dev");
-    flexarray_set(back, boffset++, disk->virtpath);
-    flexarray_set(back, boffset++, "type");
-    flexarray_set(back, boffset++, backend_type);
-    flexarray_set(back, boffset++, "mode");
-    flexarray_set(back, boffset++, disk->readwrite ? "w" : "r");
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", disk->backend_domid));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(front, foffset++, "virtual-device");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", devid));
-    flexarray_set(front, foffset++, "device-type");
-    flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk");
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", disk->domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "removable");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", (disk->unpluggable) ? 1 : 0));
+    flexarray_append(back, "bootable");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "dev");
+    flexarray_append(back, disk->virtpath);
+    flexarray_append(back, "type");
+    flexarray_append(back, backend_type);
+    flexarray_append(back, "mode");
+    flexarray_append(back, disk->readwrite ? "w" : "r");
+
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", disk->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(front, "virtual-device");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", devid));
+    flexarray_append(front, "device-type");
+    flexarray_append(front, disk->is_cdrom ? "cdrom" : "disk");
 
     if (0 /* protocol != native*/) {
-        flexarray_set(front, foffset++, "protocol");
-        flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */
+        flexarray_append(front, "protocol");
+        flexarray_append(front, "x86_32-abi"); /* hardcoded ! */
     }
 
     libxl__device_generic_add(ctx, &device,
@@ -1068,36 +1068,36 @@ int libxl_device_nic_add(libxl_ctx *ctx,
     device.domid = nic->domid;
     device.kind = DEVICE_VIF;
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", nic->domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "script");
-    flexarray_set(back, boffset++, nic->script);
-    flexarray_set(back, boffset++, "mac");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", nic->domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "script");
+    flexarray_append(back, nic->script);
+    flexarray_append(back, "mac");
+    flexarray_append(back, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                  nic->mac[0], nic->mac[1], nic->mac[2],
                                                  nic->mac[3], nic->mac[4], nic->mac[5]));
-    flexarray_set(back, boffset++, "bridge");
-    flexarray_set(back, boffset++, libxl__strdup(&gc, nic->bridge));
-    flexarray_set(back, boffset++, "handle");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", nic->devid));
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", nic->backend_domid));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(front, foffset++, "handle");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", nic->devid));
-    flexarray_set(front, foffset++, "mac");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(back, "bridge");
+    flexarray_append(back, libxl__strdup(&gc, nic->bridge));
+    flexarray_append(back, "handle");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", nic->devid));
+
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", nic->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(front, "handle");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", nic->devid));
+    flexarray_append(front, "mac");
+    flexarray_append(front, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                   nic->mac[0], nic->mac[1], nic->mac[2],
                                                   nic->mac[3], nic->mac[4], nic->mac[5]));
     if (0 /* protocol != native*/) {
-        flexarray_set(front, foffset++, "protocol");
-        flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */
+        flexarray_append(front, "protocol");
+        flexarray_append(front, "x86_32-abi"); /* hardcoded ! */
     }
 
     libxl__device_generic_add(ctx, &device,
@@ -1229,61 +1229,61 @@ int libxl_device_net2_add(libxl_ctx *ctx
     device.domid = net2->domid;
     device.kind = DEVICE_VIF2;
 
-    flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, dom);
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", net2->domid));
-
-    flexarray_set(back, boffset++, "local-trusted");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", net2->back_trusted));
-    flexarray_set(back, boffset++, "mac");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(back, "domain");
+    flexarray_append(back, dom);
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", net2->domid));
+
+    flexarray_append(back, "local-trusted");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", net2->back_trusted));
+    flexarray_append(back, "mac");
+    flexarray_append(back, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                  net2->back_mac[0], net2->back_mac[1],
                                                  net2->back_mac[2], net2->back_mac[3],
                                                  net2->back_mac[4], net2->back_mac[5]));
 
-    flexarray_set(back, boffset++, "remote-trusted");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", net2->trusted));
-    flexarray_set(back, boffset++, "remote-mac");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(back, "remote-trusted");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", net2->trusted));
+    flexarray_append(back, "remote-mac");
+    flexarray_append(back, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                  net2->front_mac[0], net2->front_mac[1],
                                                  net2->front_mac[2], net2->front_mac[3],
                                                  net2->front_mac[4], net2->front_mac[5]));
 
-    flexarray_set(back, boffset++, "max-bypasses");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", net2->max_bypasses));
-    flexarray_set(back, boffset++, "filter-mac");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", !!(net2->filter_mac)));
-    flexarray_set(back, boffset++, "handle");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", net2->devid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, "1");
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", net2->backend_domid));
-
-    flexarray_set(front, foffset++, "local-trusted");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", net2->trusted));
-    flexarray_set(front, foffset++, "mac");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(back, "max-bypasses");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", net2->max_bypasses));
+    flexarray_append(back, "filter-mac");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", !!(net2->filter_mac)));
+    flexarray_append(back, "handle");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", net2->devid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, "1");
+
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", net2->backend_domid));
+
+    flexarray_append(front, "local-trusted");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", net2->trusted));
+    flexarray_append(front, "mac");
+    flexarray_append(front, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                   net2->front_mac[0], net2->front_mac[1],
                                                   net2->front_mac[2], net2->front_mac[3],
                                                   net2->front_mac[4], net2->front_mac[5]));
 
-    flexarray_set(front, foffset++, "remote-trusted");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", net2->back_trusted));
-    flexarray_set(front, foffset++, "remote-mac");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_append(front, "remote-trusted");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", net2->back_trusted));
+    flexarray_append(front, "remote-mac");
+    flexarray_append(front, libxl__sprintf(&gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                                   net2->back_mac[0], net2->back_mac[1],
                                                   net2->back_mac[2], net2->back_mac[3],
                                                   net2->back_mac[4], net2->back_mac[5]));
 
-    flexarray_set(front, foffset++, "filter-mac");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", !!(net2->filter_mac)));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, "1");
+    flexarray_append(front, "filter-mac");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", !!(net2->filter_mac)));
+    flexarray_append(front, "state");
+    flexarray_append(front, "1");
 
     libxl__device_generic_add(ctx, &device,
                              libxl__xs_kvs_of_flexarray(&gc, back, boffset),
@@ -1404,43 +1404,43 @@ int libxl_device_console_add(libxl_ctx *
     device.domid = console->domid;
     device.kind = DEVICE_CONSOLE;
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", console->domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl__domid_to_name(&gc, domid));
-    flexarray_set(back, boffset++, "protocol");
-    flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL);
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", console->backend_domid));
-    flexarray_set(front, foffset++, "limit");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT));
-    flexarray_set(front, foffset++, "type");
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", console->domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "domain");
+    flexarray_append(back, libxl__domid_to_name(&gc, domid));
+    flexarray_append(back, "protocol");
+    flexarray_append(back, LIBXL_XENCONSOLE_PROTOCOL);
+
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", console->backend_domid));
+    flexarray_append(front, "limit");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT));
+    flexarray_append(front, "type");
     if (console->consback == LIBXL_CONSBACK_XENCONSOLED)
-        flexarray_set(front, foffset++, "xenconsoled");
+        flexarray_append(front, "xenconsoled");
     else
-        flexarray_set(front, foffset++, "ioemu");
-    flexarray_set(front, foffset++, "output");
-    flexarray_set(front, foffset++, console->output);
+        flexarray_append(front, "ioemu");
+    flexarray_append(front, "output");
+    flexarray_append(front, console->output);
 
     if (device.devid == 0) {
         if (console->build_state == NULL) {
             rc = ERROR_INVAL;
             goto out_free;
         }
-        flexarray_set(front, foffset++, "port");
-        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%"PRIu32, console->build_state->console_port));
-        flexarray_set(front, foffset++, "ring-ref");
-        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%lu", console->build_state->console_mfn));
+        flexarray_append(front, "port");
+        flexarray_append(front, libxl__sprintf(&gc, "%"PRIu32, console->build_state->console_port));
+        flexarray_append(front, "ring-ref");
+        flexarray_append(front, libxl__sprintf(&gc, "%lu", console->build_state->console_mfn));
     } else {
-        flexarray_set(front, foffset++, "state");
-        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
-        flexarray_set(front, foffset++, "protocol");
-        flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL);
+        flexarray_append(front, "state");
+        flexarray_append(front, libxl__sprintf(&gc, "%d", 1));
+        flexarray_append(front, "protocol");
+        flexarray_append(front, LIBXL_XENCONSOLE_PROTOCOL);
     }
 
     libxl__device_generic_add(ctx, &device,
@@ -1484,19 +1484,19 @@ int libxl_device_vkb_add(libxl_ctx *ctx,
     device.domid = vkb->domid;
     device.kind = DEVICE_VKBD;
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vkb->domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl__domid_to_name(&gc, domid));
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", vkb->backend_domid));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", vkb->domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(&gc, "%d", 1));
+    flexarray_append(back, "domain");
+    flexarray_append(back, libxl__domid_to_name(&gc, domid));
+
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", vkb->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, libxl__sprintf(&gc, "%d", 1));
 
     libxl__device_generic_add(ctx, &device,
                              libxl__xs_kvs_of_flexarray(&gc, back, boffset),
@@ -1659,8 +1659,6 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
-    unsigned int boffset = 0;
-    unsigned int foffset = 0;
     libxl__device device;
     int rc;
 
@@ -1682,45 +1680,30 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
     device.domid = vfb->domid;
     device.kind = DEVICE_VFB;
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", 1));
-    flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl__domid_to_name(&gc, domid));
-    flexarray_set(back, boffset++, "vnc");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->vnc));
-    flexarray_set(back, boffset++, "vnclisten");
-    flexarray_set(back, boffset++, vfb->vnclisten);
-    flexarray_set(back, boffset++, "vncpasswd");
-    flexarray_set(back, boffset++, vfb->vncpasswd);
-    flexarray_set(back, boffset++, "vncdisplay");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->vncdisplay));
-    flexarray_set(back, boffset++, "vncunused");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->vncunused));
-    flexarray_set(back, boffset++, "sdl");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->sdl));
-    flexarray_set(back, boffset++, "opengl");
-    flexarray_set(back, boffset++, libxl__sprintf(&gc, "%d", vfb->opengl));
+    flexarray_vappend(back, "frontend-id", libxl__sprintf(&gc, "%d", vfb->domid), NULL);
+    flexarray_vappend(back, "online", "1", NULL);
+    flexarray_vappend(back, "state", libxl__sprintf(&gc, "%d", 1), NULL);
+    flexarray_vappend(back, "domain", libxl__domid_to_name(&gc, domid), NULL);
+    flexarray_vappend(back, "vnc", libxl__sprintf(&gc, "%d", vfb->vnc), NULL);
+    flexarray_vappend(back, "vnclisten", vfb->vnclisten, NULL);
+    flexarray_vappend(back, "vncpasswd", vfb->vncpasswd, NULL);
+    flexarray_vappend(back, "vncdisplay", libxl__sprintf(&gc, "%d", vfb->vncdisplay), NULL);
+    flexarray_vappend(back, "vncunused", libxl__sprintf(&gc, "%d", vfb->vncunused), NULL);
+    flexarray_vappend(back, "sdl", libxl__sprintf(&gc, "%d", vfb->sdl), NULL);
+    flexarray_vappend(back, "opengl", libxl__sprintf(&gc, "%d", vfb->opengl), NULL);
     if (vfb->xauthority) {
-        flexarray_set(back, boffset++, "xauthority");
-        flexarray_set(back, boffset++, vfb->xauthority);
+        flexarray_vappend(back, "xauthority", vfb->xauthority, NULL);
     }
     if (vfb->display) {
-        flexarray_set(back, boffset++, "display");
-        flexarray_set(back, boffset++, vfb->display);
+        flexarray_vappend(back, "display", vfb->display, NULL);
     }
 
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", vfb->backend_domid));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
+    flexarray_vappend(front, "backend-id", libxl__sprintf(&gc, "%d", vfb->backend_domid), NULL);
+    flexarray_vappend(front, "state", libxl__sprintf(&gc, "%d", 1), NULL);
 
     libxl__device_generic_add(ctx, &device,
-                             libxl__xs_kvs_of_flexarray(&gc, back, boffset),
-                             libxl__xs_kvs_of_flexarray(&gc, front, foffset));
+                             libxl__xs_kvs_of_flexarray(&gc, back, back->count),
+                             libxl__xs_kvs_of_flexarray(&gc, front, front->count));
     rc = 0;
 out_free:
     flexarray_free(front);
diff -r 2f8749c5e015 -r 3feb91094abb tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c	Wed Jan 05 12:50:42 2011 +0000
+++ b/tools/libxl/libxl_dm.c	Wed Jan 05 12:51:50 2011 +0000
@@ -32,101 +32,88 @@ static char ** libxl_build_device_model_
                                              libxl_device_nic *vifs,
                                              int num_vifs)
 {
-    int num = 0, i;
+    int i;
     flexarray_t *dm_args;
     dm_args = flexarray_make(16, 1);
 
     if (!dm_args)
         return NULL;
 
-    flexarray_set(dm_args, num++, "qemu-dm");
-    flexarray_set(dm_args, num++, "-d");
+    flexarray_vappend(dm_args, "qemu-dm", "-d", libxl__sprintf(gc, "%d", info->domid), NULL);
 
-    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
+    if (info->dom_name)
+        flexarray_vappend(dm_args, "-domain-name", info->dom_name, NULL);
 
-    if (info->dom_name) {
-        flexarray_set(dm_args, num++, "-domain-name");
-        flexarray_set(dm_args, num++, info->dom_name);
-    }
     if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
-        flexarray_set(dm_args, num++, "-vnc");
+        flexarray_append(dm_args, "-vnc");
         if (info->vncdisplay) {
             if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
-                flexarray_set(
-                    dm_args, num++,
+                flexarray_append(dm_args, 
                     libxl__sprintf(gc, "%s:%d%s",
                                   info->vnclisten,
                                   info->vncdisplay,
                                   info->vncpasswd ? ",password" : ""));
             } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
+                flexarray_append(dm_args, libxl__sprintf(gc, "127.0.0.1:%d", info->vncdisplay));
             }
         } else if (info->vnclisten) {
             if (strchr(info->vnclisten, ':') != NULL) {
-                flexarray_set(dm_args, num++, info->vnclisten);
+                flexarray_append(dm_args, info->vnclisten);
             } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%s:0", info->vnclisten));
+                flexarray_append(dm_args, libxl__sprintf(gc, "%s:0", info->vnclisten));
             }
         } else {
-            flexarray_set(dm_args, num++, "127.0.0.1:0");
+            flexarray_append(dm_args, "127.0.0.1:0");
         }
         if (info->vncunused) {
-            flexarray_set(dm_args, num++, "-vncunused");
+            flexarray_append(dm_args, "-vncunused");
         }
     }
     if (info->sdl) {
-        flexarray_set(dm_args, num++, "-sdl");
+        flexarray_append(dm_args, "-sdl");
         if (!info->opengl) {
-            flexarray_set(dm_args, num++, "-disable-opengl");
+            flexarray_append(dm_args, "-disable-opengl");
         }
     }
     if (info->keymap) {
-        flexarray_set(dm_args, num++, "-k");
-        flexarray_set(dm_args, num++, info->keymap);
+        flexarray_vappend(dm_args, "-k", info->keymap, NULL);
     }
     if (info->nographic && (!info->sdl && !info->vnc)) {
-        flexarray_set(dm_args, num++, "-nographic");
+        flexarray_append(dm_args, "-nographic");
     }
     if (info->serial) {
-        flexarray_set(dm_args, num++, "-serial");
-        flexarray_set(dm_args, num++, info->serial);
+        flexarray_vappend(dm_args, "-serial", info->serial, NULL);
     }
     if (info->type == XENFV) {
         int ioemu_vifs = 0;
 
         if (info->videoram) {
-            flexarray_set(dm_args, num++, "-videoram");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->videoram));
+            flexarray_vappend(dm_args, "-videoram", libxl__sprintf(gc, "%d", info->videoram), NULL);
         }
         if (info->stdvga) {
-            flexarray_set(dm_args, num++, "-std-vga");
+            flexarray_append(dm_args, "-std-vga");
         }
 
         if (info->boot) {
-            flexarray_set(dm_args, num++, "-boot");
-            flexarray_set(dm_args, num++, info->boot);
+            flexarray_vappend(dm_args, "-boot", info->boot, NULL);
         }
         if (info->usb || info->usbdevice) {
-            flexarray_set(dm_args, num++, "-usb");
+            flexarray_append(dm_args, "-usb");
             if (info->usbdevice) {
-                flexarray_set(dm_args, num++, "-usbdevice");
-                flexarray_set(dm_args, num++, info->usbdevice);
+                flexarray_vappend(dm_args, "-usbdevice", info->usbdevice, NULL);
             }
         }
         if (info->soundhw) {
-            flexarray_set(dm_args, num++, "-soundhw");
-            flexarray_set(dm_args, num++, info->soundhw);
+            flexarray_vappend(dm_args, "-soundhw", info->soundhw, NULL);
         }
         if (info->apic) {
-            flexarray_set(dm_args, num++, "-acpi");
+            flexarray_append(dm_args, "-acpi");
         }
         if (info->vcpus > 1) {
-            flexarray_set(dm_args, num++, "-vcpus");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
+            flexarray_vappend(dm_args, "-vcpus", libxl__sprintf(gc, "%d", info->vcpus), NULL);
         }
         if (info->vcpu_avail) {
-            flexarray_set(dm_args, num++, "-vcpu_avail");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "0x%x", info->vcpu_avail));
+            flexarray_vappend(dm_args, "-vcpu_avail", libxl__sprintf(gc, "0x%x", info->vcpu_avail), NULL);
         }
         for (i = 0; i < num_vifs; i++) {
             if (vifs[i].nictype == NICTYPE_IOEMU) {
@@ -138,33 +125,30 @@ static char ** libxl_build_device_model_
                     ifname = libxl__sprintf(gc, "tap%d.%d", info->domid, vifs[i].devid);
                 else
                     ifname = vifs[i].ifname;
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
-                            vifs[i].devid, smac, vifs[i].model));
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
-                            vifs[i].devid, ifname, vifs[i].bridge));
+                flexarray_vappend(dm_args,
+                                "-net", libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
+                                                       vifs[i].devid, smac, vifs[i].model),
+                                "-net", libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,bridge=%s,script=no",
+                                                       vifs[i].devid, ifname, vifs[i].bridge), NULL);
                 ioemu_vifs++;
             }
         }
         /* If we have no emulated nics, tell qemu not to create any */
         if ( ioemu_vifs == 0 ) {
-            flexarray_set(dm_args, num++, "-net");
-            flexarray_set(dm_args, num++, "none");
+            flexarray_vappend(dm_args, "-net", "none", NULL);
         }
     }
     if (info->saved_state) {
-        flexarray_set(dm_args, num++, "-loadvm");
-        flexarray_set(dm_args, num++, info->saved_state);
+        flexarray_vappend(dm_args, "-loadvm", info->saved_state, NULL);
     }
     for (i = 0; info->extra && info->extra[i] != NULL; i++)
-        flexarray_set(dm_args, num++, info->extra[i]);
-    flexarray_set(dm_args, num++, "-M");
+        flexarray_append(dm_args, info->extra[i]);
+    flexarray_append(dm_args, "-M");
     if (info->type == XENPV)
-        flexarray_set(dm_args, num++, "xenpv");
+        flexarray_append(dm_args, "xenpv");
     else
-        flexarray_set(dm_args, num++, "xenfv");
-    flexarray_set(dm_args, num++, NULL);
+        flexarray_append(dm_args, "xenfv");
+    flexarray_append(dm_args, NULL);
     return (char **) flexarray_contents(dm_args);
 }
 
@@ -173,33 +157,29 @@ static char ** libxl_build_device_model_
                                              libxl_device_nic *vifs,
                                              int num_vifs)
 {
-    int num = 0, i;
     flexarray_t *dm_args;
-    int nb;
     libxl_device_disk *disks;
+    int nb, i;
 
     dm_args = flexarray_make(16, 1);
     if (!dm_args)
         return NULL;
 
-    flexarray_set(dm_args, num++, libxl__strdup(gc, info->device_model));
-
-    flexarray_set(dm_args, num++, "-xen-domid");
-    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->domid));
+    flexarray_vappend(dm_args, libxl__strdup(gc, info->device_model),
+                        "-xen-domid", libxl__sprintf(gc, "%d", info->domid), NULL);
 
     if (info->type == XENPV) {
-        flexarray_set(dm_args, num++, "-xen-attach");
+        flexarray_append(dm_args, "-xen-attach");
     }
 
     if (info->dom_name) {
-        flexarray_set(dm_args, num++, "-name");
-        flexarray_set(dm_args, num++, info->dom_name);
+        flexarray_vappend(dm_args, "-name", info->dom_name, NULL);
     }
     if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
         int display = 0;
         const char *listen = "127.0.0.1";
 
-        flexarray_set(dm_args, num++, "-vnc");
+        flexarray_append(dm_args, "-vnc");
 
         if (info->vncdisplay) {
             display = info->vncdisplay;
@@ -211,66 +191,59 @@ static char ** libxl_build_device_model_
         }
 
         if (strchr(listen, ':') != NULL)
-            flexarray_set(dm_args, num++,
+            flexarray_append(dm_args, 
                     libxl__sprintf(gc, "%s%s", listen,
                         info->vncunused ? ",to=99" : ""));
         else
-            flexarray_set(dm_args, num++,
+            flexarray_append(dm_args, 
                     libxl__sprintf(gc, "%s:%d%s", listen, display,
                         info->vncunused ? ",to=99" : ""));
     }
     if (info->sdl) {
-        flexarray_set(dm_args, num++, "-sdl");
+        flexarray_append(dm_args, "-sdl");
     }
 
     if (info->type == XENPV && !info->nographic) {
-        flexarray_set(dm_args, num++, "-vga");
-        flexarray_set(dm_args, num++, "xenfb");
+        flexarray_vappend(dm_args, "-vga", "xenfb", NULL);
     }
 
     if (info->keymap) {
-        flexarray_set(dm_args, num++, "-k");
-        flexarray_set(dm_args, num++, info->keymap);
+        flexarray_vappend(dm_args, "-k", info->keymap, NULL);
     }
     if (info->nographic && (!info->sdl && !info->vnc)) {
-        flexarray_set(dm_args, num++, "-nographic");
+        flexarray_append(dm_args, "-nographic");
     }
     if (info->serial) {
-        flexarray_set(dm_args, num++, "-serial");
-        flexarray_set(dm_args, num++, info->serial);
+        flexarray_vappend(dm_args, "-serial", info->serial, NULL);
     }
     if (info->type == XENFV) {
         int ioemu_vifs = 0;
 
         if (info->stdvga) {
-                flexarray_set(dm_args, num++, "-vga");
-                flexarray_set(dm_args, num++, "std");
+                flexarray_vappend(dm_args, "-vga", "std", NULL);
         }
 
         if (info->boot) {
-            flexarray_set(dm_args, num++, "-boot");
-            flexarray_set(dm_args, num++, libxl__sprintf(gc, "order=%s", info->boot));
+            flexarray_vappend(dm_args, "-boot", libxl__sprintf(gc, "order=%s", info->boot), NULL);
         }
         if (info->usb || info->usbdevice) {
-            flexarray_set(dm_args, num++, "-usb");
+            flexarray_append(dm_args, "-usb");
             if (info->usbdevice) {
-                flexarray_set(dm_args, num++, "-usbdevice");
-                flexarray_set(dm_args, num++, info->usbdevice);
+                flexarray_vappend(dm_args, "-usbdevice", info->usbdevice, NULL);
             }
         }
         if (info->soundhw) {
-            flexarray_set(dm_args, num++, "-soundhw");
-            flexarray_set(dm_args, num++, info->soundhw);
+            flexarray_vappend(dm_args, "-soundhw", info->soundhw, NULL);
         }
         if (!info->apic) {
-            flexarray_set(dm_args, num++, "-no-acpi");
+            flexarray_append(dm_args, "-no-acpi");
         }
         if (info->vcpus > 1) {
-            flexarray_set(dm_args, num++, "-smp");
+            flexarray_append(dm_args, "-smp");
             if (info->vcpu_avail)
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
+                flexarray_append(dm_args, libxl__sprintf(gc, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail));
             else
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->vcpus));
+                flexarray_append(dm_args, libxl__sprintf(gc, "%d", info->vcpus));
         }
         for (i = 0; i < num_vifs; i++) {
             if (vifs[i].nictype == NICTYPE_IOEMU) {
@@ -283,48 +256,45 @@ static char ** libxl_build_device_model_
                 } else {
                     ifname = vifs[i].ifname;
                 }
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
-                            vifs[i].devid, smac, vifs[i].model));
-                flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
-                            vifs[i].devid, ifname));
+                flexarray_vappend(dm_args,
+                                    "-net", libxl__sprintf(gc, "nic,vlan=%d,macaddr=%s,model=%s",
+                                                           vifs[i].devid, smac, vifs[i].model),
+                                    "-net", libxl__sprintf(gc, "tap,vlan=%d,ifname=%s,script=no",
+                                                            vifs[i].devid, ifname), NULL);
                 ioemu_vifs++;
             }
         }
         /* If we have no emulated nics, tell qemu not to create any */
         if ( ioemu_vifs == 0 ) {
-            flexarray_set(dm_args, num++, "-net");
-            flexarray_set(dm_args, num++, "none");
+            flexarray_vappend(dm_args, "-net", "none", NULL);
         }
     }
     if (info->saved_state) {
-        flexarray_set(dm_args, num++, "-loadvm");
-        flexarray_set(dm_args, num++, info->saved_state);
+        flexarray_vappend(dm_args, "-loadvm", info->saved_state, NULL);
     }
     for (i = 0; info->extra && info->extra[i] != NULL; i++)
-        flexarray_set(dm_args, num++, info->extra[i]);
-    flexarray_set(dm_args, num++, "-M");
+        flexarray_append(dm_args, info->extra[i]);
+    flexarray_append(dm_args, "-M");
     if (info->type == XENPV)
-        flexarray_set(dm_args, num++, "xenpv");
+        flexarray_append(dm_args, "xenpv");
     else
-        flexarray_set(dm_args, num++, "xenfv");
+        flexarray_append(dm_args, "xenfv");
 
     if (info->type == XENFV) {
         disks = libxl_device_disk_list(libxl__gc_owner(gc), info->domid, &nb);
         for (i; i < nb; i++) {
             if (disks[i].is_cdrom) {
-                flexarray_set(dm_args, num++, "-cdrom");
-                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
+                flexarray_append(dm_args, "-cdrom");
+                flexarray_append(dm_args, libxl__strdup(gc, disks[i].physpath));
             } else {
-                flexarray_set(dm_args, num++, libxl__sprintf(gc, "-%s", disks[i].virtpath));
-                flexarray_set(dm_args, num++, libxl__strdup(gc, disks[i].physpath));
+                flexarray_append(dm_args, libxl__sprintf(gc, "-%s", disks[i].virtpath));
+                flexarray_append(dm_args, libxl__strdup(gc, disks[i].physpath));
             }
             libxl_device_disk_destroy(&disks[i]);
         }
     }
     free(disks);
-    flexarray_set(dm_args, num++, NULL);
+    flexarray_append(dm_args, NULL);
     return (char **) flexarray_contents(dm_args);
 }
 
diff -r 2f8749c5e015 -r 3feb91094abb tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c	Wed Jan 05 12:50:42 2011 +0000
+++ b/tools/libxl/libxl_pci.c	Wed Jan 05 12:51:50 2011 +0000
@@ -226,8 +226,6 @@ static int libxl_create_pci_backend(libx
     libxl_ctx *ctx = libxl__gc_owner(gc);
     flexarray_t *front;
     flexarray_t *back;
-    unsigned int boffset = 0;
-    unsigned int foffset = 0;
     libxl__device device;
     int i;
 
@@ -248,39 +246,28 @@ static int libxl_create_pci_backend(libx
     device.domid = domid;
     device.kind = DEVICE_PCI;
 
-    flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", domid));
-    flexarray_set(back, boffset++, "online");
-    flexarray_set(back, boffset++, "1");
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", 1));
-    flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl__domid_to_name(gc, domid));
+    flexarray_vappend(back, "frontend-id", libxl__sprintf(gc, "%d", domid),
+                     "online", "1", "state", libxl__sprintf(gc, "%d", 1),
+                    "domain", libxl__domid_to_name(gc, domid), NULL);
     for (i = 0; i < num; i++) {
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "key-%d", i));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "dev-%d", i));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+        flexarray_append(back, libxl__sprintf(gc, "key-%d", i));
+        flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+        flexarray_append(back, libxl__sprintf(gc, "dev-%d", i));
+        flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
         if (pcidev->vdevfn) {
-            flexarray_set(back, boffset++, libxl__sprintf(gc, "vdevfn-%d", i));
-            flexarray_set(back, boffset++, libxl__sprintf(gc, "%x", pcidev->vdevfn));
+            flexarray_vappend(back, libxl__sprintf(gc, "vdevfn-%d", i), libxl__sprintf(gc, "%x", pcidev->vdevfn), NULL);
         }
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "opts-%d", i));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "state-%d", i));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", 1));
+        flexarray_append(back, libxl__sprintf(gc, "opts-%d", i));
+        flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
+        flexarray_vappend(back, libxl__sprintf(gc, "state-%d", i), libxl__sprintf(gc, "%d", 1), NULL);
     }
-    flexarray_set(back, boffset++, "num_devs");
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", num));
-
-    flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl__sprintf(gc, "%d", 0));
-    flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl__sprintf(gc, "%d", 1));
+    flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num),
+                    "backend-id", libxl__sprintf(gc, "%d", 0),
+                    "state", libxl__sprintf(gc, "%d", 1), NULL);
 
     libxl__device_generic_add(ctx, &device,
-                             libxl__xs_kvs_of_flexarray(gc, back, boffset),
-                             libxl__xs_kvs_of_flexarray(gc, front, foffset));
+                             libxl__xs_kvs_of_flexarray(gc, back, back->count),
+                             libxl__xs_kvs_of_flexarray(gc, front, front->count));
 
     flexarray_free(back);
     flexarray_free(front);
@@ -293,7 +280,6 @@ static int libxl_device_pci_add_xenstore
     flexarray_t *back;
     char *num_devs, *be_path;
     int num = 0;
-    unsigned int boffset = 0;
     xs_transaction_t t;
 
     be_path = libxl__sprintf(gc, "%s/backend/pci/%d/0", libxl__xs_get_dompath(gc, 0), domid);
@@ -312,27 +298,24 @@ static int libxl_device_pci_add_xenstore
 
     LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Adding new pci device to xenstore");
     num = atoi(num_devs);
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "key-%d", num));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "dev-%d", num));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_append(back, libxl__sprintf(gc, "key-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_append(back, libxl__sprintf(gc, "dev-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
     if (pcidev->vdevfn) {
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "vdevfn-%d", num));
-        flexarray_set(back, boffset++, libxl__sprintf(gc, "%x", pcidev->vdevfn));
+        flexarray_append(back, libxl__sprintf(gc, "vdevfn-%d", num));
+        flexarray_append(back, libxl__sprintf(gc, "%x", pcidev->vdevfn));
     }
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "opts-%d", num));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "state-%d", num));
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", 1));
-    flexarray_set(back, boffset++, "num_devs");
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", num + 1));
-    flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl__sprintf(gc, "%d", 7));
+    flexarray_append(back, libxl__sprintf(gc, "opts-%d", num));
+    flexarray_append(back, libxl__sprintf(gc, "msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
+    flexarray_vappend(back, libxl__sprintf(gc, "state-%d", num), libxl__sprintf(gc, "%d", 1), NULL);
+    flexarray_vappend(back, "num_devs", libxl__sprintf(gc, "%d", num + 1), NULL);
+    flexarray_vappend(back, "state", libxl__sprintf(gc, "%d", 7), NULL);
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
     libxl__xs_writev(gc, t, be_path,
-                    libxl__xs_kvs_of_flexarray(gc, back, boffset));
+                    libxl__xs_kvs_of_flexarray(gc, back, back->count));
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1 of 4] xl: idl: Abolish keyed union types
  2011-01-05 13:41 ` [PATCH 1 of 4] xl: idl: Abolish keyed union types Gianni Tedesco
@ 2011-01-06 17:56   ` Ian Jackson
  2011-01-06 18:55     ` Ian Campbell
  2011-01-07 13:09     ` Gianni Tedesco
  0 siblings, 2 replies; 15+ messages in thread
From: Ian Jackson @ 2011-01-06 17:56 UTC (permalink / raw)
  To: Gianni Tedesco; +Cc: Ian Campbell, xen-devel, Stefano Stabellini

Gianni Tedesco writes ("[Xen-devel] [PATCH 1 of 4] xl: idl: Abolish keyed union types"):
> xl: idl: Abolish keyed union types
> 
> Since the IDL file has become useful for generating language
> bindings it has become apparent that the KeyedUnion type has no
> straightforward translation to scripting languages which have no
> notion of unions.

Uhh?  Most scripting languages' aggregate types are practically
nothing _but_ unions!

The correct translation of a keyed union would probably be an
aggregate (eg, in Python, a dictionary) containing an entry for the
key and entries for whatever version of the union it involved.

> Turns out this is only used in domain_build_info which is hardly a memory
> criticial structure.

However I don't have a strong opinion about the desirability of using
a tagged union for this particular structure.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
  2011-01-05 13:41 ` [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
@ 2011-01-06 17:58   ` Ian Jackson
  2011-01-06 19:34     ` Stefano Stabellini
  0 siblings, 1 reply; 15+ messages in thread
From: Ian Jackson @ 2011-01-06 17:58 UTC (permalink / raw)
  To: Gianni Tedesco; +Cc: Ian Campbell, xen-devel, Stefano Stabellini

Gianni Tedesco writes ("[Xen-devel] [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()"):
> xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()

This patch looks reasonable to me - at least, the API seems sensible
to me.  I didn't diff all of the shuffled-about code :-).

I'll wait for an ack from Stefano too though.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages]
  2011-01-05 13:41 ` [PATCH 3 of 4] xl: Move device model functions in to a separate file Gianni Tedesco
@ 2011-01-06 18:00   ` Ian Jackson
  2011-01-07 13:12     ` Gianni Tedesco
  0 siblings, 1 reply; 15+ messages in thread
From: Ian Jackson @ 2011-01-06 18:00 UTC (permalink / raw)
  To: Gianni Tedesco; +Cc: Ian Campbell, xen-devel, Stefano Stabellini

Gianni Tedesco writes ("[Xen-devel] [PATCH 3 of 4] xl: Move device model functions in to a separate file"):
> xl: Move device model functions in to a separate file

Gianni Tedesco writes ("[Xen-devel] [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend()"):
> xl: Implement flexarray_append() and flexarray_vappend()

These are very sensible rearrangements, well done.  I'll apply them as
soon as the earlier parts of the series go in, or if you prefer you
can repost versions of 3 and 4 as a new 2-part series to go in right
away.

Thanks,
Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1 of 4] xl: idl: Abolish keyed union types
  2011-01-06 17:56   ` Ian Jackson
@ 2011-01-06 18:55     ` Ian Campbell
  2011-01-07 13:09     ` Gianni Tedesco
  1 sibling, 0 replies; 15+ messages in thread
From: Ian Campbell @ 2011-01-06 18:55 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel, Gianni Tedesco, Stefano Stabellini

On Thu, 2011-01-06 at 17:56 +0000, Ian Jackson wrote: 
> Gianni Tedesco writes ("[Xen-devel] [PATCH 1 of 4] xl: idl: Abolish keyed union types"):
> > xl: idl: Abolish keyed union types
> > 
> > Since the IDL file has become useful for generating language
> > bindings it has become apparent that the KeyedUnion type has no
> > straightforward translation to scripting languages which have no
> > notion of unions.
> 
> Uhh?  Most scripting languages' aggregate types are practically
> nothing _but_ unions!
> 
> The correct translation of a keyed union would probably be an
> aggregate (eg, in Python, a dictionary) containing an entry for the
> key and entries for whatever version of the union it involved.

The union type ends up looking quite nice in the ocaml bindings too:

        type build_spec = BuildHVM of build_hvm_info | BuildPV of build_pv_info

which allows nice ocaml idiomatic stuff like
        match build with
        | BuildHVM hvm -> do_some_hvm_stuff hvm
        | BuildPV pv -> do_some_pv_stuff pv

> > Turns out this is only used in domain_build_info which is hardly a memory
> > criticial structure.
> 
> However I don't have a strong opinion about the desirability of using
> a tagged union for this particular structure.

Me neither.

That ocaml stuff currently hand coded (and no one is imminently working
on changing that to my knowledge) so I don't think the libxl API change
arising from this IDL change prevents retaining this interface but it
does suggest why having the notion of a key which selects between
alternative fields could be a semantically useful concept in the
interface.

If having KeyedStruct instead of KeyedUnion simplifies things that could
be an alternative. Or go the whole hog and define a Dict type (turns
into an enum + the relevant number of fields)? Or just nuke it and cross
the bridge when we come to it ;-).

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
  2011-01-06 17:58   ` Ian Jackson
@ 2011-01-06 19:34     ` Stefano Stabellini
  2011-01-07 12:58       ` Gianni Tedesco
  0 siblings, 1 reply; 15+ messages in thread
From: Stefano Stabellini @ 2011-01-06 19:34 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Ian Campbell, xen-devel, Gianni Tedesco, Stefano Stabellini

On Thu, 6 Jan 2011, Ian Jackson wrote:
> Gianni Tedesco writes ("[Xen-devel] [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()"):
> > xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
> 
> This patch looks reasonable to me - at least, the API seems sensible
> to me.  I didn't diff all of the shuffled-about code :-).
> 
> I'll wait for an ack from Stefano too though.
 
Thanks.

I think the patch is overall correct but please make sure to test it
with stubdoms at least once.
Also I think we need to move all the init_*_info functions to libxl too,
in order to provide sensible defaults for libxl_domain_config *d_config.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
  2011-01-06 19:34     ` Stefano Stabellini
@ 2011-01-07 12:58       ` Gianni Tedesco
  0 siblings, 0 replies; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-07 12:58 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: Ian Campbell, xen-devel, Ian Jackson

On Thu, 2011-01-06 at 19:34 +0000, Stefano Stabellini wrote:
> On Thu, 6 Jan 2011, Ian Jackson wrote:
> > Gianni Tedesco writes ("[Xen-devel] [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()"):
> > > xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
> > 
> > This patch looks reasonable to me - at least, the API seems sensible
> > to me.  I didn't diff all of the shuffled-about code :-).
> > 
> > I'll wait for an ack from Stefano too though.
>  
> Thanks.
> 
> I think the patch is overall correct but please make sure to test it
> with stubdoms at least once.

OK, I'll do a thorough round of testing before submitting next version.
I may have found an error in there anyway but I need to chase that one
down to be sure.

> Also I think we need to move all the init_*_info functions to libxl too,
> in order to provide sensible defaults for libxl_domain_config *d_config.

Yeah, I just realised that last night. To be honest there's a lot of
duplicated fields in those structures so that they may be better off
being re-organised somehow anyway. I'll see what I can come up with.

Gianni

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 1 of 4] xl: idl: Abolish keyed union types
  2011-01-06 17:56   ` Ian Jackson
  2011-01-06 18:55     ` Ian Campbell
@ 2011-01-07 13:09     ` Gianni Tedesco
  1 sibling, 0 replies; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-07 13:09 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Ian, Campbell, xen-devel, Stefano Stabellini

On Thu, 2011-01-06 at 17:56 +0000, Ian Jackson wrote:
> Gianni Tedesco writes ("[Xen-devel] [PATCH 1 of 4] xl: idl: Abolish keyed union types"):
> > xl: idl: Abolish keyed union types
> > 
> > Since the IDL file has become useful for generating language
> > bindings it has become apparent that the KeyedUnion type has no
> > straightforward translation to scripting languages which have no
> > notion of unions.
> 
> Uhh?  Most scripting languages' aggregate types are practically
> nothing _but_ unions!

Not really sure I follow this.

> The correct translation of a keyed union would probably be an
> aggregate (eg, in Python, a dictionary) containing an entry for the
> key and entries for whatever version of the union it involved.

Hrm, I don't think we can easily do it this way. We create full fledged
python types to correspond to the C types currently. Probably the more
natural construction for unions would be basically the C equivalent of:

class Foo:
	def __init__(self):
		self.__hidden = xl.thing_pv()
	def __getattr__(self, k):
		return self.__hidden.__getattr__(k)
	def __setattr__(self, k, v):
		if k == 'hvm':
			if v:
				self.__hidden = xl.thing_hvm()
				# copy all attributes from before
			elif v:
				self.__hidden = xl.thing_pv()
				# copy all attributes from before
		return self.__hidden.__setattr__(k, v)

so that:
	x = Foo()
	x.pv_thing = True
	x.pv_thing
	>>> True
	x.hvm = True
	x.pv_thing
	>>> Exception: AttributeError
	x.hvm_thing = 'thing'

In other words, frob the getter/setter table whenever the key is set. I
could probably implement this if required as a pre-requisite for the
rest of the series but it may take a day or two.

Alternatively, I have some further patches to do with the Python binding
which does some more sophisticated stuff and I could re-introduce the
KeyedUnion later?

> > Turns out this is only used in domain_build_info which is hardly a memory
> > criticial structure.
> 
> However I don't have a strong opinion about the desirability of using
> a tagged union for this particular structure.

Hence my casualness in abolishing it.

Gianni

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages]
  2011-01-06 18:00   ` [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages] Ian Jackson
@ 2011-01-07 13:12     ` Gianni Tedesco
  2011-01-07 15:43       ` Ian Jackson
  0 siblings, 1 reply; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-07 13:12 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Ian, Campbell, xen-devel, Stefano Stabellini

On Thu, 2011-01-06 at 18:00 +0000, Ian Jackson wrote:
> Gianni Tedesco writes ("[Xen-devel] [PATCH 3 of 4] xl: Move device model functions in to a separate file"):
> > xl: Move device model functions in to a separate file
> 
> Gianni Tedesco writes ("[Xen-devel] [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend()"):
> > xl: Implement flexarray_append() and flexarray_vappend()
> 
> These are very sensible rearrangements, well done.  I'll apply them as
> soon as the earlier parts of the series go in, or if you prefer you
> can repost versions of 3 and 4 as a new 2-part series to go in right
> away.

OK, I'll wait on your response to other questions but maybe it should be
re-orderd anyway:

1. move dm functions around
2. flexarray append
3. create_domain()

--

Other python-binding and idl stuff to follow in a future series.

Gianni

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend()
  2011-01-05 13:41 ` [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend() Gianni Tedesco
@ 2011-01-07 13:37   ` Gianni Tedesco
  0 siblings, 0 replies; 15+ messages in thread
From: Gianni Tedesco @ 2011-01-07 13:37 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

On Wed, 2011-01-05 at 13:41 +0000, Gianni Tedesco wrote:
> @@ -919,35 +919,35 @@ int libxl_device_disk_add(libxl_ctx *ctx
>              goto out_free;
>      }
> 
> -    flexarray_set(back, boffset++, "frontend-id");

This stuff is erroneous because boffset needs removing!

Will fix this for next go around.

Gianni

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages]
  2011-01-07 13:12     ` Gianni Tedesco
@ 2011-01-07 15:43       ` Ian Jackson
  0 siblings, 0 replies; 15+ messages in thread
From: Ian Jackson @ 2011-01-07 15:43 UTC (permalink / raw)
  To: Gianni Tedesco; +Cc: Ian, Campbell, xen-devel, Stefano Stabellini

Gianni Tedesco writes ("Re: [Xen-devel] [PATCH 3 of 4] xl: Move device model functions in to a	separate file [and 1 more messages]"):
> On Thu, 2011-01-06 at 18:00 +0000, Ian Jackson wrote:
> > These are very sensible rearrangements, well done.  I'll apply them as
> > soon as the earlier parts of the series go in, or if you prefer you
> > can repost versions of 3 and 4 as a new 2-part series to go in right
> > away.
> 
> OK, I'll wait on your response to other questions but maybe it should be
> re-orderd anyway:
> 
> 1. move dm functions around
> 2. flexarray append
> 3. create_domain()

That would be fine by me.

Ian.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-01-07 15:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-05 13:41 [PATCH 0 of 4] Refactor libxl domain creation, v2 Gianni Tedesco
2011-01-05 13:41 ` [PATCH 1 of 4] xl: idl: Abolish keyed union types Gianni Tedesco
2011-01-06 17:56   ` Ian Jackson
2011-01-06 18:55     ` Ian Campbell
2011-01-07 13:09     ` Gianni Tedesco
2011-01-05 13:41 ` [PATCH 2 of 4] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
2011-01-06 17:58   ` Ian Jackson
2011-01-06 19:34     ` Stefano Stabellini
2011-01-07 12:58       ` Gianni Tedesco
2011-01-05 13:41 ` [PATCH 3 of 4] xl: Move device model functions in to a separate file Gianni Tedesco
2011-01-06 18:00   ` [PATCH 3 of 4] xl: Move device model functions in to a separate file [and 1 more messages] Ian Jackson
2011-01-07 13:12     ` Gianni Tedesco
2011-01-07 15:43       ` Ian Jackson
2011-01-05 13:41 ` [PATCH 4 of 4] xl: Implement flexarray_append() and flexarray_vappend() Gianni Tedesco
2011-01-07 13:37   ` Gianni Tedesco

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.