[libvirt] [PATCH V4 3/5] add nodeGetCPUmap.

Hu Tao hutao at cn.fujitsu.com
Tue Jan 31 09:58:17 UTC 2012


On Sat, Jan 28, 2012 at 03:24:04PM +0900, KAMEZAWA Hiroyuki wrote:
> add nodeGetCPUmap() for getting available CPU IDs in a bitmap.
> add virBitmapParseCommaSeparetedFormat() for parsing bitmap in
> comma separeted ascii format. This format of bitmap is used in Linux
> sysfs and cpuset.
> 
> * cpuacct's percpu usage information is provided based on
>   /sys/devices/system/cpu/present cpu map.
>   So, this kind of call is required. This routine itself may be
>   useful for other purpose.
> 
>  libvirt_private.syms |    2 +
>  nodeinfo.c           |   51 ++++++++++++++++++++++++++++++++++++++++
>  nodeinfo.h           |    4 +++
>  util/bitmap.c        |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  util/bitmap.h        |    6 +++-
>  5 files changed, 127 insertions(+), 1 deletion(-)
> ---
>  src/libvirt_private.syms |    2 +
>  src/nodeinfo.c           |   51 ++++++++++++++++++++++++++++++++++++
>  src/nodeinfo.h           |    4 +++
>  src/util/bitmap.c        |   65 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/bitmap.h        |    6 +++-
>  5 files changed, 127 insertions(+), 1 deletions(-)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 915a43f..fd44322 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -17,6 +17,7 @@ virBitmapFree;
>  virBitmapGetBit;
>  virBitmapSetBit;
>  virBitmapString;
> +virBitmapParseCommaSeparatedFormat;
>  
>  
>  # buf.h
> @@ -800,6 +801,7 @@ nodeGetCellsFreeMemory;
>  nodeGetFreeMemory;
>  nodeGetInfo;
>  nodeGetMemoryStats;
> +nodeGetCPUmap;
>  
>  
>  # nwfilter_conf.h
> diff --git a/src/nodeinfo.c b/src/nodeinfo.c
> index e0b66f7..92bada7 100644
> --- a/src/nodeinfo.c
> +++ b/src/nodeinfo.c
> @@ -47,6 +47,7 @@
>  #include "count-one-bits.h"
>  #include "intprops.h"
>  #include "virfile.h"
> +#include "bitmap.h"
>  
>  
>  #define VIR_FROM_THIS VIR_FROM_NONE
> @@ -569,6 +570,33 @@ int linuxNodeGetMemoryStats(FILE *meminfo,
>  cleanup:
>      return ret;
>  }
> +
> +/*
> + * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set
> + * and max cpu is 7. The map file shows 0-4,6-7. This functin parse
> + * it and returns bitmap.
> + */
> +static virBitmapPtr linuxParseCPUmap(int *max_cpuid, const char *path)
> +{
> +    char str[1024];
> +    FILE *fp;
> +    virBitmapPtr map = NULL;
> +
> +    fp = fopen(path, "r");
> +    if (!fp) {
> +        virReportSystemError(errno,  _("cannot open %s"), path);
> +        goto cleanup;
> +    }
> +    if (fgets(str, sizeof(str), fp) == NULL) {
> +        virReportSystemError(errno, _("cannot read from %s"), path);
> +        goto cleanup;
> +    }
> +    map = virBitmapParseCommaSeparatedFormat(str, max_cpuid);
> +
> +cleanup:
> +    VIR_FORCE_FCLOSE(fp);
> +    return map;
> +}
>  #endif
>  
>  int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) {
> @@ -712,6 +740,29 @@ int nodeGetMemoryStats(virConnectPtr conn ATTRIBUTE_UNUSED,
>  #endif
>  }
>  
> +virBitmapPtr nodeGetCPUmap(virConnectPtr conn ATTRIBUTE_UNUSED,
> +                           int *max_id,
> +                           const char *mapname)
> +{
> +#ifdef __linux__
> +    char *path;
> +    virBitmapPtr map;
> +
> +    if (virAsprintf(&path, CPU_SYS_PATH "/%s", mapname) < 0) {
> +        virReportOOMError();
> +        return NULL;
> +    }
> +
> +    map = linuxParseCPUmap(max_id, path);
> +    VIR_FREE(path);
> +    return map;
> +#else
> +     nodeReportError(VIR_ERR_NO_SUPPORT, "%s",
> +                     _("node cpumap not implemented on this platform"));
> +     return -1;
> +#endif
> +}
> +
>  #if HAVE_NUMACTL
>  # if LIBNUMA_API_VERSION <= 1
>  #  define NUMA_MAX_N_CPUS 4096
> diff --git a/src/nodeinfo.h b/src/nodeinfo.h
> index 4766152..7f26b77 100644
> --- a/src/nodeinfo.h
> +++ b/src/nodeinfo.h
> @@ -26,6 +26,7 @@
>  
>  # include "libvirt/libvirt.h"
>  # include "capabilities.h"
> +# include "bitmap.h"
>  
>  int nodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo);
>  int nodeCapsInitNUMA(virCapsPtr caps);
> @@ -46,4 +47,7 @@ int nodeGetCellsFreeMemory(virConnectPtr conn,
>                             int maxCells);
>  unsigned long long nodeGetFreeMemory(virConnectPtr conn);
>  
> +virBitmapPtr nodeGetCPUmap(virConnectPtr conn,
> +                           int *max_id,
> +                           const char *mapname);
>  #endif /* __VIR_NODEINFO_H__*/
> diff --git a/src/util/bitmap.c b/src/util/bitmap.c
> index 8c326c4..c7e1a81 100644
> --- a/src/util/bitmap.c
> +++ b/src/util/bitmap.c
> @@ -33,6 +33,11 @@
>  #include "bitmap.h"
>  #include "memory.h"
>  #include "buf.h"
> +#include "c-ctype.h"
> +#include "util.h"
> +#include "virterror_internal.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_NONE
>  
>  
>  struct _virBitmap {
> @@ -180,3 +185,63 @@ char *virBitmapString(virBitmapPtr bitmap)
>  
>      return virBufferContentAndReset(&buf);
>  }
> +
> +/**
> + * virBitmapParseCommaSeparatedFormat:
> + *
> + * When bitmap is printed in ascii format, expecially in Linux,

s/expecially/especially/

> + * comma-separated format is sometimes used. For example, a bitmap 11111011 is
> + * represetned as 0-4,6-7. This function parse comma-separated format

s/parse/parses/

> + * and returns virBitmap. Found max bit is returend, too.

s/returend/returned/

> + *
> + * This functions stops if characters other than digits, ',', '-' are
> + * found. This function will be useful for parsing linux's bitmap.
> + */
> +virBitmapPtr virBitmapParseCommaSeparatedFormat(char *buf, int *max_bit)
> +{
> +    char *pos = buf;
> +    virBitmapPtr map = NULL;
> +    int val, x;
> +
> +    /* at first, find the highest number */
> +    val = 0;
> +    while ((*pos != '\n') || (*pos != 0)) {

(*pos != '\n') && (*pos != 0)

> +        if (c_isdigit(*pos)) {
> +            virStrToLong_i(pos, &pos, 10, &val);
> +        } else if ((*pos == ',') || (*pos == '-')) {
> +            ++pos;
> +        } else
> +            break;
> +    }
> +    *max_bit = val;
> +
> +    map = virBitmapAlloc(val + 1);
> +    if (map == NULL) { /* we may return NULL at failure of parsing */
> +        virReportOOMError();
> +        return NULL;
> +    }
> +
> +    pos = buf;
> +    while ((*pos != '\n') || (*pos != 0)) {

(*pos != '\n') && (*pos != 0)

> +        if (c_isdigit(*pos)) {
> +            virStrToLong_i(pos, &pos, 10, &val);
> +            if (virBitmapSetBit(map, val) < 0)
> +                goto failed;
> +        } else if (*pos == ',') {
> +            ++pos;
> +        } else if (*pos == '-') {
> +            x = val;
> +            pos++;
> +            virStrToLong_i(pos, &pos, 10, &val);
> +            for (;x <= val; ++x) {
> +                if (virBitmapSetBit(map, x) < 0)
> +                    goto failed;
> +            }
> +        } else
> +            break;
> +    }
> +    return map;
> +failed:
> +    virBitmapFree(map);
> +    return NULL;
> +}
> diff --git a/src/util/bitmap.h b/src/util/bitmap.h
> index ef62cca..e3d3e2b 100644
> --- a/src/util/bitmap.h
> +++ b/src/util/bitmap.h
> @@ -61,5 +61,9 @@ int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
>  
>  char *virBitmapString(virBitmapPtr bitmap)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
> -
> +/*
> + * parese comma-separeted bitmap format and allocate virBitmap.
> + */
> +virBitmapPtr virBitmapParseCommaSeparatedFormat(char *buf, int *max_bit)
> +    ATTRIBUTE_RETURN_CHECK;
>  #endif
> -- 
> 1.7.4.1
> 
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

-- 
Thanks,
Hu Tao




More information about the libvir-list mailing list