static int showDomains(virConnectPtr conn) { int ret = 0, numNames, numInactiveDomains, numActiveDomains; ssize_t i; int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | VIR_CONNECT_LIST_DOMAINS_INACTIVE; virDomainPtr *nameList = NULL; /* NB: The return from the virConnectNum*() APIs is only useful for * the current call. A domain could be started or stopped and any * assumptions made purely on these return values could result in * unexpected results */ numActiveDomains = virConnectNumOfDomains(conn); if (numActiveDomains == -1) { ret = 1; printf("Failed to get number of active domains: %s\n", virGetLastErrorMessage()); goto out; } numInactiveDomains = virConnectNumOfDefinedDomains(conn); if (numInactiveDomains == -1) { ret = 1; printf("Failed to get number of inactive domains: %s\n", virGetLastErrorMessage()); goto out; } printf("There are %d active and %d inactive domains\n", numActiveDomains, numInactiveDomains); /* Return a list of all active and inactive domains. Using this API * instead of virConnectListDomains() and virConnectListDefinedDomains() * is preferred since it "solves" an inherit race between separated API * calls if domains are started or stopped between calls */ numNames = virConnectListAllDomains(conn, &nameList, flags); if (numNames == -1) { ret = 1; printf("Failed to get a list of all domains: %s\n", virGetLastErrorMessage()); goto out; } for (i = 0; i < numNames; i++) { int active = virDomainIsActive(nameList[i]); printf(" %8s (%s)\n", virDomainGetName(nameList[i]), (active == 1 ? "active" : "non-active")); /* must free the returned named per the API documentation */ virDomainFree(nameList[i]); } free(nameList); out: return ret; }
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(); }
int ConnAliveThread::domEventCallback(virConnectPtr _conn, virDomainPtr dom, int event, int detail, void *opaque) { //qDebug()<<"domEventCallback"<<_conn; ConnAliveThread *obj = static_cast<ConnAliveThread*>(opaque); if ( NULL==obj || *(obj->ptr_ConnPtr)!=_conn ) return 0; bool end = false; QString msg, domainName; domainName = QString(virDomainGetName(dom)); msg = QString("<b>'%1'</b> Domain %2 %3\n") .arg(domainName) .arg(obj->domEventToString(event)) .arg(obj->domEventDetailToString(event, detail, &end)); if ( end ) emit obj->domainEnd(domainName); emit obj->connMsg(msg); if ( obj->onView ) { Result result; QStringList domainList; if ( _conn!=NULL && obj->keep_alive ) { virDomainPtr *domains = NULL; unsigned int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | VIR_CONNECT_LIST_DOMAINS_INACTIVE; // the number of domains found or -1 and sets domains to NULL in case of error. int ret = virConnectListAllDomains(_conn, &domains, flags); if ( ret<0 ) { obj->sendConnErrors(); return 0; }; // therefore correctly to use for() command, because domains[0] can not exist. for (int i = 0; i < ret; i++) { QStringList currentAttr; QString autostartStr; int is_autostart = 0; if (virDomainGetAutostart(domains[i], &is_autostart) < 0) { autostartStr.append("no autostart"); } else autostartStr.append( is_autostart ? "yes" : "no" ); int state; int reason; // flags : extra flags; not used yet, so callers should always pass 0 flags = 0; QString domainState; if ( virDomainGetState(domains[i], &state, &reason, flags)+1 ) { switch (state) { case VIR_DOMAIN_NOSTATE: domainState.append("NOSTATE"); break; case VIR_DOMAIN_RUNNING: domainState.append("RUNNING"); break; case VIR_DOMAIN_BLOCKED: domainState.append("BLOCKED"); break; case VIR_DOMAIN_PAUSED: domainState.append("PAUSED"); break; case VIR_DOMAIN_SHUTDOWN: domainState.append("SHUTDOWN"); break; case VIR_DOMAIN_SHUTOFF: domainState.append("SHUTOFF"); break; case VIR_DOMAIN_CRASHED: domainState.append("CRASHED"); break; case VIR_DOMAIN_PMSUSPENDED: domainState.append("PMSUSPENDED"); break; default: domainState.append("UNKNOWN"); break; } } else domainState.append("ERROR"); currentAttr<< QString().fromUtf8( virDomainGetName(domains[i]) ) << QString("%1:%2") .arg( virDomainIsActive(domains[i]) ? "active" : "inactive" ) .arg(domainState) << autostartStr << QString( virDomainIsPersistent(domains[i]) ? "yes" : "no" ); domainList.append(currentAttr.join(DFR)); virDomainFree(domains[i]); }; free(domains); }; //result.name = ; result.type = "domain"; //result.number = number; result.action = GET_ALL_ENTITY_STATE; result.result = true; result.msg = domainList; emit obj->domStateChanged(result); }; return 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; }
int main(int argc, char **argv) { virConfPtr conf = NULL; const char *login_shell_path = conf_file; pid_t cpid = -1; int ret = EXIT_CANCELED; int status; uid_t uid = getuid(); gid_t gid = getgid(); char *name = NULL; char **shargv = NULL; virSecurityModelPtr secmodel = NULL; virSecurityLabelPtr seclabel = NULL; virDomainPtr dom = NULL; virConnectPtr conn = NULL; char *homedir = NULL; int arg; int longindex = -1; int ngroups; gid_t *groups = NULL; ssize_t nfdlist = 0; int *fdlist = NULL; int openmax; size_t i; struct option opt[] = { {"help", no_argument, NULL, 'h'}, {"version", optional_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; if (virInitialize() < 0) { fprintf(stderr, _("Failed to initialize libvirt error handling")); return EXIT_CANCELED; } setenv("PATH", "/bin:/usr/bin", 1); virSetErrorFunc(NULL, NULL); virSetErrorLogPriorityFunc(NULL); progname = argv[0]; if (!setlocale(LC_ALL, "")) { perror("setlocale"); /* failure to setup locale is not fatal */ } if (!bindtextdomain(PACKAGE, LOCALEDIR)) { perror("bindtextdomain"); return ret; } if (!textdomain(PACKAGE)) { perror("textdomain"); return ret; } while ((arg = getopt_long(argc, argv, "hV", opt, &longindex)) != -1) { switch (arg) { case 'h': usage(); exit(EXIT_SUCCESS); case 'V': show_version(); exit(EXIT_SUCCESS); case '?': default: usage(); exit(EXIT_CANCELED); } } if (argc > optind) { virReportSystemError(EINVAL, _("%s takes no options"), progname); goto cleanup; } if (uid == 0) { virReportSystemError(EPERM, _("%s must be run by non root users"), progname); goto cleanup; } name = virGetUserName(uid); if (!name) goto cleanup; homedir = virGetUserDirectoryByUID(uid); if (!homedir) goto cleanup; if (!(conf = virConfReadFile(login_shell_path, 0))) goto cleanup; if ((ngroups = virGetGroupList(uid, gid, &groups)) < 0) goto cleanup; if (virLoginShellAllowedUser(conf, name, groups) < 0) goto cleanup; if (!(shargv = virLoginShellGetShellArgv(conf))) goto cleanup; conn = virConnectOpen("lxc:///"); if (!conn) goto cleanup; dom = virDomainLookupByName(conn, name); if (!dom) goto cleanup; if (!virDomainIsActive(dom) && virDomainCreate(dom)) { virErrorPtr last_error; last_error = virGetLastError(); if (last_error->code != VIR_ERR_OPERATION_INVALID) { virReportSystemError(last_error->code, _("Can't create %s container: %s"), name, last_error->message); goto cleanup; } } openmax = sysconf(_SC_OPEN_MAX); if (openmax < 0) { virReportSystemError(errno, "%s", _("sysconf(_SC_OPEN_MAX) failed")); goto cleanup; } if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0) goto cleanup; if (VIR_ALLOC(secmodel) < 0) goto cleanup; if (VIR_ALLOC(seclabel) < 0) goto cleanup; if (virNodeGetSecurityModel(conn, secmodel) < 0) goto cleanup; if (virDomainGetSecurityLabel(dom, seclabel) < 0) goto cleanup; if (virSetUIDGID(0, 0, NULL, 0) < 0) goto cleanup; if (virDomainLxcEnterSecurityLabel(secmodel, seclabel, NULL, 0) < 0) goto cleanup; if (nfdlist > 0 && virDomainLxcEnterNamespace(dom, nfdlist, fdlist, NULL, NULL, 0) < 0) goto cleanup; if (virSetUIDGID(uid, gid, groups, ngroups) < 0) goto cleanup; if (chdir(homedir) < 0) { virReportSystemError(errno, _("Unable to chdir(%s)"), homedir); goto cleanup; } /* A fork is required to create new process in correct pid namespace. */ if ((cpid = virFork()) < 0) goto cleanup; if (cpid == 0) { int tmpfd; for (i = 3; i < openmax; i++) { tmpfd = i; VIR_MASS_CLOSE(tmpfd); } if (execv(shargv[0], (char *const*) shargv) < 0) { virReportSystemError(errno, _("Unable to exec shell %s"), shargv[0]); virDispatchError(NULL); return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE; } } /* At this point, the parent is now waiting for the child to exit, * but as that may take a long time, we release resources now. */ cleanup: if (nfdlist > 0) for (i = 0; i < nfdlist; i++) VIR_FORCE_CLOSE(fdlist[i]); VIR_FREE(fdlist); virConfFree(conf); if (dom) virDomainFree(dom); if (conn) virConnectClose(conn); virStringFreeList(shargv); VIR_FREE(name); VIR_FREE(homedir); VIR_FREE(seclabel); VIR_FREE(secmodel); VIR_FREE(groups); if (virProcessWait(cpid, &status, true) == 0) virProcessExitWithStatus(status); if (virGetLastError()) virDispatchError(NULL); return ret; }