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

[Xen-devel] [PATCH] libxenlight: implement support for pv guests



Hi all,
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>

---


diff -r bec27eb6f72c tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/libxl.c       Tue Nov 17 16:36:08 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 @@
 
     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 @@
     return 0;
 }
 
-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)
 {
-    libxl_domain_build_state state;
+    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_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 0;
+    build_post(ctx, domid, info, state, vments, localents);
+    return state;
 }
 
 int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
@@ -414,13 +424,6 @@
         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"));
         if (info->vncdisplay) {
@@ -459,38 +462,47 @@
         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->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));
+            }
         }
     }
-    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));
-        }
-    }
+    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 @@
         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 @@
     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,9 +730,125 @@
 }
 
 
/******************************************************************************/
-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)
 {
-    return ERROR_NI;
+    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)
@@ -732,9 +862,119 @@
 }
 
 
/******************************************************************************/
-int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid)
+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)
 {
-    return ERROR_NI;
+    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 bec27eb6f72c tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/libxl.h       Tue Nov 17 16:36:08 2009 +0000
@@ -76,19 +76,28 @@
         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 */
@@ -107,6 +116,40 @@
     char **extra; /* extra parameters pass directly to qemu, NULL terminated */
     /* 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,
@@ -179,7 +222,7 @@
 
 /* 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 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(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 bec27eb6f72c tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/libxl_device.c        Tue Nov 17 16:36:08 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 @@
     [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 @@
     }
 }
 
-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 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 bec27eb6f72c tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/libxl_dom.c   Tue Nov 17 16:36:08 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, 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 @@
     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 @@
     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, 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 bec27eb6f72c tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/libxl_internal.h      Tue Nov 17 16:36:08 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 @@
     DEVICE_PCI,
     DEVICE_VFB,
     DEVICE_VKBD,
+    DEVICE_CONSOLE,
 } libxl_device_kinds;
 
 typedef struct {
@@ -119,7 +122,8 @@
 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 bec27eb6f72c tools/libxl/xl.c
--- a/tools/libxl/xl.c  Sat Nov 14 10:32:59 2009 +0000
+++ b/tools/libxl/xl.c  Tue Nov 17 16:36:08 2009 +0000
@@ -42,10 +42,14 @@
                         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 @@
     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 @@
         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 @@
     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 @@
     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 @@
                               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 @@
         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 @@
         }
     }
 
+    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 @@
         }
     }
 
-    /* init dm from c and b */
-    init_dm_info(dm_info, c_info, b_info);
+    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);
+        /* 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 @@
     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 @@
         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-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®.