Hi

On Tue, Jan 21, 2025 at 10:47 PM Roman Penyaev <r.peni...@gmail.com> wrote:
>
> Mux is a character backend (host side) device, which multiplexes
> multiple frontends with one backend device. The following is a
> few lines from the QEMU manpage [1]:
>
>   A multiplexer is a "1:N" device, and here the "1" end is your
>   specified chardev backend, and the "N" end is the various parts
>   of QEMU that can talk to a chardev.
>
> But sadly multiple backends are not supported.
>
> This work implements a new chardev backend `hub` device, which
> aggregates input from multiple backend devices and forwards it to a
> single frontend device. Additionally, `hub` device takes the output
> from the frontend device and sends it back to all the connected
> backend devices. This allows for seamless interaction between
> different backend devices and a single frontend interface.
>
> The motivation is the EVE project [2], where it would be very
> convenient to have a virtio console frontend device on the guest that
> can be controlled from multiple backend devices, namely VNC and local
> TTY emulator. The following is an example of the QEMU command line:
>
>     -chardev pty,path=/tmp/pty,id=pty0 \
>     -chardev vc,id=vc0 \
>     -chardev hub,id=hub0,chardevs.0=pty0,chardevs.1=vc0 \
>     -device virtconsole,chardev=hub0 \
>     -vnc 0.0.0.0:0
>
> Which creates two backend devices:
>
> * Text virtual console (`vc0`)
> * A pseudo TTY (`pty0`) connected to the single virtio hvc console with the
>   help of a new backend aggregator (`hub0`)
>
> `vc0` renders text to an image, which can be shared over the VNC
> protocol.  `pty0` is a pseudo TTY backend which provides bidirectional
> communication to the virtio hvc console.
>
> Once QEMU starts, the VNC client and any TTY emulator can be used to
> control a single hvc console. For example, these two different
> consoles should have similar input and output due to the buffer
> aggregation:
>
>     # Start TTY emulator
>     tio /tmp/pty
>
>     # Start VNC client and switch to virtual console Ctrl-Alt-2
>     vncviewer :0
>
> 'chardevs.N' list syntax is used for the sake of compatibility with
> the representation of JSON lists in 'key=val' pairs format of the
> util/keyval.c, despite the fact that modern QAPI way of parsing,
> namely qobject_input_visitor_new_str(), is not used. Choice of keeping
> QAPI list syntax may help to smoothly switch to modern parsing in the
> future.
>
> v7 .. v8:
>
> * No need for a separate `->frontend` pointer in the hub device
>   structure, use `hub->parent.fe` directly.
> * Remove special handling of !EAGAIN error while serving write
>   to all backends. This should be safe, because detached backends
>   are handled by the `->be_open` flag check.
> * Combine `hub_chr_write_to_all()` and `hub_chr_write()` calls.
> * Fix docs generation: no single backtick, but double, so not
>   a `hub` but ``hub`` in qemu-options.hx
>
> v6 .. v7:
>
> After discussing v6 it was decided to:
>
> * Rename "multiplexer" to "aggregator"
> * Rename "mux-be" device type to "hub"
> * Drop all changes related to the original multiplexer implementation
>
> Code changes:
>
> * Added counting of CHR_EVENT_OPENED and CHR_EVENT_CLOSED events
> coming from backend devices. This prevents frontend devices from
> closing if one of the backend devices has been disconnected. The
> logic is simple: "the last one turns off the light".
>
> v5 .. v6:
>
> * Rebased on latest master
> * Changed how chardev is attached to a multiplexer: with version 6
> mux should specify list elements with ID of chardevs:
>
>     chardevs.0=ID[,chardevs.N=ID]
>
> 'chardevs.N' list syntax is used for the sake of compatibility with
> the representation of JSON lists in 'key=val' pairs format of the
> util/keyval.c, despite the fact that modern QAPI way of parsing,
> namely qobject_input_visitor_new_str(), is not used. Choice of keeping
> QAPI list syntax may help to smoothly switch to modern parsing in the
> future.
>
> v4 .. v5:
>
> * Spelling fixes in qemu-options description
> * Memory leaks fixes in mux-be tests
> * Add sanity checks to chardev to avoid stacking of mux devices
> * Add corresponding unit test case to cover the creation of stacked
>   muxers: `-chardev mux-be,mux-id-be=ID`, which is forbidden
> * Reflect the fact that stacking is not supported in the documentation
>
> v3 .. v4:
>
> * Rebase on latest chardev changes
> * Add unit tests which test corner cases:
>    * Inability to remove mux with active frontend
>    * Inability to add more chardevs to a mux than `MUX_MAX`
>    * Inability to mix mux-fe and mux-be for the same chardev
>
> v2 .. v3:
>
> * Split frontend and backend multiplexer implementations and
>   move them to separate files: char-mux-fe.c and char-mux-be.c
>
> v1 .. v2:
>
> * Separate type for the backend multiplexer `mux-be`
> * Handle EAGAIN on write to the backend device
> * Support of watch of previously failed backend device
> * Proper json support of the `mux-be-id` option
> * Unit test for the `mux-be` multiplexer
>
> [1] https://www.qemu.org/docs/master/system/qemu-manpage.html#hxtool-6
> [2] https://github.com/lf-edge/eve
>
> Signed-off-by: Roman Penyaev <r.peni...@gmail.com>
> Cc: "Marc-André Lureau" <marcandre.lur...@redhat.com>
> Cc: Markus Armbruster <arm...@redhat.com>
> Cc: Kevin Wolf <kw...@redhat.com>
> Cc: Daniel P. Berrange <berra...@redhat.com>
> Cc: qemu-devel@nongnu.org

Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com>

>
> Roman Penyaev (4):
>   chardev/char-pty: send CHR_EVENT_CLOSED on disconnect
>   chardev/char-hub: implement backend chardev aggregator
>   tests/unit/test-char: add unit tests for hub chardev backend
>   qemu-options.hx: describe hub chardev and aggregation of several
>     backends
>
>  chardev/char-hub.c         | 301 ++++++++++++++++++++++++++++
>  chardev/char-pty.c         |   4 +-
>  chardev/char.c             |  23 ++-
>  chardev/chardev-internal.h |  51 ++++-
>  chardev/meson.build        |   1 +
>  include/chardev/char.h     |   1 +
>  qapi/char.json             |  27 +++
>  qemu-options.hx            |  48 ++++-
>  tests/unit/test-char.c     | 398 +++++++++++++++++++++++++++++++++++++
>  9 files changed, 846 insertions(+), 8 deletions(-)
>  create mode 100644 chardev/char-hub.c
>
> --
> 2.43.0
>


Reply via email to