[libvirt] [RFC] Add uptime to API returning Dom Info
Nehal J Wani
nehaljw.kkd1 at gmail.com
Mon Mar 30 07:56:40 UTC 2015
On Mon, Mar 30, 2015 at 1:16 PM, Peter Krempa <pkrempa at redhat.com> wrote:
> On Mon, Mar 30, 2015 at 03:29:40 +0530, Nehal J Wani wrote:
>> 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 */
>> };
>>
>
> The public structs can't be changed once they are released. The next
> best place will be the bulk stats API that is extensible.
>
>> /**
>> 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");
>
> This copies a static string using virAsprintf?
>
>> + if (ret < 0)
>> + return -1;
>> +
>> + pidinfo = fopen(proc, "r");
>
> And uses it in a place where you can use static strings? That doesn't
> make sense.
>
>> + 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);
>
> This certainly does not calculate uptime of the guest, merely just the
> time since the process started. This will not work at least in these
> cases:
>
> 1) When the VM is migrated to a different host
> 2) When the VM is saved
> 3) The uptime will not be accurate when the guest was paused
Is storing the timestamp at which the VM was started and then taking a
diff with the current timestamp right way to go?
How is uptime defined in case of (2) and (3) ?
>
> ...
>
>> +
>> /* 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;
>
> Peter
--
Nehal J Wani
More information about the libvir-list
mailing list