WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 1 of 2] xl: Move device model functions in to a separ

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 1 of 2] xl: Move device model functions in to a separate file
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Fri, 7 Jan 2011 16:07:05 +0000
Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Delivery-date: Fri, 07 Jan 2011 08:13:13 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1294416424@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1294416424@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.6.3
 tools/libxl/Makefile         |    2 +-
 tools/libxl/libxl.c          |  810 +-----------------------------------------
 tools/libxl/libxl_dm.c       |  833 +++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |    2 +
 4 files changed, 838 insertions(+), 809 deletions(-)


# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
# Date 1294416306 0
# Node ID 2bde4e48657ec8087778a5924bf2d07f02666c39
# Parent  82c205df44062aaa6f3ad2d22b5273e18ec3151e
xl: Move device model functions in to a separate file

No functional changes.

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

diff -r 82c205df4406 -r 2bde4e48657e tools/libxl/Makefile
--- a/tools/libxl/Makefile      Fri Jan 07 14:13:15 2011 +0000
+++ b/tools/libxl/Makefile      Fri Jan 07 16:05:06 2011 +0000
@@ -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 = flexarray.o libxl.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 82c205df4406 -r 2bde4e48657e tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Fri Jan 07 14:13:15 2011 +0000
+++ b/tools/libxl/libxl.c       Fri Jan 07 16:05:06 2011 +0000
@@ -902,46 +902,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);
@@ -975,8 +935,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);
@@ -1107,698 +1067,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");
-
-    /* RAM Size */
-    flexarray_set(dm_args, num++, "-m");
-    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->target_ram));
-
-    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.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;
-
-    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;
-}
-
-int libxl_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 = libxl_detach_device_model(ctx, starting);
-    return problem ? problem : detach;
-}
-
-
 
/******************************************************************************/
 
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk 
*disk)
@@ -2631,80 +1899,6 @@ out:
 }
 
 
/******************************************************************************/
-static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
-                                       uint32_t domid,
-                                       libxl_device_vfb *vfb,
-                                       libxl_device_model_info *info)
-{
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-    memset(info, 0x00, sizeof(libxl_device_model_info));
-
-    if (vfb != NULL) {
-        info->vnc = vfb->vnc;
-        if (vfb->vnclisten)
-            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
-        info->vncdisplay = vfb->vncdisplay;
-        info->vncunused = vfb->vncunused;
-        if (vfb->vncpasswd)
-            info->vncpasswd = vfb->vncpasswd;
-        if (vfb->keymap)
-            info->keymap = libxl__strdup(gc, vfb->keymap);
-        info->sdl = vfb->sdl;
-        info->opengl = vfb->opengl;
-    } else
-        info->nographic = 1;
-    info->domid = domid;
-    info->dom_name = libxl_domid_to_name(ctx, domid);
-    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
-    info->type = XENPV;
-    return 0;
-}
-
-int libxl_need_xenpv_qemu(libxl_ctx *ctx,
-        int nr_consoles, libxl_device_console *consoles,
-        int nr_vfbs, libxl_device_vfb *vfbs,
-        int nr_disks, libxl_device_disk *disks)
-{
-    int i, ret = 0;
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-
-    if (nr_consoles > 1) {
-        ret = 1;
-        goto out;
-    }
-
-    for (i = 0; i < nr_consoles; i++) {
-        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
-            ret = 1;
-            goto out;
-        }
-    }
-
-    if (nr_vfbs > 0) {
-        ret = 1;
-        goto out;
-    }
-
-    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
-        ret = 1;
-
-out:
-    libxl__free_all(&gc);
-    return ret;
-}
-
-int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb,
-                            libxl_device_model_starting **starting_r)
-{
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
-    libxl_device_model_info info;
-
-    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
-    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
-    libxl__free_all(&gc);
-    return 0;
-}
-
 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
diff -r 82c205df4406 -r 2bde4e48657e tools/libxl/libxl_dm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_dm.c    Fri Jan 07 16:05:06 2011 +0000
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ * Author Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
+ * Author Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
+ *
+ * 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_utils.h"
+#include "libxl_internal.h"
+#include "libxl.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");
+
+    /* RAM Size */
+    flexarray_set(dm_args, num++, "-m");
+    flexarray_set(dm_args, num++, libxl__sprintf(gc, "%d", info->target_ram));
+
+    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.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;
+
+    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;
+}
+
+int libxl_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 = libxl_detach_device_model(ctx, starting);
+    return problem ? problem : detach;
+}
+
+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;
+}
+
+static int libxl_build_xenpv_qemu_args(libxl__gc *gc,
+                                       uint32_t domid,
+                                       libxl_device_vfb *vfb,
+                                       libxl_device_model_info *info)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    memset(info, 0x00, sizeof(libxl_device_model_info));
+
+    if (vfb != NULL) {
+        info->vnc = vfb->vnc;
+        if (vfb->vnclisten)
+            info->vnclisten = libxl__strdup(gc, vfb->vnclisten);
+        info->vncdisplay = vfb->vncdisplay;
+        info->vncunused = vfb->vncunused;
+        if (vfb->vncpasswd)
+            info->vncpasswd = vfb->vncpasswd;
+        if (vfb->keymap)
+            info->keymap = libxl__strdup(gc, vfb->keymap);
+        info->sdl = vfb->sdl;
+        info->opengl = vfb->opengl;
+    } else
+        info->nographic = 1;
+    info->domid = domid;
+    info->dom_name = libxl_domid_to_name(ctx, domid);
+    info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
+    info->type = XENPV;
+    return 0;
+}
+
+int libxl_need_xenpv_qemu(libxl_ctx *ctx,
+        int nr_consoles, libxl_device_console *consoles,
+        int nr_vfbs, libxl_device_vfb *vfbs,
+        int nr_disks, libxl_device_disk *disks)
+{
+    int i, ret = 0;
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+
+    if (nr_consoles > 1) {
+        ret = 1;
+        goto out;
+    }
+
+    for (i = 0; i < nr_consoles; i++) {
+        if (consoles[i].consback == LIBXL_CONSBACK_IOEMU) {
+            ret = 1;
+            goto out;
+        }
+    }
+
+    if (nr_vfbs > 0) {
+        ret = 1;
+        goto out;
+    }
+
+    if (nr_disks > 0 && !libxl__blktap_enabled(&gc))
+        ret = 1;
+
+out:
+    libxl__free_all(&gc);
+    return ret;
+}
+
+int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb,
+                            libxl_device_model_starting **starting_r)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    libxl_device_model_info info;
+
+    libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
+    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
+    libxl__free_all(&gc);
+    return 0;
+}
diff -r 82c205df4406 -r 2bde4e48657e tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri Jan 07 14:13:15 2011 +0000
+++ b/tools/libxl/libxl_internal.h      Fri Jan 07 16:05:06 2011 +0000
@@ -204,6 +204,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

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel