Add a helper function virBhyveGetDomainTotalCpuStats() to
obtain process CPU time using kvm (kernel memory interface)
and use it to set cpuTime field of the virDomainInfo struct in
bhyveDomainGetInfo().
---
configure.ac | 7 +++++++
src/bhyve/bhyve_driver.c | 9 +++++++++
src/bhyve/bhyve_process.c | 40 ++++++++++++++++++++++++++++++++++++++++
src/bhyve/bhyve_process.h | 3 +++
4 files changed, 59 insertions(+)
diff --git a/configure.ac b/configure.ac
index 12338d4..2e5fa1a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2684,6 +2684,13 @@ AC_CHECK_DECLS([cpuset_getaffinity],
#include <sys/cpuset.h>
])
+# Check for BSD kvm (kernel memory interface)
+if test $with_freebsd = yes; then
+ AC_CHECK_LIB([kvm], [kvm_getprocs], [],
+ [AC_MSG_ERROR([BSD kernel memory interface library is required to build
on FreeBSD])]
+ )
+fi
+
# Check if we need to look for ifconfig
if test "$want_ifconfig" = "yes"; then
AC_PATH_PROG([IFCONFIG_PATH], [ifconfig])
diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 6d681fd..0780e74 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -268,6 +268,15 @@ bhyveDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
if (virDomainGetInfoEnsureACL(domain->conn, vm->def) < 0)
goto cleanup;
+ if (virDomainObjIsActive(vm)) {
+ if (virBhyveGetDomainTotalCpuStats(vm, &(info->cpuTime)) < 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("Cannot read cputime for
domain"));
+ goto cleanup;
+ }
+ } else
+ info->cpuTime = 0;
+
info->state = virDomainObjGetState(vm, NULL);
info->maxMem = vm->def->mem.max_balloon;
info->nrVirtCpu = vm->def->vcpus;
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index a557bc5..b6f0f2c 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -22,7 +22,11 @@
#include <config.h>
#include <fcntl.h>
+#include <kvm.h>
+#include <sys/param.h>
#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_tap.h>
@@ -246,3 +250,39 @@ virBhyveProcessStop(bhyveConnPtr driver,
virCommandFree(cmd);
return ret;
}
+
+int
+virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm,
+ unsigned long long *cpustats)
+{
+ struct kinfo_proc *kp;
+ kvm_t *kd;
+ char errbuf[_POSIX2_LINE_MAX];
+ int nprocs;
+ int ret = -1;
+
+ if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Unable to get kvm descriptor: %s"),
+ errbuf);
+ return -1;
+
+ }
+
+ kp = kvm_getprocs(kd, KERN_PROC_PID, vm->pid, &nprocs);
+ if (kp == NULL || nprocs != 1) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Unable to obtain information about pid: %d"),
+ (int)vm->pid);
+ goto cleanup;
+ }
+
+ *cpustats = kp->ki_runtime * 1000ull;
+
+ ret = 0;
+
+ cleanup:
+ kvm_close(kd);
+
+ return ret;
+}
diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h
index f91504e..3049ad0 100644
--- a/src/bhyve/bhyve_process.h
+++ b/src/bhyve/bhyve_process.h
@@ -34,6 +34,9 @@ int virBhyveProcessStop(bhyveConnPtr driver,
virDomainObjPtr vm,
virDomainShutoffReason reason);
+int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm,
+ unsigned long long *cpustats);
+
typedef enum {
VIR_BHYVE_PROCESS_START_AUTODESTROY = 1 << 0,
} bhyveProcessStartFlags;
--
1.9.0