diff mbox series

[3/4] qapi: device-sync-config: check runstate

Message ID 20231006202045.1161543-4-vsementsov@yandex-team.ru
State New
Headers show
Series vhost-user-blk: live resize additional APIs | expand

Commit Message

Vladimir Sementsov-Ogievskiy Oct. 6, 2023, 8:20 p.m. UTC
Command result is racy if allow it during migration. Let's allow the
sync only in RUNNING state.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 include/sysemu/runstate.h |  1 +
 softmmu/qdev-monitor.c    | 27 ++++++++++++++++++++++++++-
 softmmu/runstate.c        |  5 +++++
 3 files changed, 32 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
index 08afb97695..1fc14c8122 100644
--- a/include/sysemu/runstate.h
+++ b/include/sysemu/runstate.h
@@ -5,6 +5,7 @@ 
 #include "qemu/notify.h"
 
 bool runstate_check(RunState state);
+const char *current_run_state_str(void);
 void runstate_set(RunState new_state);
 RunState runstate_get(void);
 bool runstate_is_running(void);
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index b6da24389f..b485375049 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -23,6 +23,7 @@ 
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
 #include "sysemu/arch_init.h"
+#include "sysemu/runstate.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
 #include "qapi/qapi-events-qdev.h"
@@ -1002,7 +1003,31 @@  int qdev_sync_config(DeviceState *dev, Error **errp)
 
 void qmp_x_device_sync_config(const char *id, Error **errp)
 {
-    DeviceState *dev = find_device_state(id, errp);
+    MigrationState *s = migrate_get_current();
+    DeviceState *dev;
+
+    /*
+     * During migration there is a race between syncing`config and migrating it,
+     * so let's just not allow it.
+     *
+     * Moreover, let's not rely on setting up interrupts in paused state, which
+     * may be a part of migration process.
+     */
+
+    if (migration_is_running(s->state)) {
+        error_setg(errp, "Config synchronization is not allowed "
+                   "during migration.");
+        return;
+    }
+
+    if (!runstate_is_running()) {
+        error_setg(errp, "Config synchronization allowed only in '%s' state, "
+                   "current state is '%s'", RunState_str(RUN_STATE_RUNNING),
+                   current_run_state_str());
+        return;
+    }
+
+    dev = find_device_state(id, errp);
     if (!dev) {
         return;
     }
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 1652ed0439..3a8211474e 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -181,6 +181,11 @@  bool runstate_check(RunState state)
     return current_run_state == state;
 }
 
+const char *current_run_state_str(void)
+{
+    return RunState_str(current_run_state);
+}
+
 static void runstate_init(void)
 {
     const RunStateTransition *p;