Beispiel #1
0
static xmlDocPtr
get_domain_xml (guestfs_h *g, virDomainPtr dom)
{
  virErrorPtr err;
  xmlDocPtr doc;

  CLEANUP_FREE char *xml = virDomainGetXMLDesc (dom, 0);
  if (!xml) {
    err = virGetLastError ();
    error (g, _("error reading libvirt XML information: %s"), err->message);
    return NULL;
  }

  debug (g, "original domain XML:\n%s", xml);

  /* Parse the domain XML into an XML document. */
  doc = xmlReadMemory (xml, strlen (xml),
                       NULL, NULL, XML_PARSE_NONET);
  if (doc == NULL) {
    error (g, _("unable to parse XML information returned by libvirt"));
    return NULL;
  }

  return doc;
}
Beispiel #2
0
Datei: virt.cpp Projekt: kohn/rsi
int VM_Controller::get_image_config_fd_by_name(std::string vm_name){
    virDomainPtr dom = virDomainLookupByName(_conn, vm_name.c_str());
    if(dom == NULL){
        return -1;
    }
    char *domain_xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
    virDomainFree(dom);
    std::string config_file = _make_tmp_config_file_name(vm_name);
    int fd = open(config_file.c_str(), O_WRONLY|O_CREAT);

    int filesize = strlen(domain_xml);
    int write_count = 0;
    while(write_count < filesize){
        int once_write_count = write(fd, domain_xml, filesize);
        if(once_write_count < 0){
            LOG_ERROR("write error");
            close(fd);
            return -1;
        }
        write_count += once_write_count;
    }
    close(fd);

    fd = open(config_file.c_str(), O_RDONLY);
    return fd;
}
Beispiel #3
0
static char *
getMetadataFromXML(virDomainPtr dom)
{
    xmlDocPtr doc = NULL;
    xmlXPathContextPtr ctxt = NULL;
    xmlNodePtr node;

    char *xml = NULL;
    char *ret = NULL;

    if (!(xml = virDomainGetXMLDesc(dom, 0)))
        goto cleanup;

    if (!(doc = virXMLParseStringCtxt(xml, "(domain_definition)", &ctxt)))
        goto cleanup;

    if (!(node = virXPathNode("//metadata/*", ctxt)))
        goto cleanup;

    ret = virXMLNodeToString(node->doc, node);

 cleanup:
    VIR_FREE(xml);
    xmlFreeDoc(doc);
    xmlXPathFreeContext(ctxt);

    return ret;
}
void SetDisksDataThread::run()
{
    if ( nullptr==ptr_ConnPtr || nullptr==*ptr_ConnPtr ) {
        emit ptrIsNull();
        return;
    };
    // NOTE: currConnName == domainName
    virDomainPtr domain = virDomainLookupByName(
                *ptr_ConnPtr, currConnName.toUtf8().data());
    if ( nullptr!=domain ) {
        char *xmlDesc = virDomainGetXMLDesc(domain, 0);
        virDomainFree(domain);
        if ( nullptr!=xmlDesc ) {
            QDomDocument doc;
            doc.setContent(QString(xmlDesc));
            free(xmlDesc);
            QDomElement _devices = doc
                    .firstChildElement("domain")
                    .firstChildElement("devices");
            QDomElement _disk = _devices
                    .firstChildElement("disk");
            while ( !_disk.isNull() ) {
                emit diskData(_disk);
                _disk = _disk.nextSiblingElement("disk");
            };
        };
    } else
        sendConnErrors();
}
Beispiel #5
0
Datei: virt.cpp Projekt: kohn/rsi
std::string VM_Controller::_get_vm_image_path(virDomainPtr dom){
    char *domain_xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
    tinyxml2::XMLDocument doc;
    doc.Parse(domain_xml);
    std::string img_path = doc.RootElement()
        ->FirstChildElement("devices")
        ->FirstChildElement("disk")
        ->FirstChildElement("source")
        ->Attribute("file");
    return img_path;
}
Beispiel #6
0
Datei: virt.cpp Projekt: kohn/rsi
std::string VM_Controller::_get_vm_mac(virDomainPtr dom){
    char *domain_xml = virDomainGetXMLDesc(dom,
                                           VIR_DOMAIN_XML_SECURE);
    tinyxml2::XMLDocument doc;
    doc.Parse(domain_xml);
    std::string mac = doc.RootElement()
        ->FirstChildElement("devices")
        ->FirstChildElement("interface")
        ->FirstChildElement("mac")
        ->Attribute("address");
    return mac;
}
Beispiel #7
0
Datei: virt.cpp Projekt: kohn/rsi
std::string VM_Controller::get_vm_detail(virDomainPtr dom){
    Json::Value j;
    j["status"] = "ok";
    virDomainInfo info;
    if(virDomainGetInfo(dom, &info) < 0){
        LOG_ERROR("could not get domain info");
        j["status"] = "no such domain";
        return j.toStyledString();
    }
    // basic info
    int state;
    virDomainGetState(dom, &state, NULL, 0);
    j["vm_status"] = state_code2string(state);
    if(virDomainIsActive(dom)){
        j["id"] = virDomainGetID(dom);
    }
    j["name"] = virDomainGetName(dom);
    j["vcpu"] = virDomainGetMaxVcpus(dom);
    j["mem_total"] = (unsigned long long)virDomainGetMaxMemory(dom);

    // more detailed info
    char *domain_xml = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_SECURE);
    tinyxml2::XMLDocument doc;
    doc.Parse(domain_xml);
    j["img_path"] = doc.RootElement()
        ->FirstChildElement("devices")
        ->FirstChildElement("disk")
        ->FirstChildElement("source")
        ->Attribute("file");
    tinyxml2::XMLElement *graphics = doc.RootElement()
        ->FirstChildElement("devices")
        ->FirstChildElement("graphics");
    j["vnc_port"] = graphics->Attribute("port");

    virDomainFree(dom);
    
    return j.toStyledString();
}
Beispiel #8
0
int libvirt_open() {
	conn = virConnectOpenReadOnly("xen:///");
	if(conn == NULL) {
	  printf("libvirt connection open error on uri \n"); 
	  return 0;
	}
	int n;
	n = virConnectNumOfDomains(conn);
	if(n < 0) {
		printf("Error reading number of domains \n");
		return -1;
	}

	int i;
	int *domids;

	domids = malloc(sizeof(int) * n);
	if(domids == 0) {
		printf("libvirt domain ids malloc failed");
		return -1;
	}
	n = virConnectListDomains(conn, domids, n);
	if(n < 0) {
		printf("Error reading list of domains \n");
		free(domids);
		return -1;
	}

	free_block_devices();
	free_interface_devices();
	free_domains();

	for (i = 0; i < n ; ++i) {
		virDomainPtr dom = NULL;
		const char *name;
		char *xml = NULL;
		xmlDocPtr xml_doc = NULL;
		xmlXPathContextPtr xpath_ctx = NULL;
		xmlXPathObjectPtr xpath_obj = NULL;
		int j;

		//printf("Publishing Domain Id : %d \n ", domids[i]);
		dom = virDomainLookupByID(conn, domids[i]);
		if(dom == NULL) {
			printf("Domain no longer active or moved away .. \n");
		}
		name = virDomainGetName(dom);
		//printf("Publishing Domain Name : %s \n ", name);
		if(name == NULL) {
			printf("Domain name not valid .. \n");
			goto cont;	
		}
		if(add_domain(dom) < 0) {
			printf("libvirt plugin malloc failed .. \n");
			goto cont;
		}
		xml = virDomainGetXMLDesc(dom, 0);
		if(!xml) {
			printf("Virt domain xml description error ..\n");
			goto cont;
		}
		//printf("Publishing XML : \n %s \n ", xml);

		xml_doc = xmlReadDoc((xmlChar *) xml, NULL, NULL, XML_PARSE_NONET);
		if(xml_doc == NULL) {
			printf("XML read doc error ..\n");
			goto cont;
		}

		xpath_ctx = xmlXPathNewContext(xml_doc);
		xpath_obj = xmlXPathEval((xmlChar *) "/domain/devices/disk/target[@dev]", xpath_ctx);
		if(xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) {
			goto cont;
		}

		for(j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
			xmlNodePtr node;
			char *path = NULL;
			node = xpath_obj->nodesetval->nodeTab[j];
			if(!node) continue;
			path = (char *) xmlGetProp (node, (xmlChar *) "dev");
			if(!path) continue;
			add_block_device(dom, path);
		}
		xmlXPathFreeObject(xpath_obj);

		xpath_obj = xmlXPathEval((xmlChar *) "/domain/devices/interface/target[@dev]", xpath_ctx);
		if(xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) {
			goto cont;
		}

		for(j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
			xmlNodePtr node;
			char *path = NULL;
			node = xpath_obj->nodesetval->nodeTab[j];
			if(!node) continue;
			path = (char *) xmlGetProp(node, (xmlChar *) "dev");
			if(!path) continue;
			add_interface_device(dom, path);
		}
		cont:
			if(xpath_obj) xmlXPathFreeObject(xpath_obj);
			if(xpath_ctx) xmlXPathFreeContext(xpath_ctx);
			if(xml_doc) xmlFreeDoc(xml_doc);
			if(xml) free(xml);
	}
	free(domids);
	return 0;
}
Beispiel #9
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;
}
Beispiel #10
0
static int
refresh_lists (void)
{
    int n;

    n = virConnectNumOfDomains (conn);
    if (n < 0) {
        VIRT_ERROR (conn, "reading number of domains");
        return -1;
    }

    if (n > 0) {
        int i;
        int *domids;

        /* Get list of domains. */
        domids = malloc (sizeof (*domids) * n);
        if (domids == NULL) {
            ERROR (PLUGIN_NAME " plugin: malloc failed.");
            return -1;
        }

        n = virConnectListDomains (conn, domids, n);
        if (n < 0) {
            VIRT_ERROR (conn, "reading list of domains");
            sfree (domids);
            return -1;
        }

        free_block_devices ();
        free_interface_devices ();
        free_domains ();

        /* Fetch each domain and add it to the list, unless ignore. */
        for (i = 0; i < n; ++i) {
            virDomainPtr dom = NULL;
            const char *name;
            char *xml = NULL;
            xmlDocPtr xml_doc = NULL;
            xmlXPathContextPtr xpath_ctx = NULL;
            xmlXPathObjectPtr xpath_obj = NULL;
            int j;

            dom = virDomainLookupByID (conn, domids[i]);
            if (dom == NULL) {
                VIRT_ERROR (conn, "virDomainLookupByID");
                /* Could be that the domain went away -- ignore it anyway. */
                continue;
            }

            name = virDomainGetName (dom);
            if (name == NULL) {
                VIRT_ERROR (conn, "virDomainGetName");
                goto cont;
            }

            if (il_domains && ignorelist_match (il_domains, name) != 0)
                goto cont;

            if (add_domain (dom) < 0) {
                ERROR (PLUGIN_NAME " plugin: malloc failed.");
                goto cont;
            }

            /* Get a list of devices for this domain. */
            xml = virDomainGetXMLDesc (dom, 0);
            if (!xml) {
                VIRT_ERROR (conn, "virDomainGetXMLDesc");
                goto cont;
            }

            /* Yuck, XML.  Parse out the devices. */
            xml_doc = xmlReadDoc ((xmlChar *) xml, NULL, NULL, XML_PARSE_NONET);
            if (xml_doc == NULL) {
                VIRT_ERROR (conn, "xmlReadDoc");
                goto cont;
            }

            xpath_ctx = xmlXPathNewContext (xml_doc);

            /* Block devices. */
            xpath_obj = xmlXPathEval
                ((xmlChar *) "/domain/devices/disk/target[@dev]",
                 xpath_ctx);
            if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
                xpath_obj->nodesetval == NULL)
                goto cont;

            for (j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
                xmlNodePtr node;
                char *path = NULL;

                node = xpath_obj->nodesetval->nodeTab[j];
                if (!node) continue;
                path = (char *) xmlGetProp (node, (xmlChar *) "dev");
                if (!path) continue;

                if (il_block_devices &&
                    ignore_device_match (il_block_devices, name, path) != 0)
                    goto cont2;

                add_block_device (dom, path);
            cont2:
                if (path) xmlFree (path);
            }
            xmlXPathFreeObject (xpath_obj);

            /* Network interfaces. */
            xpath_obj = xmlXPathEval
                ((xmlChar *) "/domain/devices/interface[target[@dev]]",
                 xpath_ctx);
            if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
                xpath_obj->nodesetval == NULL)
                goto cont;

            xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;

            for (j = 0; j < xml_interfaces->nodeNr; ++j) {
                char *path = NULL;
                char *address = NULL;
                xmlNodePtr xml_interface;

                xml_interface = xml_interfaces->nodeTab[j];
                if (!xml_interface) continue;
                xmlNodePtr child = NULL;

                for (child = xml_interface->children; child; child = child->next) {
                    if (child->type != XML_ELEMENT_NODE) continue;

                    if (xmlStrEqual(child->name, (const xmlChar *) "target")) {
                        path = (char *) xmlGetProp (child, (const xmlChar *) "dev");
                        if (!path) continue;
                    } else if (xmlStrEqual(child->name, (const xmlChar *) "mac")) {
                        address = (char *) xmlGetProp (child, (const xmlChar *) "address");
                        if (!address) continue;
                    }
                }

                if (il_interface_devices &&
                    (ignore_device_match (il_interface_devices, name, path) != 0 ||
                     ignore_device_match (il_interface_devices, name, address) != 0))
                    goto cont3;

                add_interface_device (dom, path, address, j+1);
                cont3:
                    if (path) xmlFree (path);
                    if (address) xmlFree (address);
            }

        cont:
            if (xpath_obj) xmlXPathFreeObject (xpath_obj);
            if (xpath_ctx) xmlXPathFreeContext (xpath_ctx);
            if (xml_doc) xmlFreeDoc (xml_doc);
            sfree (xml);
        }

        sfree (domids);
    }

    return 0;
}
Beispiel #11
0
static int
domainStarted(virDomainPtr mojaDomain, const char *path, int mode)
{
	char dom_uuid[42];
	char *xml;
	xmlDocPtr doc;
	xmlNodePtr cur, devices, child, serial;
	xmlAttrPtr attr, attr_mode, attr_path;

	if (!mojaDomain)
		return -1;

	virDomainGetUUIDString(mojaDomain, dom_uuid);

	xml = virDomainGetXMLDesc(mojaDomain, 0);
	// printf("%s\n", xml);
	// @todo: free mojaDomain       

	// parseXML output
	doc = xmlParseMemory(xml, strlen(xml));
	xmlFree(xml);
	cur = xmlDocGetRootElement(doc);

	if (cur == NULL) {
		fprintf(stderr, "Empty doc\n");
		xmlFreeDoc(doc);
		return -1;
	}

	if (xmlStrcmp(cur->name, (const xmlChar *) "domain")) {
		fprintf(stderr, "no domain?\n");
		xmlFreeDoc(doc);
		return -1;
	}

	devices = cur->xmlChildrenNode;
	for (devices = cur->xmlChildrenNode; devices != NULL;
	     devices = devices->next) {
		if (xmlStrcmp(devices->name, (const xmlChar *) "devices")) {
			continue;
		}

		for (child = devices->xmlChildrenNode; child != NULL;
		     child = child->next) {
			
			if ((!mode && xmlStrcmp(child->name, (const xmlChar *) "serial")) ||
			    (mode && xmlStrcmp(child->name, (const xmlChar *) "channel"))) {
				continue;
			}

			attr = xmlHasProp(child, (const xmlChar *)"type");
			if (attr == NULL)
				continue;

			if (xmlStrcmp(attr->children->content,
				      (const xmlChar *) "unix")) {
				continue;
			}

			for (serial = child->xmlChildrenNode; serial != NULL;
			     serial = serial->next) {
				if (xmlStrcmp(serial->name,
					      (const xmlChar *) "source")) {
					continue;
				}

				attr_mode = xmlHasProp(serial, (const xmlChar *)"mode");
				attr_path = xmlHasProp(serial, (const xmlChar *)"path");

				if (!attr_path || !attr_mode)
					continue;

				if (xmlStrcmp(attr_mode->children->content,
					      (const xmlChar *) "bind"))
					continue;

				if (path && !is_in_directory(path, (const char *)
							attr_path->children->content))
					continue;

				domain_sock_setup(dom_uuid, (const char *)
						  attr_path->children->content);
			}
		}
	}

	xmlFreeDoc(doc);
	return 0;
}
Beispiel #12
0
//!
//! Defines the thread that does the actual reboot of an instance.
//!
//! @param[in] arg a transparent pointer to the argument passed to this thread handler
//!
//! @return Always return NULL
//!
static void *rebooting_thread(void *arg)
{
    char *xml = NULL;
    char resourceName[1][MAX_SENSOR_NAME_LEN] = { "" };
    char resourceAlias[1][MAX_SENSOR_NAME_LEN] = { "" };
    //    ncInstance *instance = ((ncInstance *) arg);
    ncInstance *instance = NULL;
    struct nc_state_t *nc = NULL;
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;
    rebooting_thread_params *params = ((rebooting_thread_params *) arg);
    instance = &(params->instance);
    nc = &(params->nc);

    LOGDEBUG("[%s] spawning rebooting thread\n", instance->instanceId);

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    dom = virDomainLookupByName(conn, instance->instanceId);
    if (dom == NULL) {
        LOGERROR("[%s] cannot locate instance to reboot, giving up\n", instance->instanceId);
        unlock_hypervisor_conn();
        EUCA_FREE(params);
        return NULL;
    }
    // obtain the most up-to-date XML for domain from libvirt
    xml = virDomainGetXMLDesc(dom, 0);
    if (xml == NULL) {
        LOGERROR("[%s] cannot obtain metadata for instance to reboot, giving up\n", instance->instanceId);
        virDomainFree(dom);            // release libvirt resource
        unlock_hypervisor_conn();
        EUCA_FREE(params);
        return NULL;
    }
    virDomainFree(dom);                // release libvirt resource
    unlock_hypervisor_conn();

    // try shutdown first, then kill it if uncooperative
    if (shutdown_then_destroy_domain(instance->instanceId, TRUE) != EUCA_OK) {
        LOGERROR("[%s] failed to shutdown and destroy the instance to reboot, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    // Add a shift to values of three of the metrics: ones that
    // drop back to zero after a reboot. The shift, which is based
    // on the latest value, ensures that values sent upstream do
    // not go backwards .
    sensor_shift_metric(instance->instanceId, "CPUUtilization");
    sensor_shift_metric(instance->instanceId, "NetworkIn");
    sensor_shift_metric(instance->instanceId, "NetworkOut");

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    // domain is now shut down, create a new one with the same XML
    LOGINFO("[%s] rebooting\n", instance->instanceId);
    if (!strcmp(nc->pEucaNet->sMode, NETMODE_VPCMIDO)) {
        // need to sleep to allow midolman to update the VM interface
        sleep(10);
    }
    dom = virDomainCreateLinux(conn, xml, 0);
    if (dom == NULL) {
        LOGERROR("[%s] failed to restart instance\n", instance->instanceId);
        change_state(instance, SHUTOFF);
    } else {
        euca_strncpy(resourceName[0], instance->instanceId, MAX_SENSOR_NAME_LEN);
        sensor_refresh_resources(resourceName, resourceAlias, 1);   // refresh stats so we set base value accurately
        virDomainFree(dom);

        if (!strcmp(nc->pEucaNet->sMode, NETMODE_VPCMIDO)) {
            char iface[16], cmd[EUCA_MAX_PATH], obuf[256], ebuf[256], sPath[EUCA_MAX_PATH];
            int rc;
            snprintf(iface, 16, "vn_%s", instance->instanceId);
            
            // If this device does not have a 'brport' path, this isn't a bridge device
            snprintf(sPath, EUCA_MAX_PATH, "/sys/class/net/%s/brport/", iface);
            if (!check_directory(sPath)) {
                LOGDEBUG("[%s] removing instance interface %s from host bridge\n", instance->instanceId, iface);
                snprintf(cmd, EUCA_MAX_PATH, "%s brctl delif %s %s", nc->rootwrap_cmd_path, instance->params.guestNicDeviceName, iface);
                rc = timeshell(cmd, obuf, ebuf, 256, 10);
                if (rc) {
                    LOGERROR("unable to remove instance interface from bridge after launch: instance will not be able to connect to midonet (will not connect to network): check bridge/libvirt/kvm health\n");
                }
            }

            // Repeat process for secondary interfaces as well
            for (int i=0; i < EUCA_MAX_NICS; i++) {
                if (strlen(instance->secNetCfgs[i].interfaceId) == 0)
                    continue;

                snprintf(iface, 16, "vn_%s", instance->secNetCfgs[i].interfaceId);

                // If this device does not have a 'brport' path, this isn't a bridge device
                snprintf(sPath, EUCA_MAX_PATH, "/sys/class/net/%s/brport/", iface);
                if (!check_directory(sPath)) {
                    LOGDEBUG("[%s] removing instance interface %s from host bridge\n", instance->instanceId, iface);
                    snprintf(cmd, EUCA_MAX_PATH, "%s brctl delif %s %s", nc->rootwrap_cmd_path, instance->params.guestNicDeviceName, iface);
                    rc = timeshell(cmd, obuf, ebuf, 256, 10);
                    if (rc) {
                        LOGERROR("unable to remove instance interface from bridge after launch: instance will not be able to connect to midonet (will not connect to network): check bridge/libvirt/kvm health\n");
                    }
                }
            }
        }

    }
    EUCA_FREE(xml);

    unlock_hypervisor_conn();
    unset_corrid(get_corrid());
    EUCA_FREE(params);
    return NULL;
}
Beispiel #13
0
int startDomain(char *xml, char *uri)
{
	int id, tries, res = 0;
	char *port = NULL;
	char *xmldesc = NULL;
	virDomainPtr dp = NULL;

	if (cp == NULL) {
		cp = libvirtConnect(uri);
		if (cp == NULL) {
			DPRINTF("Connection to %s failed\n", uri);
			return -EIO;
		}
	}

	DPRINTF("Starting domain\n");
	dp = virDomainCreateXML(cp, xml, 0);
	if (dp == NULL) {
		DPRINTF("virDomainCreateXML call failed\n");
		DPRINTF("XML File data:\n%s\n", xml);
		return -EINVAL;
	}

	DPRINTF("Domain started\n");

	tries = 0;
	xmldesc = virDomainGetXMLDesc(dp, 0);
	if (xmldesc == NULL) {
		if (tries > 5) {
			DPRINTF("Cannot get domain XML description\n");
			virDomainFree(dp);
			return -EIO;
		}

		sleep(1);
		tries++;
	}

	port = xml_query(xmldesc, "//domain/devices/graphics/@port");
	free(xmldesc);

	if (port == NULL) {
		DPRINTF("Port lookup failed, node not accessible\n");
		virDomainFree(dp);
		return -ENOENT;
	}

	DPRINTF("Graphics port number: %s\n", port);

	id = virDomainGetID(dp);
	DPRINTF("Domain created with ID %d\n", id);
#ifdef USE_HACK
	if (startVNCViewer(NULL, NULL, 1) != VNC_STATUS_UNSUPPORTED) {
		char path[1024] = { 0 };
		char buf[2048] = { 0 };
		char cmd[4096] = { 0 };

		snprintf(path, sizeof(path), "/proc/%d/exe", getpid());
		readlink(path, buf, sizeof(buf));
		snprintf(cmd, sizeof(cmd), "%s -v localhost:%s -f -l console 2> /dev/null", buf, port);
		DPRINTF("About to run '%s'\n", cmd);
		res = WEXITSTATUS(system(cmd));
	}
	else
		res = VNC_STATUS_NO_CONNECTION;
#else
	res = startVNCViewer("localhost", port, 1);
#endif
	if (((virDomainIsActive(dp)) && (!domainIsOff))
		|| (res != VNC_STATUS_SHUTDOWN)) {
		DPRINTF("Domain is active, destroying...\n");
		virDomainDestroy(dp);
	}

	DPRINTF("Domain %d done.\n", id);
	virDomainFree(dp);

	DPRINTF("Returning with %d\n", lastErrorCode);
	return lastErrorCode;
}
Beispiel #14
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;
}
Beispiel #15
0
//!
//! Defines the thread that does the actual reboot of an instance.
//!
//! @param[in] arg a transparent pointer to the argument passed to this thread handler
//!
//! @return Always return NULL
//!
static void *rebooting_thread(void *arg)
{
    char *xml = NULL;
    char resourceName[1][MAX_SENSOR_NAME_LEN] = { "" };
    char resourceAlias[1][MAX_SENSOR_NAME_LEN] = { "" };
    ncInstance *instance = ((ncInstance *) arg);
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;

    LOGDEBUG("[%s] spawning rebooting thread\n", instance->instanceId);

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        return NULL;
    }
    dom = virDomainLookupByName(conn, instance->instanceId);
    if (dom == NULL) {
        LOGERROR("[%s] cannot locate instance to reboot, giving up\n", instance->instanceId);
        unlock_hypervisor_conn();
        return NULL;
    }
    // obtain the most up-to-date XML for domain from libvirt
    xml = virDomainGetXMLDesc(dom, 0);
    if (xml == NULL) {
        LOGERROR("[%s] cannot obtain metadata for instance to reboot, giving up\n", instance->instanceId);
        virDomainFree(dom);            // release libvirt resource
        unlock_hypervisor_conn();
        return NULL;
    }
    virDomainFree(dom);                // release libvirt resource
    unlock_hypervisor_conn();

    // try shutdown first, then kill it if uncooperative
    if (shutdown_then_destroy_domain(instance->instanceId, TRUE) != EUCA_OK) {
        LOGERROR("[%s] failed to shutdown and destroy the instance to reboot, giving up\n", instance->instanceId);
        return NULL;
    }
    // Add a shift to values of three of the metrics: ones that
    // drop back to zero after a reboot. The shift, which is based
    // on the latest value, ensures that values sent upstream do
    // not go backwards .
    sensor_shift_metric(instance->instanceId, "CPUUtilization");
    sensor_shift_metric(instance->instanceId, "NetworkIn");
    sensor_shift_metric(instance->instanceId, "NetworkOut");

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        return NULL;
    }
    // domain is now shut down, create a new one with the same XML
    LOGINFO("[%s] rebooting\n", instance->instanceId);
    dom = virDomainCreateLinux(conn, xml, 0);
    if (dom == NULL) {
        LOGERROR("[%s] failed to restart instance\n", instance->instanceId);
        change_state(instance, SHUTOFF);
    } else {
        euca_strncpy(resourceName[0], instance->instanceId, MAX_SENSOR_NAME_LEN);
        sensor_refresh_resources(resourceName, resourceAlias, 1);   // refresh stats so we set base value accurately
        virDomainFree(dom);
    }
    EUCA_FREE(xml);

    unlock_hypervisor_conn();
    unset_corrid(get_corrid());
    return NULL;
}