[libvirt] [PATCH 00/17] Add tests for disk hotplug

This series adds tests for hotplugging all supported disk types. Jiri Denemark (17): qemu: Typedef monitor callbacks qemu: Avoid using global qemu_driver in event handlers qemu: Move qemuDomainAttachDeviceDiskLive to qemu_hotplug.c qemu: Move qemuDomainDetachDeviceDiskLive to qemu_hotplug.c qemuhotplugtest: Generate better output qemuhotplugtest: Compare domain XML after device hotplug qemuhotplugtest: Define QMP_OK for the most common reply qemuxml2argvtest: Add XML for testing device hotplug qemuhotplugtest: Add tests for virtio disk hotplug tests: Add support for passing vm to qemu monitor tests: Add support for passing driver to qemu monitor qemu: Export qemuProcessHandleDeviceDeleted for tests qemu: Let tests override waiting time for device unplug qemuhotplugtest: Add support for DEVICE_DELETED event qemuhotplugtest: Add tests for async virtio disk detach qemuhotplugtest: Add tests for USB disk hotplug qemuhotplugtest: Add tests for virtio SCSI disk hotplug src/Makefile.am | 2 + src/qemu/qemu_capabilities.c | 5 +- src/qemu/qemu_driver.c | 166 --------------- src/qemu/qemu_hotplug.c | 219 +++++++++++++++++-- src/qemu/qemu_hotplug.h | 25 +-- src/qemu/qemu_hotplugpriv.h | 31 +++ src/qemu/qemu_monitor.c | 30 +-- src/qemu/qemu_monitor.h | 198 +++++++++++------- src/qemu/qemu_process.c | 104 +++++---- src/qemu/qemu_process.h | 2 +- src/qemu/qemu_processpriv.h | 37 ++++ tests/qemuhotplugtest.c | 232 +++++++++++++++++---- ...qemuhotplug-console-compat-2+console-virtio.xml | 127 +++++++++++ .../qemuhotplugtestdata/qemuhotplug-disk-scsi.xml | 7 + tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml | 7 + .../qemuhotplug-disk-virtio.xml | 7 + .../qemuhotplug-hotplug-base+disk-scsi.xml | 46 ++++ .../qemuhotplug-hotplug-base+disk-usb.xml | 45 ++++ .../qemuhotplug-hotplug-base+disk-virtio.xml | 46 ++++ tests/qemumonitorjsontest.c | 26 +-- tests/qemumonitortestutils.c | 31 ++- tests/qemumonitortestutils.h | 8 +- .../qemuxml2argv-hotplug-base.args | 7 + .../qemuxml2argvdata/qemuxml2argv-hotplug-base.xml | 38 ++++ tests/qemuxml2argvtest.c | 4 + 25 files changed, 1047 insertions(+), 403 deletions(-) create mode 100644 src/qemu/qemu_hotplugpriv.h create mode 100644 src/qemu/qemu_processpriv.h create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml -- 1.8.3.2

Otherwise defining variables that hold callbacks pointers is ugly and several places have to be changed when new parameters are added. --- src/qemu/qemu_monitor.c | 6 +- src/qemu/qemu_monitor.h | 171 +++++++++++++++++++++++++++--------------------- 2 files changed, 98 insertions(+), 79 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 5b2fb04..2801c9c 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -660,8 +660,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { * but is this safe ? I think it is, because the callback * will try to acquire the virDomainObjPtr mutex next */ if (eof) { - void (*eofNotify)(qemuMonitorPtr, virDomainObjPtr) - = mon->cb->eofNotify; + qemuMonitorEofNotifyCallback eofNotify = mon->cb->eofNotify; virDomainObjPtr vm = mon->vm; /* Make sure anyone waiting wakes up now */ @@ -671,8 +670,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { VIR_DEBUG("Triggering EOF callback"); (eofNotify)(mon, vm); } else if (error) { - void (*errorNotify)(qemuMonitorPtr, virDomainObjPtr) - = mon->cb->errorNotify; + qemuMonitorErrorNotifyCallback errorNotify = mon->cb->errorNotify; virDomainObjPtr vm = mon->vm; /* Make sure anyone waiting wakes up now */ diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 4a55501..9e12788 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -67,84 +67,105 @@ struct _qemuMonitorMessage { void *passwordOpaque; }; + +typedef void (*qemuMonitorDestroyCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef void (*qemuMonitorEofNotifyCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef void (*qemuMonitorErrorNotifyCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +/* XXX we'd really like to avoid virConnectPtr here + * It is required so the callback can find the active + * secret driver. Need to change this to work like the + * security drivers do, to avoid this + */ +typedef int (*qemuMonitorDiskSecretLookupCallback)(qemuMonitorPtr mon, + virConnectPtr conn, + virDomainObjPtr vm, + const char *path, + char **secret, + size_t *secretLen); +typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainPowerdownCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainStopCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainResumeCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainRTCChangeCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + long long offset); +typedef int (*qemuMonitorDomainWatchdogCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + int action); +typedef int (*qemuMonitorDomainIOErrorCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *diskAlias, + int action, + const char *reason); +typedef int (*qemuMonitorDomainGraphicsCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + int phase, + int localFamily, + const char *localNode, + const char *localService, + int remoteFamily, + const char *remoteNode, + const char *remoteService, + const char *authScheme, + const char *x509dname, + const char *saslUsername); +typedef int (*qemuMonitorDomainBlockJobCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *diskAlias, + int type, + int status); +typedef int (*qemuMonitorDomainTrayChangeCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *devAlias, + int reason); +typedef int (*qemuMonitorDomainPMWakeupCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainPMSuspendCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainBalloonChangeCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + unsigned long long actual); +typedef int (*qemuMonitorDomainPMSuspendDiskCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm); +typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *devAlias); + typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks; typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr; struct _qemuMonitorCallbacks { - void (*destroy)(qemuMonitorPtr mon, - virDomainObjPtr vm); - - void (*eofNotify)(qemuMonitorPtr mon, - virDomainObjPtr vm); - void (*errorNotify)(qemuMonitorPtr mon, - virDomainObjPtr vm); - /* XXX we'd really like to avoid virConnectPtr here - * It is required so the callback can find the active - * secret driver. Need to change this to work like the - * security drivers do, to avoid this - */ - int (*diskSecretLookup)(qemuMonitorPtr mon, - virConnectPtr conn, - virDomainObjPtr vm, - const char *path, - char **secret, - size_t *secretLen); - - int (*domainShutdown)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainReset)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainPowerdown)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainStop)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainResume)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainRTCChange)(qemuMonitorPtr mon, - virDomainObjPtr vm, - long long offset); - int (*domainWatchdog)(qemuMonitorPtr mon, - virDomainObjPtr vm, - int action); - int (*domainIOError)(qemuMonitorPtr mon, - virDomainObjPtr vm, - const char *diskAlias, - int action, - const char *reason); - int (*domainGraphics)(qemuMonitorPtr mon, - virDomainObjPtr vm, - int phase, - int localFamily, - const char *localNode, - const char *localService, - int remoteFamily, - const char *remoteNode, - const char *remoteService, - const char *authScheme, - const char *x509dname, - const char *saslUsername); - int (*domainBlockJob)(qemuMonitorPtr mon, - virDomainObjPtr vm, - const char *diskAlias, - int type, - int status); - int (*domainTrayChange)(qemuMonitorPtr mon, - virDomainObjPtr vm, - const char *devAlias, - int reason); - int (*domainPMWakeup)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainPMSuspend)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainBalloonChange)(qemuMonitorPtr mon, - virDomainObjPtr vm, - unsigned long long actual); - int (*domainPMSuspendDisk)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainGuestPanic)(qemuMonitorPtr mon, - virDomainObjPtr vm); - int (*domainDeviceDeleted)(qemuMonitorPtr mon, - virDomainObjPtr vm, - const char *devAlias); + qemuMonitorDestroyCallback destroy; + qemuMonitorEofNotifyCallback eofNotify; + qemuMonitorErrorNotifyCallback errorNotify; + qemuMonitorDiskSecretLookupCallback diskSecretLookup; + qemuMonitorDomainShutdownCallback domainShutdown; + qemuMonitorDomainResetCallback domainReset; + qemuMonitorDomainPowerdownCallback domainPowerdown; + qemuMonitorDomainStopCallback domainStop; + qemuMonitorDomainResumeCallback domainResume; + qemuMonitorDomainRTCChangeCallback domainRTCChange; + qemuMonitorDomainWatchdogCallback domainWatchdog; + qemuMonitorDomainIOErrorCallback domainIOError; + qemuMonitorDomainGraphicsCallback domainGraphics; + qemuMonitorDomainBlockJobCallback domainBlockJob; + qemuMonitorDomainTrayChangeCallback domainTrayChange; + qemuMonitorDomainPMWakeupCallback domainPMWakeup; + qemuMonitorDomainPMSuspendCallback domainPMSuspend; + qemuMonitorDomainBalloonChangeCallback domainBalloonChange; + qemuMonitorDomainPMSuspendDiskCallback domainPMSuspendDisk; + qemuMonitorDomainGuestPanicCallback domainGuestPanic; + qemuMonitorDomainDeviceDeletedCallback domainDeviceDeleted; }; char *qemuMonitorEscapeArg(const char *in); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:10PM +0200, Jiri Denemark wrote:
Otherwise defining variables that hold callbacks pointers is ugly and several places have to be changed when new parameters are added. --- src/qemu/qemu_monitor.c | 6 +- src/qemu/qemu_monitor.h | 171 +++++++++++++++++++++++++++--------------------- 2 files changed, 98 insertions(+), 79 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

We will have to pass a mock-up of the driver when testing monitor events. --- src/qemu/qemu_capabilities.c | 5 ++- src/qemu/qemu_monitor.c | 24 +++++++---- src/qemu/qemu_monitor.h | 69 ++++++++++++++++++++---------- src/qemu/qemu_process.c | 99 +++++++++++++++++++++++++++----------------- tests/qemumonitortestutils.c | 9 ++-- 5 files changed, 130 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 08406b8..718b8d3 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2352,7 +2352,8 @@ cleanup: static void virQEMUCapsMonitorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm ATTRIBUTE_UNUSED) + virDomainObjPtr vm ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) { } @@ -2544,7 +2545,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps, memset(&vm, 0, sizeof(vm)); vm.pid = pid; - if (!(mon = qemuMonitorOpen(&vm, &config, true, &callbacks))) { + if (!(mon = qemuMonitorOpen(&vm, &config, true, &callbacks, NULL))) { ret = 0; goto cleanup; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2801c9c..ecec8e2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -61,6 +61,7 @@ struct _qemuMonitor { virDomainObjPtr vm; qemuMonitorCallbacksPtr cb; + void *callbackOpaque; /* If there's a command being processed this will be * non-NULL */ @@ -248,7 +249,7 @@ static void qemuMonitorDispose(void *obj) VIR_DEBUG("mon=%p", mon); if (mon->cb && mon->cb->destroy) - (mon->cb->destroy)(mon, mon->vm); + (mon->cb->destroy)(mon, mon->vm, mon->callbackOpaque); virCondDestroy(&mon->notify); VIR_FREE(mon->buffer); virJSONValueFree(mon->options); @@ -668,7 +669,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { virObjectUnlock(mon); virObjectUnref(mon); VIR_DEBUG("Triggering EOF callback"); - (eofNotify)(mon, vm); + (eofNotify)(mon, vm, mon->callbackOpaque); } else if (error) { qemuMonitorErrorNotifyCallback errorNotify = mon->cb->errorNotify; virDomainObjPtr vm = mon->vm; @@ -678,7 +679,7 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { virObjectUnlock(mon); virObjectUnref(mon); VIR_DEBUG("Triggering error callback"); - (errorNotify)(mon, vm); + (errorNotify)(mon, vm, mon->callbackOpaque); } else { virObjectUnlock(mon); virObjectUnref(mon); @@ -691,7 +692,8 @@ qemuMonitorOpenInternal(virDomainObjPtr vm, int fd, bool hasSendFD, bool json, - qemuMonitorCallbacksPtr cb) + qemuMonitorCallbacksPtr cb, + void *opaque) { qemuMonitorPtr mon; @@ -725,6 +727,7 @@ qemuMonitorOpenInternal(virDomainObjPtr vm, if (json) mon->waitGreeting = true; mon->cb = cb; + mon->callbackOpaque = opaque; if (virSetCloseExec(mon->fd) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -778,7 +781,8 @@ qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, bool json, - qemuMonitorCallbacksPtr cb) + qemuMonitorCallbacksPtr cb, + void *opaque) { int fd; bool hasSendFD = false; @@ -803,7 +807,7 @@ qemuMonitorOpen(virDomainObjPtr vm, return NULL; } - ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb); + ret = qemuMonitorOpenInternal(vm, fd, hasSendFD, json, cb, opaque); if (!ret) VIR_FORCE_CLOSE(fd); return ret; @@ -813,9 +817,10 @@ qemuMonitorOpen(virDomainObjPtr vm, qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, int sockfd, bool json, - qemuMonitorCallbacksPtr cb) + qemuMonitorCallbacksPtr cb, + void *opaque) { - return qemuMonitorOpenInternal(vm, sockfd, true, json, cb); + return qemuMonitorOpenInternal(vm, sockfd, true, json, cb, opaque); } @@ -1068,7 +1073,8 @@ cleanup: virObjectRef(mon); \ virObjectUnlock(mon); \ if ((mon)->cb && (mon)->cb->callback) \ - (ret) = ((mon)->cb->callback)(mon, __VA_ARGS__); \ + (ret) = (mon)->cb->callback(mon, __VA_ARGS__, \ + (mon)->callbackOpaque); \ virObjectLock(mon); \ virObjectUnref(mon); \ } while (0) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9e12788..5fe33db 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -69,11 +69,14 @@ struct _qemuMonitorMessage { typedef void (*qemuMonitorDestroyCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef void (*qemuMonitorEofNotifyCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef void (*qemuMonitorErrorNotifyCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); /* XXX we'd really like to avoid virConnectPtr here * It is required so the callback can find the active * secret driver. Need to change this to work like the @@ -84,28 +87,37 @@ typedef int (*qemuMonitorDiskSecretLookupCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, const char *path, char **secret, - size_t *secretLen); + size_t *secretLen, + void *opaque); typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainResetCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainPowerdownCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainStopCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainResumeCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainRTCChangeCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, - long long offset); + long long offset, + void *opaque); typedef int (*qemuMonitorDomainWatchdogCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, - int action); + int action, + void *opaque); typedef int (*qemuMonitorDomainIOErrorCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, const char *diskAlias, int action, - const char *reason); + const char *reason, + void *opaque); typedef int (*qemuMonitorDomainGraphicsCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, int phase, @@ -117,30 +129,39 @@ typedef int (*qemuMonitorDomainGraphicsCallback)(qemuMonitorPtr mon, const char *remoteService, const char *authScheme, const char *x509dname, - const char *saslUsername); + const char *saslUsername, + void *opaque); typedef int (*qemuMonitorDomainBlockJobCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, const char *diskAlias, int type, - int status); + int status, + void *opaque); typedef int (*qemuMonitorDomainTrayChangeCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, const char *devAlias, - int reason); + int reason, + void *opaque); typedef int (*qemuMonitorDomainPMWakeupCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainPMSuspendCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainBalloonChangeCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, - unsigned long long actual); + unsigned long long actual, + void *opaque); typedef int (*qemuMonitorDomainPMSuspendDiskCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon, - virDomainObjPtr vm); + virDomainObjPtr vm, + void *opaque); typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, - const char *devAlias); + const char *devAlias, + void *opaque); typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks; typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr; @@ -174,12 +195,14 @@ char *qemuMonitorUnescapeArg(const char *in); qemuMonitorPtr qemuMonitorOpen(virDomainObjPtr vm, virDomainChrSourceDefPtr config, bool json, - qemuMonitorCallbacksPtr cb) + qemuMonitorCallbacksPtr cb, + void *opaque) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4); qemuMonitorPtr qemuMonitorOpenFD(virDomainObjPtr vm, int sockfd, bool json, - qemuMonitorCallbacksPtr cb) + qemuMonitorCallbacksPtr cb, + void *opaque) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); void qemuMonitorClose(qemuMonitorPtr mon); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0dccac3..0d48f4f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -280,9 +280,10 @@ cleanup: */ static void qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; qemuDomainObjPrivatePtr priv; int eventReason = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN; @@ -341,9 +342,10 @@ cleanup: */ static void qemuProcessHandleMonitorError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; VIR_DEBUG("Received error on %p '%s'", vm, vm->def->name); @@ -486,7 +488,8 @@ qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, const char *path, char **secretRet, - size_t *secretLen) + size_t *secretLen, + void *opaque ATTRIBUTE_UNUSED) { virDomainDiskDefPtr disk; int ret = -1; @@ -507,9 +510,10 @@ cleanup: static int qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event; qemuDomainObjPrivatePtr priv; @@ -637,9 +641,10 @@ qemuProcessShutdownOrReboot(virQEMUDriverPtr driver, static int qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; qemuDomainObjPrivatePtr priv; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -691,9 +696,10 @@ unlock: static int qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -737,9 +743,10 @@ unlock: static int qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -790,9 +797,10 @@ unlock: static int qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, - long long offset) + long long offset, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -830,9 +838,10 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, - int action) + int action, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr watchdogEvent = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -896,9 +905,10 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, const char *diskAlias, int action, - const char *reason) + const char *reason, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr ioErrorEvent = NULL; virDomainEventPtr ioErrorEvent2 = NULL; virDomainEventPtr lifecycleEvent = NULL; @@ -956,9 +966,10 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, const char *diskAlias, int type, - int status) + int status, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; const char *path; virDomainDiskDefPtr disk; @@ -1008,9 +1019,10 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED, const char *remoteService, const char *authScheme, const char *x509dname, - const char *saslUsername) + const char *saslUsername, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event; virDomainEventGraphicsAddressPtr localAddr = NULL; virDomainEventGraphicsAddressPtr remoteAddr = NULL; @@ -1084,7 +1096,8 @@ error: static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque ATTRIBUTE_UNUSED) { virObjectUnref(vm); } @@ -1093,9 +1106,10 @@ static int qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, const char *devAlias, - int reason) + int reason, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virDomainDiskDefPtr disk; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -1128,9 +1142,10 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -1168,9 +1183,10 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -1212,9 +1228,10 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, - unsigned long long actual) + unsigned long long actual, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -1238,9 +1255,10 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virDomainEventPtr event = NULL; virDomainEventPtr lifecycleEvent = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); @@ -1283,9 +1301,10 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static int qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; struct qemuProcessEvent *processEvent; virObjectLock(vm); @@ -1316,9 +1335,10 @@ cleanup: static int qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, - const char *devAlias) + const char *devAlias, + void *opaque) { - virQEMUDriverPtr driver = qemu_driver; + virQEMUDriverPtr driver = opaque; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virDomainDeviceDef dev; @@ -1391,7 +1411,8 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm) mon = qemuMonitorOpen(vm, priv->monConfig, priv->monJSON, - &monitorCallbacks); + &monitorCallbacks, + driver); virObjectLock(vm); priv->monStart = 0; diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index fb76156..93fb342 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -708,14 +708,16 @@ error: static void qemuMonitorTestEOFNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm ATTRIBUTE_UNUSED) + virDomainObjPtr vm ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) { } static void qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm ATTRIBUTE_UNUSED) + virDomainObjPtr vm ATTRIBUTE_UNUSED, + void *opaque ATTRIBUTE_UNUSED) { } @@ -870,7 +872,8 @@ qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt) if (!(test->mon = qemuMonitorOpen(test->vm, &src, json, - &qemuMonitorTestCallbacks))) + &qemuMonitorTestCallbacks, + NULL))) goto error; virObjectLock(test->mon); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:11PM +0200, Jiri Denemark wrote:
We will have to pass a mock-up of the driver when testing monitor events. --- src/qemu/qemu_capabilities.c | 5 ++- src/qemu/qemu_monitor.c | 24 +++++++---- src/qemu/qemu_monitor.h | 69 ++++++++++++++++++++---------- src/qemu/qemu_process.c | 99 +++++++++++++++++++++++++++----------------- tests/qemumonitortestutils.c | 9 ++-- 5 files changed, 130 insertions(+), 76 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- src/qemu/qemu_driver.c | 114 -------------------------------------- src/qemu/qemu_hotplug.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---- src/qemu/qemu_hotplug.h | 16 ++---- 3 files changed, 134 insertions(+), 138 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2daafa8..c926fba 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6270,120 +6270,6 @@ qemuDomainUndefine(virDomainPtr dom) } static int -qemuDomainAttachDeviceDiskLive(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) -{ - virDomainDiskDefPtr disk = dev->data.disk; - virDomainDiskDefPtr orig_disk = NULL; - virDomainDeviceDefPtr dev_copy = NULL; - virDomainDiskDefPtr tmp = NULL; - virCgroupPtr cgroup = NULL; - virCapsPtr caps = NULL; - int ret = -1; - - if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unsupported driver name '%s' for disk '%s'"), - disk->driverName, disk->src); - goto end; - } - - if (qemuTranslateDiskSourcePool(conn, disk) < 0) - goto end; - - if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0) - goto end; - - if (qemuSetUnprivSGIO(dev) < 0) - goto end; - - if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) - goto end; - - if (qemuSetupDiskCgroup(vm, disk) < 0) - goto end; - - switch (disk->device) { - case VIR_DOMAIN_DISK_DEVICE_CDROM: - case VIR_DOMAIN_DISK_DEVICE_FLOPPY: - if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def, - disk->bus, disk->dst))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("No device with bus '%s' and target '%s'"), - virDomainDiskBusTypeToString(disk->bus), - disk->dst); - goto end; - } - - if (!(caps = virQEMUDriverGetCapabilities(driver, false))) - goto end; - - tmp = dev->data.disk; - dev->data.disk = orig_disk; - - if (!(dev_copy = virDomainDeviceDefCopy(dev, vm->def, - caps, driver->xmlopt))) { - dev->data.disk = tmp; - goto end; - } - dev->data.disk = tmp; - - ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, false); - /* 'disk' must not be accessed now - it has been free'd. - * 'orig_disk' now points to the new disk, while 'dev_copy' - * now points to the old disk */ - - /* Need to remove the shared disk entry for the original disk src - * if the operation is either ejecting or updating. - */ - if (ret == 0) - ignore_value(qemuRemoveSharedDevice(driver, dev_copy, - vm->def->name)); - break; - case VIR_DOMAIN_DISK_DEVICE_DISK: - case VIR_DOMAIN_DISK_DEVICE_LUN: - if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { - if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("disk device='lun' is not supported for usb bus")); - break; - } - ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm, - disk); - } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { - ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk); - } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { - ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk); - } else { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("disk bus '%s' cannot be hotplugged."), - virDomainDiskBusTypeToString(disk->bus)); - } - break; - default: - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("disk device type '%s' cannot be hotplugged"), - virDomainDiskDeviceTypeToString(disk->device)); - break; - } - - if (ret != 0 && cgroup) { - if (qemuTeardownDiskCgroup(vm, disk) < 0) - VIR_WARN("Failed to teardown cgroup for disk path %s", - NULLSTR(disk->src)); - } - -end: - if (ret != 0) - ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name)); - virObjectUnref(caps); - virDomainDeviceDefFree(dev_copy); - return ret; -} - -static int qemuDomainAttachDeviceControllerLive(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 032de69..0f5622d 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -217,10 +217,11 @@ cleanup: return ret; } -int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk) +static int +qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk) { size_t i; int ret = -1; @@ -450,10 +451,11 @@ qemuDomainFindOrCreateSCSIDiskController(virQEMUDriverPtr driver, } -int qemuDomainAttachSCSIDisk(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk) +static int +qemuDomainAttachSCSIDisk(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk) { size_t i; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -573,10 +575,11 @@ error: } -int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk) +static int +qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk) { qemuDomainObjPrivatePtr priv = vm->privateData; size_t i; @@ -665,6 +668,121 @@ error: } +int +qemuDomainAttachDeviceDiskLive(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + virDomainDiskDefPtr disk = dev->data.disk; + virDomainDiskDefPtr orig_disk = NULL; + virDomainDeviceDefPtr dev_copy = NULL; + virDomainDiskDefPtr tmp = NULL; + virCgroupPtr cgroup = NULL; + virCapsPtr caps = NULL; + int ret = -1; + + if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported driver name '%s' for disk '%s'"), + disk->driverName, disk->src); + goto end; + } + + if (qemuTranslateDiskSourcePool(conn, disk) < 0) + goto end; + + if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0) + goto end; + + if (qemuSetUnprivSGIO(dev) < 0) + goto end; + + if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) + goto end; + + if (qemuSetupDiskCgroup(vm, disk) < 0) + goto end; + + switch (disk->device) { + case VIR_DOMAIN_DISK_DEVICE_CDROM: + case VIR_DOMAIN_DISK_DEVICE_FLOPPY: + if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def, + disk->bus, disk->dst))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("No device with bus '%s' and target '%s'"), + virDomainDiskBusTypeToString(disk->bus), + disk->dst); + goto end; + } + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto end; + + tmp = dev->data.disk; + dev->data.disk = orig_disk; + + if (!(dev_copy = virDomainDeviceDefCopy(dev, vm->def, + caps, driver->xmlopt))) { + dev->data.disk = tmp; + goto end; + } + dev->data.disk = tmp; + + ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, false); + /* 'disk' must not be accessed now - it has been free'd. + * 'orig_disk' now points to the new disk, while 'dev_copy' + * now points to the old disk */ + + /* Need to remove the shared disk entry for the original disk src + * if the operation is either ejecting or updating. + */ + if (ret == 0) + ignore_value(qemuRemoveSharedDevice(driver, dev_copy, + vm->def->name)); + break; + case VIR_DOMAIN_DISK_DEVICE_DISK: + case VIR_DOMAIN_DISK_DEVICE_LUN: + if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disk device='lun' is not supported for usb bus")); + break; + } + ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm, + disk); + } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { + ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk); + } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk); + } else { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk bus '%s' cannot be hotplugged."), + virDomainDiskBusTypeToString(disk->bus)); + } + break; + default: + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk device type '%s' cannot be hotplugged"), + virDomainDiskDeviceTypeToString(disk->device)); + break; + } + + if (ret != 0 && cgroup) { + if (qemuTeardownDiskCgroup(vm, disk) < 0) + VIR_WARN("Failed to teardown cgroup for disk path %s", + NULLSTR(disk->src)); + } + +end: + if (ret != 0) + ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name)); + virObjectUnref(caps); + virDomainDeviceDefFree(dev_copy); + return ret; +} + + /* XXX conn required for network -> bridge resolution */ int qemuDomainAttachNetDevice(virConnectPtr conn, virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 6fa1f33..80f6e4b 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -36,21 +36,13 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, int qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver, virDomainObjPtr vm, enum qemuDomainAsyncJob asyncJob); -int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainControllerDefPtr controller); -int qemuDomainAttachSCSIDisk(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); -int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, - virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); +int qemuDomainAttachDeviceDiskLive(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev); int qemuDomainAttachNetDevice(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:12PM +0200, Jiri Denemark wrote:
--- src/qemu/qemu_driver.c | 114 -------------------------------------- src/qemu/qemu_hotplug.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---- src/qemu/qemu_hotplug.h | 16 ++---- 3 files changed, 134 insertions(+), 138 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 08/01/2013 03:28 PM, Jiri Denemark wrote:
--- src/qemu/qemu_driver.c | 114 -------------------------------------- src/qemu/qemu_hotplug.c | 142 ++++++++++++++++++++++++++++++++++++++++++++---- src/qemu/qemu_hotplug.h | 16 ++---- 3 files changed, 134 insertions(+), 138 deletions(-)
Although it seems it already existed, the code motion seems to have awoken Coverity into determining that qemuDomainAttachDeviceDiskLive() has unreachable code. The 'cgroup' definition starts out as NULL, is never changed, and then the condition to make the qemuTeardownDiskCgroup call is if cgroup has been set. In any case, considering it never is reached - the question remains under what circumstances should the call be made. John ...
+int +qemuDomainAttachDeviceDiskLive(virConnectPtr conn, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + virDomainDiskDefPtr disk = dev->data.disk; + virDomainDiskDefPtr orig_disk = NULL; + virDomainDeviceDefPtr dev_copy = NULL; + virDomainDiskDefPtr tmp = NULL;
685 virDomainDiskDefPtr tmp = NULL; (1) Event assignment: Assigning: "cgroup" = "NULL". Also see events: [null][dead_error_condition][dead_error_line] 686 virCgroupPtr cgroup = NULL;
+ virCgroupPtr cgroup = NULL; + virCapsPtr caps = NULL; + int ret = -1; + + if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported driver name '%s' for disk '%s'"), + disk->driverName, disk->src); + goto end; + } + + if (qemuTranslateDiskSourcePool(conn, disk) < 0) + goto end; + + if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0) + goto end; + + if (qemuSetUnprivSGIO(dev) < 0) + goto end; + + if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) + goto end; + + if (qemuSetupDiskCgroup(vm, disk) < 0) + goto end; + + switch (disk->device) { + case VIR_DOMAIN_DISK_DEVICE_CDROM: + case VIR_DOMAIN_DISK_DEVICE_FLOPPY: + if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def, + disk->bus, disk->dst))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("No device with bus '%s' and target '%s'"), + virDomainDiskBusTypeToString(disk->bus), + disk->dst); + goto end; + } + + if (!(caps = virQEMUDriverGetCapabilities(driver, false))) + goto end; + + tmp = dev->data.disk; + dev->data.disk = orig_disk; + + if (!(dev_copy = virDomainDeviceDefCopy(dev, vm->def, + caps, driver->xmlopt))) { + dev->data.disk = tmp; + goto end; + } + dev->data.disk = tmp; + + ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, false); + /* 'disk' must not be accessed now - it has been free'd. + * 'orig_disk' now points to the new disk, while 'dev_copy' + * now points to the old disk */ + + /* Need to remove the shared disk entry for the original disk src + * if the operation is either ejecting or updating. + */ + if (ret == 0) + ignore_value(qemuRemoveSharedDevice(driver, dev_copy, + vm->def->name)); + break; + case VIR_DOMAIN_DISK_DEVICE_DISK: + case VIR_DOMAIN_DISK_DEVICE_LUN: + if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { + if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disk device='lun' is not supported for usb bus")); + break; + } + ret = qemuDomainAttachUsbMassstorageDevice(conn, driver, vm, + disk); + } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { + ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk); + } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk); + } else { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk bus '%s' cannot be hotplugged."), + virDomainDiskBusTypeToString(disk->bus)); + } + break; + default: + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk device type '%s' cannot be hotplugged"), + virDomainDiskDeviceTypeToString(disk->device)); + break; + } + 775
(2) Event null: At condition "cgroup", the value of "cgroup" must be NULL. (3) Event dead_error_condition: The condition "cgroup" cannot be true. Also see events: [assignment][dead_error_line] 776 if (ret != 0 && cgroup) { (4) Event dead_error_line: Execution cannot reach this statement "if (qemuTeardownDiskCgroup(...". Also see events: [assignment][null][dead_error_condition] 777 if (qemuTeardownDiskCgroup(vm, disk) < 0)
+ if (ret != 0 && cgroup) { + if (qemuTeardownDiskCgroup(vm, disk) < 0) + VIR_WARN("Failed to teardown cgroup for disk path %s", + NULLSTR(disk->src)); + } + +end: + if (ret != 0) + ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name)); + virObjectUnref(caps); + virDomainDeviceDefFree(dev_copy); + return ret; +} + +
...

--- src/qemu/qemu_driver.c | 52 -------------------------------------- src/qemu/qemu_hotplug.c | 67 ++++++++++++++++++++++++++++++++++++++++++++----- src/qemu/qemu_hotplug.h | 9 +++---- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c926fba..864a67a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6362,58 +6362,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, } static int -qemuFindDisk(virDomainDefPtr def, const char *dst) -{ - size_t i; - - for (i = 0; i < def->ndisks; i++) { - if (STREQ(def->disks[i]->dst, dst)) { - return i; - } - } - - return -1; -} - -static int -qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) -{ - virDomainDiskDefPtr disk; - int ret = -1; - int idx; - - if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("disk %s not found"), dev->data.disk->dst); - return -1; - } - disk = vm->def->disks[idx]; - - switch (disk->device) { - case VIR_DOMAIN_DISK_DEVICE_DISK: - case VIR_DOMAIN_DISK_DEVICE_LUN: - if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk); - else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || - disk->bus == VIR_DOMAIN_DISK_BUS_USB) - ret = qemuDomainDetachDiskDevice(driver, vm, disk); - else - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("This type of disk cannot be hot unplugged")); - break; - default: - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("disk device type '%s' cannot be detached"), - virDomainDiskDeviceTypeToString(disk->device)); - break; - } - - return ret; -} - -static int qemuDomainDetachDeviceControllerLive(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0f5622d..f8bcc9a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2749,9 +2749,10 @@ qemuDomainSignalDeviceRemoval(virDomainObjPtr vm, } -int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr detach) +static int +qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr detach) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -2820,9 +2821,10 @@ cleanup: return ret; } -int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr detach) +static int +qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr detach) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -2872,6 +2874,59 @@ cleanup: return ret; } +static int +qemuFindDisk(virDomainDefPtr def, const char *dst) +{ + size_t i; + + for (i = 0; i < def->ndisks; i++) { + if (STREQ(def->disks[i]->dst, dst)) { + return i; + } + } + + return -1; +} + +int +qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + virDomainDiskDefPtr disk; + int ret = -1; + int idx; + + if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("disk %s not found"), dev->data.disk->dst); + return -1; + } + disk = vm->def->disks[idx]; + + switch (disk->device) { + case VIR_DOMAIN_DISK_DEVICE_DISK: + case VIR_DOMAIN_DISK_DEVICE_LUN: + if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) + ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk); + else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || + disk->bus == VIR_DOMAIN_DISK_BUS_USB) + ret = qemuDomainDetachDiskDevice(driver, vm, disk); + else + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("This type of disk cannot be hot unplugged")); + break; + default: + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("disk device type '%s' cannot be detached"), + virDomainDiskDeviceTypeToString(disk->device)); + break; + } + + return ret; +} + + static bool qemuDomainDiskControllerIsBusy(virDomainObjPtr vm, virDomainControllerDefPtr detach) { diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 80f6e4b..355d809 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -75,12 +75,9 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainNetDefPtr dev, int linkstate); -int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); -int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk); +int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev); int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:13PM +0200, Jiri Denemark wrote:
--- src/qemu/qemu_driver.c | 52 -------------------------------------- src/qemu/qemu_hotplug.c | 67 ++++++++++++++++++++++++++++++++++++++++++++----- src/qemu/qemu_hotplug.h | 9 +++---- 3 files changed, 64 insertions(+), 64 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Each test case label now contains more data useful to identify the test. --- tests/qemuhotplugtest.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index c7be5f6..4f48ee0 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -96,7 +96,7 @@ testQemuHotplugAttach(virDomainObjPtr vm, break; default: if (virTestGetVerbose()) - fprintf(stderr, "device type '%s' cannot be attached", + fprintf(stderr, "device type '%s' cannot be attached\n", virDomainDeviceTypeToString(dev->type)); break; } @@ -116,7 +116,7 @@ testQemuHotplugDetach(virDomainObjPtr vm, break; default: if (virTestGetVerbose()) - fprintf(stderr, "device type '%s' cannot be attached", + fprintf(stderr, "device type '%s' cannot be detached\n", virDomainDeviceTypeToString(dev->type)); break; } @@ -141,7 +141,7 @@ testQemuHotplugUpdate(virDomainObjPtr vm, break; default: if (virTestGetVerbose()) - fprintf(stderr, "device type '%s' cannot be updated", + fprintf(stderr, "device type '%s' cannot be updated\n", virDomainDeviceTypeToString(dev->type)); break; } @@ -276,33 +276,28 @@ mymain(void) if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) return EXIT_FAILURE; -#define DO_TEST(file, dev, fial, kep, ...) \ +#define DO_TEST(file, ACTION, dev, fial, kep, ...) \ + do { \ const char *my_mon[] = { __VA_ARGS__, NULL}; \ + const char *name = file " " #ACTION " " dev; \ + data.action = ACTION; \ data.domain_filename = file; \ data.device_filename = dev; \ data.fail = fial; \ data.mon = my_mon; \ data.keep = kep; \ - if (virtTestRun(#file, 1, testQemuHotplug, &data) < 0) \ + if (virtTestRun(name, 1, testQemuHotplug, &data) < 0) \ ret = -1; \ + } while (0) #define DO_TEST_ATTACH(file, dev, fial, kep, ...) \ - do { \ - data.action = ATTACH; \ - DO_TEST(file, dev, fial, kep, __VA_ARGS__) \ - } while (0) + DO_TEST(file, ATTACH, dev, fial, kep, __VA_ARGS__) #define DO_TEST_DETACH(file, dev, fial, kep, ...) \ - do { \ - data.action = DETACH; \ - DO_TEST(file, dev, fial, kep, __VA_ARGS__) \ - } while (0) + DO_TEST(file, DETACH, dev, fial, kep, __VA_ARGS__) #define DO_TEST_UPDATE(file, dev, fial, kep, ...) \ - do { \ - data.action = UPDATE; \ - DO_TEST(file, dev, fial, kep, __VA_ARGS__) \ - } while (0) + DO_TEST(file, UPDATE, dev, fial, kep, __VA_ARGS__) DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:14PM +0200, Jiri Denemark wrote:
Each test case label now contains more data useful to identify the test. --- tests/qemuhotplugtest.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

We need to make sure a device is properly added/removed (or not) to a domain definition to check that a hotplug API did not lie to us. --- tests/qemuhotplugtest.c | 67 +++++++++-- ...qemuhotplug-console-compat-2+console-virtio.xml | 127 +++++++++++++++++++++ 2 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 4f48ee0..98dfd93 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -52,7 +52,7 @@ struct qemuHotplugTestData { static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, - const char *filename) + const char *domxml) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; @@ -60,11 +60,11 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, if (!(*vm = virDomainObjNew(xmlopt))) goto cleanup; - if (!((*vm)->def = virDomainDefParseFile(filename, - driver.caps, - driver.xmlopt, - QEMU_EXPECTED_VIRT_TYPES, - 0))) + if (!((*vm)->def = virDomainDefParseString(domxml, + driver.caps, + driver.xmlopt, + QEMU_EXPECTED_VIRT_TYPES, + 0))) goto cleanup; priv = (*vm)->privateData; @@ -150,13 +150,42 @@ testQemuHotplugUpdate(virDomainObjPtr vm, } static int +testQemuHotplugCheckResult(virDomainObjPtr vm, + const char *expected, + bool fail) +{ + char *actual; + int ret; + + actual = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE); + if (!actual) + return -1; + + if (STREQ(expected, actual)) { + if (fail) + fprintf(stderr, "domain XML unexpectedly changed\n"); + ret = 0; + } else { + if (!fail) + virtTestDifference(stderr, expected, actual); + ret = -1; + } + + VIR_FREE(actual); + return ret; +} + +static int testQemuHotplug(const void *data) { int ret = -1; struct qemuHotplugTestData *test = (struct qemuHotplugTestData *) data; char *domain_filename = NULL; char *device_filename = NULL; + char *result_filename = NULL; + char *domain_xml = NULL; char *device_xml = NULL; + char *result_xml = NULL; const char *const *tmp; bool fail = test->fail; bool keep = test->keep; @@ -169,7 +198,19 @@ testQemuHotplug(const void *data) if (virAsprintf(&domain_filename, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", abs_srcdir, test->domain_filename) < 0 || virAsprintf(&device_filename, "%s/qemuhotplugtestdata/qemuhotplug-%s.xml", - abs_srcdir, test->device_filename) < 0) + abs_srcdir, test->device_filename) < 0 || + virAsprintf(&result_filename, + "%s/qemuhotplugtestdata/qemuhotplug-%s+%s.xml", + abs_srcdir, test->domain_filename, + test->device_filename) < 0) + goto cleanup; + + if (virtTestLoadFile(domain_filename, &domain_xml) < 0 || + virtTestLoadFile(device_filename, &device_xml) < 0) + goto cleanup; + + if (test->action != UPDATE && + virtTestLoadFile(result_filename, &result_xml) < 0) goto cleanup; if (!(caps = virQEMUDriverGetCapabilities(&driver, false))) @@ -178,13 +219,10 @@ testQemuHotplug(const void *data) if (test->vm) { vm = test->vm; } else { - if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_filename) < 0) + if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_xml) < 0) goto cleanup; } - if (virtTestLoadFile(device_filename, &device_xml) < 0) - goto cleanup; - if (!(dev = virDomainDeviceDefParse(device_xml, vm->def, caps, driver.xmlopt, 0))) goto cleanup; @@ -218,10 +256,14 @@ testQemuHotplug(const void *data) switch (test->action) { case ATTACH: ret = testQemuHotplugAttach(vm, dev); + if (ret == 0 || fail) + ret = testQemuHotplugCheckResult(vm, result_xml, fail); break; case DETACH: ret = testQemuHotplugDetach(vm, dev); + if (ret == 0 || fail) + ret = testQemuHotplugCheckResult(vm, domain_xml, fail); break; case UPDATE: @@ -231,7 +273,10 @@ testQemuHotplug(const void *data) cleanup: VIR_FREE(domain_filename); VIR_FREE(device_filename); + VIR_FREE(result_filename); + VIR_FREE(domain_xml); VIR_FREE(device_xml); + VIR_FREE(result_xml); /* don't dispose test monitor with VM */ if (priv) priv->mon = NULL; diff --git a/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml new file mode 100644 index 0000000..21fd090 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml @@ -0,0 +1,127 @@ +<domain type='kvm' id='2'> + <name>f17</name> + <uuid>a1cd52eb-d37f-4717-fc6e-972f0774f4c9</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-1.4'>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> + <pm> + <suspend-to-mem enabled='yes'/> + <suspend-to-disk enabled='yes'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/libvirt/images/f17.qcow2'/> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/home/user/tmp/Fedora-17-x86_64-Live-KDE.iso'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <alias name='ide0-1-0'/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'> + <alias name='ide0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0'> + <alias name='usb0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <alias name='pci0'/> + </controller> + <controller type='virtio-serial' index='0'> + <alias name='virtio-serial0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </controller> + <interface type='network'> + <mac address='52:54:00:ea:35:6f'/> + <source network='default'/> + <target dev='vnet0'/> + <model type='virtio'/> + <bandwidth> + <inbound average='4000' peak='8000' floor='200' burst='1024'/> + <outbound average='4000' peak='8000' burst='1024'/> + </bandwidth> + <alias name='net0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <source path='/dev/pts/22'/> + <target type='isa-serial' port='0'/> + <alias name='serial0'/> + </serial> + <serial type='pty'> + <source path='/dev/pts/25'/> + <target port='0'/> + <alias name='serial1'/> + </serial> + <serial type='tcp'> + <source mode='bind' host='0.0.0.0' service='2445'/> + <protocol type='raw'/> + <target port='1'/> + <alias name='serial2'/> + </serial> + <console type='pty' tty='/dev/pts/22'> + <source path='/dev/pts/22'/> + <target type='serial' port='0'/> + <alias name='serial0'/> + </console> + <console type='pty'> + <source path='/dev/pts/26'/> + <target type='virtio' port='1'/> + <alias name='console1'/> + </console> + <channel type='unix'> + <source mode='bind' path='/var/lib/libvirt/qemu/f17x86_64.agent'/> + <target type='virtio' name='org.qemu.guest_agent.0'/> + <alias name='channel0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <input type='tablet' bus='usb'> + <alias name='input0'/> + </input> + <input type='mouse' bus='ps2'/> + <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'> + <listen type='address' address='0.0.0.0'/> + </graphics> + <sound model='ich6'> + <alias name='sound0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='cirrus' vram='9216' heads='1'/> + <alias name='video0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <memballoon model='virtio'> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </memballoon> + </devices> + <seclabel type='static' model='dac' relabel='no'> + <label>root:root</label> + </seclabel> +</domain> -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:15PM +0200, Jiri Denemark wrote:
We need to make sure a device is properly added/removed (or not) to a domain definition to check that a hotplug API did not lie to us. --- tests/qemuhotplugtest.c | 67 +++++++++-- ...qemuhotplug-console-compat-2+console-virtio.xml | 127 +++++++++++++++++++++ 2 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 98dfd93..4712334 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -344,24 +344,27 @@ mymain(void) #define DO_TEST_UPDATE(file, dev, fial, kep, ...) \ DO_TEST(file, UPDATE, dev, fial, kep, __VA_ARGS__) + +#define QMP_OK "{\"return\": {}}" + 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", "{\"return\":{}}", "expire_password", "{\"return\":{}}"); + "set_password", QMP_OK, "expire_password", QMP_OK); DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-password", false, false, - "set_password", "{\"return\":{}}", "expire_password", "{\"return\":{}}"); + "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", false, false, - "set_password", "{\"return\":{}}", "expire_password", "{\"return\":{}}"); + "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", "console-virtio", false, true, "chardev-add", "{\"return\": {\"pty\": \"/dev/pts/26\"}}", - "device_add", "{\"return\": {}}"); + "device_add", QMP_OK); DO_TEST_DETACH("console-compat-2", "console-virtio", false, false, - "device_del", "{\"return\": {}}", - "chardev-remove", "{\"return\": {}}"); + "device_del", QMP_OK, + "chardev-remove", QMP_OK); virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:16PM +0200, Jiri Denemark wrote:
--- tests/qemuhotplugtest.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

This is a generic XML usable for hotplugging various types of devices. --- .../qemuxml2argv-hotplug-base.args | 7 ++++ .../qemuxml2argvdata/qemuxml2argv-hotplug-base.xml | 38 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 4 +++ 3 files changed, 49 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args b/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args new file mode 100644 index 0000000..c4bd9c5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args @@ -0,0 +1,7 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/libexec/qemu-kvm -S -M pc -m 4096 -smp 4 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-boot c \ +-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 \ +-usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml b/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml new file mode 100644 index 0000000..bfb0167 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml @@ -0,0 +1,38 @@ +<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> + <memballoon model='none'/> + </devices> + <seclabel type='none'/> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index b7485fc..5770f20 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1027,6 +1027,10 @@ mymain(void) DO_TEST_PARSE_ERROR("pci-root-address", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE); + DO_TEST("hotplug-base", + QEMU_CAPS_KVM, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, + QEMU_CAPS_VIRTIO_SCSI); + virObjectUnref(driver.config); virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:17PM +0200, Jiri Denemark wrote:
This is a generic XML usable for hotplugging various types of devices. --- .../qemuxml2argv-hotplug-base.args | 7 ++++ .../qemuxml2argvdata/qemuxml2argv-hotplug-base.xml | 38 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 4 +++ 3 files changed, 49 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hotplug-base.xml
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 44 ++++++++++++++++++--- .../qemuhotplug-disk-virtio.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-virtio.xml | 46 ++++++++++++++++++++++ 3 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 4712334..bb047fe 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -75,6 +75,9 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, /* for attach & detach qemu must support -device */ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE); + if (qemuDomainAssignPCIAddresses((*vm)->def, priv->qemuCaps, *vm) < 0) + goto cleanup; + ret = 0; cleanup: return ret; @@ -87,12 +90,14 @@ testQemuHotplugAttach(virDomainObjPtr vm, int ret = -1; switch (dev->type) { + case VIR_DOMAIN_DEVICE_DISK: + /* 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); - if (!ret) { - /* vm->def stolen dev->data.chr so we ought to avoid freeing it */ - dev->data.chr = NULL; - } break; default: if (virTestGetVerbose()) @@ -111,6 +116,9 @@ testQemuHotplugDetach(virDomainObjPtr vm, 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); break; @@ -256,6 +264,11 @@ testQemuHotplug(const void *data) switch (test->action) { case ATTACH: ret = testQemuHotplugAttach(vm, dev); + 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, fail); break; @@ -297,6 +310,7 @@ mymain(void) { int ret = 0; struct qemuHotplugTestData data = {0}; + virSecurityManagerPtr mgr; #if !WITH_YAJL fputs("libvirt not compiled with yajl, skipping this test\n", stderr); @@ -313,12 +327,22 @@ mymain(void) driver.config = virQEMUDriverConfigNew(false); VIR_FREE(driver.config->spiceListen); VIR_FREE(driver.config->vncListen); + /* some dummy values from 'config file' */ + if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + return EXIT_FAILURE; if (!(driver.domainEventState = virDomainEventStateNew())) return EXIT_FAILURE; - /* some dummy values from 'config file' */ - if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + driver.lockManager = virLockManagerPluginNew("nop", "qemu", + driver.config->configBaseDir, + 0); + if (!driver.lockManager) + return EXIT_FAILURE; + + if (!(mgr = virSecurityManagerNew(NULL, "qemu", false, false, false))) + return EXIT_FAILURE; + if (!(driver.securityManager = virSecurityManagerNewStack(mgr))) return EXIT_FAILURE; #define DO_TEST(file, ACTION, dev, fial, kep, ...) \ @@ -346,6 +370,7 @@ mymain(void) #define QMP_OK "{\"return\": {}}" +#define HMP(msg) "{\"return\": \"" msg "\"}" DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, @@ -366,6 +391,13 @@ mymain(void) "device_del", QMP_OK, "chardev-remove", QMP_OK); + DO_TEST_ATTACH("hotplug-base", "disk-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-virtio", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); virObjectUnref(driver.config); diff --git a/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml new file mode 100644 index 0000000..844dc79 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml @@ -0,0 +1,7 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='vde' bus='virtio'/> + <readonly/> + <shareable/> +</disk> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml new file mode 100644 index 0000000..e96055c --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml @@ -0,0 +1,46 @@ +<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> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='vde' bus='virtio'/> + <readonly/> + <shareable/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <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> + <memballoon model='none'/> + </devices> + <seclabel type='none'/> +</domain> -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:18PM +0200, Jiri Denemark wrote:
diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 4712334..bb047fe 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -313,12 +327,22 @@ mymain(void) driver.config = virQEMUDriverConfigNew(false); VIR_FREE(driver.config->spiceListen); VIR_FREE(driver.config->vncListen); + /* some dummy values from 'config file' */ + if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + return EXIT_FAILURE;
if (!(driver.domainEventState = virDomainEventStateNew())) return EXIT_FAILURE;
- /* some dummy values from 'config file' */ - if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + driver.lockManager = virLockManagerPluginNew("nop", "qemu", + driver.config->configBaseDir, + 0); + if (!driver.lockManager) + return EXIT_FAILURE; + + if (!(mgr = virSecurityManagerNew(NULL, "qemu", false, false, false))) + return EXIT_FAILURE;
Isn't passing "NULL" here going to cause it to auto-detect the sec driver, potentially running the real SELinux / AppArmour drivers? I would have thought we'd pass 'none' here to explicitly get the no-op security driver. Though, in the future we likely want to have a special "test" security driver, so we can validate that the appropriate driver methods are being invoked for each hotplug operation. Likewise for the lock manager. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- Version 2: - generate aliases for all devices present in domain XML; this is required for hotplugging PCI devices as that needs the appropriate PCI controller to already have its alias assigned tests/qemuhotplugtest.c | 49 +++++++++++++++++++--- ...qemuhotplug-console-compat-2+console-virtio.xml | 2 +- .../qemuhotplug-disk-virtio.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-virtio.xml | 46 ++++++++++++++++++++ .../qemuxml2argv-console-compat-2.xml | 2 +- 5 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 34b375f..7e547ad 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -73,7 +73,15 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, goto cleanup; /* for attach & detach qemu must support -device */ + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DRIVE); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_NET_NAME); + + if (qemuDomainAssignPCIAddresses((*vm)->def, priv->qemuCaps, *vm) < 0) + goto cleanup; + + if (qemuAssignDeviceAliases((*vm)->def, priv->qemuCaps) < 0) + goto cleanup; ret = 0; cleanup: @@ -87,12 +95,14 @@ testQemuHotplugAttach(virDomainObjPtr vm, int ret = -1; switch (dev->type) { + case VIR_DOMAIN_DEVICE_DISK: + /* 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); - if (!ret) { - /* vm->def stolen dev->data.chr so we ought to avoid freeing it */ - dev->data.chr = NULL; - } break; default: if (virTestGetVerbose()) @@ -111,6 +121,9 @@ testQemuHotplugDetach(virDomainObjPtr vm, 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); break; @@ -256,6 +269,11 @@ testQemuHotplug(const void *data) switch (test->action) { case ATTACH: ret = testQemuHotplugAttach(vm, dev); + 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, fail); break; @@ -297,6 +315,7 @@ mymain(void) { int ret = 0; struct qemuHotplugTestData data = {0}; + virSecurityManagerPtr mgr; #if !WITH_YAJL fputs("libvirt not compiled with yajl, skipping this test\n", stderr); @@ -313,12 +332,22 @@ mymain(void) driver.config = virQEMUDriverConfigNew(false); VIR_FREE(driver.config->spiceListen); VIR_FREE(driver.config->vncListen); + /* some dummy values from 'config file' */ + if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + return EXIT_FAILURE; if (!(driver.domainEventState = virDomainEventStateNew())) return EXIT_FAILURE; - /* some dummy values from 'config file' */ - if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) + driver.lockManager = virLockManagerPluginNew("nop", "qemu", + driver.config->configBaseDir, + 0); + if (!driver.lockManager) + return EXIT_FAILURE; + + if (!(mgr = virSecurityManagerNew("none", "qemu", false, false, false))) + return EXIT_FAILURE; + if (!(driver.securityManager = virSecurityManagerNewStack(mgr))) return EXIT_FAILURE; #define DO_TEST(file, ACTION, dev, fial, kep, ...) \ @@ -346,6 +375,7 @@ mymain(void) #define QMP_OK "{\"return\": {}}" +#define HMP(msg) "{\"return\": \"" msg "\"}" DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, @@ -366,6 +396,13 @@ mymain(void) "device_del", QMP_OK, "chardev-remove", QMP_OK); + DO_TEST_ATTACH("hotplug-base", "disk-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-virtio", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); virObjectUnref(driver.config); diff --git a/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml index 21fd090..d75af19 100644 --- a/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml +++ b/tests/qemuhotplugtestdata/qemuhotplug-console-compat-2+console-virtio.xml @@ -50,7 +50,7 @@ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'> - <alias name='pci0'/> + <alias name='pci.0'/> </controller> <controller type='virtio-serial' index='0'> <alias name='virtio-serial0'/> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml new file mode 100644 index 0000000..844dc79 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml @@ -0,0 +1,7 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='vde' bus='virtio'/> + <readonly/> + <shareable/> +</disk> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml new file mode 100644 index 0000000..e96055c --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml @@ -0,0 +1,46 @@ +<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> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='vde' bus='virtio'/> + <readonly/> + <shareable/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </disk> + <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> + <memballoon model='none'/> + </devices> + <seclabel type='none'/> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml index 3fc1153..37e8e00 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-2.xml @@ -50,7 +50,7 @@ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'> - <alias name='pci0'/> + <alias name='pci.0'/> </controller> <controller type='virtio-serial' index='0'> <alias name='virtio-serial0'/> -- 1.8.3.2

On 08/26/13 15:47, Jiri Denemark wrote:
--- Version 2: - generate aliases for all devices present in domain XML; this is required for hotplugging PCI devices as that needs the appropriate PCI controller to already have its alias assigned
tests/qemuhotplugtest.c | 49 +++++++++++++++++++--- ...qemuhotplug-console-compat-2+console-virtio.xml | 2 +- .../qemuhotplug-disk-virtio.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-virtio.xml | 46 ++++++++++++++++++++ .../qemuxml2argv-console-compat-2.xml | 2 +- 5 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-virtio.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-virtio.xml
ACK. Peter

Some tests need the monitor to operate on an already existing VM object rather than on a new mock-up the monitor test normally creates. --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitorjsontest.c | 26 +++++++++++++------------- tests/qemumonitortestutils.c | 19 ++++++++++++++----- tests/qemumonitortestutils.h | 6 +++++- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index bb047fe..088a0f1 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -237,7 +237,7 @@ testQemuHotplug(const void *data) /* Now is the best time to feed the spoofed monitor with predefined * replies. */ - if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt))) + if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt, vm))) goto cleanup; tmp = test->mon; diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 9e66059..b287747 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -35,7 +35,7 @@ static int testQemuMonitorJSONGetStatus(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; bool running = false; virDomainPausedReason reason = 0; @@ -129,7 +129,7 @@ static int testQemuMonitorJSONGetVersion(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; int major; int minor; @@ -232,7 +232,7 @@ static int testQemuMonitorJSONGetMachines(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; qemuMonitorMachineInfoPtr *info; int ninfo = 0; @@ -314,7 +314,7 @@ static int testQemuMonitorJSONGetCPUDefinitions(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; char **cpus = NULL; int ncpus = 0; @@ -380,7 +380,7 @@ static int testQemuMonitorJSONGetCommands(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; char **commands = NULL; int ncommands = 0; @@ -445,7 +445,7 @@ static int testQemuMonitorJSONGetTPMModels(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; char **tpmmodels = NULL; int ntpmmodels = 0; @@ -498,7 +498,7 @@ static int testQemuMonitorJSONGetCommandLineOptionParameters(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; char **params = NULL; int nparams = 0; @@ -599,7 +599,7 @@ static int testQemuMonitorJSONAttachChardev(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); virDomainChrSourceDef chr; int ret = 0; @@ -680,7 +680,7 @@ static int testQemuMonitorJSONDetachChardev(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; if (!test) @@ -713,7 +713,7 @@ static int testQemuMonitorJSONGetListPaths(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; qemuMonitorJSONListPathPtr *paths; int npaths = 0; @@ -791,7 +791,7 @@ static int testQemuMonitorJSONGetObjectProperty(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; qemuMonitorJSONObjectProperty prop; @@ -834,7 +834,7 @@ static int testQemuMonitorJSONSetObjectProperty(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; qemuMonitorJSONObjectProperty prop; @@ -886,7 +886,7 @@ static int testQemuMonitorJSONGetDeviceAliases(const void *data) { const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; char **aliases = NULL; char **alias; diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 93fb342..95c1b3d 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -743,6 +743,7 @@ static qemuAgentCallbacks qemuMonitorTestAgentCallbacks = { static qemuMonitorTestPtr qemuMonitorCommonTestNew(virDomainXMLOptionPtr xmlopt, + virDomainObjPtr vm, virDomainChrSourceDefPtr src) { qemuMonitorTestPtr test = NULL; @@ -773,8 +774,14 @@ qemuMonitorCommonTestNew(virDomainXMLOptionPtr xmlopt, if (virAsprintf(&path, "%s/qemumonitorjsontest.sock", test->tmpdir) < 0) goto error; - if (!(test->vm = virDomainObjNew(xmlopt))) - goto error; + if (vm) { + virObjectRef(vm); + test->vm = vm; + } else { + test->vm = virDomainObjNew(xmlopt); + if (!test->vm) + goto error; + } if (virNetSocketNewListenUNIX(path, 0700, getuid(), getgid(), &test->server) < 0) @@ -860,12 +867,14 @@ error: #define QEMU_TEXT_GREETING "QEMU 1.0,1 monitor - type 'help' for more information" qemuMonitorTestPtr -qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt) +qemuMonitorTestNew(bool json, + virDomainXMLOptionPtr xmlopt, + virDomainObjPtr vm) { qemuMonitorTestPtr test = NULL; virDomainChrSourceDef src; - if (!(test = qemuMonitorCommonTestNew(xmlopt, &src))) + if (!(test = qemuMonitorCommonTestNew(xmlopt, vm, &src))) goto error; test->json = json; @@ -902,7 +911,7 @@ qemuMonitorTestNewAgent(virDomainXMLOptionPtr xmlopt) qemuMonitorTestPtr test = NULL; virDomainChrSourceDef src; - if (!(test = qemuMonitorCommonTestNew(xmlopt, &src))) + if (!(test = qemuMonitorCommonTestNew(xmlopt, NULL, &src))) goto error; if (!(test->agent = qemuAgentOpen(test->vm, diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index 1122409..ccb5457 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -59,8 +59,12 @@ int qemuMonitorTestAddItemParams(qemuMonitorTestPtr test, ...) ATTRIBUTE_SENTINEL; +# define qemuMonitorTestNewSimple(json, xmlopt) \ + qemuMonitorTestNew(json, xmlopt, NULL) + qemuMonitorTestPtr qemuMonitorTestNew(bool json, - virDomainXMLOptionPtr xmlopt); + virDomainXMLOptionPtr xmlopt, + virDomainObjPtr vm); qemuMonitorTestPtr qemuMonitorTestNewAgent(virDomainXMLOptionPtr xmlopt); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:19PM +0200, Jiri Denemark wrote:
Some tests need the monitor to operate on an already existing VM object rather than on a new mock-up the monitor test normally creates. --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitorjsontest.c | 26 +++++++++++++------------- tests/qemumonitortestutils.c | 19 ++++++++++++++----- tests/qemumonitortestutils.h | 6 +++++- 4 files changed, 33 insertions(+), 20 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

The driver is then passed to monitor event handlers. --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitortestutils.c | 5 +++-- tests/qemumonitortestutils.h | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 088a0f1..6fa331e 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -237,7 +237,7 @@ testQemuHotplug(const void *data) /* Now is the best time to feed the spoofed monitor with predefined * replies. */ - if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt, vm))) + if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt, vm, &driver))) goto cleanup; tmp = test->mon; diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 95c1b3d..1857cfd 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -869,7 +869,8 @@ error: qemuMonitorTestPtr qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt, - virDomainObjPtr vm) + virDomainObjPtr vm, + virQEMUDriverPtr driver) { qemuMonitorTestPtr test = NULL; virDomainChrSourceDef src; @@ -882,7 +883,7 @@ qemuMonitorTestNew(bool json, &src, json, &qemuMonitorTestCallbacks, - NULL))) + driver))) goto error; virObjectLock(test->mon); diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index ccb5457..9e39795 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -21,6 +21,7 @@ # define __VIR_QEMU_MONITOR_TEST_UTILS_H__ # include "domain_conf.h" +# include "qemu/qemu_conf.h" # include "qemu/qemu_monitor.h" # include "qemu/qemu_agent.h" @@ -60,11 +61,12 @@ int qemuMonitorTestAddItemParams(qemuMonitorTestPtr test, ATTRIBUTE_SENTINEL; # define qemuMonitorTestNewSimple(json, xmlopt) \ - qemuMonitorTestNew(json, xmlopt, NULL) + qemuMonitorTestNew(json, xmlopt, NULL, NULL) qemuMonitorTestPtr qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt, - virDomainObjPtr vm); + virDomainObjPtr vm, + virQEMUDriverPtr driver); qemuMonitorTestPtr qemuMonitorTestNewAgent(virDomainXMLOptionPtr xmlopt); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:20PM +0200, Jiri Denemark wrote:
The driver is then passed to monitor event handlers. --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitortestutils.c | 5 +++-- tests/qemumonitortestutils.h | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- src/Makefile.am | 1 + src/qemu/qemu_process.c | 5 +++-- src/qemu/qemu_process.h | 2 +- src/qemu/qemu_processpriv.h | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/qemu/qemu_processpriv.h diff --git a/src/Makefile.am b/src/Makefile.am index 62e427e..88dc5fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -635,6 +635,7 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_hotplug.c qemu/qemu_hotplug.h \ qemu/qemu_conf.c qemu/qemu_conf.h \ qemu/qemu_process.c qemu/qemu_process.h \ + qemu/qemu_processpriv.h \ qemu/qemu_migration.c qemu/qemu_migration.h \ qemu/qemu_monitor.c qemu/qemu_monitor.h \ qemu/qemu_monitor_text.c \ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0d48f4f..4647d99 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1,5 +1,5 @@ /* - * qemu_process.h: QEMU process management + * qemu_process.c: QEMU process management * * Copyright (C) 2006-2013 Red Hat, Inc. * @@ -33,6 +33,7 @@ #endif #include "qemu_process.h" +#include "qemu_processpriv.h" #include "qemu_domain.h" #include "qemu_cgroup.h" #include "qemu_capabilities.h" @@ -1332,7 +1333,7 @@ cleanup: } -static int +int qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, const char *devAlias, diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 8c81e40..405c73d 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -1,5 +1,5 @@ /* - * qemu_process.c: QEMU process management + * qemu_process.h: QEMU process management * * Copyright (C) 2006-2012 Red Hat, Inc. * diff --git a/src/qemu/qemu_processpriv.h b/src/qemu/qemu_processpriv.h new file mode 100644 index 0000000..782fcd5 --- /dev/null +++ b/src/qemu/qemu_processpriv.h @@ -0,0 +1,37 @@ +/* + * qemu_processpriv.h: private declarations for QEMU process management + * + * Copyright (C) 2013 Red Hat, Inc. + * + * 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/>. + * + */ + +#ifndef __QEMU_PROCESSPRIV_H__ +# define __QEMU_PROCESSPRIV_H__ + +# include "domain_conf.h" +# include "qemu_monitor.h" + +/* + * This header file should never be used outside unit tests. + */ + +int qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon, + virDomainObjPtr vm, + const char *devAlias, + void *opaque); + +#endif /* __QEMU_PROCESSPRIV_H__ */ -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:21PM +0200, Jiri Denemark wrote:
--- src/Makefile.am | 1 + src/qemu/qemu_process.c | 5 +++-- src/qemu/qemu_process.h | 2 +- src/qemu/qemu_processpriv.h | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/qemu/qemu_processpriv.h
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

We don't want tests to wait 5 seconds for an event which we know will never come. --- src/Makefile.am | 1 + src/qemu/qemu_hotplug.c | 10 ++++++---- src/qemu/qemu_hotplugpriv.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 src/qemu/qemu_hotplugpriv.h diff --git a/src/Makefile.am b/src/Makefile.am index 88dc5fe..3f410da 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -633,6 +633,7 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_cgroup.c qemu/qemu_cgroup.h \ qemu/qemu_hostdev.c qemu/qemu_hostdev.h \ qemu/qemu_hotplug.c qemu/qemu_hotplug.h \ + qemu/qemu_hotplugpriv.h \ qemu/qemu_conf.c qemu/qemu_conf.h \ qemu/qemu_process.c qemu/qemu_process.h \ qemu/qemu_processpriv.h \ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f8bcc9a..f9d75dc 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -25,6 +25,7 @@ #include <config.h> #include "qemu_hotplug.h" +#include "qemu_hotplugpriv.h" #include "qemu_capabilities.h" #include "qemu_domain.h" #include "qemu_command.h" @@ -53,6 +54,10 @@ #define VIR_FROM_THIS VIR_FROM_QEMU #define CHANGE_MEDIA_RETRIES 10 +/* Wait up to 5 seconds for device removal to finish. */ +unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5; + + int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, @@ -2679,9 +2684,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, } -/* Wait up to 5 seconds for device removal to finish. */ -#define QEMU_REMOVAL_WAIT_TIME (1000ull * 5) - static void qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm, virDomainDeviceInfoPtr info) @@ -2718,7 +2720,7 @@ qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm) if (virTimeMillisNow(&until) < 0) return -1; - until += QEMU_REMOVAL_WAIT_TIME; + until += qemuDomainRemoveDeviceWaitTime; while (priv->unpluggingDevice) { if (virCondWaitUntil(&priv->unplugFinished, diff --git a/src/qemu/qemu_hotplugpriv.h b/src/qemu/qemu_hotplugpriv.h new file mode 100644 index 0000000..e4a1164 --- /dev/null +++ b/src/qemu/qemu_hotplugpriv.h @@ -0,0 +1,31 @@ +/* + * qemu_hotplugpriv.h: private declarations for QEMU device hotplug management + * + * Copyright (C) 2013 Red Hat, Inc. + * + * 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/>. + * + */ + +#ifndef __QEMU_HOTPLUGPRIV_H__ +# define __QEMU_HOTPLUGPRIV_H__ + +/* + * This header file should never be used outside unit tests. + */ + +unsigned long long qemuDomainRemoveDeviceWaitTime; + +#endif /* __QEMU_HOTPLUGPRIV_H__ */ -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:22PM +0200, Jiri Denemark wrote:
We don't want tests to wait 5 seconds for an event which we know will never come. --- src/Makefile.am | 1 + src/qemu/qemu_hotplug.c | 10 ++++++---- src/qemu/qemu_hotplugpriv.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 src/qemu/qemu_hotplugpriv.h
diff --git a/src/Makefile.am b/src/Makefile.am index 88dc5fe..3f410da 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -633,6 +633,7 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_cgroup.c qemu/qemu_cgroup.h \ qemu/qemu_hostdev.c qemu/qemu_hostdev.h \ qemu/qemu_hotplug.c qemu/qemu_hotplug.h \ + qemu/qemu_hotplugpriv.h \ qemu/qemu_conf.c qemu/qemu_conf.h \ qemu/qemu_process.c qemu/qemu_process.h \ qemu/qemu_processpriv.h \ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f8bcc9a..f9d75dc 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -25,6 +25,7 @@ #include <config.h>
#include "qemu_hotplug.h" +#include "qemu_hotplugpriv.h" #include "qemu_capabilities.h" #include "qemu_domain.h" #include "qemu_command.h" @@ -53,6 +54,10 @@ #define VIR_FROM_THIS VIR_FROM_QEMU #define CHANGE_MEDIA_RETRIES 10
+/* Wait up to 5 seconds for device removal to finish. */ +unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5; + + int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, @@ -2679,9 +2684,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, }
-/* Wait up to 5 seconds for device removal to finish. */ -#define QEMU_REMOVAL_WAIT_TIME (1000ull * 5) - static void qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm, virDomainDeviceInfoPtr info) @@ -2718,7 +2720,7 @@ qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
if (virTimeMillisNow(&until) < 0) return -1; - until += QEMU_REMOVAL_WAIT_TIME; + until += qemuDomainRemoveDeviceWaitTime;
while (priv->unpluggingDevice) { if (virCondWaitUntil(&priv->unplugFinished, diff --git a/src/qemu/qemu_hotplugpriv.h b/src/qemu/qemu_hotplugpriv.h new file mode 100644 index 0000000..e4a1164 --- /dev/null +++ b/src/qemu/qemu_hotplugpriv.h @@ -0,0 +1,31 @@ +/* + * qemu_hotplugpriv.h: private declarations for QEMU device hotplug management + * + * Copyright (C) 2013 Red Hat, Inc. + * + * 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/>. + * + */ + +#ifndef __QEMU_HOTPLUGPRIV_H__ +# define __QEMU_HOTPLUGPRIV_H__ + +/* + * This header file should never be used outside unit tests. + */ + +unsigned long long qemuDomainRemoveDeviceWaitTime;
Don't you need 'extern' here otherwise every .c file that includes this header will allocate storage a new copy of this variable. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 29 +++++++++++++++++++++++------ tests/qemumonitortestutils.c | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 6fa331e..4901178 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -21,6 +21,7 @@ #include "qemu/qemu_conf.h" #include "qemu/qemu_hotplug.h" +#include "qemu/qemu_hotplugpriv.h" #include "qemumonitortestutils.h" #include "testutils.h" #include "testutilsqemu.h" @@ -47,12 +48,14 @@ struct qemuHotplugTestData { int action; bool keep; virDomainObjPtr vm; + bool deviceDeletedEvent; }; static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, - const char *domxml) + const char *domxml, + bool event) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; @@ -74,6 +77,9 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, /* for attach & detach qemu must support -device */ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DRIVE); + if (event) + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT); if (qemuDomainAssignPCIAddresses((*vm)->def, priv->qemuCaps, *vm) < 0) goto cleanup; @@ -227,7 +233,8 @@ testQemuHotplug(const void *data) if (test->vm) { vm = test->vm; } else { - if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_xml) < 0) + if (qemuHotplugCreateObjects(driver.xmlopt, &vm, domain_xml, + test->deviceDeletedEvent) < 0) goto cleanup; } @@ -345,7 +352,10 @@ mymain(void) if (!(driver.securityManager = virSecurityManagerNewStack(mgr))) return EXIT_FAILURE; -#define DO_TEST(file, ACTION, dev, fial, kep, ...) \ + /* wait only 100ms for DEVICE_DELETED event */ + qemuDomainRemoveDeviceWaitTime = 100; + +#define DO_TEST(file, ACTION, dev, event, fial, kep, ...) \ do { \ const char *my_mon[] = { __VA_ARGS__, NULL}; \ const char *name = file " " #ACTION " " dev; \ @@ -355,18 +365,25 @@ mymain(void) data.fail = fial; \ data.mon = my_mon; \ data.keep = kep; \ + data.deviceDeletedEvent = event; \ if (virtTestRun(name, 1, testQemuHotplug, &data) < 0) \ ret = -1; \ } while (0) #define DO_TEST_ATTACH(file, dev, fial, kep, ...) \ - DO_TEST(file, ATTACH, dev, fial, kep, __VA_ARGS__) + DO_TEST(file, ATTACH, dev, false, fial, kep, __VA_ARGS__) #define DO_TEST_DETACH(file, dev, fial, kep, ...) \ - DO_TEST(file, DETACH, dev, fial, kep, __VA_ARGS__) + DO_TEST(file, DETACH, dev, false, fial, kep, __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_UPDATE(file, dev, fial, kep, ...) \ - DO_TEST(file, UPDATE, dev, fial, kep, __VA_ARGS__) + DO_TEST(file, UPDATE, dev, false, fial, kep, __VA_ARGS__) #define QMP_OK "{\"return\": {}}" diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 1857cfd..2322c08 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -27,6 +27,7 @@ #include "qemumonitortestutils.h" #include "virthread.h" +#include "qemu/qemu_processpriv.h" #include "qemu/qemu_monitor.h" #include "qemu/qemu_agent.h" #include "rpc/virnetsocket.h" @@ -725,6 +726,7 @@ qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBUTE_UNUSED, static qemuMonitorCallbacks qemuMonitorTestCallbacks = { .eofNotify = qemuMonitorTestEOFNotify, .errorNotify = qemuMonitorTestErrorNotify, + .domainDeviceDeleted = qemuProcessHandleDeviceDeleted, }; -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:23PM +0200, Jiri Denemark wrote:
--- tests/qemuhotplugtest.c | 29 +++++++++++++++++++++++------ tests/qemumonitortestutils.c | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 4901178..5e25ea9 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -389,6 +389,19 @@ mymain(void) #define QMP_OK "{\"return\": {}}" #define HMP(msg) "{\"return\": \"" msg "\"}" +#define QMP_DEVICE_DELETED(dev) \ + "{" \ + " \"timestamp\": {" \ + " \"seconds\": 1374137171," \ + " \"microseconds\": 2659" \ + " }," \ + " \"event\": \"DEVICE_DELETED\"," \ + " \"data\": {" \ + " \"device\": \"" dev "\"," \ + " \"path\": \"/machine/peripheral/" dev "\"" \ + " }" \ + "}\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); @@ -415,6 +428,16 @@ mymain(void) "device_del", QMP_OK, "human-monitor-command", HMP("")); + DO_TEST_ATTACH_EVENT("hotplug-base", "disk-virtio", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-virtio", true, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("hotplug-base", "disk-virtio", false, false, + "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, + "human-monitor-command", HMP("")); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); virObjectUnref(driver.config); -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:24PM +0200, Jiri Denemark wrote:
--- tests/qemuhotplugtest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 17 ++++++++ tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-usb.xml | 45 ++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 5e25ea9..d47dab9 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -438,6 +438,23 @@ mymain(void) "device_del", QMP_DEVICE_DELETED("virtio-disk4") QMP_OK, "human-monitor-command", HMP("")); + DO_TEST_ATTACH("hotplug-base", "disk-usb", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-usb", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT("hotplug-base", "disk-usb", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-usb", true, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("hotplug-base", "disk-usb", false, false, + "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, + "human-monitor-command", HMP("")); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); virObjectUnref(driver.config); diff --git a/tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml b/tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml new file mode 100644 index 0000000..3f0c318 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml @@ -0,0 +1,7 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='sdq' bus='usb'/> + <readonly/> + <shareable/> +</disk> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml new file mode 100644 index 0000000..1ea0f88 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml @@ -0,0 +1,45 @@ +<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> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='sdq' bus='usb'/> + <readonly/> + <shareable/> + </disk> + <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> + <memballoon model='none'/> + </devices> + <seclabel type='none'/> +</domain> -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:25PM +0200, Jiri Denemark wrote:
--- tests/qemuhotplugtest.c | 17 ++++++++ tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-usb.xml | 45 ++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-usb.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- tests/qemuhotplugtest.c | 18 +++++++++ .../qemuhotplugtestdata/qemuhotplug-disk-scsi.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-scsi.xml | 46 ++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index d47dab9..8a94345 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -78,6 +78,7 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, /* for attach & detach qemu must support -device */ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DRIVE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VIRTIO_SCSI); if (event) virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT); @@ -455,6 +456,23 @@ mymain(void) "device_del", QMP_DEVICE_DELETED("usb-disk16") QMP_OK, "human-monitor-command", HMP("")); + DO_TEST_ATTACH("hotplug-base", "disk-scsi", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-scsi", false, false, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + + DO_TEST_ATTACH_EVENT("hotplug-base", "disk-scsi", false, true, + "human-monitor-command", HMP("OK\\r\\n"), + "device_add", QMP_OK); + DO_TEST_DETACH("hotplug-base", "disk-scsi", true, true, + "device_del", QMP_OK, + "human-monitor-command", HMP("")); + DO_TEST_DETACH("hotplug-base", "disk-scsi", false, false, + "device_del", QMP_DEVICE_DELETED("scsi0-0-0-5") QMP_OK, + "human-monitor-command", HMP("")); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); virObjectUnref(driver.config); diff --git a/tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml b/tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml new file mode 100644 index 0000000..5be72b7 --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml @@ -0,0 +1,7 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='sdf' bus='scsi'/> + <readonly/> + <shareable/> +</disk> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml new file mode 100644 index 0000000..a06158b --- /dev/null +++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml @@ -0,0 +1,46 @@ +<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> + <disk type='file' device='disk'> + <driver name='qemu' type='raw' cache='none'/> + <source file='/dev/null'/> + <target dev='sdf' bus='scsi'/> + <readonly/> + <shareable/> + <address type='drive' controller='0' bus='0' target='0' unit='5'/> + </disk> + <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> + <memballoon model='none'/> + </devices> + <seclabel type='none'/> +</domain> -- 1.8.3.2

On Thu, Aug 01, 2013 at 09:28:26PM +0200, Jiri Denemark wrote:
--- tests/qemuhotplugtest.c | 18 +++++++++ .../qemuhotplugtestdata/qemuhotplug-disk-scsi.xml | 7 ++++ .../qemuhotplug-hotplug-base+disk-scsi.xml | 46 ++++++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-disk-scsi.xml create mode 100644 tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-scsi.xml
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Thu, Aug 01, 2013 at 21:28:09 +0200, Jiri Denemark wrote:
This series adds tests for hotplugging all supported disk types.
Jiri Denemark (17): qemu: Typedef monitor callbacks qemu: Avoid using global qemu_driver in event handlers qemu: Move qemuDomainAttachDeviceDiskLive to qemu_hotplug.c qemu: Move qemuDomainDetachDeviceDiskLive to qemu_hotplug.c qemuhotplugtest: Generate better output qemuhotplugtest: Compare domain XML after device hotplug qemuhotplugtest: Define QMP_OK for the most common reply qemuxml2argvtest: Add XML for testing device hotplug qemuhotplugtest: Add tests for virtio disk hotplug tests: Add support for passing vm to qemu monitor tests: Add support for passing driver to qemu monitor qemu: Export qemuProcessHandleDeviceDeleted for tests qemu: Let tests override waiting time for device unplug qemuhotplugtest: Add support for DEVICE_DELETED event qemuhotplugtest: Add tests for async virtio disk detach qemuhotplugtest: Add tests for USB disk hotplug qemuhotplugtest: Add tests for virtio SCSI disk hotplug
ping Jirka

On Thu, Aug 01, 2013 at 21:28:09 +0200, Jiri Denemark wrote:
This series adds tests for hotplugging all supported disk types.
Jiri Denemark (17): qemu: Typedef monitor callbacks qemu: Avoid using global qemu_driver in event handlers qemu: Move qemuDomainAttachDeviceDiskLive to qemu_hotplug.c qemu: Move qemuDomainDetachDeviceDiskLive to qemu_hotplug.c qemuhotplugtest: Generate better output qemuhotplugtest: Compare domain XML after device hotplug qemuhotplugtest: Define QMP_OK for the most common reply qemuxml2argvtest: Add XML for testing device hotplug qemuhotplugtest: Add tests for virtio disk hotplug tests: Add support for passing vm to qemu monitor tests: Add support for passing driver to qemu monitor qemu: Export qemuProcessHandleDeviceDeleted for tests qemu: Let tests override waiting time for device unplug qemuhotplugtest: Add support for DEVICE_DELETED event qemuhotplugtest: Add tests for async virtio disk detach qemuhotplugtest: Add tests for USB disk hotplug qemuhotplugtest: Add tests for virtio SCSI disk hotplug
I fixed small issues found by Daniel and pushed this series. Jirka
participants (4)
-
Daniel P. Berrange
-
Jiri Denemark
-
John Ferlan
-
Peter Krempa