Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}