ia64/xen-unstable
changeset 13788:beb0b36de156
[XENAPI] Add VDI.location support and test c prog for HVM test.
Signed-off-by: Alastair Tse <atse@xensource.com>
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 +}