Signed-off-by: Elena Ufimtseva <elena.ufimts...@oracle.com> Signed-off-by: John G Johnson <john.g.john...@oracle.com> Signed-off-by: Jagannathan Raman <jag.ra...@oracle.com> --- include/hw/qdev-core.h | 5 +++++ softmmu/qdev-monitor.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index eed2983072..67df5e0081 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -193,6 +193,7 @@ struct DeviceState { int instance_id_alias; int alias_required_for_version; ResettableState reset; + GSList *unplug_blockers; }; struct DeviceListener { @@ -433,6 +434,10 @@ typedef bool (QDevPutBusFunc)(BusState *bus, Error **errp); bool qdev_set_bus_cbs(QDevGetBusFunc *get_bus, QDevPutBusFunc *put_bus, Error **errp); +int qdev_add_unplug_blocker(DeviceState *dev, Error *reason, Error **errp); +void qdev_del_unplug_blocker(DeviceState *dev, Error *reason); +bool qdev_unplug_blocked(DeviceState *dev, Error **errp); + /** * GpioPolarity: Polarity of a GPIO line * diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index 7306074019..1a169f89a2 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -978,10 +978,45 @@ void qmp_device_del(const char *id, Error **errp) return; } + if (qdev_unplug_blocked(dev, errp)) { + return; + } + qdev_unplug(dev, errp); } } +int qdev_add_unplug_blocker(DeviceState *dev, Error *reason, Error **errp) +{ + ERRP_GUARD(); + + if (!migration_is_idle()) { + error_setg(errp, "migration is in progress"); + return -EBUSY; + } + + dev->unplug_blockers = g_slist_prepend(dev->unplug_blockers, reason); + + return 0; +} + +void qdev_del_unplug_blocker(DeviceState *dev, Error *reason) +{ + dev->unplug_blockers = g_slist_remove(dev->unplug_blockers, reason); +} + +bool qdev_unplug_blocked(DeviceState *dev, Error **errp) +{ + ERRP_GUARD(); + + if (dev->unplug_blockers) { + error_propagate(errp, error_copy(dev->unplug_blockers->data)); + return true; + } + + return false; +} + void hmp_device_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; -- 2.20.1