All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch] support of cpu pools in xl
@ 2010-09-17  6:10 Juergen Gross
  2010-09-17  9:46 ` Ian Campbell
  0 siblings, 1 reply; 3+ messages in thread
From: Juergen Gross @ 2010-09-17  6:10 UTC (permalink / raw)
  To: xen-devel@lists.xensource.com, Ian Campbell

[-- Attachment #1: Type: text/plain, Size: 693 bytes --]

Hi,

attached patch adds support of cpu pools in xl/libxl.
Ian, I didn't split up this patch, because the updated libxl_cpumask structure
requires changes to xl in any case.
BTW: I realized that libxlu_cfg_l.c seems to be in the repository. Isn't this
      file generated by make? I think it should be removed there.

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: cpupools-xl.patch --]
[-- Type: text/x-patch, Size: 32574 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 d978675f3d53 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.c	Fri Sep 17 07:42:30 2010 +0200
@@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c
 libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
 {
     libxl_poolinfo *ptr;
-    int i, ret;
-    xc_cpupoolinfo_t info[256];
-    int size = 256;
+    int i, m;
+    xc_cpupoolinfo_t *info;
+    int size;
+    uint32_t poolid;
+    libxl_physinfo physinfo;
+
+    if (libxl_get_physinfo(ctx, &physinfo) != 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info");
+        return NULL;
+    }
+    size = physinfo.max_cpu_id + 32;
 
     ptr = calloc(size, sizeof(libxl_poolinfo));
     if (!ptr) {
@@ -619,16 +627,23 @@ libxl_poolinfo * libxl_list_pool(libxl_c
         return NULL;
     }
 
-    ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
-    if (ret<0) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info");
-        return NULL;
+    poolid = 0;
+    for (i = 0; i < size; i++) {
+        info = xc_cpupool_getinfo(ctx->xch, poolid);
+        if (info == NULL)
+            break;
+        ptr[i].poolid = info->cpupool_id;
+        ptr[i].sched_id = info->sched_id;
+        ptr[i].n_dom = info->n_dom;
+        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[m];
+        poolid = info->cpupool_id + 1;
+        free(info);
     }
 
-    for (i = 0; i < ret; i++) {
-        ptr[i].poolid = info[i].cpupool_id;
-    }
-    *nb_pool = ret;
+    *nb_pool = i;
     return ptr;
 }
 
@@ -2928,7 +2943,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");
@@ -2944,10 +2958,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) {
@@ -2955,7 +2968,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;
         }
@@ -3359,3 +3372,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__poolid_to_name(&gc, poolid);
+    vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path));
+    for (; vm_path;) {
+        t = xs_transaction_start(ctx->xsh);
+
+        libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), poolname);
+
+        if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
+            break;
+    }
+
+    return 0;
+}
diff -r d978675f3d53 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.h	Fri Sep 17 07:42:30 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];
 
@@ -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 d978675f3d53 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.idl	Fri Sep 17 07:42:30 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_cpumap = Struct("cpumap", [
+    ("size", uint32, False, "number of bytes in map"),
+    ("map",  Reference(uint64)),
+    ])
+                      
 libxl_poolinfo = Struct("poolinfo", [
-    ("poolid", uint32)
-    ], destructor_fn=None)
+    ("poolid",      uint32),
+    ("sched_id",    uint32),
+    ("n_dom",       uint32),
+    ("cpumap",      libxl_cpumap)
+    ], destructor_fn="libxl_poolinfo_destroy")
 
 libxl_vminfo = Struct("vminfo", [
     ("uuid", libxl_uuid),
diff -r d978675f3d53 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl_utils.c	Fri Sep 17 07:42:30 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)
 {
@@ -124,19 +135,41 @@ int libxl_name_to_poolid(libxl_ctx *ctx,
         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_poolid_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_poolinfo_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 d978675f3d53 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl_utils.h	Fri Sep 17 07:42:30 2010 +0200
@@ -23,6 +23,8 @@ char *libxl_domid_to_name(libxl_ctx *ctx
 char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid);
 int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
 char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid);
+int libxl_name_to_schedid(libxl_ctx *ctx, const char *name);
+char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid);
 int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid);
 int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid);
 int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name);
@@ -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 d978675f3d53 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxltypes.py	Fri Sep 17 07:42:30 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 d978675f3d53 tools/libxl/xl.h
--- a/tools/libxl/xl.h	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl.h	Fri Sep 17 07:42:30 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 d978675f3d53 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Fri Sep 17 07:42:30 2010 +0200
@@ -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
@@ -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_poolid(&ctx, name, &poolid)) {
+        fprintf(stderr, "Pool name \"%s\" already exists\n", name);
+        return -ERROR_FAIL;
+    }
+
+    if (!xlu_cfg_get_string (config, "sched", &buf)) {
+        if ((schedid = libxl_name_to_schedid(&ctx, buf)) < 0) {
+            fprintf(stderr, "Unknown scheduler\n");
+            return -ERROR_FAIL;
+        }
+    } else {
+        if ((schedid = libxl_get_sched_id(&ctx)) < 0) {
+            fprintf(stderr, "get_sched_id sysctl failed.\n");
+            return -ERROR_FAIL;
+        }
+    }
+    sched = libxl_schedid_to_name(&ctx, schedid);
+
+    if (libxl_get_freecpus(&ctx, &freemap)) {
+        fprintf(stderr, "libxl_get_freecpus failed\n");
+        return -ERROR_FAIL;
+    }
+    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)) {
+        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_poolinfo *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_poolid(&ctx, pool, &poolid)) {
+            fprintf(stderr, "Pool \'%s\' does not exist\n", pool);
+            return -ERROR_FAIL;
+        }
+    }
+
+    poolinfo = libxl_list_pool(&ctx, &n_pools);
+    if (!poolinfo) {
+        fprintf(stderr, "error getting cpupool info\n");
+        return -ERROR_NOMEM;
+    }
+
+    if (!opt_long) {
+        printf("%-19s", "Name");
+        if (opt_cpus)
+            printf("CPU list\n");
+        else
+            printf("CPUs   Sched     Active   Domain count\n");
+    }
+
+    for (p = 0; p < n_pools; p++) {
+        if (!ret && (!pool || (poolinfo[p].poolid != poolid))) {
+            name = libxl_poolid_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_poolinfo_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 (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+        !libxl_poolid_to_name(&ctx, poolid)) {
+        fprintf(stderr, "unknown pool \'%s\'\n", pool);
+        return -ERROR_FAIL;
+    }
+
+    return -libxl_destroy_cpupool(&ctx, poolid);
+}
+
+int main_poolcpuadd(int argc, char **argv)
+{
+    int opt;
+    char *pool;
+    uint32_t poolid;
+    int cpu;
+
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("pool-cpu-add");
+            return 0;
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    pool = argv[optind++];
+    if (!pool) {
+        fprintf(stderr, "no cpupool specified\n");
+        help("pool-cpu-add");
+        return -ERROR_FAIL;
+    }
+
+    if (!argv[optind]) {
+        fprintf(stderr, "no cpu specified\n");
+        help("pool-cpu-add");
+        return -ERROR_FAIL;
+    }
+    cpu = atoi(argv[optind]);
+
+    if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+        !libxl_poolid_to_name(&ctx, poolid)) {
+        fprintf(stderr, "unknown pool \'%s\'\n", pool);
+        return -ERROR_FAIL;
+    }
+
+    return -libxl_cpupool_cpuadd(&ctx, poolid, cpu);
+}
+
+int main_poolcpuremove(int argc, char **argv)
+{
+    int opt;
+    char *pool;
+    uint32_t poolid;
+    int cpu;
+
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("pool-cpu-remove");
+            return 0;
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    pool = argv[optind++];
+    if (!pool) {
+        fprintf(stderr, "no cpupool specified\n");
+        help("pool-cpu-remove");
+        return -ERROR_FAIL;
+    }
+
+    if (!argv[optind]) {
+        fprintf(stderr, "no cpu specified\n");
+        help("pool-cpu-remove");
+        return -ERROR_FAIL;
+    }
+    cpu = atoi(argv[optind]);
+
+    if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+        !libxl_poolid_to_name(&ctx, poolid)) {
+        fprintf(stderr, "unknown pool \'%s\'\n", pool);
+        return -ERROR_FAIL;
+    }
+
+    return -libxl_cpupool_cpuremove(&ctx, poolid, cpu);
+}
+
+int main_poolmigrate(int argc, char **argv)
+{
+    int opt;
+    char *pool;
+    uint32_t poolid;
+    char *dom;
+    uint32_t domid;
+
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("pool-migrate");
+            return 0;
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    dom = argv[optind++];
+    if (!dom) {
+       fprintf(stderr, "no domain specified\n");
+        help("pool-migrate");
+        return -ERROR_FAIL;
+    }
+
+    pool = argv[optind++];
+    if (!pool) {
+        fprintf(stderr, "no cpupool specified\n");
+        help("pool-migrate");
+        return -ERROR_FAIL;
+    }
+
+    if (domain_qualifier_to_domid(dom, &domid, NULL) ||
+        !libxl_domid_to_name(&ctx, domid)) {
+        fprintf(stderr, "unknown domain \'%s\'\n", dom);
+        return -ERROR_FAIL;
+    }
+
+    if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+        !libxl_poolid_to_name(&ctx, poolid)) {
+        fprintf(stderr, "unknown pool \'%s\'\n", pool);
+        return -ERROR_FAIL;
+    }
+
+    return -libxl_cpupool_movedomain(&ctx, poolid, domid);
+}
diff -r d978675f3d53 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c	Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl_cmdtable.c	Fri Sep 17 07:42:30 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);

[-- 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] 3+ messages in thread

* Re: [Patch] support of cpu pools in xl
  2010-09-17  6:10 Juergen Gross
@ 2010-09-17  9:46 ` Ian Campbell
  0 siblings, 0 replies; 3+ messages in thread
From: Ian Campbell @ 2010-09-17  9:46 UTC (permalink / raw)
  To: Juergen Gross; +Cc: xen-devel@lists.xensource.com


> On Fri, 2010-09-17 at 07:10 +0100, Juergen Gross wrote:
> 
> attached patch adds support of cpu pools in xl/libxl.
> Ian, I didn't split up this patch, because the updated libxl_cpumask
> structure requires changes to xl in any case.

That's fine.

> BTW: I realized that libxlu_cfg_l.c seems to be in the repository.
> Isn't this file generated by make? I think it should be removed there.

In an ideal world, yes. I think this was a workaround for buggy versions
of flex observed in the field or something.

> 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 d978675f3d53 tools/libxl/libxl.c
> --- a/tools/libxl/libxl.c       Thu Sep 16 18:29:26 2010 +0100
> +++ b/tools/libxl/libxl.c       Fri Sep 17 07:42:30 2010 +0200
> @@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c
>  libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
>  {
>      libxl_poolinfo *ptr;
> -    int i, ret;
> -    xc_cpupoolinfo_t info[256];
> -    int size = 256;
> +    int i, m;
> +    xc_cpupoolinfo_t *info;
> +    int size;
> +    uint32_t poolid;
> +    libxl_physinfo physinfo;
> +
> +    if (libxl_get_physinfo(ctx, &physinfo) != 0) {
> +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info");
> +        return NULL;
> +    }
> +    size = physinfo.max_cpu_id + 32;

Where does the number 32 come from?

>      ptr = calloc(size, sizeof(libxl_poolinfo));

>      if (!ptr) {
> @@ -619,16 +627,23 @@ libxl_poolinfo * libxl_list_pool(libxl_c
>          return NULL;
>      }
>  
> -    ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
> -    if (ret<0) {
> -        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info");
> -        return NULL;
> +    poolid = 0;
> +    for (i = 0; i < size; i++) {
> +        info = xc_cpupool_getinfo(ctx->xch, poolid);
> +        if (info == NULL)
> +            break;
> +        ptr[i].poolid = info->cpupool_id;
> +        ptr[i].sched_id = info->sched_id;
> +        ptr[i].n_dom = info->n_dom;
> +        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[m];

I guess if "physinfo.max_cpu_id + 1" does not correspond to
info->cpumap_size then that is a serious error but if it does happen
then you may run over the end of either ptr[i].cpumap.map or
info->cpumap.

Ian.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Patch] support of cpu pools in xl
@ 2010-09-20  6:46 Juergen Gross
  0 siblings, 0 replies; 3+ messages in thread
From: Juergen Gross @ 2010-09-20  6:46 UTC (permalink / raw)
  To: xen-devel@lists.xensource.com, Ian Campbell

[-- Attachment #1: Type: text/plain, Size: 729 bytes --]

Hi,

next version of cpupool support in xl.
Changes since last version: rename "pool" to "cpupool" in interfaces, use
#define instead of magic constant.
Ian, I had to add functions attrib__uint64_t_ptr_set/get in
python/xen/lowlevel/xl/xl.c to get a proper build. Could you please look if
the dummy implementation is okay? I'm really not sure about it.


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: cpupools-xl.patch --]
[-- Type: text/x-patch, Size: 42177 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 7405e0ddb912 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl.c	Mon Sep 20 08:38:02 2010 +0200
@@ -606,29 +606,45 @@ 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, ret;
-    xc_cpupoolinfo_t info[256];
-    int size = 256;
+    libxl_cpupoolinfo *ptr;
+    int i, m;
+    xc_cpupoolinfo_t *info;
+    int size;
+    uint32_t poolid;
+    libxl_physinfo physinfo;
 
-    ptr = calloc(size, sizeof(libxl_poolinfo));
+    if (libxl_get_physinfo(ctx, &physinfo) != 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info");
+        return NULL;
+    }
+    size = physinfo.max_cpu_id + LIBXL__CPUPOOL_INFO_SPARE;	/* allow some inactive cpu pools */
+
+    ptr = calloc(size, sizeof(libxl_cpupoolinfo));
     if (!ptr) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
         return NULL;
     }
 
-    ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
-    if (ret<0) {
-        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info");
-        return NULL;
+    poolid = 0;
+    for (i = 0; i < size; i++) {
+        info = xc_cpupool_getinfo(ctx->xch, poolid);
+        if (info == NULL)
+            break;
+        ptr[i].poolid = info->cpupool_id;
+        ptr[i].sched_id = info->sched_id;
+        ptr[i].n_dom = info->n_dom;
+        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);
     }
 
-    for (i = 0; i < ret; i++) {
-        ptr[i].poolid = info[i].cpupool_id;
-    }
-    *nb_pool = ret;
+    *nb_pool = i;
     return ptr;
 }
 
@@ -2928,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");
@@ -2944,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) {
@@ -2955,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;
         }
@@ -3359,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 7405e0ddb912 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl.h	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl.idl	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl_internal.h	Mon Sep 20 08:38:02 2010 +0200
@@ -234,7 +234,9 @@ _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
diff -r 7405e0ddb912 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl_utils.c	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxl_utils.h	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxltypes.py	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxlu_cfg_l.c
--- a/tools/libxl/libxlu_cfg_l.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxlu_cfg_l.c	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/libxlu_cfg_l.h
--- a/tools/libxl/libxlu_cfg_l.h	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/libxlu_cfg_l.h	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/xl.h
--- a/tools/libxl/xl.h	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/xl.h	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c	Mon Sep 20 08:38:02 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)) {
+        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 7405e0ddb912 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/libxl/xl_cmdtable.c	Mon Sep 20 08:38:02 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 7405e0ddb912 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c	Sat Sep 18 08:57:15 2010 +0100
+++ b/tools/python/xen/lowlevel/xl/xl.c	Mon Sep 20 08:38:02 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] 3+ messages in thread

end of thread, other threads:[~2010-09-20  6:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-20  6:46 [Patch] support of cpu pools in xl Juergen Gross
  -- strict thread matches above, loose matches on Subject: below --
2010-09-17  6:10 Juergen Gross
2010-09-17  9:46 ` Ian Campbell

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.