[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 0 of 3] Refactor libxl domain creation



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

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

No functional changes.

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

# HG changeset patch
# Parent 1ff6243eba261a0ae731b62a5c55bcbb18b6069a

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



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.