qemuGetSchedInfo is more likely a process utility function, just rename it to virProcessGetSchedInfo and move it to virprocess.c source file. --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 78 +----------------------------------------------- src/util/virprocess.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/virprocess.h | 2 ++ 4 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3681869..7f468dc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2381,6 +2381,7 @@ virProcessGetAffinity; virProcessGetMaxMemLock; virProcessGetNamespaces; virProcessGetPids; +virProcessGetSchedInfo; virProcessGetStartTime; virProcessGetStat; virProcessKill; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a4aa5da..9e2fb7e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1302,82 +1302,6 @@ static char *qemuConnectGetCapabilities(virConnectPtr conn) { return xml; } - -static int -qemuGetSchedInfo(unsigned long long *cpuWait, - pid_t pid, pid_t tid) -{ - char *proc = NULL; - char *data = NULL; - char **lines = NULL; - size_t i; - int ret = -1; - double val; - - *cpuWait = 0; - - /* In general, we cannot assume pid_t fits in int; but /proc parsing - * is specific to Linux where int works fine. */ - if (tid) - ret = virAsprintf(&proc, "/proc/%d/task/%d/sched", (int)pid, (int)tid); - else - ret = virAsprintf(&proc, "/proc/%d/sched", (int)pid); - if (ret < 0) - goto cleanup; - ret = -1; - - /* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */ - if (access(proc, R_OK) < 0) { - ret = 0; - goto cleanup; - } - - if (virFileReadAll(proc, (1<<16), &data) < 0) - goto cleanup; - - lines = virStringSplit(data, "\n", 0); - if (!lines) - goto cleanup; - - for (i = 0; lines[i] != NULL; i++) { - const char *line = lines[i]; - - /* Needs CONFIG_SCHEDSTATS. The second check - * is the old name the kernel used in past */ - if (STRPREFIX(line, "se.statistics.wait_sum") || - STRPREFIX(line, "se.wait_sum")) { - line = strchr(line, ':'); - if (!line) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Missing separator in sched info '%s'"), - lines[i]); - goto cleanup; - } - line++; - while (*line == ' ') - line++; - - if (virStrToDouble(line, NULL, &val) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unable to parse sched info value '%s'"), - line); - goto cleanup; - } - - *cpuWait = (unsigned long long)(val * 1000000); - break; - } - } - - ret = 0; - - cleanup: - VIR_FREE(data); - VIR_FREE(proc); - virStringListFree(lines); - return ret; -} - static int qemuDomainHelperGetVcpus(virDomainObjPtr vm, virVcpuInfoPtr info, @@ -1441,7 +1365,7 @@ qemuDomainHelperGetVcpus(virDomainObjPtr vm, } if (cpuwait) { - if (qemuGetSchedInfo(&(cpuwait[ncpuinfo]), vm->pid, vcpupid) < 0) + if (virProcessGetSchedInfo(vm->pid, vcpupid, &(cpuwait[ncpuinfo])) < 0) return -1; } diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 98f4b25..67e8cef 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1488,3 +1488,78 @@ virProcessGetStat(pid_t pid, int tid, return 0; } + +int +virProcessGetSchedInfo(pid_t pid, int tid, + unsigned long long *cpuWait) +{ + char *proc = NULL; + char *data = NULL; + char **lines = NULL; + size_t i; + int ret = -1; + double val; + + *cpuWait = 0; + + /* In general, we cannot assume pid_t fits in int; but /proc parsing + * is specific to Linux where int works fine. */ + if (tid) + ret = virAsprintf(&proc, "/proc/%d/task/%d/sched", (int)pid, (int)tid); + else + ret = virAsprintf(&proc, "/proc/%d/sched", (int)pid); + if (ret < 0) + goto cleanup; + ret = -1; + + /* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */ + if (access(proc, R_OK) < 0) { + ret = 0; + goto cleanup; + } + + if (virFileReadAll(proc, (1<<16), &data) < 0) + goto cleanup; + + lines = virStringSplit(data, "\n", 0); + if (!lines) + goto cleanup; + + for (i = 0; lines[i] != NULL; i++) { + const char *line = lines[i]; + + /* Needs CONFIG_SCHEDSTATS. The second check + * is the old name the kernel used in past */ + if (STRPREFIX(line, "se.statistics.wait_sum") || + STRPREFIX(line, "se.wait_sum")) { + line = strchr(line, ':'); + if (!line) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing separator in sched info '%s'"), + lines[i]); + goto cleanup; + } + line++; + while (*line == ' ') + line++; + + if (virStrToDouble(line, NULL, &val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse sched info value '%s'"), + line); + goto cleanup; + } + + *cpuWait = (unsigned long long)(val * 1000000); + break; + } + } + + ret = 0; + + cleanup: + VIR_FREE(data); + VIR_FREE(proc); + virStringListFree(lines); + return ret; +} diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 2a2b91d..ac80750 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -109,5 +109,7 @@ int virProcessNamespaceAvailable(unsigned int ns); int virProcessGetStat(pid_t pid, int tid, unsigned long long *cpuTime, int *lastCpu, long *vm_rss); +int virProcessGetSchedInfo(pid_t pid, int tid, + unsigned long long *cpuWait); #endif /* __VIR_PROCESS_H__ */ -- 2.8.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list