[libvirt] [PATCH 1/2] cpustats: collect VM user and sys times
Osier Yang
jyang at redhat.com
Sat Mar 10 11:18:33 UTC 2012
On 2012年03月10日 01:37, Eric Blake wrote:
> As documented in linux.git/Documentation/cgroups/cpuacct.txt,
> cpuacct.stat returns user and system time in ticks (the same
> unit used in times(2)). It would be a bit nicer if it were like
> getrusage(2) and reported timeval contents, or like cpuacct.usage
> and in nanoseconds, but we can't be picky.
>
> * src/util/cgroup.h (virCgroupGetCpuacctStat): New function.
> * src/util/cgroup.c (virCgroupGetCpuacctStat): Implement it.
> (virCgroupGetValueStr): Allow for multi-line files.
> * src/libvirt_private.syms (cgroup.h): Export it.
> ---
> src/libvirt_private.syms | 1 +
> src/util/cgroup.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-
> src/util/cgroup.h | 4 ++-
> 3 files changed, 53 insertions(+), 3 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index d7ec221..1f55f5d 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -78,6 +78,7 @@ virCgroupGetCpuCfsPeriod;
> virCgroupGetCpuCfsQuota;
> virCgroupGetCpuShares;
> virCgroupGetCpuacctPercpuUsage;
> +virCgroupGetCpuacctStat;
> virCgroupGetCpuacctUsage;
> virCgroupGetCpusetMems;
> virCgroupGetFreezerState;
> diff --git a/src/util/cgroup.c b/src/util/cgroup.c
> index c150fbb..ad49bc2 100644
> --- a/src/util/cgroup.c
> +++ b/src/util/cgroup.c
> @@ -355,8 +355,8 @@ static int virCgroupGetValueStr(virCgroupPtr group,
> VIR_DEBUG("Failed to read %s: %m\n", keypath);
> } else {
> /* Terminated with '\n' has sometimes harmful effects to the caller */
> - char *p = strchr(*value, '\n');
> - if (p) *p = '\0';
> + if ((*value)[rc - 1] == '\n')
> + (*value)[rc - 1] = '\0';
>
> rc = 0;
> }
> @@ -1561,6 +1561,53 @@ int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage)
> "cpuacct.usage_percpu", usage);
> }
>
> +#ifdef _SC_CLK_TCK
> +int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
> + unsigned long long *sys)
> +{
> + char *str;
> + char *p;
> + int ret;
> + static double scale = -1.0;
> +
> + if ((ret = virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT,
> + "cpuacct.stat",&str))< 0)
> + return ret;
> + if (!(p = STRSKIP(str, "user ")) ||
> + virStrToLong_ull(p,&p, 10, user)< 0 ||
> + !(p = STRSKIP(p, "\nsystem ")) ||
> + virStrToLong_ull(p, NULL, 10, sys)< 0) {
> + ret = -EINVAL;
> + goto cleanup;
> + }
> + /* times reported are in system ticks (generally 100 Hz), but that
> + * rate can theoretically vary between machines. Scale things
> + * into approximate nanoseconds. */
> + if (scale< 0) {
> + long ticks_per_sec = sysconf(_SC_CLK_TCK);
> + if (ticks_per_sec == -1) {
> + ret = -errno;
> + goto cleanup;
> + }
> + scale = 1000000000.0 / ticks_per_sec;
> + }
> + *user *= scale;
> + *sys *= scale;
> +
> + ret = 0;
> +cleanup:
> + VIR_FREE(str);
> + return ret;
> +}
> +#else
> +int virCgroupGetCpuacctStat(virCgroupPtr group ATTRIBUTE_UNUSED,
> + unsigned long long *user ATTRIBUTE_UNUSED,
> + unsigned long long *sys ATTRIBUTE_UNUSED)
> +{
> + return -ENOSYS;
> +}
> +#endif
> +
> int virCgroupSetFreezerState(virCgroupPtr group, const char *state)
> {
> return virCgroupSetValueStr(group,
> diff --git a/src/util/cgroup.h b/src/util/cgroup.h
> index b4e0f37..8486c42 100644
> --- a/src/util/cgroup.h
> +++ b/src/util/cgroup.h
> @@ -1,7 +1,7 @@
> /*
> * cgroup.h: Interface to tools for managing cgroups
> *
> - * Copyright (C) 2011 Red Hat, Inc.
> + * Copyright (C) 2011-2012 Red Hat, Inc.
> * Copyright IBM Corp. 2008
> *
> * See COPYING.LIB for the License of this software
> @@ -116,6 +116,8 @@ int virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota);
>
> int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
> int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage);
> +int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
> + unsigned long long *sys);
>
> int virCgroupSetFreezerState(virCgroupPtr group, const char *state);
> int virCgroupGetFreezerState(virCgroupPtr group, char **state);
ACK
More information about the libvir-list
mailing list