mirror of https://github.com/xemu-project/xemu.git
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----- 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>
This commit is contained in:
commit
838fc0a876
|
@ -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;
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -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) ||
|
||||
|
@ -888,6 +893,9 @@ QemuOptsList qemu_chardev_opts = {
|
|||
},{
|
||||
.name = "reconnect",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
},{
|
||||
.name = "reconnect-ms",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
},{
|
||||
.name = "telnet",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
|
|
|
@ -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
|
||||
'''''''''''''''''''''
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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' }
|
||||
|
||||
##
|
||||
|
@ -431,6 +444,20 @@
|
|||
'base': 'ChardevCommon',
|
||||
'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:
|
||||
#
|
||||
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue