Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 3985fea87987 tools/libxc/xc_cpupool.c --- a/tools/libxc/xc_cpupool.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxc/xc_cpupool.c Wed Sep 15 13:14:35 2010 +0200 @@ -34,6 +34,20 @@ static int do_sysctl_save(xc_interface * return ret; } +static int get_cpumap_size(xc_interface *xch) +{ + static int cpumap_size = 0; + xc_physinfo_t physinfo; + + if ( cpumap_size ) + return cpumap_size; + + if ( !xc_physinfo(xch, &physinfo) ) + cpumap_size = (physinfo.max_cpu_id + 8) / 8; + + return cpumap_size; +} + int xc_cpupool_create(xc_interface *xch, uint32_t *ppoolid, uint32_t sched_id) @@ -64,50 +78,56 @@ int xc_cpupool_destroy(xc_interface *xch return do_sysctl_save(xch, &sysctl); } -int xc_cpupool_getinfo(xc_interface *xch, - uint32_t first_poolid, - uint32_t n_max, - xc_cpupoolinfo_t *info) +xc_cpupoolinfo_t *xc_cpupool_getinfo(xc_interface *xch, + uint32_t poolid) { int err = 0; - int p; - uint32_t poolid = first_poolid; - uint8_t local[sizeof (info->cpumap)]; + xc_cpupoolinfo_t *info; + uint8_t *local; + int local_size; + int cpumap_size; + int size; DECLARE_SYSCTL; - memset(info, 0, n_max * sizeof(xc_cpupoolinfo_t)); + local_size = get_cpumap_size(xch); + cpumap_size = (local_size + 7) / 8; + size = sizeof(xc_cpupoolinfo_t) + cpumap_size * 8 + local_size; + info = malloc(size); + if ( !info ) + return NULL; - for (p = 0; p < n_max; p++) + memset(info, 0, size); + info->cpumap_size = local_size * 8; + info->cpumap = (uint64_t *)(info + 1); + local = (uint8_t *)(info->cpumap + cpumap_size); + + sysctl.cmd = XEN_SYSCTL_cpupool_op; + sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_INFO; + sysctl.u.cpupool_op.cpupool_id = poolid; + set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local); + sysctl.u.cpupool_op.cpumap.nr_cpus = local_size * 8; + + if ( (err = lock_pages(local, local_size)) != 0 ) { - sysctl.cmd = XEN_SYSCTL_cpupool_op; - sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_INFO; - sysctl.u.cpupool_op.cpupool_id = poolid; - set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local); - sysctl.u.cpupool_op.cpumap.nr_cpus = sizeof(info->cpumap) * 8; + PERROR("Could not lock memory for Xen hypercall"); + free(info); + return NULL; + } + err = do_sysctl_save(xch, &sysctl); + unlock_pages(local, local_size); - if ( (err = lock_pages(local, sizeof(local))) != 0 ) - { - PERROR("Could not lock memory for Xen hypercall"); - break; - } - err = do_sysctl_save(xch, &sysctl); - unlock_pages(local, sizeof (local)); - - if ( err < 0 ) - break; - - info->cpupool_id = sysctl.u.cpupool_op.cpupool_id; - info->sched_id = sysctl.u.cpupool_op.sched_id; - info->n_dom = sysctl.u.cpupool_op.n_dom; - bitmap_byte_to_64(&(info->cpumap), local, sizeof(local) * 8); - poolid = sysctl.u.cpupool_op.cpupool_id + 1; - info++; + if ( err < 0 ) + { + free(info); + return NULL; } - if ( p == 0 ) - return err; + info->cpupool_id = sysctl.u.cpupool_op.cpupool_id; + info->sched_id = sysctl.u.cpupool_op.sched_id; + info->n_dom = sysctl.u.cpupool_op.n_dom; + bitmap_byte_to_64(info->cpumap, local, local_size * 8); - return p; + return info; } int xc_cpupool_addcpu(xc_interface *xch, @@ -150,30 +170,37 @@ int xc_cpupool_movedomain(xc_interface * } int xc_cpupool_freeinfo(xc_interface *xch, - uint64_t *cpumap) + uint64_t *cpumap, + int cpusize) { int err; - uint8_t local[sizeof (*cpumap)]; + uint8_t *local; DECLARE_SYSCTL; + + local = malloc(cpusize); + if (local == NULL) + return -ENOMEM; sysctl.cmd = XEN_SYSCTL_cpupool_op; sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_FREEINFO; set_xen_guest_handle(sysctl.u.cpupool_op.cpumap.bitmap, local); - sysctl.u.cpupool_op.cpumap.nr_cpus = sizeof(*cpumap) * 8; + sysctl.u.cpupool_op.cpumap.nr_cpus = cpusize * 8; - if ( (err = lock_pages(local, sizeof(local))) != 0 ) + if ( (err = lock_pages(local, cpusize)) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); + free(local); return err; } err = do_sysctl_save(xch, &sysctl); - unlock_pages(local, sizeof (local)); + unlock_pages(local, cpusize); + bitmap_byte_to_64(cpumap, local, cpusize * 8); + + free(local); if (err < 0) return err; - bitmap_byte_to_64(cpumap, local, sizeof(local) * 8); - return 0; } diff -r 3985fea87987 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxc/xenctrl.h Wed Sep 15 13:14:35 2010 +0200 @@ -535,7 +535,8 @@ typedef struct xc_cpupoolinfo { uint32_t cpupool_id; uint32_t sched_id; uint32_t n_dom; - uint64_t cpumap; + uint32_t cpumap_size; /* max number of cpus in map */ + uint64_t *cpumap; } xc_cpupoolinfo_t; /** @@ -564,15 +565,11 @@ int xc_cpupool_destroy(xc_interface *xch * Get cpupool info. Returns info for up to the specified number of cpupools * starting at the given id. * @parm xc_handle a handle to an open hypervisor interface - * @parm first_poolid lowest id for which info is returned - * @parm n_max maximum number of cpupools to return info - * @parm info pointer to xc_cpupoolinfo_t array - * return number of cpupool infos + * @parm poolid lowest id for which info is returned + * return cpupool info ptr (obtained by malloc) */ -int xc_cpupool_getinfo(xc_interface *xch, - uint32_t first_poolid, - uint32_t n_max, - xc_cpupoolinfo_t *info); +xc_cpupoolinfo_t *xc_cpupool_getinfo(xc_interface *xch, + uint32_t poolid); /** * Add cpu to a cpupool. cpu may be -1 indicating the first unassigned. @@ -615,10 +612,12 @@ int xc_cpupool_movedomain(xc_interface * * * @parm xc_handle a handle to an open hypervisor interface * @parm cpumap pointer where to store the cpumap + * @parm cpusize size of cpumap array in bytes * return 0 on success, -1 on failure */ int xc_cpupool_freeinfo(xc_interface *xch, - uint64_t *cpumap); + uint64_t *cpumap, + int cpusize); /* diff -r 3985fea87987 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxl.c Wed Sep 15 13:14:35 2010 +0200 @@ -594,26 +594,46 @@ libxl_poolinfo * libxl_list_pool(libxl_c libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) { libxl_poolinfo *ptr; - int i, ret; - xc_cpupoolinfo_t info[256]; - int size = 256; + int i, m; + xc_cpupoolinfo_t *info; + int size; + uint32_t poolid; + libxl_physinfo physinfo; + int mapsize; + uint64_t *cpumap; - ptr = calloc(size, sizeof(libxl_poolinfo)); + if (libxl_get_physinfo(ctx, &physinfo) != 0) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info"); + return NULL; + } + mapsize = (physinfo.max_cpu_id + 64) / 64; + size = physinfo.max_cpu_id + 32; + + ptr = calloc(size, sizeof(libxl_poolinfo) + mapsize * sizeof(*cpumap)); if (!ptr) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info"); return NULL; } + cpumap = (uint64_t *)(ptr + size); - ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info); - if (ret<0) { - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info"); - return NULL; + poolid = 0; + for (i = 0; i < size; i++) { + info = xc_cpupool_getinfo(ctx->xch, poolid); + if (info == NULL) + break; + ptr[i].poolid = info->cpupool_id; + ptr[i].sched_id = info->sched_id; + ptr[i].n_dom = info->n_dom; + ptr[i].cpumap.size = mapsize * sizeof(*cpumap); + ptr[i].cpumap.map = cpumap; + for (m = 0; m < mapsize; m++) + cpumap[m] = info->cpumap[m]; + cpumap += mapsize; + poolid = info->cpupool_id + 1; + free(info); } - for (i = 0; i < ret; i++) { - ptr[i].poolid = info[i].cpupool_id; - } - *nb_pool = ret; + *nb_pool = i; return ptr; } @@ -2927,8 +2947,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct num_cpuwords = ((physinfo.max_cpu_id + 64) / 64); for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) { - ptr->cpumap = malloc(num_cpuwords * sizeof(*ptr->cpumap)); - if (!ptr->cpumap) { + ptr->cpumap.size = num_cpuwords * sizeof(*ptr->cpumap.map); + ptr->cpumap.map = malloc(ptr->cpumap.size); + if (!ptr->cpumap.map) { return NULL; } if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) { @@ -2936,7 +2957,7 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct return NULL; } if (xc_vcpu_getaffinity(ctx->xch, domid, *nb_vcpu, - ptr->cpumap, ((*nrcpus) + 7) / 8) == -1) { + ptr->cpumap.map, ((*nrcpus) + 7) / 8) == -1) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting vcpu affinity"); return NULL; } @@ -3340,3 +3361,182 @@ void libxl_file_reference_destroy(libxl_ libxl__file_reference_unmap(f); free(f->path); } + +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap) +{ + libxl_physinfo info; + int mapsize; + + if (libxl_get_physinfo(ctx, &info) != 0) + return ERROR_FAIL; + + mapsize = (info.max_cpu_id + 64) / 64; + cpumap->map = calloc(mapsize, sizeof(*cpumap->map)); + if (!cpumap->map) + return ERROR_NOMEM; + cpumap->size = mapsize * sizeof(*cpumap->map); + + if (xc_cpupool_freeinfo(ctx->xch, cpumap->map, cpumap->size)) { + free(cpumap->map); + cpumap->map = NULL; + return ERROR_FAIL; + } + + return 0; +} + +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid, + libxl_cpumap cpumap, libxl_uuid *uuid, + uint32_t *poolid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc; + int i; + xs_transaction_t t; + char *uuid_string; + + uuid_string = libxl__uuid2string(&gc, *uuid); + if (!uuid_string) + return ERROR_NOMEM; + + rc = xc_cpupool_create(ctx->xch, poolid, schedid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Could not create cpupool"); + return ERROR_FAIL; + } + + for (i = 0; i < cpumap.size * 8; i++) + if (cpumap.map[i / 64] & (1L << (i % 64))) { + rc = xc_cpupool_addcpu(ctx->xch, *poolid, i); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving cpu to cpupool"); + return ERROR_FAIL; + } + } + + for (;;) { + t = xs_transaction_start(ctx->xsh); + + xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/pool/%d", *poolid)); + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/uuid", *poolid), + uuid_string); + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/name", *poolid), + name); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + return 0; + } +} + +int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc, i; + xc_cpupoolinfo_t *info; + xs_transaction_t t; + + info = xc_cpupool_getinfo(ctx->xch, poolid); + if (info == NULL) + return ERROR_NOMEM; + + rc = ERROR_INVAL; + if ((info->cpupool_id != poolid) || (info->n_dom)) + goto out; + + for (i = 0; i < info->cpumap_size; i++) + if (info->cpumap[i / 64] & (1L << (i % 64))) { + rc = xc_cpupool_removecpu(ctx->xch, poolid, i); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error removing cpu from cpupool"); + rc = ERROR_FAIL; + goto out; + } + } + + rc = xc_cpupool_destroy(ctx->xch, poolid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "Could not destroy cpupool"); + rc = ERROR_FAIL; + goto out; + } + + for (;;) { + t = xs_transaction_start(ctx->xsh); + + xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/pool/%d", poolid)); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + break; + } + + rc = 0; + +out: + free(info); + + return rc; +} + +int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu) +{ + int rc; + + rc = xc_cpupool_addcpu(ctx->xch, poolid, cpu); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving cpu to cpupool"); + return ERROR_FAIL; + } + return 0; +} + +int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu) +{ + int rc; + + rc = xc_cpupool_removecpu(ctx->xch, poolid, cpu); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error removing cpu from cpupool"); + return ERROR_FAIL; + } + return 0; +} + +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc; + char *dom_path; + char *vm_path; + char *poolname; + xs_transaction_t t; + + dom_path = libxl__xs_get_dompath(&gc, domid); + if (!dom_path) { + return ERROR_FAIL; + } + + rc = xc_cpupool_movedomain(ctx->xch, poolid, domid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving domain to cpupool"); + return ERROR_FAIL; + } + + poolname = libxl__poolid_to_name(&gc, poolid); + vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path)); + for (; vm_path;) { + t = xs_transaction_start(ctx->xsh); + + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), poolname); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + break; + } + + return 0; +} diff -r 3985fea87987 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxl.h Wed Sep 15 13:14:35 2010 +0200 @@ -138,8 +138,6 @@ typedef char **libxl_string_list; typedef char **libxl_string_list; typedef char **libxl_key_value_list; - -typedef uint64_t *libxl_cpumap; typedef uint32_t libxl_hwcap[8]; @@ -471,6 +469,15 @@ int libxl_device_net2_del(libxl_ctx *ctx int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait); +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap); +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid, + libxl_cpumap cpumap, libxl_uuid *uuid, + uint32_t *poolid); +int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid); +int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu); +int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu); +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid); + /* common paths */ const char *libxl_sbindir_path(void); const char *libxl_bindir_path(void); diff -r 3985fea87987 tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxl.idl Wed Sep 15 13:14:35 2010 +0200 @@ -14,8 +14,6 @@ libxl_nic_type = Builtin("nic_type") libxl_string_list = Builtin("string_list", destructor_fn="libxl_string_list_destroy", passby=PASS_BY_REFERENCE) libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE) - -libxl_cpumap = Builtin("cpumap", destructor_fn="free") libxl_hwcap = Builtin("hwcap") @@ -42,8 +40,16 @@ SHUTDOWN_* constant."""), ("vcpu_online", uint32), ], destructor_fn=None) +libxl_cpumap = Struct("cpumap", [ + ("size", uint32), + ("map", Reference(uint64)), + ]) + libxl_poolinfo = Struct("poolinfo", [ - ("poolid", uint32) + ("poolid", uint32), + ("sched_id", uint32), + ("n_dom", uint32), + ("cpumap", libxl_cpumap) ], destructor_fn=None) libxl_vminfo = Struct("vminfo", [ diff -r 3985fea87987 tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxl_utils.c Wed Sep 15 13:14:35 2010 +0200 @@ -31,6 +31,17 @@ #include "libxl_utils.h" #include "libxl_internal.h" +struct schedid_name { + char *name; + int id; +}; + +static struct schedid_name schedid_name[] = { + { "credit", XEN_SCHEDULER_CREDIT }, + { "sedf", XEN_SCHEDULER_SEDF }, + { "credit2", XEN_SCHEDULER_CREDIT2 }, + { NULL, -1 } +}; unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus) { @@ -137,6 +148,28 @@ int libxl_name_to_poolid(libxl_ctx *ctx, } free(poolinfo); return ret; +} + +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name) +{ + int i; + + for (i = 0; schedid_name[i].name != NULL; i++) + if (strcmp(name, schedid_name[i].name) == 0) + return schedid_name[i].id; + + return -1; +} + +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid) +{ + int i; + + for (i = 0; schedid_name[i].name != NULL; i++) + if (schedid_name[i].id == schedid) + return schedid_name[i].name; + + return "unknown"; } int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid) diff -r 3985fea87987 tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxl_utils.h Wed Sep 15 13:14:35 2010 +0200 @@ -23,6 +23,8 @@ char *libxl_domid_to_name(libxl_ctx *ctx char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid); int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid); char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid); +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name); +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid); int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid); int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid); int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name); diff -r 3985fea87987 tools/libxl/libxltypes.py --- a/tools/libxl/libxltypes.py Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxltypes.py Wed Sep 15 13:14:35 2010 +0200 @@ -119,7 +119,10 @@ class Reference(Type): kwargs.setdefault('passby', PASS_BY_VALUE) kwargs.setdefault('namespace', ty.namespace) - typename = ty.typename[len(kwargs['namespace']):] + + typename = ty.typename + if ty.namespace: + typename = typename[len(kwargs['namespace']):] Type.__init__(self, typename + " *", **kwargs) # diff -r 3985fea87987 tools/libxl/libxlu_cfg_l.c --- a/tools/libxl/libxlu_cfg_l.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxlu_cfg_l.c Wed Sep 15 13:14:35 2010 +0200 @@ -54,6 +54,7 @@ typedef unsigned char flex_uint8_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -83,8 +84,6 @@ typedef unsigned int flex_uint32_t; #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -159,15 +158,7 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -496,7 +487,7 @@ void xlu__cfg_yyset_column(int column_n void xlu__cfg_yyset_column(int column_no, yyscan_t yyscanner); -#line 500 "libxlu_cfg_l.c" +#line 491 "libxlu_cfg_l.c" #define INITIAL 0 #define lexerr 1 @@ -632,12 +623,7 @@ static int input (yyscan_t yyscanner ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -645,7 +631,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -656,7 +642,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -744,7 +730,7 @@ YY_DECL #line 37 "libxlu_cfg_l.l" -#line 748 "libxlu_cfg_l.c" +#line 734 "libxlu_cfg_l.c" yylval = yylval_param; @@ -944,7 +930,7 @@ YY_RULE_SETUP #line 82 "libxlu_cfg_l.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 948 "libxlu_cfg_l.c" +#line 934 "libxlu_cfg_l.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(lexerr): yyterminate(); @@ -1687,8 +1673,8 @@ YY_BUFFER_STATE xlu__cfg_yy_scan_string /** Setup the input buffer state to scan the given bytes. The next call to xlu__cfg_yylex() will * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ diff -r 3985fea87987 tools/libxl/libxlu_cfg_l.h --- a/tools/libxl/libxlu_cfg_l.h Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/libxlu_cfg_l.h Wed Sep 15 13:14:35 2010 +0200 @@ -58,6 +58,7 @@ typedef unsigned char flex_uint8_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -87,8 +88,6 @@ typedef unsigned int flex_uint32_t; #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -132,15 +131,7 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE @@ -310,12 +301,7 @@ static int yy_flex_strlen (yyconst char /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ @@ -352,6 +338,6 @@ extern int xlu__cfg_yylex \ #line 82 "libxlu_cfg_l.l" -#line 356 "libxlu_cfg_l.h" +#line 342 "libxlu_cfg_l.h" #undef xlu__cfg_yyIN_HEADER #endif /* xlu__cfg_yyHEADER_H */ diff -r 3985fea87987 tools/libxl/xl.h --- a/tools/libxl/xl.h Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/xl.h Wed Sep 15 13:14:35 2010 +0200 @@ -79,6 +79,12 @@ int main_network2attach(int argc, char * int main_network2attach(int argc, char **argv); int main_network2list(int argc, char **argv); int main_network2detach(int argc, char **argv); +int main_poolcreate(int argc, char **argv); +int main_poollist(int argc, char **argv); +int main_pooldestroy(int argc, char **argv); +int main_poolcpuadd(int argc, char **argv); +int main_poolcpuremove(int argc, char **argv); +int main_poolmigrate(int argc, char **argv); void help(char *command); diff -r 3985fea87987 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Wed Sep 15 13:14:35 2010 +0200 @@ -420,7 +420,7 @@ static void printf_info(int domid, printf("\t(ssidref %d)\n", c_info->ssidref); printf("\t(name %s)\n", c_info->name); printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(c_info->uuid)); - printf("\t(cpupool %s (%d))\n", c_info->poolname, c_info->poolid); + printf("\t(cpupool %s)\n", c_info->poolname); if (c_info->xsdata) printf("\t(xsdata contains data)\n"); else @@ -3283,7 +3283,7 @@ static void print_vcpuinfo(uint32_t tdom printf("%9.1f ", ((float)vcpuinfo->vcpu_time / 1e9)); /* CPU AFFINITY */ pcpumap = nr_cpus > 64 ? (uint64_t)-1 : ((1ULL << nr_cpus) - 1); - for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) { + for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) { if (*cpumap < pcpumap) { break; } @@ -3298,7 +3298,7 @@ static void print_vcpuinfo(uint32_t tdom if (!nr_cpus) { printf("any cpu\n"); } else { - for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) { + for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) { pcpumap = *cpumap; for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1) ; @@ -3569,10 +3569,7 @@ static void output_xeninfo(void) printf("xen_minor : %d\n", info->xen_version_minor); printf("xen_extra : %s\n", info->xen_version_extra); printf("xen_caps : %s\n", info->capabilities); - printf("xen_scheduler : %s\n", - sched_id == XEN_SCHEDULER_SEDF ? "sedf" : - sched_id == XEN_SCHEDULER_CREDIT ? "credit" : - sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown"); + printf("xen_scheduler : %s\n", libxl_schedid_to_name(&ctx, sched_id)); printf("xen_pagesize : %lu\n", info->pagesize); printf("platform_params : virt_start=0x%lx\n", info->virt_start); printf("xen_changeset : %s\n", info->changeset); @@ -3603,6 +3600,8 @@ static void output_physinfo(void) libxl_physinfo info; const libxl_version_info *vinfo; unsigned int i; + libxl_cpumap cpumap; + int n = 0; if (libxl_get_physinfo(&ctx, &info) != 0) { fprintf(stderr, "libxl_physinfo failed.\n"); @@ -3629,6 +3628,13 @@ static void output_physinfo(void) printf("total_memory : %"PRIu64"\n", info.total_pages / i); printf("free_memory : %"PRIu64"\n", info.free_pages / i); } + if (!libxl_get_freecpus(&ctx, &cpumap)) { + for (i = 0; i < cpumap.size * 8; i++) + if (cpumap.map[i / 64] & ((uint64_t)1 << (i % 64))) + n++; + printf("free_cpus : %d\n", n); + free(cpumap.map); + } return; } @@ -5044,3 +5050,444 @@ int main_tmem_freeable(int argc, char ** printf("%d\n", mb); return 0; } + +int main_poolcreate(int argc, char **argv) +{ + char *filename = NULL; + char *p, extra_config[1024]; + int dryrun = 0; + int opt; + int option_index = 0; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"defconfig", 1, 0, 'f'}, + {"dryrun", 0, 0, 'n'}, + {0, 0, 0, 0} + }; + int ret; + void *config_data = 0; + int config_len = 0; + XLU_Config *config; + const char *buf; + char *name, *sched; + uint32_t poolid; + int schedid = -1; + XLU_ConfigList *cpus; + int n_cpus, i, n; + libxl_cpumap freemap; + libxl_cpumap cpumap; + libxl_uuid uuid; + + while (1) { + opt = getopt_long(argc, argv, "hnf:", long_options, &option_index); + if (opt == -1) + break; + + switch (opt) { + case 'f': + filename = optarg; + break; + case 'h': + help("pool-create"); + return 0; + case 'n': + dryrun = 1; + break; + default: + fprintf(stderr, "option not supported\n"); + break; + } + } + + memset(extra_config, 0, sizeof(extra_config)); + while (optind < argc) { + if ((p = strchr(argv[optind], '='))) { + if (strlen(extra_config) + 1 < sizeof(extra_config)) { + if (strlen(extra_config)) + strcat(extra_config, "\n"); + strcat(extra_config, argv[optind]); + } + } else if (!filename) { + filename = argv[optind]; + } else { + help("pool-create"); + return -ERROR_FAIL; + } + optind++; + } + + if (!filename) { + help("pool-create"); + return -ERROR_FAIL; + } + + if (libxl_read_file_contents(&ctx, filename, &config_data, &config_len)) { + fprintf(stderr, "Failed to read config file: %s: %s\n", + filename, strerror(errno)); + return -ERROR_FAIL; + } + if (strlen(extra_config)) { + if (config_len > INT_MAX - (strlen(extra_config) + 2)) { + fprintf(stderr, "Failed to attach extra configration\n"); + return -ERROR_FAIL; + } + config_data = realloc(config_data, + config_len + strlen(extra_config) + 2); + if (!config_data) { + fprintf(stderr, "Failed to realloc config_data\n"); + return -ERROR_FAIL; + } + strcat(config_data, "\n"); + strcat(config_data, extra_config); + strcat(config_data, "\n"); + config_len += (strlen(extra_config) + 2); + } + + config = xlu_cfg_init(stderr, filename); + if (!config) { + fprintf(stderr, "Failed to allocate for configuration\n"); + return -ERROR_FAIL; + } + + ret = xlu_cfg_readdata(config, config_data, config_len); + if (ret) { + fprintf(stderr, "Failed to parse config file: %s\n", strerror(ret)); + return -ERROR_FAIL; + } + + if (!xlu_cfg_get_string (config, "name", &buf)) + name = strdup(buf); + else + name = basename(filename); + if (!libxl_name_to_poolid(&ctx, name, &poolid)) { + fprintf(stderr, "Pool name \"%s\" already exists\n", name); + return -ERROR_FAIL; + } + + if (!xlu_cfg_get_string (config, "sched", &buf)) { + if ((schedid = libxl_name_to_schedid(&ctx, buf)) < 0) { + fprintf(stderr, "Unknown scheduler\n"); + return -ERROR_FAIL; + } + } else { + if ((schedid = libxl_get_sched_id(&ctx)) < 0) { + fprintf(stderr, "get_sched_id sysctl failed.\n"); + return -ERROR_FAIL; + } + } + sched = libxl_schedid_to_name(&ctx, schedid); + + if (libxl_get_freecpus(&ctx, &freemap)) { + fprintf(stderr, "libxl_get_freecpus failed\n"); + return -ERROR_FAIL; + } + cpumap.map = calloc(freemap.size, 1); + if (!cpumap.map) { + fprintf(stderr, "Failed to allocate cpumap\n"); + return -ERROR_FAIL; + } + cpumap.size = freemap.size; + if (!xlu_cfg_get_list(config, "cpus", &cpus, 0)) { + n_cpus = 0; + while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) { + i = atoi(buf); + if ((i < 0) || (i >= freemap.size * 8) || + !(freemap.map[i / 64] & (1L << (i % 64)))) { + fprintf(stderr, "cpu %d illegal or not free\n", i); + return -ERROR_FAIL; + } + cpumap.map[i / 64] |= 1L << (i % 64); + n_cpus++; + } + } else { + n_cpus = 1; + n = 0; + for (i = 0; i < freemap.size; i++) + if (freemap.map[i / 64] & (1L << (i % 64))) { + n++; + cpumap.map[i / 64] = 1L << (i % 64); + break; + } + if (n != n_cpus) { + fprintf(stderr, "no free cpu found\n"); + return -ERROR_FAIL; + } + } + + libxl_uuid_generate(&uuid); + + printf("Using config file \"%s\"\n", filename); + printf("pool name: %s\n", name); + printf("scheduler: %s\n", sched); + printf("number of cpus: %d\n", n_cpus); + + if (dryrun) + return 0; + + poolid = 0; + if (libxl_create_cpupool(&ctx, name, schedid, cpumap, &uuid, &poolid)) { + fprintf(stderr, "error on creating cpupool\n"); + return -ERROR_FAIL; + } + + return 0; +} + +int main_poollist(int argc, char **argv) +{ + int opt; + int option_index = 0; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"long", 0, 0, 'l'}, + {"cpus", 0, 0, 'c'}, + {0, 0, 0, 0} + }; + int opt_long = 0; + int opt_cpus = 0; + char *pool = NULL; + libxl_poolinfo *poolinfo; + int n_pools, p, c, n; + uint32_t poolid; + char *name; + + while (1) { + opt = getopt_long(argc, argv, "hlc", long_options, &option_index); + if (opt == -1) + break; + + switch (opt) { + case 'h': + help("pool-list"); + return 0; + case 'l': + opt_long = 1; + break; + case 'c': + opt_cpus = 1; + break; + default: + fprintf(stderr, "option not supported\n"); + break; + } + } + + if ((optind + 1) < argc) { + help("pool-list"); + return -ERROR_FAIL; + } + if (optind < argc) { + pool = argv[optind]; + if (libxl_name_to_poolid(&ctx, pool, &poolid)) { + fprintf(stderr, "Pool \'%s\' does not exist\n", pool); + return -ERROR_FAIL; + } + } + + poolinfo = libxl_list_pool(&ctx, &n_pools); + if (!poolinfo) { + fprintf(stderr, "error getting cpupool info\n"); + return -ERROR_NOMEM; + } + + if (!opt_long) { + printf("%-19s", "Name"); + if (opt_cpus) + printf("CPU list\n"); + else + printf("CPUs Sched Active Domain count\n"); + } + + for (p = 0; p < n_pools; p++) { + if (pool && (poolinfo[p].poolid != poolid)) + continue; + name = libxl_poolid_to_name(&ctx, poolinfo[p].poolid); + if (!name) { + fprintf(stderr, "error getting cpupool info\n"); + return -ERROR_NOMEM; + } + if (opt_long) { + return -ERROR_NI; + } else { + printf("%-19s", name); + n = 0; + for (c = 0; c < poolinfo[p].cpumap.size * 8; c++) + if (poolinfo[p].cpumap.map[c / 64] & (1L << (c % 64))) { + if (n && opt_cpus) printf(","); + if (opt_cpus) printf("%d", c); + n++; + } + if (!opt_cpus) { + printf("%3d %9s y %4d", n, + libxl_schedid_to_name(&ctx, poolinfo[p].sched_id), + poolinfo[p].n_dom); + } + printf("\n"); + } + } + + return 0; +} + +int main_pooldestroy(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-destroy"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-destroy"); + return -ERROR_FAIL; + } + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_destroy_cpupool(&ctx, poolid); +} + +int main_poolcpuadd(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + int cpu; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-cpu-add"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-cpu-add"); + return -ERROR_FAIL; + } + + if (!argv[optind]) { + fprintf(stderr, "no cpu specified\n"); + help("pool-cpu-add"); + return -ERROR_FAIL; + } + cpu = atoi(argv[optind]); + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); +} + +int main_poolcpuremove(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + int cpu; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-cpu-remove"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-cpu-remove"); + return -ERROR_FAIL; + } + + if (!argv[optind]) { + fprintf(stderr, "no cpu specified\n"); + help("pool-cpu-remove"); + return -ERROR_FAIL; + } + cpu = atoi(argv[optind]); + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); +} + +int main_poolmigrate(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + char *dom; + uint32_t domid; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-migrate"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + dom = argv[optind++]; + if (!dom) { + fprintf(stderr, "no domain specified\n"); + help("pool-migrate"); + return -ERROR_FAIL; + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-migrate"); + return -ERROR_FAIL; + } + + if (domain_qualifier_to_domid(dom, &domid, NULL) || + !libxl_domid_to_name(&ctx, domid)) { + fprintf(stderr, "unknown domain \'%s\'\n", dom); + return -ERROR_FAIL; + } + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_movedomain(&ctx, poolid, domid); +} diff -r 3985fea87987 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Wed Sep 15 13:14:35 2010 +0200 @@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = { "destroy a domain's version 2 virtual network device", " ", }, + { "pool-create", + &main_poolcreate, + "Create a CPU pool based an ConfigFile", + "[options] [vars]", + "-h, --help Print this help.\n" + "-f=FILE, --defconfig=FILE Use the given configuration file.\n" + "-n, --dryrun Dry run - prints the resulting configuration." + }, + { "pool-list", + &main_poollist, + "List CPU pools on host", + "[-l|--long] [-c|--cpus] []", + "-l, --long Output all CPU pool details.\n" + "-c, --cpus Output list of CPUs used by a pool" + }, + { "pool-destroy", + &main_pooldestroy, + "Deactivates a CPU pool", + "", + }, + { "pool-cpu-add", + &main_poolcpuadd, + "Adds a CPU to a CPU pool", + " ", + }, + { "pool-cpu-remove", + &main_poolcpuremove, + "Removes a CPU from a CPU pool", + " ", + }, + { "pool-migrate", + &main_poolmigrate, + "Moves a domain into a CPU pool", + " ", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); diff -r 3985fea87987 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Fri Sep 10 19:06:33 2010 +0100 +++ b/tools/python/xen/lowlevel/xc/xc.c Wed Sep 15 13:14:35 2010 +0200 @@ -241,7 +241,7 @@ static PyObject *pyxc_vcpu_setaffinity(X if ( xc_physinfo(self->xc_handle, &info) != 0 ) return pyxc_error_to_exception(self->xc_handle); - nr_cpus = info.nr_cpus; + nr_cpus = info.max_cpu_id + 1; size = (nr_cpus + cpumap_size * 8 - 1)/ (cpumap_size * 8); cpumap = malloc(cpumap_size * size); @@ -400,7 +400,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObj if ( xc_physinfo(self->xc_handle, &pinfo) != 0 ) return pyxc_error_to_exception(self->xc_handle); - nr_cpus = pinfo.nr_cpus; + nr_cpus = pinfo.max_cpu_id + 1; rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info); if ( rc < 0 ) @@ -1906,22 +1906,23 @@ static PyObject *pyxc_dom_set_memshr(XcO return zero; } -static PyObject *cpumap_to_cpulist(uint64_t cpumap) +static PyObject *cpumap_to_cpulist(uint64_t *cpumap, int cpusize) { PyObject *cpulist = NULL; - uint32_t i; + int i; cpulist = PyList_New(0); - for ( i = 0; cpumap != 0; i++ ) + for ( i = 0; i < cpusize; i++ ) { - if ( cpumap & 1 ) + if ( *cpumap & (1L << (i % 64)) ) { PyObject* pyint = PyInt_FromLong(i); PyList_Append(cpulist, pyint); Py_DECREF(pyint); } - cpumap >>= 1; + if ( (i % 64) == 63 ) + cpumap++; } return cpulist; } @@ -1966,7 +1967,7 @@ static PyObject *pyxc_cpupool_getinfo(Xc PyObject *list, *info_dict; uint32_t first_pool = 0; - int max_pools = 1024, nr_pools, i; + int max_pools = 1024, i; xc_cpupoolinfo_t *info; static char *kwd_list[] = { "first_pool", "max_pools", NULL }; @@ -1975,38 +1976,31 @@ static PyObject *pyxc_cpupool_getinfo(Xc &first_pool, &max_pools) ) return NULL; - info = calloc(max_pools, sizeof(xc_cpupoolinfo_t)); - if (info == NULL) - return PyErr_NoMemory(); - - nr_pools = xc_cpupool_getinfo(self->xc_handle, first_pool, max_pools, info); - - if (nr_pools < 0) + list = PyList_New(0); + for (i = 0; i < max_pools; i++) { - free(info); - return pyxc_error_to_exception(self->xc_handle); - } - - list = PyList_New(nr_pools); - for ( i = 0 ; i < nr_pools; i++ ) - { + info = xc_cpupool_getinfo(self->xc_handle, first_pool); + if (info == NULL) + break; info_dict = Py_BuildValue( "{s:i,s:i,s:i,s:N}", - "cpupool", (int)info[i].cpupool_id, - "sched", info[i].sched_id, - "n_dom", info[i].n_dom, - "cpulist", cpumap_to_cpulist(info[i].cpumap)); + "cpupool", (int)info->cpupool_id, + "sched", info->sched_id, + "n_dom", info->n_dom, + "cpulist", cpumap_to_cpulist(info->cpumap, + info->cpumap_size)); + first_pool = info->cpupool_id + 1; + free(info); + if ( info_dict == NULL ) { Py_DECREF(list); - if ( info_dict != NULL ) { Py_DECREF(info_dict); } - free(info); return NULL; } - PyList_SetItem(list, i, info_dict); + + PyList_Append(list, info_dict); + Py_DECREF(info_dict); } - - free(info); return list; } @@ -2072,12 +2066,28 @@ static PyObject *pyxc_cpupool_movedomain static PyObject *pyxc_cpupool_freeinfo(XcObject *self) { - uint64_t cpumap; + uint64_t *cpumap; + xc_physinfo_t physinfo; + int ret; + PyObject *info = NULL; - if (xc_cpupool_freeinfo(self->xc_handle, &cpumap) != 0) + if (xc_physinfo(self->xc_handle, &physinfo)) return pyxc_error_to_exception(self->xc_handle); - return cpumap_to_cpulist(cpumap); + cpumap = calloc((physinfo.max_cpu_id + 64) / 64, sizeof(uint64_t)); + if (!cpumap) { + errno = -ENOMEM; + return PyErr_SetFromErrno(xc_error_obj); + } + + ret = xc_cpupool_freeinfo(self->xc_handle, cpumap, + (physinfo.max_cpu_id + 8) / 8); + if (!ret) + info = cpumap_to_cpulist(cpumap, physinfo.max_cpu_id + 1); + + free(cpumap); + + return ret ? pyxc_error_to_exception(self->xc_handle) : info; } static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,