diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 456b4776adfed20db4e6fc6e2ab7f5bd8ebca2c2..dfc64150fb16e34b2dd2a4b1bfd427b7dd8b0c5b 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -44,6 +44,7 @@ #include "xen_hypervisor.h" #include "xs_internal.h" /* To extract VNC port & Serial console TTY */ #include "memory.h" +#include "count-one-bits.h" /* required for cpumap_t */ #include @@ -2191,7 +2192,9 @@ xenDaemonParseSxpr(virConnectPtr conn, } def->maxvcpus = sexpr_int(root, "domain/vcpus"); - def->vcpus = def->maxvcpus; + def->vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail")); + if (!def->vcpus || def->maxvcpus < def->vcpus) + def->vcpus = def->maxvcpus; tmp = sexpr_node(root, "domain/on_poweroff"); if (tmp != NULL) { @@ -2433,7 +2436,7 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root, virDomainInfoPtr info) { const char *flags; - + int vcpus; if ((root == NULL) || (info == NULL)) return (-1); @@ -2464,7 +2467,11 @@ sexpr_to_xend_domain_info(virDomainPtr domain, const struct sexpr *root, info->state = VIR_DOMAIN_NOSTATE; } info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000; - info->nrVirtCpu = sexpr_int(root, "domain/vcpus"); + vcpus = sexpr_int(root, "domain/vcpus"); + info->nrVirtCpu = count_one_bits(sexpr_int(root, "domain/vcpu_avail")); + if (!info->nrVirtCpu || vcpus < info->nrVirtCpu) + info->nrVirtCpu = vcpus; + return (0); } @@ -5668,6 +5675,9 @@ xenDaemonFormatSxpr(virConnectPtr conn, virBufferVSprintf(&buf, "(memory %lu)(maxmem %lu)", def->mem.cur_balloon/1024, def->mem.max_balloon/1024); virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus); + /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is 32. */ + if (def->vcpus < def->maxvcpus) + virBufferVSprintf(&buf, "(vcpu_avail %u)", (1U << def->vcpus) - 1); if (def->cpumask) { char *ranges = virDomainCpuSetFormat(def->cpumask, def->cpumasklen); @@ -5763,6 +5773,9 @@ xenDaemonFormatSxpr(virConnectPtr conn, virBufferVSprintf(&buf, "(kernel '%s')", def->os.loader); virBufferVSprintf(&buf, "(vcpus %u)", def->maxvcpus); + if (def->vcpus < def->maxvcpus) + virBufferVSprintf(&buf, "(vcpu_avail %u)", + (1U << def->vcpus) - 1); for (i = 0 ; i < def->os.nBootDevs ; i++) { switch (def->os.bootDevs[i]) { diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index bf20a64dfe2ac0a88e55274a62c54cfe0966e33f..f7121ab2a9c7dc799a5c34bc4348d8685807fd7f 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -46,6 +46,7 @@ #include "util.h" #include "memory.h" #include "logging.h" +#include "count-one-bits.h" #define VIR_FROM_THIS VIR_FROM_XENXM @@ -772,10 +773,12 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { def->mem.max_balloon *= 1024; if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 || - (unsigned short) count != count) + MAX_VIRT_CPUS < count) goto cleanup; def->maxvcpus = count; - def->vcpus = def->maxvcpus; + if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0) + goto cleanup; + def->vcpus = MIN(count_one_bits(count), def->maxvcpus); if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0) goto cleanup; @@ -2246,6 +2249,9 @@ virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0) goto no_memory; + if (def->vcpus < def->maxvcpus && + xenXMConfigSetInt(conf, "vcpu_avail", (1U << def->vcpus) - 1) < 0) + goto no_memory; if ((def->cpumask != NULL) && ((cpus = virDomainCpuSetFormat(def->cpumask, diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr new file mode 100644 index 0000000000000000000000000000000000000000..2be6822c420e41c6771389cfcc6d4a6b3835a87d --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.sexpr @@ -0,0 +1 @@ +(domain (domid 6)(name 'pvtest')(memory 420)(maxmem 420)(vcpus 4)(vcpu_avail 3)(uuid '596a5d2171f48fb2e068e2386a5c413e')(on_poweroff 'destroy')(on_reboot 'destroy')(on_crash 'destroy')(image (linux (kernel '/var/lib/xen/vmlinuz.2Dn2YT')(ramdisk '/var/lib/xen/initrd.img.0u-Vhq')(args ' method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os ')))(device (vbd (dev 'xvda')(uname 'file:/root/some.img')(mode 'w')))) diff --git a/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml new file mode 100644 index 0000000000000000000000000000000000000000..0d6bf11bcac8614de1a06e3eb7673150e11cce4c --- /dev/null +++ b/tests/sexpr2xmldata/sexpr2xml-pv-vcpus.xml @@ -0,0 +1,27 @@ + + pvtest + 596a5d21-71f4-8fb2-e068-e2386a5c413e + 430080 + 430080 + 4 + + linux + /var/lib/xen/vmlinuz.2Dn2YT + /var/lib/xen/initrd.img.0u-Vhq + method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test/5.91/x86_64/os + + + destroy + destroy + destroy + + + + + + + + + + + diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c index d62b44f8d69bff40bb21395f2df90bd587643123..f100dd87ce52ed17ff52b55d0b7d51682db46461 100644 --- a/tests/sexpr2xmltest.c +++ b/tests/sexpr2xmltest.c @@ -132,6 +132,7 @@ mymain(int argc, char **argv) DO_TEST("pv-vfb-type-crash", "pv-vfb-type-crash", 3); DO_TEST("fv-autoport", "fv-autoport", 3); DO_TEST("pv-bootloader", "pv-bootloader", 1); + DO_TEST("pv-vcpus", "pv-vcpus", 1); DO_TEST("disk-file", "disk-file", 2); DO_TEST("disk-block", "disk-block", 2); diff --git a/tests/xmconfigdata/test-paravirt-vcpu.cfg b/tests/xmconfigdata/test-paravirt-vcpu.cfg new file mode 100644 index 0000000000000000000000000000000000000000..24c78f42ccccc8375b821f687073bba66fb5f915 --- /dev/null +++ b/tests/xmconfigdata/test-paravirt-vcpu.cfg @@ -0,0 +1,17 @@ +name = "XenGuest1" +uuid = "c7a5fdb0-cdaf-9455-926a-d65c16db1809" +maxmem = 579 +memory = 394 +vcpus = 4 +vcpu_avail = 3 +bootloader = "/usr/bin/pygrub" +on_poweroff = "destroy" +on_reboot = "restart" +on_crash = "restart" +sdl = 0 +vnc = 1 +vncunused = 1 +vnclisten = "127.0.0.1" +vncpasswd = "123poi" +disk = [ "phy:/dev/HostVG/XenGuest1,xvda,w" ] +vif = [ "mac=00:16:3e:66:94:9c,bridge=br0,script=vif-bridge" ] diff --git a/tests/xmconfigdata/test-paravirt-vcpu.xml b/tests/xmconfigdata/test-paravirt-vcpu.xml new file mode 100644 index 0000000000000000000000000000000000000000..0be94568a04910792137bad0eb51cd68548bfb69 --- /dev/null +++ b/tests/xmconfigdata/test-paravirt-vcpu.xml @@ -0,0 +1,32 @@ + + XenGuest1 + c7a5fdb0-cdaf-9455-926a-d65c16db1809 + 592896 + 403456 + 4 + /usr/bin/pygrub + + linux + + + destroy + restart + restart + + + + + + + + + +