https://bugzilla.redhat.com/show_bug.cgi?id=1447169 Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_hotplug.c | 67 ++++++++++++++++++++++ src/qemu/qemu_hotplug.h | 3 + tests/qemuhotplugtest.c | 7 ++- .../qemuhotplug-watchdog-full.xml | 4 ++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-watchdog-full.xml diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index db8ad0b04..4c8e9297a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7747,12 +7747,14 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_SHMEM: ret = qemuDomainDetachShmemDevice(driver, vm, dev->data.shmem); break; + case VIR_DOMAIN_DEVICE_WATCHDOG: + ret = qemuDomainDetachWatchdog(driver, vm, dev->data.watchdog); + break; case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: - case VIR_DOMAIN_DEVICE_WATCHDOG: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_SMARTCARD: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 11afa7ec6..1d95b88c4 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4337,6 +4337,25 @@ qemuDomainRemoveShmemDevice(virQEMUDriverPtr driver, } +static int +qemuDomainRemoveWatchdog(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainWatchdogDefPtr watchdog) +{ + virObjectEventPtr event = NULL; + + VIR_DEBUG("Removing watchdog %s from domain %p %s", + watchdog->info.alias, vm, vm->def->name); + + event = virDomainEventDeviceRemovedNewFromObj(vm, watchdog->info.alias); + qemuDomainEventQueue(driver, event); + qemuDomainReleaseDeviceAddress(vm, &watchdog->info, NULL); + virDomainWatchdogDefFree(vm->def->watchdog); + vm->def->watchdog = NULL; + return 0; +} + + int qemuDomainRemoveDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -5053,6 +5072,54 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, } +int +qemuDomainDetachWatchdog(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainWatchdogDefPtr dev) +{ + int ret = -1; + virDomainWatchdogDefPtr watchdog = vm->def->watchdog; + qemuDomainObjPrivatePtr priv = vm->privateData; + + /* While domains can have up to one watchdog, the one supplied by the user + * doesn't necessarily match the one domain has. Refuse to detach in such + * case. */ + if (!(watchdog && + watchdog->model == dev->model && + watchdog->action == dev->action && + virDomainDeviceInfoAddressIsEqual(&dev->info, &watchdog->info))) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("watchdog device not present in domain configuration")); + return -1; + } + + if (watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("hotunplug of watchdog of model %s is not supported"), + virDomainWatchdogModelTypeToString(watchdog->model)); + return -1; + } + + qemuDomainMarkDeviceForRemoval(vm, &watchdog->info); + qemuDomainObjEnterMonitor(driver, vm); + + ret = qemuMonitorDelDevice(priv->mon, watchdog->info.alias); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + if (ret == 0) { + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) { + qemuDomainReleaseDeviceAddress(vm, &watchdog->info, NULL); + ret = qemuDomainRemoveWatchdog(driver, vm, watchdog); + } + } + qemuDomainResetDeviceRemoval(vm); + + return ret; +} + + int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index a9dfd8f7a..3455832d6 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -122,6 +122,9 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainShmemDefPtr dev); +int qemuDomainDetachWatchdog(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainWatchdogDefPtr watchdog); int qemuDomainAttachLease(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainLeaseDefPtr lease); diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index b02ae8034..df28a7fbd 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -155,6 +155,9 @@ testQemuHotplugDetach(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_SHMEM: ret = qemuDomainDetachShmemDevice(&driver, vm, dev->data.shmem); break; + case VIR_DOMAIN_DEVICE_WATCHDOG: + ret = qemuDomainDetachWatchdog(&driver, vm, dev->data.watchdog); + break; default: VIR_TEST_VERBOSE("device type '%s' cannot be detached\n", virDomainDeviceTypeToString(dev->type)); @@ -818,9 +821,11 @@ mymain(void) "human-monitor-command", HMP("OK\\r\\n"), "device_add", QMP_OK); - DO_TEST_ATTACH("base-live", "watchdog", false, false, + DO_TEST_ATTACH("base-live", "watchdog", false, true, "watchdog-set-action", QMP_OK, "device_add", QMP_OK); + DO_TEST_DETACH("base-live", "watchdog-full", false, false, + "device_del", QMP_OK); #define DO_TEST_CPU_GROUP(prefix, vcpus, modernhp, expectfail) \ do { \ diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-full.xml b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-full.xml new file mode 100644 index 000000000..68bbfa87c --- /dev/null +++ b/tests/qemuhotplugtestdevices/qemuhotplug-watchdog-full.xml @@ -0,0 +1,4 @@ +<watchdog model='i6300esb' action='poweroff'> + <alias name='watchdog0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> +</watchdog> -- 2.13.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list