mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 20:45:18 +00:00
Fill in vCPU <-> pCPU current mapping, and vCPU cpuTime for QEMU
* src/qemu_driver.c: implement missing features in qemudDomainGetVcpus for 'cpu' and 'cpuTime' fields
This commit is contained in:
parent
85453c4247
commit
c4a04dc024
@ -2541,24 +2541,44 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
|
static int qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, int pid, int tid) {
|
||||||
char proc[PATH_MAX];
|
char proc[PATH_MAX];
|
||||||
FILE *pidinfo;
|
FILE *pidinfo;
|
||||||
unsigned long long usertime, systime;
|
unsigned long long usertime, systime;
|
||||||
|
int cpu;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (snprintf(proc, sizeof(proc), "/proc/%d/stat", pid) >= (int)sizeof(proc)) {
|
if (tid)
|
||||||
|
ret = snprintf(proc, sizeof(proc), "/proc/%d/task/%d/stat", pid, tid);
|
||||||
|
else
|
||||||
|
ret = snprintf(proc, sizeof(proc), "/proc/%d/stat", pid);
|
||||||
|
if (ret >= (int)sizeof(proc)) {
|
||||||
|
errno = E2BIG;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pidinfo = fopen(proc, "r"))) {
|
if (!(pidinfo = fopen(proc, "r"))) {
|
||||||
/*printf("cannot read pid info");*/
|
/*printf("cannot read pid info");*/
|
||||||
/* VM probably shut down, so fake 0 */
|
/* VM probably shut down, so fake 0 */
|
||||||
*cpuTime = 0;
|
if (cpuTime)
|
||||||
|
*cpuTime = 0;
|
||||||
|
if (lastCpu)
|
||||||
|
*lastCpu = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fscanf(pidinfo, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu", &usertime, &systime) != 2) {
|
/* See 'man proc' for information about what all these fields are. We're
|
||||||
qemudDebug("not enough arg");
|
* only interested in a very few of them */
|
||||||
|
if (fscanf(pidinfo,
|
||||||
|
/* pid -> stime */
|
||||||
|
"%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu"
|
||||||
|
/* cutime -> endcode */
|
||||||
|
"%*d %*d %*d %*d %*d %*u %*u %*d %*u %*u %*u %*u"
|
||||||
|
/* startstack -> processor */
|
||||||
|
"%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
|
||||||
|
&usertime, &systime, &cpu) != 3) {
|
||||||
|
VIR_WARN0("cannot parse process status data");
|
||||||
|
errno = -EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2567,9 +2587,14 @@ static int qemudGetProcessInfo(unsigned long long *cpuTime, int pid) {
|
|||||||
* _SC_CLK_TCK is jiffies per second
|
* _SC_CLK_TCK is jiffies per second
|
||||||
* So calulate thus....
|
* So calulate thus....
|
||||||
*/
|
*/
|
||||||
*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime) / (unsigned long long)sysconf(_SC_CLK_TCK);
|
if (cpuTime)
|
||||||
|
*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime) / (unsigned long long)sysconf(_SC_CLK_TCK);
|
||||||
|
if (lastCpu)
|
||||||
|
*lastCpu = cpu;
|
||||||
|
|
||||||
qemudDebug("Got %llu %llu %llu", usertime, systime, *cpuTime);
|
|
||||||
|
VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d",
|
||||||
|
pid, tid, usertime, systime, cpu);
|
||||||
|
|
||||||
fclose(pidinfo);
|
fclose(pidinfo);
|
||||||
|
|
||||||
@ -3209,7 +3234,7 @@ static int qemudDomainGetInfo(virDomainPtr dom,
|
|||||||
if (!virDomainIsActive(vm)) {
|
if (!virDomainIsActive(vm)) {
|
||||||
info->cpuTime = 0;
|
info->cpuTime = 0;
|
||||||
} else {
|
} else {
|
||||||
if (qemudGetProcessInfo(&(info->cpuTime), vm->pid) < 0) {
|
if (qemudGetProcessInfo(&(info->cpuTime), NULL, vm->pid, 0) < 0) {
|
||||||
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, ("cannot read cputime for domain"));
|
qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, ("cannot read cputime for domain"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -3752,7 +3777,16 @@ qemudDomainGetVcpus(virDomainPtr dom,
|
|||||||
for (i = 0 ; i < maxinfo ; i++) {
|
for (i = 0 ; i < maxinfo ; i++) {
|
||||||
info[i].number = i;
|
info[i].number = i;
|
||||||
info[i].state = VIR_VCPU_RUNNING;
|
info[i].state = VIR_VCPU_RUNNING;
|
||||||
/* XXX cpu time, current pCPU mapping */
|
|
||||||
|
if (vm->vcpupids != NULL &&
|
||||||
|
qemudGetProcessInfo(&(info[i].cpuTime),
|
||||||
|
&(info[i].cpu),
|
||||||
|
vm->pid,
|
||||||
|
vm->vcpupids[i]) < 0) {
|
||||||
|
virReportSystemError(dom->conn, errno, "%s",
|
||||||
|
_("cannot get vCPU placement & pCPU time"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user