return ((ret < 0 && fail) || (!ret && !fail)) ? 0 : -1;
}
+
+struct testQemuHotplugCpuData {
+ char *file_xml_dom;
+ char *file_xml_res_live;
+ char *file_xml_res_conf;
+ char *file_json_monitor;
+
+ char *xml_dom;
+
+ virDomainObjPtr vm;
+ qemuMonitorTestPtr mon;
+ bool modern;
+};
+
+
+static void
+testQemuHotplugCpuDataFree(struct testQemuHotplugCpuData *data)
+{
+ if (!data)
+ return;
+
+ VIR_FREE(data->file_xml_dom);
+ VIR_FREE(data->file_xml_res_live);
+ VIR_FREE(data->file_xml_res_conf);
+ VIR_FREE(data->file_json_monitor);
+
+ VIR_FREE(data->xml_dom);
+
+ virObjectUnref(data->vm);
+ qemuMonitorTestFree(data->mon);
+}
+
+
+static struct testQemuHotplugCpuData *
+testQemuHotplugCpuPrepare(const char *test,
+ bool modern)
+{
+ qemuDomainObjPrivatePtr priv = NULL;
+ virCapsPtr caps = NULL;
+ char *prefix = NULL;
+ struct testQemuHotplugCpuData *data = NULL;
+
+ if (virAsprintf(&prefix, "%s/qemuhotplugtestcpus/%s", abs_srcdir, test) < 0)
+ return NULL;
+
+ if (VIR_ALLOC(data) < 0)
+ goto error;
+
+ data->modern = modern;
+
+ if (virAsprintf(&data->file_xml_dom, "%s-domain.xml", prefix) < 0 ||
+ virAsprintf(&data->file_xml_res_live, "%s-result-live.xml", prefix) < 0 ||
+ virAsprintf(&data->file_xml_res_conf, "%s-result-conf.xml", prefix) < 0 ||
+ virAsprintf(&data->file_json_monitor, "%s-monitor.json", prefix) < 0)
+ goto error;
+
+ if (virTestLoadFile(data->file_xml_dom, &data->xml_dom) < 0)
+ goto error;
+
+ if (qemuHotplugCreateObjects(driver.xmlopt, &data->vm, data->xml_dom, true,
+ "cpu-hotplug-test-domain") < 0)
+ goto error;
+
+ if (!(caps = virQEMUDriverGetCapabilities(&driver, false)))
+ goto error;
+
+ /* create vm->newDef */
+ data->vm->persistent = true;
+ if (virDomainObjSetDefTransient(caps, driver.xmlopt, data->vm) < 0)
+ goto error;
+
+ priv = data->vm->privateData;
+
+ if (data->modern)
+ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS);
+
+ if (!(data->mon = qemuMonitorTestNewFromFileFull(data->file_json_monitor,
+ &driver, data->vm)))
+ goto error;
+
+ priv->mon = qemuMonitorTestGetMonitor(data->mon);
+ priv->monJSON = true;
+ virObjectUnlock(priv->mon);
+
+ if (qemuDomainRefreshVcpuInfo(&driver, data->vm, 0, false) < 0)
+ goto error;
+
+ return data;
+
+ error:
+ virObjectUnref(caps);
+ testQemuHotplugCpuDataFree(data);
+ VIR_FREE(prefix);
+ return NULL;
+}
+
+
+static int
+testQemuHotplugCpuFinalize(struct testQemuHotplugCpuData *data)
+{
+ int ret = -1;
+ char *activeXML = NULL;
+ char *configXML = NULL;
+
+ if (data->file_xml_res_live) {
+ if (!(activeXML = virDomainDefFormat(data->vm->def, driver.caps,
+ VIR_DOMAIN_DEF_FORMAT_SECURE)))
+ goto cleanup;
+
+ if (virTestCompareToFile(activeXML, data->file_xml_res_live) < 0)
+ goto cleanup;
+ }
+
+ if (data->file_xml_res_conf) {
+ if (!(configXML = virDomainDefFormat(data->vm->newDef, driver.caps,
+ VIR_DOMAIN_DEF_FORMAT_SECURE |
+ VIR_DOMAIN_DEF_FORMAT_INACTIVE)))
+ goto cleanup;
+
+ if (virTestCompareToFile(configXML, data->file_xml_res_conf) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(activeXML);
+ VIR_FREE(configXML);
+ return ret;
+}
+
+
+struct testQemuHotplugCpuParams {
+ const char *test;
+ int newcpus;
+ bool modern;
+ bool fail;
+};
+
+
+static int
+testQemuHotplugCpuGroup(const void *opaque)
+{
+ const struct testQemuHotplugCpuParams *params = opaque;
+ struct testQemuHotplugCpuData *data = NULL;
+ int ret = -1;
+ int rc;
+
+ if (!(data = testQemuHotplugCpuPrepare(params->test, params->modern)))
+ return -1;
+
+ rc = qemuDomainSetVcpusInternal(&driver, data->vm, data->vm->def,
+ data->vm->newDef, params->newcpus,
+ params->modern);
+
+ if (params->fail) {
+ if (rc == 0)
+ fprintf(stderr, "cpu test '%s' should have failed\n", params->test);
+ else
+ ret = 0;
+
+ goto cleanup;
+ } else {
+ if (rc < 0)
+ goto cleanup;
+ }
+
+ ret = testQemuHotplugCpuFinalize(data);
+
+ cleanup:
+ testQemuHotplugCpuDataFree(data);
+ return ret;
+}
+
+
static int
mymain(void)
{
int ret = 0;
struct qemuHotplugTestData data = {0};
+ struct testQemuHotplugCpuParams cpudata;
#if !WITH_YAJL
fputs("libvirt not compiled with yajl, skipping this test\n", stderr);
"device_del", QMP_OK,
"object-del", QMP_OK);
+#define DO_TEST_CPU_GROUP(prefix, vcpus, modernhp, expectfail) \
+ do { \
+ cpudata.test = prefix; \
+ cpudata.newcpus = vcpus; \
+ cpudata.modern = modernhp; \
+ cpudata.fail = expectfail; \
+ if (virTestRun("hotplug vcpus group " prefix, \
+ testQemuHotplugCpuGroup, &cpudata) < 0) \
+ ret = -1; \
+ } while (0)
+
+ DO_TEST_CPU_GROUP("x86-modern-bulk", 7, true, false);
+
qemuTestDriverFree(&driver);
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' current='5'>8</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu>
+ <topology sockets="4" cores="2" threads="1"/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ </devices>
+</domain>
--- /dev/null
+{"execute":"query-hotpluggable-cpus","id":"libvirt-1"}
+
+{
+ "return": [
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[5]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[4]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[3]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[2]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[0]",
+ "type": "qemu64-x86_64-cpu"
+ }
+ ],
+ "id": "libvirt-23"
+}
+
+{"execute":"query-cpus","id":"libvirt-2"}
+
+{
+ "return": [
+ {
+ "arch": "x86",
+ "current": true,
+ "CPU": 0,
+ "qom_path": "/machine/unattached/device[0]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518291
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 1,
+ "qom_path": "/machine/unattached/device[2]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518292
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 2,
+ "qom_path": "/machine/unattached/device[3]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518294
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 3,
+ "qom_path": "/machine/unattached/device[4]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518295
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 4,
+ "qom_path": "/machine/unattached/device[5]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518296
+ }
+ ],
+ "id": "libvirt-22"
+}
+
+{
+ "execute": "device_add",
+ "arguments": {
+ "driver": "qemu64-x86_64-cpu",
+ "id": "vcpu5",
+ "socket-id": 1,
+ "core-id": 0,
+ "thread-id": 1
+ },
+ "id": "libvirt-3"
+}
+
+{"return": {}}
+
+{"execute":"query-hotpluggable-cpus","id":"libvirt-4"}
+
+{
+ "return": [
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/peripheral/vcpu5",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[5]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[4]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[3]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[2]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[0]",
+ "type": "qemu64-x86_64-cpu"
+ }
+ ],
+ "id": "libvirt-23"
+}
+
+{"execute":"query-cpus","id":"libvirt-5"}
+
+{
+ "return": [
+ {
+ "arch": "x86",
+ "current": true,
+ "CPU": 0,
+ "qom_path": "/machine/unattached/device[0]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518291
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 1,
+ "qom_path": "/machine/unattached/device[2]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518292
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 2,
+ "qom_path": "/machine/unattached/device[3]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518294
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 3,
+ "qom_path": "/machine/unattached/device[4]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518295
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 4,
+ "qom_path": "/machine/unattached/device[5]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518296
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 5,
+ "qom_path": "/machine/peripheral/vcpu5",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518297
+ }
+ ],
+ "id": "libvirt-22"
+}
+
+{
+ "execute": "device_add",
+ "arguments": {
+ "driver": "qemu64-x86_64-cpu",
+ "id": "vcpu6",
+ "socket-id": 1,
+ "core-id": 1,
+ "thread-id": 0
+ },
+ "id": "libvirt-6"
+}
+
+{"return": {}}
+
+{"execute":"query-hotpluggable-cpus","id":"libvirt-7"}
+
+{
+ "return": [
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/peripheral/vcpu6",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/peripheral/vcpu5",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[5]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[4]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[3]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[2]",
+ "type": "qemu64-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[0]",
+ "type": "qemu64-x86_64-cpu"
+ }
+ ],
+ "id": "libvirt-23"
+}
+
+{"execute":"query-cpus","id":"libvirt-8"}
+
+{
+ "return": [
+ {
+ "arch": "x86",
+ "current": true,
+ "CPU": 0,
+ "qom_path": "/machine/unattached/device[0]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518291
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 1,
+ "qom_path": "/machine/unattached/device[2]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518292
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 2,
+ "qom_path": "/machine/unattached/device[3]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518294
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 3,
+ "qom_path": "/machine/unattached/device[4]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518295
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 4,
+ "qom_path": "/machine/unattached/device[5]",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518296
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 5,
+ "qom_path": "/machine/peripheral/vcpu5",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518297
+ },
+ {
+ "arch": "x86",
+ "current": false,
+ "CPU": 6,
+ "qom_path": "/machine/peripheral/vcpu6",
+ "pc": -2130415978,
+ "halted": true,
+ "thread_id": 518298
+ }
+ ],
+ "id": "libvirt-22"
+}
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' current='7'>8</vcpu>
+ <vcpus>
+ <vcpu id='0' enabled='yes' hotpluggable='no'/>
+ <vcpu id='1' enabled='yes' hotpluggable='no'/>
+ <vcpu id='2' enabled='yes' hotpluggable='no'/>
+ <vcpu id='3' enabled='yes' hotpluggable='no'/>
+ <vcpu id='4' enabled='yes' hotpluggable='no'/>
+ <vcpu id='5' enabled='yes' hotpluggable='yes'/>
+ <vcpu id='6' enabled='yes' hotpluggable='yes'/>
+ <vcpu id='7' enabled='no' hotpluggable='yes'/>
+ </vcpus>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu>
+ <topology sockets='4' cores='2' threads='1'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
--- /dev/null
+<domain type='qemu' id='7'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static' current='7'>8</vcpu>
+ <vcpus>
+ <vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>
+ <vcpu id='1' enabled='yes' hotpluggable='no' order='2'/>
+ <vcpu id='2' enabled='yes' hotpluggable='no' order='3'/>
+ <vcpu id='3' enabled='yes' hotpluggable='no' order='4'/>
+ <vcpu id='4' enabled='yes' hotpluggable='no' order='5'/>
+ <vcpu id='5' enabled='yes' hotpluggable='yes' order='6'/>
+ <vcpu id='6' enabled='yes' hotpluggable='yes' order='7'/>
+ <vcpu id='7' enabled='no' hotpluggable='yes'/>
+ </vcpus>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <cpu>
+ <topology sockets='4' cores='2' threads='1'/>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'>
+ <alias name='usb'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'>
+ <alias name='pci'/>
+ </controller>
+ <input type='mouse' bus='ps2'>
+ <alias name='input0'/>
+ </input>
+ <input type='keyboard' bus='ps2'>
+ <alias name='input1'/>
+ </input>
+ <memballoon model='virtio'>
+ <alias name='balloon0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>