direct-io.hg

view tools/libxen/test/test_bindings.c @ 14114:36702d9b2c5c

Added host.capabilities field.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Sun Feb 25 23:37:05 2007 +0000 (2007-02-25)
parents 2840b5e7f585
children 7e66858aa811
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 xen_string_set *capabilities;
242 if (!xen_host_get_capabilities(session, &capabilities, host))
243 {
244 print_error(session);
245 free(dmesg);
246 xen_string_set_free(supported_bootloaders);
247 xen_string_string_map_free(versions);
248 xen_host_free(host);
249 xen_vm_record_free(vm_record);
250 xen_uuid_bytes_free(vm_uuid_bytes);
251 xen_uuid_free(vm_uuid);
252 xen_vm_free(vm);
253 CLEANUP;
254 return 1;
255 }
257 printf("%s.\n", vm_uuid);
259 fprintf(stderr, "In bytes, the VM UUID is ");
260 for (int i = 0; i < 15; i++)
261 {
262 fprintf(stderr, "%x, ", (unsigned int)vm_uuid_bytes[i]);
263 }
264 fprintf(stderr, "%x.\n", (unsigned int)vm_uuid_bytes[15]);
266 printf("%zd.\n", versions->size);
268 for (size_t i = 0; i < versions->size; i++)
269 {
270 printf("%s -> %s.\n", versions->contents[i].key,
271 versions->contents[i].val);
272 }
274 printf("Host dmesg follows:\n%s\n\n", dmesg);
276 printf("Host supports the following bootloaders:");
277 for (size_t i = 0; i < supported_bootloaders->size; i++)
278 {
279 printf(" %s", supported_bootloaders->contents[i]);
280 }
281 printf("\n");
283 printf("Host has the following capabilities:");
284 for (size_t i = 0; i < capabilities->size; i++)
285 {
286 printf(" %s", capabilities->contents[i]);
287 }
288 printf("\n");
290 printf("%s.\n", vm_record->uuid);
292 printf("Resident on %s.\n", (char *)vm_record->resident_on->u.handle);
294 printf("%s.\n", xen_vm_power_state_to_string(vm_record->power_state));
296 xen_uuid_bytes_free(vm_uuid_bytes);
297 xen_uuid_free(vm_uuid);
299 xen_vm_record_free(vm_record);
301 xen_host_free(host);
302 xen_string_string_map_free(versions);
303 free(dmesg);
304 xen_string_set_free(supported_bootloaders);
305 xen_string_set_free(capabilities);
307 print_vm_metrics(session, vm);
308 if (!session->ok)
309 {
310 /* Error has been logged, just clean up. */
311 xen_vm_free(vm);
312 CLEANUP;
313 return 1;
314 }
316 xen_vm_free(vm);
318 xen_vm new_vm = create_new_vm(session, true);
319 if (!session->ok)
320 {
321 /* Error has been logged, just clean up. */
322 CLEANUP;
323 return 1;
324 }
326 print_vm_power_state(session, new_vm);
327 if (!session->ok)
328 {
329 /* Error has been logged, just clean up. */
330 xen_vm_free(new_vm);
331 CLEANUP;
332 return 1;
333 }
335 xen_vm_free(new_vm);
336 CLEANUP;
338 return 0;
339 }
342 /**
343 * Creation of a new VM, using the Named Parameters idiom. Allocate the
344 * xen_vm_record here, but the sets through the library. Either
345 * allocation patterns can be used, as long as the allocation and free are
346 * paired correctly.
347 */
348 static xen_vm create_new_vm(xen_session *session, bool hvm)
349 {
350 xen_string_string_map *vcpus_params = xen_string_string_map_alloc(1);
351 vcpus_params->contents[0].key = strdup("weight");
352 vcpus_params->contents[0].val = strdup("300");
354 xen_string_string_map *hvm_boot_params;
355 if (hvm)
356 {
357 hvm_boot_params = xen_string_string_map_alloc(1);
358 hvm_boot_params->contents[0].key = strdup("order");
359 hvm_boot_params->contents[0].val = strdup("cd");
360 }
361 else
362 {
363 hvm_boot_params = NULL;
364 }
366 xen_vm_record vm_record =
367 {
368 .name_label = hvm ? "NewHVM" : "NewPV",
369 .name_description = hvm ? "New HVM VM" : "New PV VM",
370 .user_version = 1,
371 .is_a_template = false,
372 .memory_static_max = 256,
373 .memory_dynamic_max = 256,
374 .memory_dynamic_min = 128,
375 .memory_static_min = 128,
376 .vcpus_policy = "credit",
377 .vcpus_params = vcpus_params,
378 .actions_after_shutdown = XEN_ON_NORMAL_EXIT_DESTROY,
379 .actions_after_reboot = XEN_ON_NORMAL_EXIT_RESTART,
380 .actions_after_crash = XEN_ON_CRASH_BEHAVIOUR_PRESERVE,
381 .hvm_boot_policy = hvm ? "BIOS order" : NULL,
382 .hvm_boot_params = hvm ? hvm_boot_params : NULL,
383 .pv_bootloader = hvm ? NULL : "pygrub",
384 .pv_kernel = hvm ? NULL : "/boot/vmlinuz-2.6.16.33-xen",
385 };
387 xen_vm vm;
388 xen_vm_create(session, &vm, &vm_record);
390 xen_string_string_map_free(vcpus_params);
391 xen_string_string_map_free(hvm_boot_params);
393 if (!session->ok)
394 {
395 fprintf(stderr, "VM creation failed.\n");
396 print_error(session);
397 return NULL;
398 }
401 /*
402 * Create a new disk for the new VM.
403 */
404 xen_sr_set *srs;
405 if (!xen_sr_get_by_name_label(session, &srs, "Local") ||
406 srs->size < 1)
407 {
408 fprintf(stderr, "SR lookup failed.\n");
409 print_error(session);
410 xen_vm_free(vm);
411 return NULL;
412 }
414 xen_sr_record_opt sr_record =
415 {
416 .u.handle = srs->contents[0]
417 };
418 xen_vdi_record vdi0_record =
419 {
420 .name_label = "MyRootFS",
421 .name_description = "MyRootFS description",
422 .sr = &sr_record,
423 .virtual_size = (1 << 21), // 1GiB / 512 bytes/sector
424 .sector_size = 512,
425 .type = XEN_VDI_TYPE_SYSTEM,
426 .sharable = false,
427 .read_only = false
428 };
430 xen_vdi vdi0;
431 if (!xen_vdi_create(session, &vdi0, &vdi0_record))
432 {
433 fprintf(stderr, "VDI creation failed.\n");
434 print_error(session);
436 xen_sr_set_free(srs);
437 xen_vm_free(vm);
438 return NULL;
439 }
442 xen_vm_record_opt vm_record_opt =
443 {
444 .u.handle = vm
445 };
446 xen_vdi_record_opt vdi0_record_opt =
447 {
448 .u.handle = vdi0
449 };
450 xen_vbd_record vbd0_record =
451 {
452 .vm = &vm_record_opt,
453 .vdi = &vdi0_record_opt,
454 .device = "xvda1",
455 .mode = XEN_VBD_MODE_RW,
456 .bootable = 1,
457 };
459 xen_vbd vbd0;
460 if (!xen_vbd_create(session, &vbd0, &vbd0_record))
461 {
462 fprintf(stderr, "VBD creation failed.\n");
463 print_error(session);
465 xen_vdi_free(vdi0);
466 xen_sr_set_free(srs);
467 xen_vm_free(vm);
468 return NULL;
469 }
471 xen_console vnc_console = NULL;
472 if (hvm) {
473 xen_console_record vnc_console_record =
474 {
475 .protocol = XEN_CONSOLE_PROTOCOL_RFB,
476 .vm = &vm_record_opt,
477 };
479 if (!xen_console_create(session, &vnc_console, &vnc_console_record))
480 {
481 fprintf(stderr, "VNC console creation failed.\n");
482 print_error(session);
484 xen_vbd_free(vbd0);
485 xen_vdi_free(vdi0);
486 xen_sr_set_free(srs);
487 xen_vm_free(vm);
488 return NULL;
489 }
490 }
492 char *vm_uuid;
493 char *vdi0_uuid;
494 char *vbd0_uuid;
495 char *vnc_uuid = NULL;
497 xen_vm_get_uuid(session, &vm_uuid, vm);
498 xen_vdi_get_uuid(session, &vdi0_uuid, vdi0);
499 xen_vbd_get_uuid(session, &vbd0_uuid, vbd0);
500 if (hvm) {
501 xen_console_get_uuid(session, &vnc_uuid, vnc_console);
502 }
504 if (!session->ok)
505 {
506 fprintf(stderr, "get_uuid call failed.\n");
507 print_error(session);
509 xen_uuid_free(vm_uuid);
510 xen_uuid_free(vdi0_uuid);
511 xen_uuid_free(vbd0_uuid);
512 xen_uuid_free(vnc_uuid);
513 xen_vbd_free(vbd0);
514 xen_vdi_free(vdi0);
515 xen_console_free(vnc_console);
516 xen_sr_set_free(srs);
517 xen_vm_free(vm);
518 return NULL;
519 }
521 if (hvm) {
522 fprintf(stderr,
523 "Created a new HVM VM, with UUID %s, VDI UUID %s, VBD "
524 "UUID %s, and VNC console UUID %s.\n",
525 vm_uuid, vdi0_uuid, vbd0_uuid, vnc_uuid);
526 }
527 else {
528 fprintf(stderr,
529 "Created a new PV VM, with UUID %s, VDI UUID %s, and VBD "
530 "UUID %s.\n",
531 vm_uuid, vdi0_uuid, vbd0_uuid);
532 }
534 xen_uuid_free(vm_uuid);
535 xen_uuid_free(vdi0_uuid);
536 xen_uuid_free(vbd0_uuid);
537 xen_uuid_free(vnc_uuid);
538 xen_vbd_free(vbd0);
539 xen_vdi_free(vdi0);
540 xen_console_free(vnc_console);
541 xen_sr_set_free(srs);
543 return vm;
544 }
547 /**
548 * Print the power state for the given VM.
549 */
550 static void print_vm_power_state(xen_session *session, xen_vm vm)
551 {
552 char *vm_uuid;
553 enum xen_vm_power_state power_state;
555 if (!xen_vm_get_uuid(session, &vm_uuid, vm))
556 {
557 print_error(session);
558 return;
559 }
561 if (!xen_vm_get_power_state(session, &power_state, vm))
562 {
563 xen_uuid_free(vm_uuid);
564 print_error(session);
565 return;
566 }
568 printf("VM %s power state is %s.\n", vm_uuid,
569 xen_vm_power_state_to_string(power_state));
571 xen_uuid_free(vm_uuid);
572 }
575 /**
576 * Print the metrics for the given VM.
577 */
578 static void print_vm_metrics(xen_session *session, xen_vm vm)
579 {
580 xen_vm_metrics vm_metrics;
581 if (!xen_vm_get_metrics(session, &vm_metrics, vm))
582 {
583 print_error(session);
584 return;
585 }
587 xen_vm_metrics_record *vm_metrics_record;
588 if (!xen_vm_metrics_get_record(session, &vm_metrics_record, vm_metrics))
589 {
590 xen_vm_metrics_free(vm_metrics);
591 print_error(session);
592 return;
593 }
595 for (size_t i = 0; i < vm_metrics_record->vcpus_utilisation->size; i++)
596 {
597 printf("%"PRId64" -> %lf.\n",
598 vm_metrics_record->vcpus_utilisation->contents[i].key,
599 vm_metrics_record->vcpus_utilisation->contents[i].val);
600 }
602 xen_vm_metrics_record_free(vm_metrics_record);
603 xen_vm_metrics_free(vm_metrics);
604 }