qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH V2 19/22] monitor: cpr support


From: Steve Sistare
Subject: [PATCH V2 19/22] monitor: cpr support
Date: Tue, 5 Jan 2021 07:42:07 -0800

A monitor socket requires special treatment.  Save and restore the
qmp negotiation status.  Stop the monitor's iothread in cpsave. Otherwise,
the thread will detect the close of the monitor socket and call 
unsetenv_fd,which modifies environ and races with execv which uses environ.

Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
---
 include/monitor/monitor.h |  2 ++
 migration/cpr.c           |  2 ++
 monitor/monitor.c         |  5 +++++
 monitor/qmp.c             | 43 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 1018d75..5456cff 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -22,6 +22,8 @@ void monitor_init_hmp(Chardev *chr, bool use_readline, Error 
**errp);
 int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp);
 int monitor_init_opts(QemuOpts *opts, Error **errp);
 void monitor_cleanup(void);
+void monitor_iothread_stop(void);
+void monitor_cprsave(void);
 
 int monitor_suspend(Monitor *mon);
 void monitor_resume(Monitor *mon);
diff --git a/migration/cpr.c b/migration/cpr.c
index de85d56..0f49c7d 100644
--- a/migration/cpr.c
+++ b/migration/cpr.c
@@ -137,9 +137,11 @@ void cprsave(const char *file, CprMode mode, Error **errp)
         if (vfio_cprsave()) {
             goto err;
         }
+        monitor_iothread_stop();
         walkenv(FD_PREFIX, preserve_fd, 0);
         vhost_dev_reset_all();
         qemu_term_exit();
+        monitor_cprsave();
         setenv("QEMU_START_FREEZE", "", 1);
         qemu_system_exec_request();
     }
diff --git a/monitor/monitor.c b/monitor/monitor.c
index b385a3d..1bda67c 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -591,6 +591,11 @@ void monitor_cleanup(void)
     }
 }
 
+void monitor_iothread_stop(void)
+{
+    iothread_stop(mon_iothread);
+}
+
 static void monitor_qapi_event_init(void)
 {
     monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash,
diff --git a/monitor/qmp.c b/monitor/qmp.c
index d433cea..d7eeab1 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -33,6 +33,7 @@
 #include "qapi/qmp/qlist.h"
 #include "qapi/qmp/qstring.h"
 #include "trace.h"
+#include "qemu/env.h"
 
 struct QMPRequest {
     /* Owner of the request */
@@ -398,6 +399,21 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
     monitor_list_append(&mon->common);
 }
 
+static void setenv_qmp(const char *name, bool val)
+{
+    setenv_bool(name, val);
+}
+
+static bool getenv_qmp(const char *name)
+{
+    bool ret = getenv_bool(name);
+    if (ret != -1) {
+        unsetenv_bool(name);
+        return ret;
+    }
+    return false;
+}
+
 void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
 {
     MonitorQMP *mon = g_new0(MonitorQMP, 1);
@@ -438,4 +454,31 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error 
**errp)
                                  NULL, &mon->common, NULL, true);
         monitor_list_append(&mon->common);
     }
+
+    /*
+     * If a chr->label qmp env var is true, this is a restored qmp
+     * connection with capabilities negotiated.
+     */
+    if (getenv_qmp(chr->label) == true) {
+        mon->commands = &qmp_commands;
+    }
+}
+
+/* Save the result of capability negotiation in the environment */
+
+void monitor_cprsave(void)
+{
+    Monitor *mon;
+    MonitorQMP *qmp_mon;
+
+    QTAILQ_FOREACH(mon, &mon_list, entry) {
+        if (!monitor_is_qmp(mon)) {
+            continue;
+        }
+
+        qmp_mon = container_of(mon, MonitorQMP, common);
+        if (qmp_mon->commands == &qmp_commands) {
+            setenv_qmp(mon->chr.chr->label, true);
+        }
+    }
 }
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]