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 <ala...@bitdefender.com> --- accel/kvm/vmi.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) 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; }