diff options
author | Octavian Purdila <tavip@google.com> | 2024-08-05 18:07:35 -0700 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2024-10-09 12:13:05 +0400 |
commit | b74cb8761c68275240af0826086590a03a1f419d (patch) | |
tree | 53584e9b6ea344e182437ac054009acb98fea33f /chardev | |
parent | c8e2b6b4d7e2abaf34afd120eb065227ce240106 (diff) |
chardev: add path option for pty backend
Add path option to the pty char backend which will create a symbolic
link to the given path that points to the allocated PTY.
This avoids having to make QMP or HMP monitor queries to find out what
the new PTY device path is.
Based on patch from Paulo Neves:
https://patchew.org/QEMU/1548509635-15776-1-git-send-email-ptsneves@gmail.com/
Tested with the following invocations that the link is created and
removed when qemu stops:
qemu-system-x86_64 -nodefaults -mon chardev=compat_monitor \
-chardev pty,path=test,id=compat_monitor0
qemu-system-x86_64 -nodefaults -monitor pty:test
# check QMP invocation with path set
qemu-system-x86_64 -nodefaults -qmp tcp:localhost:4444,server=on,wait=off
nc localhost 4444
> {"execute": "qmp_capabilities"}
> {"execute": "chardev-add", "arguments": {"id": "bar", "backend": {
"type": "pty", "data": {"path": "test" }}}}
# check QMP invocation with path not set
qemu-system-x86_64 -nodefaults -qmp tcp:localhost:4444,server=on,wait=off
nc localhost 4444
> {"execute": "qmp_capabilities"}
> {"execute": "chardev-add", "arguments": {"id": "bar", "backend": {
"type": "pty", "data": {}}}}
Also tested that when a link path is not passed invocations still work, e.g.:
qemu-system-x86_64 -monitor pty
Co-authored-by: Paulo Neves <ptsneves@gmail.com>
Signed-off-by: Paulo Neves <ptsneves@gmail.com>
[OP: rebase and address original patch review comments]
Signed-off-by: Octavian Purdila <tavip@google.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20240806010735.2450555-1-tavip@google.com>
Diffstat (limited to 'chardev')
-rw-r--r-- | chardev/char-pty.c | 33 | ||||
-rw-r--r-- | chardev/char.c | 5 |
2 files changed, 38 insertions, 0 deletions
diff --git a/chardev/char-pty.c b/chardev/char-pty.c index cc2f7617fe..cbb21b76ae 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.c b/chardev/char.c index 35623c78a3..c0cc52824b 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) || |