debuggers.hg

changeset 22319:063927551e9c

tools: cpupools: xl: commands and library changes

Support of cpu pools in libxl and xl:
library functions
xl cpupool-create
xl cpupool-list
xl cpupool-destroy
xl cpupool-cpu-add
xl cpupool-cpu-remove
xl cpupool-migrate
Renamed all cpu pool related names to *cpupool*

Signed-off-by: juergen.gross@ts.fujitsu.com
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Juergen Gross <juergen.gross@ts.fujitsu.com>
date Thu Oct 21 18:36:22 2010 +0100 (2010-10-21)
parents 87e8339826f7
children 783c4d9d098f
files tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl.idl tools/libxl/libxl_internal.h tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h tools/libxl/libxltypes.py tools/libxl/libxlu_cfg_l.c tools/libxl/libxlu_cfg_l.h tools/libxl/xl.h tools/libxl/xl_cmdimpl.c tools/libxl/xl_cmdtable.c
line diff
     1.1 --- a/tools/libxl/libxl.c	Thu Oct 21 18:35:18 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Thu Oct 21 18:36:22 2010 +0100
     1.3 @@ -607,21 +607,26 @@ int libxl_domain_info(libxl_ctx *ctx, li
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
     1.8 +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx *ctx, int *nb_pool)
     1.9  {
    1.10 -    libxl_poolinfo *ptr, *tmp;
    1.11 -    int i;
    1.12 +    libxl_cpupoolinfo *ptr, *tmp;
    1.13 +    int i, m, ncpu;
    1.14      xc_cpupoolinfo_t *info;
    1.15      uint32_t poolid;
    1.16  
    1.17      ptr = NULL;
    1.18 +    ncpu = xc_get_max_cpus(ctx->xch);
    1.19 +    if (!ncpu) {
    1.20 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting max cpu number");
    1.21 +        return NULL;
    1.22 +    }
    1.23  
    1.24      poolid = 0;
    1.25      for (i = 0;; i++) {
    1.26          info = xc_cpupool_getinfo(ctx->xch, poolid);
    1.27          if (info == NULL)
    1.28              break;
    1.29 -        tmp = realloc(ptr, (i + 1) * sizeof(libxl_poolinfo));
    1.30 +        tmp = realloc(ptr, (i + 1) * sizeof(libxl_cpupoolinfo));
    1.31          if (!tmp) {
    1.32              LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpupool info");
    1.33              free(ptr);
    1.34 @@ -629,6 +634,13 @@ libxl_poolinfo * libxl_list_pool(libxl_c
    1.35          }
    1.36          ptr = tmp;
    1.37          ptr[i].poolid = info->cpupool_id;
    1.38 +        ptr[i].sched_id = info->sched_id;
    1.39 +        ptr[i].n_dom = info->n_dom;
    1.40 +        if (libxl_cpumap_alloc(&ptr[i].cpumap, ncpu))
    1.41 +            break;
    1.42 +        for (m = 0; m < ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++)
    1.43 +            ptr[i].cpumap.map[m] = (info->cpumap_size > (m * sizeof(*ptr[i].cpumap.map))) ?
    1.44 +                info->cpumap[m] : 0;
    1.45          poolid = info->cpupool_id + 1;
    1.46          free(info);
    1.47      }
    1.48 @@ -3211,7 +3223,6 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
    1.49      libxl_vcpuinfo *ptr, *ret;
    1.50      xc_domaininfo_t domaininfo;
    1.51      xc_vcpuinfo_t vcpuinfo;
    1.52 -    unsigned num_cpuwords;
    1.53  
    1.54      if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) {
    1.55          LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist");
    1.56 @@ -3223,10 +3234,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
    1.57          return NULL;
    1.58      }
    1.59  
    1.60 -    num_cpuwords = ((*nrcpus + 63) / 64);
    1.61      for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) {
    1.62 -        ptr->cpumap = malloc(num_cpuwords * sizeof(*ptr->cpumap));
    1.63 -        if (!ptr->cpumap) {
    1.64 +        if (libxl_cpumap_alloc(&ptr->cpumap, *nrcpus)) {
    1.65 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpumap");
    1.66              return NULL;
    1.67          }
    1.68          if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) {
    1.69 @@ -3234,7 +3244,7 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
    1.70              return NULL;
    1.71          }
    1.72          if (xc_vcpu_getaffinity(ctx->xch, domid, *nb_vcpu,
    1.73 -            ptr->cpumap, ((*nrcpus) + 7) / 8) == -1) {
    1.74 +            ptr->cpumap.map, ((*nrcpus) + 7) / 8) == -1) {
    1.75              LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting vcpu affinity");
    1.76              return NULL;
    1.77          }
    1.78 @@ -3917,3 +3927,176 @@ void libxl_file_reference_destroy(libxl_
    1.79      libxl__file_reference_unmap(f);
    1.80      free(f->path);
    1.81  }
    1.82 +
    1.83 +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap)
    1.84 +{
    1.85 +    int ncpus;
    1.86 +
    1.87 +    cpumap->map = xc_cpupool_freeinfo(ctx->xch, &ncpus);
    1.88 +    if (cpumap->map == NULL)
    1.89 +        return ERROR_FAIL;
    1.90 +
    1.91 +    cpumap->size = (ncpus + 7) / 8;
    1.92 +
    1.93 +    return 0;
    1.94 +}
    1.95 +
    1.96 +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid,
    1.97 +                         libxl_cpumap cpumap, libxl_uuid *uuid,
    1.98 +                         uint32_t *poolid)
    1.99 +{
   1.100 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   1.101 +    int rc;
   1.102 +    int i;
   1.103 +    xs_transaction_t t;
   1.104 +    char *uuid_string;
   1.105 +
   1.106 +    uuid_string = libxl__uuid2string(&gc, *uuid);
   1.107 +    if (!uuid_string)
   1.108 +        return ERROR_NOMEM;
   1.109 +
   1.110 +    rc = xc_cpupool_create(ctx->xch, poolid, schedid);
   1.111 +    if (rc) {
   1.112 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.113 +           "Could not create cpupool");
   1.114 +        return ERROR_FAIL;
   1.115 +    }
   1.116 +
   1.117 +    for (i = 0; i < cpumap.size * 8; i++)
   1.118 +        if (cpumap.map[i / 64] & (1L << (i % 64))) {
   1.119 +            rc = xc_cpupool_addcpu(ctx->xch, *poolid, i);
   1.120 +            if (rc) {
   1.121 +                LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.122 +                    "Error moving cpu to cpupool");
   1.123 +                libxl_destroy_cpupool(ctx, *poolid);
   1.124 +                return ERROR_FAIL;
   1.125 +            }
   1.126 +        }
   1.127 +
   1.128 +    for (;;) {
   1.129 +        t = xs_transaction_start(ctx->xsh);
   1.130 +
   1.131 +        xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/pool/%d", *poolid));
   1.132 +        libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/uuid", *poolid),
   1.133 +                 uuid_string);
   1.134 +        libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/name", *poolid),
   1.135 +                 name);
   1.136 +
   1.137 +        if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
   1.138 +            return 0;
   1.139 +    }
   1.140 +}
   1.141 +
   1.142 +int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid)
   1.143 +{
   1.144 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   1.145 +    int rc, i;
   1.146 +    xc_cpupoolinfo_t *info;
   1.147 +    xs_transaction_t t;
   1.148 +
   1.149 +    info = xc_cpupool_getinfo(ctx->xch, poolid);
   1.150 +    if (info == NULL)
   1.151 +        return ERROR_NOMEM;
   1.152 +
   1.153 +    rc = ERROR_INVAL;
   1.154 +    if ((info->cpupool_id != poolid) || (info->n_dom))
   1.155 +        goto out;
   1.156 +
   1.157 +    for (i = 0; i < info->cpumap_size; i++)
   1.158 +        if (info->cpumap[i / 64] & (1L << (i % 64))) {
   1.159 +            rc = xc_cpupool_removecpu(ctx->xch, poolid, i);
   1.160 +            if (rc) {
   1.161 +                LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.162 +                    "Error removing cpu from cpupool");
   1.163 +                rc = ERROR_FAIL;
   1.164 +                goto out;
   1.165 +            }
   1.166 +        }
   1.167 +
   1.168 +    rc = xc_cpupool_destroy(ctx->xch, poolid);
   1.169 +    if (rc) {
   1.170 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "Could not destroy cpupool");
   1.171 +        rc = ERROR_FAIL;
   1.172 +        goto out;
   1.173 +    }
   1.174 +
   1.175 +    for (;;) {
   1.176 +        t = xs_transaction_start(ctx->xsh);
   1.177 +
   1.178 +        xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/pool/%d", poolid));
   1.179 +
   1.180 +        if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
   1.181 +            break;
   1.182 +    }
   1.183 +
   1.184 +    rc = 0;
   1.185 +
   1.186 +out:
   1.187 +    free(info);
   1.188 +
   1.189 +    return rc;
   1.190 +}
   1.191 +
   1.192 +int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu)
   1.193 +{
   1.194 +    int rc;
   1.195 +
   1.196 +    rc = xc_cpupool_addcpu(ctx->xch, poolid, cpu);
   1.197 +    if (rc) {
   1.198 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.199 +            "Error moving cpu to cpupool");
   1.200 +        return ERROR_FAIL;
   1.201 +    }
   1.202 +    return 0;
   1.203 +}
   1.204 +
   1.205 +int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu)
   1.206 +{
   1.207 +    int rc;
   1.208 +
   1.209 +    rc = xc_cpupool_removecpu(ctx->xch, poolid, cpu);
   1.210 +    if (rc) {
   1.211 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.212 +            "Error removing cpu from cpupool");
   1.213 +        return ERROR_FAIL;
   1.214 +    }
   1.215 +    return 0;
   1.216 +}
   1.217 +
   1.218 +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid)
   1.219 +{
   1.220 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   1.221 +    int rc;
   1.222 +    char *dom_path;
   1.223 +    char *vm_path;
   1.224 +    char *poolname;
   1.225 +    xs_transaction_t t;
   1.226 +
   1.227 +    dom_path = libxl__xs_get_dompath(&gc, domid);
   1.228 +    if (!dom_path) {
   1.229 +        return ERROR_FAIL;
   1.230 +    }
   1.231 +
   1.232 +    rc = xc_cpupool_movedomain(ctx->xch, poolid, domid);
   1.233 +    if (rc) {
   1.234 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
   1.235 +            "Error moving domain to cpupool");
   1.236 +        return ERROR_FAIL;
   1.237 +    }
   1.238 +
   1.239 +    for (;;) {
   1.240 +        t = xs_transaction_start(ctx->xsh);
   1.241 +
   1.242 +        poolname = libxl__cpupoolid_to_name(&gc, poolid);
   1.243 +        vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path));
   1.244 +        if (!vm_path)
   1.245 +            break;
   1.246 +
   1.247 +        libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), poolname);
   1.248 +
   1.249 +        if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
   1.250 +            break;
   1.251 +    }
   1.252 +
   1.253 +    return 0;
   1.254 +}
     2.1 --- a/tools/libxl/libxl.h	Thu Oct 21 18:35:18 2010 +0100
     2.2 +++ b/tools/libxl/libxl.h	Thu Oct 21 18:36:22 2010 +0100
     2.3 @@ -141,9 +141,13 @@ void libxl_string_list_destroy(libxl_str
     2.4  typedef char **libxl_key_value_list;
     2.5  void libxl_key_value_list_destroy(libxl_key_value_list *kvl);
     2.6  
     2.7 -typedef uint64_t *libxl_cpumap;
     2.8 +typedef uint32_t libxl_hwcap[8];
     2.9  
    2.10 -typedef uint32_t libxl_hwcap[8];
    2.11 +typedef struct {
    2.12 +    uint32_t size;          /* number of bytes in map */
    2.13 +    uint64_t *map;
    2.14 +} libxl_cpumap;
    2.15 +void libxl_cpumap_destroy(libxl_cpumap *map);
    2.16  
    2.17  typedef enum {
    2.18      XENFV = 1,
    2.19 @@ -361,7 +365,7 @@ int libxl_primary_console_exec(libxl_ctx
    2.20  int libxl_domain_info(libxl_ctx*, libxl_dominfo *info_r,
    2.21                        uint32_t domid);
    2.22  libxl_dominfo * libxl_list_domain(libxl_ctx*, int *nb_domain);
    2.23 -libxl_poolinfo * libxl_list_pool(libxl_ctx*, int *nb_pool);
    2.24 +libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool);
    2.25  libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm);
    2.26  
    2.27  typedef struct libxl__device_model_starting libxl_device_model_starting;
    2.28 @@ -504,6 +508,15 @@ libxl_net2info *libxl_device_net2_list(l
    2.29  int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2,
    2.30                            int wait);
    2.31  
    2.32 +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap);
    2.33 +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid,
    2.34 +                         libxl_cpumap cpumap, libxl_uuid *uuid,
    2.35 +                         uint32_t *poolid);
    2.36 +int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid);
    2.37 +int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
    2.38 +int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
    2.39 +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid);
    2.40 +
    2.41  /* common paths */
    2.42  const char *libxl_sbindir_path(void);
    2.43  const char *libxl_bindir_path(void);
     3.1 --- a/tools/libxl/libxl.idl	Thu Oct 21 18:35:18 2010 +0100
     3.2 +++ b/tools/libxl/libxl.idl	Thu Oct 21 18:36:22 2010 +0100
     3.3 @@ -6,6 +6,7 @@
     3.4  libxl_ctx = Builtin("ctx")
     3.5  libxl_uuid = Builtin("uuid")
     3.6  libxl_mac = Builtin("mac")
     3.7 +libxl_cpumap = Builtin("cpumap", destructor_fn="libxl_cpumap_destroy", passby=PASS_BY_REFERENCE)
     3.8  libxl_qemu_machine_type = Number("qemu_machine_type", namespace="libxl_")
     3.9  libxl_console_consback = Number("console_consback", namespace="libxl_")
    3.10  libxl_console_constype = Number("console_constype", namespace="libxl_")
    3.11 @@ -17,8 +18,6 @@ libxl_string_list = Builtin("string_list
    3.12  libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE)
    3.13  libxl_file_reference = Builtin("file_reference", destructor_fn="libxl_file_reference_destroy", passby=PASS_BY_REFERENCE)
    3.14  
    3.15 -libxl_cpumap = Builtin("cpumap", destructor_fn="free")
    3.16 -
    3.17  libxl_hwcap = Builtin("hwcap")
    3.18  
    3.19  #
    3.20 @@ -45,9 +44,12 @@ SHUTDOWN_* constant."""),
    3.21      ("vcpu_online", uint32),
    3.22      ], destructor_fn=None)
    3.23  
    3.24 -libxl_poolinfo = Struct("poolinfo", [
    3.25 -    ("poolid", uint32)
    3.26 -    ], destructor_fn=None)
    3.27 +libxl_cpupoolinfo = Struct("cpupoolinfo", [
    3.28 +    ("poolid",      uint32),
    3.29 +    ("sched_id",    uint32),
    3.30 +    ("n_dom",       uint32),
    3.31 +    ("cpumap",      libxl_cpumap)
    3.32 +    ])
    3.33  
    3.34  libxl_vminfo = Struct("vminfo", [
    3.35      ("uuid", libxl_uuid),
     4.1 --- a/tools/libxl/libxl_internal.h	Thu Oct 21 18:35:18 2010 +0100
     4.2 +++ b/tools/libxl/libxl_internal.h	Thu Oct 21 18:36:22 2010 +0100
     4.3 @@ -235,7 +235,7 @@ struct libxl__device_model_starting {
     4.4  #define LIBXL__LOG_ERROR   XTL_ERROR
     4.5  
     4.6  _hidden char *libxl__domid_to_name(libxl__gc *gc, uint32_t domid);
     4.7 -_hidden char *libxl__poolid_to_name(libxl__gc *gc, uint32_t poolid);
     4.8 +_hidden char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid);
     4.9  
    4.10  
    4.11    /* holds the CPUID response for a single CPUID leaf
     5.1 --- a/tools/libxl/libxl_utils.c	Thu Oct 21 18:35:18 2010 +0100
     5.2 +++ b/tools/libxl/libxl_utils.c	Thu Oct 21 18:36:22 2010 +0100
     5.3 @@ -31,6 +31,17 @@
     5.4  #include "libxl_utils.h"
     5.5  #include "libxl_internal.h"
     5.6  
     5.7 +struct schedid_name {
     5.8 +    char *name;
     5.9 +    int id;
    5.10 +};
    5.11 +
    5.12 +static struct schedid_name schedid_name[] = {
    5.13 +    { "credit", XEN_SCHEDULER_CREDIT },
    5.14 +    { "sedf", XEN_SCHEDULER_SEDF },
    5.15 +    { "credit2", XEN_SCHEDULER_CREDIT2 },
    5.16 +    { NULL, -1 }
    5.17 +};
    5.18  
    5.19  unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus)
    5.20  {
    5.21 @@ -90,7 +101,7 @@ int libxl_name_to_domid(libxl_ctx *ctx, 
    5.22      return ret;
    5.23  }
    5.24  
    5.25 -char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid)
    5.26 +char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid)
    5.27  {
    5.28      unsigned int len;
    5.29      char path[strlen("/local/pool") + 12];
    5.30 @@ -103,42 +114,63 @@ char *libxl_poolid_to_name(libxl_ctx *ct
    5.31      return s;
    5.32  }
    5.33  
    5.34 -char *libxl__poolid_to_name(libxl__gc *gc, uint32_t poolid)
    5.35 +char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid)
    5.36  {
    5.37 -    char *s = libxl_poolid_to_name(libxl__gc_owner(gc), poolid);
    5.38 +    char *s = libxl_cpupoolid_to_name(libxl__gc_owner(gc), poolid);
    5.39      if ( s )
    5.40          libxl__ptr_add(gc, s);
    5.41      return s;
    5.42  }
    5.43  
    5.44 -int libxl_name_to_poolid(libxl_ctx *ctx, const char *name,
    5.45 +int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name,
    5.46                          uint32_t *poolid)
    5.47  {
    5.48      int i, nb_pools;
    5.49      char *poolname;
    5.50 -    libxl_poolinfo *poolinfo;
    5.51 +    libxl_cpupoolinfo *poolinfo;
    5.52      int ret = -1;
    5.53  
    5.54 -    poolinfo = libxl_list_pool(ctx, &nb_pools);
    5.55 +    poolinfo = libxl_list_cpupool(ctx, &nb_pools);
    5.56      if (!poolinfo)
    5.57          return ERROR_NOMEM;
    5.58  
    5.59      for (i = 0; i < nb_pools; i++) {
    5.60 -        poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid);
    5.61 -        if (!poolname)
    5.62 -            continue;
    5.63 -        if (strcmp(poolname, name) == 0) {
    5.64 -            *poolid = poolinfo[i].poolid;
    5.65 -            ret = 0;
    5.66 +        if (ret && ((poolname = libxl_cpupoolid_to_name(ctx,
    5.67 +            poolinfo[i].poolid)) != NULL)) {
    5.68 +            if (strcmp(poolname, name) == 0) {
    5.69 +                *poolid = poolinfo[i].poolid;
    5.70 +                ret = 0;
    5.71 +            }
    5.72              free(poolname);
    5.73 -            break;
    5.74          }
    5.75 -        free(poolname);
    5.76 +        libxl_cpupoolinfo_destroy(poolinfo + i);
    5.77      }
    5.78      free(poolinfo);
    5.79      return ret;
    5.80  }
    5.81  
    5.82 +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name)
    5.83 +{
    5.84 +    int i;
    5.85 +
    5.86 +    for (i = 0; schedid_name[i].name != NULL; i++)
    5.87 +        if (strcmp(name, schedid_name[i].name) == 0)
    5.88 +            return schedid_name[i].id;
    5.89 +
    5.90 +    return -1;
    5.91 +}
    5.92 +
    5.93 +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid)
    5.94 +{
    5.95 +    int i;
    5.96 +
    5.97 +    for (i = 0; schedid_name[i].name != NULL; i++)
    5.98 +        if (schedid_name[i].id == schedid)
    5.99 +            return schedid_name[i].name;
   5.100 +
   5.101 +    return "unknown";
   5.102 +}
   5.103 +
   5.104  int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid)
   5.105  {
   5.106      libxl__gc gc = LIBXL_INIT_GC(ctx);
   5.107 @@ -676,6 +708,44 @@ out:
   5.108      return rc;
   5.109  }
   5.110  
   5.111 +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus)
   5.112 +{
   5.113 +    int elems;
   5.114 +
   5.115 +    elems = (max_cpus + 63) / 64;
   5.116 +    cpumap->map = calloc(elems, sizeof(*cpumap->map));
   5.117 +    if (!cpumap->map)
   5.118 +        return ERROR_NOMEM;
   5.119 +    cpumap->size = elems * 8;     /* size in bytes */
   5.120 +    return 0;
   5.121 +}
   5.122 +
   5.123 +void libxl_cpumap_destroy(libxl_cpumap *map)
   5.124 +{
   5.125 +    free(map->map);
   5.126 +}
   5.127 +
   5.128 +int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu)
   5.129 +{
   5.130 +    if (cpu >= cpumap->size * 8)
   5.131 +        return 0;
   5.132 +    return (cpumap->map[cpu / 64] & (1L << (cpu & 63))) ? 1 : 0;
   5.133 +}
   5.134 +
   5.135 +void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu)
   5.136 +{
   5.137 +    if (cpu >= cpumap->size * 8)
   5.138 +        return;
   5.139 +    cpumap->map[cpu / 64] |= 1L << (cpu & 63);
   5.140 +}
   5.141 +
   5.142 +void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu)
   5.143 +{
   5.144 +    if (cpu >= cpumap->size * 8)
   5.145 +        return;
   5.146 +    cpumap->map[cpu / 64] &= ~(1L << (cpu & 63));
   5.147 +}
   5.148 +
   5.149  int libxl_get_max_cpus(libxl_ctx *ctx)
   5.150  {
   5.151      return xc_get_max_cpus(ctx->xch);
     6.1 --- a/tools/libxl/libxl_utils.h	Thu Oct 21 18:35:18 2010 +0100
     6.2 +++ b/tools/libxl/libxl_utils.h	Thu Oct 21 18:36:22 2010 +0100
     6.3 @@ -21,8 +21,10 @@
     6.4  unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus);
     6.5  int libxl_name_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
     6.6  char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid);
     6.7 -int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
     6.8 -char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid);
     6.9 +int libxl_name_to_cpupoolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
    6.10 +char *libxl_cpupoolid_to_name(libxl_ctx *ctx, uint32_t poolid);
    6.11 +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name);
    6.12 +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid);
    6.13  int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid);
    6.14  int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid);
    6.15  int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name);
    6.16 @@ -74,5 +76,9 @@ int libxl_devid_to_device_net2(libxl_ctx
    6.17   * return -1 if there are an error */
    6.18  int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
    6.19  
    6.20 +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus);
    6.21 +int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu);
    6.22 +void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu);
    6.23 +void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu);
    6.24  #endif
    6.25  
     7.1 --- a/tools/libxl/libxltypes.py	Thu Oct 21 18:35:18 2010 +0100
     7.2 +++ b/tools/libxl/libxltypes.py	Thu Oct 21 18:36:22 2010 +0100
     7.3 @@ -131,7 +131,10 @@ class Reference(Type):
     7.4          kwargs.setdefault('passby', PASS_BY_VALUE)
     7.5          
     7.6          kwargs.setdefault('namespace', ty.namespace)
     7.7 -        typename = ty.typename[len(kwargs['namespace']):]
     7.8 +
     7.9 +        typename = ty.typename
    7.10 +        if ty.namespace:
    7.11 +            typename = typename[len(kwargs['namespace']):]
    7.12          Type.__init__(self, typename + " *", **kwargs)
    7.13  
    7.14  #
     8.1 --- a/tools/libxl/libxlu_cfg_l.c	Thu Oct 21 18:35:18 2010 +0100
     8.2 +++ b/tools/libxl/libxlu_cfg_l.c	Thu Oct 21 18:36:22 2010 +0100
     8.3 @@ -54,6 +54,7 @@ typedef int flex_int32_t;
     8.4  typedef unsigned char flex_uint8_t; 
     8.5  typedef unsigned short int flex_uint16_t;
     8.6  typedef unsigned int flex_uint32_t;
     8.7 +#endif /* ! C99 */
     8.8  
     8.9  /* Limits of integral types. */
    8.10  #ifndef INT8_MIN
    8.11 @@ -84,8 +85,6 @@ typedef unsigned int flex_uint32_t;
    8.12  #define UINT32_MAX             (4294967295U)
    8.13  #endif
    8.14  
    8.15 -#endif /* ! C99 */
    8.16 -
    8.17  #endif /* ! FLEXINT_H */
    8.18  
    8.19  #ifdef __cplusplus
    8.20 @@ -159,15 +158,7 @@ typedef void* yyscan_t;
    8.21  
    8.22  /* Size of default input buffer. */
    8.23  #ifndef YY_BUF_SIZE
    8.24 -#ifdef __ia64__
    8.25 -/* On IA-64, the buffer size is 16k, not 8k.
    8.26 - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
    8.27 - * Ditto for the __ia64__ case accordingly.
    8.28 - */
    8.29 -#define YY_BUF_SIZE 32768
    8.30 -#else
    8.31  #define YY_BUF_SIZE 16384
    8.32 -#endif /* __ia64__ */
    8.33  #endif
    8.34  
    8.35  /* The state buf must be large enough to hold one state per character in the main buffer.
    8.36 @@ -496,7 +487,7 @@ int xlu__cfg_yyget_column(yyscan_t yysca
    8.37  void xlu__cfg_yyset_column(int  column_no, yyscan_t yyscanner);
    8.38  
    8.39  
    8.40 -#line 500 "libxlu_cfg_l.c"
    8.41 +#line 491 "libxlu_cfg_l.c"
    8.42  
    8.43  #define INITIAL 0
    8.44  #define lexerr 1
    8.45 @@ -632,12 +623,7 @@ static int input (yyscan_t yyscanner );
    8.46  
    8.47  /* Amount of stuff to slurp up with each read. */
    8.48  #ifndef YY_READ_BUF_SIZE
    8.49 -#ifdef __ia64__
    8.50 -/* On IA-64, the buffer size is 16k, not 8k */
    8.51 -#define YY_READ_BUF_SIZE 16384
    8.52 -#else
    8.53  #define YY_READ_BUF_SIZE 8192
    8.54 -#endif /* __ia64__ */
    8.55  #endif
    8.56  
    8.57  /* Copy whatever the last rule matched to the standard output. */
    8.58 @@ -645,7 +631,7 @@ static int input (yyscan_t yyscanner );
    8.59  /* This used to be an fputs(), but since the string might contain NUL's,
    8.60   * we now use fwrite().
    8.61   */
    8.62 -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
    8.63 +#define ECHO fwrite( yytext, yyleng, 1, yyout )
    8.64  #endif
    8.65  
    8.66  /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
    8.67 @@ -656,7 +642,7 @@ static int input (yyscan_t yyscanner );
    8.68  	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
    8.69  		{ \
    8.70  		int c = '*'; \
    8.71 -		size_t n; \
    8.72 +		int n; \
    8.73  		for ( n = 0; n < max_size && \
    8.74  			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
    8.75  			buf[n] = (char) c; \
    8.76 @@ -744,7 +730,7 @@ YY_DECL
    8.77  #line 37 "libxlu_cfg_l.l"
    8.78  
    8.79  
    8.80 -#line 748 "libxlu_cfg_l.c"
    8.81 +#line 734 "libxlu_cfg_l.c"
    8.82  
    8.83      yylval = yylval_param;
    8.84  
    8.85 @@ -944,7 +930,7 @@ YY_RULE_SETUP
    8.86  #line 82 "libxlu_cfg_l.l"
    8.87  YY_FATAL_ERROR( "flex scanner jammed" );
    8.88  	YY_BREAK
    8.89 -#line 948 "libxlu_cfg_l.c"
    8.90 +#line 934 "libxlu_cfg_l.c"
    8.91  case YY_STATE_EOF(INITIAL):
    8.92  case YY_STATE_EOF(lexerr):
    8.93  	yyterminate();
    8.94 @@ -1687,8 +1673,8 @@ YY_BUFFER_STATE xlu__cfg_yy_scan_string 
    8.95  
    8.96  /** Setup the input buffer state to scan the given bytes. The next call to xlu__cfg_yylex() will
    8.97   * scan from a @e copy of @a bytes.
    8.98 - * @param yybytes the byte buffer to scan
    8.99 - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
   8.100 + * @param bytes the byte buffer to scan
   8.101 + * @param len the number of bytes in the buffer pointed to by @a bytes.
   8.102   * @param yyscanner The scanner object.
   8.103   * @return the newly allocated buffer state object.
   8.104   */
     9.1 --- a/tools/libxl/libxlu_cfg_l.h	Thu Oct 21 18:35:18 2010 +0100
     9.2 +++ b/tools/libxl/libxlu_cfg_l.h	Thu Oct 21 18:36:22 2010 +0100
     9.3 @@ -58,6 +58,7 @@ typedef int flex_int32_t;
     9.4  typedef unsigned char flex_uint8_t; 
     9.5  typedef unsigned short int flex_uint16_t;
     9.6  typedef unsigned int flex_uint32_t;
     9.7 +#endif /* ! C99 */
     9.8  
     9.9  /* Limits of integral types. */
    9.10  #ifndef INT8_MIN
    9.11 @@ -88,8 +89,6 @@ typedef unsigned int flex_uint32_t;
    9.12  #define UINT32_MAX             (4294967295U)
    9.13  #endif
    9.14  
    9.15 -#endif /* ! C99 */
    9.16 -
    9.17  #endif /* ! FLEXINT_H */
    9.18  
    9.19  #ifdef __cplusplus
    9.20 @@ -132,15 +131,7 @@ typedef void* yyscan_t;
    9.21  
    9.22  /* Size of default input buffer. */
    9.23  #ifndef YY_BUF_SIZE
    9.24 -#ifdef __ia64__
    9.25 -/* On IA-64, the buffer size is 16k, not 8k.
    9.26 - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
    9.27 - * Ditto for the __ia64__ case accordingly.
    9.28 - */
    9.29 -#define YY_BUF_SIZE 32768
    9.30 -#else
    9.31  #define YY_BUF_SIZE 16384
    9.32 -#endif /* __ia64__ */
    9.33  #endif
    9.34  
    9.35  #ifndef YY_TYPEDEF_YY_BUFFER_STATE
    9.36 @@ -310,12 +301,7 @@ static int yy_flex_strlen (yyconst char 
    9.37  
    9.38  /* Amount of stuff to slurp up with each read. */
    9.39  #ifndef YY_READ_BUF_SIZE
    9.40 -#ifdef __ia64__
    9.41 -/* On IA-64, the buffer size is 16k, not 8k */
    9.42 -#define YY_READ_BUF_SIZE 16384
    9.43 -#else
    9.44  #define YY_READ_BUF_SIZE 8192
    9.45 -#endif /* __ia64__ */
    9.46  #endif
    9.47  
    9.48  /* Number of entries by which start-condition stack grows. */
    9.49 @@ -352,6 +338,6 @@ extern int xlu__cfg_yylex \
    9.50  
    9.51  #line 82 "libxlu_cfg_l.l"
    9.52  
    9.53 -#line 356 "libxlu_cfg_l.h"
    9.54 +#line 342 "libxlu_cfg_l.h"
    9.55  #undef xlu__cfg_yyIN_HEADER
    9.56  #endif /* xlu__cfg_yyHEADER_H */
    10.1 --- a/tools/libxl/xl.h	Thu Oct 21 18:35:18 2010 +0100
    10.2 +++ b/tools/libxl/xl.h	Thu Oct 21 18:36:22 2010 +0100
    10.3 @@ -79,6 +79,12 @@ int main_tmem_freeable(int argc, char **
    10.4  int main_network2attach(int argc, char **argv);
    10.5  int main_network2list(int argc, char **argv);
    10.6  int main_network2detach(int argc, char **argv);
    10.7 +int main_cpupoolcreate(int argc, char **argv);
    10.8 +int main_cpupoollist(int argc, char **argv);
    10.9 +int main_cpupooldestroy(int argc, char **argv);
   10.10 +int main_cpupoolcpuadd(int argc, char **argv);
   10.11 +int main_cpupoolcpuremove(int argc, char **argv);
   10.12 +int main_cpupoolmigrate(int argc, char **argv);
   10.13  
   10.14  void help(char *command);
   10.15  
    11.1 --- a/tools/libxl/xl_cmdimpl.c	Thu Oct 21 18:35:18 2010 +0100
    11.2 +++ b/tools/libxl/xl_cmdimpl.c	Thu Oct 21 18:36:22 2010 +0100
    11.3 @@ -213,14 +213,14 @@ static int domain_qualifier_to_domid(con
    11.4      return was_name ? libxl_name_to_domid(&ctx, p, domid_r) : 0;
    11.5  }
    11.6  
    11.7 -static int pool_qualifier_to_poolid(const char *p, uint32_t *poolid_r,
    11.8 +static int cpupool_qualifier_to_cpupoolid(const char *p, uint32_t *poolid_r,
    11.9                                       int *was_name_r)
   11.10  {
   11.11      int was_name;
   11.12  
   11.13      was_name = qualifier_to_id(p, poolid_r);
   11.14      if (was_name_r) *was_name_r = was_name;
   11.15 -    return was_name ? libxl_name_to_poolid(&ctx, p, poolid_r) : 0;
   11.16 +    return was_name ? libxl_name_to_cpupoolid(&ctx, p, poolid_r) : 0;
   11.17  }
   11.18  
   11.19  static void find_domain(const char *p)
   11.20 @@ -494,7 +494,7 @@ static void printf_info(int domid,
   11.21          printf("\t(uuid <unknown>)\n");
   11.22      }
   11.23  
   11.24 -    printf("\t(cpupool %s (%d))\n", c_info->poolname, c_info->poolid);
   11.25 +    printf("\t(cpupool %s)\n", c_info->poolname);
   11.26      if (c_info->xsdata)
   11.27          printf("\t(xsdata contains data)\n");
   11.28      else
   11.29 @@ -697,9 +697,9 @@ static void parse_config_data(const char
   11.30  
   11.31      if (!xlu_cfg_get_string (config, "pool", &buf)) {
   11.32          c_info->poolid = -1;
   11.33 -        pool_qualifier_to_poolid(buf, &c_info->poolid, NULL);
   11.34 -    }
   11.35 -    c_info->poolname = libxl_poolid_to_name(&ctx, c_info->poolid);
   11.36 +        cpupool_qualifier_to_cpupoolid(buf, &c_info->poolid, NULL);
   11.37 +    }
   11.38 +    c_info->poolname = libxl_cpupoolid_to_name(&ctx, c_info->poolid);
   11.39      if (!c_info->poolname) {
   11.40          fprintf(stderr, "Illegal pool specified\n");
   11.41          exit(1);
   11.42 @@ -3517,7 +3517,7 @@ static void print_vcpuinfo(uint32_t tdom
   11.43      printf("%9.1f  ", ((float)vcpuinfo->vcpu_time / 1e9));
   11.44      /* CPU AFFINITY */
   11.45      pcpumap = nr_cpus > 64 ? (uint64_t)-1 : ((1ULL << nr_cpus) - 1);
   11.46 -    for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
   11.47 +    for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) {
   11.48          if (*cpumap < pcpumap) {
   11.49              break;
   11.50          }
   11.51 @@ -3532,7 +3532,7 @@ static void print_vcpuinfo(uint32_t tdom
   11.52      if (!nr_cpus) {
   11.53          printf("any cpu\n");
   11.54      } else {
   11.55 -        for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
   11.56 +        for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) {
   11.57              pcpumap = *cpumap;
   11.58              for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1)
   11.59                  ;
   11.60 @@ -3804,10 +3804,7 @@ static void output_xeninfo(void)
   11.61      printf("xen_minor              : %d\n", info->xen_version_minor);
   11.62      printf("xen_extra              : %s\n", info->xen_version_extra);
   11.63      printf("xen_caps               : %s\n", info->capabilities);
   11.64 -    printf("xen_scheduler          : %s\n",
   11.65 -        sched_id == XEN_SCHEDULER_SEDF ? "sedf" :
   11.66 -        sched_id == XEN_SCHEDULER_CREDIT ? "credit" :
   11.67 -        sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown");
   11.68 +    printf("xen_scheduler          : %s\n", libxl_schedid_to_name(&ctx, sched_id));
   11.69      printf("xen_pagesize           : %lu\n", info->pagesize);
   11.70      printf("platform_params        : virt_start=0x%lx\n", info->virt_start);
   11.71      printf("xen_changeset          : %s\n", info->changeset);
   11.72 @@ -3838,6 +3835,8 @@ static void output_physinfo(void)
   11.73      libxl_physinfo info;
   11.74      const libxl_version_info *vinfo;
   11.75      unsigned int i;
   11.76 +    libxl_cpumap cpumap;
   11.77 +    int n = 0;
   11.78  
   11.79      if (libxl_get_physinfo(&ctx, &info) != 0) {
   11.80          fprintf(stderr, "libxl_physinfo failed.\n");
   11.81 @@ -3864,6 +3863,13 @@ static void output_physinfo(void)
   11.82          printf("total_memory           : %"PRIu64"\n", info.total_pages / i);
   11.83          printf("free_memory            : %"PRIu64"\n", info.free_pages / i);
   11.84      }
   11.85 +    if (!libxl_get_freecpus(&ctx, &cpumap)) {
   11.86 +        for (i = 0; i < cpumap.size * 8; i++)
   11.87 +            if (libxl_cpumap_test(&cpumap, i))
   11.88 +                n++;
   11.89 +        printf("free_cpus              : %d\n", n);
   11.90 +        free(cpumap.map);
   11.91 +    }
   11.92  
   11.93      return;
   11.94  }
   11.95 @@ -5279,3 +5285,445 @@ int main_tmem_freeable(int argc, char **
   11.96      printf("%d\n", mb);
   11.97      return 0;
   11.98  }
   11.99 +
  11.100 +int main_cpupoolcreate(int argc, char **argv)
  11.101 +{
  11.102 +    char *filename = NULL;
  11.103 +    char *p, extra_config[1024];
  11.104 +    int dryrun = 0;
  11.105 +    int opt;
  11.106 +    int option_index = 0;
  11.107 +    static struct option long_options[] = {
  11.108 +        {"help", 0, 0, 'h'},
  11.109 +        {"defconfig", 1, 0, 'f'},
  11.110 +        {"dryrun", 0, 0, 'n'},
  11.111 +        {0, 0, 0, 0}
  11.112 +    };
  11.113 +    int ret;
  11.114 +    void *config_data = 0;
  11.115 +    int config_len = 0;
  11.116 +    XLU_Config *config;
  11.117 +    const char *buf;
  11.118 +    char *name, *sched;
  11.119 +    uint32_t poolid;
  11.120 +    int schedid = -1;
  11.121 +    XLU_ConfigList *cpus;
  11.122 +    int n_cpus, i, n;
  11.123 +    libxl_cpumap freemap;
  11.124 +    libxl_cpumap cpumap;
  11.125 +    libxl_uuid uuid;
  11.126 +
  11.127 +    while (1) {
  11.128 +        opt = getopt_long(argc, argv, "hnf:", long_options, &option_index);
  11.129 +        if (opt == -1)
  11.130 +            break;
  11.131 +
  11.132 +        switch (opt) {
  11.133 +        case 'f':
  11.134 +            filename = optarg;
  11.135 +            break;
  11.136 +        case 'h':
  11.137 +            help("cpupool-create");
  11.138 +            return 0;
  11.139 +        case 'n':
  11.140 +            dryrun = 1;
  11.141 +            break;
  11.142 +        default:
  11.143 +            fprintf(stderr, "option not supported\n");
  11.144 +            break;
  11.145 +        }
  11.146 +    }
  11.147 +
  11.148 +    memset(extra_config, 0, sizeof(extra_config));
  11.149 +    while (optind < argc) {
  11.150 +        if ((p = strchr(argv[optind], '='))) {
  11.151 +            if (strlen(extra_config) + 1 < sizeof(extra_config)) {
  11.152 +                if (strlen(extra_config))
  11.153 +                    strcat(extra_config, "\n");
  11.154 +                strcat(extra_config, argv[optind]);
  11.155 +            }
  11.156 +        } else if (!filename) {
  11.157 +            filename = argv[optind];
  11.158 +        } else {
  11.159 +            help("cpupool-create");
  11.160 +            return -ERROR_FAIL;
  11.161 +        }
  11.162 +        optind++;
  11.163 +    }
  11.164 +
  11.165 +    if (!filename) {
  11.166 +        help("cpupool-create");
  11.167 +        return -ERROR_FAIL;
  11.168 +    }
  11.169 +
  11.170 +    if (libxl_read_file_contents(&ctx, filename, &config_data, &config_len)) {
  11.171 +        fprintf(stderr, "Failed to read config file: %s: %s\n",
  11.172 +                filename, strerror(errno));
  11.173 +        return -ERROR_FAIL;
  11.174 +    }
  11.175 +    if (strlen(extra_config)) {
  11.176 +        if (config_len > INT_MAX - (strlen(extra_config) + 2)) {
  11.177 +            fprintf(stderr, "Failed to attach extra configration\n");
  11.178 +            return -ERROR_FAIL;
  11.179 +        }
  11.180 +        config_data = xrealloc(config_data,
  11.181 +                              config_len + strlen(extra_config) + 2);
  11.182 +        if (!config_data) {
  11.183 +            fprintf(stderr, "Failed to realloc config_data\n");
  11.184 +            return -ERROR_FAIL;
  11.185 +        }
  11.186 +        strcat(config_data, "\n");
  11.187 +        strcat(config_data, extra_config);
  11.188 +        strcat(config_data, "\n");
  11.189 +        config_len += (strlen(extra_config) + 2);
  11.190 +    }
  11.191 +
  11.192 +    config = xlu_cfg_init(stderr, filename);
  11.193 +    if (!config) {
  11.194 +        fprintf(stderr, "Failed to allocate for configuration\n");
  11.195 +        return -ERROR_FAIL;
  11.196 +    }
  11.197 +
  11.198 +    ret = xlu_cfg_readdata(config, config_data, config_len);
  11.199 +    if (ret) {
  11.200 +        fprintf(stderr, "Failed to parse config file: %s\n", strerror(ret));
  11.201 +        return -ERROR_FAIL;
  11.202 +    }
  11.203 +
  11.204 +    if (!xlu_cfg_get_string (config, "name", &buf))
  11.205 +        name = strdup(buf);
  11.206 +    else
  11.207 +        name = basename(filename);
  11.208 +    if (!libxl_name_to_cpupoolid(&ctx, name, &poolid)) {
  11.209 +        fprintf(stderr, "Pool name \"%s\" already exists\n", name);
  11.210 +        return -ERROR_FAIL;
  11.211 +    }
  11.212 +
  11.213 +    if (!xlu_cfg_get_string (config, "sched", &buf)) {
  11.214 +        if ((schedid = libxl_name_to_schedid(&ctx, buf)) < 0) {
  11.215 +            fprintf(stderr, "Unknown scheduler\n");
  11.216 +            return -ERROR_FAIL;
  11.217 +        }
  11.218 +    } else {
  11.219 +        if ((schedid = libxl_get_sched_id(&ctx)) < 0) {
  11.220 +            fprintf(stderr, "get_sched_id sysctl failed.\n");
  11.221 +            return -ERROR_FAIL;
  11.222 +        }
  11.223 +    }
  11.224 +    sched = libxl_schedid_to_name(&ctx, schedid);
  11.225 +
  11.226 +    if (libxl_get_freecpus(&ctx, &freemap)) {
  11.227 +        fprintf(stderr, "libxl_get_freecpus failed\n");
  11.228 +        return -ERROR_FAIL;
  11.229 +    }
  11.230 +    if (libxl_cpumap_alloc(&cpumap, freemap.size * 8)) {
  11.231 +        fprintf(stderr, "Failed to allocate cpumap\n");
  11.232 +        return -ERROR_FAIL;
  11.233 +    }
  11.234 +    if (!xlu_cfg_get_list(config, "cpus", &cpus, 0, 0)) {
  11.235 +        n_cpus = 0;
  11.236 +        while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) {
  11.237 +            i = atoi(buf);
  11.238 +            if ((i < 0) || (i >= freemap.size * 8) ||
  11.239 +                !libxl_cpumap_test(&freemap, i)) {
  11.240 +                fprintf(stderr, "cpu %d illegal or not free\n", i);
  11.241 +                return -ERROR_FAIL;
  11.242 +            }
  11.243 +            libxl_cpumap_set(&cpumap, i);
  11.244 +            n_cpus++;
  11.245 +        }
  11.246 +    } else {
  11.247 +        n_cpus = 1;
  11.248 +        n = 0;
  11.249 +        for (i = 0; i < freemap.size * 8; i++)
  11.250 +            if (libxl_cpumap_test(&freemap, i)) {
  11.251 +                n++;
  11.252 +                libxl_cpumap_set(&cpumap, i);
  11.253 +                break;
  11.254 +            }
  11.255 +        if (n < n_cpus) {
  11.256 +            fprintf(stderr, "no free cpu found\n");
  11.257 +            return -ERROR_FAIL;
  11.258 +        }
  11.259 +    }
  11.260 +
  11.261 +    libxl_uuid_generate(&uuid);
  11.262 +
  11.263 +    printf("Using config file \"%s\"\n", filename);
  11.264 +    printf("cpupool name:   %s\n", name);
  11.265 +    printf("scheduler:      %s\n", sched);
  11.266 +    printf("number of cpus: %d\n", n_cpus);
  11.267 +
  11.268 +    if (dryrun)
  11.269 +        return 0;
  11.270 +
  11.271 +    poolid = 0;
  11.272 +    if (libxl_create_cpupool(&ctx, name, schedid, cpumap, &uuid, &poolid)) {
  11.273 +        fprintf(stderr, "error on creating cpupool\n");
  11.274 +        return -ERROR_FAIL;
  11.275 +    }
  11.276 +
  11.277 +    return 0;
  11.278 +}
  11.279 +
  11.280 +int main_cpupoollist(int argc, char **argv)
  11.281 +{
  11.282 +    int opt;
  11.283 +    int option_index = 0;
  11.284 +    static struct option long_options[] = {
  11.285 +        {"help", 0, 0, 'h'},
  11.286 +        {"long", 0, 0, 'l'},
  11.287 +        {"cpus", 0, 0, 'c'},
  11.288 +        {0, 0, 0, 0}
  11.289 +    };
  11.290 +    int opt_long = 0;
  11.291 +    int opt_cpus = 0;
  11.292 +    char *pool = NULL;
  11.293 +    libxl_cpupoolinfo *poolinfo;
  11.294 +    int n_pools, p, c, n;
  11.295 +    uint32_t poolid;
  11.296 +    char *name;
  11.297 +    int ret = 0;
  11.298 +
  11.299 +    while (1) {
  11.300 +        opt = getopt_long(argc, argv, "hlc", long_options, &option_index);
  11.301 +        if (opt == -1)
  11.302 +            break;
  11.303 +
  11.304 +        switch (opt) {
  11.305 +        case 'h':
  11.306 +            help("cpupool-list");
  11.307 +            return 0;
  11.308 +        case 'l':
  11.309 +            opt_long = 1;
  11.310 +            break;
  11.311 +        case 'c':
  11.312 +            opt_cpus = 1;
  11.313 +            break;
  11.314 +        default:
  11.315 +            fprintf(stderr, "option not supported\n");
  11.316 +            break;
  11.317 +        }
  11.318 +    }
  11.319 +
  11.320 +    if ((optind + 1) < argc) {
  11.321 +        help("cpupool-list");
  11.322 +        return -ERROR_FAIL;
  11.323 +    }
  11.324 +    if (optind < argc) {
  11.325 +        pool = argv[optind];
  11.326 +        if (libxl_name_to_cpupoolid(&ctx, pool, &poolid)) {
  11.327 +            fprintf(stderr, "Pool \'%s\' does not exist\n", pool);
  11.328 +            return -ERROR_FAIL;
  11.329 +        }
  11.330 +    }
  11.331 +
  11.332 +    poolinfo = libxl_list_cpupool(&ctx, &n_pools);
  11.333 +    if (!poolinfo) {
  11.334 +        fprintf(stderr, "error getting cpupool info\n");
  11.335 +        return -ERROR_NOMEM;
  11.336 +    }
  11.337 +
  11.338 +    if (!opt_long) {
  11.339 +        printf("%-19s", "Name");
  11.340 +        if (opt_cpus)
  11.341 +            printf("CPU list\n");
  11.342 +        else
  11.343 +            printf("CPUs   Sched     Active   Domain count\n");
  11.344 +    }
  11.345 +
  11.346 +    for (p = 0; p < n_pools; p++) {
  11.347 +        if (!ret && (!pool || (poolinfo[p].poolid != poolid))) {
  11.348 +            name = libxl_cpupoolid_to_name(&ctx, poolinfo[p].poolid);
  11.349 +            if (!name) {
  11.350 +                fprintf(stderr, "error getting cpupool info\n");
  11.351 +                ret = -ERROR_NOMEM;
  11.352 +            }
  11.353 +            else if (opt_long) {
  11.354 +                ret = -ERROR_NI;
  11.355 +            } else {
  11.356 +                printf("%-19s", name);
  11.357 +                free(name);
  11.358 +                n = 0;
  11.359 +                for (c = 0; c < poolinfo[p].cpumap.size * 8; c++)
  11.360 +                    if (poolinfo[p].cpumap.map[c / 64] & (1L << (c % 64))) {
  11.361 +                        if (n && opt_cpus) printf(",");
  11.362 +                        if (opt_cpus) printf("%d", c);
  11.363 +                        n++;
  11.364 +                    }
  11.365 +                if (!opt_cpus) {
  11.366 +                    printf("%3d %9s       y       %4d", n,
  11.367 +                           libxl_schedid_to_name(&ctx, poolinfo[p].sched_id),
  11.368 +                           poolinfo[p].n_dom);
  11.369 +                }
  11.370 +                printf("\n");
  11.371 +            }
  11.372 +        }
  11.373 +        libxl_cpupoolinfo_destroy(poolinfo + p);
  11.374 +    }
  11.375 +
  11.376 +    return ret;
  11.377 +}
  11.378 +
  11.379 +int main_cpupooldestroy(int argc, char **argv)
  11.380 +{
  11.381 +    int opt;
  11.382 +    char *pool;
  11.383 +    uint32_t poolid;
  11.384 +
  11.385 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  11.386 +        switch (opt) {
  11.387 +        case 'h':
  11.388 +            help("cpupool-destroy");
  11.389 +            return 0;
  11.390 +        default:
  11.391 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  11.392 +            break;
  11.393 +        }
  11.394 +    }
  11.395 +
  11.396 +    pool = argv[optind];
  11.397 +    if (!pool) {
  11.398 +        fprintf(stderr, "no cpupool specified\n");
  11.399 +        help("cpupool-destroy");
  11.400 +        return -ERROR_FAIL;
  11.401 +    }
  11.402 +
  11.403 +    if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
  11.404 +        !libxl_cpupoolid_to_name(&ctx, poolid)) {
  11.405 +        fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
  11.406 +        return -ERROR_FAIL;
  11.407 +    }
  11.408 +
  11.409 +    return -libxl_destroy_cpupool(&ctx, poolid);
  11.410 +}
  11.411 +
  11.412 +int main_cpupoolcpuadd(int argc, char **argv)
  11.413 +{
  11.414 +    int opt;
  11.415 +    char *pool;
  11.416 +    uint32_t poolid;
  11.417 +    int cpu;
  11.418 +
  11.419 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  11.420 +        switch (opt) {
  11.421 +        case 'h':
  11.422 +            help("cpupool-cpu-add");
  11.423 +            return 0;
  11.424 +        default:
  11.425 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  11.426 +            break;
  11.427 +        }
  11.428 +    }
  11.429 +
  11.430 +    pool = argv[optind++];
  11.431 +    if (!pool) {
  11.432 +        fprintf(stderr, "no cpupool specified\n");
  11.433 +        help("cpupool-cpu-add");
  11.434 +        return -ERROR_FAIL;
  11.435 +    }
  11.436 +
  11.437 +    if (!argv[optind]) {
  11.438 +        fprintf(stderr, "no cpu specified\n");
  11.439 +        help("cpupool-cpu-add");
  11.440 +        return -ERROR_FAIL;
  11.441 +    }
  11.442 +    cpu = atoi(argv[optind]);
  11.443 +
  11.444 +    if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
  11.445 +        !libxl_cpupoolid_to_name(&ctx, poolid)) {
  11.446 +        fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
  11.447 +        return -ERROR_FAIL;
  11.448 +    }
  11.449 +
  11.450 +    return -libxl_cpupool_cpuadd(&ctx, poolid, cpu);
  11.451 +}
  11.452 +
  11.453 +int main_cpupoolcpuremove(int argc, char **argv)
  11.454 +{
  11.455 +    int opt;
  11.456 +    char *pool;
  11.457 +    uint32_t poolid;
  11.458 +    int cpu;
  11.459 +
  11.460 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  11.461 +        switch (opt) {
  11.462 +        case 'h':
  11.463 +            help("cpupool-cpu-remove");
  11.464 +            return 0;
  11.465 +        default:
  11.466 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  11.467 +            break;
  11.468 +        }
  11.469 +    }
  11.470 +
  11.471 +    pool = argv[optind++];
  11.472 +    if (!pool) {
  11.473 +        fprintf(stderr, "no cpupool specified\n");
  11.474 +        help("cpupool-cpu-remove");
  11.475 +        return -ERROR_FAIL;
  11.476 +    }
  11.477 +
  11.478 +    if (!argv[optind]) {
  11.479 +        fprintf(stderr, "no cpu specified\n");
  11.480 +        help("cpupool-cpu-remove");
  11.481 +        return -ERROR_FAIL;
  11.482 +    }
  11.483 +    cpu = atoi(argv[optind]);
  11.484 +
  11.485 +    if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
  11.486 +        !libxl_cpupoolid_to_name(&ctx, poolid)) {
  11.487 +        fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
  11.488 +        return -ERROR_FAIL;
  11.489 +    }
  11.490 +
  11.491 +    return -libxl_cpupool_cpuremove(&ctx, poolid, cpu);
  11.492 +}
  11.493 +
  11.494 +int main_cpupoolmigrate(int argc, char **argv)
  11.495 +{
  11.496 +    int opt;
  11.497 +    char *pool;
  11.498 +    uint32_t poolid;
  11.499 +    char *dom;
  11.500 +    uint32_t domid;
  11.501 +
  11.502 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  11.503 +        switch (opt) {
  11.504 +        case 'h':
  11.505 +            help("cpupool-migrate");
  11.506 +            return 0;
  11.507 +        default:
  11.508 +            fprintf(stderr, "option `%c' not supported.\n", opt);
  11.509 +            break;
  11.510 +        }
  11.511 +    }
  11.512 +
  11.513 +    dom = argv[optind++];
  11.514 +    if (!dom) {
  11.515 +       fprintf(stderr, "no domain specified\n");
  11.516 +        help("cpupool-migrate");
  11.517 +        return -ERROR_FAIL;
  11.518 +    }
  11.519 +
  11.520 +    pool = argv[optind++];
  11.521 +    if (!pool) {
  11.522 +        fprintf(stderr, "no cpupool specified\n");
  11.523 +        help("cpupool-migrate");
  11.524 +        return -ERROR_FAIL;
  11.525 +    }
  11.526 +
  11.527 +    if (domain_qualifier_to_domid(dom, &domid, NULL) ||
  11.528 +        !libxl_domid_to_name(&ctx, domid)) {
  11.529 +        fprintf(stderr, "unknown domain \'%s\'\n", dom);
  11.530 +        return -ERROR_FAIL;
  11.531 +    }
  11.532 +
  11.533 +    if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) ||
  11.534 +        !libxl_cpupoolid_to_name(&ctx, poolid)) {
  11.535 +        fprintf(stderr, "unknown cpupool \'%s\'\n", pool);
  11.536 +        return -ERROR_FAIL;
  11.537 +    }
  11.538 +
  11.539 +    return -libxl_cpupool_movedomain(&ctx, poolid, domid);
  11.540 +}
    12.1 --- a/tools/libxl/xl_cmdtable.c	Thu Oct 21 18:35:18 2010 +0100
    12.2 +++ b/tools/libxl/xl_cmdtable.c	Thu Oct 21 18:36:22 2010 +0100
    12.3 @@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = {
    12.4        "destroy a domain's version 2 virtual network device",
    12.5        "<Domain> <DevId>",
    12.6      },
    12.7 +    { "cpupool-create",
    12.8 +      &main_cpupoolcreate,
    12.9 +      "Create a CPU pool based an ConfigFile",
   12.10 +      "[options] <ConfigFile> [vars]",
   12.11 +      "-h, --help                   Print this help.\n"
   12.12 +      "-f=FILE, --defconfig=FILE    Use the given configuration file.\n"
   12.13 +      "-n, --dryrun                 Dry run - prints the resulting configuration."
   12.14 +    },
   12.15 +    { "cpupool-list",
   12.16 +      &main_cpupoollist,
   12.17 +      "List CPU pools on host",
   12.18 +      "[-l|--long] [-c|--cpus] [<CPU Pool>]",
   12.19 +      "-l, --long                     Output all CPU pool details.\n"
   12.20 +      "-c, --cpus                     Output list of CPUs used by a pool"
   12.21 +    },
   12.22 +    { "cpupool-destroy",
   12.23 +      &main_cpupooldestroy,
   12.24 +      "Deactivates a CPU pool",
   12.25 +      "<CPU Pool>",
   12.26 +    },
   12.27 +    { "cpupool-cpu-add",
   12.28 +      &main_cpupoolcpuadd,
   12.29 +      "Adds a CPU to a CPU pool",
   12.30 +      "<CPU Pool> <CPU nr>",
   12.31 +    },
   12.32 +    { "cpupool-cpu-remove",
   12.33 +      &main_cpupoolcpuremove,
   12.34 +      "Removes a CPU from a CPU pool",
   12.35 +      "<CPU Pool> <CPU nr>",
   12.36 +    },
   12.37 +    { "cpupool-migrate",
   12.38 +      &main_cpupoolmigrate,
   12.39 +      "Moves a domain into a CPU pool",
   12.40 +      "<Domain> <CPU Pool>",
   12.41 +    },
   12.42  };
   12.43  
   12.44  int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);