mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-08 22:15:21 +00:00
Use virProcessGetStat
This eliminates one incorrect parsing implementation which relied on the command field not having a closing bracket. This possibility is already tested against in the virProcessGetStat() tests. Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
e370d4056b
commit
edd1fd8ca9
@ -1399,36 +1399,18 @@ qemuGetSchedInfo(unsigned long long *cpuWait,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
|
qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
|
||||||
pid_t pid, int tid)
|
pid_t pid, pid_t tid)
|
||||||
{
|
{
|
||||||
g_autofree char *proc = NULL;
|
g_auto(GStrv) proc_stat = virProcessGetStat(pid, tid);
|
||||||
FILE *pidinfo;
|
|
||||||
unsigned long long usertime = 0, systime = 0;
|
unsigned long long usertime = 0, systime = 0;
|
||||||
long rss = 0;
|
long rss = 0;
|
||||||
int cpu = 0;
|
int cpu = 0;
|
||||||
|
|
||||||
/* In general, we cannot assume pid_t fits in int; but /proc parsing
|
if (!proc_stat ||
|
||||||
* is specific to Linux where int works fine. */
|
virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_UTIME], NULL, 10, &usertime) < 0 ||
|
||||||
if (tid)
|
virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_STIME], NULL, 10, &systime) < 0 ||
|
||||||
proc = g_strdup_printf("/proc/%d/task/%d/stat", (int)pid, tid);
|
virStrToLong_l(proc_stat[VIR_PROCESS_STAT_RSS], NULL, 10, &rss) < 0 ||
|
||||||
else
|
virStrToLong_i(proc_stat[VIR_PROCESS_STAT_PROCESSOR], NULL, 10, &cpu) < 0) {
|
||||||
proc = g_strdup_printf("/proc/%d/stat", (int)pid);
|
|
||||||
if (!proc)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
pidinfo = fopen(proc, "r");
|
|
||||||
|
|
||||||
/* See 'man proc' for information about what all these fields are. We're
|
|
||||||
* only interested in a very few of them */
|
|
||||||
if (!pidinfo ||
|
|
||||||
fscanf(pidinfo,
|
|
||||||
/* pid -> stime */
|
|
||||||
"%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %llu %llu"
|
|
||||||
/* cutime -> endcode */
|
|
||||||
"%*d %*d %*d %*d %*d %*d %*u %*u %ld %*u %*u %*u"
|
|
||||||
/* startstack -> processor */
|
|
||||||
"%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d",
|
|
||||||
&usertime, &systime, &rss, &cpu) != 4) {
|
|
||||||
VIR_WARN("cannot parse process status data");
|
VIR_WARN("cannot parse process status data");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,8 +1432,6 @@ qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
|
|||||||
VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
|
VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
|
||||||
(int)pid, tid, usertime, systime, cpu, rss);
|
(int)pid, tid, usertime, systime, cpu, rss);
|
||||||
|
|
||||||
VIR_FORCE_FCLOSE(pidinfo);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1153,56 +1153,22 @@ virProcessSetMaxCoreSize(pid_t pid G_GNUC_UNUSED,
|
|||||||
int virProcessGetStartTime(pid_t pid,
|
int virProcessGetStartTime(pid_t pid,
|
||||||
unsigned long long *timestamp)
|
unsigned long long *timestamp)
|
||||||
{
|
{
|
||||||
char *tmp;
|
g_auto(GStrv) proc_stat = virProcessGetStat(pid, 0);
|
||||||
int len;
|
const char *starttime_str = NULL;
|
||||||
g_autofree char *filename = NULL;
|
|
||||||
g_autofree char *buf = NULL;
|
|
||||||
g_auto(GStrv) tokens = NULL;
|
|
||||||
|
|
||||||
filename = g_strdup_printf("/proc/%llu/stat", (long long)pid);
|
if (!proc_stat || g_strv_length(proc_stat) < 22) {
|
||||||
|
|
||||||
if ((len = virFileReadAll(filename, 1024, &buf)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* start time is the token at index 19 after the '(process name)' entry - since only this
|
|
||||||
* field can contain the ')' character, search backwards for this to avoid malicious
|
|
||||||
* processes trying to fool us
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!(tmp = strrchr(buf, ')'))) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Cannot find start time in %s"),
|
_("Cannot find start time for pid %d"), (int)pid);
|
||||||
filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tmp += 2; /* skip ') ' */
|
|
||||||
if ((tmp - buf) >= len) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Cannot find start time in %s"),
|
|
||||||
filename);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens = g_strsplit(tmp, " ", 0);
|
starttime_str = proc_stat[VIR_PROCESS_STAT_STARTTIME];
|
||||||
|
if (virStrToLong_ull(starttime_str, NULL, 10, timestamp) < 0) {
|
||||||
if (!tokens ||
|
|
||||||
g_strv_length(tokens) < 20) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Cannot find start time in %s"),
|
_("Cannot parse start time %s for pid %d"),
|
||||||
filename);
|
starttime_str, (int)pid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virStrToLong_ull(tokens[19],
|
|
||||||
NULL,
|
|
||||||
10,
|
|
||||||
timestamp) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Cannot parse start time %s in %s"),
|
|
||||||
tokens[19], filename);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
|
Loading…
Reference in New Issue
Block a user