The "reconnect" option only allows to specify the time in seconds,
which is way too long for certain workflows.

We have a lightweight disk backend server, which takes about 20ms to
live update, but due to this limitation in QEMU, previously the guest
disk controller would hang for one second because it would take this
long for QEMU to reinitialize the socket connection.

Make it possible to specify a smaller timeout by treating the value in
"reconnect" as milliseconds via the new "reconnect-is-ms" option.

Signed-off-by: Daniil Tatianin <d-tatia...@yandex-team.ru>
---
 chardev/char-socket.c |  7 +++++--
 chardev/char.c        |  3 +++
 qapi/char.json        | 12 +++++++++---
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 1ca9441b1b..d87859e641 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -74,7 +74,7 @@ static void qemu_chr_socket_restart_timer(Chardev *chr)
     assert(!s->reconnect_timer);
     name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
     s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
-                                                 s->reconnect_time * 1000,
+                                                 s->reconnect_time,
                                                  socket_reconnect_timeout,
                                                  chr);
     g_source_set_name(s->reconnect_timer, name);
@@ -1082,7 +1082,7 @@ static int tcp_chr_wait_connected(Chardev *chr, Error 
**errp)
             if (tcp_chr_connect_client_sync(chr, &err) < 0) {
                 if (s->reconnect_time) {
                     error_free(err);
-                    g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
+                    g_usleep(s->reconnect_time * 1000ULL);
                 } else {
                     error_propagate(errp, err);
                     return -1;
@@ -1509,6 +1509,9 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
     sock->wait = qemu_opt_get_bool(opts, "wait", true);
     sock->has_reconnect = qemu_opt_find(opts, "reconnect");
     sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
+    if (!qemu_opt_get_bool(opts, "reconnect-is-ms", false)) {
+        sock->reconnect *= 1000ULL;
+    }
     sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
     sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
 
diff --git a/chardev/char.c b/chardev/char.c
index 3c43fb1278..f6e5f1d5c9 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -859,6 +859,9 @@ QemuOptsList qemu_chardev_opts = {
         },{
             .name = "reconnect",
             .type = QEMU_OPT_NUMBER,
+        },{
+            .name = "reconnect-is-ms",
+            .type = QEMU_OPT_BOOL,
         },{
             .name = "telnet",
             .type = QEMU_OPT_BOOL,
diff --git a/qapi/char.json b/qapi/char.json
index ef58445cee..61aeccf09d 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -272,8 +272,13 @@
 #     (default: false) (Since: 3.1)
 #
 # @reconnect: For a client socket, if a socket is disconnected, then
-#     attempt a reconnect after the given number of seconds.  Setting
-#     this to zero disables this function.  (default: 0) (Since: 2.2)
+#     attempt a reconnect after the given number of seconds (unless
+#     @reconnect-is-ms is set to true, in that case the number is
+#     treated as milliseconds).  Setting this to zero disables
+#     this function.  (default: 0) (Since: 2.2)
+#
+# @reconnect-is-ms: The value specified in @reconnect should be treated
+#     as milliseconds.  (default: false) (Since: 9.2)
 #
 # Since: 1.4
 ##
@@ -287,7 +292,8 @@
             '*telnet': 'bool',
             '*tn3270': 'bool',
             '*websocket': 'bool',
-            '*reconnect': 'int' },
+            '*reconnect': 'int',
+            '*reconnect-is-ms': 'bool' },
   'base': 'ChardevCommon' }
 
 ##
-- 
2.34.1


Reply via email to