@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "qom/object_interfaces.h"
#include "sysemu/sysemu.h"
@@ -23,6 +24,8 @@
#include "migration/vmstate.h"
#include "migration/migration.h"
#include "migration/misc.h"
+#include "qapi/qmp/qobject.h"
+#include "monitor/monitor.h"
#include "sysemu/vmi-intercept.h"
#include "sysemu/vmi-handshake.h"
@@ -63,6 +66,9 @@ typedef struct VMIntrospection {
Notifier migration_state_change;
bool created_from_command_line;
+ void *qmp_monitor;
+ QDict *qmp_rsp;
+
bool kvmi_hooked;
} VMIntrospection;
@@ -333,6 +339,8 @@ static void instance_finalize(Object *obj)
error_free(i->init_error);
+ qobject_unref(i->qmp_rsp);
+
ic->instance_counter--;
if (!ic->instance_counter) {
ic->uniq = NULL;
@@ -506,6 +514,12 @@ static void continue_with_the_intercepted_action(VMIntrospection *i)
info_report("VMI: continue with '%s'",
action_string[i->intercepted_action]);
+
+ if (i->qmp_rsp) {
+ monitor_qmp_respond_later(i->qmp_monitor, i->qmp_rsp);
+ i->qmp_monitor = NULL;
+ i->qmp_rsp = NULL;
+ }
}
/*
@@ -676,6 +690,21 @@ static VMIntrospection *vm_introspection_object(void)
return ic ? ic->uniq : NULL;
}
+bool vm_introspection_qmp_delay(void *mon, QDict *rsp)
+{
+ VMIntrospection *i = vm_introspection_object();
+ bool intercepted;
+
+ intercepted = i && i->intercepted_action == VMI_INTERCEPT_SUSPEND;
+
+ if (intercepted) {
+ i->qmp_monitor = mon;
+ i->qmp_rsp = rsp;
+ }
+
+ return intercepted;
+}
+
/*
* This ioctl succeeds only when KVM signals the introspection tool.
* (the socket is connected and the event was sent without error).
@@ -1,7 +1,14 @@
#include "qemu/osdep.h"
+#include "qapi/qmp/qdict.h"
+
#include "sysemu/vmi-intercept.h"
bool vm_introspection_intercept(VMI_intercept_command ic, Error **errp)
{
return false;
}
+
+bool vm_introspection_qmp_delay(void *mon, QDict *rsp)
+{
+ return false;
+}
@@ -47,5 +47,6 @@ int monitor_fdset_get_fd(int64_t fdset_id, int flags);
int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
void monitor_fdset_dup_fd_remove(int dup_fd);
int64_t monitor_fdset_dup_fd_find(int dup_fd);
+void monitor_qmp_respond_later(void *_mon, QDict *rsp);
#endif /* MONITOR_H */
@@ -19,6 +19,6 @@ typedef enum {
} VMI_intercept_command;
bool vm_introspection_intercept(VMI_intercept_command ic, Error **errp);
-bool vm_introspection_qmp_delay(void *mon, QObject *id, bool resume);
+bool vm_introspection_qmp_delay(void *mon, QDict *rsp);
#endif /* QEMU_VMI_INTERCEPT_H */
@@ -3,4 +3,4 @@ common-obj-y += monitor.o qmp.o hmp.o
common-obj-y += qmp-cmds.o qmp-cmds-control.o
common-obj-y += hmp-cmds.o
-storage-daemon-obj-y += monitor.o qmp.o qmp-cmds-control.o
+storage-daemon-obj-y += monitor.o qmp.o qmp-cmds-control.o stubs.o
@@ -32,6 +32,7 @@
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h"
+#include "sysemu/vmi-intercept.h"
#include "trace.h"
struct QMPRequest {
@@ -158,6 +159,16 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
}
}
+ if (!vm_introspection_qmp_delay(mon, rsp)) {
+ monitor_qmp_respond(mon, rsp);
+ qobject_unref(rsp);
+ }
+}
+
+void monitor_qmp_respond_later(void *_mon, QDict *rsp)
+{
+ MonitorQMP *mon = _mon;
+
monitor_qmp_respond(mon, rsp);
qobject_unref(rsp);
}
new file mode 100644
@@ -0,0 +1,9 @@
+#include "qemu/osdep.h"
+#include "qapi/qmp/qdict.h"
+
+#include "sysemu/vmi-intercept.h"
+
+bool vm_introspection_qmp_delay(void *mon, QDict *rsp)
+{
+ return false;
+}
The method to postpone the intercepted command (pause/suspend/migrate) until the introspection tool has the chance to remove its hooks (e.g. breakpoints) from guest doesn't work on snapshot+memory (at least as it is done by libvirt/virt-manager 1.3.1). The sequence qmp_stop()+save_vm+qmp_cont() doesn't wait for the STOP event. save_vm() is called right after qmp_stop() returns OK. What we do is postpone this OK response until the introspection tools finishes the unhook process. CC: Markus Armbruster <armbru@redhat.com> Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com> --- accel/kvm/vmi.c | 29 +++++++++++++++++++++++++++++ accel/stubs/vmi-stubs.c | 7 +++++++ include/monitor/monitor.h | 1 + include/sysemu/vmi-intercept.h | 2 +- monitor/Makefile.objs | 2 +- monitor/qmp.c | 11 +++++++++++ monitor/stubs.c | 9 +++++++++ 7 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 monitor/stubs.c