[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