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-changelog

[Xen-changelog] [xen-unstable] xl: Move device model functions in to a s

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xl: Move device model functions in to a separate file
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 17 Jan 2011 07:59:03 -0800
Delivery-date: Mon, 17 Jan 2011 08:09:44 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
# Date 1294424694 0
# Node ID e1392f5327ce81587ca1eb0e3fda16cf3b84a167
# Parent  52b57a4781b437daf23b1393db48ab370f827104
xl: Move device model functions in to a separate file

No functional changes.

Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
---
 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(-)

diff -r 52b57a4781b4 -r e1392f5327ce tools/libxl/Makefile
--- a/tools/libxl/Makefile      Fri Jan 07 18:01:18 2011 +0000
+++ b/tools/libxl/Makefile      Fri Jan 07 18:24:54 2011 +0000
@@ -29,7 +29,7 @@ LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.
 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 52b57a4781b4 -r e1392f5327ce tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Fri Jan 07 18:01:18 2011 +0000
+++ b/tools/libxl/libxl.c       Fri Jan 07 18:24:54 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);
@@ -1106,698 +1066,6 @@ skip_autopass:
     libxl__exec(autopass_fd, -1, -1, args[0], args);
     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;
-}
-
 
 
/******************************************************************************/
 
@@ -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 52b57a4781b4 -r e1392f5327ce tools/libxl/libxl_dm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_dm.c    Fri Jan 07 18:24:54 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 52b57a4781b4 -r e1392f5327ce tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri Jan 07 18:01:18 2011 +0000
+++ b/tools/libxl/libxl_internal.h      Fri Jan 07 18:24:54 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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xl: Move device model functions in to a separate file, Xen patchbot-unstable <=