diff mbox series

[RFC,v1,22/26] kvm: vmi: add 'async_unhook' property

Message ID 20200415005938.23895-23-alazar@bitdefender.com
State New
Headers show
Series None | expand

Commit Message

Adalbert Lazăr April 15, 2020, 12:59 a.m. UTC
The default method to handle the intercepted commands
(pause/suspend/migrate) might not be the simplest method. We add an
alternative method, used when async_unhook is set to false, that runs
the main loop until the introspection tool finish the unhook process
and closes the introspection socket.

Signed-off-by: Adalbert Lazăr <alazar@bitdefender.com>
---
 accel/kvm/vmi.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
diff mbox series

Patch

diff --git a/accel/kvm/vmi.c b/accel/kvm/vmi.c
index 01034d460e..bee9798e54 100644
--- a/accel/kvm/vmi.c
+++ b/accel/kvm/vmi.c
@@ -57,6 +57,7 @@  typedef struct VMIntrospection {
     int intercepted_action;
     GSource *unhook_timer;
     uint32_t unhook_timeout;
+    bool async_unhook;
 
     int reconnect_time;
 
@@ -186,6 +187,20 @@  static void prop_set_key(Object *obj, const char *value, Error **errp)
     i->keyid = g_strdup(value);
 }
 
+static bool prop_get_async_unhook(Object *obj, Error **errp)
+{
+    VMIntrospection *i = VM_INTROSPECTION(obj);
+
+    return i->async_unhook;
+}
+
+static void prop_set_async_unhook(Object *obj, bool value, Error **errp)
+{
+    VMIntrospection *i = VM_INTROSPECTION(obj);
+
+    i->async_unhook = value;
+}
+
 static void prop_get_uint32(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
 {
@@ -263,6 +278,11 @@  static void instance_init(Object *obj)
                         prop_set_uint32, prop_get_uint32,
                         NULL, &i->unhook_timeout, NULL);
 
+    i->async_unhook = true;
+    object_property_add_bool(obj, "async_unhook",
+                             prop_get_async_unhook,
+                             prop_set_async_unhook, NULL);
+
     vmstate_register(NULL, 0, &vmstate_introspection, i);
 }
 
@@ -739,6 +759,19 @@  static bool record_intercept_action(VMI_intercept_command action)
     return true;
 }
 
+static void wait_until_the_socket_is_closed(VMIntrospection *i)
+{
+    info_report("VMI: start waiting until fd=%d is closed", i->sock_fd);
+
+    while (i->sock_fd != -1) {
+        main_loop_wait(false);
+    }
+
+    info_report("VMI: continue with the intercepted action fd=%d", i->sock_fd);
+
+    maybe_disable_socket_reconnect(i);
+}
+
 static bool intercept_action(VMIntrospection *i,
                              VMI_intercept_command action, Error **errp)
 {
@@ -767,6 +800,11 @@  static bool intercept_action(VMIntrospection *i,
                                               i->unhook_timeout * 1000,
                                               unhook_timeout_cbk, i);
 
+    if (!i->async_unhook) {
+        wait_until_the_socket_is_closed(i);
+        return false;
+    }
+
     i->intercepted_action = action;
     return true;
 }