static inline int wait_domain(const char *vm_name, virConnectPtr vp, int timeout) { int tries = 0; int response = 1; int ret; virDomainPtr vdp; virDomainInfo vdi; int uuid_check; uuid_check = is_uuid(vm_name); if (uuid_check) { vdp = virDomainLookupByUUIDString(vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(vp, vm_name); } if (!vdp) return 0; /* Check domain liveliness. If the domain is still here, we return failure, and the client must then retry */ /* XXX On the xen 3.0.4 API, we will be able to guarantee synchronous virDomainDestroy, so this check will not be necessary */ do { if (++tries > timeout) break; sleep(1); if (uuid_check) { vdp = virDomainLookupByUUIDString(vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(vp, vm_name); } if (!vdp) { dbg_printf(2, "Domain no longer exists\n"); response = 0; break; } memset(&vdi, 0, sizeof(vdi)); ret = virDomainGetInfo(vdp, &vdi); virDomainFree(vdp); if (ret < 0) continue; if (vdi.state == VIR_DOMAIN_SHUTOFF) { dbg_printf(2, "Domain has been shut off\n"); response = 0; break; } dbg_printf(4, "Domain still exists (state %d) after %d seconds\n", vdi.state, tries); } while (1); return response; }
static int libvirt_status(const char *vm_name, void *priv) { struct libvirt_info *info = (struct libvirt_info *)priv; virDomainPtr vdp; virDomainInfo vdi; int ret = 0; dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); VALIDATE(info); if (is_uuid(vm_name)) { vdp = virDomainLookupByUUIDString(info->vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(info->vp, vm_name); } if (!vdp || ((virDomainGetInfo(vdp, &vdi) == 0) && (vdi.state == VIR_DOMAIN_SHUTOFF))) { ret = RESP_OFF; } if (vdp) virDomainFree(vdp); return ret; }
static int libvirt_off(const char *vm_name, const char *src, uint32_t seqno, void *priv) { struct libvirt_info *info = (struct libvirt_info *)priv; virDomainPtr vdp; virDomainInfo vdi; int ret = -1; dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); VALIDATE(info); if (is_uuid(vm_name)) { vdp = virDomainLookupByUUIDString(info->vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(info->vp, vm_name); } if (!vdp) { dbg_printf(2, "Nothing to do - domain does not exist\n"); return 1; } if (((virDomainGetInfo(vdp, &vdi) == 0) && (vdi.state == VIR_DOMAIN_SHUTOFF))) { dbg_printf(2, "Nothing to do - domain is off\n"); virDomainFree(vdp); return 0; } syslog(LOG_NOTICE, "Destroying domain %s\n", vm_name); dbg_printf(2, "[OFF] Calling virDomainDestroy\n"); ret = virDomainDestroy(vdp); if (ret < 0) { syslog(LOG_NOTICE, "Failed to destroy domain: %d\n", ret); printf("virDomainDestroy() failed: %d\n", ret); return 1; } if (ret) { syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", vm_name); printf("Domain %s still exists; fencing failed\n", vm_name); return 1; } return 0; }
static int libvirt_on(const char *vm_name, const char *src, uint32_t seqno, void *priv) { struct libvirt_info *info = (struct libvirt_info *)priv; virDomainPtr vdp; virDomainInfo vdi; int ret = -1; dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); VALIDATE(info); if (is_uuid(vm_name)) { vdp = virDomainLookupByUUIDString(info->vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(info->vp, vm_name); } if (vdp && ((virDomainGetInfo(vdp, &vdi) == 0) && (vdi.state != VIR_DOMAIN_SHUTOFF))) { dbg_printf(2, "Nothing to do - domain is running\n"); if (vdp) virDomainFree(vdp); return 0; } syslog(LOG_NOTICE, "Starting domain %s\n", vm_name); dbg_printf(2, "[ON] Calling virDomainCreate\n"); ret = virDomainCreate(vdp); if (ret < 0) { syslog(LOG_NOTICE, "Failed to start domain: %d\n", ret); printf("virDomainCreate() failed: %d\n", ret); return 1; } if (ret) { syslog(LOG_NOTICE, "Domain %s did not start\n", vm_name); printf("Domain %s did not start\n", vm_name); return 1; } syslog(LOG_NOTICE, "Domain %s started\n", vm_name); return 0; }
int guestfs_impl_add_domain (guestfs_h *g, const char *domain_name, const struct guestfs_add_domain_argv *optargs) { virErrorPtr err; virConnectPtr conn = NULL; virDomainPtr dom = NULL; int r = -1; const char *libvirturi; int readonly; int live; int allowuuid; const char *readonlydisk; const char *iface; const char *cachemode; const char *discard; bool copyonread; struct guestfs_add_libvirt_dom_argv optargs2 = { .bitmask = 0 }; libvirturi = optargs->bitmask & GUESTFS_ADD_DOMAIN_LIBVIRTURI_BITMASK ? optargs->libvirturi : NULL; readonly = optargs->bitmask & GUESTFS_ADD_DOMAIN_READONLY_BITMASK ? optargs->readonly : 0; iface = optargs->bitmask & GUESTFS_ADD_DOMAIN_IFACE_BITMASK ? optargs->iface : NULL; live = optargs->bitmask & GUESTFS_ADD_DOMAIN_LIVE_BITMASK ? optargs->live : 0; allowuuid = optargs->bitmask & GUESTFS_ADD_DOMAIN_ALLOWUUID_BITMASK ? optargs->allowuuid : 0; readonlydisk = optargs->bitmask & GUESTFS_ADD_DOMAIN_READONLYDISK_BITMASK ? optargs->readonlydisk : NULL; cachemode = optargs->bitmask & GUESTFS_ADD_DOMAIN_CACHEMODE_BITMASK ? optargs->cachemode : NULL; discard = optargs->bitmask & GUESTFS_ADD_DOMAIN_DISCARD_BITMASK ? optargs->discard : NULL; copyonread = optargs->bitmask & GUESTFS_ADD_DOMAIN_COPYONREAD_BITMASK ? optargs->copyonread : false; if (live && readonly) { error (g, _("you cannot set both live and readonly flags")); return -1; } /* Connect to libvirt, find the domain. */ conn = guestfs_int_open_libvirt_connection (g, libvirturi, VIR_CONNECT_RO); if (!conn) { err = virGetLastError (); error (g, _("could not connect to libvirt (code %d, domain %d): %s"), err->code, err->domain, err->message); goto cleanup; } /* Suppress default behaviour of printing errors to stderr. Note * you can't set this to NULL to ignore errors; setting it to NULL * restores the default error handler ... */ virConnSetErrorFunc (conn, NULL, ignore_errors); /* Try UUID first. */ if (allowuuid) dom = virDomainLookupByUUIDString (conn, domain_name); /* Try ordinary domain name. */ if (!dom) dom = virDomainLookupByName (conn, domain_name); if (!dom) { err = virGetLastError (); error (g, _("no libvirt domain called '%s': %s"), domain_name, err->message); goto cleanup; } if (readonly) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_READONLY_BITMASK; optargs2.readonly = readonly; } if (iface) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_IFACE_BITMASK; optargs2.iface = iface; } if (live) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_LIVE_BITMASK; optargs2.live = live; } if (readonlydisk) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_READONLYDISK_BITMASK; optargs2.readonlydisk = readonlydisk; } if (cachemode) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_CACHEMODE_BITMASK; optargs2.cachemode = cachemode; } if (discard) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_DISCARD_BITMASK; optargs2.discard = discard; } if (copyonread) { optargs2.bitmask |= GUESTFS_ADD_LIBVIRT_DOM_COPYONREAD_BITMASK; optargs2.copyonread = copyonread; } r = guestfs_add_libvirt_dom_argv (g, dom, &optargs2); cleanup: if (dom) virDomainFree (dom); if (conn) virConnectClose (conn); return r; } static int add_disk (guestfs_h *g, const char *filename, const char *format, int readonly, const char *protocol, char *const *server, const char *username, void *data); static int connect_live (guestfs_h *g, virDomainPtr dom); enum readonlydisk { readonlydisk_error, readonlydisk_read, readonlydisk_write, readonlydisk_ignore, }; struct add_disk_data { int readonly; enum readonlydisk readonlydisk; /* Other args to pass through to add_drive_opts. */ struct guestfs_add_drive_opts_argv optargs; }; int guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp, const struct guestfs_add_libvirt_dom_argv *optargs) { virDomainPtr dom = domvp; ssize_t r; int readonly; const char *iface; const char *cachemode; const char *discard; bool copyonread; int live; /* Default for back-compat reasons: */ enum readonlydisk readonlydisk = readonlydisk_write; size_t ckp; struct add_disk_data data; CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL; CLEANUP_FREE char *label = NULL, *imagelabel = NULL; readonly = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_READONLY_BITMASK ? optargs->readonly : 0; iface = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_IFACE_BITMASK ? optargs->iface : NULL; live = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_LIVE_BITMASK ? optargs->live : 0; if ((optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_READONLYDISK_BITMASK)) { if (STREQ (optargs->readonlydisk, "error")) readonlydisk = readonlydisk_error; else if (STREQ (optargs->readonlydisk, "read")) readonlydisk = readonlydisk_read; else if (STREQ (optargs->readonlydisk, "write")) readonlydisk = readonlydisk_write; else if (STREQ (optargs->readonlydisk, "ignore")) readonlydisk = readonlydisk_ignore; else { error (g, _("unknown readonlydisk parameter")); return -1; } } cachemode = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_CACHEMODE_BITMASK ? optargs->cachemode : NULL; discard = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_DISCARD_BITMASK ? optargs->discard : NULL; copyonread = optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_COPYONREAD_BITMASK ? optargs->copyonread : false; if (live && readonly) { error (g, _("you cannot set both live and readonly flags")); return -1; } if (!readonly) { virDomainInfo info; virErrorPtr err; int vm_running; if (virDomainGetInfo (dom, &info) == -1) { err = virGetLastError (); error (g, _("error getting domain info: %s"), err->message); return -1; } vm_running = info.state != VIR_DOMAIN_SHUTOFF; if (vm_running) { /* If the caller specified the 'live' flag, then they want us to * try to connect to guestfsd if the domain is running. Note * that live readonly connections are not possible. */ if (live) return connect_live (g, dom); /* Dangerous to modify the disks of a running VM. */ error (g, _("error: domain is a live virtual machine.\n" "Writing to the disks of a running virtual machine can cause disk corruption.\n" "Either use read-only access, or if the guest is running the guestfsd daemon\n" "specify live access. In most libguestfs tools these options are --ro or\n" "--live respectively. Consult the documentation for further information.")); return -1; } } /* Domain XML. */ if ((doc = get_domain_xml (g, dom)) == NULL) return -1; /* Find and pass the SELinux security label to the libvirt back end. * Note this has to happen before adding the disks, since those may * use the label. */ if (libvirt_selinux_label (g, doc, &label, &imagelabel) == -1) return -1; if (label && imagelabel) { guestfs_set_backend_setting (g, "internal_libvirt_label", label); guestfs_set_backend_setting (g, "internal_libvirt_imagelabel", imagelabel); guestfs_set_backend_setting (g, "internal_libvirt_norelabel_disks", "1"); } else guestfs_clear_backend_setting (g, "internal_libvirt_norelabel_disks"); /* Add the disks. */ data.optargs.bitmask = 0; data.readonly = readonly; data.readonlydisk = readonlydisk; if (iface) { data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_IFACE_BITMASK; data.optargs.iface = iface; } if (cachemode) { data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_CACHEMODE_BITMASK; data.optargs.cachemode = cachemode; } if (discard) { data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_DISCARD_BITMASK; data.optargs.discard = discard; } if (copyonread) { data.optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_COPYONREAD_BITMASK; data.optargs.copyonread = copyonread; } /* Checkpoint the command line around the operation so that either * all disks are added or none are added. */ ckp = guestfs_int_checkpoint_drives (g); r = for_each_disk (g, doc, add_disk, &data); if (r == -1) guestfs_int_rollback_drives (g, ckp); return r; }
void NodeWrap::syncDomains() { /* Sync up with domains that are defined but not active. */ int maxname = virConnectNumOfDefinedDomains(conn); if (maxname < 0) { REPORT_ERR(conn, "virConnectNumOfDefinedDomains"); return; } else { char **dnames; dnames = (char **) malloc(sizeof(char *) * maxname); if ((maxname = virConnectListDefinedDomains(conn, dnames, maxname)) < 0) { REPORT_ERR(conn, "virConnectListDefinedDomains"); free(dnames); return; } for (int i = 0; i < maxname; i++) { virDomainPtr domain_ptr; bool found = false; for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end(); iter++) { if ((*iter)->domain_name == dnames[i]) { found = true; break; } } if (found) { continue; } domain_ptr = virDomainLookupByName(conn, dnames[i]); if (!domain_ptr) { REPORT_ERR(conn, "virDomainLookupByName"); } else { DomainWrap *domain; try { domain = new DomainWrap(agent, this, domain_ptr, conn); printf("Created new domain: %s, ptr is %p\n", dnames[i], domain_ptr); domains.push_back(domain); } catch (int i) { printf ("Error constructing domain\n"); REPORT_ERR(conn, "constructing domain."); delete domain; } } } for (int i = 0; i < maxname; i++) { free(dnames[i]); } free(dnames); } /* Go through all the active domains */ int maxids = virConnectNumOfDomains(conn); if (maxids < 0) { REPORT_ERR(conn, "virConnectNumOfDomains"); return; } else { int *ids; ids = (int *) malloc(sizeof(int *) * maxids); if ((maxids = virConnectListDomains(conn, ids, maxids)) < 0) { printf("Error getting list of defined domains\n"); return; } for (int i = 0; i < maxids; i++) { virDomainPtr domain_ptr; char dom_uuid[VIR_UUID_STRING_BUFLEN]; domain_ptr = virDomainLookupByID(conn, ids[i]); if (!domain_ptr) { REPORT_ERR(conn, "virDomainLookupByID"); continue; } if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) { REPORT_ERR(conn, "virDomainGetUUIDString"); continue; } bool found = false; for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end(); iter++) { if (strcmp((*iter)->domain_uuid.c_str(), dom_uuid) == 0) { found = true; break; } } if (found) { virDomainFree(domain_ptr); continue; } DomainWrap *domain; try { domain = new DomainWrap(agent, this, domain_ptr, conn); printf("Created new domain: %d, ptr is %p\n", ids[i], domain_ptr); domains.push_back(domain); } catch (int i) { printf ("Error constructing domain\n"); REPORT_ERR(conn, "constructing domain."); delete domain; } } free(ids); } /* Go through our list of domains and ensure that they still exist. */ for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end();) { printf("verifying domain %s\n", (*iter)->domain_name.c_str()); virDomainPtr ptr = virDomainLookupByUUIDString(conn, (*iter)->domain_uuid.c_str()); if (ptr == NULL) { REPORT_ERR(conn, "virDomainLookupByUUIDString"); delete (*iter); iter = domains.erase(iter); } else { virDomainFree(ptr); iter++; } } }
static int libvirt_reboot(const char *vm_name, const char *src, uint32_t seqno, void *priv) { struct libvirt_info *info = (struct libvirt_info *)priv; virDomainPtr vdp, nvdp; virDomainInfo vdi; char *domain_desc; int ret; //uuid_unparse(vm_uuid, uu_string); dbg_printf(5, "%s %s\n", __FUNCTION__, vm_name); VALIDATE(info); if (is_uuid(vm_name)) { vdp = virDomainLookupByUUIDString(info->vp, (const char *)vm_name); } else { vdp = virDomainLookupByName(info->vp, vm_name); } if (!vdp) { dbg_printf(2, "[libvirt:REBOOT] Nothing to " "do - domain does not exist\n"); return 1; } if (((virDomainGetInfo(vdp, &vdi) == 0) && (vdi.state == VIR_DOMAIN_SHUTOFF))) { dbg_printf(2, "[libvirt:REBOOT] Nothing to " "do - domain is off\n"); virDomainFree(vdp); return 0; } syslog(LOG_NOTICE, "Rebooting domain %s\n", vm_name); printf("Rebooting domain %s...\n", vm_name); domain_desc = virDomainGetXMLDesc(vdp, 0); if (!domain_desc) { printf("Failed getting domain description from " "libvirt\n"); } dbg_printf(2, "[REBOOT] Calling virDomainDestroy(%p)\n", vdp); ret = virDomainDestroy(vdp); if (ret < 0) { printf("virDomainDestroy() failed: %d/%d\n", ret, errno); free(domain_desc); virDomainFree(vdp); return 1; } ret = wait_domain(vm_name, info->vp, 15); if (ret) { syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", vm_name); printf("Domain %s still exists; fencing failed\n", vm_name); if (domain_desc) free(domain_desc); return 1; } if (!domain_desc) return 0; /* 'on' is not a failure */ ret = 0; dbg_printf(3, "[[ XML Domain Info ]]\n"); dbg_printf(3, "%s\n[[ XML END ]]\n", domain_desc); dbg_printf(2, "Calling virDomainCreateLinux()...\n"); nvdp = virDomainCreateLinux(info->vp, domain_desc, 0); if (nvdp == NULL) { /* More recent versions of libvirt or perhaps the * KVM back-end do not let you create a domain from * XML if there is already a defined domain description * with the same name that it knows about. You must * then call virDomainCreate() */ dbg_printf(2, "Failed; Trying virDomainCreate()...\n"); if (virDomainCreate(vdp) < 0) { syslog(LOG_NOTICE, "Could not restart %s\n", vm_name); dbg_printf(1, "Failed to recreate guest" " %s!\n", vm_name); } } free(domain_desc); return ret; }
void run(char *myIP, virConnectPtr localhost) { printf("*** New run\n"); virDomainPtr *domains, *domainsptr; virConnectListAllDomains(localhost, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE|VIR_CONNECT_LIST_DOMAINS_INACTIVE|VIR_CONNECT_LIST_DOMAINS_RUNNING|VIR_CONNECT_LIST_DOMAINS_SHUTOFF); domainsptr = domains; char **domainuuids = malloc(sizeof(char*)*1024); char **domainuuidsptr = domainuuids; *domainuuids = NULL; printf("Domains\n"); while(*domainsptr != NULL) { char buf[VIR_UUID_STRING_BUFLEN]; virDomainGetUUIDString(*domainsptr, buf); const char *name = virDomainGetName(*domainsptr); if (!strncmp("ignore",name,strlen("ignore"))) { domainsptr++; continue; } printf("%s\n", buf); *(domainuuidsptr++) = strdup(buf); *domainuuidsptr = NULL; domainsptr++; } domainuuidsptr = domainuuids; size_t domainuuids_count=0; while(*domainuuidsptr != NULL) domainuuidsptr++, domainuuids_count++; domainuuidsptr = domainuuids; domainsptr = domains; char **hosts = gethosts(); char **hostsptr=hosts; size_t hosts_count = 0; while (*hostsptr != NULL) hosts_count++, hostsptr++; hostsptr = hosts; struct hostwithvmhash **cs = malloc(sizeof(struct hostwithvmhash)*1024); *cs = NULL; struct hostwithvmhash **csptr = cs; int sign=0; while(*hostsptr != NULL) { if (!strcmp(*hostsptr, myIP)) printf("ME! "); sign = !sign; size_t k=1; while(*domainuuidsptr != NULL) { /* char *num = "$6$hest"; char *hash = crypt(*domainuuidsptr, num); char *hash2 = crypt(*hostsptr, num);*/ struct hostwithvmhash *c=malloc(sizeof(struct hostwithvmhash)); c->host = *hostsptr; // c->host_hash = strdup(hash+10); c->vm = *domainuuidsptr; // c->vm_hash = strdup(hash2+10); c->combined = malloc(10000); strcpy(c->combined, ""); strcat(c->combined, c->host); strcat(c->combined, c->vm); //c->combined = strdup(crypt(c->combined, num)); *(csptr++) = c; *csptr = NULL; domainuuidsptr++; } domainuuidsptr = domainuuids; printf("%s\n", *hostsptr); /* char URL[512]; sprintf(URL, "qemu+ssh://%s/system", *hosts); virConnectPtr dest = virConnectOpen(URL); *(destsptr++) = dest; *destsptr = NULL;*/ hostsptr++; } csptr = cs; printf("\n"); size_t count=0; while(*csptr != NULL) count++, csptr++; csptr = cs; qsort(csptr, count, sizeof(struct hostwithvmhash*), (__compar_fn_t)cscompare); struct hostwithvmhash **csptrptr = csptr; size_t i=0,k=0,j=0,q=1,m=0; char *last_host=NULL,*last_vm=NULL; struct hostwithvmhash **seen=malloc(sizeof(struct hostwithvmhash*)*1024); *seen = NULL; struct hostwithvmhash **seenptr=seen; struct hostwithvmhash **seenaddptr=seen; while(*csptrptr != NULL) { if (last_host == NULL || strcmp(last_host, (*csptrptr)->host)) last_host = (*csptrptr)->host,k++; seenptr=seen; int is_seen=0; while(*seenptr != NULL) { if (!strcmp((*seenptr)->vm, (*csptrptr)->vm)) is_seen=1; seenptr++; } if (!is_seen) { m++,*(seenaddptr++) = *csptrptr, *seenaddptr = NULL; (*csptrptr)->prio = 100*m+(k+m)%hosts_count; if (m == domainuuids_count) m = 0, seenaddptr=seenptr=seen,*seen=NULL; } else (*csptrptr)->prio = k; csptrptr++; } qsort(csptr, count, sizeof(struct hostwithvmhash*), (__compar_fn_t)cscompareprio); struct hostwithvmhash **cleaned = cleanlist(csptr); struct hostwithvmhash **cleanedstart = cleaned; while(*cleaned != NULL) { virDomainPtr d = virDomainLookupByUUIDString(localhost, (*cleaned)->vm); const char *name = virDomainGetName(d); int state, reason; virDomainGetState(d, &state, &reason, 0); if (!strcmp((*cleaned)->host, myIP)) { printf("I should be running %s (%s)\n", name, (*cleaned)->vm); if (state == VIR_DOMAIN_RUNNING) printf("...and it's running.\n"); else virDomainCreate(d); } else { printf("I should NOT be running %s (%s)\n", name, (*cleaned)->vm); if (state == VIR_DOMAIN_RUNNING) { printf("Destroying.\n"); virDomainDestroy(d); } else printf("...and it's not running.\n"); } if (d) { virDomainFree(d); } //printf("prio:%d host:%s, vm:%s combined:%s\n", (*cleaned)->prio, (*cleaned)->host, (*cleaned)->vm, (*cleaned)->combined); cleaned++; } domainuuidsptr = domainuuids; while(*domainuuidsptr != NULL) { free(*domainuuidsptr); domainuuidsptr++; } free(domainuuids); free(cleanedstart); csptr = cs; while(*csptr != NULL) { free((*csptr)->combined); free(*csptr); csptr++; } free(cs); free(seen); hostsptr = hosts; while(*hostsptr != NULL) { free(*hostsptr); hostsptr++; } free(hosts); domainsptr = domains; while(*domainsptr != NULL) { virDomainFree(*domainsptr); domainsptr++; } free(domains); /* virDomainPtr *domains; virConnectListAllDomains(src, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE); while(*domains != NULL) { char *config = virDomainGetXMLDesc(*domains, 0); char uuid[VIR_UUID_BUFLEN]; char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainGetUUIDString(*domains, uuidstr); virDomainGetUUID(*domains, uuid); destsptr = dests; while (*destsptr != NULL) { virConnectPtr dest = *destsptr; virDomainPtr d = virDomainLookupByUUID(dest, uuid); if (d) printf("%s already in dest\n", uuidstr); if (!d) { printf("%s\n", config); printf("Injecting domain on dest\n"); virDomainPtr new = virDomainDefineXML(dest, config); } fflush(stdout); destsptr++; } domains++; }*/ }