All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 3] Refactor libxl domain creation
@ 2011-01-04 16:51 Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 1 of 3] xl: idl: Abolish keyed union types Gianni Tedesco
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-04 16:51 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.

Gianni

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

* [PATCH 1 of 3] xl: idl: Abolish keyed union types
  2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
@ 2011-01-04 16:51 ` Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 2 of 3] xl: Remove libxl_need_xenpv_qemu() Gianni Tedesco
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-04 16:51 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 1294156918 0
# Node ID 01a1ce470640c67cf507e1f64a32561443b43061
# Parent  a8d69de8eb315b3b18c8a86c4d1505f53b84a443
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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/gentypes.py
--- a/tools/libxl/gentypes.py	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/gentypes.py	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/libxl.c	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/libxl.idl	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/libxl_bootloader.c
--- a/tools/libxl/libxl_bootloader.c	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/libxl_bootloader.c	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/libxl_dom.c	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/libxltypes.py	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Tue Jan 04 16:01:58 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 a8d69de8eb31 -r 01a1ce470640 tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 04 11:32:20 2011 +0000
+++ b/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 04 16:01:58 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] 6+ messages in thread

* [PATCH 2 of 3] xl: Remove libxl_need_xenpv_qemu()
  2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 1 of 3] xl: idl: Abolish keyed union types Gianni Tedesco
@ 2011-01-04 16:51 ` Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 3 of 3] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-04 16:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/libxl.c |  33 ---------------------------------
 tools/libxl/libxl.h |   4 ----
 2 files changed, 0 insertions(+), 37 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294158577 0
# Node ID deb521c7f86fe761a9eed8e3ef55942087eb90fa
# Parent  01a1ce470640c67cf507e1f64a32561443b43061
xl: Remove libxl_need_xenpv_qemu()

It appears to have been made redundant with no users in-tree.

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

diff -r 01a1ce470640 -r deb521c7f86f tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Tue Jan 04 16:01:58 2011 +0000
+++ b/tools/libxl/libxl.c	Tue Jan 04 16:29:37 2011 +0000
@@ -2654,39 +2654,6 @@ static int libxl_build_xenpv_qemu_args(l
     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)
 {
diff -r 01a1ce470640 -r deb521c7f86f tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Tue Jan 04 16:01:58 2011 +0000
+++ b/tools/libxl/libxl.h	Tue Jan 04 16:29:37 2011 +0000
@@ -383,10 +383,6 @@ int libxl_create_device_model(libxl_ctx 
                               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. */

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

* [PATCH 3 of 3] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
  2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 1 of 3] xl: idl: Abolish keyed union types Gianni Tedesco
  2011-01-04 16:51 ` [PATCH 2 of 3] xl: Remove libxl_need_xenpv_qemu() Gianni Tedesco
@ 2011-01-04 16:51 ` Gianni Tedesco
  2011-01-04 17:51 ` [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
  2011-01-05 11:15 ` Gianni Tedesco
  4 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-04 16:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

 tools/libxl/Makefile           |    4 +-
 tools/libxl/libxl.c            |  284 +----------------------
 tools/libxl/libxl.h            |   58 +++-
 tools/libxl/libxl_create.c     |  475 +++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_exec.c       |    2 +-
 tools/libxl/libxl_internal.h   |   24 +-
 tools/libxl/xl_cmdimpl.c       |  328 ++++++---------------------
 tools/ocaml/libs/xl/xl_stubs.c |   85 +------
 8 files changed, 644 insertions(+), 616 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@citrix.com>
# Date 1294159328 0
# Node ID 35fab5f9eb393daaaa35bfe5960cd80c04f78d37
# Parent  deb521c7f86fe761a9eed8e3ef55942087eb90fa
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 need 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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/Makefile
--- a/tools/libxl/Makefile	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/Makefile	Tue Jan 04 16:42:08 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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/libxl.c	Tue Jan 04 16:42:08 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,14 +2412,14 @@ static int libxl_build_xenpv_qemu_args(l
     return 0;
 }
 
-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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/libxl.h	Tue Jan 04 16:42:08 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,23 +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);
-  /* 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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/libxl_create.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_create.c	Tue Jan 04 16:42:08 2011 +0000
@@ -0,0 +1,475 @@
+/*
+ * 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 {
+        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;
+        if (d_config->num_vfbs)
+             console.consback = LIBXL_CONSBACK_IOEMU;
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        if (d_config->num_vfbs)
+            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 ret;
+
+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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/libxl_exec.c	Tue Jan 04 16:42:08 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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/libxl_internal.h	Tue Jan 04 16:42:08 2011 +0000
@@ -194,14 +194,32 @@ 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);
+  /* 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 deb521c7f86f -r 35fab5f9eb39 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Tue Jan 04 16:42:08 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 deb521c7f86f -r 35fab5f9eb39 tools/ocaml/libs/xl/xl_stubs.c
--- a/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 04 16:29:37 2011 +0000
+++ b/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 04 16:42:08 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] 6+ messages in thread

* Re: [PATCH 0 of 3] Refactor libxl domain creation
  2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
                   ` (2 preceding siblings ...)
  2011-01-04 16:51 ` [PATCH 3 of 3] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
@ 2011-01-04 17:51 ` Gianni Tedesco
  2011-01-05 11:15 ` Gianni Tedesco
  4 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-04 17:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

Just thought of a fourth patch for this series. It leaves libxl.c ~800
lines slimmer and looking good for it.

--
xl: Move device model functions in to a separate file

No functional changes.

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

# HG changeset patch
# Parent 1ff6243eba261a0ae731b62a5c55bcbb18b6069a

diff -r 1ff6243eba26 tools/libxl/Makefile
--- a/tools/libxl/Makefile	Tue Jan 04 16:27:45 2011 +0000
+++ b/tools/libxl/Makefile	Tue Jan 04 17:44:26 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 1ff6243eba26 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Tue Jan 04 16:27:45 2011 +0000
+++ b/tools/libxl/libxl.c	Tue Jan 04 17:44:26 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,47 +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__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 1ff6243eba26 tools/libxl/libxl_dm.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_dm.c	Tue Jan 04 17:44:26 2011 +0000
@@ -0,0 +1,798 @@
+/*
+ * 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__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 1ff6243eba26 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Tue Jan 04 16:27:45 2011 +0000
+++ b/tools/libxl/libxl_internal.h	Tue Jan 04 17:44:26 2011 +0000
@@ -222,6 +222,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] 6+ messages in thread

* Re: [PATCH 0 of 3] Refactor libxl domain creation
  2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
                   ` (3 preceding siblings ...)
  2011-01-04 17:51 ` [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
@ 2011-01-05 11:15 ` Gianni Tedesco
  4 siblings, 0 replies; 6+ messages in thread
From: Gianni Tedesco @ 2011-01-05 11:15 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell, Ian Jackson, Stefano Stabellini

On Tue, 2011-01-04 at 16:51 +0000, Gianni Tedesco wrote:
> Introduce libxl_domain_create_new() and libxl_domain_create_restore() rendering
> redundant several other, more complex, API's and simplifying the xl create
> implementation.

Damnit, please do not apply, I screwed this up somewhere for the PV
case.

libxl_need_xenpv_qemu() *is* required and can't remember editing this
out of the code?! So maybe it's a mis-paste.

Please wait for second version.

Gianni

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

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

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-04 16:51 [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
2011-01-04 16:51 ` [PATCH 1 of 3] xl: idl: Abolish keyed union types Gianni Tedesco
2011-01-04 16:51 ` [PATCH 2 of 3] xl: Remove libxl_need_xenpv_qemu() Gianni Tedesco
2011-01-04 16:51 ` [PATCH 3 of 3] xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore() Gianni Tedesco
2011-01-04 17:51 ` [PATCH 0 of 3] Refactor libxl domain creation Gianni Tedesco
2011-01-05 11:15 ` 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.