ia64/xen-unstable

view tools/libxen/test/test_bindings.c @ 14052:2840b5e7f585

Added C bindings for host.supported_bootloaders.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Wed Feb 21 00:04:59 2007 +0000 (2007-02-21)
parents 8773b1a38c83
children 36702d9b2c5c
line source
1 /*
2 * Copyright (c) 2006-2007 XenSource, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
19 #define _GNU_SOURCE
20 #include <inttypes.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
25 #include <libxml/parser.h>
26 #include <curl/curl.h>
28 #include "xen_host.h"
29 #include "xen_sr.h"
30 #include "xen_vbd.h"
31 #include "xen_vdi.h"
32 #include "xen_console.h"
33 #include "xen_vm.h"
34 #include "xen_vm_metrics.h"
37 static void usage()
38 {
39 fprintf(stderr,
40 "Usage:\n"
41 "\n"
42 " test_bindings <url> <username> <password>\n"
43 "\n"
44 "where\n"
45 " <url> is a fragment of the server's URL, e.g. localhost:8005/RPC2;\n"
46 " <username> is the username to use at the server; and\n"
47 " <password> is the password.\n");
49 exit(EXIT_FAILURE);
50 }
53 static char *url;
56 typedef struct
57 {
58 xen_result_func func;
59 void *handle;
60 } xen_comms;
63 static xen_vm create_new_vm(xen_session *session, bool hvm);
64 static void print_vm_power_state(xen_session *session, xen_vm vm);
65 static void print_vm_metrics(xen_session *session, xen_vm vm);
68 static size_t
69 write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
70 {
71 size_t n = size * nmemb;
72 return comms->func(ptr, n, comms->handle) ? n : 0;
73 }
76 static int
77 call_func(const void *data, size_t len, void *user_handle,
78 void *result_handle, xen_result_func result_func)
79 {
80 (void)user_handle;
82 CURL *curl = curl_easy_init();
83 if (!curl) {
84 return -1;
85 }
87 xen_comms comms = {
88 .func = result_func,
89 .handle = result_handle
90 };
92 curl_easy_setopt(curl, CURLOPT_URL, url);
93 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
94 curl_easy_setopt(curl, CURLOPT_MUTE, 1);
95 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
96 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
97 curl_easy_setopt(curl, CURLOPT_POST, 1);
98 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
99 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
101 CURLcode result = curl_easy_perform(curl);
103 curl_easy_cleanup(curl);
105 return result;
106 }
109 static void print_error(xen_session *session)
110 {
111 fprintf(stderr, "Error: %d", session->error_description_count);
112 for (int i = 0; i < session->error_description_count; i++)
113 {
114 fprintf(stderr, "%s ", session->error_description[i]);
115 }
116 fprintf(stderr, "\n");
117 }
120 int main(int argc, char **argv)
121 {
122 if (argc != 4)
123 {
124 usage();
125 }
127 url = argv[1];
128 char *username = argv[2];
129 char *password = argv[3];
131 xmlInitParser();
132 xen_init();
133 curl_global_init(CURL_GLOBAL_ALL);
135 #define CLEANUP \
136 do { \
137 xen_session_logout(session); \
138 curl_global_cleanup(); \
139 xen_fini(); \
140 xmlCleanupParser(); \
141 } while(0) \
144 xen_session *session =
145 xen_session_login_with_password(call_func, NULL, username, password);
147 xen_vm vm;
148 if (!xen_vm_get_by_uuid(session, &vm,
149 "00000000-0000-0000-0000-000000000000"))
150 {
151 print_error(session);
152 CLEANUP;
153 return 1;
154 }
156 char *vm_uuid;
157 if (!xen_vm_get_uuid(session, &vm_uuid, vm))
158 {
159 print_error(session);
160 xen_vm_free(vm);
161 CLEANUP;
162 return 1;
163 }
165 char *vm_uuid_bytes;
166 if (!xen_uuid_string_to_bytes(vm_uuid, &vm_uuid_bytes))
167 {
168 fprintf(stderr, "xen_uuid_string_to_bytes failed.\n");
169 xen_uuid_free(vm_uuid);
170 xen_vm_free(vm);
171 CLEANUP;
172 return 1;
173 }
175 xen_vm_record *vm_record;
176 if (!xen_vm_get_record(session, &vm_record, vm))
177 {
178 print_error(session);
179 xen_uuid_bytes_free(vm_uuid_bytes);
180 xen_uuid_free(vm_uuid);
181 xen_vm_free(vm);
182 CLEANUP;
183 return 1;
184 }
186 xen_host host;
187 if (!xen_session_get_this_host(session, &host))
188 {
189 print_error(session);
190 xen_vm_record_free(vm_record);
191 xen_uuid_bytes_free(vm_uuid_bytes);
192 xen_uuid_free(vm_uuid);
193 xen_vm_free(vm);
194 CLEANUP;
195 return 1;
196 }
198 xen_string_string_map *versions;
199 if (!xen_host_get_software_version(session, &versions, host))
200 {
201 print_error(session);
202 xen_host_free(host);
203 xen_vm_record_free(vm_record);
204 xen_uuid_bytes_free(vm_uuid_bytes);
205 xen_uuid_free(vm_uuid);
206 xen_vm_free(vm);
207 CLEANUP;
208 return 1;
209 }
211 char *dmesg;
212 if (!xen_host_dmesg(session, &dmesg, host))
213 {
214 print_error(session);
215 xen_string_string_map_free(versions);
216 xen_host_free(host);
217 xen_vm_record_free(vm_record);
218 xen_uuid_bytes_free(vm_uuid_bytes);
219 xen_uuid_free(vm_uuid);
220 xen_vm_free(vm);
221 CLEANUP;
222 return 1;
223 }
225 xen_string_set *supported_bootloaders;
226 if (!xen_host_get_supported_bootloaders(session, &supported_bootloaders,
227 host))
228 {
229 print_error(session);
230 free(dmesg);
231 xen_string_string_map_free(versions);
232 xen_host_free(host);
233 xen_vm_record_free(vm_record);
234 xen_uuid_bytes_free(vm_uuid_bytes);
235 xen_uuid_free(vm_uuid);
236 xen_vm_free(vm);
237 CLEANUP;
238 return 1;
239 }
241 printf("%s.\n", vm_uuid);
243 fprintf(stderr, "In bytes, the VM UUID is ");
244 for (int i = 0; i < 15; i++)
245 {
246 fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
247 }
248 fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
250 printf("%zd.\n", versions->size);
252 for (size_t i = 0; i < versions->size; i++)
253 {
254 printf("%s -> %s.\n", versions->contents[i].key,
255 versions->contents[i].val);
256 }
258 printf("Host dmesg follows:\n%s\n\n", dmesg);
260 printf("Host supports the following bootloaders:");
261 for (size_t i = 0; i < supported_bootloaders->size; i++)
262 {
263 printf(" %s", supported_bootloaders->contents[i]);
264 }
265 printf("\n");
267 printf("%s.\n", vm_record->uuid);
269 printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
271 printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
273 xen_uuid_bytes_free(vm_uuid_bytes);
274 xen_uuid_free(vm_uuid);
276 xen_vm_record_free(vm_record);
278 xen_host_free(host);
279 xen_string_string_map_free(versions);
280 free(dmesg);
281 xen_string_set_free(supported_bootloaders);
283 print_vm_metrics(session, vm);
284 if (!session->ok)
285 {
286 /* Error has been logged, just clean up. */
287 xen_vm_free(vm);
288 CLEANUP;
289 return 1;
290 }
292 xen_vm_free(vm);
294 xen_vm new_vm = create_new_vm(session, true);
295 if (!session->ok)
296 {
297 /* Error has been logged, just clean up. */
298 CLEANUP;
299 return 1;
300 }
302 print_vm_power_state(session, new_vm);
303 if (!session->ok)
304 {
305 /* Error has been logged, just clean up. */
306 xen_vm_free(new_vm);
307 CLEANUP;
308 return 1;
309 }
311 xen_vm_free(new_vm);
312 CLEANUP;
314 return 0;
315 }
318 /**
319 * Creation of a new VM, using the Named Parameters idiom. Allocate the
320 * xen_vm_record here, but the sets through the library. Either
321 * allocation patterns can be used, as long as the allocation and free are
322 * paired correctly.
323 */
324 static xen_vm create_new_vm(xen_session *session, bool hvm)
325 {
326 xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
327 vcpus_params->contents[0].key = strdup("weight");
328 vcpus_params->contents[0].val = strdup("300");
330 xen_string_string_map *hvm_boot_params;
331 if (hvm)
332 {
333 hvm_boot_params = xen_string_string_map_alloc(1);
334 hvm_boot_params->contents[0].key = strdup("order");
335 hvm_boot_params->contents[0].val = strdup("cd");
336 }
337 else
338 {
339 hvm_boot_params = NULL;
340 }
342 xen_vm_record vm_record =
343 {
344 .name_label = hvm ? "NewHVM" : "NewPV",
345 .name_description = hvm ? "New HVM VM" : "New PV VM",
346 .user_version = 1,
347 .is_a_template = false,
348 .memory_static_max = 256,
349 .memory_dynamic_max = 256,
350 .memory_dynamic_min = 128,
351 .memory_static_min = 128,
352 .vcpus_policy = "credit",
353 .vcpus_params = vcpus_params,
354 .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
355 .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
356 .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
357 .hvm_boot_policy = hvm ? "BIOS order" : NULL,
358 .hvm_boot_params = hvm ? hvm_boot_params : NULL,
359 .pv_bootloader = hvm ? NULL : "pygrub",
360 .pv_kernel = hvm ? NULL : "/boot/vmlinuz-2.6.16.33-xen",
361 };
363 xen_vm vm;
364 xen_vm_create(session, &vm, &vm_record);
366 xen_string_string_map_free(vcpus_params);
367 xen_string_string_map_free(hvm_boot_params);
369 if (!session->ok)
370 {
371 fprintf(stderr, "VM creation failed.\n");
372 print_error(session);
373 return NULL;
374 }
377 /*
378 * Create a new disk for the new VM.
379 */
380 xen_sr_set *srs;
381 if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
382 srs->size < 1)
383 {
384 fprintf(stderr, "SR lookup failed.\n");
385 print_error(session);
386 xen_vm_free(vm);
387 return NULL;
388 }
390 xen_sr_record_opt sr_record =
391 {
392 .u.handle = srs->contents[0]
393 };
394 xen_vdi_record vdi0_record =
395 {
396 .name_label = "MyRootFS",
397 .name_description = "MyRootFS description",
398 .sr = &sr_record,
399 .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector
400 .sector_size = 512,
401 .type = XEN_VDI_TYPE_SYSTEM,
402 .sharable = false,
403 .read_only = false
404 };
406 xen_vdi vdi0;
407 if (!xen_vdi_create(session, &vdi0, &vdi0_record))
408 {
409 fprintf(stderr, "VDI creation failed.\n");
410 print_error(session);
412 xen_sr_set_free(srs);
413 xen_vm_free(vm);
414 return NULL;
415 }
418 xen_vm_record_opt vm_record_opt =
419 {
420 .u.handle = vm
421 };
422 xen_vdi_record_opt vdi0_record_opt =
423 {
424 .u.handle = vdi0
425 };
426 xen_vbd_record vbd0_record =
427 {
428 .vm = &vm_record_opt,
429 .vdi = &vdi0_record_opt,
430 .device = "xvda1",
431 .mode = XEN_VBD_MODE_RW,
432 .bootable = 1,
433 };
435 xen_vbd vbd0;
436 if (!xen_vbd_create(session, &vbd0, &vbd0_record))
437 {
438 fprintf(stderr, "VBD creation failed.\n");
439 print_error(session);
441 xen_vdi_free(vdi0);
442 xen_sr_set_free(srs);
443 xen_vm_free(vm);
444 return NULL;
445 }
447 xen_console vnc_console = NULL;
448 if (hvm) {
449 xen_console_record vnc_console_record =
450 {
451 .protocol = XEN_CONSOLE_PROTOCOL_RFB,
452 .vm = &vm_record_opt,
453 };
455 if (!xen_console_create(session, &vnc_console, &vnc_console_record))
456 {
457 fprintf(stderr, "VNC console creation failed.\n");
458 print_error(session);
460 xen_vbd_free(vbd0);
461 xen_vdi_free(vdi0);
462 xen_sr_set_free(srs);
463 xen_vm_free(vm);
464 return NULL;
465 }
466 }
468 char *vm_uuid;
469 char *vdi0_uuid;
470 char *vbd0_uuid;
471 char *vnc_uuid = NULL;
473 xen_vm_get_uuid(session, &vm_uuid, vm);
474 xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
475 xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
476 if (hvm) {
477 xen_console_get_uuid(session, &vnc_uuid, vnc_console);
478 }
480 if (!session->ok)
481 {
482 fprintf(stderr, "get_uuid call failed.\n");
483 print_error(session);
485 xen_uuid_free(vm_uuid);
486 xen_uuid_free(vdi0_uuid);
487 xen_uuid_free(vbd0_uuid);
488 xen_uuid_free(vnc_uuid);
489 xen_vbd_free(vbd0);
490 xen_vdi_free(vdi0);
491 xen_console_free(vnc_console);
492 xen_sr_set_free(srs);
493 xen_vm_free(vm);
494 return NULL;
495 }
497 if (hvm) {
498 fprintf(stderr,
499 "Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
500 "UUID %s, and VNC console UUID %s.\n",
501 vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
502 }
503 else {
504 fprintf(stderr,
505 "Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
506 "UUID %s.\n",
507 vm_uuid, vdi0_uuid, vbd0_uuid);
508 }
510 xen_uuid_free(vm_uuid);
511 xen_uuid_free(vdi0_uuid);
512 xen_uuid_free(vbd0_uuid);
513 xen_uuid_free(vnc_uuid);
514 xen_vbd_free(vbd0);
515 xen_vdi_free(vdi0);
516 xen_console_free(vnc_console);
517 xen_sr_set_free(srs);
519 return vm;
520 }
523 /**
524 * Print the power state for the given VM.
525 */
526 static void print_vm_power_state(xen_session *session, xen_vm vm)
527 {
528 char *vm_uuid;
529 enum xen_vm_power_state power_state;
531 if (!xen_vm_get_uuid(session, &vm_uuid, vm))
532 {
533 print_error(session);
534 return;
535 }
537 if (!xen_vm_get_power_state(session, &power_state, vm))
538 {
539 xen_uuid_free(vm_uuid);
540 print_error(session);
541 return;
542 }
544 printf("VM %s power state is %s.\n", vm_uuid,
545 xen_vm_power_state_to_string(power_state));
547 xen_uuid_free(vm_uuid);
548 }
551 /**
552 * Print the metrics for the given VM.
553 */
554 static void print_vm_metrics(xen_session *session, xen_vm vm)
555 {
556 xen_vm_metrics vm_metrics;
557 if (!xen_vm_get_metrics(session, &vm_metrics, vm))
558 {
559 print_error(session);
560 return;
561 }
563 xen_vm_metrics_record *vm_metrics_record;
564 if (!xen_vm_metrics_get_record(session, &vm_metrics_record, vm_metrics))
565 {
566 xen_vm_metrics_free(vm_metrics);
567 print_error(session);
568 return;
569 }
571 for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
572 {
573 printf("%"PRId64" -> %lf.\n",
574 vm_metrics_record->vcpus_utilisation->contents[i].key,
575 vm_metrics_record->vcpus_utilisation->contents[i].val);
576 }
578 xen_vm_metrics_record_free(vm_metrics_record);
579 xen_vm_metrics_free(vm_metrics);
580 }