diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 4a2ba84797..15d4ec47a2 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -4254,23 +4254,19 @@ int libxl_domain_get_nodeaffinity(libxl_ctx *ctx, uint32_t domid, } static int libxl__set_vcpuonline_xenstore(libxl__gc *gc, uint32_t domid, - libxl_bitmap *cpumap) + libxl_bitmap *cpumap, + const libxl_dominfo *info) { - libxl_dominfo info; char *dompath; xs_transaction_t t; int i, rc = ERROR_FAIL; - if (libxl_domain_info(CTX, &info, domid) < 0) { - LOGE(ERROR, "getting domain info list"); - goto out; - } if (!(dompath = libxl__xs_get_dompath(gc, domid))) goto out; retry_transaction: t = xs_transaction_start(CTX->xsh); - for (i = 0; i <= info.vcpu_max_id; i++) + for (i = 0; i <= info->vcpu_max_id; i++) libxl__xs_write(gc, t, libxl__sprintf(gc, "%s/cpu/%u/availability", dompath, i), "%s", libxl_bitmap_test(cpumap, i) ? "online" : "offline"); @@ -4284,16 +4280,12 @@ out: } static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid, - libxl_bitmap *cpumap) + libxl_bitmap *cpumap, + const libxl_dominfo *info) { - libxl_dominfo info; int i; - if (libxl_domain_info(CTX, &info, domid) < 0) { - LOGE(ERROR, "getting domain info list"); - return ERROR_FAIL; - } - for (i = 0; i <= info.vcpu_max_id; i++) { + for (i = 0; i <= info->vcpu_max_id; i++) { if (libxl_bitmap_test(cpumap, i)) { /* Return value is ignore because it does not tell anything useful * on the completion of the command. @@ -4309,17 +4301,35 @@ static int libxl__set_vcpuonline_qmp(libxl__gc *gc, uint32_t domid, int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_bitmap *cpumap) { GC_INIT(ctx); - int rc; + int rc, maxcpus; + libxl_dominfo info; + + rc = libxl_domain_info(CTX, &info, domid); + if (rc < 0) { + LOGE(ERROR, "getting domain info list"); + goto out; + } + + maxcpus = libxl_bitmap_count_set(cpumap); + if (maxcpus > info.vcpu_max_id + 1) + { + LOGE(ERROR, "Requested %d VCPUs, however maxcpus is %d!", + maxcpus, info.vcpu_max_id + 1); + rc = ERROR_FAIL; + goto out; + } + switch (libxl__device_model_version_running(gc, domid)) { case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: - rc = libxl__set_vcpuonline_xenstore(gc, domid, cpumap); + rc = libxl__set_vcpuonline_xenstore(gc, domid, cpumap, &info); break; case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: - rc = libxl__set_vcpuonline_qmp(gc, domid, cpumap); + rc = libxl__set_vcpuonline_qmp(gc, domid, cpumap, &info); break; default: rc = ERROR_INVAL; } +out: GC_FREE; return rc; }