# HG changeset patch # User Juergen Gross # Date 1286536912 -7200 # Node ID 91397dcffead192708972a2628b4b31a58fdbdfb # Parent fc17462ba612d67069c1110f8cca3b1adb8c233b support of cpupools in xl: commands and library changes Support of cpu pools in xl: library functions xl pool-create xl pool-list xl pool-destroy xl pool-cpu-add xl pool-cpu-remove xl pool-migrate Renamed all cpu pool related names to *cpupool* Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r fc17462ba612 -r 91397dcffead tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl.c Fri Oct 08 13:21:52 2010 +0200 @@ -607,21 +607,26 @@ return 0; } -libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) -{ - libxl_poolinfo *ptr, *tmp; - int i; +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool) +{ + libxl_cpupoolinfo *ptr, *tmp; + int i, m, ncpu; xc_cpupoolinfo_t *info; uint32_t poolid; ptr = NULL; + ncpu = xc_get_max_cpus(ctx->xch); + if (!ncpu) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting max cpu number"); + return NULL; + } poolid = 0; for (i = 0;; i++) { info = xc_cpupool_getinfo(ctx->xch, poolid); if (info == NULL) break; - tmp = realloc(ptr, (i + 1) * sizeof(libxl_poolinfo)); + tmp = realloc(ptr, (i + 1) * sizeof(libxl_cpupoolinfo)); if (!tmp) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info"); free(ptr); @@ -629,6 +634,13 @@ } ptr = tmp; ptr[i].poolid = info->cpupool_id; + ptr[i].sched_id = info->sched_id; + ptr[i].n_dom = info->n_dom; + if (libxl_cpumap_alloc(&ptr[i].cpumap, ncpu)) + break; + for (m = 0; m < ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++) + ptr[i].cpumap.map[m] = (info->cpumap_size > (m * sizeof(*ptr[i].cpumap.map))) ? + info->cpumap[m] : 0; poolid = info->cpupool_id + 1; free(info); } @@ -3207,7 +3219,6 @@ libxl_vcpuinfo *ptr, *ret; xc_domaininfo_t domaininfo; xc_vcpuinfo_t vcpuinfo; - unsigned num_cpuwords; if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist"); @@ -3219,10 +3230,9 @@ return NULL; } - num_cpuwords = ((*nrcpus + 63) / 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) { + if (libxl_cpumap_alloc(&ptr->cpumap, *nrcpus)) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpumap"); return NULL; } if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) { @@ -3230,7 +3240,7 @@ 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; } @@ -3913,3 +3923,176 @@ libxl__file_reference_unmap(f); free(f->path); } + +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap) +{ + int ncpus; + + cpumap->map = xc_cpupool_freeinfo(ctx->xch, &ncpus); + if (cpumap->map == NULL) + return ERROR_FAIL; + + cpumap->size = (ncpus + 7) / 8; + + 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"); + libxl_destroy_cpupool(ctx, *poolid); + 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; + } + + for (;;) { + t = xs_transaction_start(ctx->xsh); + + poolname = libxl__cpupoolid_to_name(&gc, poolid); + vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path)); + if (!vm_path) + break; + + 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 fc17462ba612 -r 91397dcffead tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl.h Fri Oct 08 13:21:52 2010 +0200 @@ -141,9 +141,12 @@ typedef char **libxl_key_value_list; void libxl_key_value_list_destroy(libxl_key_value_list *kvl); -typedef uint64_t *libxl_cpumap; +typedef uint32_t libxl_hwcap[8]; -typedef uint32_t libxl_hwcap[8]; +typedef struct { + uint32_t size; /* number of bytes in map */ + uint64_t *map; +} libxl_cpumap; typedef enum { XENFV = 1, @@ -361,7 +364,7 @@ int libxl_domain_info(libxl_ctx*, libxl_dominfo *info_r, uint32_t domid); libxl_dominfo * libxl_list_domain(libxl_ctx*, int *nb_domain); -libxl_poolinfo * libxl_list_pool(libxl_ctx*, int *nb_pool); +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool); libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm); typedef struct libxl__device_model_starting libxl_device_model_starting; @@ -504,6 +507,15 @@ 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 fc17462ba612 -r 91397dcffead tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl.idl Fri Oct 08 13:21:52 2010 +0200 @@ -6,6 +6,7 @@ libxl_ctx = Builtin("ctx") libxl_uuid = Builtin("uuid") libxl_mac = Builtin("mac") +libxl_cpumap = Builtin("cpumap") libxl_qemu_machine_type = Number("qemu_machine_type", namespace="libxl_") libxl_console_consback = Number("console_consback", namespace="libxl_") libxl_console_constype = Number("console_constype", namespace="libxl_") @@ -16,8 +17,6 @@ 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_file_reference = Builtin("file_reference", destructor_fn="libxl_file_reference_destroy", passby=PASS_BY_REFERENCE) - -libxl_cpumap = Builtin("cpumap", destructor_fn="free") libxl_hwcap = Builtin("hwcap") @@ -45,9 +44,12 @@ ("vcpu_online", uint32), ], destructor_fn=None) -libxl_poolinfo = Struct("poolinfo", [ - ("poolid", uint32) - ], destructor_fn=None) +libxl_cpupoolinfo = Struct("cpupoolinfo", [ + ("poolid", uint32), + ("sched_id", uint32), + ("n_dom", uint32), + ("cpumap", libxl_cpumap) + ], destructor_fn="libxl_cpupoolinfo_destroy") libxl_vminfo = Struct("vminfo", [ ("uuid", libxl_uuid), diff -r fc17462ba612 -r 91397dcffead tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl_internal.h Fri Oct 08 13:21:52 2010 +0200 @@ -237,7 +237,7 @@ #define LIBXL__LOG_ERROR XTL_ERROR _hidden char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid); -_hidden char *libxl__poolid_to_name(libxl__gc *gc, uint32_t poolid); +_hidden char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid); /* holds the CPUID response for a single CPUID leaf diff -r fc17462ba612 -r 91397dcffead tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl_utils.c Fri Oct 08 13:21:52 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) { @@ -90,7 +101,7 @@ return ret; } -char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid) +char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid) { unsigned int len; char path[strlen("/local/pool") + 12]; @@ -103,40 +114,61 @@ return s; } -char *libxl__poolid_to_name(libxl__gc *gc, uint32_t poolid) +char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid) { - char *s = libxl_poolid_to_name(libxl__gc_owner(gc), poolid); + char *s = libxl_cpupoolid_to_name(libxl__gc_owner(gc), poolid); if ( s ) libxl__ptr_add(gc, s); return s; } -int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, +int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name, uint32_t *poolid) { int i, nb_pools; char *poolname; - libxl_poolinfo *poolinfo; + libxl_cpupoolinfo *poolinfo; int ret = -1; - poolinfo = libxl_list_pool(ctx, &nb_pools); + poolinfo = libxl_list_cpupool(ctx, &nb_pools); if (!poolinfo) return ERROR_NOMEM; for (i = 0; i < nb_pools; i++) { - poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid); - if (!poolname) - continue; - if (strcmp(poolname, name) == 0) { - *poolid = poolinfo[i].poolid; - ret = 0; + if (ret && ((poolname = libxl_cpupoolid_to_name(ctx, + poolinfo[i].poolid)) != NULL)) { + if (strcmp(poolname, name) == 0) { + *poolid = poolinfo[i].poolid; + ret = 0; + } free(poolname); - break; } - free(poolname); + libxl_cpupoolinfo_destroy(poolinfo + i); } 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) @@ -676,6 +708,39 @@ return rc; } +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus) +{ + int elems; + + elems = (max_cpus + 63) / 64; + cpumap->map = calloc(elems, sizeof(*cpumap->map)); + if (!cpumap->map) + return ERROR_NOMEM; + cpumap->size = elems * 8; /* size in bytes */ + return 0; +} + +int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return 0; + return (cpumap->map[cpu / 64] & (1L << (cpu & 63))) ? 1 : 0; +} + +void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return; + cpumap->map[cpu / 64] |= 1L << (cpu & 63); +} + +void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return; + cpumap->map[cpu / 64] &= ~(1L << (cpu & 63)); +} + int libxl_get_max_cpus(libxl_ctx *ctx) { return xc_get_max_cpus(ctx->xch); diff -r fc17462ba612 -r 91397dcffead tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxl_utils.h Fri Oct 08 13:21:52 2010 +0200 @@ -21,8 +21,10 @@ unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus); int libxl_name_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid); 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_cpupoolid(libxl_ctx *ctx, const char *name, uint32_t *poolid); +char *libxl_cpupoolid_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); @@ -74,5 +76,9 @@ * return -1 if there are an error */ int libxl_check_device_model_version(libxl_ctx *ctx, char *path); +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus); +int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu); +void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu); +void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu); #endif diff -r fc17462ba612 -r 91397dcffead tools/libxl/libxltypes.py --- a/tools/libxl/libxltypes.py Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxltypes.py Fri Oct 08 13:21:52 2010 +0200 @@ -131,7 +131,10 @@ 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 fc17462ba612 -r 91397dcffead tools/libxl/libxlu_cfg_l.c --- a/tools/libxl/libxlu_cfg_l.c Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxlu_cfg_l.c Fri Oct 08 13:21:52 2010 +0200 @@ -54,6 +54,7 @@ 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 @@ #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -159,15 +158,7 @@ /* 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_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 @@ /* 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 @@ /* 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 @@ 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 @@ #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 @@ #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 @@ /** 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 fc17462ba612 -r 91397dcffead tools/libxl/libxlu_cfg_l.h --- a/tools/libxl/libxlu_cfg_l.h Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/libxlu_cfg_l.h Fri Oct 08 13:21:52 2010 +0200 @@ -58,6 +58,7 @@ 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 @@ #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -132,15 +131,7 @@ /* 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 @@ /* 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 @@ #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 fc17462ba612 -r 91397dcffead tools/libxl/xl.h --- a/tools/libxl/xl.h Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/xl.h Fri Oct 08 13:21:52 2010 +0200 @@ -79,6 +79,12 @@ 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 fc17462ba612 -r 91397dcffead tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/xl_cmdimpl.c Fri Oct 08 13:21:52 2010 +0200 @@ -213,14 +213,14 @@ return was_name ? libxl_name_to_domid(&ctx, p, domid_r) : 0; } -static int pool_qualifier_to_poolid(const char *p, uint32_t *poolid_r, +static int cpupool_qualifier_to_cpupoolid(const char *p, uint32_t *poolid_r, int *was_name_r) { int was_name; was_name = qualifier_to_id(p, poolid_r); if (was_name_r) *was_name_r = was_name; - return was_name ? libxl_name_to_poolid(&ctx, p, poolid_r) : 0; + return was_name ? libxl_name_to_cpupoolid(&ctx, p, poolid_r) : 0; } static void find_domain(const char *p) @@ -491,7 +491,7 @@ printf("\t(uuid )\n"); } - 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 @@ -694,9 +694,9 @@ if (!xlu_cfg_get_string (config, "pool", &buf)) { c_info->poolid = -1; - pool_qualifier_to_poolid(buf, &c_info->poolid, NULL); - } - c_info->poolname = libxl_poolid_to_name(&ctx, c_info->poolid); + cpupool_qualifier_to_cpupoolid(buf, &c_info->poolid, NULL); + } + c_info->poolname = libxl_cpupoolid_to_name(&ctx, c_info->poolid); if (!c_info->poolname) { fprintf(stderr, "Illegal pool specified\n"); exit(1); @@ -3498,7 +3498,7 @@ 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; } @@ -3513,7 +3513,7 @@ 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) ; @@ -3785,10 +3785,7 @@ 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); @@ -3819,6 +3816,8 @@ 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"); @@ -3845,6 +3844,13 @@ 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 (libxl_cpumap_test(&cpumap, i)) + n++; + printf("free_cpus : %d\n", n); + free(cpumap.map); + } return; } @@ -5260,3 +5266,445 @@ 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 = xrealloc(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_cpupoolid(&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; + } + if (libxl_cpumap_alloc(&cpumap, freemap.size * 8)) { + fprintf(stderr, "Failed to allocate cpumap\n"); + return -ERROR_FAIL; + } + if (!xlu_cfg_get_list(config, "cpus", &cpus, 0, 0)) { + n_cpus = 0; + while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) { + i = atoi(buf); + if ((i < 0) || (i >= freemap.size * 8) || + !libxl_cpumap_test(&freemap, i)) { + fprintf(stderr, "cpu %d illegal or not free\n", i); + return -ERROR_FAIL; + } + libxl_cpumap_set(&cpumap, i); + n_cpus++; + } + } else { + n_cpus = 1; + n = 0; + for (i = 0; i < freemap.size; i++) + if (libxl_cpumap_test(&freemap, i)) { + n++; + libxl_cpumap_set(&cpumap, i); + 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_cpupoolinfo *poolinfo; + int n_pools, p, c, n; + uint32_t poolid; + char *name; + int ret = 0; + + 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_cpupoolid(&ctx, pool, &poolid)) { + fprintf(stderr, "Pool \'%s\' does not exist\n", pool); + return -ERROR_FAIL; + } + } + + poolinfo = libxl_list_cpupool(&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 (!ret && (!pool || (poolinfo[p].poolid != poolid))) { + name = libxl_cpupoolid_to_name(&ctx, poolinfo[p].poolid); + if (!name) { + fprintf(stderr, "error getting cpupool info\n"); + ret = -ERROR_NOMEM; + } + else if (opt_long) { + ret = -ERROR_NI; + } else { + printf("%-19s", name); + free(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"); + } + } + libxl_cpupoolinfo_destroy(poolinfo + p); + } + + return ret; +} + +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 (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || + !libxl_cpupoolid_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 (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || + !libxl_cpupoolid_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 (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || + !libxl_cpupoolid_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 (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || + !libxl_cpupoolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_movedomain(&ctx, poolid, domid); +} diff -r fc17462ba612 -r 91397dcffead tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Fri Oct 08 13:16:43 2010 +0200 +++ b/tools/libxl/xl_cmdtable.c Fri Oct 08 13:21:52 2010 +0200 @@ -338,6 +338,41 @@ "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);