direct-io.hg

changeset 13752:beb0b36de156

[XENAPI] Add VDI.location support and test c prog for HVM test.

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Wed Jan 31 15:08:29 2007 +0000 (2007-01-31)
parents 85e8d7b8360a
children 3db881ef97c4
files tools/libxen/Makefile tools/libxen/include/xen_vdi.h tools/libxen/src/xen_vdi.c tools/libxen/test/test_bindings.c tools/libxen/test/test_hvm_bindings.c
line diff
     1.1 --- a/tools/libxen/Makefile	Wed Jan 31 15:06:40 2007 +0000
     1.2 +++ b/tools/libxen/Makefile	Wed Jan 31 15:08:29 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 15:06:40 2007 +0000
     2.2 +++ b/tools/libxen/include/xen_vdi.h	Wed Jan 31 15:08:29 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 15:06:40 2007 +0000
     3.2 +++ b/tools/libxen/src/xen_vdi.c	Wed Jan 31 15:08:29 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 15:06:40 2007 +0000
     4.2 +++ b/tools/libxen/test/test_bindings.c	Wed Jan 31 15:08:29 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 15:08:29 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 +}