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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list