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 = NULL; virDomainInfo vdi; virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); int ret = -1; int i; dbg_printf(5, "ENTER %s %s %u\n", __FUNCTION__, vm_name, seqno); VALIDATE(info); if (is_uuid(vm_name)) virt_lookup_fn = virDomainLookupByUUIDString; else virt_lookup_fn = virDomainLookupByName; for (i = 0 ; i < info->vp_count ; i++) { vdp = virt_lookup_fn(info->vp[i], vm_name); if (vdp) break; } if (!vdp) { dbg_printf(2, "[libvirt:OFF] Domain %s does not exist\n", vm_name); return 1; } if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) { dbg_printf(2, "[libvirt:OFF] Nothing to do - " "domain %s is already off\n", vm_name); virDomainFree(vdp); return 0; } syslog(LOG_NOTICE, "Destroying domain %s\n", vm_name); dbg_printf(2, "[libvirt:OFF] Calling virDomainDestroy for %s\n", vm_name); ret = virDomainDestroy(vdp); virDomainFree(vdp); if (ret < 0) { syslog(LOG_NOTICE, "Failed to destroy domain %s: %d\n", vm_name, ret); dbg_printf(2, "[libvirt:OFF] Failed to destroy domain: %s %d\n", vm_name, ret); return 1; } if (ret) { syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", vm_name); dbg_printf(2, "[libvirt:OFF] Domain %s still exists; fencing failed\n", vm_name); return 1; } dbg_printf(2, "[libvirt:OFF] Success for %s\n", vm_name); return 0; }
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 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 struct ovs_port *parse_port(json_t *jresult, json_t *uuid, struct ovs_bridge *br) { struct ovs_port *port; struct ovs_if *ptr = NULL; /* GCC false positive */ struct ovs_if *iface; json_t *jport, *jarr; unsigned int i; if (!is_uuid(uuid)) return NULL; jport = json_object_get(jresult, "Port"); jport = json_object_get(jport, json_string_value(json_array_get(uuid, 1))); jport = json_object_get(jport, "new"); port = calloc(sizeof(*port), 1); if (!port) return NULL; port->name = strdup(json_string_value(json_object_get(jport, "name"))); port->bridge = br; if (parse_port_info(port, jport)) return NULL; jarr = json_object_get(jport, "interfaces"); if (is_set(jarr)) { jarr = json_array_get(jarr, 1); for (i = 0; i < json_array_size(jarr); i++) { iface = parse_iface(jresult, json_array_get(jarr, i)); if (!iface) return NULL; iface->port = port; if (!port->ifaces) port->ifaces = iface; else ptr->next = iface; ptr = iface; port->iface_count++; } } else { iface = parse_iface(jresult, jarr); if (!iface) return NULL; iface->port = port; port->ifaces = iface; port->iface_count = 1; } if (!strcmp(json_string_value(json_object_get(jport, "name")), br->name)) br->system = port; return port; }
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; }
static struct ovs_if *parse_iface(json_t *jresult, json_t *uuid) { struct ovs_if *iface; json_t *jif, *jarr; unsigned int i; if (!is_uuid(uuid)) return NULL; jif = json_object_get(jresult, "Interface"); jif = json_object_get(jif, json_string_value(json_array_get(uuid, 1))); jif = json_object_get(jif, "new"); iface = calloc(sizeof(*iface), 1); if (!iface) return NULL; iface->name = strdup(json_string_value(json_object_get(jif, "name"))); iface->type = strdup(json_string_value(json_object_get(jif, "type"))); jarr = json_object_get(jif, "options"); if (!strcmp(iface->type, "vxlan") && is_map(jarr)) { jarr = json_array_get(jarr, 1); for (i = 0; i < json_array_size(jarr); i++) { json_t *jkv; const char *key, *val; jkv = json_array_get(jarr, i); key = json_string_value(json_array_get(jkv, 0)); val = json_string_value(json_array_get(jkv, 1)); if (!strcmp(key, "local_ip")) iface->local_ip = strdup(val); else if (!strcmp(key, "remote_ip")) iface->remote_ip = strdup(val); } } else if (!strcmp(iface->type, "patch") && is_map(jarr)) { jarr = json_array_get(jarr, 1); for (i = 0; i < json_array_size(jarr); i++) { json_t *jkv; const char *key, *val; jkv = json_array_get(jarr, i); key = json_string_value(json_array_get(jkv, 0)); val = json_string_value(json_array_get(jkv, 1)); if (!strcmp(key, "peer")) iface->peer = strdup(val); } } return iface; }
int main(int argc, char **argv) { int ret; if (argc < 2) { printf("Usage: uuidtest <value>\n"); return 1; } ret = is_uuid(argv[1]); if (ret == 0) { printf("%s is NOT a uuid\n", argv[1]); } else if (ret == 1) { printf("%s is a uuid\n", argv[1]); } else { printf("Error: %s\n", strerror(errno)); return 1; } return 0; }
static int libvirt_status(const char *vm_name, void *priv) { struct libvirt_info *info = (struct libvirt_info *)priv; virDomainPtr vdp = NULL; virDomainInfo vdi; int ret = 0; int i; virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); dbg_printf(5, "ENTER %s %s\n", __FUNCTION__, vm_name); VALIDATE(info); if (is_uuid(vm_name)) virt_lookup_fn = virDomainLookupByUUIDString; else virt_lookup_fn = virDomainLookupByName; for (i = 0 ; i < info->vp_count ; i++) { vdp = virt_lookup_fn(info->vp[i], vm_name); if (vdp) break; } if (!vdp) { dbg_printf(2, "[libvirt:STATUS] Unknown VM %s - return OFF\n", vm_name); return RESP_OFF; } if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) { dbg_printf(2, "[libvirt:STATUS] VM %s is OFF\n", vm_name); ret = RESP_OFF; } if (vdp) virDomainFree(vdp); return ret; }
static struct ovs_bridge *parse_bridge(json_t *jresult, json_t *uuid) { struct ovs_bridge *br; struct ovs_port *ptr = NULL; /* GCC false positive */ struct ovs_port *port; json_t *jbridge, *jarr; unsigned int i; if (!is_uuid(uuid)) return NULL; jbridge = json_object_get(jresult, "Bridge"); jbridge = json_object_get(jbridge, json_string_value(json_array_get(uuid, 1))); jbridge = json_object_get(jbridge, "new"); br = calloc(sizeof(*br), 1); if (!br) return NULL; br->name = strdup(json_string_value(json_object_get(jbridge, "name"))); jarr = json_object_get(jbridge, "ports"); if (is_set(jarr)) { jarr = json_array_get(jarr, 1); for (i = 0; i < json_array_size(jarr); i++) { port = parse_port(jresult, json_array_get(jarr, i), br); if (!port) return NULL; if (!br->ports) br->ports = port; else ptr->next = port; ptr = port; } } else br->ports = parse_port(jresult, jarr, br); if (!br->ports) return NULL; return br; }
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 = NULL, nvdp; virDomainInfo vdi; char *domain_desc; virConnectPtr vcp = NULL; virDomainPtr (*virt_lookup_fn)(virConnectPtr, const char *); int ret; int i; dbg_printf(5, "ENTER %s %s %u\n", __FUNCTION__, vm_name, seqno); VALIDATE(info); if (is_uuid(vm_name)) virt_lookup_fn = virDomainLookupByUUIDString; else virt_lookup_fn = virDomainLookupByName; for (i = 0 ; i < info->vp_count ; i++) { vdp = virt_lookup_fn(info->vp[i], vm_name); if (vdp) { vcp = info->vp[i]; break; } } if (!vdp || !vcp) { dbg_printf(2, "[libvirt:REBOOT] Nothing to do - domain %s does not exist\n", vm_name); return 1; } if (virDomainGetInfo(vdp, &vdi) == 0 && vdi.state == VIR_DOMAIN_SHUTOFF) { dbg_printf(2, "[libvirt:REBOOT] Nothing to do - domain %s is off\n", vm_name); virDomainFree(vdp); return 0; } syslog(LOG_NOTICE, "Rebooting domain %s\n", vm_name); dbg_printf(5, "[libvirt:REBOOT] Rebooting domain %s...\n", vm_name); domain_desc = virDomainGetXMLDesc(vdp, 0); if (!domain_desc) { dbg_printf(5, "[libvirt:REBOOT] Failed getting domain description " "from libvirt for %s...\n", vm_name); } dbg_printf(2, "[libvirt:REBOOT] Calling virDomainDestroy(%p) for %s\n", vdp, vm_name); ret = virDomainDestroy(vdp); if (ret < 0) { dbg_printf(2, "[libvirt:REBOOT] virDomainDestroy() failed for %s: %d/%d\n", vm_name, ret, errno); if (domain_desc) free(domain_desc); virDomainFree(vdp); return 1; } ret = wait_domain(vm_name, vcp, 15); if (ret) { syslog(LOG_NOTICE, "Domain %s still exists; fencing failed\n", vm_name); dbg_printf(2, "[libvirt:REBOOT] Domain %s still exists; fencing failed\n", vm_name); if (domain_desc) free(domain_desc); virDomainFree(vdp); 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, "[libvirt:REBOOT] Calling virDomainCreateLinux() for %s\n", vm_name); nvdp = virDomainCreateLinux(vcp, 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, "[libvirt:REBOOT] virDomainCreateLinux() failed for %s; " "Trying virDomainCreate()\n", vm_name); if (virDomainCreate(vdp) < 0) { syslog(LOG_NOTICE, "Could not restart %s\n", vm_name); dbg_printf(1, "[libvirt:REBOOT] Failed to recreate guest %s!\n", vm_name); } } free(domain_desc); virDomainFree(vdp); return ret; }
int do_lq_request(struct lq_info *info, const char *vm_name, const char *action) { std::string vm_state; const char *property = "name"; if (is_uuid(vm_name) == 1) { property = "uuid"; } qmf::ConsoleSession session(lq_open_session(info)); if (!session.isValid()) { std::cout << "Invalid session." << std::endl; return 1; } qmf::Agent agent; qmf::Data domain; int result; unsigned tries = 0; bool found = false; while (++tries < 10 && !found) { sleep(1); uint32_t numAgents = session.getAgentCount(); for (unsigned a = 0; !found && a < numAgents; a++) { agent = session.getAgent(a); qmf::ConsoleEvent event(queryDomain(agent)); uint32_t numDomains = event.getDataCount(); for (unsigned d = 0; !found && d < numDomains; d++) { domain = event.getData(d); qpid::types::Variant prop; try { prop = domain.getProperty(property); } catch (qmf::KeyNotFound e) { std::cout << e.what() << " - skipping" << std::endl; continue; } if (prop.asString() != vm_name) { continue; } found = true; } } } if (!found) { result = 1; goto out; } vm_state = domain.getProperty("state").asString(); std::cout << vm_name << " " << vm_state << std::endl; int r; if (vm_state == "running" || vm_state == "idle" || vm_state == "paused" || vm_state == "no state") { r = RESP_OFF; } else { r = 0; } if (strcasecmp(action, "state") == 0) { result = r; goto out; } result = 1; if (!r && strcasecmp(action, "destroy") == 0) { std::cout << "Domain is inactive; nothing to do" << std::endl; result = 0; goto out; } if (r && strcasecmp(action, "create") == 0) { std::cout << "Domain is active; nothing to do" << std::endl; result = 0; goto out; } { qmf::ConsoleEvent response; response = agent.callMethod(action, qpid::types::Variant::Map(), domain.getAddr()); if (response.getType() == qmf::CONSOLE_EXCEPTION) { std::string errorText; if (response.getDataCount()) { qmf::Data responseData(response.getData(0)); qpid::types::Variant code(responseData.getProperty("error_code")); if (code.getType() == qpid::types::VAR_INT32) { result = responseData.getProperty("error_code").asInt32(); } else { result = 7; // Exception } qpid::types::Variant text(responseData.getProperty("error_text")); if (text.getType() != qpid::types::VAR_VOID) { errorText = text.asString(); } } else { result = 7; // Exception } std::cout << "Response: " << result; if (errorText.length()) { std::cout << " (" << errorText << ")"; } std::cout << std::endl; } else { // Success result = 0; } } out: session.close(); return result; }
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; }