include/chardev/char-fe.h | 13 ++++++++++++- backends/cryptodev-vhost-user.c | 8 +------- backends/rng-egd.c | 8 +------- backends/vhost-user.c | 8 +------- hw/char/imx_serial.c | 4 ++-- 5 files changed, 17 insertions(+), 24 deletions(-)
A number of chardev users where calling qemu_chr_fe_get_driver() which
is discouraged as it blocks backend hotswap. As the pattern is common
and need for the string is transitory add a helper and keep
qemu_chr_fe_get_driver() for those that really need the funkiness of
poking around the backend setup.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
---
include/chardev/char-fe.h | 13 ++++++++++++-
backends/cryptodev-vhost-user.c | 8 +-------
backends/rng-egd.c | 8 +-------
backends/vhost-user.c | 8 +-------
hw/char/imx_serial.c | 4 ++--
5 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
index 5f8a6df17dc..13218d04c8d 100644
--- a/include/chardev/char-fe.h
+++ b/include/chardev/char-fe.h
@@ -52,7 +52,8 @@ void qemu_chr_fe_deinit(CharFrontend *c, bool del);
* associated Chardev.
* Note: avoid this function as the driver should never be accessed directly,
* especially by the frontends that support chardevice hotswap.
- * Consider qemu_chr_fe_backend_connected() to check for driver existence
+ * Consider qemu_chr_fe_backend_connected() to check for driver
+ * existence or qemu_chr_fe_backend_name() if you need the name.
*/
Chardev *qemu_chr_fe_get_driver(CharFrontend *c);
@@ -70,6 +71,16 @@ bool qemu_chr_fe_backend_connected(CharFrontend *c);
*/
bool qemu_chr_fe_backend_open(CharFrontend *c);
+/**
+ * qemu_chr_fe_backend_name:
+ *
+ * Returns: caller freeable string or NULL
+ */
+static inline char * qemu_chr_fe_backend_name(CharFrontend *c)
+{
+ return (c->chr && c->chr->label) ? g_strdup(c->chr->label) : NULL;
+}
+
/**
* qemu_chr_fe_set_handlers_full:
* @c: a CharFrontend
diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index cc478d9902d..3334e280a27 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -373,13 +373,7 @@ cryptodev_vhost_user_get_chardev(Object *obj, Error **errp)
{
CryptoDevBackendVhostUser *s =
CRYPTODEV_BACKEND_VHOST_USER(obj);
- Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
-
- if (chr && chr->label) {
- return g_strdup(chr->label);
- }
-
- return NULL;
+ return qemu_chr_fe_backend_name(&s->chr);
}
static void cryptodev_vhost_user_finalize(Object *obj)
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 1d92bd71cf7..c2207f40c5c 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -126,13 +126,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
static char *rng_egd_get_chardev(Object *obj, Error **errp)
{
RngEgd *s = RNG_EGD(obj);
- Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
-
- if (chr && chr->label) {
- return g_strdup(chr->label);
- }
-
- return NULL;
+ return qemu_chr_fe_backend_name(&s->chr);
}
static void rng_egd_finalize(Object *obj)
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
index 380d8250233..46dadb74800 100644
--- a/backends/vhost-user.c
+++ b/backends/vhost-user.c
@@ -152,13 +152,7 @@ static void set_chardev(Object *obj, const char *value, Error **errp)
static char *get_chardev(Object *obj, Error **errp)
{
VhostUserBackend *b = VHOST_USER_BACKEND(obj);
- Chardev *chr = qemu_chr_fe_get_driver(&b->chr);
-
- if (chr && chr->label) {
- return g_strdup(chr->label);
- }
-
- return NULL;
+ return qemu_chr_fe_backend_name(&b->chr);
}
static void vhost_user_backend_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index fb41ee2ac50..8ac4efbb5e9 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -278,10 +278,10 @@ static void imx_serial_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
IMXSerialState *s = (IMXSerialState *)opaque;
- Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
+ g_autofree char *label = qemu_chr_fe_backend_name(&s->chr);
unsigned char ch;
- trace_imx_serial_write(chr ? chr->label : "NODEV", offset, value);
+ trace_imx_serial_write(label ? label : "NODEV", offset, value);
switch (offset >> 2) {
case 0x10: /* UTXD */
--
2.47.3
On Mon, Aug 10, 2026 at 7:36 PM Alex Bennée <alex.bennee@linaro.org> wrote:
>
> A number of chardev users where calling qemu_chr_fe_get_driver() which
> is discouraged as it blocks backend hotswap. As the pattern is common
> and need for the string is transitory add a helper and keep
> qemu_chr_fe_get_driver() for those that really need the funkiness of
> poking around the backend setup.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/chardev/char-fe.h | 13 ++++++++++++-
> backends/cryptodev-vhost-user.c | 8 +-------
> backends/rng-egd.c | 8 +-------
> backends/vhost-user.c | 8 +-------
> hw/char/imx_serial.c | 4 ++--
> 5 files changed, 17 insertions(+), 24 deletions(-)
>
> diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
> index 5f8a6df17dc..13218d04c8d 100644
> --- a/include/chardev/char-fe.h
> +++ b/include/chardev/char-fe.h
> @@ -52,7 +52,8 @@ void qemu_chr_fe_deinit(CharFrontend *c, bool del);
> * associated Chardev.
> * Note: avoid this function as the driver should never be accessed directly,
> * especially by the frontends that support chardevice hotswap.
> - * Consider qemu_chr_fe_backend_connected() to check for driver existence
> + * Consider qemu_chr_fe_backend_connected() to check for driver
> + * existence or qemu_chr_fe_backend_name() if you need the name.
> */
> Chardev *qemu_chr_fe_get_driver(CharFrontend *c);
>
> @@ -70,6 +71,16 @@ bool qemu_chr_fe_backend_connected(CharFrontend *c);
> */
> bool qemu_chr_fe_backend_open(CharFrontend *c);
>
> +/**
> + * qemu_chr_fe_backend_name:
> + *
> + * Returns: caller freeable string or NULL
> + */
> +static inline char * qemu_chr_fe_backend_name(CharFrontend *c)
> +{
> + return (c->chr && c->chr->label) ? g_strdup(c->chr->label) : NULL;
> +}
> +
> /**
> * qemu_chr_fe_set_handlers_full:
> * @c: a CharFrontend
> diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
> index cc478d9902d..3334e280a27 100644
> --- a/backends/cryptodev-vhost-user.c
> +++ b/backends/cryptodev-vhost-user.c
> @@ -373,13 +373,7 @@ cryptodev_vhost_user_get_chardev(Object *obj, Error **errp)
> {
> CryptoDevBackendVhostUser *s =
> CRYPTODEV_BACKEND_VHOST_USER(obj);
> - Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
> -
> - if (chr && chr->label) {
> - return g_strdup(chr->label);
> - }
> -
> - return NULL;
> + return qemu_chr_fe_backend_name(&s->chr);
> }
>
> static void cryptodev_vhost_user_finalize(Object *obj)
> diff --git a/backends/rng-egd.c b/backends/rng-egd.c
> index 1d92bd71cf7..c2207f40c5c 100644
> --- a/backends/rng-egd.c
> +++ b/backends/rng-egd.c
> @@ -126,13 +126,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
> static char *rng_egd_get_chardev(Object *obj, Error **errp)
> {
> RngEgd *s = RNG_EGD(obj);
> - Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
> -
> - if (chr && chr->label) {
> - return g_strdup(chr->label);
> - }
> -
> - return NULL;
> + return qemu_chr_fe_backend_name(&s->chr);
> }
>
> static void rng_egd_finalize(Object *obj)
> diff --git a/backends/vhost-user.c b/backends/vhost-user.c
> index 380d8250233..46dadb74800 100644
> --- a/backends/vhost-user.c
> +++ b/backends/vhost-user.c
> @@ -152,13 +152,7 @@ static void set_chardev(Object *obj, const char *value, Error **errp)
> static char *get_chardev(Object *obj, Error **errp)
> {
> VhostUserBackend *b = VHOST_USER_BACKEND(obj);
> - Chardev *chr = qemu_chr_fe_get_driver(&b->chr);
> -
> - if (chr && chr->label) {
> - return g_strdup(chr->label);
> - }
> -
> - return NULL;
> + return qemu_chr_fe_backend_name(&b->chr);
> }
>
> static void vhost_user_backend_class_init(ObjectClass *oc, const void *data)
> diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
> index fb41ee2ac50..8ac4efbb5e9 100644
> --- a/hw/char/imx_serial.c
> +++ b/hw/char/imx_serial.c
> @@ -278,10 +278,10 @@ static void imx_serial_write(void *opaque, hwaddr offset,
> uint64_t value, unsigned size)
> {
> IMXSerialState *s = (IMXSerialState *)opaque;
> - Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
> + g_autofree char *label = qemu_chr_fe_backend_name(&s->chr);
> unsigned char ch;
>
> - trace_imx_serial_write(chr ? chr->label : "NODEV", offset, value);
> + trace_imx_serial_write(label ? label : "NODEV", offset, value);
>
> switch (offset >> 2) {
> case 0x10: /* UTXD */
> --
> 2.47.3
>
>
On 10/8/26 17:35, Alex Bennée wrote:
> A number of chardev users where calling qemu_chr_fe_get_driver() which
> is discouraged as it blocks backend hotswap. As the pattern is common
> and need for the string is transitory add a helper and keep
> qemu_chr_fe_get_driver() for those that really need the funkiness of
> poking around the backend setup.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> include/chardev/char-fe.h | 13 ++++++++++++-
> backends/cryptodev-vhost-user.c | 8 +-------
> backends/rng-egd.c | 8 +-------
> backends/vhost-user.c | 8 +-------
> hw/char/imx_serial.c | 4 ++--
> 5 files changed, 17 insertions(+), 24 deletions(-)
>
> diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
> index 5f8a6df17dc..13218d04c8d 100644
> --- a/include/chardev/char-fe.h
> +++ b/include/chardev/char-fe.h
> @@ -52,7 +52,8 @@ void qemu_chr_fe_deinit(CharFrontend *c, bool del);
> * associated Chardev.
> * Note: avoid this function as the driver should never be accessed directly,
> * especially by the frontends that support chardevice hotswap.
> - * Consider qemu_chr_fe_backend_connected() to check for driver existence
> + * Consider qemu_chr_fe_backend_connected() to check for driver
> + * existence or qemu_chr_fe_backend_name() if you need the name.
> */
> Chardev *qemu_chr_fe_get_driver(CharFrontend *c);
>
> @@ -70,6 +71,16 @@ bool qemu_chr_fe_backend_connected(CharFrontend *c);
> */
> bool qemu_chr_fe_backend_open(CharFrontend *c);
>
> +/**
> + * qemu_chr_fe_backend_name:
> + *
> + * Returns: caller freeable string or NULL
> + */
> +static inline char * qemu_chr_fe_backend_name(CharFrontend *c)
> +{
> + return (c->chr && c->chr->label) ? g_strdup(c->chr->label) : NULL;
> +}
This looks like a safe setter for the "chardev" ObjectProperty.
Maybe we could go one step further and unify adding a
object_class_property_add_chardev() helper?
© 2016 - 2026 Red Hat, Inc.