[libvirt] [PATCH v3 0/6] Test persistent device attachment

Changes in v3: * fewer patches, because part of v2 was ACK'd * two old commits, 08/10 and 09/10, are now one commit * qemuDomainUpdateDeviceFlags is now also split, creating a new function qemuDomainUpdateDeviceLiveAndConfig(). This function is now used in qemuhotplugtest.c. * qemuDomainAttachDeviceLiveAndConfig, qemuDomainDetachDeviceLiveAndConfig and qemuDomainUpdateDeviceLiveAndConfig are now in a new file: qemu_driverpriv.h * variable "target" is renamed to "impact" and its type is changed * testQemuHotplugCheckResult() now takes "impact" as a parameter to determine whether to test the ->def or ->newDef * def->id is no longer set when handling a persistent domain * split DO_TEST_ATTACH (and other macros) to DO_TEST_ATTACH_LIVE and DO_TEST_ATTACH_CONFIG instead of taking a parameter * fixed indentation * "<source mode='bind'/>" is removed from one xml * a three year old testcase for updating a disk device was modified a little bit to make it finally execute and test something Link to v2: https://www.redhat.com/archives/libvir-list/2016-July/msg00595.html Tomasz Flendrich (6): Split qemuDomainUpdateDeviceFlags in two Make qemu attach/detach functions public Make qemuhotplugtest work with persistent domains qemuhotplug: Use a more generic function to update devices qemuhotplugtest: add testcase to update a disk device qemuhotplugtest: add a persistent attachment testcase src/qemu/qemu_driver.c | 117 +++--- src/qemu/qemu_driverpriv.h | 47 +++ tests/qemuhotplugtest.c | 433 ++++++++++++--------- .../qemuhotplug-disk-cdrom-nochange.xml | 2 +- .../qemuhotplug-qemu-agent.xml | 1 - .../qemuhotplug-base-config+qemu-agent+config.xml | 44 +++ .../qemuhotplug-base-config.xml | 40 ++ .../qemuhotplug-disk-cdrom.xml | 2 +- 8 files changed, 454 insertions(+), 232 deletions(-) create mode 100644 src/qemu/qemu_driverpriv.h create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-config+qemu-agent+config.xml create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-config.xml -- 1.9.1

Previously, qemuDomainUpdateDeviceFlags was doing two things: handling the job and updating devices. Now the second part is in a new function, qemuDomainUpdateDeviceLiveAndConfig. qemuDomainUpdateDeviceLive's parameter was narrowed down, so that qemuDomainUpdateDeviceLiveAndConfig works without accepting an unnecessary parameter. It will also make testing easier. --- src/qemu/qemu_driver.c | 112 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 47 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b47ef41..6c3a413 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7596,10 +7596,9 @@ static int qemuDomainUpdateDeviceLive(virConnectPtr conn, virDomainObjPtr vm, virDomainDeviceDefPtr dev, - virDomainPtr dom, + virQEMUDriverPtr driver, bool force) { - virQEMUDriverPtr driver = dom->conn->privateData; int ret = -1; switch ((virDomainDeviceType) dev->type) { @@ -8202,53 +8201,34 @@ static int qemuDomainAttachDevice(virDomainPtr dom, const char *xml) VIR_DOMAIN_AFFECT_LIVE); } - -static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, - const char *xml, - unsigned int flags) +static int +qemuDomainUpdateDeviceLiveAndConfig(virConnectPtr conn, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + const char *xml, + unsigned int flags) { - virQEMUDriverPtr driver = dom->conn->privateData; - virDomainObjPtr vm = NULL; - virDomainDefPtr vmdef = NULL; - virDomainDeviceDefPtr dev = NULL, dev_copy = NULL; - bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0; int ret = -1; + virDomainDeviceDefPtr dev = NULL, dev_copy = NULL; virQEMUCapsPtr qemuCaps = NULL; - qemuDomainObjPrivatePtr priv; + virDomainDefPtr vmdef = NULL; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0; unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; - virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG | - VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1); - - virNWFilterReadLockFilterUpdates(); - cfg = virQEMUDriverGetConfig(driver); if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; - if (!(vm = qemuDomObjFromDomain(dom))) - goto cleanup; - - priv = vm->privateData; - - if (virDomainUpdateDeviceFlagsEnsureACL(dom->conn, vm->def, flags) < 0) - goto cleanup; - - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) - goto cleanup; - dev = dev_copy = virDomainDeviceDefParse(xml, vm->def, caps, driver->xmlopt, parse_flags); - if (dev == NULL) - goto endjob; - if (virDomainObjUpdateModificationImpact(vm, &flags) < 0) - goto endjob; + if (dev == NULL) + goto cleanup; if (flags & VIR_DOMAIN_AFFECT_CONFIG && flags & VIR_DOMAIN_AFFECT_LIVE) { @@ -8258,37 +8238,37 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, */ dev_copy = virDomainDeviceDefCopy(dev, vm->def, caps, driver->xmlopt); if (!dev_copy) - goto endjob; + goto cleanup; } if (priv->qemuCaps) qemuCaps = virObjectRef(priv->qemuCaps); else if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, vm->def->emulator))) - goto endjob; + goto cleanup; if (flags & VIR_DOMAIN_AFFECT_CONFIG) { /* Make a copy for updated domain. */ vmdef = virDomainObjCopyPersistentDef(vm, caps, driver->xmlopt); if (!vmdef) - goto endjob; + goto cleanup; if (virDomainDefCompatibleDevice(vmdef, dev, VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) - goto endjob; + goto cleanup; if ((ret = qemuDomainUpdateDeviceConfig(vmdef, dev, caps, parse_flags, driver->xmlopt)) < 0) - goto endjob; + goto cleanup; } if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (virDomainDefCompatibleDevice(vm->def, dev_copy, VIR_DOMAIN_DEVICE_ACTION_UPDATE) < 0) - goto endjob; + goto cleanup; - if ((ret = qemuDomainUpdateDeviceLive(dom->conn, vm, dev_copy, dom, force)) < 0) - goto endjob; + if ((ret = qemuDomainUpdateDeviceLive(conn, vm, dev_copy, driver, force)) < 0) + goto cleanup; /* * update domain status forcibly because the domain status may be * changed even if we failed to attach the device. For example, @@ -8296,7 +8276,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, */ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) { ret = -1; - goto endjob; + goto cleanup; } } @@ -8309,18 +8289,56 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom, } } - endjob: - qemuDomainObjEndJob(driver, vm); cleanup: - virObjectUnref(qemuCaps); virDomainDefFree(vmdef); + virObjectUnref(qemuCaps); + virObjectUnref(cfg); if (dev != dev_copy) virDomainDeviceDefFree(dev_copy); virDomainDeviceDefFree(dev); - virDomainObjEndAPI(&vm); virObjectUnref(caps); - virObjectUnref(cfg); + + return ret; +} + +static int +qemuDomainUpdateDeviceFlags(virDomainPtr dom, + const char *xml, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm = NULL; + int ret = -1; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG | + VIR_DOMAIN_DEVICE_MODIFY_FORCE, -1); + + virNWFilterReadLockFilterUpdates(); + + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + + if (virDomainUpdateDeviceFlagsEnsureACL(dom->conn, vm->def, flags) < 0) + goto cleanup; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + goto cleanup; + + if (virDomainObjUpdateModificationImpact(vm, &flags) < 0) + goto endjob; + + if (qemuDomainUpdateDeviceLiveAndConfig(dom->conn, vm, driver, xml, flags) < 0) + goto endjob; + + ret = 0; + + endjob: + qemuDomainObjEndJob(driver, vm); + + cleanup: + virDomainObjEndAPI(&vm); virNWFilterUnlockFilterUpdates(); return ret; } -- 1.9.1

qemuDomainAttachDeviceLiveAndConfig and qemuDomainDetachDeviceLiveAndConfig will be used to test device attachment and detachment, so they have to be visible outside. Because they are not a part of public interface of qemu driver, a new header file is created: qemu_driverpriv.h, in a smilar fashion to qemu_processpriv.h --- src/qemu/qemu_driver.c | 5 +++-- src/qemu/qemu_driverpriv.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/qemu/qemu_driverpriv.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6c3a413..f650766 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -44,6 +44,7 @@ #include "qemu_driver.h" +#include "qemu_driverpriv.h" #include "qemu_agent.h" #include "qemu_alias.h" #include "qemu_conf.h" @@ -8065,7 +8066,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef, return 0; } -static int +int qemuDomainAttachDeviceLiveAndConfig(virConnectPtr conn, virDomainObjPtr vm, virQEMUDriverPtr driver, @@ -8343,7 +8344,7 @@ qemuDomainUpdateDeviceFlags(virDomainPtr dom, return ret; } -static int +int qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver, virDomainObjPtr vm, const char *xml, diff --git a/src/qemu/qemu_driverpriv.h b/src/qemu/qemu_driverpriv.h new file mode 100644 index 0000000..943f0da --- /dev/null +++ b/src/qemu/qemu_driverpriv.h @@ -0,0 +1,40 @@ +/* + * qemu_driverpriv.h: private declarations for managing qemu guests + * + * Copyright (C) 2016 Tomasz Flendrich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Tomasz Flendrich + */ + +#ifndef __QEMU_DRIVERPRIV_H__ +# define __QEMU_DRIVERPRIV_H__ + +# include "domain_conf.h" +# include "qemu_conf.h" + +int qemuDomainAttachDeviceLiveAndConfig(virConnectPtr conn, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + const char *xml, + unsigned int flags); + +int qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *xml, + unsigned int flags); + +#endif /* __QEMU_DRIVERPRIV_H__ */ -- 1.9.1

More generic functions, qemuDomainAttachDeviceLiveAndConfig and qemuDomainDetachDeviceLiveAndConfig, are now used instead of other functions in qemuhotplugtest to attach and detach devices. This allows us to test attachments/detachments to the persistent domain too. Previously, qemuhotplugtest worked only with live domains. --- tests/qemuhotplugtest.c | 417 ++++++++++++++++++++++++++++-------------------- 1 file changed, 242 insertions(+), 175 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 0a5f068..13d2bdc 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -23,6 +23,7 @@ #include "qemu/qemu_conf.h" #include "qemu/qemu_hotplug.h" #include "qemu/qemu_hotplugpriv.h" +#include "qemu/qemu_driverpriv.h" #include "qemumonitortestutils.h" #include "testutils.h" #include "testutilsqemu.h" @@ -52,13 +53,15 @@ struct qemuHotplugTestData { bool keep; virDomainObjPtr vm; bool deviceDeletedEvent; + virDomainModificationImpact impact; }; static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, const char *domxml, - bool event, const char *testname) + bool event, const char *testname, + virDomainModificationImpact impact) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; @@ -93,7 +96,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (qemuAssignDeviceAliases((*vm)->def, priv->qemuCaps) < 0) goto cleanup; - (*vm)->def->id = QEMU_HOTPLUG_TEST_DOMAIN_ID; + if (impact == VIR_DOMAIN_AFFECT_LIVE) + (*vm)->def->id = QEMU_HOTPLUG_TEST_DOMAIN_ID; if (qemuDomainSetPrivatePaths(&driver, *vm) < 0) goto cleanup; @@ -105,19 +109,20 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, static int testQemuHotplugAttach(virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + const char *device_xml, + virDomainModificationImpact impact) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: + case VIR_DOMAIN_DEVICE_CHR: /* conn in only used for storage pool and secrets lookup so as long * as we don't use any of them, passing NULL should be safe */ - ret = qemuDomainAttachDeviceDiskLive(NULL, &driver, vm, dev); - break; - case VIR_DOMAIN_DEVICE_CHR: - ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr); + ret = qemuDomainAttachDeviceLiveAndConfig(NULL, vm, &driver, + device_xml, impact); break; default: VIR_TEST_VERBOSE("device type '%s' cannot be attached\n", @@ -130,16 +135,17 @@ testQemuHotplugAttach(virDomainObjPtr vm, static int testQemuHotplugDetach(virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + const char *device_xml, + virDomainModificationImpact impact) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainDetachDeviceDiskLive(&driver, vm, dev); - break; case VIR_DOMAIN_DEVICE_CHR: - ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr); + ret = qemuDomainDetachDeviceLiveAndConfig(&driver, vm, + device_xml, impact); break; default: VIR_TEST_VERBOSE("device type '%s' cannot be detached\n", @@ -178,16 +184,30 @@ static int testQemuHotplugCheckResult(virDomainObjPtr vm, const char *expected, const char *expectedFile, - bool fail) + bool fail, + virDomainModificationImpact impact) { - char *actual; + char *actual = NULL; int ret; - actual = virDomainDefFormat(vm->def, driver.caps, - VIR_DOMAIN_DEF_FORMAT_SECURE); + switch (impact) { + case VIR_DOMAIN_AFFECT_LIVE: + actual = virDomainDefFormat(vm->def, driver.caps, + VIR_DOMAIN_DEF_FORMAT_SECURE); + vm->def->id = QEMU_HOTPLUG_TEST_DOMAIN_ID; + break; + case VIR_DOMAIN_AFFECT_CONFIG: + actual = virDomainDefFormat(vm->def, driver.caps, + VIR_DOMAIN_DEF_FORMAT_SECURE); + break; + case VIR_DOMAIN_AFFECT_CURRENT: + VIR_TEST_VERBOSE("Please specify either VIR_DOMAIN_AFFECT_LIVE or" + "VIR_DOMAIN_AFFECT_CONFIG"); + break; + } + if (!actual) return -1; - vm->def->id = QEMU_HOTPLUG_TEST_DOMAIN_ID; if (STREQ(expected, actual)) { if (fail) @@ -225,17 +245,35 @@ testQemuHotplug(const void *data) virCapsPtr caps = NULL; qemuMonitorTestPtr test_mon = NULL; qemuDomainObjPrivatePtr priv = NULL; + virDomainModificationImpact impact = test->impact; if (virAsprintf(&domain_filename, "%s/qemuhotplugtestdomains/qemuhotplug-%s.xml", abs_srcdir, test->domain_filename) < 0 || virAsprintf(&device_filename, "%s/qemuhotplugtestdevices/qemuhotplug-%s.xml", - abs_srcdir, test->device_filename) < 0 || - virAsprintf(&result_filename, - "%s/qemuhotplugtestdomains/qemuhotplug-%s+%s.xml", - abs_srcdir, test->domain_filename, - test->device_filename) < 0) + abs_srcdir, test->device_filename) < 0) goto cleanup; + switch (impact) { + case VIR_DOMAIN_AFFECT_LIVE: + if (virAsprintf(&result_filename, + "%s/qemuhotplugtestdomains/qemuhotplug-%s+%s.xml", + abs_srcdir, test->domain_filename, + test->device_filename) < 0) + goto cleanup; + break; + case VIR_DOMAIN_AFFECT_CONFIG: + if (virAsprintf(&result_filename, + "%s/qemuhotplugtestdomains/qemuhotplug-%s+%s+config.xml", + abs_srcdir, test->domain_filename, + test->device_filename) < 0) + goto cleanup; + break; + default: + VIR_TEST_VERBOSE("Impact can either be VIR_DOMAIN_AFFECT_LIVE" + " or VIR_DOMAIN_AFFECT_CONFIG\n"); + goto cleanup; + } + if (virTestLoadFile(domain_filename, &domain_xml) < 0 || virTestLoadFile(device_filename, &device_xml) < 0) goto cleanup; @@ -252,7 +290,8 @@ testQemuHotplug(const void *data) } else { if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_xml, test->deviceDeletedEvent, - test->domain_filename) < 0) + test->domain_filename, + impact) < 0) goto cleanup; } @@ -292,22 +331,22 @@ testQemuHotplug(const void *data) switch (test->action) { case ATTACH: - ret = testQemuHotplugAttach(vm, dev); + ret = testQemuHotplugAttach(vm, dev, device_xml, impact); if (ret == 0) { /* vm->def stolen dev->data.* so we just need to free the dev * envelope */ VIR_FREE(dev); } if (ret == 0 || fail) - ret = testQemuHotplugCheckResult(vm, result_xml, - result_filename, fail); + ret = testQemuHotplugCheckResult(vm, result_xml, result_filename, + fail, impact); break; case DETACH: - ret = testQemuHotplugDetach(vm, dev); + ret = testQemuHotplugDetach(vm, dev, device_xml, impact); if (ret == 0 || fail) - ret = testQemuHotplugCheckResult(vm, domain_xml, - domain_filename, fail); + ret = testQemuHotplugCheckResult(vm, domain_xml, domain_filename, + fail, impact); break; case UPDATE: @@ -371,7 +410,7 @@ mymain(void) /* wait only 100ms for DEVICE_DELETED event */ qemuDomainRemoveDeviceWaitTime = 100; -#define DO_TEST(file, ACTION, dev, event, fial, kep, ...) \ +#define DO_TEST(file, ACTION, dev, event, fial, kep, impct, ...) \ do { \ const char *my_mon[] = { __VA_ARGS__, NULL}; \ const char *name = file " " #ACTION " " dev; \ @@ -382,28 +421,44 @@ mymain(void) data.mon = my_mon; \ data.keep = kep; \ data.deviceDeletedEvent = event; \ + data.impact = impct; \ if (virTestRun(name, testQemuHotplug, &data) < 0) \ ret = -1; \ } while (0) -#define DO_TEST_ATTACH(file, dev, fial, kep, ...) \ - DO_TEST(file, ATTACH, dev, false, fial, kep, __VA_ARGS__) +#define DO_TEST_ATTACH_LIVE(file, dev, fial, kep, ...) \ + DO_TEST(file, ATTACH, dev, false, fial, kep, \ + VIR_DOMAIN_AFFECT_LIVE, __VA_ARGS__) + +#define DO_TEST_DETACH_LIVE(file, dev, fial, kep, ...) \ + DO_TEST(file, DETACH, dev, false, fial, kep, \ + VIR_DOMAIN_AFFECT_LIVE, __VA_ARGS__) + +#define DO_TEST_ATTACH_EVENT_LIVE(file, dev, fial, kep, ...) \ + DO_TEST(file, ATTACH, dev, true, fial, kep, \ + VIR_DOMAIN_AFFECT_LIVE, __VA_ARGS__) + +#define DO_TEST_DETACH_EVENT_LIVE(file, dev, fial, kep, ...) \ + DO_TEST(file, DETACH, dev, true, fial, kep, \ + VIR_DOMAIN_AFFECT_LIVE, __VA_ARGS__) -#define DO_TEST_DETACH(file, dev, fial, kep, ...) \ - DO_TEST(file, DETACH, dev, false, fial, kep, __VA_ARGS__) +#define DO_TEST_UPDATE_LIVE(file, dev, fial, kep, ...) \ + DO_TEST(file, UPDATE, dev, false, fial, kep, \ + VIR_DOMAIN_AFFECT_LIVE, __VA_ARGS__) -#define DO_TEST_ATTACH_EVENT(file, dev, fial, kep, ...) \ - DO_TEST(file, ATTACH, dev, true, fial, kep, __VA_ARGS__) -#define DO_TEST_DETACH_EVENT(file, dev, fial, kep, ...) \ - DO_TEST(file, DETACH, dev, true, fial, kep, __VA_ARGS__) +#define DO_TEST_ATTACH_CONFIG(file, dev, fial, kep, ...) \ + DO_TEST(file, ATTACH, dev, false, fial, kep, \ + VIR_DOMAIN_AFFECT_CONFIG, __VA_ARGS__) -#define DO_TEST_UPDATE(file, dev, fial, kep, ...) \ - DO_TEST(file, UPDATE, dev, false, fial, kep, __VA_ARGS__) +#define DO_TEST_DETACH_CONFIG(file, dev, fial, kep, ...) \ + DO_TEST(file, DETACH, dev, false, fial, kep, \ + VIR_DOMAIN_AFFECT_CONFIG, __VA_ARGS__) #define QMP_OK "{\"return\": {}}" #define HMP(msg) "{\"return\": \"" msg "\"}" +#define QOM_OK "{ \"return\": []}" #define QMP_DEVICE_DELETED(dev) \ "{" \ @@ -418,147 +473,159 @@ mymain(void) " }" \ "}\r\n" - DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); - DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, - "set_password", QMP_OK, "expire_password", QMP_OK); - DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-password", false, false, - "set_password", QMP_OK, "expire_password", QMP_OK); - DO_TEST_UPDATE("graphics-spice", "graphics-spice-listen", true, false, NULL); - DO_TEST_UPDATE("graphics-spice-listen-network", "graphics-spice-listen-network-password", false, false, - "set_password", QMP_OK, "expire_password", QMP_OK); + DO_TEST_UPDATE_LIVE("graphics-spice", "graphics-spice-nochange", false, false, NULL); + DO_TEST_UPDATE_LIVE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, + "set_password", QMP_OK, "expire_password", QMP_OK); + DO_TEST_UPDATE_LIVE("graphics-spice-timeout", "graphics-spice-timeout-password", false, false, + "set_password", QMP_OK, "expire_password", QMP_OK); + DO_TEST_UPDATE_LIVE("graphics-spice", "graphics-spice-listen", true, false, NULL); + DO_TEST_UPDATE_LIVE("graphics-spice-listen-network", "graphics-spice-listen-network-password", false, false, + "set_password", QMP_OK, "expire_password", QMP_OK); /* Strange huh? Currently, only graphics can be updated :-P */ - DO_TEST_UPDATE("disk-cdrom", "disk-cdrom-nochange", true, false, NULL); - - DO_TEST_ATTACH("console-compat-2-live", "console-virtio", false, true, - "chardev-add", "{\"return\": {\"pty\": \"/dev/pts/26\"}}", - "device_add", QMP_OK); - - DO_TEST_DETACH("console-compat-2-live", "console-virtio", false, false, - "device_del", QMP_OK, - "chardev-remove", QMP_OK); - - DO_TEST_ATTACH("base-live", "disk-virtio", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-virtio", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH_EVENT("base-live", "disk-virtio", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-virtio", true, true, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - DO_TEST_DETACH("base-live", "disk-virtio", false, false, - "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-live", "disk-usb", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-usb", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH_EVENT("base-live", "disk-usb", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-usb", true, true, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - DO_TEST_DETACH("base-live", "disk-usb", false, false, - "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-live", "disk-scsi", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-scsi", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH_EVENT("base-live", "disk-scsi", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "disk-scsi", true, true, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - DO_TEST_DETACH("base-live", "disk-scsi", false, false, - "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-without-scsi-controller-live", "disk-scsi-2", false, true, - /* Four controllers added */ - "device_add", QMP_OK, - "device_add", QMP_OK, - "device_add", QMP_OK, - "device_add", QMP_OK, - "human-monitor-command", HMP("OK\\r\\n"), - /* Disk added */ - "device_add", QMP_OK); - DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH_EVENT("base-without-scsi-controller-live", "disk-scsi-2", false, true, - /* Four controllers added */ - "device_add", QMP_OK, - "device_add", QMP_OK, - "device_add", QMP_OK, - "device_add", QMP_OK, - "human-monitor-command", HMP("OK\\r\\n"), - /* Disk added */ - "device_add", QMP_OK); - DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", true, true, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - DO_TEST_DETACH("base-with-scsi-controller-live", "disk-scsi-2", false, false, - "device_del", QMP_DEVICE_DELETED("scsi3-0-5-7") QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-live", "qemu-agent", false, true, - "chardev-add", QMP_OK, - "device_add", QMP_OK); - DO_TEST_DETACH("base-live", "qemu-agent-detach", false, false, - "device_del", QMP_OK, - "chardev-remove", QMP_OK); - - DO_TEST_ATTACH("base-ccw-live", "ccw-virtio", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - DO_TEST_DETACH("base-ccw-live", "ccw-virtio", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - - DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); - - DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); - - DO_TEST_DETACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, false, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); + DO_TEST_UPDATE_LIVE("disk-cdrom", "disk-cdrom-nochange", true, false, NULL); + + DO_TEST_ATTACH_LIVE("console-compat-2-live", "console-virtio", false, true, + "chardev-add", "{\"return\": {\"pty\": \"/dev/pts/26\"}}", + "device_add", QMP_OK); + + DO_TEST_DETACH_LIVE("console-compat-2-live", "console-virtio", false, false, + "device_del", QMP_OK, + "chardev-remove", QMP_OK); + + DO_TEST_ATTACH_LIVE("base-live", "disk-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-virtio", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT_LIVE("base-live", "disk-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK, + "qom-list", QOM_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-virtio", true, true, + "device_del", QMP_OK, + "qom-list", QOM_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH_LIVE("base-live", "disk-virtio", false, false, + "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, + "human-monitor-command", HMP(""), + "qom-list", QOM_OK); + + DO_TEST_ATTACH_LIVE("base-live", "disk-usb", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-usb", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT_LIVE("base-live", "disk-usb", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK, + "qom-list", QOM_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-usb", true, true, + "device_del", QMP_OK, + "qom-list", QOM_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH_LIVE("base-live", "disk-usb", false, false, + "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, + "human-monitor-command", HMP(""), + "qom-list", QOM_OK); + + DO_TEST_ATTACH_LIVE("base-live", "disk-scsi", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-scsi", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT_LIVE("base-live", "disk-scsi", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK, + "qom-list", QOM_OK); + DO_TEST_DETACH_LIVE("base-live", "disk-scsi", true, true, + "device_del", QMP_OK, + "qom-list", QOM_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH_LIVE("base-live", "disk-scsi", false, false, + "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, + "human-monitor-command", HMP(""), + "qom-list", QOM_OK); + + DO_TEST_ATTACH_LIVE("base-without-scsi-controller-live", "disk-scsi-2", false, true, + /* Four controllers added */ + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, + "human-monitor-command", HMP("OK\\r\\n"), + /* Disk added */ + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-with-scsi-controller-live", "disk-scsi-2", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT_LIVE("base-without-scsi-controller-live", "disk-scsi-2", false, true, + /* Four controllers added */ + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, + "device_add", QMP_OK, + "human-monitor-command", HMP("OK\\r\\n"), + /* Disk added */ + "device_add", QMP_OK, + "qom-list", QOM_OK); + DO_TEST_DETACH_LIVE("base-with-scsi-controller-live", "disk-scsi-2", true, true, + "device_del", QMP_OK, + "qom-list", QOM_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH_LIVE("base-with-scsi-controller-live", "disk-scsi-2", false, false, + "device_del", QMP_DEVICE_DELETED("scsi3-0-5-7") QMP_OK, + "human-monitor-command", HMP(""), + "qom-list", QOM_OK); + + DO_TEST_ATTACH_LIVE("base-live", "qemu-agent", false, true, + "chardev-add", QMP_OK, + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-live", "qemu-agent-detach", false, false, + "device_del", QMP_OK, + "chardev-remove", QMP_OK); + + DO_TEST_ATTACH_LIVE("base-ccw-live", "ccw-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH_LIVE("base-ccw-live", "ccw-virtio", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_LIVE("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + + DO_TEST_DETACH_LIVE("base-ccw-live-with-ccw-virtio", "ccw-virtio-2", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_LIVE("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + + DO_TEST_DETACH_LIVE("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); /* Attach a second device, then detach the first one. Then attach the first one again. */ - DO_TEST_ATTACH("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); + DO_TEST_ATTACH_LIVE("base-ccw-live-with-ccw-virtio", "ccw-virtio-2-explicit", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); - DO_TEST_DETACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-explicit", false, true, - "device_del", QMP_OK, - "human-monitor-command", HMP("")); + DO_TEST_DETACH_LIVE("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-explicit", false, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); - DO_TEST_ATTACH("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-reverse", false, false, - "human-monitor-command", HMP("OK\\r\\n"), - "device_add", QMP_OK); + DO_TEST_ATTACH_LIVE("base-ccw-live-with-2-ccw-virtio", "ccw-virtio-1-reverse", false, false, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); qemuTestDriverFree(&driver); return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -- 1.9.1

Previously, specific functions had to be used to test updating devices, different for every device type. It was too much trouble and noone bothered with it. qemuDomainUpdateDeviceLiveAndConfig is now being used instead. --- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_driverpriv.h | 7 +++++++ tests/qemuhotplugtest.c | 10 +++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f650766..b10efd4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8202,7 +8202,7 @@ static int qemuDomainAttachDevice(virDomainPtr dom, const char *xml) VIR_DOMAIN_AFFECT_LIVE); } -static int +int qemuDomainUpdateDeviceLiveAndConfig(virConnectPtr conn, virDomainObjPtr vm, virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_driverpriv.h b/src/qemu/qemu_driverpriv.h index 943f0da..2a71a00 100644 --- a/src/qemu/qemu_driverpriv.h +++ b/src/qemu/qemu_driverpriv.h @@ -37,4 +37,11 @@ int qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr driver, const char *xml, unsigned int flags); +int +qemuDomainUpdateDeviceLiveAndConfig(virConnectPtr conn, + virDomainObjPtr vm, + virQEMUDriverPtr driver, + const char *xml, + unsigned int flags); + #endif /* __QEMU_DRIVERPRIV_H__ */ diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 13d2bdc..115dc1e 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -158,7 +158,9 @@ testQemuHotplugDetach(virDomainObjPtr vm, static int testQemuHotplugUpdate(virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDeviceDefPtr dev, + const char *device_xml, + virDomainModificationImpact impact) { int ret = -1; @@ -169,7 +171,9 @@ testQemuHotplugUpdate(virDomainObjPtr vm, * required object, we can replace this code then. */ switch (dev->type) { case VIR_DOMAIN_DEVICE_GRAPHICS: - ret = qemuDomainChangeGraphics(&driver, vm, dev->data.graphics); + /* conn is only used for storage lookup, so passing NULL should be safe. */ + ret = qemuDomainUpdateDeviceLiveAndConfig(NULL, vm, &driver, + device_xml, impact); break; default: VIR_TEST_VERBOSE("device type '%s' cannot be updated\n", @@ -350,7 +354,7 @@ testQemuHotplug(const void *data) break; case UPDATE: - ret = testQemuHotplugUpdate(vm, dev); + ret = testQemuHotplugUpdate(vm, dev, device_xml, impact); } cleanup: -- 1.9.1

Since we can now use qemuDomainUpdateDeviceLiveAndConfig in tests, updating more types of devices can be tested now. One particular testcase was previously expected to trivially fail because there was no way to test updating a disk device. Since now it's possible to execute it, I modified it to make it work. --- tests/qemuhotplugtest.c | 9 ++------- tests/qemuhotplugtestdevices/qemuhotplug-disk-cdrom-nochange.xml | 2 +- tests/qemuhotplugtestdomains/qemuhotplug-disk-cdrom.xml | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 115dc1e..0bb4fe6 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -164,13 +164,9 @@ testQemuHotplugUpdate(virDomainObjPtr vm, { int ret = -1; - /* XXX Ideally, we would call qemuDomainUpdateDeviceLive here. But that - * would require us to provide virConnectPtr and virDomainPtr (they're used - * in case of updating a disk device. So for now, we will proceed with - * breaking the function into pieces. If we ever learn how to fake those - * required object, we can replace this code then. */ switch (dev->type) { case VIR_DOMAIN_DEVICE_GRAPHICS: + case VIR_DOMAIN_DEVICE_DISK: /* conn is only used for storage lookup, so passing NULL should be safe. */ ret = qemuDomainUpdateDeviceLiveAndConfig(NULL, vm, &driver, device_xml, impact); @@ -485,8 +481,7 @@ mymain(void) DO_TEST_UPDATE_LIVE("graphics-spice", "graphics-spice-listen", true, false, NULL); DO_TEST_UPDATE_LIVE("graphics-spice-listen-network", "graphics-spice-listen-network-password", false, false, "set_password", QMP_OK, "expire_password", QMP_OK); - /* Strange huh? Currently, only graphics can be updated :-P */ - DO_TEST_UPDATE_LIVE("disk-cdrom", "disk-cdrom-nochange", true, false, NULL); + DO_TEST_UPDATE_LIVE("disk-cdrom", "disk-cdrom-nochange", false, false, NULL); DO_TEST_ATTACH_LIVE("console-compat-2-live", "console-virtio", false, true, "chardev-add", "{\"return\": {\"pty\": \"/dev/pts/26\"}}", diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-disk-cdrom-nochange.xml b/tests/qemuhotplugtestdevices/qemuhotplug-disk-cdrom-nochange.xml index 26841ea..ad2f9a6 100644 --- a/tests/qemuhotplugtestdevices/qemuhotplug-disk-cdrom-nochange.xml +++ b/tests/qemuhotplugtestdevices/qemuhotplug-disk-cdrom-nochange.xml @@ -1,6 +1,6 @@ <disk type='block' device='disk'> <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> + <source dev='/dev/null'/> <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-disk-cdrom.xml b/tests/qemuhotplugtestdomains/qemuhotplug-disk-cdrom.xml index 04f4976..89ca23e 100644 --- a/tests/qemuhotplugtestdomains/qemuhotplug-disk-cdrom.xml +++ b/tests/qemuhotplugtestdomains/qemuhotplug-disk-cdrom.xml @@ -16,7 +16,7 @@ <emulator>/usr/bin/qemu</emulator> <disk type='block' device='disk'> <driver name='qemu' type='raw'/> - <source dev='/dev/HostVG/QEMUGuest1'/> + <source dev='/dev/null'/> <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> -- 1.9.1

This is the first testcase for attaching and detaching a device to the persistent domain. --- tests/qemuhotplugtest.c | 7 ++++ .../qemuhotplug-qemu-agent.xml | 1 - .../qemuhotplug-base-config+qemu-agent+config.xml | 44 ++++++++++++++++++++++ .../qemuhotplug-base-config.xml | 40 ++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-config+qemu-agent+config.xml create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-config.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 0bb4fe6..f26aedd 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -626,6 +626,13 @@ mymain(void) "human-monitor-command", HMP("OK\\r\\n"), "device_add", QMP_OK); + DO_TEST_ATTACH_CONFIG("base-config", "qemu-agent", false, true, + "chardev-add", QMP_OK, + "device_add", QMP_OK); + DO_TEST_DETACH_CONFIG("base-config", "qemu-agent", false, false, + "device_del", QMP_OK, + "chardev-remove", QMP_OK); + qemuTestDriverFree(&driver); return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent.xml b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent.xml index f0e90de..648da4b 100644 --- a/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent.xml +++ b/tests/qemuhotplugtestdevices/qemuhotplug-qemu-agent.xml @@ -1,5 +1,4 @@ <channel type='unix'> - <source mode='bind'/> <target type='virtio' name='org.qemu.guest_agent.0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-config+qemu-agent+config.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-config+qemu-agent+config.xml new file mode 100644 index 0000000..94dc934 --- /dev/null +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-config+qemu-agent+config.xml @@ -0,0 +1,44 @@ +<domain type='kvm'> + <name>hotplug</name> + <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>4</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='virtio-scsi'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> + <seclabel type='none' model='none'/> +</domain> diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-config.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-config.xml new file mode 100644 index 0000000..20ad0a5 --- /dev/null +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-config.xml @@ -0,0 +1,40 @@ +<domain type='kvm'> + <name>hotplug</name> + <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid> + <memory unit='KiB'>4194304</memory> + <currentMemory unit='KiB'>4194304</currentMemory> + <vcpu placement='static'>4</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <acpi/> + <apic/> + <pae/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <devices> + <emulator>/usr/libexec/qemu-kvm</emulator> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='virtio-scsi'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='virtio-serial' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='none'/> + </devices> + <seclabel type='none' model='none'/> +</domain> -- 1.9.1

+ DO_TEST_ATTACH_CONFIG("base-config", "qemu-agent", false, true, + "chardev-add", QMP_OK, + "device_add", QMP_OK); + DO_TEST_DETACH_CONFIG("base-config", "qemu-agent", false, false, + "device_del", QMP_OK, + "chardev-remove", QMP_OK); + The indentation is broken here (a few spaces are missing), because I forgot to fix it in this place after adding the _CONFIG suffix.

On Thu, Jul 28, 2016 at 09:53:55PM +0200, Tomasz Flendrich wrote:
Changes in v3: * fewer patches, because part of v2 was ACK'd * two old commits, 08/10 and 09/10, are now one commit * qemuDomainUpdateDeviceFlags is now also split, creating a new function qemuDomainUpdateDeviceLiveAndConfig(). This function is now used in qemuhotplugtest.c. * qemuDomainAttachDeviceLiveAndConfig, qemuDomainDetachDeviceLiveAndConfig and qemuDomainUpdateDeviceLiveAndConfig are now in a new file: qemu_driverpriv.h * variable "target" is renamed to "impact" and its type is changed * testQemuHotplugCheckResult() now takes "impact" as a parameter to determine whether to test the ->def or ->newDef * def->id is no longer set when handling a persistent domain * split DO_TEST_ATTACH (and other macros) to DO_TEST_ATTACH_LIVE and DO_TEST_ATTACH_CONFIG instead of taking a parameter * fixed indentation * "<source mode='bind'/>" is removed from one xml * a three year old testcase for updating a disk device was modified a little bit to make it finally execute and test something
Link to v2: https://www.redhat.com/archives/libvir-list/2016-July/msg00595.html
So I took all the series and started working some stuff in on top of them as they are kinda connected and some things could be handled differently and so on. I got swamped by other stuff in the meantime and left this for a later time. If anyone checked my github [1], branch "tom" is where I keep both changed and new patches. IIRC, it is currently working, but it's not ready for posting. I would love to make it complete. Feel free to tell me your thoughts on it and we can discuss how to split the work or how to continue from there. Sorry for the huge delays, Martin
participants (2)
-
Martin Kletzander
-
Tomasz Flendrich