This is an attempt to fix: https://bugzilla.redhat.com/show_bug.cgi?id=812911 Calculate vm uptime by subtracting process starttime from system uptime: Almost equivalent to: echo $(($(($(awk '{print $1}' /proc/uptime)*1e9 - $(($(cut -d " " -f22 /proc/$PID/stat)*1e7))))/(1.0 * 1e9))) --- include/libvirt/libvirt-domain.h | 1 + src/qemu/qemu_driver.c | 32 +++++++++++++++++++++++++------- src/remote/remote_protocol.x | 1 + src/remote_protocol-structs | 1 + tools/virsh-domain-monitor.c | 8 ++++++++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 7be4219..2df0241 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -275,6 +275,7 @@ struct _virDomainInfo { unsigned long memory; /* the memory in KBytes used by the domain */ unsigned short nrVirtCpu; /* the number of virtual CPUs for the domain */ unsigned long long cpuTime; /* the CPU time used in nanoseconds */ + unsigned long long upTime; /* the total uptime in nanoseconds */ }; /** diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f07e4fb..0b5098f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1309,11 +1309,12 @@ static char *qemuConnectGetCapabilities(virConnectPtr conn) { static int qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, - pid_t pid, int tid) + pid_t pid, int tid, unsigned long long *upTime) { char *proc; FILE *pidinfo; - unsigned long long usertime = 0, systime = 0; + unsigned long long usertime = 0, systime = 0, starttime = 0; + double _uptime; long rss = 0; int cpu = 0; int ret; @@ -1337,13 +1338,29 @@ qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, /* pid -> stime */ "%*d %*s %*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" + "%*d %*d %*d %*d %*d %*d %llu %*u %ld %*u %*u %*u" /* startstack -> processor */ "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*d %d", - &usertime, &systime, &rss, &cpu) != 4) { + &usertime, &systime, &starttime, &rss, &cpu) != 5) { VIR_WARN("cannot parse process status data"); } + ret = virAsprintf(&proc, "/proc/uptime"); + if (ret < 0) + return -1; + + pidinfo = fopen(proc, "r"); + VIR_FREE(proc); + + if (!pidinfo || fscanf(pidinfo, "%lf %*f", &_uptime) != 1) { + VIR_WARN("cannot parse machine uptime data"); + } + + if (upTime) + *upTime = 1000ull * 1000ull * 1000ull * _uptime - + (1000ull * 1000ull * 1000ull * starttime) + / (unsigned long long)sysconf(_SC_CLK_TCK); + /* We got jiffies * We want nanoseconds * _SC_CLK_TCK is jiffies per second @@ -1404,7 +1421,8 @@ qemuDomainHelperGetVcpus(virDomainObjPtr vm, virVcpuInfoPtr info, int maxinfo, &(info[i].cpu), NULL, vm->pid, - priv->vcpupids[i]) < 0) { + priv->vcpupids[i], + NULL) < 0) { virReportSystemError(errno, "%s", _("cannot get vCPU placement & pCPU time")); return -1; @@ -2595,7 +2613,7 @@ static int qemuDomainGetInfo(virDomainPtr dom, if (!virDomainObjIsActive(vm)) { info->cpuTime = 0; } else { - if (qemuGetProcessInfo(&(info->cpuTime), NULL, NULL, vm->pid, 0) < 0) { + if (qemuGetProcessInfo(&(info->cpuTime), NULL, NULL, vm->pid, 0, &(info->upTime)) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("cannot read cputime for domain")); goto cleanup; @@ -11474,7 +11492,7 @@ qemuDomainMemoryStats(virDomainPtr dom, if (ret >= 0 && ret < nr_stats) { long rss; - if (qemuGetProcessInfo(NULL, NULL, &rss, vm->pid, 0) < 0) { + if (qemuGetProcessInfo(NULL, NULL, &rss, vm->pid, 0, NULL) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("cannot get RSS for domain")); } else { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index d90e6b5..193f501 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -901,6 +901,7 @@ struct remote_domain_get_info_ret { /* insert@1 */ unsigned hyper memory; unsigned short nrVirtCpu; unsigned hyper cpuTime; + unsigned hyper upTime; }; struct remote_domain_save_args { diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index e614f77..1f54d5d 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -531,6 +531,7 @@ struct remote_domain_get_info_ret { uint64_t memory; u_short nrVirtCpu; uint64_t cpuTime; + uint64_t upTime; }; struct remote_domain_save_args { remote_nonnull_domain dom; diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 6951db2..027790f 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -1246,6 +1246,14 @@ cmdDominfo(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%-15s %.1lfs\n", _("CPU time:"), cpuUsed); } + if (info.upTime != 0) { + double upTime = info.upTime; + + upTime /= 1000000000.0; + + vshPrint(ctl, "%-15s %.1lfs\n", _("Uptime:"), upTime); + } + if (info.maxMem != UINT_MAX) vshPrint(ctl, "%-15s %lu KiB\n", _("Max memory:"), info.maxMem); -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list