// automatically generated. Do not modify static void testVMs(xen_session *session) { printf("\nGet all the VM Records\n"); xen_vm_set *vm_set; bool d = xen_vm_get_all(session, &vm_set); if (d) { size_t i = 0; for (; i < vm_set->size; ++i) { xen_vm_record *vm_record; xen_vm_get_record(session, &vm_record, vm_set->contents[i]); char *handle = (char*) vm_record->handle; char *opaque = (char*) vm_set->contents[i]; if (strcmp(handle, opaque) == 0) printf("identical: %s\n", opaque); else printf("record->handle[%s] v.s. set->contents[%d][%s]\n", opaque, i, handle); xen_vm_record_free(vm_record); } } else { print_error(session); } xen_vm_set_free(vm_set); #if 0 printf("== Get All VM Records ============================\n\n"); xen_vm_xen_vm_record_map *result; bool ok = xen_vm_get_all_records(session, &result); if(!ok) { print_error(session); } size_t i=0; for(;i<result->size;++i) { xen_vm key = result->contents[i].key; struct xen_vm_record *val = result->contents[i].val; if(strcmp((char*)key, (char*)val->handle)==0) { } else { printf("%s v.s. %s", (char*)key, (char*)val->handle); } xen_vm_record_free(val); xen_vm_free(key); } free(result); #endif printf("\n==============================================\n\n"); }
int main(int argc, char **argv) { if (argc != 5) { usage(); } url = argv[1]; char *sr_name = argv[2]; char *username = argv[3]; char *password = argv[4]; xmlInitParser(); xmlKeepBlanksDefault(0); xen_init(); curl_global_init(CURL_GLOBAL_ALL); #define CLEANUP \ do { \ xen_session_logout(session); \ curl_global_cleanup(); \ xen_fini(); \ xmlCleanupParser(); \ } while(0) \ xen_session *session = xen_session_login_with_password(call_func, NULL, username, password, xen_api_latest_version); /* --------------------------------------------------------------------- Read host, capabilities and API vsn --------------------------------------------------------------------- */ printf("\n\nQuerying host...\n"); xen_host host; if (!xen_session_get_this_host(session, &host, session)) { print_error(session); CLEANUP; return 1; } xen_string_string_map *versions; if (!xen_host_get_software_version(session, &versions, host)) { print_error(session); xen_host_free(host); CLEANUP; return 1; } xen_string_set *supported_bootloaders; if (!xen_host_get_supported_bootloaders(session, &supported_bootloaders, host)) { print_error(session); xen_string_string_map_free(versions); xen_host_free(host); CLEANUP; return 1; } xen_string_set *capabilities; if (!xen_host_get_capabilities(session, &capabilities, host)) { print_error(session); xen_string_set_free(supported_bootloaders); xen_string_string_map_free(versions); xen_host_free(host); CLEANUP; return 1; } for (size_t i = 0; i < versions->size; i++) { printf("%s -> %s.\n", versions->contents[i].key, versions->contents[i].val); } printf("Host supports the following bootloaders:"); for (size_t i = 0; i < supported_bootloaders->size; i++) { printf(" %s", supported_bootloaders->contents[i]); } printf("\n"); printf("Host has the following capabilities:"); for (size_t i = 0; i < capabilities->size; i++) { printf(" %s", capabilities->contents[i]); } printf("\n"); xen_host_free(host); xen_string_string_map_free(versions); xen_string_set_free(supported_bootloaders); xen_string_set_free(capabilities); /* --------------------------------------------------------------------- Create a new VM with a blank disk: --------------------------------------------------------------------- */ printf("\n\nCreating new HVM VM...\n"); xen_vm hvm_vm = create_new_vm(session, "Other install media", sr_name, false); if (!session->ok) { /* Error has been logged, just clean up. */ CLEANUP; return 1; } print_vm_power_state(session, hvm_vm); /* Blob handling used to crash when we tried to free the VM record: * CA-38872. */ xen_blob blob; xen_blob_create(session, &blob, "hello", false); xen_vm_create_new_blob(session, &blob, hvm_vm, "test", "test", false); printf("\nBlob created.\n"); xen_blob_record *blob_record; xen_blob_get_record(session, &blob_record, blob); printf("Blob record retrieved.\n"); printf("\nGetting VM record...\n"); xen_vm_record *vm_record; xen_vm_get_record(session, &vm_record, hvm_vm); printf("VM record: %s blob: %s\n", (char *)vm_record->handle, (char *)blob_record->handle); printf("Freeing VM record...\n"); xen_vm_record_free(vm_record); printf("VM record freed.\n"); printf("Freeing blob record...\n"); xen_blob_record_free(blob_record); printf("Blob record freed.\n"); if (!session->ok) { /* Error has been logged, just clean up. */ xen_vm_free(hvm_vm); CLEANUP; return 1; } /* Test Enum parsing by setting actions after shutdown */ xen_vm_set_actions_after_shutdown(session, hvm_vm, XEN_ON_NORMAL_EXIT_RESTART); /* Test getting a map and having a play */ xen_string_string_map *hvm_boot_params; if (!xen_vm_get_hvm_boot_params(session, &hvm_boot_params, hvm_vm)) { print_error(session); CLEANUP; return 1; } printf("HVM_boot_params contains:\n"); for (size_t i = 0; i < hvm_boot_params->size; i++) { printf("%s -> %s.\n", hvm_boot_params->contents[i].key, hvm_boot_params->contents[i].val); } xen_string_string_map_free(hvm_boot_params); cycle_vm(session, hvm_vm); xen_vm_free(hvm_vm); /* TODO uncomment this when we test against real hosts, as SDK doesn't have debian template printf("\n\nCreating new PV VM...\n"); xen_vm pv_vm = create_new_vm(session, "Debian Etch 4.0", sr_name, true); if (!session->ok) { CLEANUP; return 1; } if (!xen_vm_get_hvm_boot_params(session, &hvm_boot_params, pv_vm)) { print_error(session); CLEANUP; return 1; } for (size_t i = 0; i < hvm_boot_params->size; i++) { printf("%s -> %s.\n", hvm_boot_params->contents[i].key, hvm_boot_params->contents[i].val); } cycle_vm(session, pv_vm); xen_vm_free(pv_vm); */ CLEANUP; }
/****************************************************************************** * Function to enumerate a xen resource * * @param session - handle to a xen_utils_session object * @param resources - pointer to the provider_resource_list * @return CMPIrc error codes *****************************************************************************/ static CMPIrc xen_resource_list_enum( xen_utils_session *session, provider_resource_list *resources ) { enum domain_choice choice = vms_only; xen_domain_resources *domain_set = NULL; if(!xen_utils_get_domain_resources(session, &domain_set, choice)) return CMPI_RC_ERR_FAILED; xen_vm resource_handle; xen_vm_record *resource_rec = NULL; kvp_set *complete_set; initialise_kvp_set(&complete_set); for(domain_set->currentdomain=0; domain_set->currentdomain < domain_set->numdomains; domain_set->currentdomain++){ _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Current Domain: %d", domain_set->currentdomain)); resource_handle = domain_set->domains->contents[domain_set->currentdomain]; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Current resource handle = %s", resource_handle)); if(!xen_vm_get_record(session->xen, &resource_rec, resource_handle)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- xen_vm_get_record failed: \"%s\" \"%s\"", session->xen->error_description[0], resource_handle)); char *error = xen_utils_get_xen_error(session->xen); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("%s", error)); RESET_XEN_ERROR(session->xen); if (error) free(error); continue; } char *res = xen_utils_get_from_string_string_map(resource_rec->other_config, "kvp_enabled"); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("result = %s", res)); if(res) { /* Result is not NULL - therefore the VM is counted as being 'enabled' for KVP */ xen_host_record_opt *host = resource_rec->resident_on; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("VM is resident on host '%s'",host->u.handle)); if (host->u.handle){ char *address = NULL; if(!xen_host_get_address(session->xen, &address, host->u.handle)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Host address not found")); } else { /* Make remote call for store */ char *plugin = "services/plugin/xscim"; char *xenref = (char *)((session->xen)->session_id); /* Add overhead of 15 characters */ int len = sizeof(char) * (25 + strlen(plugin) + strlen(address) + strlen(resource_rec->uuid) + strlen(xenref)); char *url = (char *)malloc(len); sprintf(url, "http://%s/%s/vm/%s?session_id=%s", address, plugin, resource_rec->uuid, xenref); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Fetch store from URL '%s'", url)); kvp_set *set; Xen_KVP_RC rc = xen_utils_get_kvp_store(url, (char *)resource_rec->uuid,&set); if (rc != Xen_KVP_RC_OK) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Unable to retrieve KVP store for VM %s", resource_rec->uuid)); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Continuing on to the next domain")); } else { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("sets so far %d", set->size)); /* Append the contents of the returned set */ xen_utils_append_kvp_set(complete_set, set); if (set) xen_utils_free_kvpset(set); if(url) free(url); /* Free the host address */ if (address) free(address); } } } else { /* VM is not started, and so may not be resident on any host. */ } } xen_vm_record_free(resource_rec); } xen_utils_free_domain_resources(domain_set); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("all in %d keys", complete_set->size)); /* Return the set of KVPs */ resources->ctx = complete_set; return CMPI_RC_OK; }
int main(int argc, char **argv) { if (argc != 6) { usage(); } url = argv[1]; char *username = argv[2]; char *password = argv[3]; source_url = argv[4]; target_url = argv[5]; xmlInitParser(); xmlKeepBlanksDefault(0); xen_init(); curl_global_init(CURL_GLOBAL_ALL); #define CLEANUP \ do { \ xen_session_logout(session); \ curl_global_cleanup(); \ xen_fini(); \ xmlCleanupParser(); \ } while(0) \ xen_session *session = xen_session_login_with_password(call_func, NULL, username, password, xen_api_latest_version); printf("\n\nQuerying host...\n"); xen_host host; if (!xen_session_get_this_host(session, &host, session)) { print_error(session); CLEANUP; return 1; } /* Read in the source host and target host using their name labels */ xen_host_set *source_hosts; int rc = 0; rc = get_host_names(session, &source_hosts, source_url ); if (rc !=0 ) { fprintf(stderr, "source host lookup failed.\n"); print_error(session); return 1; } xen_host_set *target_hosts; rc = 0; rc = get_host_names(session, &target_hosts, target_url ); if (rc !=0 ) { fprintf(stderr, "target host lookup failed.\n"); print_error(session); return 1; } struct xen_vm_set *all_vms_in_pool; xen_vm_get_all(session, &all_vms_in_pool); bool *vm_to_be_migrated = calloc(all_vms_in_pool->size, sizeof(bool)); int num_vms_to_migrate = 0; enum xen_task_status_type task_status; xen_vm_record* result; for (size_t i = 0; i < all_vms_in_pool->size; i++ ) { xen_vm a_vm = all_vms_in_pool->contents[i]; xen_vm_get_record(session, &result, a_vm); /* * we can only migrate VMs that are * -not templates * -not control domains * -and are running * * resident_on is used to identify the eligible VMs on the user * requested source_host */ if ( !result->is_a_template && !result->is_control_domain && (result->power_state == XEN_VM_POWER_STATE_RUNNING) && (strcmp(result->resident_on->u.handle, (char*)source_hosts->contents[0]) == 0) ) { // flag this VM as one suitable to migrate vm_to_be_migrated[i] = true; num_vms_to_migrate++; } else { vm_to_be_migrated[i] = false; } } if (!session->ok) { /* Error has been logged, just clean up. */ xen_host_set_free(source_hosts); xen_host_set_free(target_hosts); xen_vm_set_free(all_vms_in_pool); xen_vm_record_free(result); free(vm_to_be_migrated); CLEANUP; return 1; } xen_task* task_list = calloc(num_vms_to_migrate, sizeof(xen_task)); xen_string_string_map* options = xen_string_string_map_alloc(0); xen_string_set *error_msgs = NULL; int idx = 0; for (size_t i = 0; i < all_vms_in_pool->size; i++ ) { if (vm_to_be_migrated[i] == true) { xen_vm_pool_migrate_async(session, &task_list[idx], all_vms_in_pool->contents[i], target_hosts->contents[0], options ); idx++; printf(" Migrating VM %zd \n", i); } } // time out after certain number of iterations int max_iter = 50; int iter = 0; int pause_interval_secs = 4; int tasks_running = 0; int tasks_completed = 0; xen_task a_task; bool tasks_still_pending = true; /* Poll how many of the migration tasks have completed. * * The task querying below isn't is intended to provide a sample of useful * syntax. In practice a user would probably consider using functions such * as xen_task_cancel or indeed the asynchronous equivalent * xen_task_cancel_async. * These functions and other task handling ones are defined in xen_task.c */ while ( iter < max_iter && tasks_still_pending ) { tasks_running = 0; tasks_completed = 0; for (int j = 0; j < num_vms_to_migrate; j++) { a_task = task_list[j]; xen_task_get_status(session, &task_status, a_task); if (task_status == XEN_TASK_STATUS_TYPE_PENDING) { tasks_running++; } else { /* See the xen_task_status_type enum definitions * defined in xen_task_status_type.h a task can have * failed, or be cancelled or in the process of being cancelled * amongst others. * The definition of tasks_completed in this context is tasks * not pending. */ if (task_status == XEN_TASK_STATUS_TYPE_FAILURE) { if (xen_task_get_error_info(session, &error_msgs, task_list[j] )) { /* VMs may need to meet certain criteria for migration to be * possible between hosts; such as shared storage between * hosts. It is advisable to check the criteria needed for * migration on the particular version of XenServer. * The error messages output below should give information * that allows the identification of an unsupported * operation */ printf("-------------------------------------\n"); printf("Failed while trying to migrate VM: \n"); for(size_t k=0; k<error_msgs->size; k++) { printf("error_msg %zu : %s \n", k, error_msgs->contents[k]); } } } tasks_completed++; } } if (tasks_running == 0) { tasks_still_pending = false; // stop the iteration early printf("All tasks completed \n"); } printf("*********************************************\n"); printf("VM migration progress, poll number %d \n", iter); printf("----------------------------------------\n"); printf(" Tasks pending : %d \n", tasks_running); printf(" ended : %d \n", tasks_completed); printf("*********************************************\n"); iter++; sleep(pause_interval_secs); } xen_string_set_free(error_msgs); xen_string_string_map_free(options); xen_host_set_free(source_hosts); xen_host_set_free(target_hosts); free(task_list); free(vm_to_be_migrated); xen_vm_set_free(all_vms_in_pool); CLEANUP; }