From: Mark Kanda <mark.ka...@oracle.com> Save and restore QMP compatibility negotiation status across cprsave and cprload.
Signed-off-by: Mark Kanda <mark.ka...@oracle.com> Signed-off-by: Steve Sistare <steven.sist...@oracle.com> --- include/sysemu/sysemu.h | 1 + migration/savevm.c | 1 + monitor/qmp.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 3e7bfee..c5b2f24 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -30,6 +30,7 @@ void load_cpr_snapshot(const char *file, Error **errp); void save_chardev_fds(void); void save_vnc_fds(void); void load_vnc_fds(void); +void save_qmp_negotiation_status(void); extern int autostart; diff --git a/migration/savevm.c b/migration/savevm.c index 35fafb7..225eaa6 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2770,6 +2770,7 @@ void save_cpr_snapshot(const char *file, const char *mode, Error **errp) save_chardev_fds(); save_vnc_fds(); walkenv(FD_PREFIX, preserve_fd, 0); + save_qmp_negotiation_status(); qemu_system_exec_request(); putenv((char *)"QEMU_START_FREEZE="); } diff --git a/monitor/qmp.c b/monitor/qmp.c index d433cea..9944ce5 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -33,6 +33,8 @@ #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" #include "trace.h" +#include "qemu/env.h" +#include "sysemu/sysemu.h" struct QMPRequest { /* Owner of the request */ @@ -398,6 +400,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 +455,29 @@ 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; + } +} + +void save_qmp_negotiation_status(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