* [Patch 2/2] support of cpupools in xl: commands and library changes
@ 2010-10-01 7:20 Juergen Gross
2010-10-01 9:41 ` Ian Campbell
0 siblings, 1 reply; 5+ messages in thread
From: Juergen Gross @ 2010-10-01 7:20 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
[-- Attachment #1: Type: text/plain, Size: 435 bytes --]
Hi,
attached patch adds support of cpu pools in xl/libxl.
Juergen
--
Juergen Gross Principal Developer Operating Systems
TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
[-- Attachment #2: pools2.patch --]
[-- Type: text/x-patch, Size: 41652 bytes --]
Signed-off-by: juergen.gross@ts.fujitsu.com
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*
diff -r f501dd7581e2 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl.c Fri Oct 01 09:12:27 2010 +0200
@@ -607,10 +607,10 @@ int libxl_domain_info(libxl_ctx *ctx, li
return 0;
}
-libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
+libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool)
{
- libxl_poolinfo *ptr;
- int i;
+ libxl_cpupoolinfo *ptr;
+ int i, m;
xc_cpupoolinfo_t *info;
uint32_t poolid;
libxl_physinfo physinfo;
@@ -627,12 +627,19 @@ libxl_poolinfo * libxl_list_pool(libxl_c
info = xc_cpupool_getinfo(ctx->xch, poolid);
if (info == NULL)
break;
- ptr = realloc(ptr, (i + 1) * sizeof(libxl_poolinfo));
+ ptr = realloc(ptr, (i + 1) * sizeof(libxl_cpupoolinfo));
if (!ptr) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
return NULL;
}
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, physinfo.max_cpu_id + 1))
+ 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);
}
@@ -3228,7 +3235,6 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
xc_domaininfo_t domaininfo;
xc_vcpuinfo_t vcpuinfo;
xc_physinfo_t physinfo = { 0 };
- unsigned num_cpuwords;
if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist");
@@ -3244,10 +3250,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
return NULL;
}
- 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) {
+ 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) {
@@ -3255,7 +3260,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;
}
@@ -3659,3 +3664,180 @@ 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 ret;
+
+ if (libxl_get_physinfo(ctx, &info) != 0)
+ return ERROR_FAIL;
+
+ ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1);
+ if (ret)
+ return ret;
+
+ 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__cpupoolid_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 f501dd7581e2 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl.h Fri Oct 01 09:12:27 2010 +0200
@@ -140,8 +140,6 @@ void libxl_string_list_destroy(libxl_str
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];
@@ -358,7 +356,7 @@ int libxl_domain_info(libxl_ctx*, libxl_
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;
@@ -498,6 +496,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 f501dd7581e2 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl.idl Fri Oct 01 09:12:27 2010 +0200
@@ -16,8 +16,6 @@ libxl_string_list = Builtin("string_list
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 +43,17 @@ SHUTDOWN_* constant."""),
("vcpu_online", uint32),
], destructor_fn=None)
-libxl_poolinfo = Struct("poolinfo", [
- ("poolid", uint32)
- ], destructor_fn=None)
+libxl_cpumap = Struct("cpumap", [
+ ("size", uint32, False, "number of bytes in map"),
+ ("map", Reference(uint64)),
+ ])
+
+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 f501dd7581e2 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl_internal.h Fri Oct 01 09:12:27 2010 +0200
@@ -237,7 +237,7 @@ _hidden char *libxl__abs_path(libxl__gc
#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
* input contains the value of the EAX and ECX register,
diff -r f501dd7581e2 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl_utils.c Fri Oct 01 09:12:27 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 @@ int libxl_name_to_domid(libxl_ctx *ctx,
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,62 @@ char *libxl_poolid_to_name(libxl_ctx *ct
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);
+ }
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)
@@ -675,3 +708,36 @@ out:
libxl__free_all(&gc);
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));
+}
diff -r f501dd7581e2 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxl_utils.h Fri Oct 01 09:12:27 2010 +0200
@@ -21,8 +21,10 @@ unsigned long libxl_get_required_shadow_
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 @@ int libxl_devid_to_device_net2(libxl_ctx
* 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 f501dd7581e2 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxltypes.py Fri Oct 01 09:12:27 2010 +0200
@@ -131,7 +131,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 f501dd7581e2 tools/libxl/libxlu_cfg_l.c
--- a/tools/libxl/libxlu_cfg_l.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxlu_cfg_l.c Fri Oct 01 09:12:27 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 f501dd7581e2 tools/libxl/libxlu_cfg_l.h
--- a/tools/libxl/libxlu_cfg_l.h Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/libxlu_cfg_l.h Fri Oct 01 09:12:27 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 f501dd7581e2 tools/libxl/xl.h
--- a/tools/libxl/xl.h Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/xl.h Fri Oct 01 09:12:27 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 f501dd7581e2 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/xl_cmdimpl.c Fri Oct 01 09:12:27 2010 +0200
@@ -213,14 +213,14 @@ static int domain_qualifier_to_domid(con
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)
@@ -481,7 +481,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
@@ -684,9 +684,9 @@ static void parse_config_data(const char
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);
@@ -3406,7 +3406,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;
}
@@ -3421,7 +3421,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)
;
@@ -3693,10 +3693,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);
@@ -3727,6 +3724,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");
@@ -3753,6 +3752,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 (libxl_cpumap_test(&cpumap, i))
+ n++;
+ printf("free_cpus : %d\n", n);
+ free(cpumap.map);
+ }
return;
}
@@ -5168,3 +5174,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_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);
+ 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 f501dd7581e2 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/libxl/xl_cmdtable.c Fri Oct 01 09:12:27 2010 +0200
@@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = {
"destroy a domain's version 2 virtual network device",
"<Domain> <DevId>",
},
+ { "pool-create",
+ &main_poolcreate,
+ "Create a CPU pool based an ConfigFile",
+ "[options] <ConfigFile> [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] [<CPU Pool>]",
+ "-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",
+ "<CPU Pool>",
+ },
+ { "pool-cpu-add",
+ &main_poolcpuadd,
+ "Adds a CPU to a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-cpu-remove",
+ &main_poolcpuremove,
+ "Removes a CPU from a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-migrate",
+ &main_poolmigrate,
+ "Moves a domain into a CPU pool",
+ "<Domain> <CPU Pool>",
+ },
};
int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
diff -r f501dd7581e2 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Fri Oct 01 09:03:51 2010 +0200
+++ b/tools/python/xen/lowlevel/xl/xl.c Fri Oct 01 09:12:27 2010 +0200
@@ -208,6 +208,11 @@ int attrib__libxl_cpuid_policy_list_set(
return -1;
}
+int attrib__uint64_t_ptr_set(PyObject *v, uint64_t * *pptr)
+{
+ return -1;
+}
+
int attrib__libxl_cpumap_set(PyObject *v, libxl_cpumap *pptr)
{
return -1;
@@ -254,6 +259,11 @@ int attrib__struct_in_addr_set(PyObject
}
PyObject *attrib__libxl_cpuid_policy_list_get(libxl_cpuid_policy_list *pptr)
+{
+ return NULL;
+}
+
+PyObject *attrib__uint64_t_ptr_get(uint64_t * *pptr)
{
return NULL;
}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Patch 2/2] support of cpupools in xl: commands and library changes
2010-10-01 7:20 [Patch 2/2] support of cpupools in xl: commands and library changes Juergen Gross
@ 2010-10-01 9:41 ` Ian Campbell
2010-10-05 13:49 ` Juergen Gross
0 siblings, 1 reply; 5+ messages in thread
From: Ian Campbell @ 2010-10-01 9:41 UTC (permalink / raw)
To: Juergen Gross; +Cc: xen-devel@lists.xensource.com
Not a new issue with this series but is there documentation for the pool
configuration file format or an example somewhere? If not could you
maybe add an example at some point (e.g. under tools/examples)?
On Fri, 2010-10-01 at 08:20 +0100, Juergen Gross wrote:
> Signed-off-by: juergen.gross@ts.fujitsu.com
Should go after the comment...
> 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*
But not the actual xl command names -- I presume this is for xm
compatibility, which is shame but unavoidable I suppose.
> diff -r f501dd7581e2 tools/libxl/libxl.c
> --- a/tools/libxl/libxl.c Fri Oct 01 09:03:51 2010 +0200
> +++ b/tools/libxl/libxl.c Fri Oct 01 09:12:27 2010 +0200
> @@ -607,10 +607,10 @@ int libxl_domain_info(libxl_ctx *ctx, li
> return 0;
> }
>
> -libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
> +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool)
> {
> - libxl_poolinfo *ptr;
> - int i;
> + libxl_cpupoolinfo *ptr;
> + int i, m;
> xc_cpupoolinfo_t *info;
> uint32_t poolid;
> libxl_physinfo physinfo;
> @@ -627,12 +627,19 @@ libxl_poolinfo * libxl_list_pool(libxl_c
> info = xc_cpupool_getinfo(ctx->xch, poolid);
> if (info == NULL)
> break;
> - ptr = realloc(ptr, (i + 1) * sizeof(libxl_poolinfo));
> + ptr = realloc(ptr, (i + 1) * sizeof(libxl_cpupoolinfo));
> if (!ptr) {
> LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
> return NULL;
> }
> 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, physinfo.max_cpu_id + 1))
> + break;
Ah, here's the user of physinfo I couldn't find in the previous patch!
Why isn't this just using "info->cpumap_size * sizeof(*info->cpumap)"
though? (I have a feeling I asked this before but I can't find the
question or answer in the thread anywhere so maybe I just thought about
it).
I have a feeling that most users of these interfaces are more interested
in the number of CPUs represented by the cpumap rather than the number
of bytes which happen to be needed to represent them. Perhaps this is
something you could look at while changing the map to uint8_t?
> @@ -3659,3 +3664,180 @@ 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 ret;
> +
> + if (libxl_get_physinfo(ctx, &info) != 0)
> + return ERROR_FAIL;
> +
> + ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1);
> + if (ret)
> + return ret;
> +
> + if (xc_cpupool_freeinfo(ctx->xch, cpumap->map, cpumap->size)) {
> + free(cpumap->map);
This should be libxl_cpumap_destroy(&cpumap).
> + 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))) {
I see a lot of this sort of thing in various places, perhaps it is worth
(later, not now) having an iterator in the style of the Linux foreach_*
macros? e.g.
xl_cpumap_foreach_present(cpumap, i) {
rc = xc_cpupool_addcpu(ctx->xch, *poolid, i);
...
}
> + 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;
I guess it's a toss up whether this should destroy the partially created
pool or not.
> + }
> + }
> +
> + 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;
Does this return success on failure with errno != EAGAIN?
> + }
> +}
> +
> +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);
I take it this is necessary and that destroying a pool doesn't
implicitly remove all CPUs from the pool?
> + 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;
Same comment wrt failure with errno != EAGAIN.
> +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__cpupoolid_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))
errno != EGAIN handling again.
Have you thought about possible races here? Is it possible that the
reads of vm_path and poolname need to be under the transaction to avoid
races with other operations renaming the pool or migrating the guest
etc?
> @@ -5168,3 +5174,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++;
> + }
Move this loop until after libxl_read_file_contents so you can add the
items directly to the end of the data along with the reallocs and
therefore avoid the 1024 character limitation?
> +
> + 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) {
Leaks previous config_data on failure, need to use a temporary variable.
> +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);
Need to free name somewhere.
> + if (!name) {
> + fprintf(stderr, "error getting cpupool info\n");
> + ret = -ERROR_NOMEM;
> + }
> + else if (opt_long) {
> + ret = -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");
> + }
> + }
> + 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)) {
Given that cpupool_qualifier_to_cpupoolid basically ==
libxl_name_to_cpupoolid is there really any need to check the inverse
before attempting to destroy the pool?
Ian.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Patch 2/2] support of cpupools in xl: commands and library changes
2010-10-01 9:41 ` Ian Campbell
@ 2010-10-05 13:49 ` Juergen Gross
2010-10-06 13:17 ` Ian Campbell
0 siblings, 1 reply; 5+ messages in thread
From: Juergen Gross @ 2010-10-05 13:49 UTC (permalink / raw)
To: Ian Campbell; +Cc: xen-devel@lists.xensource.com
On 10/01/10 11:41, Ian Campbell wrote:
> Not a new issue with this series but is there documentation for the pool
> configuration file format or an example somewhere? If not could you
> maybe add an example at some point (e.g. under tools/examples)?
>
> On Fri, 2010-10-01 at 08:20 +0100, Juergen Gross wrote:
>> Signed-off-by: juergen.gross@ts.fujitsu.com
>
> Should go after the comment...
>
>> 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*
>
> But not the actual xl command names -- I presume this is for xm
> compatibility, which is shame but unavoidable I suppose.
Hmm. What about adding aliases for xm (xm cpupool-*) and using only
the cpupool-* commands for xl?
>
>> diff -r f501dd7581e2 tools/libxl/libxl.c
>> --- a/tools/libxl/libxl.c Fri Oct 01 09:03:51 2010 +0200
>> +++ b/tools/libxl/libxl.c Fri Oct 01 09:12:27 2010 +0200
>> @@ -607,10 +607,10 @@ int libxl_domain_info(libxl_ctx *ctx, li
>> return 0;
>> }
>>
>> -libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
>> +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool)
>> {
>> - libxl_poolinfo *ptr;
>> - int i;
>> + libxl_cpupoolinfo *ptr;
>> + int i, m;
>> xc_cpupoolinfo_t *info;
>> uint32_t poolid;
>> libxl_physinfo physinfo;
>> @@ -627,12 +627,19 @@ libxl_poolinfo * libxl_list_pool(libxl_c
>> info = xc_cpupool_getinfo(ctx->xch, poolid);
>> if (info == NULL)
>> break;
>> - ptr = realloc(ptr, (i + 1) * sizeof(libxl_poolinfo));
>> + ptr = realloc(ptr, (i + 1) * sizeof(libxl_cpupoolinfo));
>> if (!ptr) {
>> LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
>> return NULL;
>> }
>> 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, physinfo.max_cpu_id + 1))
>> + break;
>
> Ah, here's the user of physinfo I couldn't find in the previous patch!
>
> Why isn't this just using "info->cpumap_size * sizeof(*info->cpumap)"
> though? (I have a feeling I asked this before but I can't find the
> question or answer in the thread anywhere so maybe I just thought about
> it).
Changing to xc_get_max_cpus().
>
> I have a feeling that most users of these interfaces are more interested
> in the number of CPUs represented by the cpumap rather than the number
> of bytes which happen to be needed to represent them. Perhaps this is
> something you could look at while changing the map to uint8_t?
I think this would make sense.
>
>> @@ -3659,3 +3664,180 @@ 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 ret;
>> +
>> + if (libxl_get_physinfo(ctx,&info) != 0)
>> + return ERROR_FAIL;
>> +
>> + ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1);
>> + if (ret)
>> + return ret;
>> +
>> + if (xc_cpupool_freeinfo(ctx->xch, cpumap->map, cpumap->size)) {
>> + free(cpumap->map);
>
> This should be libxl_cpumap_destroy(&cpumap).
With the change of xc_cpupool_freeinfo() no need for free() any more.
>
>> + 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))) {
>
> I see a lot of this sort of thing in various places, perhaps it is worth
> (later, not now) having an iterator in the style of the Linux foreach_*
> macros? e.g.
> xl_cpumap_foreach_present(cpumap, i) {
> rc = xc_cpupool_addcpu(ctx->xch, *poolid, i);
> ...
> }
>
I'll look into this when I change the cpumap type.
>> + 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;
>
> I guess it's a toss up whether this should destroy the partially created
> pool or not.
A call of libxl_destroy_cpupool() should do the job.
>
>> + }
>> + }
>> +
>> + 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;
>
> Does this return success on failure with errno != EAGAIN?
Like lots of other libxl functions...
Missing xenstore entries seem not to be regarded as failures.
>
>> + }
>> +}
>> +
>> +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);
>
> I take it this is necessary and that destroying a pool doesn't
> implicitly remove all CPUs from the pool?
Not in the hypervisor. This is subject to the tools.
>
>> + 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;
>
> Same comment wrt failure with errno != EAGAIN.
Same answer as above :-)
>
>> +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__cpupoolid_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))
>
> errno != EGAIN handling again.
>
> Have you thought about possible races here? Is it possible that the
> reads of vm_path and poolname need to be under the transaction to avoid
> races with other operations renaming the pool or migrating the guest
> etc?
Theoretically possible, yes.
>
>> @@ -5168,3 +5174,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++;
>> + }
>
> Move this loop until after libxl_read_file_contents so you can add the
> items directly to the end of the data along with the reallocs and
> therefore avoid the 1024 character limitation?
The filename may be a result of this loop...
>
>> +
>> + 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) {
>
> Leaks previous config_data on failure, need to use a temporary variable.
Hmm. I had the impression xl isn't always free-ing all it's allocated
memory...
Switching to xrealloc.
>
>> +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);
>
> Need to free name somewhere.
I can do it, but I think there is much more work ahead for freeing all
allocated memory in xl!
>
>> + if (!name) {
>> + fprintf(stderr, "error getting cpupool info\n");
>> + ret = -ERROR_NOMEM;
>> + }
>> + else if (opt_long) {
>> + ret = -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");
>> + }
>> + }
>> + 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)) {
>
> Given that cpupool_qualifier_to_cpupoolid basically ==
> libxl_name_to_cpupoolid is there really any need to check the inverse
> before attempting to destroy the pool?
Yes.
cpupool_qualifier_to_cpupoolid() will always return 0 for any positive
integer given to it (like domain_qualifier_to_domid()). This may be
still no valid cpupoolid.
Juergen
--
Juergen Gross Principal Developer Operating Systems
TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [Patch 2/2] support of cpupools in xl: commands and library changes
2010-10-05 13:49 ` Juergen Gross
@ 2010-10-06 13:17 ` Ian Campbell
0 siblings, 0 replies; 5+ messages in thread
From: Ian Campbell @ 2010-10-06 13:17 UTC (permalink / raw)
To: Juergen Gross; +Cc: xen-devel@lists.xensource.com
On Tue, 2010-10-05 at 14:49 +0100, Juergen Gross wrote:
> >> Renamed all cpu pool related names to *cpupool*
> >
> > But not the actual xl command names -- I presume this is for xm
> > compatibility, which is shame but unavoidable I suppose.
>
> Hmm. What about adding aliases for xm (xm cpupool-*) and using only
> the cpupool-* commands for xl?
I'm not sure, what do others on the list think of this?
> >
> >> + }
> >> + }
> >> +
> >> + 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;
> >
> > Does this return success on failure with errno != EAGAIN?
>
> Like lots of other libxl functions...
> Missing xenstore entries seem not to be regarded as failures.
OK, I'm not sure what is considered correct here but if its the norm
then fine.
> >> +
> >> +int main_poolcreate(int argc, char **argv)
> >> +{
[...]
> >> + while (1) {
[...]
> }
> >> +
> >> + memset(extra_config, 0, sizeof(extra_config));
> >> + while (optind< argc) {
[...]
> >> + }
> >
> > Move this loop until after libxl_read_file_contents so you can add the
> > items directly to the end of the data along with the reallocs and
> > therefore avoid the 1024 character limitation?
>
> The filename may be a result of this loop...
OK, it's consistent with xl create too so I guess even though it looks
weird to me it must be ok ;-)
> > Need to free name somewhere.
>
> I can do it, but I think there is much more work ahead for freeing all
> allocated memory in xl!
Some of us have been actively working towards making xl free its memory
correctly since it is a useful to have xl leak free in order to validate
libxl which may be used by longer running toolstacks and hence better
not leak!
I'd certainly like to avoid taking backward steps where possible.
> >> + if (cpupool_qualifier_to_cpupoolid(pool,&poolid, NULL) ||
> >> + !libxl_cpupoolid_to_name(&ctx, poolid)) {
> >
> > Given that cpupool_qualifier_to_cpupoolid basically ==
> > libxl_name_to_cpupoolid is there really any need to check the inverse
> > before attempting to destroy the pool?
>
> Yes.
> cpupool_qualifier_to_cpupoolid() will always return 0 for any positive
> integer given to it (like domain_qualifier_to_domid()). This may be
> still no valid cpupoolid.
I see, cpupool_qualifier_to_cpupoolid is just a more clever strtoul-like
function not an actual cpupoolid lookup function. No problem then.
Thanks,
Ian.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Patch 2/2] support of cpupools in xl: commands and library changes
@ 2010-09-22 5:42 Juergen Gross
0 siblings, 0 replies; 5+ messages in thread
From: Juergen Gross @ 2010-09-22 5:42 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
[-- Attachment #1: Type: text/plain, Size: 434 bytes --]
Hi,
attached patch adds support of cpu pools in xl/libxl.
Juergen
--
Juergen Gross Principal Developer Operating Systems
TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
[-- Attachment #2: pools2.patch --]
[-- Type: text/x-patch, Size: 41699 bytes --]
Signed-off-by: juergen.gross@ts.fujitsu.com
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
diff -r bae7362610b1 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl.c Wed Sep 22 07:28:40 2010 +0200
@@ -606,10 +606,10 @@ int libxl_domain_info(libxl_ctx *ctx, li
return 0;
}
-libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
+libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool)
{
- libxl_poolinfo *ptr;
- int i;
+ libxl_cpupoolinfo *ptr;
+ int i, m;
xc_cpupoolinfo_t *info;
int size;
uint32_t poolid;
@@ -621,7 +621,7 @@ libxl_poolinfo * libxl_list_pool(libxl_c
}
size = physinfo.max_cpu_id + LIBXL__CPUPOOL_INFO_SPARE; /* allow some inactive cpu pools */
- ptr = calloc(size, sizeof(libxl_poolinfo));
+ ptr = calloc(size, sizeof(libxl_cpupoolinfo));
if (!ptr) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
return NULL;
@@ -633,6 +633,13 @@ libxl_poolinfo * libxl_list_pool(libxl_c
if (info == NULL)
break;
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, physinfo.max_cpu_id + 1))
+ 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);
}
@@ -2937,7 +2944,6 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
xc_domaininfo_t domaininfo;
xc_vcpuinfo_t vcpuinfo;
xc_physinfo_t physinfo = { 0 };
- unsigned num_cpuwords;
if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist");
@@ -2953,10 +2959,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
return NULL;
}
- 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) {
+ 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) {
@@ -2964,7 +2969,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;
}
@@ -3368,3 +3373,180 @@ 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 ret;
+
+ if (libxl_get_physinfo(ctx, &info) != 0)
+ return ERROR_FAIL;
+
+ ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1);
+ if (ret)
+ return ret;
+
+ 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__cpupoolid_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 bae7362610b1 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl.h Wed Sep 22 07:28:40 2010 +0200
@@ -140,8 +140,6 @@ void libxl_string_list_destroy(libxl_str
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];
@@ -348,7 +346,7 @@ int libxl_domain_info(libxl_ctx*, libxl_
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;
@@ -488,6 +486,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 bae7362610b1 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl.idl Wed Sep 22 07:28:40 2010 +0200
@@ -16,8 +16,6 @@ libxl_string_list = Builtin("string_list
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")
@@ -44,9 +42,17 @@ SHUTDOWN_* constant."""),
("vcpu_online", uint32),
], destructor_fn=None)
-libxl_poolinfo = Struct("poolinfo", [
- ("poolid", uint32)
- ], destructor_fn=None)
+libxl_cpumap = Struct("cpumap", [
+ ("size", uint32, False, "number of bytes in map"),
+ ("map", Reference(uint64)),
+ ])
+
+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 bae7362610b1 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl_internal.h Wed Sep 22 07:28:40 2010 +0200
@@ -234,9 +234,10 @@ _hidden char *libxl__abs_path(libxl__gc
#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);
#define LIBXL__CPUPOOL_INFO_SPARE 32
+
/* holds the CPUID response for a single CPUID leaf
* input contains the value of the EAX and ECX register,
diff -r bae7362610b1 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl_utils.c Wed Sep 22 07:28:40 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 @@ int libxl_name_to_domid(libxl_ctx *ctx,
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,62 @@ char *libxl_poolid_to_name(libxl_ctx *ct
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);
+ }
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)
@@ -675,3 +708,36 @@ out:
libxl__free_all(&gc);
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));
+}
diff -r bae7362610b1 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxl_utils.h Wed Sep 22 07:28:40 2010 +0200
@@ -21,8 +21,10 @@ unsigned long libxl_get_required_shadow_
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 @@ int libxl_devid_to_device_net2(libxl_ctx
* 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 bae7362610b1 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxltypes.py Wed Sep 22 07:28:40 2010 +0200
@@ -131,7 +131,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 bae7362610b1 tools/libxl/libxlu_cfg_l.c
--- a/tools/libxl/libxlu_cfg_l.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxlu_cfg_l.c Wed Sep 22 07:28:40 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 bae7362610b1 tools/libxl/libxlu_cfg_l.h
--- a/tools/libxl/libxlu_cfg_l.h Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/libxlu_cfg_l.h Wed Sep 22 07:28:40 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 bae7362610b1 tools/libxl/xl.h
--- a/tools/libxl/xl.h Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/xl.h Wed Sep 22 07:28:40 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 bae7362610b1 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/xl_cmdimpl.c Wed Sep 22 07:28:40 2010 +0200
@@ -212,14 +212,14 @@ static int domain_qualifier_to_domid(con
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)
@@ -421,7 +421,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
@@ -624,9 +624,9 @@ static void parse_config_data(const char
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);
@@ -3287,7 +3287,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;
}
@@ -3302,7 +3302,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)
;
@@ -3574,10 +3574,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);
@@ -3608,6 +3605,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");
@@ -3634,6 +3633,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 (libxl_cpumap_test(&cpumap, i))
+ n++;
+ printf("free_cpus : %d\n", n);
+ free(cpumap.map);
+ }
return;
}
@@ -5049,3 +5055,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_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);
+ 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 bae7362610b1 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/libxl/xl_cmdtable.c Wed Sep 22 07:28:40 2010 +0200
@@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = {
"destroy a domain's version 2 virtual network device",
"<Domain> <DevId>",
},
+ { "pool-create",
+ &main_poolcreate,
+ "Create a CPU pool based an ConfigFile",
+ "[options] <ConfigFile> [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] [<CPU Pool>]",
+ "-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",
+ "<CPU Pool>",
+ },
+ { "pool-cpu-add",
+ &main_poolcpuadd,
+ "Adds a CPU to a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-cpu-remove",
+ &main_poolcpuremove,
+ "Removes a CPU from a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-migrate",
+ &main_poolmigrate,
+ "Moves a domain into a CPU pool",
+ "<Domain> <CPU Pool>",
+ },
};
int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
diff -r bae7362610b1 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Wed Sep 22 07:21:32 2010 +0200
+++ b/tools/python/xen/lowlevel/xl/xl.c Wed Sep 22 07:28:40 2010 +0200
@@ -208,6 +208,11 @@ int attrib__libxl_cpuid_policy_list_set(
return -1;
}
+int attrib__uint64_t_ptr_set(PyObject *v, uint64_t * *pptr)
+{
+ return -1;
+}
+
int attrib__libxl_cpumap_set(PyObject *v, libxl_cpumap *pptr)
{
return -1;
@@ -254,6 +259,11 @@ int attrib__struct_in_addr_set(PyObject
}
PyObject *attrib__libxl_cpuid_policy_list_get(libxl_cpuid_policy_list *pptr)
+{
+ return NULL;
+}
+
+PyObject *attrib__uint64_t_ptr_get(uint64_t * *pptr)
{
return NULL;
}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-10-06 13:17 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-01 7:20 [Patch 2/2] support of cpupools in xl: commands and library changes Juergen Gross
2010-10-01 9:41 ` Ian Campbell
2010-10-05 13:49 ` Juergen Gross
2010-10-06 13:17 ` Ian Campbell
-- strict thread matches above, loose matches on Subject: below --
2010-09-22 5:42 Juergen Gross
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.