mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
chardev/char-hub: implement backend chardev aggregator
This patch 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 idea of the change is trivial: keep list of backend devices (up to 4), init them on demand and forward data buffer back and forth. The following is QEMU command line example: -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 2 backend devices: text virtual console (`vc0`) and a pseudo TTY (`pty0`) connected to the single virtio hvc console with the backend aggregator (`hub0`) help. `vc0` renders text to an image, which can be shared over the VNC protocol. `pty0` is a pseudo TTY backend which provides biderectional communication to the virtio hvc console. '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. Signed-off-by: Roman Penyaev <r.peniaev@gmail.com> Reviewed-by: "Marc-André Lureau" <marcandre.lureau@redhat.com> Cc: qemu-devel@nongnu.org Message-ID: <20250123085327.965501-3-r.peniaev@gmail.com>
This commit is contained in:
parent
4e059a9d96
commit
b66ed23238
6 changed files with 401 additions and 3 deletions
|
@ -29,13 +29,16 @@
|
|||
#include "chardev/char-fe.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define MAX_HUB 4
|
||||
#define MAX_MUX 4
|
||||
#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
|
||||
#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
|
||||
|
||||
struct MuxChardev {
|
||||
Chardev parent;
|
||||
/* Linked frontends */
|
||||
CharBackend *backends[MAX_MUX];
|
||||
/* Linked backend */
|
||||
CharBackend chr;
|
||||
unsigned long mux_bitset;
|
||||
int focus;
|
||||
|
@ -53,11 +56,57 @@ struct MuxChardev {
|
|||
int64_t timestamps_start;
|
||||
};
|
||||
typedef struct MuxChardev MuxChardev;
|
||||
typedef struct HubChardev HubChardev;
|
||||
typedef struct HubCharBackend HubCharBackend;
|
||||
|
||||
/*
|
||||
* Back-pointer on a hub, actual backend and its index in
|
||||
* `hub->backends` array
|
||||
*/
|
||||
struct HubCharBackend {
|
||||
HubChardev *hub;
|
||||
CharBackend be;
|
||||
unsigned int be_ind;
|
||||
};
|
||||
|
||||
struct HubChardev {
|
||||
Chardev parent;
|
||||
/* Linked backends */
|
||||
HubCharBackend backends[MAX_HUB];
|
||||
/*
|
||||
* Number of backends attached to this hub. Once attached, a
|
||||
* backend can't be detached, so the counter is only increasing.
|
||||
* To safely remove a backend, hub has to be removed first.
|
||||
*/
|
||||
unsigned int be_cnt;
|
||||
/*
|
||||
* Number of CHR_EVEN_OPENED events from all backends. Needed to
|
||||
* send CHR_EVEN_CLOSED only when counter goes to zero.
|
||||
*/
|
||||
unsigned int be_event_opened_cnt;
|
||||
/*
|
||||
* Counters of written bytes from a single frontend device
|
||||
* to multiple backend devices.
|
||||
*/
|
||||
unsigned int be_written[MAX_HUB];
|
||||
unsigned int be_min_written;
|
||||
/*
|
||||
* Index of a backend device which got EAGAIN on last write,
|
||||
* -1 is invalid index.
|
||||
*/
|
||||
int be_eagain_ind;
|
||||
};
|
||||
typedef struct HubChardev HubChardev;
|
||||
|
||||
DECLARE_INSTANCE_CHECKER(MuxChardev, MUX_CHARDEV,
|
||||
TYPE_CHARDEV_MUX)
|
||||
#define CHARDEV_IS_MUX(chr) \
|
||||
DECLARE_INSTANCE_CHECKER(HubChardev, HUB_CHARDEV,
|
||||
TYPE_CHARDEV_HUB)
|
||||
|
||||
#define CHARDEV_IS_MUX(chr) \
|
||||
object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_MUX)
|
||||
#define CHARDEV_IS_HUB(chr) \
|
||||
object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_HUB)
|
||||
|
||||
bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b,
|
||||
unsigned int *tag, Error **errp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue