direct-io.hg

changeset 13758:5d09e6098f93

Merge
author Tim Deegan <Tim.Deegan@xensource.com>
date Wed Jan 31 17:22:17 2007 +0000 (2007-01-31)
parents 5e66c05c67ad 56377f5ce588
children 82062701b199 6db6b5df4f6f
files
line diff
     1.1 --- a/tools/libxen/Makefile	Wed Jan 31 17:22:00 2007 +0000
     1.2 +++ b/tools/libxen/Makefile	Wed Jan 31 17:22:17 2007 +0000
     1.3 @@ -51,6 +51,9 @@ libxenapi.a: $(LIBXENAPI_OBJS)
     1.4  test/test_bindings: test/test_bindings.o libxenapi.so
     1.5  	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
     1.6  
     1.7 +test/test_hvm_bindings: test/test_hvm_bindings.o libxenapi.so
     1.8 +	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
     1.9 +
    1.10  
    1.11  .PHONY: install
    1.12  install: all
     2.1 --- a/tools/libxen/include/xen_vdi.h	Wed Jan 31 17:22:00 2007 +0000
     2.2 +++ b/tools/libxen/include/xen_vdi.h	Wed Jan 31 17:22:17 2007 +0000
     2.3 @@ -74,6 +74,7 @@ typedef struct xen_vdi_record
     2.4      int64_t virtual_size;
     2.5      int64_t physical_utilisation;
     2.6      int64_t sector_size;
     2.7 +    char *location;
     2.8      enum xen_vdi_type type;
     2.9      bool sharable;
    2.10      bool read_only;
     3.1 --- a/tools/libxen/src/xen_vdi.c	Wed Jan 31 17:22:00 2007 +0000
     3.2 +++ b/tools/libxen/src/xen_vdi.c	Wed Jan 31 17:22:17 2007 +0000
     3.3 @@ -67,6 +67,9 @@ static const struct_member xen_vdi_recor
     3.4          { .key = "sector_size",
     3.5            .type = &abstract_type_int,
     3.6            .offset = offsetof(xen_vdi_record, sector_size) },
     3.7 +        { .key = "location",
     3.8 +          .type = &abstract_type_string,
     3.9 +          .offset = offsetof(xen_vdi_record, location) },
    3.10          { .key = "type",
    3.11            .type = &xen_vdi_type_abstract_type_,
    3.12            .offset = offsetof(xen_vdi_record, type) },
     4.1 --- a/tools/libxen/test/test_bindings.c	Wed Jan 31 17:22:00 2007 +0000
     4.2 +++ b/tools/libxen/test/test_bindings.c	Wed Jan 31 17:22:17 2007 +0000
     4.3 @@ -295,10 +295,10 @@ static xen_vm create_new_vm(xen_session 
     4.4              .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
     4.5              .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
     4.6              .hvm_boot = "",
     4.7 -            .pv_bootloader = "pygrub",
     4.8 -            .pv_kernel = "/boot/vmlinuz-2.6.16.33-xen",
     4.9 +            //.pv_bootloader = "pygrub",
    4.10 +            .pv_kernel = "/boot/vmlinuz-2.6.18-xenU",
    4.11              .pv_ramdisk = "",
    4.12 -            .pv_args = "",
    4.13 +            .pv_args = "root=/dev/sda1 ro",
    4.14              .pv_bootloader_args = ""
    4.15          };
    4.16  
    4.17 @@ -338,6 +338,7 @@ static xen_vm create_new_vm(xen_session 
    4.18              .sr = &sr_record,
    4.19              .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
    4.20              .sector_size = 512,
    4.21 +            .location = "file:/root/gentoo.amd64.img",
    4.22              .type = XEN_VDI_TYPE_SYSTEM,
    4.23              .sharable = false,
    4.24              .read_only = false
    4.25 @@ -367,8 +368,9 @@ static xen_vm create_new_vm(xen_session 
    4.26          {
    4.27              .vm = &vm_record_opt,
    4.28              .vdi = &vdi0_record_opt,
    4.29 -            .device = "xvda1",
    4.30 -            .mode = XEN_VBD_MODE_RW
    4.31 +            .device = "sda1",
    4.32 +            .mode = XEN_VBD_MODE_RW,
    4.33 +            .bootable = 1,
    4.34          };
    4.35  
    4.36      xen_vbd vbd0;
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/libxen/test/test_hvm_bindings.c	Wed Jan 31 17:22:17 2007 +0000
     5.3 @@ -0,0 +1,445 @@
     5.4 +/*
     5.5 + * Copyright (c) 2006 XenSource, Inc.
     5.6 + *
     5.7 + * This library is free software; you can redistribute it and/or
     5.8 + * modify it under the terms of the GNU Lesser General Public
     5.9 + * License as published by the Free Software Foundation; either
    5.10 + * version 2.1 of the License, or (at your option) any later version.
    5.11 + *
    5.12 + * This library is distributed in the hope that it will be useful,
    5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.15 + * Lesser General Public License for more details.
    5.16 + *
    5.17 + * You should have received a copy of the GNU Lesser General Public
    5.18 + * License along with this library; if not, write to the Free Software
    5.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
    5.20 + */
    5.21 +
    5.22 +#define _GNU_SOURCE
    5.23 +#include <inttypes.h>
    5.24 +#include <stdlib.h>
    5.25 +#include <stdio.h>
    5.26 +#include <string.h>
    5.27 +
    5.28 +#include <libxml/parser.h>
    5.29 +#include <curl/curl.h>
    5.30 +
    5.31 +#include "xen_host.h"
    5.32 +#include "xen_sr.h"
    5.33 +#include "xen_vbd.h"
    5.34 +#include "xen_vdi.h"
    5.35 +#include "xen_vm.h"
    5.36 +
    5.37 +
    5.38 +static void usage()
    5.39 +{
    5.40 +    fprintf(stderr,
    5.41 +"Usage:\n"
    5.42 +"\n"
    5.43 +"    test_bindings <url> <username> <password>\n"
    5.44 +"\n"
    5.45 +"where\n"
    5.46 +"        <url>      is a fragment of the server's URL, e.g. localhost:8005/RPC2;\n"
    5.47 +"        <username> is the username to use at the server; and\n"
    5.48 +"        <password> is the password.\n");
    5.49 +
    5.50 +    exit(EXIT_FAILURE);
    5.51 +}
    5.52 +
    5.53 +
    5.54 +static char *url;
    5.55 +
    5.56 +
    5.57 +typedef struct
    5.58 +{
    5.59 +    xen_result_func func;
    5.60 +    void *handle;
    5.61 +} xen_comms;
    5.62 +
    5.63 +
    5.64 +static xen_vm create_new_vm(xen_session *session);
    5.65 +static void print_vm_power_state(xen_session *session, xen_vm vm);
    5.66 +
    5.67 +
    5.68 +static size_t
    5.69 +write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
    5.70 +{
    5.71 +    size_t n = size * nmemb;
    5.72 +    return comms->func(ptr, n, comms->handle) ? n : 0;
    5.73 +}
    5.74 +
    5.75 +
    5.76 +static int
    5.77 +call_func(const void *data, size_t len, void *user_handle,
    5.78 +          void *result_handle, xen_result_func result_func)
    5.79 +{
    5.80 +    (void)user_handle;
    5.81 +
    5.82 +    CURL *curl = curl_easy_init();
    5.83 +    if (!curl) {
    5.84 +        return -1;
    5.85 +    }
    5.86 +
    5.87 +    xen_comms comms = {
    5.88 +        .func = result_func,
    5.89 +        .handle = result_handle
    5.90 +    };
    5.91 +
    5.92 +    curl_easy_setopt(curl, CURLOPT_URL, url);
    5.93 +    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
    5.94 +    curl_easy_setopt(curl, CURLOPT_MUTE, 1);
    5.95 +    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
    5.96 +    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
    5.97 +    curl_easy_setopt(curl, CURLOPT_POST, 1);
    5.98 +    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
    5.99 +    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
   5.100 +
   5.101 +    CURLcode result = curl_easy_perform(curl);
   5.102 +
   5.103 +    curl_easy_cleanup(curl);
   5.104 +
   5.105 +    return result;
   5.106 +}
   5.107 +
   5.108 +
   5.109 +static void print_error(xen_session *session)
   5.110 +{
   5.111 +    fprintf(stderr, "Error: %d", session->error_description_count);
   5.112 +    for (int i = 0; i < session->error_description_count; i++)
   5.113 +    {
   5.114 +        fprintf(stderr, "%s ", session->error_description[i]);
   5.115 +    }
   5.116 +    fprintf(stderr, "\n");
   5.117 +}
   5.118 +
   5.119 +
   5.120 +int main(int argc, char **argv)
   5.121 +{
   5.122 +    if (argc != 4)
   5.123 +    {
   5.124 +        usage();
   5.125 +    }
   5.126 +
   5.127 +    url = argv[1];
   5.128 +    char *username = argv[2];
   5.129 +    char *password = argv[3];
   5.130 +
   5.131 +    xmlInitParser();
   5.132 +    xen_init();
   5.133 +    curl_global_init(CURL_GLOBAL_ALL);
   5.134 +
   5.135 +#define CLEANUP                                 \
   5.136 +    do {                                        \
   5.137 +        xen_session_logout(session);            \
   5.138 +        curl_global_cleanup();                  \
   5.139 +        xen_fini();                             \
   5.140 +        xmlCleanupParser();                     \
   5.141 +    } while(0)                                  \
   5.142 +
   5.143 +    
   5.144 +    xen_session *session =
   5.145 +        xen_session_login_with_password(call_func, NULL, username, password);
   5.146 +
   5.147 +    xen_vm vm;
   5.148 +    if (!xen_vm_get_by_uuid(session, &vm,
   5.149 +                            "00000000-0000-0000-0000-000000000000"))
   5.150 +    {
   5.151 +        print_error(session);
   5.152 +        CLEANUP;
   5.153 +        return 1;
   5.154 +    }
   5.155 +
   5.156 +    char *vm_uuid;
   5.157 +    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
   5.158 +    {
   5.159 +        print_error(session);
   5.160 +        xen_vm_free(vm);
   5.161 +        CLEANUP;
   5.162 +        return 1;
   5.163 +    }
   5.164 +
   5.165 +    char *vm_uuid_bytes;
   5.166 +    if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes))
   5.167 +    {
   5.168 +        fprintf(stderr, "xen_uuid_string_to_bytes failed.\n");
   5.169 +        xen_uuid_free(vm_uuid);
   5.170 +        xen_vm_free(vm);
   5.171 +        CLEANUP;
   5.172 +        return 1;
   5.173 +    }
   5.174 +
   5.175 +    xen_vm_record *vm_record;
   5.176 +    if (!xen_vm_get_record(session, &vm_record, vm))
   5.177 +    {
   5.178 +        print_error(session);
   5.179 +        xen_uuid_bytes_free(vm_uuid_bytes);
   5.180 +        xen_uuid_free(vm_uuid);
   5.181 +        xen_vm_free(vm);
   5.182 +        CLEANUP;
   5.183 +        return 1;
   5.184 +    }
   5.185 +
   5.186 +    xen_host host;
   5.187 +    if (!xen_session_get_this_host(session, &host))
   5.188 +    {
   5.189 +        print_error(session);
   5.190 +        xen_vm_record_free(vm_record);
   5.191 +        xen_uuid_bytes_free(vm_uuid_bytes);
   5.192 +        xen_uuid_free(vm_uuid);
   5.193 +        xen_vm_free(vm);
   5.194 +        CLEANUP;
   5.195 +        return 1;
   5.196 +    }
   5.197 +
   5.198 +    xen_string_string_map *versions;
   5.199 +    if (!xen_host_get_software_version(session, &versions, host))
   5.200 +    {
   5.201 +        print_error(session);
   5.202 +        xen_host_free(host);
   5.203 +        xen_vm_record_free(vm_record);
   5.204 +        xen_uuid_bytes_free(vm_uuid_bytes);
   5.205 +        xen_uuid_free(vm_uuid);
   5.206 +        xen_vm_free(vm);
   5.207 +        CLEANUP;
   5.208 +        return 1;
   5.209 +    }
   5.210 +
   5.211 +    printf("%s.\n", vm_uuid);
   5.212 +
   5.213 +    fprintf(stderr, "In bytes, the VM UUID is ");
   5.214 +    for (int i = 0; i < 15; i++)
   5.215 +    {
   5.216 +        fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
   5.217 +    }
   5.218 +    fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
   5.219 +
   5.220 +    printf("%zd.\n", versions->size);
   5.221 +
   5.222 +    for (size_t i = 0; i < versions->size; i++)
   5.223 +    {
   5.224 +        printf("%s -> %s.\n", versions->contents[i].key,
   5.225 +               versions->contents[i].val);
   5.226 +    }
   5.227 +
   5.228 +    printf("%s.\n", vm_record->uuid);
   5.229 +
   5.230 +    printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
   5.231 +
   5.232 +    printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
   5.233 +
   5.234 +    for (size_t i = 0; i < vm_record->vcpus_utilisation->size; i++)
   5.235 +    {
   5.236 +        printf("%"PRId64" -> %lf.\n",
   5.237 +               vm_record->vcpus_utilisation->contents[i].key,
   5.238 +               vm_record->vcpus_utilisation->contents[i].val);
   5.239 +    }
   5.240 +
   5.241 +    xen_uuid_bytes_free(vm_uuid_bytes);
   5.242 +    xen_uuid_free(vm_uuid);
   5.243 +    xen_vm_free(vm);
   5.244 +
   5.245 +    xen_vm_record_free(vm_record);
   5.246 +
   5.247 +    xen_host_free(host);
   5.248 +    xen_string_string_map_free(versions);
   5.249 +
   5.250 +
   5.251 +    xen_vm new_vm = create_new_vm(session);
   5.252 +    if (!session->ok)
   5.253 +    {
   5.254 +        /* Error has been logged, just clean up. */
   5.255 +        CLEANUP;
   5.256 +        return 1;
   5.257 +    }
   5.258 +
   5.259 +    print_vm_power_state(session, new_vm);
   5.260 +    if (!session->ok)
   5.261 +    {
   5.262 +        /* Error has been logged, just clean up. */
   5.263 +        xen_vm_free(new_vm);
   5.264 +        CLEANUP;
   5.265 +        return 1;
   5.266 +    }
   5.267 +
   5.268 +    xen_vm_free(new_vm);
   5.269 +    CLEANUP;
   5.270 +
   5.271 +    return 0;
   5.272 +}
   5.273 +
   5.274 +
   5.275 +/**
   5.276 + * Creation of a new VM, using the Named Parameters idiom.  Allocate the
   5.277 + * xen_vm_record here, but the sets through the library.  Either
   5.278 + * allocation patterns can be used, as long as the allocation and free are
   5.279 + * paired correctly.
   5.280 + */
   5.281 +static xen_vm create_new_vm(xen_session *session)
   5.282 +{
   5.283 +    xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
   5.284 +    xen_vm_record vm_record =
   5.285 +        {
   5.286 +            .name_label = "NewHVM",
   5.287 +            .name_description = "New HVM Description",
   5.288 +            .user_version = 1,
   5.289 +            .is_a_template = false,
   5.290 +            .memory_static_max = 256,
   5.291 +            .memory_dynamic_max = 256,
   5.292 +            .memory_dynamic_min = 128,
   5.293 +            .memory_static_min = 128,
   5.294 +            .vcpus_policy = "credit",
   5.295 +            .vcpus_params = vcpus_params,
   5.296 +            .vcpus_number = 2,
   5.297 +            .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
   5.298 +            .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
   5.299 +            .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
   5.300 +            .hvm_boot = "cda",
   5.301 +        };
   5.302 +
   5.303 +
   5.304 +    xen_vm vm;
   5.305 +    xen_vm_create(session, &vm, &vm_record);
   5.306 +
   5.307 +    if (!session->ok)
   5.308 +    {
   5.309 +        fprintf(stderr, "VM creation failed.\n");
   5.310 +        print_error(session);
   5.311 +        return NULL;
   5.312 +    }
   5.313 +
   5.314 +
   5.315 +    /*
   5.316 +     * Create a new disk for the new VM.
   5.317 +     */
   5.318 +    xen_sr_set *srs;
   5.319 +    if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
   5.320 +        srs->size < 1)
   5.321 +    {
   5.322 +        fprintf(stderr, "SR lookup failed.\n");
   5.323 +        print_error(session);
   5.324 +        xen_vm_free(vm);
   5.325 +        return NULL;
   5.326 +    }
   5.327 +
   5.328 +    xen_sr_record_opt sr_record =
   5.329 +        {
   5.330 +            .u.handle = srs->contents[0]
   5.331 +        };
   5.332 +    xen_vdi_record vdi0_record =
   5.333 +        {
   5.334 +            .name_label = "MyRootFS",
   5.335 +            .name_description = "MyRootFS description",
   5.336 +            .sr = &sr_record,
   5.337 +            .virtual_size = (1 << 21),  // 1GiB / 512 bytes/sector
   5.338 +            .sector_size = 512,
   5.339 +            .location = "file:/root/gentoo.amd64.hvm.img",
   5.340 +            .type = XEN_VDI_TYPE_SYSTEM,
   5.341 +            .sharable = false,
   5.342 +            .read_only = false
   5.343 +        };
   5.344 +    
   5.345 +    xen_vdi vdi0;
   5.346 +    if (!xen_vdi_create(session, &vdi0, &vdi0_record))
   5.347 +    {
   5.348 +        fprintf(stderr, "VDI creation failed.\n");
   5.349 +        print_error(session);
   5.350 +
   5.351 +        xen_sr_set_free(srs);
   5.352 +        xen_vm_free(vm);
   5.353 +        return NULL;
   5.354 +    }
   5.355 +
   5.356 +
   5.357 +    xen_vm_record_opt vm_record_opt =
   5.358 +        {
   5.359 +            .u.handle = vm
   5.360 +        };
   5.361 +    xen_vdi_record_opt vdi0_record_opt =
   5.362 +        {
   5.363 +            .u.handle = vdi0
   5.364 +        };
   5.365 +    xen_vbd_record vbd0_record =
   5.366 +        {
   5.367 +            .vm = &vm_record_opt,
   5.368 +            .vdi = &vdi0_record_opt,
   5.369 +            .device = "xvda1",
   5.370 +            .mode = XEN_VBD_MODE_RW
   5.371 +        };
   5.372 +
   5.373 +    xen_vbd vbd0;
   5.374 +    if (!xen_vbd_create(session, &vbd0, &vbd0_record))
   5.375 +    {
   5.376 +        fprintf(stderr, "VBD creation failed.\n");
   5.377 +        print_error(session);
   5.378 +
   5.379 +        xen_vdi_free(vdi0);
   5.380 +        xen_sr_set_free(srs);
   5.381 +        xen_vm_free(vm);
   5.382 +        return NULL;
   5.383 +    }
   5.384 +
   5.385 +    char *vm_uuid;
   5.386 +    char *vdi0_uuid;
   5.387 +    char *vbd0_uuid;
   5.388 +
   5.389 +    xen_vm_get_uuid(session,  &vm_uuid,   vm);
   5.390 +    xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
   5.391 +    xen_vbd_get_uuid(session, &vbd0_uuid, vbd0); 
   5.392 +
   5.393 +    if (!session->ok)
   5.394 +    {
   5.395 +        fprintf(stderr, "get_uuid call failed.\n");
   5.396 +        print_error(session);
   5.397 +
   5.398 +        xen_uuid_free(vm_uuid);
   5.399 +        xen_uuid_free(vdi0_uuid);
   5.400 +        xen_uuid_free(vbd0_uuid);
   5.401 +        xen_vbd_free(vbd0);
   5.402 +        xen_vdi_free(vdi0);
   5.403 +        xen_sr_set_free(srs);
   5.404 +        xen_vm_free(vm);
   5.405 +        return NULL;
   5.406 +    }
   5.407 +
   5.408 +    fprintf(stderr,
   5.409 +            "Created a new VM, with UUID %s, VDI UUID %s, and VBD UUID %s.\n",
   5.410 +            vm_uuid, vdi0_uuid, vbd0_uuid);
   5.411 +
   5.412 +    xen_uuid_free(vm_uuid);
   5.413 +    xen_uuid_free(vdi0_uuid);
   5.414 +    xen_uuid_free(vbd0_uuid);
   5.415 +    xen_vbd_free(vbd0);
   5.416 +    xen_vdi_free(vdi0);
   5.417 +    xen_sr_set_free(srs);
   5.418 +
   5.419 +    return vm;
   5.420 +}
   5.421 +
   5.422 +
   5.423 +/**
   5.424 + * Print the power state for the given VM.
   5.425 + */
   5.426 +static void print_vm_power_state(xen_session *session, xen_vm vm)
   5.427 +{
   5.428 +    char *vm_uuid;
   5.429 +    enum xen_vm_power_state power_state;
   5.430 +
   5.431 +    if (!xen_vm_get_uuid(session, &vm_uuid, vm))
   5.432 +    {
   5.433 +        print_error(session);
   5.434 +        return;
   5.435 +    }
   5.436 +
   5.437 +    if (!xen_vm_get_power_state(session, &power_state, vm))
   5.438 +    {
   5.439 +        xen_uuid_free(vm_uuid);
   5.440 +        print_error(session);
   5.441 +        return;
   5.442 +    }
   5.443 +
   5.444 +    printf("VM %s power state is %s.\n", vm_uuid,
   5.445 +           xen_vm_power_state_to_string(power_state));
   5.446 +
   5.447 +    xen_uuid_free(vm_uuid);
   5.448 +}
     6.1 --- a/tools/python/scripts/test_hvm_create.py	Wed Jan 31 17:22:00 2007 +0000
     6.2 +++ b/tools/python/scripts/test_hvm_create.py	Wed Jan 31 17:22:17 2007 +0000
     6.3 @@ -13,16 +13,11 @@ vm_cfg = {
     6.4      
     6.5      
     6.6      'VCPUs_policy': 'credit',
     6.7 -    'VCPUs_params': '',
     6.8 +    'VCPUs_params': {},
     6.9      'VCPUs_number': 2,
    6.10 -    'VCPUs_features_required': '',
    6.11 -    'VCPUs_features_can_use': '',
    6.12 -    'VCPUs_features_force_on': '',
    6.13 -    'VCPUs_features_force_off': '',
    6.14  
    6.15      'actions_after_shutdown': 'destroy',
    6.16      'actions_after_reboot': 'restart',
    6.17 -    'actions_after_suspend': 'destroy',
    6.18      'actions_after_crash': 'destroy',
    6.19      
    6.20      'PV_bootloader': '',
    6.21 @@ -44,7 +39,7 @@ vm_cfg = {
    6.22  local_vdi_cfg = {
    6.23      'name_label': 'gentoo.hvm',
    6.24      'name_description': '',
    6.25 -    'uri': 'file:/root/gentoo.amd64.hvm.img',
    6.26 +    'location': 'file:/root/gentoo.amd64.hvm.img',
    6.27      'virtual_size': 0,
    6.28      'sector_size': 0,
    6.29      'type': 'system',
    6.30 @@ -72,6 +67,12 @@ vif_cfg = {
    6.31      'MTU': 1500,
    6.32  }    
    6.33  
    6.34 +console_cfg = {
    6.35 +    'protocol': 'rfb',
    6.36 +    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
    6.37 +}
    6.38 +
    6.39 +
    6.40  import sys
    6.41  import time
    6.42  sys.path.append('/usr/lib/python')
    6.43 @@ -125,6 +126,12 @@ def test_vm_create():
    6.44          vif_cfg['VM'] = vm_uuid
    6.45          vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
    6.46  
    6.47 +        # Create a console
    6.48 +        console_cfg['VM'] = vm_uuid
    6.49 +        console_uuid = execute(server, 'console.create',
    6.50 +                               (session, console_cfg))
    6.51 +        print console_uuid
    6.52 +
    6.53          # Start the VM
    6.54          execute(server, 'VM.start', (session, vm_uuid, False))
    6.55  
     7.1 --- a/tools/python/scripts/test_vm_create.py	Wed Jan 31 17:22:00 2007 +0000
     7.2 +++ b/tools/python/scripts/test_vm_create.py	Wed Jan 31 17:22:17 2007 +0000
     7.3 @@ -15,14 +15,9 @@ vm_cfg = {
     7.4      'VCPUs_policy': 'credit',
     7.5      'VCPUs_params': '',
     7.6      'VCPUs_number': 2,
     7.7 -    'VCPUs_features_required': '',
     7.8 -    'VCPUs_features_can_use': '',
     7.9 -    'VCPUs_features_force_on': '',
    7.10 -    'VCPUs_features_force_off': '',
    7.11  
    7.12      'actions_after_shutdown': 'destroy',
    7.13      'actions_after_reboot': 'restart',
    7.14 -    'actions_after_suspend': 'destroy',
    7.15      'actions_after_crash': 'destroy',
    7.16      
    7.17      'PV_bootloader': '',
    7.18 @@ -65,7 +60,7 @@ vbd_cfg = {
    7.19  local_vdi_cfg = {
    7.20      'name_label': 'gentoo.amd64.img',
    7.21      'name_description': '',
    7.22 -    'uri': 'file:/root/gentoo.amd64.img',
    7.23 +    'location': 'file:/root/gentoo.amd64.img',
    7.24      'virtual_size': 0,
    7.25      'sector_size': 0,
    7.26      'type': 'system',
    7.27 @@ -91,6 +86,11 @@ vif_cfg = {
    7.28      'network': '',
    7.29      'MAC': '',
    7.30      'MTU': 1500,
    7.31 +}
    7.32 +
    7.33 +console_cfg = {
    7.34 +    'protocol': 'rfb',
    7.35 +    'other_config': {'vncunused': 1, 'vncpasswd': 'testing'},
    7.36  }    
    7.37  
    7.38  import sys
    7.39 @@ -157,12 +157,18 @@ def test_vm_create():
    7.40          vif_cfg['VM'] = vm_uuid
    7.41          vif_uuid = execute(server, 'VIF.create', (session, vif_cfg))
    7.42  
    7.43 +        # Create a console
    7.44 +        console_cfg['VM'] = vm_uuid
    7.45 +        console_uuid = execute(server, 'console.create',
    7.46 +                               (session, console_cfg))
    7.47 +        print console_uuid
    7.48 +
    7.49          # Start the VM
    7.50          execute(server, 'VM.start', (session, vm_uuid, False))
    7.51  
    7.52          time.sleep(30)
    7.53  
    7.54 -        test_suspend = True
    7.55 +        test_suspend = False
    7.56          if test_suspend:
    7.57              print 'Suspending VM..'
    7.58              execute(server, 'VM.suspend', (session, vm_uuid))
    7.59 @@ -172,13 +178,13 @@ def test_vm_create():
    7.60              execute(server, 'VM.resume', (session, vm_uuid, False))
    7.61              print 'Resumed VM.'
    7.62  
    7.63 +    finally:
    7.64          # Wait for user to say we're good to shut it down
    7.65          while True:
    7.66              destroy = raw_input('destroy VM? ')
    7.67              if destroy[0] in ('y', 'Y'):
    7.68                  break
    7.69 -
    7.70 -    finally:
    7.71 +        
    7.72          # Clean up
    7.73          if vif_uuid:
    7.74              execute(server, 'VIF.destroy', (session, vif_uuid))
     8.1 --- a/tools/python/scripts/xapi.py	Wed Jan 31 17:22:00 2007 +0000
     8.2 +++ b/tools/python/scripts/xapi.py	Wed Jan 31 17:22:17 2007 +0000
     8.3 @@ -45,7 +45,7 @@ VDI_LIST_FORMAT = '%(name_label)-18s %(u
     8.4  VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'
     8.5  TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'
     8.6  VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'
     8.7 -CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(uri)-32s'
     8.8 +CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(location)-32s'
     8.9  
    8.10  COMMANDS = {
    8.11      'host-info': ('', 'Get Xen Host Info'),
    8.12 @@ -545,7 +545,7 @@ def xapi_console_list(args, async = Fals
    8.13  
    8.14      if not is_long:
    8.15          print CONSOLE_LIST_FORMAT % {'protocol': 'Protocol',
    8.16 -                                     'uri': 'URI',
    8.17 +                                     'location': 'Location',
    8.18                                       'uuid': 'UUID'}
    8.19  
    8.20          for console in consoles:
     9.1 --- a/tools/python/xen/xend/XendAPI.py	Wed Jan 31 17:22:00 2007 +0000
     9.2 +++ b/tools/python/xen/xend/XendAPI.py	Wed Jan 31 17:22:17 2007 +0000
     9.3 @@ -1121,11 +1121,11 @@ class XendAPI(object):
     9.4      
     9.5      def VM_get_VCPUs_policy(self, session, vm_ref):
     9.6          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
     9.7 -        return dom.get_vcpus_policy()
     9.8 +        return xen_api_success(dom.get_vcpus_policy())
     9.9      
    9.10      def VM_get_VCPUs_params(self, session, vm_ref):
    9.11          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    9.12 -        return xen_api_todo() # need access to scheduler
    9.13 +        return xen_api_success(dom.get_vcpus_params())
    9.14      
    9.15      def VM_get_actions_after_shutdown(self, session, vm_ref):
    9.16          dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
    9.17 @@ -1186,7 +1186,7 @@ class XendAPI(object):
    9.18          return xen_api_success(dom.get_platform_keymap())
    9.19      
    9.20      def VM_get_other_config(self, session, vm_ref):
    9.21 -        return self.VM_get('otherconfig', session, vm_ref)        
    9.22 +        return self.VM_get('other_config', session, vm_ref)        
    9.23  
    9.24      def VM_get_is_control_domain(self, session, vm_ref):
    9.25          xd = XendDomain.instance()
    9.26 @@ -1363,7 +1363,7 @@ class XendAPI(object):
    9.27              'platform_keymap': xeninfo.get_platform_keymap(),
    9.28              'PCI_bus': xeninfo.get_pci_bus(),
    9.29              'tools_version': xeninfo.get_tools_version(),
    9.30 -            'other_config': xeninfo.info.get('otherconfig'),
    9.31 +            'other_config': xeninfo.info.get('other_config', {}),
    9.32              'is_control_domain': xeninfo == xendom.privilegedDomain(),
    9.33          }
    9.34          return xen_api_success(record)
    9.35 @@ -1469,7 +1469,7 @@ class XendAPI(object):
    9.36              vdi = XendNode.instance().get_vdi_by_uuid(vdi_ref)
    9.37              if not vdi:
    9.38                  return xen_api_error(['VDI_HANDLE_INVALID', vdi_ref])
    9.39 -            vdi_image = vdi.get_image_uri()
    9.40 +            vdi_image = vdi.get_location()
    9.41              vbd_ref = XendTask.log_progress(0, 100,
    9.42                                              dom.create_vbd,
    9.43                                              vbd_struct, vdi_image)
    9.44 @@ -1835,8 +1835,9 @@ class XendAPI(object):
    9.45      # ----------------------------------------------------------------
    9.46  
    9.47  
    9.48 -    console_attr_ro = ['uri', 'protocol', 'VM']
    9.49 -    console_attr_rw = []
    9.50 +    console_attr_ro = ['location', 'protocol', 'VM']
    9.51 +    console_attr_rw = ['other_config']
    9.52 +    console_funcs = [('create', 'console')]
    9.53      
    9.54      def console_get_all(self, session):
    9.55          xendom = XendDomain.instance()
    9.56 @@ -1844,10 +1845,10 @@ class XendAPI(object):
    9.57          cons = reduce(lambda x, y: x + y, cons)
    9.58          return xen_api_success(cons)
    9.59  
    9.60 -    def console_get_uri(self, session, console_ref):
    9.61 +    def console_get_location(self, session, console_ref):
    9.62          return xen_api_success(xendom.get_dev_property_by_uuid('console',
    9.63                                                                 console_ref,
    9.64 -                                                               'uri'))
    9.65 +                                                               'location'))
    9.66  
    9.67      def console_get_protocol(self, session, console_ref):
    9.68          return xen_api_success(xendom.get_dev_property_by_uuid('console',
    9.69 @@ -1879,6 +1880,22 @@ class XendAPI(object):
    9.70              
    9.71          return xen_api_success(return_cfg)
    9.72  
    9.73 +    def console_create(self, session, console_struct):
    9.74 +        xendom = XendDomain.instance()
    9.75 +        if not xendom.is_valid_vm(console_struct['VM']):
    9.76 +            return xen_api_error(['VM_HANDLE_INVALID', console_struct['VM']])
    9.77 +        
    9.78 +        dom = xendom.get_vm_by_uuid(console_struct['VM'])
    9.79 +        try:
    9.80 +            if 'protocol' not in console_struct:
    9.81 +                return xen_api_error(['CONSOLE_PROTOCOL_INVALID',
    9.82 +                                      'No protocol specified'])
    9.83 +            
    9.84 +            console_ref = dom.create_console(console_struct)
    9.85 +            xendom.managed_config_save(dom)
    9.86 +            return xen_api_success(console_ref)
    9.87 +        except XendError, e:
    9.88 +            return xen_api_error([XEND_ERROR_TODO, str(e)])
    9.89  
    9.90      # Xen API: Class SR
    9.91      # ----------------------------------------------------------------
    10.1 --- a/tools/python/xen/xend/XendAuthSessions.py	Wed Jan 31 17:22:00 2007 +0000
    10.2 +++ b/tools/python/xen/xend/XendAuthSessions.py	Wed Jan 31 17:22:17 2007 +0000
    10.3 @@ -21,11 +21,6 @@ from xen.xend import uuid
    10.4  from xen.xend.XendError import *
    10.5  from xen.xend.XendLogging import log
    10.6  
    10.7 -try:
    10.8 -    import PAM
    10.9 -except ImportError:
   10.10 -    log.warn("python-pam is required for XenAPI support.")
   10.11 -
   10.12  class XendAuthSessions:
   10.13      """Keeps track of Xen API Login Sessions using PAM.
   10.14  
   10.15 @@ -80,7 +75,11 @@ class XendAuthSessions:
   10.16          """
   10.17          pam_auth = None
   10.18          try:
   10.19 +            import PAM
   10.20              pam_auth = PAM.pam()
   10.21 +        except ImportError:
   10.22 +            log.warn("python-pam is required for XenAPI support.")
   10.23 +            return False
   10.24          except NameError:
   10.25              # if PAM doesn't exist, let's ignore it
   10.26              return False
    11.1 --- a/tools/python/xen/xend/XendConfig.py	Wed Jan 31 17:22:00 2007 +0000
    11.2 +++ b/tools/python/xen/xend/XendConfig.py	Wed Jan 31 17:22:17 2007 +0000
    11.3 @@ -126,6 +126,7 @@ XENAPI_HVM_CFG = {
    11.4      'platform_serial' : 'serial',
    11.5      'platform_localtime': 'localtime',
    11.6      'platform_keymap' : 'keymap',
    11.7 +    'HVM_boot': 'boot',
    11.8  }    
    11.9  
   11.10  # List of XendConfig configuration keys that have no direct equivalent
   11.11 @@ -250,7 +251,8 @@ LEGACY_IMAGE_CFG = [
   11.12      ('sdl', int),
   11.13      ('vncdisplay', int),
   11.14      ('vncunused', int),
   11.15 -    ('vncpasswd', str),    
   11.16 +    ('vncpasswd', str),
   11.17 +    ('vnclisten', str),
   11.18  ]
   11.19  
   11.20  LEGACY_IMAGE_HVM_CFG = [
   11.21 @@ -379,6 +381,7 @@ class XendConfig(dict):
   11.22              'vif_refs': [],
   11.23              'vbd_refs': [],
   11.24              'vtpm_refs': [],
   11.25 +            'other_config': {},
   11.26          }
   11.27          
   11.28          defaults['name_label'] = 'Domain-' + defaults['uuid']
   11.29 @@ -660,6 +663,25 @@ class XendConfig(dict):
   11.30          self['vbd_refs'] = cfg.get('vbd_refs', [])
   11.31          self['vtpm_refs'] = cfg.get('vtpm_refs', [])
   11.32  
   11.33 +        # coalesce hvm vnc frame buffer with vfb config
   11.34 +        if self['image']['type'] == 'hvm' and self['image'].get('vnc', 0):
   11.35 +            # add vfb device if it isn't there already
   11.36 +            has_rfb = False
   11.37 +            for console_uuid in self['console_refs']:
   11.38 +                if self['devices'][console_uuid][1].get('protocol') == 'rfb':
   11.39 +                    has_rfb = True
   11.40 +                    break
   11.41 +
   11.42 +            if not has_rfb:
   11.43 +                dev_config = ['vfb']
   11.44 +                # copy VNC related params from image config to vfb dev conf
   11.45 +                for key in ['vncpasswd', 'vncunused', 'vncdisplay',
   11.46 +                            'vnclisten']:
   11.47 +                    if key in self['image']:
   11.48 +                        dev_config.append([key, self['image'][key]])
   11.49 +
   11.50 +                self.device_add('vfb', cfg_sxp = dev_config)
   11.51 +
   11.52  
   11.53      def _sxp_to_xapi_unsupported(self, sxp_cfg):
   11.54          """Read in an SXP configuration object and populate
   11.55 @@ -756,7 +778,7 @@ class XendConfig(dict):
   11.56  
   11.57                  # currently unsupported options
   11.58                  self['image']['hvm']['device_model'] = LEGACY_DM
   11.59 -                self['image']['vnc'] = 1
   11.60 +                self['image']['vnc'] = 0
   11.61                  self['image']['hvm']['pae'] = 1
   11.62  
   11.63                  if self['platform_enable_audio']:
   11.64 @@ -883,8 +905,9 @@ class XendConfig(dict):
   11.65                                  # store as part of the device config.
   11.66                                  dev_uuid = sxp.child_value(config, 'uuid')
   11.67                                  dev_type, dev_cfg = self['devices'][dev_uuid]
   11.68 -                                config.append(['bootable',
   11.69 -                                               int(dev_cfg['bootable'])])
   11.70 +                                is_bootable = dev_cfg.get('bootable', 0)
   11.71 +                                config.append(['bootable', int(is_bootable)])
   11.72 +
   11.73                              sxpr.append(['device', config])
   11.74  
   11.75                          found = True
   11.76 @@ -955,7 +978,7 @@ class XendConfig(dict):
   11.77                      pass
   11.78  
   11.79              if dev_type == 'vbd':
   11.80 -                dev_info['bootable'] = False
   11.81 +                dev_info['bootable'] = 0
   11.82                  if dev_info.get('dev', '').startswith('ioemu:'):
   11.83                      dev_info['driver'] = 'ioemu'
   11.84                  else:
   11.85 @@ -975,7 +998,7 @@ class XendConfig(dict):
   11.86                      if dev_type == 'vbd' and not target[param]:
   11.87                          # Compat hack -- this is the first disk, so mark it
   11.88                          # bootable.
   11.89 -                        dev_info['bootable'] = True
   11.90 +                        dev_info['bootable'] = 1
   11.91                      target[param].append(dev_uuid)
   11.92              elif dev_type == 'tap':
   11.93                  if 'vbd_refs' not in target:
   11.94 @@ -984,8 +1007,30 @@ class XendConfig(dict):
   11.95                      if not target['vbd_refs']:
   11.96                          # Compat hack -- this is the first disk, so mark it
   11.97                          # bootable.
   11.98 -                        dev_info['bootable'] = True
   11.99 +                        dev_info['bootable'] = 1
  11.100                      target['vbd_refs'].append(dev_uuid)
  11.101 +                    
  11.102 +            elif dev_type == 'vfb':
  11.103 +                # Populate other config with aux data that is associated
  11.104 +                # with vfb
  11.105 +
  11.106 +                other_config = {}
  11.107 +                for key in ['vncunused', 'vncdisplay', 'vnclisten',
  11.108 +                            'vncpasswd', 'type', 'display', 'xauthority',
  11.109 +                            'keymap']:
  11.110 +                    if key in dev_info:
  11.111 +                        other_config[key] = dev_info[key]
  11.112 +                target['devices'][dev_uuid][1]['other_config'] =  other_config
  11.113 +                
  11.114 +                
  11.115 +                if 'console_refs' not in target:
  11.116 +                    target['console_refs'] = []
  11.117 +
  11.118 +                # Treat VFB devices as console devices so they are found
  11.119 +                # through Xen API
  11.120 +                if dev_uuid not in target['console_refs']:
  11.121 +                    target['console_refs'].append(dev_uuid)
  11.122 +
  11.123              elif dev_type == 'console':
  11.124                  if 'console_refs' not in target:
  11.125                      target['console_refs'] = []
  11.126 @@ -1025,8 +1070,8 @@ class XendConfig(dict):
  11.127                  dev_info['uname'] = cfg_xenapi.get('image', '')
  11.128                  dev_info['dev'] = '%s:%s' % (cfg_xenapi.get('device'),
  11.129                                               old_vbd_type)
  11.130 -                dev_info['bootable'] = cfg_xenapi.get('bootable', False)
  11.131 -                dev_info['driver'] = cfg_xenapi.get('driver')
  11.132 +                dev_info['bootable'] = int(cfg_xenapi.get('bootable', 0))
  11.133 +                dev_info['driver'] = cfg_xenapi.get('driver', '')
  11.134                  dev_info['VDI'] = cfg_xenapi.get('VDI', '')
  11.135                      
  11.136                  if cfg_xenapi.get('mode') == 'RW':
  11.137 @@ -1048,50 +1093,117 @@ class XendConfig(dict):
  11.138                  target['devices'][dev_uuid] = (dev_type, dev_info)
  11.139                  target['vtpm_refs'].append(dev_uuid)
  11.140  
  11.141 +            elif dev_type == 'console':
  11.142 +                dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
  11.143 +                dev_info['uuid'] = dev_uuid
  11.144 +                dev_info['protocol'] = cfg_xenapi.get('protocol', 'rfb')
  11.145 +                dev_info['other_config'] = cfg_xenapi.get('other_config', {})
  11.146 +                if dev_info['protocol'] == 'rfb':
  11.147 +                    # collapse other config into devinfo for things
  11.148 +                    # such as vncpasswd, vncunused, etc.                    
  11.149 +                    dev_info.update(cfg_xenapi.get('other_config', {}))
  11.150 +                    dev_info['type'] = 'vnc'                        
  11.151 +                    target['devices'][dev_uuid] = ('vfb', dev_info)
  11.152 +                    target['console_refs'].append(dev_uuid)
  11.153 +
  11.154 +                    # Finally, if we are a pvfb, we need to make a vkbd
  11.155 +                    # as well that is not really exposed to Xen API
  11.156 +                    vkbd_uuid = uuid.createString()
  11.157 +                    target['devices'][vkbd_uuid] = ('vkbd', {})
  11.158 +                    
  11.159 +                elif dev_info['protocol'] == 'vt100':
  11.160 +                    # if someone tries to create a VT100 console
  11.161 +                    # via the Xen API, we'll have to ignore it
  11.162 +                    # because we create one automatically in
  11.163 +                    # XendDomainInfo._update_consoles
  11.164 +                    raise XendConfigError('Creating vt100 consoles via '
  11.165 +                                          'Xen API is unsupported')
  11.166 +
  11.167              return dev_uuid
  11.168  
  11.169          # no valid device to add
  11.170          return ''
  11.171  
  11.172 -    def console_add(self, protocol, uri):
  11.173 +    def console_add(self, protocol, location, other_config = {}):
  11.174          dev_uuid = uuid.createString()
  11.175 -        dev_info = {
  11.176 -            'uuid': dev_uuid,
  11.177 -            'protocol': protocol,
  11.178 -            'uri': uri
  11.179 -        }
  11.180 -        if 'devices' not in self:
  11.181 -            self['devices'] = {}
  11.182 +        if protocol == 'vt100':
  11.183 +            dev_info = {
  11.184 +                'uuid': dev_uuid,
  11.185 +                'protocol': protocol,
  11.186 +                'location': location,
  11.187 +                'other_config': other_config,
  11.188 +            }
  11.189 +
  11.190 +            if 'devices' not in self:
  11.191 +                self['devices'] = {}
  11.192              
  11.193 -        self['devices'][dev_uuid] = ('console', dev_info)
  11.194 -        self['console_refs'].append(dev_uuid)
  11.195 -        return dev_info
  11.196 +            self['devices'][dev_uuid] = ('console', dev_info)
  11.197 +            self['console_refs'].append(dev_uuid)
  11.198 +            return dev_info
  11.199 +
  11.200 +        return {}
  11.201 +
  11.202 +    def console_update(self, console_uuid, key, value):
  11.203 +        for dev_uuid, (dev_type, dev_info) in self['devices'].items():
  11.204 +            if dev_uuid == console_uuid:
  11.205 +                dev_info[key] = value
  11.206 +                break
  11.207  
  11.208      def console_get_all(self, protocol):
  11.209 -        consoles = [dinfo for dtype, dinfo in self['devices'].values()
  11.210 -                    if dtype == 'console']
  11.211 -        return [c for c in consoles if c.get('protocol') == protocol]
  11.212 +        if protocol == 'vt100':
  11.213 +            consoles = [dinfo for dtype, dinfo in self['devices'].values()
  11.214 +                        if dtype == 'console']
  11.215 +            return [c for c in consoles if c.get('protocol') == protocol]
  11.216 +
  11.217 +        elif protocol == 'rfb':
  11.218 +            vfbs = [dinfo for dtype, dinfo in self['devices'].values()
  11.219 +                   if dtype == 'vfb']
  11.220  
  11.221 -    def device_update(self, dev_uuid, cfg_sxp):
  11.222 +            # move all non-console key values to other_config before
  11.223 +            # returning console config
  11.224 +            valid_keys = ['uuid', 'location']
  11.225 +            for vfb in vfbs:
  11.226 +                other_config = {}
  11.227 +                for key, val in vfb.items():
  11.228 +                    if key not in valid_keys:
  11.229 +                        other_config[key] = vfb[key]
  11.230 +                    del vfb[key]
  11.231 +                vfb['other_config'] = other_config
  11.232 +                vfb['protocol'] = 'rfb'
  11.233 +                        
  11.234 +            return vfbs
  11.235 +
  11.236 +        else:
  11.237 +            return []
  11.238 +
  11.239 +    def device_update(self, dev_uuid, cfg_sxp = [], cfg_xenapi = {}):
  11.240          """Update an existing device with the new configuration.
  11.241  
  11.242          @rtype: boolean
  11.243          @return: Returns True if succesfully found and updated a device conf
  11.244          """
  11.245 -        if dev_uuid in self['devices']:
  11.246 +        if dev_uuid in self['devices'] and cfg_sxp:
  11.247              if sxp.child0(cfg_sxp) == 'device':            
  11.248                  config = sxp.child0(cfg_sxp)
  11.249              else:
  11.250                  config = cfg_sxp
  11.251 -                
  11.252 +
  11.253 +            dev_type, dev_info = self['devices'][dev_uuid]
  11.254              for opt_val in config[1:]:
  11.255                  try:
  11.256                      opt, val = opt_val
  11.257 -                    self['devices'][dev_uuid][opt] = val
  11.258 +                    dev_info[opt] = val
  11.259                  except (TypeError, ValueError):
  11.260                      pass # no value for this config option
  11.261 -            
  11.262 +
  11.263 +            self['devices'][dev_uuid] = (dev_type, dev_info)
  11.264              return True
  11.265 +        
  11.266 +        elif dev_uuid in self['devices'] and cfg_xenapi:
  11.267 +            dev_type, dev_info = self['devices'][dev_uuid]
  11.268 +            for key, val in cfg_xenapi.items():
  11.269 +                dev_info[key] = val
  11.270 +            self['devices'][dev_uuid] = (dev_type, dev_info)
  11.271  
  11.272          return False
  11.273  
  11.274 @@ -1111,7 +1223,12 @@ class XendConfig(dict):
  11.275                                    "configuration dictionary.")
  11.276              
  11.277          sxpr.append(dev_type)
  11.278 -        config = [(opt, val) for opt, val in dev_info.items()]
  11.279 +        if dev_type in ('console', 'vfb'):
  11.280 +            config = [(opt, val) for opt, val in dev_info.items()
  11.281 +                      if opt != 'other_config']
  11.282 +        else:
  11.283 +            config = [(opt, val) for opt, val in dev_info.items()]
  11.284 +            
  11.285          sxpr += config
  11.286  
  11.287          return sxpr
    12.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 31 17:22:00 2007 +0000
    12.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jan 31 17:22:17 2007 +0000
    12.3 @@ -695,16 +695,29 @@ class XendDomainInfo:
    12.4              if not serial_consoles:
    12.5                  cfg = self.info.console_add('vt100', self.console_port)
    12.6                  self._createDevice('console', cfg)
    12.7 +            else:
    12.8 +                console_uuid = serial_consoles[0].get('uuid')
    12.9 +                self.info.console_update(console_uuid, 'location',
   12.10 +                                         self.console_port)
   12.11 +                
   12.12  
   12.13 -        # Update VNC port if it exists
   12.14 +        # Update VNC port if it exists and write to xenstore
   12.15          vnc_port = self.readDom('console/vnc-port')
   12.16          if vnc_port is not None:
   12.17 -            vnc_consoles = self.info.console_get_all('rfb')
   12.18 -            if not vnc_consoles:
   12.19 -                cfg = self.info.console_add('rfb', 'localhost:%s' %
   12.20 -                                           str(vnc_port))
   12.21 -                self._createDevice('console', cfg)                
   12.22 +            for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
   12.23 +                if dev_type == 'vfb':
   12.24 +                    old_location = dev_info.get('location')
   12.25 +                    listen_host = dev_info.get('vnclisten', 'localhost')
   12.26 +                    new_location = '%s:%s' % (listen_host, str(vnc_port))
   12.27 +                    if old_location == new_location:
   12.28 +                        break
   12.29  
   12.30 +                    dev_info['location'] = new_location
   12.31 +                    self.info.device_update(dev_uuid, cfg_xenapi = dev_info)
   12.32 +                    vfb_ctrl = self.getDeviceController('vfb')
   12.33 +                    vfb_ctrl.reconfigureDevice(0, dev_info)
   12.34 +                    break
   12.35 +                
   12.36      #
   12.37      # Function to update xenstore /vm/*
   12.38      #
   12.39 @@ -1963,7 +1976,11 @@ class XendDomainInfo:
   12.40          else:
   12.41              return 'unknown'
   12.42      def get_vcpus_params(self):
   12.43 -        return '' # TODO
   12.44 +        if self.getDomid() is None:
   12.45 +            return {}
   12.46 +
   12.47 +        retval = xc.sched_credit_domain_get(self.getDomid())
   12.48 +        return retval
   12.49      def get_power_state(self):
   12.50          return XEN_API_VM_POWER_STATE[self.state]
   12.51      def get_platform_std_vga(self):
   12.52 @@ -2017,21 +2034,18 @@ class XendDomainInfo:
   12.53  
   12.54          @rtype: dictionary
   12.55          """
   12.56 -        dev_type_config = self.info['devices'].get(dev_uuid)
   12.57 +        dev_type, dev_config = self.info['devices'].get(dev_uuid, (None, None))
   12.58  
   12.59          # shortcut if the domain isn't started because
   12.60          # the devcontrollers will have no better information
   12.61          # than XendConfig.
   12.62          if self.state in (XEN_API_VM_POWER_STATE_HALTED,):
   12.63 -            if dev_type_config:
   12.64 -                return copy.deepcopy(dev_type_config[1])
   12.65 +            if dev_config:
   12.66 +                return copy.deepcopy(dev_config)
   12.67              return None
   12.68  
   12.69          # instead of using dev_class, we use the dev_type
   12.70          # that is from XendConfig.
   12.71 -        # This will accomdate 'tap' as well as 'vbd'
   12.72 -        dev_type = dev_type_config[0]
   12.73 -        
   12.74          controller = self.getDeviceController(dev_type)
   12.75          if not controller:
   12.76              return None
   12.77 @@ -2040,14 +2054,14 @@ class XendDomainInfo:
   12.78          if not all_configs:
   12.79              return None
   12.80  
   12.81 -        dev_config = copy.deepcopy(dev_type_config[1])
   12.82 +        updated_dev_config = copy.deepcopy(dev_config)
   12.83          for _devid, _devcfg in all_configs.items():
   12.84              if _devcfg.get('uuid') == dev_uuid:
   12.85 -                dev_config.update(_devcfg)
   12.86 -                dev_config['id'] = _devid
   12.87 -                return dev_config
   12.88 +                updated_dev_config.update(_devcfg)
   12.89 +                updated_dev_config['id'] = _devid
   12.90 +                return updated_dev_config
   12.91  
   12.92 -        return dev_config
   12.93 +        return updated_dev_config
   12.94                      
   12.95      def get_dev_xenapi_config(self, dev_class, dev_uuid):
   12.96          config = self.get_dev_config_by_uuid(dev_class, dev_uuid)
   12.97 @@ -2230,6 +2244,21 @@ class XendDomainInfo:
   12.98  
   12.99          return dev_uuid
  12.100  
  12.101 +    def create_console(self, xenapi_console):
  12.102 +        """ Create a console device from a Xen API struct.
  12.103 +
  12.104 +        @return: uuid of device
  12.105 +        @rtype: string
  12.106 +        """
  12.107 +        if self.state not in (DOM_STATE_HALTED,):
  12.108 +            raise VmError("Can only add console to a halted domain.")
  12.109 +
  12.110 +        dev_uuid = self.info.device_add('console', cfg_xenapi = xenapi_console)
  12.111 +        if not dev_uuid:
  12.112 +            raise XendError('Failed to create device')
  12.113 +
  12.114 +        return dev_uuid
  12.115 +
  12.116      def destroy_device_by_uuid(self, dev_type, dev_uuid):
  12.117          if dev_uuid not in self.info['devices']:
  12.118              raise XendError('Device does not exist')
    13.1 --- a/tools/python/xen/xend/XendVDI.py	Wed Jan 31 17:22:00 2007 +0000
    13.2 +++ b/tools/python/xen/xend/XendVDI.py	Wed Jan 31 17:22:17 2007 +0000
    13.3 @@ -73,6 +73,7 @@ class XendVDI(AutoSaveObject):
    13.4          self.sharable = False
    13.5          self.read_only = False
    13.6          self.type = "system"
    13.7 +        self.location = ''
    13.8  
    13.9      def load_config_dict(self, cfg):
   13.10          """Loads configuration into the object from a dict.
   13.11 @@ -147,9 +148,10 @@ class XendVDI(AutoSaveObject):
   13.12                  'sharable': False,
   13.13                  'readonly': False,
   13.14                  'SR': self.sr_uuid,
   13.15 +                'location': self.get_location(),
   13.16                  'VBDs': []}
   13.17  
   13.18 -    def get_image_uri(self):
   13.19 +    def get_location(self):
   13.20          raise NotImplementedError()
   13.21                  
   13.22  
   13.23 @@ -163,9 +165,10 @@ class XendQCoWVDI(XendVDI):
   13.24          self.virtual_size = vsize
   13.25          self.sector_size = 512
   13.26          self.auto_save = True
   13.27 +        self.location = 'tap:qcow:%s' % self.qcow_path
   13.28  
   13.29 -    def get_image_uri(self):
   13.30 -        return 'tap:qcow:%s' % self.qcow_path
   13.31 +    def get_location(self):
   13.32 +        return self.location
   13.33  
   13.34  class XendLocalVDI(XendVDI):
   13.35      def __init__(self, vdi_struct):
   13.36 @@ -183,7 +186,7 @@ class XendLocalVDI(XendVDI):
   13.37          self.type = vdi_struct.get('type', '')
   13.38          self.sharable = vdi_struct.get('sharable', False)
   13.39          self.read_only = vdi_struct.get('read_only', False)
   13.40 -        self.image_uri = vdi_struct.get('uri', 'file:/dev/null')
   13.41 +        self.location = vdi_struct.get('location', 'file:/dev/null')
   13.42  
   13.43 -    def get_image_uri(self):
   13.44 -        return self.image_uri
   13.45 +    def get_location(self):
   13.46 +        return self.location
    14.1 --- a/tools/python/xen/xend/image.py	Wed Jan 31 17:22:00 2007 +0000
    14.2 +++ b/tools/python/xen/xend/image.py	Wed Jan 31 17:22:17 2007 +0000
    14.3 @@ -26,6 +26,7 @@ import xen.lowlevel.xc
    14.4  from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
    14.5  from xen.xend.XendError import VmError, XendError
    14.6  from xen.xend.XendLogging import log
    14.7 +from xen.xend.XendOptions import instance as xenopts
    14.8  from xen.xend.server.netif import randomMAC
    14.9  from xen.xend.xenstore.xswatch import xswatch
   14.10  from xen.xend import arch
   14.11 @@ -340,8 +341,6 @@ class HVMImageHandler(ImageHandler):
   14.12  
   14.13          self.pid = None
   14.14  
   14.15 -        self.dmargs += self.configVNC(imageConfig)
   14.16 -
   14.17          self.pae  = imageConfig['hvm'].get('pae', 0)
   14.18          self.apic  = imageConfig['hvm'].get('apic', 0)
   14.19          self.acpi  = imageConfig['hvm']['devices'].get('acpi', 0)
   14.20 @@ -379,8 +378,8 @@ class HVMImageHandler(ImageHandler):
   14.21          dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
   14.22                     'localtime', 'serial', 'stdvga', 'isa',
   14.23                     'acpi', 'usb', 'usbdevice', 'keymap' ]
   14.24 +        
   14.25          hvmDeviceConfig = vmConfig['image']['hvm']['devices']
   14.26 -
   14.27          ret = ['-vcpus', str(self.vm.getVCpuCount())]
   14.28  
   14.29          for a in dmargs:
   14.30 @@ -439,49 +438,59 @@ class HVMImageHandler(ImageHandler):
   14.31              ret.append("-net")
   14.32              ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
   14.33  
   14.34 -        return ret
   14.35  
   14.36 -    def configVNC(self, imageConfig):
   14.37 -        # Handle graphics library related options
   14.38 -        vnc = imageConfig.get('vnc')
   14.39 -        sdl = imageConfig.get('sdl')
   14.40 -        ret = []
   14.41 -        nographic = imageConfig.get('nographic')
   14.42 -
   14.43 -        # get password from VM config (if password omitted, None)
   14.44 -        vncpasswd_vmconfig = imageConfig.get('vncpasswd')
   14.45 -
   14.46 -        if nographic:
   14.47 +        #
   14.48 +        # Find RFB console device, and if it exists, make QEMU enable
   14.49 +        # the VNC console.
   14.50 +        #
   14.51 +        if vmConfig['image'].get('nographic'):
   14.52 +            # skip vnc init if nographic is set
   14.53              ret.append('-nographic')
   14.54              return ret
   14.55  
   14.56 -        if vnc:
   14.57 -            vncdisplay = imageConfig.get('vncdisplay',
   14.58 -                                         int(self.vm.getDomid()))
   14.59 -            vncunused = imageConfig.get('vncunused')
   14.60 +        vnc_config = {}
   14.61 +        has_vfb = False
   14.62 +        has_vnc = int(vmConfig['image'].get('vnc', 0)) != 0
   14.63 +        for dev_uuid in vmConfig['console_refs']:
   14.64 +            dev_type, dev_info = vmConfig['devices'][dev_uuid]
   14.65 +            if dev_type == 'vfb':
   14.66 +                vnc_config = dev_info.get('other_config', {})
   14.67 +                has_vfb = True
   14.68 +                break
   14.69  
   14.70 -            if vncunused:
   14.71 -                ret += ['-vncunused']
   14.72 -            else:
   14.73 -                ret += ['-vnc', '%d' % vncdisplay]
   14.74 +        if not vnc_config:
   14.75 +            for key in ('vncunused', 'vnclisten', 'vncdisplay', 'vncpasswd'):
   14.76 +                if key in vmConfig['image']:
   14.77 +                    vnc_config[key] = vmConfig['image'][key]
   14.78  
   14.79 -            vnclisten = imageConfig.get('vnclisten')
   14.80 +        if not has_vfb and not has_vnc:
   14.81 +            ret.append('-nographic')
   14.82 +            return ret
   14.83  
   14.84 -            if not(vnclisten):
   14.85 -                vnclisten = (xen.xend.XendOptions.instance().
   14.86 -                             get_vnclisten_address())
   14.87 -            if vnclisten:
   14.88 -                ret += ['-vnclisten', vnclisten]
   14.89 +                    
   14.90 +        if not vnc_config.get('vncunused', 0) and \
   14.91 +               vnc_config.get('vncdisplay', 0):
   14.92 +            ret.append('-vnc')
   14.93 +            ret.append(str(vncdisplay))
   14.94 +        else:
   14.95 +            ret.append('-vncunused')
   14.96  
   14.97 -            vncpasswd = vncpasswd_vmconfig
   14.98 -            if vncpasswd is None:
   14.99 -                vncpasswd = (xen.xend.XendOptions.instance().
  14.100 -                             get_vncpasswd_default())
  14.101 -                if vncpasswd is None:
  14.102 -                    raise VmError('vncpasswd is not set up in ' +
  14.103 -                                  'VMconfig and xend-config.')
  14.104 -            if vncpasswd != '':
  14.105 -                self.vm.storeVm("vncpasswd", vncpasswd)
  14.106 +        vnclisten = vnc_config.get('vnclisten',
  14.107 +                                   xenopts().get_vnclisten_address())
  14.108 +        ret.append('-vnclisten')
  14.109 +        ret.append(str(vnclisten))
  14.110 +        
  14.111 +        # Store vncpassword in xenstore
  14.112 +        vncpasswd = vnc_config.get('vncpasswd')
  14.113 +        if not vncpasswd:
  14.114 +            vncpasswd = xenopts().get_vncpasswd_default()
  14.115 +                    
  14.116 +        if vncpasswd is None:
  14.117 +            raise VmError('vncpasswd is not setup in vmconfig or '
  14.118 +                          'xend-config.sxp')
  14.119 +
  14.120 +        if vncpasswd != '':
  14.121 +            self.vm.storeVm('vncpasswd', vncpasswd)
  14.122  
  14.123          return ret
  14.124  
    15.1 --- a/tools/python/xen/xend/server/ConsoleController.py	Wed Jan 31 17:22:00 2007 +0000
    15.2 +++ b/tools/python/xen/xend/server/ConsoleController.py	Wed Jan 31 17:22:17 2007 +0000
    15.3 @@ -8,7 +8,7 @@ class ConsoleController(DevController):
    15.4      console devices with persistent UUIDs.
    15.5      """
    15.6  
    15.7 -    valid_cfg = ['uri', 'uuid', 'protocol']
    15.8 +    valid_cfg = ['location', 'uuid', 'protocol']
    15.9  
   15.10      def __init__(self, vm):
   15.11          DevController.__init__(self, vm)
   15.12 @@ -29,3 +29,7 @@ class ConsoleController(DevController):
   15.13  
   15.14      def migrate(self, deviceConfig, network, dst, step, domName):
   15.15          return 0
   15.16 +
   15.17 +    def destroyDevice(self, devid, force):
   15.18 +        DevController.destroyDevice(self, devid, True)
   15.19 +        
    16.1 --- a/tools/python/xen/xend/server/vfbif.py	Wed Jan 31 17:22:00 2007 +0000
    16.2 +++ b/tools/python/xen/xend/server/vfbif.py	Wed Jan 31 17:22:17 2007 +0000
    16.3 @@ -14,7 +14,8 @@ def spawn_detached(path, args, env):
    16.4          os.waitpid(p, 0)
    16.5          
    16.6  CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
    16.7 -                  'display', 'xauthority', 'keymap' ]
    16.8 +                  'display', 'xauthority', 'keymap',
    16.9 +                  'uuid', 'location', 'protocol']
   16.10  
   16.11  class VfbifController(DevController):
   16.12      """Virtual frame buffer controller. Handles all vfb devices for a domain.
   16.13 @@ -27,10 +28,11 @@ class VfbifController(DevController):
   16.14      def getDeviceDetails(self, config):
   16.15          """@see DevController.getDeviceDetails"""
   16.16  
   16.17 -        back = dict([(k, config[k]) for k in CONFIG_ENTRIES
   16.18 +        back = dict([(k, str(config[k])) for k in CONFIG_ENTRIES
   16.19                       if config.has_key(k)])
   16.20  
   16.21 -        return (0, back, {})
   16.22 +        devid = 0
   16.23 +        return (devid, back, {})
   16.24  
   16.25  
   16.26      def getDeviceConfiguration(self, devid):
   16.27 @@ -44,6 +46,10 @@ class VfbifController(DevController):
   16.28  
   16.29      def createDevice(self, config):
   16.30          DevController.createDevice(self, config)
   16.31 +        if self.vm.info.get('HVM_boot'):
   16.32 +            # is HVM, so qemu-dm will handle the vfb.
   16.33 +            return
   16.34 +        
   16.35          std_args = [ "--domid", "%d" % self.vm.getDomid(),
   16.36                       "--title", self.vm.getName() ]
   16.37          t = config.get("type", None)
   16.38 @@ -82,6 +88,42 @@ class VfbifController(DevController):
   16.39          else:
   16.40              raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
   16.41  
   16.42 +
   16.43 +    def waitForDevice(self, devid):
   16.44 +        if self.vm.info.get('HVM_boot'):
   16.45 +            log.debug('skip waiting for HVM vfb')
   16.46 +            # is a qemu-dm managed device, don't wait for hotplug for these.
   16.47 +            return
   16.48 +
   16.49 +        DevController.waitForDevice(self, devid)
   16.50 +
   16.51 +
   16.52 +    def reconfigureDevice(self, _, config):
   16.53 +        """ Only allow appending location information of vnc port into
   16.54 +        xenstore."""
   16.55 +
   16.56 +        if 'location' in config:
   16.57 +            (devid, back, front) = self.getDeviceDetails(config)
   16.58 +            self.writeBackend(devid, 'location', config['location'])
   16.59 +            return back.get('uuid')
   16.60 +
   16.61 +        raise VmError('Refusing to reconfigure device vfb:%d' % devid)
   16.62 +
   16.63 +    def destroyDevice(self, devid, force):
   16.64 +        if self.vm.info.get('HVM_boot'):
   16.65 +            # remove the backend xenstore entries for HVM guests no matter
   16.66 +            # what
   16.67 +            DevController.destroyDevice(self, devid, True)
   16.68 +        else:
   16.69 +            DevController.destroyDevice(self, devid, force)
   16.70 +
   16.71 +
   16.72 +    def migrate(self, deviceConfig, network, dst, step, domName):
   16.73 +        if self.vm.info.get('HVM_boot'):        
   16.74 +            return 0
   16.75 +        return DevController.migrate(self, deviceConfig, network, dst, step,
   16.76 +                                     domName)
   16.77 +    
   16.78  class VkbdifController(DevController):
   16.79      """Virtual keyboard controller. Handles all vkbd devices for a domain.
   16.80      """
   16.81 @@ -92,3 +134,24 @@ class VkbdifController(DevController):
   16.82          back = {}
   16.83          front = {}
   16.84          return (devid, back, front)
   16.85 +
   16.86 +    def waitForDevice(self, config):
   16.87 +        if self.vm.info.get('HVM_boot'):
   16.88 +            # is a qemu-dm managed device, don't wait for hotplug for these.
   16.89 +            return
   16.90 +
   16.91 +        DevController.waitForDevice(self, config)
   16.92 +
   16.93 +    def destroyDevice(self, devid, force):
   16.94 +        if self.vm.info.get('HVM_boot'):
   16.95 +            # remove the backend xenstore entries for HVM guests no matter
   16.96 +            # what
   16.97 +            DevController.destroyDevice(self, devid, True)
   16.98 +        else:
   16.99 +            DevController.destroyDevice(self, devid, force)
  16.100 +
  16.101 +    def migrate(self, deviceConfig, network, dst, step, domName):
  16.102 +        if self.vm.info.get('HVM_boot'):        
  16.103 +            return 0
  16.104 +        return DevController.migrate(self, deviceConfig, network, dst, step,
  16.105 +                                     domName)        
    17.1 --- a/tools/xcutils/readnotes.c	Wed Jan 31 17:22:00 2007 +0000
    17.2 +++ b/tools/xcutils/readnotes.c	Wed Jan 31 17:22:17 2007 +0000
    17.3 @@ -72,8 +72,8 @@ int main(int argc, char **argv)
    17.4  	usize = xc_dom_check_gzip(image, st.st_size);
    17.5  	if (usize)
    17.6  	{
    17.7 -		tmp = malloc(size);
    17.8 -		xc_dom_do_gunzip(image, st.st_size, tmp, size);
    17.9 +		tmp = malloc(usize);
   17.10 +		xc_dom_do_gunzip(image, st.st_size, tmp, usize);
   17.11  		image = tmp;
   17.12  		size = usize;
   17.13  	}
    18.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Wed Jan 31 17:22:00 2007 +0000
    18.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Wed Jan 31 17:22:17 2007 +0000
    18.3 @@ -281,9 +281,6 @@ CFIX14:
    18.4          .quad CFLT14,CFIX14
    18.5  .previous
    18.6  
    18.7 -compat_domctl:
    18.8 -compat_sysctl:
    18.9 -
   18.10  .section .rodata, "a", @progbits
   18.11  
   18.12  ENTRY(compat_hypercall_table)
   18.13 @@ -365,8 +362,8 @@ ENTRY(compat_hypercall_args_table)
   18.14          .byte 2 /* compat_event_channel_op  */
   18.15          .byte 2 /* compat_physdev_op        */
   18.16          .byte 2 /* do_hvm_op                */
   18.17 -        .byte 1 /* compat_sysctl            */  /* 35 */
   18.18 -        .byte 1 /* compat_domctl            */
   18.19 +        .byte 1 /* do_sysctl                */  /* 35 */
   18.20 +        .byte 1 /* do_domctl                */
   18.21          .byte 2 /* compat_kexec_op          */
   18.22          .rept NR_hypercalls-(.-compat_hypercall_args_table)
   18.23          .byte 0 /* compat_ni_hypercall      */
    19.1 --- a/xen/include/public/arch-x86/xen-x86_32.h	Wed Jan 31 17:22:00 2007 +0000
    19.2 +++ b/xen/include/public/arch-x86/xen-x86_32.h	Wed Jan 31 17:22:17 2007 +0000
    19.3 @@ -103,7 +103,7 @@
    19.4           (hnd).p = val;                                     \
    19.5      } while ( 0 )
    19.6  #define uint64_aligned_t uint64_t __attribute__((aligned(8)))
    19.7 -#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
    19.8 +#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name __attribute__((aligned(8)))
    19.9  #endif
   19.10  
   19.11  #ifndef __ASSEMBLY__