mbox series

[v5,0/8] chardev: implement backend chardev multiplexing

Message ID 20241017144316.517709-1-r.peniaev@gmail.com (mailing list archive)
Headers show
Series chardev: implement backend chardev multiplexing | expand

Message

Roman Penyaev Oct. 17, 2024, 2:43 p.m. UTC
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 multiplexing capability of several backend
devices, which opens up an opportunity to use a single frontend
device on the guest, which can be manipulated from several
backend devices.

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 mux-be,id=mux0 \
   -chardev socket,path=/tmp/sock,server=on,wait=off,id=sock0,mux-be-id=mux0 \
   -chardev vc,id=vc0,mux-be-id=mux0 \
   -device virtconsole,chardev=mux0 \
   -vnc 0.0.0.0:0

Which creates two backend devices:

* Text virtual console (`vc0`)
* A socket (`sock0`) connected to the single virtio hvc console with the
  help of the backend multiplexer (`mux0`)

`vc0` renders text to an image, which can be shared over the VNC protocol.
`sock0` is a socket 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
multiplexing:

   # VNC client
   vncviewer :0

   # TTY emulator
   socat unix-connect:/tmp/sock pty,link=/tmp/pty
   tio /tmp/pty

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.peniaev@gmail.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
Cc: qemu-devel@nongnu.org

Roman Penyaev (8):
  chardev/char: rename `MuxChardev` struct to `MuxFeChardev`
  chardev/char: rename `char-mux.c` to `char-mux-fe.c`
  chardev/char: move away mux suspend/resume calls
  chardev/char: rename frontend mux calls
  chardev/char: introduce `mux-be-id=ID` option
  chardev/char-mux: implement backend chardev multiplexing
  tests/unit/test-char: add unit test for the `mux-be` multiplexer
  qemu-options.hx: describe multiplexing of several backend devices

 chardev/char-fe.c                     |  25 +-
 chardev/char-mux-be.c                 | 290 +++++++++++++++++++++++
 chardev/{char-mux.c => char-mux-fe.c} | 157 ++++---------
 chardev/char.c                        | 139 +++++++++--
 chardev/chardev-internal.h            |  55 ++++-
 chardev/meson.build                   |   3 +-
 include/chardev/char.h                |   8 +-
 qapi/char.json                        |  31 ++-
 qemu-options.hx                       |  80 +++++--
 system/vl.c                           |   4 +-
 tests/unit/test-char.c                | 323 +++++++++++++++++++++++++-
 11 files changed, 947 insertions(+), 168 deletions(-)
 create mode 100644 chardev/char-mux-be.c
 rename chardev/{char-mux.c => char-mux-fe.c} (71%)

Comments

Roman Penyaev Oct. 31, 2024, 11:09 a.m. UTC | #1
Hi Marc-André,

In this 5th version of the mux-be series it seems I addressed all the
comments and concerns. Could you please take a look once again?

--
Roman

On Thu, Oct 17, 2024 at 4:45 PM Roman Penyaev <r.peniaev@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 multiplexing capability of several backend
> devices, which opens up an opportunity to use a single frontend
> device on the guest, which can be manipulated from several
> backend devices.
>
> 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 mux-be,id=mux0 \
>    -chardev socket,path=/tmp/sock,server=on,wait=off,id=sock0,mux-be-id=mux0 \
>    -chardev vc,id=vc0,mux-be-id=mux0 \
>    -device virtconsole,chardev=mux0 \
>    -vnc 0.0.0.0:0
>
> Which creates two backend devices:
>
> * Text virtual console (`vc0`)
> * A socket (`sock0`) connected to the single virtio hvc console with the
>   help of the backend multiplexer (`mux0`)
>
> `vc0` renders text to an image, which can be shared over the VNC protocol.
> `sock0` is a socket 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
> multiplexing:
>
>    # VNC client
>    vncviewer :0
>
>    # TTY emulator
>    socat unix-connect:/tmp/sock pty,link=/tmp/pty
>    tio /tmp/pty
>
> 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.peniaev@gmail.com>
> Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
> Cc: qemu-devel@nongnu.org
>
> Roman Penyaev (8):
>   chardev/char: rename `MuxChardev` struct to `MuxFeChardev`
>   chardev/char: rename `char-mux.c` to `char-mux-fe.c`
>   chardev/char: move away mux suspend/resume calls
>   chardev/char: rename frontend mux calls
>   chardev/char: introduce `mux-be-id=ID` option
>   chardev/char-mux: implement backend chardev multiplexing
>   tests/unit/test-char: add unit test for the `mux-be` multiplexer
>   qemu-options.hx: describe multiplexing of several backend devices
>
>  chardev/char-fe.c                     |  25 +-
>  chardev/char-mux-be.c                 | 290 +++++++++++++++++++++++
>  chardev/{char-mux.c => char-mux-fe.c} | 157 ++++---------
>  chardev/char.c                        | 139 +++++++++--
>  chardev/chardev-internal.h            |  55 ++++-
>  chardev/meson.build                   |   3 +-
>  include/chardev/char.h                |   8 +-
>  qapi/char.json                        |  31 ++-
>  qemu-options.hx                       |  80 +++++--
>  system/vl.c                           |   4 +-
>  tests/unit/test-char.c                | 323 +++++++++++++++++++++++++-
>  11 files changed, 947 insertions(+), 168 deletions(-)
>  create mode 100644 chardev/char-mux-be.c
>  rename chardev/{char-mux.c => char-mux-fe.c} (71%)
>
> --
> 2.34.1
>
Marc-André Lureau Oct. 31, 2024, 11:34 a.m. UTC | #2
Hi Roman

On Thu, Oct 31, 2024 at 3:12 PM Roman Penyaev <r.peniaev@gmail.com> wrote:

> Hi Marc-André,
>
> In this 5th version of the mux-be series it seems I addressed all the
> comments and concerns. Could you please take a look once again?
>
>
I am not sure adding a "mux-be-id" option to all chardevs is the way to go.
To me it feels like working around the issue that arrays are not supported
on the CLI.

I would like others to comment..



> --
> Roman
>
> On Thu, Oct 17, 2024 at 4:45 PM Roman Penyaev <r.peniaev@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 multiplexing capability of several backend
> > devices, which opens up an opportunity to use a single frontend
> > device on the guest, which can be manipulated from several
> > backend devices.
> >
> > 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 mux-be,id=mux0 \
> >    -chardev
> socket,path=/tmp/sock,server=on,wait=off,id=sock0,mux-be-id=mux0 \
> >    -chardev vc,id=vc0,mux-be-id=mux0 \
> >    -device virtconsole,chardev=mux0 \
> >    -vnc 0.0.0.0:0
> >
> > Which creates two backend devices:
> >
> > * Text virtual console (`vc0`)
> > * A socket (`sock0`) connected to the single virtio hvc console with the
> >   help of the backend multiplexer (`mux0`)
> >
> > `vc0` renders text to an image, which can be shared over the VNC
> protocol.
> > `sock0` is a socket 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
> > multiplexing:
> >
> >    # VNC client
> >    vncviewer :0
> >
> >    # TTY emulator
> >    socat unix-connect:/tmp/sock pty,link=/tmp/pty
> >    tio /tmp/pty
> >
> > 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.peniaev@gmail.com>
> > Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>
> > Cc: qemu-devel@nongnu.org
> >
> > Roman Penyaev (8):
> >   chardev/char: rename `MuxChardev` struct to `MuxFeChardev`
> >   chardev/char: rename `char-mux.c` to `char-mux-fe.c`
> >   chardev/char: move away mux suspend/resume calls
> >   chardev/char: rename frontend mux calls
> >   chardev/char: introduce `mux-be-id=ID` option
> >   chardev/char-mux: implement backend chardev multiplexing
> >   tests/unit/test-char: add unit test for the `mux-be` multiplexer
> >   qemu-options.hx: describe multiplexing of several backend devices
> >
> >  chardev/char-fe.c                     |  25 +-
> >  chardev/char-mux-be.c                 | 290 +++++++++++++++++++++++
> >  chardev/{char-mux.c => char-mux-fe.c} | 157 ++++---------
> >  chardev/char.c                        | 139 +++++++++--
> >  chardev/chardev-internal.h            |  55 ++++-
> >  chardev/meson.build                   |   3 +-
> >  include/chardev/char.h                |   8 +-
> >  qapi/char.json                        |  31 ++-
> >  qemu-options.hx                       |  80 +++++--
> >  system/vl.c                           |   4 +-
> >  tests/unit/test-char.c                | 323 +++++++++++++++++++++++++-
> >  11 files changed, 947 insertions(+), 168 deletions(-)
> >  create mode 100644 chardev/char-mux-be.c
> >  rename chardev/{char-mux.c => char-mux-fe.c} (71%)
> >
> > --
> > 2.34.1
> >
>
>
Roman Penyaev Oct. 31, 2024, 12:10 p.m. UTC | #3
On Thu, Oct 31, 2024 at 12:34 PM Marc-André Lureau
<marcandre.lureau@gmail.com> wrote:
>
> Hi Roman
>
> On Thu, Oct 31, 2024 at 3:12 PM Roman Penyaev <r.peniaev@gmail.com> wrote:
>>
>> Hi Marc-André,
>>
>> In this 5th version of the mux-be series it seems I addressed all the
>> comments and concerns. Could you please take a look once again?
>>
>
> I am not sure adding a "mux-be-id" option to all chardevs is the way to go. To me it feels like working around the issue that arrays are not supported on the CLI.

With CLI it seems not a problem: you can always use the ',,' sequence, or we
can introduce another separator, for example ':'. With JSON I could not find
a working array example, but probably the same trick with any separator in a
string can work as well. What do you think?

> I would like others to comment..

Probably makes sense to ping them once again.

--
Roman