diff --git a/configure.ac b/configure.ac index fef99af9c2..7ab4ce7c60 100644 --- a/configure.ac +++ b/configure.ac @@ -2684,6 +2684,13 @@ AC_CHECK_DECLS([cpuset_getaffinity], #include ]) +# 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 fe17833767..67571d2a40 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -269,6 +269,13 @@ bhyveDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) if (virDomainGetInfoEnsureACL(domain->conn, vm->def) < 0) goto cleanup; + if (virDomainObjIsActive(vm)) { + if (virBhyveGetDomainTotalCpuStats(vm, &(info->cpuTime)) < 0) + 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 855d175284..9f02a4910a 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -22,7 +22,11 @@ #include #include +#include +#include #include +#include +#include #include #include #include @@ -248,3 +252,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 f91504ee26..3049ad0cb4 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;