qemu-devel
[Top][All Lists]
Advanced

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

[RFC PATCH v1 11/26] kvm: vmi: add 'handshake_timeout' property


From: Adalbert Lazăr
Subject: [RFC PATCH v1 11/26] kvm: vmi: add 'handshake_timeout' property
Date: Wed, 15 Apr 2020 03:59:23 +0300

By having a timer during handshake, the blocked connections can be
restored.

Signed-off-by: Adalbert Lazăr <address@hidden>
---
 accel/kvm/vmi.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/vmi.c b/accel/kvm/vmi.c
index 57ded2f69c..5659663caa 100644
--- a/accel/kvm/vmi.c
+++ b/accel/kvm/vmi.c
@@ -19,6 +19,8 @@
 
 #include "sysemu/vmi-handshake.h"
 
+#define HANDSHAKE_TIMEOUT_SEC 10
+
 typedef struct VMIntrospection {
     Object parent_obj;
 
@@ -32,6 +34,8 @@ typedef struct VMIntrospection {
     qemu_vmi_from_introspector hsk_in;
     uint64_t hsk_in_read_pos;
     uint64_t hsk_in_read_size;
+    GSource *hsk_timer;
+    uint32_t handshake_timeout;
 
     int64_t vm_start_time;
 
@@ -105,6 +109,26 @@ static void prop_set_chardev(Object *obj, const char 
*value, Error **errp)
     i->chardevid = g_strdup(value);
 }
 
+static void prop_get_uint32(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    uint32_t *value = opaque;
+
+    visit_type_uint32(v, name, value, errp);
+}
+
+static void prop_set_uint32(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    uint32_t *value = opaque;
+    Error *local_err = NULL;
+
+    visit_type_uint32(v, name, value, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+    }
+}
+
 static bool chardev_is_connected(VMIntrospection *i, Error **errp)
 {
     Object *obj = OBJECT(i->chr);
@@ -129,6 +153,11 @@ static void instance_init(Object *obj)
     update_vm_start_time(i);
 
     object_property_add_str(obj, "chardev", NULL, prop_set_chardev, NULL);
+
+    i->handshake_timeout = HANDSHAKE_TIMEOUT_SEC;
+    object_property_add(obj, "handshake_timeout", "uint32",
+                        prop_set_uint32, prop_get_uint32,
+                        NULL, &i->handshake_timeout, NULL);
 }
 
 static void disconnect_chardev(VMIntrospection *i)
@@ -165,12 +194,28 @@ static void disconnect_and_unhook_kvmi(VMIntrospection *i)
     unhook_kvmi(i);
 }
 
+static void cancel_timer(GSource *timer)
+{
+    if (timer) {
+        g_source_destroy(timer);
+        g_source_unref(timer);
+    }
+}
+
+static void cancel_handshake_timer(VMIntrospection *i)
+{
+    cancel_timer(i->hsk_timer);
+    i->hsk_timer = NULL;
+}
+
 static void instance_finalize(Object *obj)
 {
     VMIntrospection *i = VM_INTROSPECTION(obj);
 
     g_free(i->chardevid);
 
+    cancel_handshake_timer(i);
+
     if (i->chr) {
         shutdown_socket_fd(i);
         qemu_chr_fe_deinit(&i->sock, true);
@@ -303,7 +348,7 @@ static int chr_can_read(void *opaque)
 {
     VMIntrospection *i = opaque;
 
-    if (i->sock_fd == -1) {
+    if (i->hsk_timer == NULL || i->sock_fd == -1) {
         return 0;
     }
 
@@ -356,10 +401,24 @@ static void chr_read(void *opaque, const uint8_t *buf, 
int size)
     }
 
     if (enough_bytes_for_handshake(i)) {
+        cancel_handshake_timer(i);
         validate_and_connect(i);
     }
 }
 
+static gboolean chr_timeout(gpointer opaque)
+{
+    VMIntrospection *i = opaque;
+
+    warn_report("VMI: the handshake takes too long");
+
+    g_source_unref(i->hsk_timer);
+    i->hsk_timer = NULL;
+
+    disconnect_and_unhook_kvmi(i);
+    return FALSE;
+}
+
 static void chr_event_open(VMIntrospection *i)
 {
     Error *local_err = NULL;
@@ -378,6 +437,9 @@ static void chr_event_open(VMIntrospection *i)
     memset(&i->hsk_in, 0, sizeof(i->hsk_in));
     i->hsk_in_read_pos = 0;
     i->hsk_in_read_size = 0;
+    i->hsk_timer = qemu_chr_timeout_add_ms(i->chr,
+                                           i->handshake_timeout * 1000,
+                                           chr_timeout, i);
 }
 
 static void chr_event_close(VMIntrospection *i)
@@ -386,6 +448,8 @@ static void chr_event_close(VMIntrospection *i)
         warn_report("VMI: introspection tool disconnected");
         disconnect_and_unhook_kvmi(i);
     }
+
+    cancel_handshake_timer(i);
 }
 
 static void chr_event(void *opaque, QEMUChrEvent event)



reply via email to

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