aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-10-09 15:06:56 +0100
committerPeter Maydell <peter.maydell@linaro.org>2024-10-09 15:06:56 +0100
commit838fc0a8769d7cc6edfe50451ba4e3368395f5c1 (patch)
tree716bdbef87081d4067744d12e2c0a88b9038d770
parent54cdddc6dc29e557de33138fc0d89e73510c8487 (diff)
parentb74cb8761c68275240af0826086590a03a1f419d (diff)
downloadqemu-838fc0a8769d7cc6edfe50451ba4e3368395f5c1.zip
qemu-838fc0a8769d7cc6edfe50451ba4e3368395f5c1.tar.gz
qemu-838fc0a8769d7cc6edfe50451ba4e3368395f5c1.tar.bz2
Merge tag 'chr-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
chardev: introduce 'reconnect-ms' and deprecate 'reconnect' chardev: add path option for pty backend # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmcGQTYcHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5crYEACdw2EjdHm+OSkC2cUt # p9x0spZ8xkUJpU7f7Xc+9fIYHTqqmtgKhbC2/iSaeeL8aSN5LugOAP7u0ya9gXo2 # M1pXPx4WYwy7yftmanwVSvD94GPiCT5EN2W3zFMzvkey9b2AdayGyCXaZY2ago4+ # QJq0pPwWu5VFR0b3ocXIJM1WiEzbR6wr+R0xuPGMLAp0uOnNIyE8AD9MhHJ/BROB # dDCD7xhG6MB1CnRG6+saGV/Aon9mml5i5MmiwmQ6JjC0zZ0w4arkWfjkW5r+yZOc # BrpC6P+MdwX7t7W//4bszlW0Lv+qw9Q9FBavtLrOSTCy/h+cq5XgNjZnf0j0edNp # /EGwQ6D7lqbHp0fGX1O+vnWe0IcyGMKWTU05UGpb3TBDzfzlmjNinQxU6LZPfizh # evRkKELRsy+WTOyJzyeKemw/SdoP8o7RmDF9x3uCP6dF8Q8/UD3CgnwVa8h9L+Jz # 591Ek6srXQhEHkUJdpf48LHvCho4eWkpIy2M7/iurXFZBhpz77A27DCnfBedYg/O # f67MreVDz3C/RSlsnGj7/c0eKnZHPuNhI4AxCAH01bCy1PEv65LrWUdeAtJRm84X # upbn9alqP4LCviUBIwjDqSDhb48mYbgmP8sC3oXeyZObSGQUz94oXh1QQapUHSzz # BCImJN+feMFgLLuEXreJP1N/kQ== # =musy # -----END PGP SIGNATURE----- # gpg: Signature made Wed 09 Oct 2024 09:39:18 BST # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'chr-pull-request' of https://gitlab.com/marcandre.lureau/qemu: chardev: add path option for pty backend chardev: introduce 'reconnect-ms' and deprecate 'reconnect' Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--chardev/char-pty.c33
-rw-r--r--chardev/char-socket.c33
-rw-r--r--chardev/char.c8
-rw-r--r--docs/about/deprecated.rst6
-rw-r--r--include/chardev/char-socket.h2
-rw-r--r--qapi/char.json44
-rw-r--r--qemu-options.hx33
7 files changed, 140 insertions, 19 deletions
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index cc2f761..cbb21b7 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -29,6 +29,7 @@
#include "qemu/sockets.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
+#include "qemu/option.h"
#include "qemu/qemu-print.h"
#include "chardev/char-io.h"
@@ -41,6 +42,7 @@ struct PtyChardev {
int connected;
GSource *timer_src;
+ char *path;
};
typedef struct PtyChardev PtyChardev;
@@ -204,6 +206,12 @@ static void char_pty_finalize(Object *obj)
Chardev *chr = CHARDEV(obj);
PtyChardev *s = PTY_CHARDEV(obj);
+ /* unlink symlink */
+ if (s->path) {
+ unlink(s->path);
+ g_free(s->path);
+ }
+
pty_chr_state(chr, 0);
object_unref(OBJECT(s->ioc));
pty_chr_timer_cancel(s);
@@ -330,6 +338,7 @@ static void char_pty_open(Chardev *chr,
int master_fd, slave_fd;
char pty_name[PATH_MAX];
char *name;
+ char *path = backend->u.pty.data->path;
master_fd = qemu_openpty_raw(&slave_fd, pty_name);
if (master_fd < 0) {
@@ -354,12 +363,36 @@ static void char_pty_open(Chardev *chr,
g_free(name);
s->timer_src = NULL;
*be_opened = false;
+
+ /* create symbolic link */
+ if (path) {
+ int res = symlink(pty_name, path);
+
+ if (res != 0) {
+ error_setg_errno(errp, errno, "Failed to create PTY symlink");
+ } else {
+ s->path = g_strdup(path);
+ }
+ }
+}
+
+static void char_pty_parse(QemuOpts *opts, ChardevBackend *backend,
+ Error **errp)
+{
+ const char *path = qemu_opt_get(opts, "path");
+ ChardevPty *pty;
+
+ backend->type = CHARDEV_BACKEND_KIND_PTY;
+ pty = backend->u.pty.data = g_new0(ChardevPty, 1);
+ qemu_chr_parse_common(opts, qapi_ChardevPty_base(pty));
+ pty->path = g_strdup(path);
}
static void char_pty_class_init(ObjectClass *oc, void *data)
{
ChardevClass *cc = CHARDEV_CLASS(oc);
+ cc->parse = char_pty_parse;
cc->open = char_pty_open;
cc->chr_write = char_pty_chr_write;
cc->chr_update_read_handler = pty_chr_update_read_handler;
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 1ca9441..91496ce 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_ms,
socket_reconnect_timeout,
chr);
g_source_set_name(s->reconnect_timer, name);
@@ -481,7 +481,7 @@ static void tcp_chr_disconnect_locked(Chardev *chr)
if (emit_close) {
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
- if (s->reconnect_time && !s->reconnect_timer) {
+ if (s->reconnect_time_ms && !s->reconnect_timer) {
qemu_chr_socket_restart_timer(chr);
}
}
@@ -1080,9 +1080,9 @@ static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
} else {
Error *err = NULL;
if (tcp_chr_connect_client_sync(chr, &err) < 0) {
- if (s->reconnect_time) {
+ if (s->reconnect_time_ms) {
error_free(err);
- g_usleep(s->reconnect_time * 1000ULL * 1000ULL);
+ g_usleep(s->reconnect_time_ms * 1000ULL);
} else {
error_propagate(errp, err);
return -1;
@@ -1267,13 +1267,13 @@ skip_listen:
static int qmp_chardev_open_socket_client(Chardev *chr,
- int64_t reconnect,
+ int64_t reconnect_ms,
Error **errp)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
- if (reconnect > 0) {
- s->reconnect_time = reconnect;
+ if (reconnect_ms > 0) {
+ s->reconnect_time_ms = reconnect_ms;
tcp_chr_connect_client_async(chr);
return 0;
} else {
@@ -1354,6 +1354,12 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
}
}
+ if (sock->has_reconnect_ms && sock->has_reconnect) {
+ error_setg(errp,
+ "'reconnect' and 'reconnect-ms' are mutually exclusive");
+ return false;
+ }
+
return true;
}
@@ -1371,7 +1377,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
bool is_tn3270 = sock->has_tn3270 ? sock->tn3270 : false;
bool is_waitconnect = sock->has_wait ? sock->wait : false;
bool is_websock = sock->has_websocket ? sock->websocket : false;
- int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
+ int64_t reconnect_ms = 0;
SocketAddress *addr;
s->is_listen = is_listen;
@@ -1443,7 +1449,13 @@ static void qmp_chardev_open_socket(Chardev *chr,
return;
}
} else {
- if (qmp_chardev_open_socket_client(chr, reconnect, errp) < 0) {
+ if (sock->has_reconnect) {
+ reconnect_ms = sock->reconnect * 1000ULL;
+ } else if (sock->has_reconnect_ms) {
+ reconnect_ms = sock->reconnect_ms;
+ }
+
+ if (qmp_chardev_open_socket_client(chr, reconnect_ms, errp) < 0) {
return;
}
}
@@ -1509,6 +1521,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);
+ sock->has_reconnect_ms = qemu_opt_find(opts, "reconnect-ms");
+ sock->reconnect_ms = qemu_opt_get_number(opts, "reconnect-ms", 0);
+
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 ba847b6..c0cc528 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -428,6 +428,11 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
qemu_opt_set(opts, "path", p, &error_abort);
return opts;
}
+ if (strstart(filename, "pty:", &p)) {
+ qemu_opt_set(opts, "backend", "pty", &error_abort);
+ qemu_opt_set(opts, "path", p, &error_abort);
+ return opts;
+ }
if (strstart(filename, "tcp:", &p) ||
strstart(filename, "telnet:", &p) ||
strstart(filename, "tn3270:", &p) ||
@@ -889,6 +894,9 @@ QemuOptsList qemu_chardev_opts = {
.name = "reconnect",
.type = QEMU_OPT_NUMBER,
},{
+ .name = "reconnect-ms",
+ .type = QEMU_OPT_NUMBER,
+ },{
.name = "telnet",
.type = QEMU_OPT_BOOL,
},{
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index c02bbb6..82bb492 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -394,6 +394,12 @@ Backend ``memory`` (since 9.0)
``memory`` is a deprecated synonym for ``ringbuf``.
+``reconnect`` (since 9.2)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``reconnect`` option only allows specifiying second granularity timeouts,
+which is not enough for all types of use cases, use ``reconnect-ms`` instead.
+
CPU device properties
'''''''''''''''''''''
diff --git a/include/chardev/char-socket.h b/include/chardev/char-socket.h
index 0708ca6..d6d13ad 100644
--- a/include/chardev/char-socket.h
+++ b/include/chardev/char-socket.h
@@ -74,7 +74,7 @@ struct SocketChardev {
bool is_websock;
GSource *reconnect_timer;
- int64_t reconnect_time;
+ int64_t reconnect_time_ms;
bool connect_err_reported;
QIOTask *connect_task;
diff --git a/qapi/char.json b/qapi/char.json
index 0d6de1e..e045354 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -273,7 +273,19 @@
#
# @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)
+# this to zero disables this function. The use of this member is
+# deprecated, use @reconnect-ms instead. (default: 0) (Since: 2.2)
+#
+# @reconnect-ms: For a client socket, if a socket is disconnected,
+# then attempt a reconnect after the given number of milliseconds.
+# Setting this to zero disables this function. This member is
+# mutually exclusive with @reconnect.
+# (default: 0) (Since: 9.2)
+#
+# Features:
+#
+# @deprecated: Member @reconnect is deprecated. Use @reconnect-ms
+# instead.
#
# Since: 1.4
##
@@ -287,7 +299,8 @@
'*telnet': 'bool',
'*tn3270': 'bool',
'*websocket': 'bool',
- '*reconnect': 'int' },
+ '*reconnect': { 'type': 'int', 'features': [ 'deprecated' ] },
+ '*reconnect-ms': 'int' },
'base': 'ChardevCommon' }
##
@@ -432,6 +445,20 @@
'if': 'CONFIG_SPICE_PROTOCOL' }
##
+# @ChardevPty:
+#
+# Configuration info for pty implementation.
+#
+# @path: optional path to create a symbolic link that points to the
+# allocated PTY
+#
+# Since: 9.2
+##
+{ 'struct': 'ChardevPty',
+ 'data': { '*path': 'str' },
+ 'base': 'ChardevCommon' }
+
+##
# @ChardevBackendKind:
#
# @file: regular files
@@ -642,6 +669,17 @@
{ 'struct': 'ChardevRingbufWrapper',
'data': { 'data': 'ChardevRingbuf' } }
+
+##
+# @ChardevPtyWrapper:
+#
+# @data: Configuration info for pty chardevs
+#
+# Since: 9.2
+##
+{ 'struct': 'ChardevPtyWrapper',
+ 'data': { 'data': 'ChardevPty' } }
+
##
# @ChardevBackend:
#
@@ -662,7 +700,7 @@
'pipe': 'ChardevHostdevWrapper',
'socket': 'ChardevSocketWrapper',
'udp': 'ChardevUdpWrapper',
- 'pty': 'ChardevCommonWrapper',
+ 'pty': 'ChardevPtyWrapper',
'null': 'ChardevCommonWrapper',
'mux': 'ChardevMuxWrapper',
'msmouse': 'ChardevCommonWrapper',
diff --git a/qemu-options.hx b/qemu-options.hx
index 20a1ce0..d5afefe 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3712,7 +3712,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev serial,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
#else
- "-chardev pty,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
+ "-chardev pty,id=id[,path=path][,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev stdio,id=id[,mux=on|off][,signal=on|off][,logfile=PATH][,logappend=on|off]\n"
#endif
#ifdef CONFIG_BRLAPI
@@ -3951,12 +3951,22 @@ The available backends are:
``path`` specifies the name of the serial device to open.
-``-chardev pty,id=id``
- Create a new pseudo-terminal on the host and connect to it. ``pty``
- does not take any options.
+``-chardev pty,id=id[,path=path]``
+ Create a new pseudo-terminal on the host and connect to it.
``pty`` is not available on Windows hosts.
+ If ``path`` is specified, QEMU will create a symbolic link at
+ that location which points to the new PTY device.
+
+ This avoids having to make QMP or HMP monitor queries to find out
+ what the new PTY device path is.
+
+ Note that while QEMU will remove the symlink when it exits
+ gracefully, it will not do so in case of crashes or on certain
+ startup errors. It is recommended that the user checks and removes
+ the symlink after QEMU terminates to account for this.
+
``-chardev stdio,id=id[,signal=on|off]``
Connect to standard input and standard output of the QEMU process.
@@ -4314,8 +4324,19 @@ SRST
vc:80Cx24C
- ``pty``
- [Linux only] Pseudo TTY (a new PTY is automatically allocated)
+ ``pty[:path]``
+ [Linux only] Pseudo TTY (a new PTY is automatically allocated).
+
+ If ``path`` is specified, QEMU will create a symbolic link at
+ that location which points to the new PTY device.
+
+ This avoids having to make QMP or HMP monitor queries to find
+ out what the new PTY device path is.
+
+ Note that while QEMU will remove the symlink when it exits
+ gracefully, it will not do so in case of crashes or on certain
+ startup errors. It is recommended that the user checks and
+ removes the symlink after QEMU terminates to account for this.
``none``
No device is allocated. Note that for machine types which