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

[Xen-changelog] [xen-unstable] libxenlight: implement support for pv guests



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1258959243 0
# Node ID 014579af035057de953bfbbdcf0dcdba68c67a5e
# Parent  bcc6cd1122ea5ba01c6067c5197e5935caf2423d
libxenlight: implement support for pv guests

This patch makes pv guest work correctly with libxenlight.  It also
implements support for vfb and vkbd, starting qemu in xenpv mode. Both
xenconsole and qemu are supported as console backends.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 tools/libxl/libxl.c          |  364 +++++++++++++++++++++++++++++++++++--------
 tools/libxl/libxl.h          |   53 +++++-
 tools/libxl/libxl_device.c   |   27 ++-
 tools/libxl/libxl_dom.c      |   41 +++-
 tools/libxl/libxl_internal.h |   12 -
 tools/libxl/xl.c             |  281 +++++++++++++++++++++++++--------
 6 files changed, 624 insertions(+), 154 deletions(-)

diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/libxl.c       Mon Nov 23 06:54:03 2009 +0000
@@ -23,6 +23,8 @@
 #include <sys/select.h>
 #include <signal.h>
 #include <unistd.h> /* for write, unlink and close */
+#include <stdint.h>
+#include <inttypes.h>
 #include "libxl.h"
 #include "libxl_utils.h"
 #include "libxl_internal.h"
@@ -156,7 +158,6 @@ retry_transaction:
 
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
     xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, 
strlen(info->name));
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/image/ostype", vm_path), 
"hvm", strlen("hvm"));
 
     libxl_xs_writev(ctx, t, dom_path, info->xsdata);
     libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), 
info->platformdata);
@@ -169,24 +170,33 @@ retry_transaction:
     return 0;
 }
 
-int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, 
uint32_t domid)
-{
-    libxl_domain_build_state state;
+libxl_domain_build_state *libxl_domain_build(struct libxl_ctx *ctx, 
libxl_domain_build_info *info, uint32_t domid)
+{
+    libxl_domain_build_state *state = (libxl_domain_build_state *) 
libxl_calloc(ctx, 1, sizeof(libxl_domain_build_state));
     char **vments = NULL, **localents = NULL;
 
-    memset(&state, '\0', sizeof(state));
-
-    build_pre(ctx, domid, info, &state);
+    build_pre(ctx, domid, info, state);
     if (info->hvm) {
-        build_hvm(ctx, domid, info, &state);
-        vments = libxl_calloc(ctx, 4, sizeof(char *));
+        build_hvm(ctx, domid, info, state);
+        vments = libxl_calloc(ctx, 5, sizeof(char *));
         vments[0] = libxl_sprintf(ctx, "rtc/timeoffset");
         vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? 
info->u.hvm.timeoffset : "");
+        vments[2] = libxl_sprintf(ctx, "image/ostype");
+        vments[3] = libxl_sprintf(ctx, "hvm");
     } else {
-        build_pv(ctx, domid, info, &state);
-    }
-    build_post(ctx, domid, info, &state, vments, localents);
-    return 0;
+        build_pv(ctx, domid, info, state);
+        vments = libxl_calloc(ctx, 9, sizeof(char *));
+        vments[0] = libxl_sprintf(ctx, "image/ostype");
+        vments[1] = libxl_sprintf(ctx, "linux");
+        vments[2] = libxl_sprintf(ctx, "image/kernel");
+        vments[3] = libxl_sprintf(ctx, info->kernel);
+        vments[4] = libxl_sprintf(ctx, "image/ramdisk");
+        vments[5] = libxl_sprintf(ctx, info->u.pv.ramdisk);
+        vments[6] = libxl_sprintf(ctx, "image/cmdline");
+        vments[7] = libxl_sprintf(ctx, info->u.pv.cmdline);
+    }
+    build_post(ctx, domid, info, state, vments, localents);
+    return state;
 }
 
 int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
@@ -413,13 +423,6 @@ static char ** libxl_build_device_model_
     if (info->dom_name) {
         flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name"));
         flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", 
info->dom_name));
-    }
-    if (info->videoram) {
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram"));
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", 
info->videoram));
-    }
-    if (info->stdvga) {
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga"));
     }
     if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
         flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc"));
@@ -459,38 +462,47 @@ static char ** libxl_build_device_model_
         flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial"));
         flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial));
     }
-    if (info->boot) {
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot"));
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot));
-    }
-    if (info->usb) {
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb"));
-        if (info->usbdevice) {
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice"));
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", 
info->usbdevice));
-        }
-    }
-    if (info->apic) {
-        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi"));
-    }
-    if (info->extra) {
-        int i = 0;
-        while (info->extra[i] != NULL) {
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", 
info->extra[i]));
-        }
-    }
-    for (i = 0; i < num_vifs; i++) {
-        if (vifs[i].nictype == NICTYPE_IOEMU) {
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"nic,vlan=%d,macaddr=%s,model=%s",
-                                                        vifs[i].devid, 
vifs[i].smac, vifs[i].model));
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"tap,vlan=%d,ifname=%s,bridge=%s",
-                                                        vifs[i].devid, 
vifs[i].ifname, vifs[i].bridge));
-        }
-    }
+    if (info->type == XENFV) {
+        if (info->videoram) {
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram"));
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", 
info->videoram));
+        }
+        if (info->stdvga) {
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga"));
+        }
+
+        if (info->boot) {
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot"));
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", 
info->boot));
+        }
+        if (info->usb) {
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb"));
+            if (info->usbdevice) {
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"-usbdevice"));
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", 
info->usbdevice));
+            }
+        }
+        if (info->apic) {
+            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi"));
+        }
+        for (i = 0; i < num_vifs; i++) {
+            if (vifs[i].nictype == NICTYPE_IOEMU) {
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"nic,vlan=%d,macaddr=%s,model=%s",
+                            vifs[i].devid, vifs[i].smac, vifs[i].model));
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
+                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"tap,vlan=%d,ifname=%s,bridge=%s",
+                            vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
+            }
+        }
+    }
+    for (i = 0; info->extra && info->extra[i] != NULL; i++)
+        flexarray_set(dm_args, num++, info->extra[i]);
     flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M"));
-    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv"));
+    if (info->type == XENPV)
+        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenpv"));
+    else
+        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv"));
     flexarray_set(dm_args, num++, NULL);
 
     return (char **) flexarray_contents(dm_args);
@@ -579,7 +591,7 @@ int libxl_device_disk_add(struct libxl_c
         case PHYSTYPE_PHY: {
             int major, minor;
 
-            device_disk_major_minor(disk->virtpath, &major, &minor);
+            device_physdisk_major_minor(disk->physpath, &major, &minor);
             flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"physical-device"));
             flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, 
minor));
 
@@ -604,6 +616,8 @@ int libxl_device_disk_add(struct libxl_c
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable"));
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
(disk->unpluggable) ? 1 : 0));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "bootable"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
     flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev"));
@@ -716,25 +730,251 @@ int libxl_device_nic_hard_shutdown(struc
 }
 
 
/******************************************************************************/
-int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid)
+int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_console *console)
+{
+    flexarray_t *front;
+    flexarray_t *back;
+    unsigned int boffset = 0;
+    unsigned int foffset = 0;
+    libxl_device device;
+
+    if (console->build_state) {
+        xs_transaction_t t;
+        char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *));
+        ents[0] = libxl_sprintf(ctx, "console/port");
+        ents[1] = libxl_sprintf(ctx, "%"PRIu32, 
console->build_state->console_port);
+        ents[2] = libxl_sprintf(ctx, "console/ring-ref");
+        ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn);
+        ents[4] = libxl_sprintf(ctx, "console/limit");
+        ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT);
+        ents[6] = libxl_sprintf(ctx, "console/type");
+        if (console->constype == CONSTYPE_XENCONSOLED)
+            ents[7] = "xenconsoled";
+        else
+            ents[7] = "ioemu";
+retry_transaction:
+        t = xs_transaction_start(ctx->xsh);
+        libxl_xs_writev(ctx, t, xs_get_domain_path(ctx->xsh, console->domid), 
ents);
+        if (!xs_transaction_end(ctx->xsh, t, 0))
+            if (errno == EAGAIN)
+                goto retry_transaction;
+    }
+
+    front = flexarray_make(16, 1);
+    if (!front)
+        return ERROR_NOMEM;
+    back = flexarray_make(16, 1);
+    if (!back)
+        return ERROR_NOMEM;
+
+    device.backend_devid = console->devid;
+    device.backend_domid = console->backend_domid;
+    device.backend_kind = DEVICE_CONSOLE;
+    device.devid = console->devid;
+    device.domid = console->domid;
+    device.kind = DEVICE_CONSOLE;
+
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", 
libxl_domid_to_name(ctx, domid)));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "protocol"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
LIBXL_XENCONSOLE_PROTOCOL));
+
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
console->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "limit"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
LIBXL_XENCONSOLE_LIMIT));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
LIBXL_XENCONSOLE_PROTOCOL));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "type"));
+    if (console->constype == CONSTYPE_XENCONSOLED)
+        flexarray_set(front, foffset++, libxl_sprintf(ctx, "xenconsoled"));
+    else
+        flexarray_set(front, foffset++, libxl_sprintf(ctx, "ioemu"));
+
+    libxl_device_generic_add(ctx, &device,
+                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
+                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+
+
+    return 0;
+}
+
+/******************************************************************************/
+int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_vkb *vkb)
+{
+    flexarray_t *front;
+    flexarray_t *back;
+    unsigned int boffset = 0;
+    unsigned int foffset = 0;
+    libxl_device device;
+
+    front = flexarray_make(16, 1);
+    if (!front)
+        return ERROR_NOMEM;
+    back = flexarray_make(16, 1);
+    if (!back)
+        return ERROR_NOMEM;
+
+    device.backend_devid = vkb->devid;
+    device.backend_domid = vkb->backend_domid;
+    device.backend_kind = DEVICE_VKBD;
+    device.devid = vkb->devid;
+    device.domid = vkb->domid;
+    device.kind = DEVICE_VKBD;
+
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", 
libxl_domid_to_name(ctx, domid)));
+
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
vkb->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+
+    libxl_device_generic_add(ctx, &device,
+                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
+                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+
+    return 0;
+}
+
+int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
 {
     return ERROR_NI;
 }
 
-int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
+int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
 {
     return ERROR_NI;
 }
 
-int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
-{
-    return ERROR_NI;
-}
-
 
/******************************************************************************/
-int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid)
-{
-    return ERROR_NI;
+static int libxl_build_xenpv_qemu_args(struct libxl_ctx *ctx,
+                                       libxl_device_vfb *vfb,
+                                       int num_console,
+                                       libxl_device_console *console,
+                                       libxl_device_model_info *info) {
+    int i = 0, j = 0, num = 0;
+    memset(info, 0x00, sizeof(libxl_device_model_info));
+
+    info->vnc = vfb->vnc;
+    if (vfb->vnclisten)
+        info->vnclisten = libxl_sprintf(ctx, "%s", vfb->vnclisten);
+    info->vncdisplay = vfb->vncdisplay;
+    info->vncunused = vfb->vncunused;
+    if (vfb->keymap)
+        info->keymap = libxl_sprintf(ctx, "%s", vfb->keymap);
+    info->sdl = vfb->sdl;
+    info->opengl = vfb->opengl;
+    for (i = 0; i < num_console; i++) {
+        if (console->constype == CONSTYPE_IOEMU)
+            num++;
+    }
+    if (num > 0) {
+        info->serial = "pty";
+        num--;
+    }
+    if (num > 0) {
+        info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *));
+        for (j = 0; j < num * 2; j = j + 2) {
+            info->extra[j] = "-serial";
+            info->extra[j + 1] = "pty";
+        }
+        info->extra[j] = NULL;
+    }
+    info->domid = vfb->domid;
+    info->dom_name = libxl_domid_to_name(ctx, vfb->domid);
+    info->device_model = "/usr/lib/xen/bin/qemu-dm";
+    info->type = XENPV;
+    return 0;
+}
+
+int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb,
+                            int num_console, libxl_device_console *console)
+{
+    libxl_device_model_info info;
+
+    libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info);
+    libxl_create_device_model(ctx, &info, NULL, 0);
+    return 0;
+}
+
+int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_vfb *vfb)
+{
+    flexarray_t *front;
+    flexarray_t *back;
+    unsigned int boffset = 0;
+    unsigned int foffset = 0;
+    libxl_device device;
+
+    front = flexarray_make(16, 1);
+    if (!front)
+        return ERROR_NOMEM;
+    back = flexarray_make(16, 1);
+    if (!back)
+        return ERROR_NOMEM;
+
+    device.backend_devid = vfb->devid;
+    device.backend_domid = vfb->backend_domid;
+    device.backend_kind = DEVICE_VFB;
+    device.devid = vfb->devid;
+    device.domid = vfb->domid;
+    device.kind = DEVICE_VFB;
+
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "domain"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", 
libxl_domid_to_name(ctx, domid)));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "vnc"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "vnclisten"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", vfb->vnclisten));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "vncdisplay"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "vncunused"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "sdl"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "opengl"));
+    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl));
+    if (vfb->xauthority) {
+        flexarray_set(back, boffset++, libxl_sprintf(ctx, "xauthority"));
+        flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", 
vfb->xauthority));
+    }
+    if (vfb->display) {
+        flexarray_set(back, boffset++, libxl_sprintf(ctx, "display"));
+        flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", vfb->display));
+    }
+
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
vfb->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
+    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+
+    libxl_device_generic_add(ctx, &device,
+                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
+                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    flexarray_free(front);
+    flexarray_free(back);
+
+    return 0;
 }
 
 int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/libxl.h       Mon Nov 23 06:54:03 2009 +0000
@@ -76,19 +76,28 @@ typedef struct {
         struct {
             const char *cmdline;
             const char *ramdisk;
+            const char *features;
         } pv;
     } u;
 } libxl_domain_build_info;
 
+typedef struct libxl_domain_build_state_ libxl_domain_build_state;
+
 typedef struct {
     int flags;
     int (*suspend_callback)(void *, int);
 } libxl_domain_suspend_info;
 
+typedef enum {
+    XENFV,
+    XENPV,
+} libxl_qemu_machine_type;
+
 typedef struct {
     int domid;
     char *dom_name;
     char *device_model;
+    libxl_qemu_machine_type type;
     int videoram; /* size of the videoram in MB */
     bool stdvga; /* stdvga enabled or disabled */
     bool vnc; /* vnc enabled or disabled */
@@ -108,6 +117,40 @@ typedef struct {
     /* Network is missing */
 } libxl_device_model_info;
 
+typedef struct {
+    uint32_t backend_domid;
+    uint32_t domid;
+    int devid;
+    bool vnc; /* vnc enabled or disabled */
+    char *vnclisten; /* address:port that should be listened on for the VNC 
server if vnc is set */
+    int vncdisplay; /* set VNC display number */
+    bool vncunused; /* try to find an unused port for the VNC server */
+    char *keymap; /* set keyboard layout, default is en-us keyboard */
+    bool sdl; /* sdl enabled or disabled */
+    bool opengl; /* opengl enabled or disabled (if enabled requires sdl 
enabled) */
+    char *display;
+    char *xauthority;
+} libxl_device_vfb;
+
+typedef struct {
+    uint32_t backend_domid;
+    uint32_t domid;
+    int devid;
+} libxl_device_vkb;
+
+typedef enum {
+    CONSTYPE_XENCONSOLED,
+    CONSTYPE_IOEMU,
+} libxl_console_constype;
+
+typedef struct {
+    uint32_t backend_domid;
+    uint32_t domid;
+    int devid;
+    libxl_console_constype constype;
+    libxl_domain_build_state *build_state;
+} libxl_device_console;
+
 typedef enum {
     PHYSTYPE_QCOW,
     PHYSTYPE_QCOW2,
@@ -179,7 +222,7 @@ int libxl_ctx_set_log(struct libxl_ctx *
 
 /* domain related functions */
 int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, 
uint32_t *domid);
-int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, 
uint32_t domid);
+libxl_domain_build_state *libxl_domain_build(struct libxl_ctx *ctx, 
libxl_domain_build_info *info, uint32_t domid);
 int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
                           uint32_t domid, int fd);
 int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info 
*info,
@@ -196,6 +239,8 @@ int libxl_create_device_model(struct lib
 int libxl_create_device_model(struct libxl_ctx *ctx,
                               libxl_device_model_info *info,
                               libxl_device_nic *vifs, int num_vifs);
+int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb,
+                            int num_console, libxl_device_console *console);
 
 int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_disk *disk);
 int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
@@ -205,11 +250,13 @@ int libxl_device_nic_clean_shutdown(stru
 int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 
-int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid);
+int libxl_device_console_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_console *console);
+
+int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_vkb *vkb);
 int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 
-int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid);
+int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_vfb *vfb);
 int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 
diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/libxl_device.c        Mon Nov 23 06:54:03 2009 +0000
@@ -19,6 +19,9 @@
 #include "libxl.h"
 #include "libxl_internal.h"
 #include <sys/time.h> /* for struct timeval */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 char *string_of_kinds[] = {
     [DEVICE_VIF] = "vif",
@@ -27,6 +30,7 @@ char *string_of_kinds[] = {
     [DEVICE_PCI] = "pci",
     [DEVICE_VFB] = "vfb",
     [DEVICE_VKBD] = "vkbd",
+    [DEVICE_CONSOLE] = "console",
 };
 
 int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,
@@ -118,7 +122,17 @@ char *device_disk_backend_type_of_physty
     }
 }
 
-int device_disk_major_minor(char *virtpath, int *major, int *minor)
+int device_physdisk_major_minor(char *physpath, int *major, int *minor)
+{
+    struct stat buf;
+    if (stat(physpath, &buf) < 0)
+        return -1;
+    *major = major(buf.st_rdev);
+    *minor = minor(buf.st_rdev);
+    return 0;
+}
+
+int device_virtdisk_major_minor(char *virtpath, int *major, int *minor)
 {
     if (strstr(virtpath, "sd") == virtpath) {
         return -1;
@@ -146,9 +160,14 @@ int device_disk_dev_number(char *virtpat
     int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 };
     int major, minor;
 
-    if (device_disk_major_minor(virtpath, &major, &minor))
-        return -1;
-    return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor;
+    if (strstr(virtpath, "hd") == virtpath) {
+        if (device_virtdisk_major_minor(virtpath, &major, &minor))
+            return -1;
+        return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor;
+    } else if (strstr(virtpath, "xvd") == virtpath) {
+        return (202 << 8) + ((virtpath[3] - 'a') << 4) + (virtpath[4] ? 
(virtpath[4] - '0') : 0);
+    }
+    return -1;
 }
 
 int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force)
diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/libxl_dom.c   Mon Nov 23 06:54:03 2009 +0000
@@ -15,8 +15,11 @@
 
 #include "libxl.h"
 #include "libxl_internal.h"
+#include <stdio.h>
 #include <inttypes.h>
 #include <xenguest.h>
+#include <xenctrl.h>
+#include <xc_dom.h>
 #include <string.h>
 #include <sys/time.h> /* for struct timeval */
 #include <unistd.h> /* for sleep(2) */
@@ -37,7 +40,6 @@ int build_pre(struct libxl_ctx *ctx, uin
 int build_pre(struct libxl_ctx *ctx, uint32_t domid,
               libxl_domain_build_info *info, libxl_domain_build_state *state)
 {
-    unsigned long shadow;
     if (info->timer_mode != -1)
         xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_TIMER_MODE,
                 (unsigned long) info->timer_mode);
@@ -48,8 +50,12 @@ int build_pre(struct libxl_ctx *ctx, uin
     xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus);
     xc_domain_setmaxmem(ctx->xch, domid, info->max_memkb + info->video_memkb);
     xc_domain_set_memmap_limit(ctx->xch, domid, info->max_memkb);
-    shadow = (info->shadow_memkb + 1023) / 1024;
-    xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, 
NULL, 0, &shadow, 0, NULL);
+
+    if (info->hvm) {
+        unsigned long shadow;
+        shadow = (info->shadow_memkb + 1023) / 1024;
+        xc_shadow_control(ctx->xch, domid, 
XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL);
+    }
 
     state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0);
     state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0);
@@ -64,7 +70,7 @@ int build_post(struct libxl_ctx *ctx, ui
     xs_transaction_t t;
     char **ents;
 
-    ents = libxl_calloc(ctx, 6 * 2, sizeof(char *));
+    ents = libxl_calloc(ctx, 10 * 2, sizeof(char *));
     ents[0] = libxl_sprintf(ctx, "memory/static-max");
     ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb);
     ents[2] = libxl_sprintf(ctx, "memory/target");
@@ -95,14 +101,25 @@ int build_pv(struct libxl_ctx *ctx, uint
 int build_pv(struct libxl_ctx *ctx, uint32_t domid,
              libxl_domain_build_info *info, libxl_domain_build_state *state)
 {
-#if 0 /* unused variables */
-    int mem_target_kib = info->max_memkb;
-    char *domid_str = libxl_sprintf(ctx, "%d", domid);
-    char *memsize_str = libxl_sprintf(ctx, "%d", mem_target_kib / 1024);
-    char *store_port_str = libxl_sprintf(ctx, "%d", state->store_port);
-    char *console_port_str = libxl_sprintf(ctx, "%d", state->console_port);
-#endif
-    return ERROR_NI;
+    struct xc_dom_image *dom;
+    int ret;
+    int flags = 0;
+
+    dom = xc_dom_allocate(info->u.pv.cmdline, info->u.pv.features);
+    if (!dom) {
+        XL_LOG(ctx, XL_LOG_ERROR, "xc_dom_allocate failed: %d", dom);
+        return -1;
+    }
+    if ((ret = xc_dom_linux_build(ctx->xch, dom, domid, info->max_memkb / 1024,
+                                  info->kernel, info->u.pv.ramdisk, flags,
+                                  state->store_port, &state->store_mfn,
+                                  state->console_port, &state->console_mfn)) 
!= 0) {
+        xc_dom_release(dom);
+        XL_LOG(ctx, XL_LOG_ERROR, "xc_dom_linux_build failed: %d", ret);
+        return -2;
+    }
+    xc_dom_release(dom);
+    return 0;
 }
 
 int build_hvm(struct libxl_ctx *ctx, uint32_t domid,
diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/libxl_internal.h      Mon Nov 23 06:54:03 2009 +0000
@@ -15,7 +15,7 @@
  */
 
 #ifndef LIBXL_INTERNAL_H
-# define LIBXL_INTERNAL_H
+#define LIBXL_INTERNAL_H
 
 #include <stdint.h>
 #include <stdarg.h>
@@ -28,6 +28,8 @@
 #include "libxl_utils.h"
 
 #define LIBXL_DESTROY_TIMEOUT 10
+#define LIBXL_XENCONSOLE_LIMIT 1048576
+#define LIBXL_XENCONSOLE_PROTOCOL "vt100"
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
@@ -47,12 +49,12 @@
 
 void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, 
const char *func, char *fmt, ...);
 
-typedef struct {
+struct libxl_domain_build_state_ {
     uint32_t store_port;
     unsigned long store_mfn;
     uint32_t console_port;
     unsigned long console_mfn;
-} libxl_domain_build_state;
+};
 
 typedef enum {
     DEVICE_VIF,
@@ -61,6 +63,7 @@ typedef enum {
     DEVICE_PCI,
     DEVICE_VFB,
     DEVICE_VKBD,
+    DEVICE_CONSOLE,
 } libxl_device_kinds;
 
 typedef struct {
@@ -119,7 +122,8 @@ char *device_disk_backend_type_of_physty
 char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype);
 char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
 
-int device_disk_major_minor(char *virtpath, int *major, int *minor);
+int device_physdisk_major_minor(char *physpath, int *major, int *minor);
+int device_virtdisk_major_minor(char *virtpath, int *major, int *minor);
 int device_disk_dev_number(char *virtpath);
 
 int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,
diff -r bcc6cd1122ea -r 014579af0350 tools/libxl/xl.c
--- a/tools/libxl/xl.c  Mon Nov 23 06:52:35 2009 +0000
+++ b/tools/libxl/xl.c  Mon Nov 23 06:54:03 2009 +0000
@@ -42,10 +42,14 @@ static void printf_info(libxl_domain_cre
                         int num_vifs,
                         libxl_device_pci *pcidevs,
                         int num_pcidevs,
+                        libxl_device_vfb *vfbs,
+                        int num_vfbs,
+                        libxl_device_vkb *vkb,
+                        int num_vkbs,
                         libxl_device_model_info *dm_info)
 {
     int i;
-    char uuid_str[18];
+    char uuid_str[37];
     printf("*** domain_create_info ***\n");
     printf("hvm: %d\n", c_info->hvm);
     printf("hap: %d\n", c_info->hap);
@@ -69,12 +73,12 @@ static void printf_info(libxl_domain_cre
     printf("vpt_align: %d\n", b_info->vpt_align);
     printf("max_vcpus: %d\n", b_info->max_vcpus);
     printf("max_memkb: %d\n", b_info->max_memkb);
-    printf("video_memkb: %d\n", b_info->video_memkb);
-    printf("shadow_memkb: %d\n", b_info->shadow_memkb);
     printf("kernel: %s\n", b_info->kernel);
     printf("hvm: %d\n", b_info->hvm);
 
-    if (b_info->hvm) {
+    if (c_info->hvm) {
+        printf("video_memkb: %d\n", b_info->video_memkb);
+        printf("shadow_memkb: %d\n", b_info->shadow_memkb);
         printf("    pae: %d\n", b_info->u.hvm.pae);
         printf("    apic: %d\n", b_info->u.hvm.apic);
         printf("    acpi: %d\n", b_info->u.hvm.acpi);
@@ -114,25 +118,43 @@ static void printf_info(libxl_domain_cre
         printf("opts msitranslate %d power_mgmt %d\n", 
pcidevs[i].msitranslate, pcidevs[i].power_mgmt);
     }
 
-    printf("\n\n\n*** device_model_info ***\n");
-    printf("domid: %d\n", dm_info->domid);
-    printf("dom_name: %s\n", dm_info->dom_name);
-    printf("device_model: %s\n", dm_info->device_model);
-    printf("videoram: %d\n", dm_info->videoram);
-    printf("stdvga: %d\n", dm_info->stdvga);
-    printf("vnc: %d\n", dm_info->vnc);
-    printf("vnclisten: %s\n", dm_info->vnclisten);
-    printf("vncdisplay: %d\n", dm_info->vncdisplay);
-    printf("vncunused: %d\n", dm_info->vncunused);
-    printf("keymap: %s\n", dm_info->keymap);
-    printf("sdl: %d\n", dm_info->sdl);
-    printf("opengl: %d\n", dm_info->opengl);
-    printf("nographic: %d\n", dm_info->nographic);
-    printf("serial: %s\n", dm_info->serial);
-    printf("boot: %s\n", dm_info->boot);
-    printf("usb: %d\n", dm_info->usb);
-    printf("usbdevice: %s\n", dm_info->usbdevice);
-    printf("apic: %d\n", dm_info->apic);
+    for (i = 0; i < num_vfbs; i++) {
+        printf("\n\n\n*** vfbs_info: %d ***\n", i);
+        printf("backend_domid %d\n", vfbs[i].backend_domid);
+        printf("domid %d\n", vfbs[i].domid);
+        printf("devid %d\n", vfbs[i].devid);
+        printf("vnc: %d\n", vfbs[i].vnc);
+        printf("vnclisten: %s\n", vfbs[i].vnclisten);
+        printf("vncdisplay: %d\n", vfbs[i].vncdisplay);
+        printf("vncunused: %d\n", vfbs[i].vncunused);
+        printf("keymap: %s\n", vfbs[i].keymap);
+        printf("sdl: %d\n", vfbs[i].sdl);
+        printf("opengl: %d\n", vfbs[i].opengl);
+        printf("display: %s\n", vfbs[i].display);
+        printf("xauthority: %s\n", vfbs[i].xauthority);
+    }
+
+    if (c_info->hvm) {
+        printf("\n\n\n*** device_model_info ***\n");
+        printf("domid: %d\n", dm_info->domid);
+        printf("dom_name: %s\n", dm_info->dom_name);
+        printf("device_model: %s\n", dm_info->device_model);
+        printf("videoram: %d\n", dm_info->videoram);
+        printf("stdvga: %d\n", dm_info->stdvga);
+        printf("vnc: %d\n", dm_info->vnc);
+        printf("vnclisten: %s\n", dm_info->vnclisten);
+        printf("vncdisplay: %d\n", dm_info->vncdisplay);
+        printf("vncunused: %d\n", dm_info->vncunused);
+        printf("keymap: %s\n", dm_info->keymap);
+        printf("sdl: %d\n", dm_info->sdl);
+        printf("opengl: %d\n", dm_info->opengl);
+        printf("nographic: %d\n", dm_info->nographic);
+        printf("serial: %s\n", dm_info->serial);
+        printf("boot: %s\n", dm_info->boot);
+        printf("usb: %d\n", dm_info->usb);
+        printf("usbdevice: %s\n", dm_info->usbdevice);
+        printf("apic: %d\n", dm_info->apic);
+    }
 }
 
 static char* compat_config_file(const char *filename)
@@ -208,10 +230,10 @@ void init_build_info(libxl_domain_build_
     b_info->vpt_align = -1;
     b_info->max_vcpus = 1;
     b_info->max_memkb = 32 * 1024;
-    b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, 
b_info->max_vcpus);
-    b_info->video_memkb = 8 * 1024;
-    b_info->kernel = "/usr/lib/xen/boot/hvmloader";
     if (c_info->hvm) {
+        b_info->shadow_memkb = 
libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus);
+        b_info->video_memkb = 8 * 1024;
+        b_info->kernel = "/usr/lib/xen/boot/hvmloader";
         b_info->hvm = 1;
         b_info->u.hvm.pae = 1;
         b_info->u.hvm.apic = 1;
@@ -282,9 +304,52 @@ void disk_info_domid_fixup(libxl_device_
     disk_info->domid = domid;
 }
 
+void vfb_info_domid_fixup(libxl_device_vfb *vfb, int domid)
+{
+    vfb->domid = domid;
+}
+
+void vkb_info_domid_fixup(libxl_device_vkb *vkb, int domid)
+{
+    vkb->domid = domid;
+}
+
+void console_info_domid_fixup(libxl_device_console *console, int domid)
+{
+    console->domid = domid;
+}
+
 void device_model_info_domid_fixup(libxl_device_model_info *dm_info, int domid)
 {
     dm_info->domid = domid;
+}
+
+void init_vfb_info(libxl_device_vfb *vfb, int dev_num)
+{
+    memset(vfb, 0x00, sizeof(libxl_device_vfb));
+    vfb->devid = dev_num;
+    vfb->vnc = 1;
+    vfb->vnclisten = "127.0.0.1";
+    vfb->vncdisplay = 0;
+    vfb->vncunused = 1;
+    vfb->keymap = NULL;
+    vfb->sdl = 0;
+    vfb->opengl = 0;
+}
+
+void init_vkb_info(libxl_device_vkb *vkb, int dev_num)
+{
+    memset(vkb, 0x00, sizeof(libxl_device_vkb));
+    vkb->devid = dev_num;
+}
+
+void init_console_info(libxl_device_console *console, int dev_num, 
libxl_domain_build_state *state)
+{
+    memset(console, 0x00, sizeof(libxl_device_console));
+    console->devid = dev_num;
+    console->constype = CONSTYPE_XENCONSOLED;
+    if (state)
+        console->build_state = state;
 }
 
 static void parse_config_file(const char *filename,
@@ -296,13 +361,17 @@ static void parse_config_file(const char
                               int *num_vifs,
                               libxl_device_pci **pcidevs,
                               int *num_pcidevs,
+                              libxl_device_vfb **vfbs,
+                              int *num_vfbs,
+                              libxl_device_vkb **vkbs,
+                              int *num_vkbs,
                               libxl_device_model_info *dm_info)
 {
     const char *buf;
     xen_uuid_t uuid[16];
     long l;
     struct config_t config;
-    struct config_setting_t *vbds, *nics, *pcis;
+    struct config_setting_t *vbds, *nics, *pcis, *cvfbs;
     int pci_power_mgmt = 0;
     int pci_msitranslate = 1;
 
@@ -367,10 +436,13 @@ static void parse_config_file(const char
         if (config_lookup_int (&config, "viridian", &l) == CONFIG_TRUE)
             b_info->u.hvm.viridian = l;
     } else {
-        if (config_lookup_string (&config, "cmdline", &buf) == CONFIG_TRUE)
-            b_info->u.pv.cmdline = buf;
+        char *cmdline;
+        if (config_lookup_string (&config, "root", &buf) == CONFIG_TRUE) {
+            asprintf(&cmdline, "root=%s", buf);
+            b_info->u.pv.cmdline = cmdline;
+        }
         if (config_lookup_string (&config, "ramdisk", &buf) == CONFIG_TRUE)
-            b_info->u.pv.ramdisk = buf;
+            b_info->u.pv.ramdisk = strdup(buf);
     }
 
     if ((vbds = config_lookup (&config, "disk")) != NULL) {
@@ -494,6 +566,56 @@ skip:
         }
     }
 
+    if ((cvfbs = config_lookup (&config, "vfb")) != NULL) {
+        *num_vfbs = 0;
+        *num_vkbs = 0;
+        *vfbs = NULL;
+        *vkbs = NULL;
+        while ((buf = config_setting_get_string_elem (cvfbs, *num_vfbs)) != 
NULL) {
+            char *buf2 = strdup(buf);
+            char *p, *p2;
+            *vfbs = (libxl_device_vfb *) realloc(*vfbs, 
sizeof(libxl_device_vfb) * ((*num_vfbs) + 1));
+            init_vfb_info((*vfbs) + (*num_vfbs), (*num_vfbs));
+
+            *vkbs = (libxl_device_vkb *) realloc(*vkbs, 
sizeof(libxl_device_vkb) * ((*num_vkbs) + 1));
+            init_vkb_info((*vkbs) + (*num_vkbs), (*num_vkbs));
+
+            p = strtok(buf2, ",");
+            if (!p)
+                goto skip_vfb;
+            do {
+                while (*p == ' ')
+                    p++;
+                if ((p2 = strchr(p, '=')) == NULL)
+                    break;
+                *p2 = '\0';
+                if (!strcmp(p, "vnc")) {
+                    (*vfbs)[*num_vfbs].vnc = atoi(p2 + 1);
+                } else if (!strcmp(p, "vnclisten")) {
+                    (*vfbs)[*num_vfbs].vnclisten = strdup(p2 + 1);
+                } else if (!strcmp(p, "vncdisplay")) {
+                    (*vfbs)[*num_vfbs].vncdisplay = atoi(p2 + 1);
+                } else if (!strcmp(p, "vncunused")) {
+                    (*vfbs)[*num_vfbs].vncunused = atoi(p2 + 1);
+                } else if (!strcmp(p, "keymap")) {
+                    (*vfbs)[*num_vfbs].keymap = strdup(p2 + 1);
+                } else if (!strcmp(p, "sdl")) {
+                    (*vfbs)[*num_vfbs].sdl = atoi(p2 + 1);
+                } else if (!strcmp(p, "opengl")) {
+                    (*vfbs)[*num_vfbs].opengl = atoi(p2 + 1);
+                } else if (!strcmp(p, "display")) {
+                    (*vfbs)[*num_vfbs].display = strdup(p2 + 1);
+                } else if (!strcmp(p, "xauthority")) {
+                    (*vfbs)[*num_vfbs].xauthority = strdup(p2 + 1);
+                }
+            } while ((p = strtok(NULL, ",")) != NULL);
+skip_vfb:
+            free(buf2);
+            *num_vfbs = (*num_vfbs) + 1;
+            *num_vkbs = (*num_vkbs) + 1;
+        }
+    }
+
     if (config_lookup_int (&config, "pci_msitranslate", &l) == CONFIG_TRUE)
         pci_msitranslate = l;
 
@@ -536,38 +658,40 @@ skip_pci:
         }
     }
 
-    /* init dm from c and b */
-    init_dm_info(dm_info, c_info, b_info);
-
-    /* then process config related to dm */
-    if (config_lookup_string (&config, "device_model", &buf) == CONFIG_TRUE)
-        dm_info->device_model = strdup(buf);
-    if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE)
-        dm_info->stdvga = l;
-    if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE)
-        dm_info->vnc = l;
-    if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE)
-        dm_info->vnclisten = strdup(buf);
-    if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE)
-        dm_info->vncdisplay = l;
-    if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE)
-        dm_info->vncunused = l;
-    if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE)
-        dm_info->keymap = strdup(buf);
-    if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE)
-        dm_info->sdl = l;
-    if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE)
-        dm_info->opengl = l;
-    if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE)
-        dm_info->nographic = l;
-    if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE)
-        dm_info->serial = strdup(buf);
-    if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE)
-        dm_info->boot = strdup(buf);
-    if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE)
-        dm_info->usb = l;
-    if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE)
-        dm_info->usbdevice = strdup(buf);
+    if (c_info->hvm == 1) {
+        /* init dm from c and b */
+        init_dm_info(dm_info, c_info, b_info);
+
+        /* then process config related to dm */
+        if (config_lookup_string (&config, "device_model", &buf) == 
CONFIG_TRUE)
+            dm_info->device_model = strdup(buf);
+        if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE)
+            dm_info->stdvga = l;
+        if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE)
+            dm_info->vnc = l;
+        if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE)
+            dm_info->vnclisten = strdup(buf);
+        if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE)
+            dm_info->vncdisplay = l;
+        if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE)
+            dm_info->vncunused = l;
+        if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE)
+            dm_info->keymap = strdup(buf);
+        if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE)
+            dm_info->sdl = l;
+        if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE)
+            dm_info->opengl = l;
+        if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE)
+            dm_info->nographic = l;
+        if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE)
+            dm_info->serial = strdup(buf);
+        if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE)
+            dm_info->boot = strdup(buf);
+        if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE)
+            dm_info->usb = l;
+        if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE)
+            dm_info->usbdevice = strdup(buf);
+    }
 
     config_destroy(&config);
 }
@@ -578,24 +702,26 @@ static void create_domain(int debug, con
     uint32_t domid;
     libxl_domain_create_info info1;
     libxl_domain_build_info info2;
+    libxl_domain_build_state *state;
     libxl_device_model_info dm_info;
     libxl_device_disk *disks = NULL;
     libxl_device_nic *vifs = NULL;
     libxl_device_pci *pcidevs = NULL;
-    int num_disks = 0, num_vifs = 0, num_pcidevs = 0;
+    libxl_device_vfb *vfbs = NULL;
+    libxl_device_vkb *vkbs = NULL;
+    libxl_device_console console;
+    int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 
0;
     int i;
 
     printf("Parsing config file %s\n", filename);
-    parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, 
&num_vifs, &pcidevs, &num_pcidevs, &dm_info);
+    parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, 
&num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, 
&dm_info);
     if (debug)
-        printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, 
num_pcidevs, &dm_info);
+        printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, 
num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info);
 
     libxl_ctx_init(&ctx);
     libxl_ctx_set_log(&ctx, log_callback, NULL);
     libxl_domain_make(&ctx, &info1, &domid);
-    libxl_domain_build(&ctx, &info2, domid);
-
-    device_model_info_domid_fixup(&dm_info, domid);
+    state = libxl_domain_build(&ctx, &info2, domid);
 
     for (i = 0; i < num_disks; i++) {
         disk_info_domid_fixup(disks + i, domid);
@@ -605,7 +731,24 @@ static void create_domain(int debug, con
         nic_info_domid_fixup(vifs + i, domid);
         libxl_device_nic_add(&ctx, domid, &vifs[i]);
     }
-    libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs);
+    if (info1.hvm) {
+        device_model_info_domid_fixup(&dm_info, domid);
+        libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs);
+    } else {
+        for (i = 0; i < num_vfbs; i++) {
+            vfb_info_domid_fixup(vfbs + i, domid);
+            libxl_device_vfb_add(&ctx, domid, &vfbs[i]);
+            vkb_info_domid_fixup(vkbs + i, domid);
+            libxl_device_vkb_add(&ctx, domid, &vkbs[i]);
+        }
+        init_console_info(&console, 0, state);
+        console_info_domid_fixup(&console, domid);
+        if (num_vfbs)
+            console.constype = CONSTYPE_IOEMU;
+        libxl_device_console_add(&ctx, domid, &console);
+        if (num_vfbs)
+            libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console);
+    }
     for (i = 0; i < num_pcidevs; i++)
         libxl_device_pci_add(&ctx, domid, &pcidevs[i]);
     libxl_domain_unpause(&ctx, domid);

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


 


Rackspace

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