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

[Xen-changelog] [xen-unstable] Merge



# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1170264137 0
# Node ID 5d09e6098f93da0f4cd96c21b6ab0230a38e5048
# Parent  5e66c05c67ad704763f412d2ee9254cf0c881562
# Parent  56377f5ce588b098a0f46f77f57efc22dd2dc1cf
Merge
---
 tools/libxen/Makefile                             |    3 
 tools/libxen/include/xen_vdi.h                    |    1 
 tools/libxen/src/xen_vdi.c                        |    3 
 tools/libxen/test/test_bindings.c                 |   12 
 tools/libxen/test/test_hvm_bindings.c             |  445 ++++++++++++++++++++++
 tools/python/scripts/test_hvm_create.py           |   21 -
 tools/python/scripts/test_vm_create.py            |   24 -
 tools/python/scripts/xapi.py                      |    4 
 tools/python/xen/xend/XendAPI.py                  |   35 +
 tools/python/xen/xend/XendAuthSessions.py         |    9 
 tools/python/xen/xend/XendConfig.py               |  177 +++++++-
 tools/python/xen/xend/XendDomainInfo.py           |   71 ++-
 tools/python/xen/xend/XendVDI.py                  |   15 
 tools/python/xen/xend/image.py                    |   95 ++--
 tools/python/xen/xend/server/ConsoleController.py |    6 
 tools/python/xen/xend/server/vfbif.py             |   69 +++
 tools/xcutils/readnotes.c                         |    4 
 xen/arch/x86/x86_64/compat/entry.S                |    7 
 xen/include/public/arch-x86/xen-x86_32.h          |    2 
 19 files changed, 854 insertions(+), 149 deletions(-)

diff -r 5e66c05c67ad -r 5d09e6098f93 tools/libxen/Makefile
--- a/tools/libxen/Makefile     Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/libxen/Makefile     Wed Jan 31 17:22:17 2007 +0000
@@ -51,6 +51,9 @@ test/test_bindings: test/test_bindings.o
 test/test_bindings: test/test_bindings.o libxenapi.so
        $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
 
+test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
+       $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
+
 
 .PHONY: install
 install: all
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/libxen/include/xen_vdi.h
--- a/tools/libxen/include/xen_vdi.h    Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/libxen/include/xen_vdi.h    Wed Jan 31 17:22:17 2007 +0000
@@ -74,6 +74,7 @@ typedef struct xen_vdi_record
     int64_t virtual_size;
     int64_t physical_utilisation;
     int64_t sector_size;
+    char *location;
     enum xen_vdi_type type;
     bool sharable;
     bool read_only;
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/libxen/src/xen_vdi.c
--- a/tools/libxen/src/xen_vdi.c        Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/libxen/src/xen_vdi.c        Wed Jan 31 17:22:17 2007 +0000
@@ -67,6 +67,9 @@ static const struct_member xen_vdi_recor
         { .key = "sector_size",
           .type = &abstract_type_int,
           .offset = offsetof(xen_vdi_record, sector_size) },
+        { .key = "location",
+          .type = &abstract_type_string,
+          .offset = offsetof(xen_vdi_record, location) },
         { .key = "type",
           .type = &xen_vdi_type_abstract_type_,
           .offset = offsetof(xen_vdi_record, type) },
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/libxen/test/test_bindings.c
--- a/tools/libxen/test/test_bindings.c Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/libxen/test/test_bindings.c Wed Jan 31 17:22:17 2007 +0000
@@ -295,10 +295,10 @@ static xen_vm create_new_vm(xen_session 
             .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
             .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
             .hvm_boot = "",
-            .pv_bootloader = "pygrub",
-            .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
+            //.pv_bootloader = "pygrub",
+            .pv_kernel = "/boot/vmlinuz-2.6.18-xenU",
             .pv_ramdisk = "",
-            .pv_args = "",
+            .pv_args = "root=/dev/sda1 ro",
             .pv_bootloader_args = ""
         };
 
@@ -338,6 +338,7 @@ static xen_vm create_new_vm(xen_session 
             .sr = &sr_record,
             .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
             .sector_size = 512,
+            .location = "file:/root/gentoo.amd64.img",
             .type = XEN_VDI_TYPE_SYSTEM,
             .sharable = false,
             .read_only = false
@@ -367,8 +368,9 @@ static xen_vm create_new_vm(xen_session 
         {
             .vm = &vm_record_opt,
             .vdi = &vdi0_record_opt,
-            .device = "xvda1",
-            .mode = XEN_VBD_MODE_RW
+            .device = "sda1",
+            .mode = XEN_VBD_MODE_RW,
+            .bootable = 1,
         };
 
     xen_vbd vbd0;
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/libxen/test/test_hvm_bindings.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxen/test/test_hvm_bindings.c     Wed Jan 31 17:22:17 2007 +0000
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2006 XenSource, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#define _GNU_SOURCE
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <curl/curl.h>
+
+#include "xen_host.h"
+#include "xen_sr.h"
+#include "xen_vbd.h"
+#include "xen_vdi.h"
+#include "xen_vm.h"
+
+
+static void usage()
+{
+    fprintf(stderr,
+"Usage:\n"
+"\n"
+"    test_bindings <url> <username> <password>\n"
+"\n"
+"where\n"
+"        <url>      is a fragment of the server's URL, e.g. 
localhost:8005/RPC2;\n"
+"        <username> is the username to use at the server; and\n"
+"        <password> is the password.\n");
+
+    exit(EXIT_FAILURE);
+}
+
+
+static char *url;
+
+
+typedef struct
+{
+    xen_result_func func;
+    void *handle;
+} xen_comms;
+
+
+static xen_vm create_new_vm(xen_session *session);
+static void print_vm_power_state(xen_session *session, xen_vm vm);
+
+
+static size_t
+write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
+{
+    size_t n = size * nmemb;
+    return comms->func(ptr, n, comms->handle) ? n : 0;
+}
+
+
+static int
+call_func(const void *data, size_t len, void *user_handle,
+          void *result_handle, xen_result_func result_func)
+{
+    (void)user_handle;
+
+    CURL *curl = curl_easy_init();
+    if (!curl) {
+        return -1;
+    }
+
+    xen_comms comms = {
+        .func = result_func,
+        .handle = result_handle
+    };
+
+    curl_easy_setopt(curl, CURLOPT_URL, url);
+    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(curl, CURLOPT_MUTE, 1);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
+    curl_easy_setopt(curl, CURLOPT_POST, 1);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
+
+    CURLcode result = curl_easy_perform(curl);
+
+    curl_easy_cleanup(curl);
+
+    return result;
+}
+
+
+static void print_error(xen_session *session)
+{
+    fprintf(stderr, "Error: %d", session->error_description_count);
+    for (int i = 0; i < session->error_description_count; i++)
+    {
+        fprintf(stderr, "%s ", session->error_description[i]);
+    }
+    fprintf(stderr, "\n");
+}
+
+
+int main(int argc, char **argv)
+{
+    if (argc != 4)
+    {
+        usage();
+    }
+
+    url = argv[1];
+    char *username = argv[2];
+    char *password = argv[3];
+
+    xmlInitParser();
+    xen_init();
+    curl_global_init(CURL_GLOBAL_ALL);
+
+#define CLEANUP                                 \
+    do {                                        \
+        xen_session_logout(session);            \
+        curl_global_cleanup();                  \
+        xen_fini();                             \
+        xmlCleanupParser();                     \
+    } while(0)                                  \
+
+    
+    xen_session *session =
+        xen_session_login_with_password(call_func, NULL, username, password);
+
+    xen_vm vm;
+    if (!xen_vm_get_by_uuid(session, &vm,
+                            "00000000-0000-0000-0000-000000000000"))
+    {
+        print_error(session);
+        CLEANUP;
+        return 1;
+    }
+
+    char *vm_uuid;
+    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+    {
+        print_error(session);
+        xen_vm_free(vm);
+        CLEANUP;
+        return 1;
+    }
+
+    char *vm_uuid_bytes;
+    if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes))
+    {
+        fprintf(stderr, "xen_uuid_string_to_bytes failed.\n");
+        xen_uuid_free(vm_uuid);
+        xen_vm_free(vm);
+        CLEANUP;
+        return 1;
+    }
+
+    xen_vm_record *vm_record;
+    if (!xen_vm_get_record(session, &vm_record, vm))
+    {
+        print_error(session);
+        xen_uuid_bytes_free(vm_uuid_bytes);
+        xen_uuid_free(vm_uuid);
+        xen_vm_free(vm);
+        CLEANUP;
+        return 1;
+    }
+
+    xen_host host;
+    if (!xen_session_get_this_host(session, &host))
+    {
+        print_error(session);
+        xen_vm_record_free(vm_record);
+        xen_uuid_bytes_free(vm_uuid_bytes);
+        xen_uuid_free(vm_uuid);
+        xen_vm_free(vm);
+        CLEANUP;
+        return 1;
+    }
+
+    xen_string_string_map *versions;
+    if (!xen_host_get_software_version(session, &versions, host))
+    {
+        print_error(session);
+        xen_host_free(host);
+        xen_vm_record_free(vm_record);
+        xen_uuid_bytes_free(vm_uuid_bytes);
+        xen_uuid_free(vm_uuid);
+        xen_vm_free(vm);
+        CLEANUP;
+        return 1;
+    }
+
+    printf("%s.\n", vm_uuid);
+
+    fprintf(stderr, "In bytes, the VM UUID is ");
+    for (int i = 0; i < 15; i++)
+    {
+        fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
+    }
+    fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
+
+    printf("%zd.\n", versions->size);
+
+    for (size_t i = 0; i < versions->size; i++)
+    {
+        printf("%s -> %s.\n", versions->contents[i].key,
+               versions->contents[i].val);
+    }
+
+    printf("%s.\n", vm_record->uuid);
+
+    printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
+
+    printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
+
+    for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
+    {
+        printf("%"PRId64" -> %lf.\n",
+               vm_record->vcpus_utilisation->contents[i].key,
+               vm_record->vcpus_utilisation->contents[i].val);
+    }
+
+    xen_uuid_bytes_free(vm_uuid_bytes);
+    xen_uuid_free(vm_uuid);
+    xen_vm_free(vm);
+
+    xen_vm_record_free(vm_record);
+
+    xen_host_free(host);
+    xen_string_string_map_free(versions);
+
+
+    xen_vm new_vm = create_new_vm(session);
+    if (!session->ok)
+    {
+        /* Error has been logged, just clean up. */
+        CLEANUP;
+        return 1;
+    }
+
+    print_vm_power_state(session, new_vm);
+    if (!session->ok)
+    {
+        /* Error has been logged, just clean up. */
+        xen_vm_free(new_vm);
+        CLEANUP;
+        return 1;
+    }
+
+    xen_vm_free(new_vm);
+    CLEANUP;
+
+    return 0;
+}
+
+
+/**
+ * Creation of a new VM, using the Named Parameters idiom.  Allocate the
+ * xen_vm_record here, but the sets through the library.  Either
+ * allocation patterns can be used, as long as the allocation and free are
+ * paired correctly.
+ */
+static xen_vm create_new_vm(xen_session *session)
+{
+    xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
+    xen_vm_record vm_record =
+        {
+            .name_label = "NewHVM",
+            .name_description = "New HVM Description",
+            .user_version = 1,
+            .is_a_template = false,
+            .memory_static_max = 256,
+            .memory_dynamic_max = 256,
+            .memory_dynamic_min = 128,
+            .memory_static_min = 128,
+            .vcpus_policy = "credit",
+            .vcpus_params = vcpus_params,
+            .vcpus_number = 2,
+            .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
+            .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
+            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
+            .hvm_boot = "cda",
+        };
+
+
+    xen_vm vm;
+    xen_vm_create(session, &vm, &vm_record);
+
+    if (!session->ok)
+    {
+        fprintf(stderr, "VM creation failed.\n");
+        print_error(session);
+        return NULL;
+    }
+
+
+    /*
+     * Create a new disk for the new VM.
+     */
+    xen_sr_set *srs;
+    if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
+        srs->size < 1)
+    {
+        fprintf(stderr, "SR lookup failed.\n");
+        print_error(session);
+        xen_vm_free(vm);
+        return NULL;
+    }
+
+    xen_sr_record_opt sr_record =
+        {
+            .u.handle = srs->contents[0]
+        };
+    xen_vdi_record vdi0_record =
+        {
+            .name_label = "MyRootFS",
+            .name_description = "MyRootFS description",
+            .sr = &sr_record,
+            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
+            .sector_size = 512,
+            .location = "file:/root/gentoo.amd64.hvm.img",
+            .type = XEN_VDI_TYPE_SYSTEM,
+            .sharable = false,
+            .read_only = false
+        };
+    
+    xen_vdi vdi0;
+    if (!xen_vdi_create(session, &vdi0, &vdi0_record))
+    {
+        fprintf(stderr, "VDI creation failed.\n");
+        print_error(session);
+
+        xen_sr_set_free(srs);
+        xen_vm_free(vm);
+        return NULL;
+    }
+
+
+    xen_vm_record_opt vm_record_opt =
+        {
+            .u.handle = vm
+        };
+    xen_vdi_record_opt vdi0_record_opt =
+        {
+            .u.handle = vdi0
+        };
+    xen_vbd_record vbd0_record =
+        {
+            .vm = &vm_record_opt,
+            .vdi = &vdi0_record_opt,
+            .device = "xvda1",
+            .mode = XEN_VBD_MODE_RW
+        };
+
+    xen_vbd vbd0;
+    if (!xen_vbd_create(session, &vbd0, &vbd0_record))
+    {
+        fprintf(stderr, "VBD creation failed.\n");
+        print_error(session);
+
+        xen_vdi_free(vdi0);
+        xen_sr_set_free(srs);
+        xen_vm_free(vm);
+        return NULL;
+    }
+
+    char *vm_uuid;
+    char *vdi0_uuid;
+    char *vbd0_uuid;
+
+    xen_vm_get_uuid(session,  &vm_uuid,   vm);
+    xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
+    xen_vbd_get_uuid(session, &vbd0_uuid, vbd0); 
+
+    if (!session->ok)
+    {
+        fprintf(stderr, "get_uuid call failed.\n");
+        print_error(session);
+
+        xen_uuid_free(vm_uuid);
+        xen_uuid_free(vdi0_uuid);
+        xen_uuid_free(vbd0_uuid);
+        xen_vbd_free(vbd0);
+        xen_vdi_free(vdi0);
+        xen_sr_set_free(srs);
+        xen_vm_free(vm);
+        return NULL;
+    }
+
+    fprintf(stderr,
+            "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
+            vm_uuid, vdi0_uuid, vbd0_uuid);
+
+    xen_uuid_free(vm_uuid);
+    xen_uuid_free(vdi0_uuid);
+    xen_uuid_free(vbd0_uuid);
+    xen_vbd_free(vbd0);
+    xen_vdi_free(vdi0);
+    xen_sr_set_free(srs);
+
+    return vm;
+}
+
+
+/**
+ * Print the power state for the given VM.
+ */
+static void print_vm_power_state(xen_session *session, xen_vm vm)
+{
+    char *vm_uuid;
+    enum xen_vm_power_state power_state;
+
+    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
+    {
+        print_error(session);
+        return;
+    }
+
+    if (!xen_vm_get_power_state(session, &power_state, vm))
+    {
+        xen_uuid_free(vm_uuid);
+        print_error(session);
+        return;
+    }
+
+    printf("VM %s power state is %s.\n", vm_uuid,
+           xen_vm_power_state_to_string(power_state));
+
+    xen_uuid_free(vm_uuid);
+}
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/scripts/test_hvm_create.py
--- a/tools/python/scripts/test_hvm_create.py   Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/scripts/test_hvm_create.py   Wed Jan 31 17:22:17 2007 +0000
@@ -13,16 +13,11 @@ vm_cfg = {
     
     
     'VCPUs_policy': 'credit',
-    'VCPUs_params': '',
+    'VCPUs_params': {},
     'VCPUs_number': 2,
-    'VCPUs_features_required': '',
-    'VCPUs_features_can_use': '',
-    'VCPUs_features_force_on': '',
-    'VCPUs_features_force_off': '',
 
     'actions_after_shutdown': 'destroy',
     'actions_after_reboot': 'restart',
-    'actions_after_suspend': 'destroy',
     'actions_after_crash': 'destroy',
     
     'PV_bootloader': '',
@@ -44,7 +39,7 @@ local_vdi_cfg = {
 local_vdi_cfg = {
     'name_label': 'gentoo.hvm',
     'name_description': '',
-    'uri': 'file:/root/gentoo.amd64.hvm.img',
+    'location': 'file:/root/gentoo.amd64.hvm.img',
     'virtual_size': 0,
     'sector_size': 0,
     'type': 'system',
@@ -71,6 +66,12 @@ vif_cfg = {
     'MAC': '',
     'MTU': 1500,
 }    
+
+console_cfg = {
+    'protocol': 'rfb',
+    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
+}
+
 
 import sys
 import time
@@ -125,6 +126,12 @@ def test_vm_create():
         vif_cfg['VM'] = vm_uuid
         vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
 
+        # Create a console
+        console_cfg['VM'] = vm_uuid
+        console_uuid = execute(server, 'console.create',
+                               (session, console_cfg))
+        print console_uuid
+
         # Start the VM
         execute(server, 'VM.start', (session, vm_uuid, False))
 
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/scripts/test_vm_create.py
--- a/tools/python/scripts/test_vm_create.py    Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/scripts/test_vm_create.py    Wed Jan 31 17:22:17 2007 +0000
@@ -15,14 +15,9 @@ vm_cfg = {
     'VCPUs_policy': 'credit',
     'VCPUs_params': '',
     'VCPUs_number': 2,
-    'VCPUs_features_required': '',
-    'VCPUs_features_can_use': '',
-    'VCPUs_features_force_on': '',
-    'VCPUs_features_force_off': '',
 
     'actions_after_shutdown': 'destroy',
     'actions_after_reboot': 'restart',
-    'actions_after_suspend': 'destroy',
     'actions_after_crash': 'destroy',
     
     'PV_bootloader': '',
@@ -65,7 +60,7 @@ local_vdi_cfg = {
 local_vdi_cfg = {
     'name_label': 'gentoo.amd64.img',
     'name_description': '',
-    'uri': 'file:/root/gentoo.amd64.img',
+    'location': 'file:/root/gentoo.amd64.img',
     'virtual_size': 0,
     'sector_size': 0,
     'type': 'system',
@@ -91,6 +86,11 @@ vif_cfg = {
     'network': '',
     'MAC': '',
     'MTU': 1500,
+}
+
+console_cfg = {
+    'protocol': 'rfb',
+    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
 }    
 
 import sys
@@ -157,12 +157,18 @@ def test_vm_create():
         vif_cfg['VM'] = vm_uuid
         vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
 
+        # Create a console
+        console_cfg['VM'] = vm_uuid
+        console_uuid = execute(server, 'console.create',
+                               (session, console_cfg))
+        print console_uuid
+
         # Start the VM
         execute(server, 'VM.start', (session, vm_uuid, False))
 
         time.sleep(30)
 
-        test_suspend = True
+        test_suspend = False
         if test_suspend:
             print 'Suspending VM..'
             execute(server, 'VM.suspend', (session, vm_uuid))
@@ -172,13 +178,13 @@ def test_vm_create():
             execute(server, 'VM.resume', (session, vm_uuid, False))
             print 'Resumed VM.'
 
+    finally:
         # Wait for user to say we're good to shut it down
         while True:
             destroy = raw_input('destroy VM? ')
             if destroy[0] in ('y', 'Y'):
                 break
-
-    finally:
+        
         # Clean up
         if vif_uuid:
             execute(server, 'VIF.destroy', (session, vif_uuid))
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py      Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/scripts/xapi.py      Wed Jan 31 17:22:17 2007 +0000
@@ -45,7 +45,7 @@ VBD_LIST_FORMAT = '%(device)-6s %(uuid)-
 VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
 TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
 VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
-CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(uri)-32s'
+CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(location)-32s'
 
 COMMANDS = {
     'host-info': ('', 'Get Xen Host Info'),
@@ -545,7 +545,7 @@ def xapi_console_list(args, async = Fals
 
     if not is_long:
         print CONSOLE_LIST_FORMAT % {'protocol': 'Protocol',
-                                     'uri': 'URI',
+                                     'location': 'Location',
                                      'uuid': 'UUID'}
 
         for console in consoles:
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/XendAPI.py  Wed Jan 31 17:22:17 2007 +0000
@@ -1121,11 +1121,11 @@ class XendAPI(object):
     
     def VM_get_VCPUs_policy(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return dom.get_vcpus_policy()
+        return xen_api_success(dom.get_vcpus_policy())
     
     def VM_get_VCPUs_params(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
-        return xen_api_todo() # need access to scheduler
+        return xen_api_success(dom.get_vcpus_params())
     
     def VM_get_actions_after_shutdown(self, session, vm_ref):
         dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
@@ -1186,7 +1186,7 @@ class XendAPI(object):
         return xen_api_success(dom.get_platform_keymap())
     
     def VM_get_other_config(self, session, vm_ref):
-        return self.VM_get('otherconfig', session, vm_ref)        
+        return self.VM_get('other_config', session, vm_ref)        
 
     def VM_get_is_control_domain(self, session, vm_ref):
         xd = XendDomain.instance()
@@ -1363,7 +1363,7 @@ class XendAPI(object):
             'platform_keymap': xeninfo.get_platform_keymap(),
             'PCI_bus': xeninfo.get_pci_bus(),
             'tools_version': xeninfo.get_tools_version(),
-            'other_config': xeninfo.info.get('otherconfig'),
+            'other_config': xeninfo.info.get('other_config', {}),
             'is_control_domain': xeninfo == xendom.privilegedDomain(),
         }
         return xen_api_success(record)
@@ -1469,7 +1469,7 @@ class XendAPI(object):
             vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
             if not vdi:
                 return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
-            vdi_image = vdi.get_image_uri()
+            vdi_image = vdi.get_location()
             vbd_ref = XendTask.log_progress(0, 100,
                                             dom.create_vbd,
                                             vbd_struct, vdi_image)
@@ -1835,8 +1835,9 @@ class XendAPI(object):
     # ----------------------------------------------------------------
 
 
-    console_attr_ro = ['uri', 'protocol', 'VM']
-    console_attr_rw = []
+    console_attr_ro = ['location', 'protocol', 'VM']
+    console_attr_rw = ['other_config']
+    console_funcs = [('create', 'console')]
     
     def console_get_all(self, session):
         xendom = XendDomain.instance()
@@ -1844,10 +1845,10 @@ class XendAPI(object):
         cons = reduce(lambda x, y: x + y, cons)
         return xen_api_success(cons)
 
-    def console_get_uri(self, session, console_ref):
+    def console_get_location(self, session, console_ref):
         return xen_api_success(xendom.get_dev_property_by_uuid('console',
                                                                console_ref,
-                                                               'uri'))
+                                                               'location'))
 
     def console_get_protocol(self, session, console_ref):
         return xen_api_success(xendom.get_dev_property_by_uuid('console',
@@ -1879,6 +1880,22 @@ class XendAPI(object):
             
         return xen_api_success(return_cfg)
 
+    def console_create(self, session, console_struct):
+        xendom = XendDomain.instance()
+        if not xendom.is_valid_vm(console_struct['VM']):
+            return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
+        
+        dom = xendom.get_vm_by_uuid(console_struct['VM'])
+        try:
+            if 'protocol' not in console_struct:
+                return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
+                                      'No protocol specified'])
+            
+            console_ref = dom.create_console(console_struct)
+            xendom.managed_config_save(dom)
+            return xen_api_success(console_ref)
+        except XendError, e:
+            return xen_api_error([XEND_ERROR_TODO, str(e)])
 
     # Xen API: Class SR
     # ----------------------------------------------------------------
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/XendAuthSessions.py
--- a/tools/python/xen/xend/XendAuthSessions.py Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/XendAuthSessions.py Wed Jan 31 17:22:17 2007 +0000
@@ -20,11 +20,6 @@ from xen.xend import uuid
 from xen.xend import uuid
 from xen.xend.XendError import *
 from xen.xend.XendLogging import log
-
-try:
-    import PAM
-except ImportError:
-    log.warn("python-pam is required for XenAPI support.")
 
 class XendAuthSessions:
     """Keeps track of Xen API Login Sessions using PAM.
@@ -80,7 +75,11 @@ class XendAuthSessions:
         """
         pam_auth = None
         try:
+            import PAM
             pam_auth = PAM.pam()
+        except ImportError:
+            log.warn("python-pam is required for XenAPI support.")
+            return False
         except NameError:
             # if PAM doesn't exist, let's ignore it
             return False
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/XendConfig.py       Wed Jan 31 17:22:17 2007 +0000
@@ -126,6 +126,7 @@ XENAPI_HVM_CFG = {
     'platform_serial' : 'serial',
     'platform_localtime': 'localtime',
     'platform_keymap' : 'keymap',
+    'HVM_boot': 'boot',
 }    
 
 # List of XendConfig configuration keys that have no direct equivalent
@@ -250,7 +251,8 @@ LEGACY_IMAGE_CFG = [
     ('sdl', int),
     ('vncdisplay', int),
     ('vncunused', int),
-    ('vncpasswd', str),    
+    ('vncpasswd', str),
+    ('vnclisten', str),
 ]
 
 LEGACY_IMAGE_HVM_CFG = [
@@ -379,6 +381,7 @@ class XendConfig(dict):
             'vif_refs': [],
             'vbd_refs': [],
             'vtpm_refs': [],
+            'other_config': {},
         }
         
         defaults['name_label'] = 'Domain-' + defaults['uuid']
@@ -660,6 +663,25 @@ class XendConfig(dict):
         self['vbd_refs'] = cfg.get('vbd_refs', [])
         self['vtpm_refs'] = cfg.get('vtpm_refs', [])
 
+        # coalesce hvm vnc frame buffer with vfb config
+        if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0):
+            # add vfb device if it isn't there already
+            has_rfb = False
+            for console_uuid in self['console_refs']:
+                if self['devices'][console_uuid][1].get('protocol') == 'rfb':
+                    has_rfb = True
+                    break
+
+            if not has_rfb:
+                dev_config = ['vfb']
+                # copy VNC related params from image config to vfb dev conf
+                for key in ['vncpasswd', 'vncunused', 'vncdisplay',
+                            'vnclisten']:
+                    if key in self['image']:
+                        dev_config.append([key, self['image'][key]])
+
+                self.device_add('vfb', cfg_sxp = dev_config)
+
 
     def _sxp_to_xapi_unsupported(self, sxp_cfg):
         """Read in an SXP configuration object and populate
@@ -756,7 +778,7 @@ class XendConfig(dict):
 
                 # currently unsupported options
                 self['image']['hvm']['device_model'] = LEGACY_DM
-                self['image']['vnc'] = 1
+                self['image']['vnc'] = 0
                 self['image']['hvm']['pae'] = 1
 
                 if self['platform_enable_audio']:
@@ -883,8 +905,9 @@ class XendConfig(dict):
                                 # store as part of the device config.
                                 dev_uuid = sxp.child_value(config, 'uuid')
                                 dev_type, dev_cfg = self['devices'][dev_uuid]
-                                config.append(['bootable',
-                                               int(dev_cfg['bootable'])])
+                                is_bootable = dev_cfg.get('bootable', 0)
+                                config.append(['bootable', int(is_bootable)])
+
                             sxpr.append(['device', config])
 
                         found = True
@@ -955,7 +978,7 @@ class XendConfig(dict):
                     pass
 
             if dev_type == 'vbd':
-                dev_info['bootable'] = False
+                dev_info['bootable'] = 0
                 if dev_info.get('dev', '').startswith('ioemu:'):
                     dev_info['driver'] = 'ioemu'
                 else:
@@ -975,7 +998,7 @@ class XendConfig(dict):
                     if dev_type == 'vbd' and not target[param]:
                         # Compat hack -- this is the first disk, so mark it
                         # bootable.
-                        dev_info['bootable'] = True
+                        dev_info['bootable'] = 1
                     target[param].append(dev_uuid)
             elif dev_type == 'tap':
                 if 'vbd_refs' not in target:
@@ -984,8 +1007,30 @@ class XendConfig(dict):
                     if not target['vbd_refs']:
                         # Compat hack -- this is the first disk, so mark it
                         # bootable.
-                        dev_info['bootable'] = True
+                        dev_info['bootable'] = 1
                     target['vbd_refs'].append(dev_uuid)
+                    
+            elif dev_type == 'vfb':
+                # Populate other config with aux data that is associated
+                # with vfb
+
+                other_config = {}
+                for key in ['vncunused', 'vncdisplay', 'vnclisten',
+                            'vncpasswd', 'type', 'display', 'xauthority',
+                            'keymap']:
+                    if key in dev_info:
+                        other_config[key] = dev_info[key]
+                target['devices'][dev_uuid][1]['other_config'] =  other_config
+                
+                
+                if 'console_refs' not in target:
+                    target['console_refs'] = []
+
+                # Treat VFB devices as console devices so they are found
+                # through Xen API
+                if dev_uuid not in target['console_refs']:
+                    target['console_refs'].append(dev_uuid)
+
             elif dev_type == 'console':
                 if 'console_refs' not in target:
                     target['console_refs'] = []
@@ -1025,8 +1070,8 @@ class XendConfig(dict):
                 dev_info['uname'] = cfg_xenapi.get('image', '')
                 dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'),
                                              old_vbd_type)
-                dev_info['bootable'] = cfg_xenapi.get('bootable', False)
-                dev_info['driver'] = cfg_xenapi.get('driver')
+                dev_info['bootable'] = int(cfg_xenapi.get('bootable', 0))
+                dev_info['driver'] = cfg_xenapi.get('driver', '')
                 dev_info['VDI'] = cfg_xenapi.get('VDI', '')
                     
                 if cfg_xenapi.get('mode') == 'RW':
@@ -1048,50 +1093,117 @@ class XendConfig(dict):
                 target['devices'][dev_uuid] = (dev_type, dev_info)
                 target['vtpm_refs'].append(dev_uuid)
 
+            elif dev_type == 'console':
+                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
+                dev_info['uuid'] = dev_uuid
+                dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb')
+                dev_info['other_config'] = cfg_xenapi.get('other_config', {})
+                if dev_info['protocol'] == 'rfb':
+                    # collapse other config into devinfo for things
+                    # such as vncpasswd, vncunused, etc.                    
+                    dev_info.update(cfg_xenapi.get('other_config', {}))
+                    dev_info['type'] = 'vnc'                        
+                    target['devices'][dev_uuid] = ('vfb', dev_info)
+                    target['console_refs'].append(dev_uuid)
+
+                    # Finally, if we are a pvfb, we need to make a vkbd
+                    # as well that is not really exposed to Xen API
+                    vkbd_uuid = uuid.createString()
+                    target['devices'][vkbd_uuid] = ('vkbd', {})
+                    
+                elif dev_info['protocol'] == 'vt100':
+                    # if someone tries to create a VT100 console
+                    # via the Xen API, we'll have to ignore it
+                    # because we create one automatically in
+                    # XendDomainInfo._update_consoles
+                    raise XendConfigError('Creating vt100 consoles via '
+                                          'Xen API is unsupported')
+
             return dev_uuid
 
         # no valid device to add
         return ''
 
-    def console_add(self, protocol, uri):
+    def console_add(self, protocol, location, other_config = {}):
         dev_uuid = uuid.createString()
-        dev_info = {
-            'uuid': dev_uuid,
-            'protocol': protocol,
-            'uri': uri
-        }
-        if 'devices' not in self:
-            self['devices'] = {}
+        if protocol == 'vt100':
+            dev_info = {
+                'uuid': dev_uuid,
+                'protocol': protocol,
+                'location': location,
+                'other_config': other_config,
+            }
+
+            if 'devices' not in self:
+                self['devices'] = {}
             
-        self['devices'][dev_uuid] = ('console', dev_info)
-        self['console_refs'].append(dev_uuid)
-        return dev_info
+            self['devices'][dev_uuid] = ('console', dev_info)
+            self['console_refs'].append(dev_uuid)
+            return dev_info
+
+        return {}
+
+    def console_update(self, console_uuid, key, value):
+        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
+            if dev_uuid == console_uuid:
+                dev_info[key] = value
+                break
 
     def console_get_all(self, protocol):
-        consoles = [dinfo for dtype, dinfo in self['devices'].values()
-                    if dtype == 'console']
-        return [c for c in consoles if c.get('protocol') == protocol]
-
-    def device_update(self, dev_uuid, cfg_sxp):
+        if protocol == 'vt100':
+            consoles = [dinfo for dtype, dinfo in self['devices'].values()
+                        if dtype == 'console']
+            return [c for c in consoles if c.get('protocol') == protocol]
+
+        elif protocol == 'rfb':
+            vfbs = [dinfo for dtype, dinfo in self['devices'].values()
+                   if dtype == 'vfb']
+
+            # move all non-console key values to other_config before
+            # returning console config
+            valid_keys = ['uuid', 'location']
+            for vfb in vfbs:
+                other_config = {}
+                for key, val in vfb.items():
+                    if key not in valid_keys:
+                        other_config[key] = vfb[key]
+                    del vfb[key]
+                vfb['other_config'] = other_config
+                vfb['protocol'] = 'rfb'
+                        
+            return vfbs
+
+        else:
+            return []
+
+    def device_update(self, dev_uuid, cfg_sxp = [], cfg_xenapi = {}):
         """Update an existing device with the new configuration.
 
         @rtype: boolean
         @return: Returns True if succesfully found and updated a device conf
         """
-        if dev_uuid in self['devices']:
+        if dev_uuid in self['devices'] and cfg_sxp:
             if sxp.child0(cfg_sxp) == 'device':            
                 config = sxp.child0(cfg_sxp)
             else:
                 config = cfg_sxp
-                
+
+            dev_type, dev_info = self['devices'][dev_uuid]
             for opt_val in config[1:]:
                 try:
                     opt, val = opt_val
-                    self['devices'][dev_uuid][opt] = val
+                    dev_info[opt] = val
                 except (TypeError, ValueError):
                     pass # no value for this config option
-            
+
+            self['devices'][dev_uuid] = (dev_type, dev_info)
             return True
+        
+        elif dev_uuid in self['devices'] and cfg_xenapi:
+            dev_type, dev_info = self['devices'][dev_uuid]
+            for key, val in cfg_xenapi.items():
+                dev_info[key] = val
+            self['devices'][dev_uuid] = (dev_type, dev_info)
 
         return False
 
@@ -1111,7 +1223,12 @@ class XendConfig(dict):
                                   "configuration dictionary.")
             
         sxpr.append(dev_type)
-        config = [(opt, val) for opt, val in dev_info.items()]
+        if dev_type in ('console', 'vfb'):
+            config = [(opt, val) for opt, val in dev_info.items()
+                      if opt != 'other_config']
+        else:
+            config = [(opt, val) for opt, val in dev_info.items()]
+            
         sxpr += config
 
         return sxpr
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Jan 31 17:22:17 2007 +0000
@@ -695,16 +695,29 @@ class XendDomainInfo:
             if not serial_consoles:
                 cfg = self.info.console_add('vt100', self.console_port)
                 self._createDevice('console', cfg)
-
-        # Update VNC port if it exists
+            else:
+                console_uuid = serial_consoles[0].get('uuid')
+                self.info.console_update(console_uuid, 'location',
+                                         self.console_port)
+                
+
+        # Update VNC port if it exists and write to xenstore
         vnc_port = self.readDom('console/vnc-port')
         if vnc_port is not None:
-            vnc_consoles = self.info.console_get_all('rfb')
-            if not vnc_consoles:
-                cfg = self.info.console_add('rfb', 'localhost:%s' %
-                                           str(vnc_port))
-                self._createDevice('console', cfg)                
-
+            for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
+                if dev_type == 'vfb':
+                    old_location = dev_info.get('location')
+                    listen_host = dev_info.get('vnclisten', 'localhost')
+                    new_location = '%s:%s' % (listen_host, str(vnc_port))
+                    if old_location == new_location:
+                        break
+
+                    dev_info['location'] = new_location
+                    self.info.device_update(dev_uuid, cfg_xenapi = dev_info)
+                    vfb_ctrl = self.getDeviceController('vfb')
+                    vfb_ctrl.reconfigureDevice(0, dev_info)
+                    break
+                
     #
     # Function to update xenstore /vm/*
     #
@@ -1963,7 +1976,11 @@ class XendDomainInfo:
         else:
             return 'unknown'
     def get_vcpus_params(self):
-        return '' # TODO
+        if self.getDomid() is None:
+            return {}
+
+        retval = xc.sched_credit_domain_get(self.getDomid())
+        return retval
     def get_power_state(self):
         return XEN_API_VM_POWER_STATE[self.state]
     def get_platform_std_vga(self):
@@ -2017,21 +2034,18 @@ class XendDomainInfo:
 
         @rtype: dictionary
         """
-        dev_type_config = self.info['devices'].get(dev_uuid)
+        dev_type, dev_config = self.info['devices'].get(dev_uuid, (None, None))
 
         # shortcut if the domain isn't started because
         # the devcontrollers will have no better information
         # than XendConfig.
         if self.state in (XEN_API_VM_POWER_STATE_HALTED,):
-            if dev_type_config:
-                return copy.deepcopy(dev_type_config[1])
+            if dev_config:
+                return copy.deepcopy(dev_config)
             return None
 
         # instead of using dev_class, we use the dev_type
         # that is from XendConfig.
-        # This will accomdate 'tap' as well as 'vbd'
-        dev_type = dev_type_config[0]
-        
         controller = self.getDeviceController(dev_type)
         if not controller:
             return None
@@ -2040,14 +2054,14 @@ class XendDomainInfo:
         if not all_configs:
             return None
 
-        dev_config = copy.deepcopy(dev_type_config[1])
+        updated_dev_config = copy.deepcopy(dev_config)
         for _devid, _devcfg in all_configs.items():
             if _devcfg.get('uuid') == dev_uuid:
-                dev_config.update(_devcfg)
-                dev_config['id'] = _devid
-                return dev_config
-
-        return dev_config
+                updated_dev_config.update(_devcfg)
+                updated_dev_config['id'] = _devid
+                return updated_dev_config
+
+        return updated_dev_config
                     
     def get_dev_xenapi_config(self, dev_class, dev_uuid):
         config = self.get_dev_config_by_uuid(dev_class, dev_uuid)
@@ -2230,6 +2244,21 @@ class XendDomainInfo:
 
         return dev_uuid
 
+    def create_console(self, xenapi_console):
+        """ Create a console device from a Xen API struct.
+
+        @return: uuid of device
+        @rtype: string
+        """
+        if self.state not in (DOM_STATE_HALTED,):
+            raise VmError("Can only add console to a halted domain.")
+
+        dev_uuid = self.info.device_add('console', cfg_xenapi = xenapi_console)
+        if not dev_uuid:
+            raise XendError('Failed to create device')
+
+        return dev_uuid
+
     def destroy_device_by_uuid(self, dev_type, dev_uuid):
         if dev_uuid not in self.info['devices']:
             raise XendError('Device does not exist')
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/XendVDI.py
--- a/tools/python/xen/xend/XendVDI.py  Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/XendVDI.py  Wed Jan 31 17:22:17 2007 +0000
@@ -73,6 +73,7 @@ class XendVDI(AutoSaveObject):
         self.sharable = False
         self.read_only = False
         self.type = "system"
+        self.location = ''
 
     def load_config_dict(self, cfg):
         """Loads configuration into the object from a dict.
@@ -147,9 +148,10 @@ class XendVDI(AutoSaveObject):
                 'sharable': False,
                 'readonly': False,
                 'SR': self.sr_uuid,
+                'location': self.get_location(),
                 'VBDs': []}
 
-    def get_image_uri(self):
+    def get_location(self):
         raise NotImplementedError()
                 
 
@@ -163,9 +165,10 @@ class XendQCoWVDI(XendVDI):
         self.virtual_size = vsize
         self.sector_size = 512
         self.auto_save = True
+        self.location = 'tap:qcow:%s' % self.qcow_path
 
-    def get_image_uri(self):
-        return 'tap:qcow:%s' % self.qcow_path
+    def get_location(self):
+        return self.location
 
 class XendLocalVDI(XendVDI):
     def __init__(self, vdi_struct):
@@ -183,7 +186,7 @@ class XendLocalVDI(XendVDI):
         self.type = vdi_struct.get('type', '')
         self.sharable = vdi_struct.get('sharable', False)
         self.read_only = vdi_struct.get('read_only', False)
-        self.image_uri = vdi_struct.get('uri', 'file:/dev/null')
+        self.location = vdi_struct.get('location', 'file:/dev/null')
 
-    def get_image_uri(self):
-        return self.image_uri
+    def get_location(self):
+        return self.location
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/image.py    Wed Jan 31 17:22:17 2007 +0000
@@ -26,6 +26,7 @@ from xen.xend.XendConstants import REVER
 from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
 from xen.xend.XendError import VmError, XendError
 from xen.xend.XendLogging import log
+from xen.xend.XendOptions import instance as xenopts
 from xen.xend.server.netif import randomMAC
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend import arch
@@ -340,8 +341,6 @@ class HVMImageHandler(ImageHandler):
 
         self.pid = None
 
-        self.dmargs += self.configVNC(imageConfig)
-
         self.pae  = imageConfig['hvm'].get('pae', 0)
         self.apic  = imageConfig['hvm'].get('apic', 0)
         self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
@@ -379,8 +378,8 @@ class HVMImageHandler(ImageHandler):
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
                    'acpi', 'usb', 'usbdevice', 'keymap' ]
+        
         hvmDeviceConfig = vmConfig['image']['hvm']['devices']
-
         ret = ['-vcpus', str(self.vm.getVCpuCount())]
 
         for a in dmargs:
@@ -439,49 +438,59 @@ class HVMImageHandler(ImageHandler):
             ret.append("-net")
             ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
 
-        return ret
-
-    def configVNC(self, imageConfig):
-        # Handle graphics library related options
-        vnc = imageConfig.get('vnc')
-        sdl = imageConfig.get('sdl')
-        ret = []
-        nographic = imageConfig.get('nographic')
-
-        # get password from VM config (if password omitted, None)
-        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
-
-        if nographic:
+
+        #
+        # Find RFB console device, and if it exists, make QEMU enable
+        # the VNC console.
+        #
+        if vmConfig['image'].get('nographic'):
+            # skip vnc init if nographic is set
             ret.append('-nographic')
             return ret
 
-        if vnc:
-            vncdisplay = imageConfig.get('vncdisplay',
-                                         int(self.vm.getDomid()))
-            vncunused = imageConfig.get('vncunused')
-
-            if vncunused:
-                ret += ['-vncunused']
-            else:
-                ret += ['-vnc', '%d' % vncdisplay]
-
-            vnclisten = imageConfig.get('vnclisten')
-
-            if not(vnclisten):
-                vnclisten = (xen.xend.XendOptions.instance().
-                             get_vnclisten_address())
-            if vnclisten:
-                ret += ['-vnclisten', vnclisten]
-
-            vncpasswd = vncpasswd_vmconfig
-            if vncpasswd is None:
-                vncpasswd = (xen.xend.XendOptions.instance().
-                             get_vncpasswd_default())
-                if vncpasswd is None:
-                    raise VmError('vncpasswd is not set up in ' +
-                                  'VMconfig and xend-config.')
-            if vncpasswd != '':
-                self.vm.storeVm("vncpasswd", vncpasswd)
+        vnc_config = {}
+        has_vfb = False
+        has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
+        for dev_uuid in vmConfig['console_refs']:
+            dev_type, dev_info = vmConfig['devices'][dev_uuid]
+            if dev_type == 'vfb':
+                vnc_config = dev_info.get('other_config', {})
+                has_vfb = True
+                break
+
+        if not vnc_config:
+            for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'):
+                if key in vmConfig['image']:
+                    vnc_config[key] = vmConfig['image'][key]
+
+        if not has_vfb and not has_vnc:
+            ret.append('-nographic')
+            return ret
+
+                    
+        if not vnc_config.get('vncunused', 0) and \
+               vnc_config.get('vncdisplay', 0):
+            ret.append('-vnc')
+            ret.append(str(vncdisplay))
+        else:
+            ret.append('-vncunused')
+
+        vnclisten = vnc_config.get('vnclisten',
+                                   xenopts().get_vnclisten_address())
+        ret.append('-vnclisten')
+        ret.append(str(vnclisten))
+        
+        # Store vncpassword in xenstore
+        vncpasswd = vnc_config.get('vncpasswd')
+        if not vncpasswd:
+            vncpasswd = xenopts().get_vncpasswd_default()
+                    
+        if vncpasswd is None:
+            raise VmError('vncpasswd is not setup in vmconfig or '
+                          'xend-config.sxp')
+
+        if vncpasswd != '':
+            self.vm.storeVm('vncpasswd', vncpasswd)
 
         return ret
 
diff -r 5e66c05c67ad -r 5d09e6098f93 
tools/python/xen/xend/server/ConsoleController.py
--- a/tools/python/xen/xend/server/ConsoleController.py Wed Jan 31 17:22:00 
2007 +0000
+++ b/tools/python/xen/xend/server/ConsoleController.py Wed Jan 31 17:22:17 
2007 +0000
@@ -8,7 +8,7 @@ class ConsoleController(DevController):
     console devices with persistent UUIDs.
     """
 
-    valid_cfg = ['uri', 'uuid', 'protocol']
+    valid_cfg = ['location', 'uuid', 'protocol']
 
     def __init__(self, vm):
         DevController.__init__(self, vm)
@@ -29,3 +29,7 @@ class ConsoleController(DevController):
 
     def migrate(self, deviceConfig, network, dst, step, domName):
         return 0
+
+    def destroyDevice(self, devid, force):
+        DevController.destroyDevice(self, devid, True)
+        
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/python/xen/xend/server/vfbif.py     Wed Jan 31 17:22:17 2007 +0000
@@ -14,7 +14,8 @@ def spawn_detached(path, args, env):
         os.waitpid(p, 0)
         
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
-                  'display', 'xauthority', 'keymap' ]
+                  'display', 'xauthority', 'keymap',
+                  'uuid', 'location', 'protocol']
 
 class VfbifController(DevController):
     """Virtual frame buffer controller. Handles all vfb devices for a domain.
@@ -27,10 +28,11 @@ class VfbifController(DevController):
     def getDeviceDetails(self, config):
         """@see DevController.getDeviceDetails"""
 
-        back = dict([(k, config[k]) for k in CONFIG_ENTRIES
+        back = dict([(k, str(config[k])) for k in CONFIG_ENTRIES
                      if config.has_key(k)])
 
-        return (0, back, {})
+        devid = 0
+        return (devid, back, {})
 
 
     def getDeviceConfiguration(self, devid):
@@ -44,6 +46,10 @@ class VfbifController(DevController):
 
     def createDevice(self, config):
         DevController.createDevice(self, config)
+        if self.vm.info.get('HVM_boot'):
+            # is HVM, so qemu-dm will handle the vfb.
+            return
+        
         std_args = [ "--domid", "%d" % self.vm.getDomid(),
                      "--title", self.vm.getName() ]
         t = config.get("type", None)
@@ -82,6 +88,42 @@ class VfbifController(DevController):
         else:
             raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
 
+
+    def waitForDevice(self, devid):
+        if self.vm.info.get('HVM_boot'):
+            log.debug('skip waiting for HVM vfb')
+            # is a qemu-dm managed device, don't wait for hotplug for these.
+            return
+
+        DevController.waitForDevice(self, devid)
+
+
+    def reconfigureDevice(self, _, config):
+        """ Only allow appending location information of vnc port into
+        xenstore."""
+
+        if 'location' in config:
+            (devid, back, front) = self.getDeviceDetails(config)
+            self.writeBackend(devid, 'location', config['location'])
+            return back.get('uuid')
+
+        raise VmError('Refusing to reconfigure device vfb:%d' % devid)
+
+    def destroyDevice(self, devid, force):
+        if self.vm.info.get('HVM_boot'):
+            # remove the backend xenstore entries for HVM guests no matter
+            # what
+            DevController.destroyDevice(self, devid, True)
+        else:
+            DevController.destroyDevice(self, devid, force)
+
+
+    def migrate(self, deviceConfig, network, dst, step, domName):
+        if self.vm.info.get('HVM_boot'):        
+            return 0
+        return DevController.migrate(self, deviceConfig, network, dst, step,
+                                     domName)
+    
 class VkbdifController(DevController):
     """Virtual keyboard controller. Handles all vkbd devices for a domain.
     """
@@ -92,3 +134,24 @@ class VkbdifController(DevController):
         back = {}
         front = {}
         return (devid, back, front)
+
+    def waitForDevice(self, config):
+        if self.vm.info.get('HVM_boot'):
+            # is a qemu-dm managed device, don't wait for hotplug for these.
+            return
+
+        DevController.waitForDevice(self, config)
+
+    def destroyDevice(self, devid, force):
+        if self.vm.info.get('HVM_boot'):
+            # remove the backend xenstore entries for HVM guests no matter
+            # what
+            DevController.destroyDevice(self, devid, True)
+        else:
+            DevController.destroyDevice(self, devid, force)
+
+    def migrate(self, deviceConfig, network, dst, step, domName):
+        if self.vm.info.get('HVM_boot'):        
+            return 0
+        return DevController.migrate(self, deviceConfig, network, dst, step,
+                                     domName)        
diff -r 5e66c05c67ad -r 5d09e6098f93 tools/xcutils/readnotes.c
--- a/tools/xcutils/readnotes.c Wed Jan 31 17:22:00 2007 +0000
+++ b/tools/xcutils/readnotes.c Wed Jan 31 17:22:17 2007 +0000
@@ -72,8 +72,8 @@ int main(int argc, char **argv)
        usize = xc_dom_check_gzip(image, st.st_size);
        if (usize)
        {
-               tmp = malloc(size);
-               xc_dom_do_gunzip(image, st.st_size, tmp, size);
+               tmp = malloc(usize);
+               xc_dom_do_gunzip(image, st.st_size, tmp, usize);
                image = tmp;
                size = usize;
        }
diff -r 5e66c05c67ad -r 5d09e6098f93 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Wed Jan 31 17:22:00 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/entry.S        Wed Jan 31 17:22:17 2007 +0000
@@ -281,9 +281,6 @@ CFIX14:
         .quad CFLT14,CFIX14
 .previous
 
-compat_domctl:
-compat_sysctl:
-
 .section .rodata, "a", @progbits
 
 ENTRY(compat_hypercall_table)
@@ -365,8 +362,8 @@ ENTRY(compat_hypercall_args_table)
         .byte 2 /* compat_event_channel_op  */
         .byte 2 /* compat_physdev_op        */
         .byte 2 /* do_hvm_op                */
-        .byte 1 /* compat_sysctl            */  /* 35 */
-        .byte 1 /* compat_domctl            */
+        .byte 1 /* do_sysctl                */  /* 35 */
+        .byte 1 /* do_domctl                */
         .byte 2 /* compat_kexec_op          */
         .rept NR_hypercalls-(.-compat_hypercall_args_table)
         .byte 0 /* compat_ni_hypercall      */
diff -r 5e66c05c67ad -r 5d09e6098f93 xen/include/public/arch-x86/xen-x86_32.h
--- a/xen/include/public/arch-x86/xen-x86_32.h  Wed Jan 31 17:22:00 2007 +0000
+++ b/xen/include/public/arch-x86/xen-x86_32.h  Wed Jan 31 17:22:17 2007 +0000
@@ -103,7 +103,7 @@
          (hnd).p = val;                                     \
     } while ( 0 )
 #define uint64_aligned_t uint64_t __attribute__((aligned(8)))
-#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
+#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name 
__attribute__((aligned(8)))
 #endif
 
 #ifndef __ASSEMBLY__

_______________________________________________
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®.