Use the "kern.proc.pid" sysctl and retrieve information from the
kinfo_proc struct.

Signed-off-by: Roman Bogorodskiy <bogorods...@gmail.com>
---
 src/util/virprocess.c | 104 +++++++++++++++++++++++++++++++-----------
 1 file changed, 78 insertions(+), 26 deletions(-)

diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 05db76d834..3889ba90f9 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -1812,7 +1812,85 @@ virProcessGetStatInfo(unsigned long long *cpuTime,
 
     return 0;
 }
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+int
+virProcessGetStatInfo(unsigned long long *cpuTime,
+                      unsigned long long *userTime,
+                      unsigned long long *sysTime,
+                      int *lastCpu,
+                      unsigned long long *vm_rss,
+                      pid_t pid,
+                      pid_t tid)
+{
+    struct kinfo_proc p;
+    int mib[4];
+    size_t len = 4;
+    unsigned long long utime = 0;
+    unsigned long long stime = 0;
+    unsigned long long rss = 0;
+    int cpu = 0;
+    const long pagesize = virGetSystemPageSizeKB();
+
+    sysctlnametomib("kern.proc.pid", mib, &len);
+
+    len = sizeof(struct kinfo_proc);
+    mib[3] = pid;
+
+    if (sysctl(mib, 4, &p, &len, NULL, 0) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Unable to query process stats"));
+        return -1;
+    }
+
+    utime = p.ki_rusage.ru_utime.tv_sec;
+    stime = p.ki_rusage.ru_stime.tv_sec;
+    rss = p.ki_rssize * pagesize;
+    cpu = p.ki_lastcpu_old;
+
+    if (cpuTime)
+        *cpuTime = utime + stime;
+    if (userTime)
+        *userTime = utime;
+    if (sysTime)
+        *sysTime = stime;
+    if (lastCpu)
+        *lastCpu = cpu;
+    if (vm_rss)
+        *vm_rss = rss;
+
+    VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%lld",
+              (int) pid, tid, utime, stime, cpu, rss);
+
+    return 0;
+}
+#else
+int
+virProcessGetStatInfo(unsigned long long *cpuTime,
+                      unsigned long long *userTime,
+                      unsigned long long *sysTime,
+                      int *lastCpu,
+                      unsigned long long *vm_rss,
+                      pid_t pid G_GNUC_UNUSED,
+                      pid_t tid G_GNUC_UNUSED)
+{
+    /* We don't have a way to collect this information on non-Linux
+     * platforms, so just report neutral values */
+    if (cpuTime)
+        *cpuTime = 0;
+    if (userTime)
+        *userTime = 0;
+    if (sysTime)
+        *sysTime = 0;
+    if (lastCpu)
+        *lastCpu = 0;
+    if (vm_rss)
+        *vm_rss = 0;
+
+    return 0;
+}
+#endif
 
+#ifdef __linux__
 int
 virProcessGetSchedInfo(unsigned long long *cpuWait,
                        pid_t pid,
@@ -1879,33 +1957,7 @@ virProcessGetSchedInfo(unsigned long long *cpuWait,
 
     return 0;
 }
-
 #else
-int
-virProcessGetStatInfo(unsigned long long *cpuTime,
-                      unsigned long long *userTime,
-                      unsigned long long *sysTime,
-                      int *lastCpu,
-                      unsigned long long *vm_rss,
-                      pid_t pid G_GNUC_UNUSED,
-                      pid_t tid G_GNUC_UNUSED)
-{
-    /* We don't have a way to collect this information on non-Linux
-     * platforms, so just report neutral values */
-    if (cpuTime)
-        *cpuTime = 0;
-    if (userTime)
-        *userTime = 0;
-    if (sysTime)
-        *sysTime = 0;
-    if (lastCpu)
-        *lastCpu = 0;
-    if (vm_rss)
-        *vm_rss = 0;
-
-    return 0;
-}
-
 int
 virProcessGetSchedInfo(unsigned long long *cpuWait,
                        pid_t pid G_GNUC_UNUSED,
-- 
2.49.0

Reply via email to