All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RFC: chardev: disconnect backend when frontend closes
@ 2026-10-01 10:34 marcandre.lureau
  2026-11-01  8:30 ` Marc-André Lureau
  2026-11-02 10:09 ` Daniel P. Berrangé
  0 siblings, 2 replies; 4+ messages in thread
From: marcandre.lureau @ 2026-10-01 10:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, Marc-André Lureau, Paolo Bonzini

From: Marc-André Lureau <marcandre.lureau@redhat.com>

When the guest closes a virtio-serial channel, QEMU notifies some
backends (spice, dbus) via their chr_set_fe_open handlers. Backends
without such a handler, like socket, keep the connection open even
though the frontend is no longer active. This is problematic for
stateful protocols, as the peer has no way to know the channel was
reset and must handle re-synchronization on its own. Disconnecting
gives the peer a clean signal to reset its state.

Add a base-class chr_set_fe_open handler that calls chr_disconnect
when the frontend signals close. Subclasses that already override
chr_set_fe_open are unaffected. For the socket backend, this tears
down the connection and allows reconnection when combined with the
reconnect option.

Note: this is a behavior change that may break existing setups that
rely on the connection staying up across frontend close/reopen cycles.
It may be preferable to make this opt-in via a chardev property rather
than changing the default.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 chardev/char.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/chardev/char.c b/chardev/char.c
index 7daf87f0363e..58c69db7340e 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -331,12 +331,22 @@ static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
     return len;
 }
 
+static void chr_set_fe_open(Chardev *chr, int fe_open)
+{
+    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
+
+    if (!fe_open && cc->chr_disconnect) {
+        cc->chr_disconnect(chr);
+    }
+}
+
 static void char_class_init(ObjectClass *oc, const void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
 
     cc->chr_write = null_chr_write;
     cc->chr_be_event = chr_be_event;
+    cc->chr_set_fe_open = chr_set_fe_open;
 }
 
 static void char_finalize(Object *obj)
-- 
2.56.0.rc0.29.g47ce80527c56



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] RFC: chardev: disconnect backend when frontend closes
  2026-10-01 10:34 [PATCH] RFC: chardev: disconnect backend when frontend closes marcandre.lureau
@ 2026-11-01  8:30 ` Marc-André Lureau
  2026-11-02 10:09 ` Daniel P. Berrangé
  1 sibling, 0 replies; 4+ messages in thread
From: Marc-André Lureau @ 2026-11-01  8:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, Paolo Bonzini

Hi

On Thu, Oct 1, 2026 at 2:35 PM <marcandre.lureau@redhat.com> wrote:
>
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> When the guest closes a virtio-serial channel, QEMU notifies some
> backends (spice, dbus) via their chr_set_fe_open handlers. Backends
> without such a handler, like socket, keep the connection open even
> though the frontend is no longer active. This is problematic for
> stateful protocols, as the peer has no way to know the channel was
> reset and must handle re-synchronization on its own. Disconnecting
> gives the peer a clean signal to reset its state.
>
> Add a base-class chr_set_fe_open handler that calls chr_disconnect
> when the frontend signals close. Subclasses that already override
> chr_set_fe_open are unaffected. For the socket backend, this tears
> down the connection and allows reconnection when combined with the
> reconnect option.
>
> Note: this is a behavior change that may break existing setups that
> rely on the connection staying up across frontend close/reopen cycles.
> It may be preferable to make this opt-in via a chardev property rather
> than changing the default.

ping

>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  chardev/char.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/chardev/char.c b/chardev/char.c
> index 7daf87f0363e..58c69db7340e 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -331,12 +331,22 @@ static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
>      return len;
>  }
>
> +static void chr_set_fe_open(Chardev *chr, int fe_open)
> +{
> +    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
> +
> +    if (!fe_open && cc->chr_disconnect) {
> +        cc->chr_disconnect(chr);
> +    }
> +}
> +
>  static void char_class_init(ObjectClass *oc, const void *data)
>  {
>      ChardevClass *cc = CHARDEV_CLASS(oc);
>
>      cc->chr_write = null_chr_write;
>      cc->chr_be_event = chr_be_event;
> +    cc->chr_set_fe_open = chr_set_fe_open;
>  }
>
>  static void char_finalize(Object *obj)
> --
> 2.56.0.rc0.29.g47ce80527c56
>
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] RFC: chardev: disconnect backend when frontend closes
  2026-10-01 10:34 [PATCH] RFC: chardev: disconnect backend when frontend closes marcandre.lureau
  2026-11-01  8:30 ` Marc-André Lureau
@ 2026-11-02 10:09 ` Daniel P. Berrangé
  2026-11-02 13:29   ` Marc-André Lureau
  1 sibling, 1 reply; 4+ messages in thread
From: Daniel P. Berrangé @ 2026-11-02 10:09 UTC (permalink / raw)
  To: marcandre.lureau; +Cc: qemu-devel, Paolo Bonzini

On Thu, Oct 01, 2026 at 02:34:12PM +0400, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> When the guest closes a virtio-serial channel, QEMU notifies some
> backends (spice, dbus) via their chr_set_fe_open handlers. Backends
> without such a handler, like socket, keep the connection open even
> though the frontend is no longer active. This is problematic for
> stateful protocols, as the peer has no way to know the channel was
> reset and must handle re-synchronization on its own. Disconnecting
> gives the peer a clean signal to reset its state.

Do you have a real world example of where this was causing a
problem ?

> Add a base-class chr_set_fe_open handler that calls chr_disconnect
> when the frontend signals close. Subclasses that already override
> chr_set_fe_open are unaffected. For the socket backend, this tears
> down the connection and allows reconnection when combined with the
> reconnect option.
> 
> Note: this is a behavior change that may break existing setups that
> rely on the connection staying up across frontend close/reopen cycles.

IIUC, libvirt expects the agent TCP socket to remain open for
the lifetime of the QEMU process & any premature closure of that
socket would be considered a bug.

> It may be preferable to make this opt-in via a chardev property rather
> than changing the default.

If we want this feature, making it opt-in looks unavoidable.

> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  chardev/char.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/chardev/char.c b/chardev/char.c
> index 7daf87f0363e..58c69db7340e 100644
> --- a/chardev/char.c
> +++ b/chardev/char.c
> @@ -331,12 +331,22 @@ static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
>      return len;
>  }
>  
> +static void chr_set_fe_open(Chardev *chr, int fe_open)
> +{
> +    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
> +
> +    if (!fe_open && cc->chr_disconnect) {
> +        cc->chr_disconnect(chr);
> +    }
> +}
> +
>  static void char_class_init(ObjectClass *oc, const void *data)
>  {
>      ChardevClass *cc = CHARDEV_CLASS(oc);
>  
>      cc->chr_write = null_chr_write;
>      cc->chr_be_event = chr_be_event;
> +    cc->chr_set_fe_open = chr_set_fe_open;
>  }
>  
>  static void char_finalize(Object *obj)
> -- 
> 2.56.0.rc0.29.g47ce80527c56
> 

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] RFC: chardev: disconnect backend when frontend closes
  2026-11-02 10:09 ` Daniel P. Berrangé
@ 2026-11-02 13:29   ` Marc-André Lureau
  0 siblings, 0 replies; 4+ messages in thread
From: Marc-André Lureau @ 2026-11-02 13:29 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel, Paolo Bonzini

Hi

On Mon, Nov 2, 2026 at 2:09 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Thu, Oct 01, 2026 at 02:34:12PM +0400, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > When the guest closes a virtio-serial channel, QEMU notifies some
> > backends (spice, dbus) via their chr_set_fe_open handlers. Backends
> > without such a handler, like socket, keep the connection open even
> > though the frontend is no longer active. This is problematic for
> > stateful protocols, as the peer has no way to know the channel was
> > reset and must handle re-synchronization on its own. Disconnecting
> > gives the peer a clean signal to reset its state.
>
> Do you have a real world example of where this was causing a
> problem ?

I wrote a tool that speaks HTTP over virtio-serial. Unfortunately,
closing the socket/handle on the guest doesn't disconnect the host
client as I expected..

>
> > Add a base-class chr_set_fe_open handler that calls chr_disconnect
> > when the frontend signals close. Subclasses that already override
> > chr_set_fe_open are unaffected. For the socket backend, this tears
> > down the connection and allows reconnection when combined with the
> > reconnect option.
> >
> > Note: this is a behavior change that may break existing setups that
> > rely on the connection staying up across frontend close/reopen cycles.
>
> IIUC, libvirt expects the agent TCP socket to remain open for
> the lifetime of the QEMU process & any premature closure of that
> socket would be considered a bug.

So libvirt has to rely on out-of-band signals to know that the guest
agent disconnected... sigh

>
> > It may be preferable to make this opt-in via a chardev property rather
> > than changing the default.
>
> If we want this feature, making it opt-in looks unavoidable.

I guess that's the easy path indeed - probably a tad late for 11.2

> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> >  chardev/char.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/chardev/char.c b/chardev/char.c
> > index 7daf87f0363e..58c69db7340e 100644
> > --- a/chardev/char.c
> > +++ b/chardev/char.c
> > @@ -331,12 +331,22 @@ static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
> >      return len;
> >  }
> >
> > +static void chr_set_fe_open(Chardev *chr, int fe_open)
> > +{
> > +    ChardevClass *cc = CHARDEV_GET_CLASS(chr);
> > +
> > +    if (!fe_open && cc->chr_disconnect) {
> > +        cc->chr_disconnect(chr);
> > +    }
> > +}
> > +
> >  static void char_class_init(ObjectClass *oc, const void *data)
> >  {
> >      ChardevClass *cc = CHARDEV_CLASS(oc);
> >
> >      cc->chr_write = null_chr_write;
> >      cc->chr_be_event = chr_be_event;
> > +    cc->chr_set_fe_open = chr_set_fe_open;
> >  }
> >
> >  static void char_finalize(Object *obj)
> > --
> > 2.56.0.rc0.29.g47ce80527c56
> >
>
> With regards,
> Daniel
> --
> |: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
> |: https://libvirt.org          ~~          https://entangle-photo.org :|
> |: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|
>



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-02 13:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-01 10:34 [PATCH] RFC: chardev: disconnect backend when frontend closes marcandre.lureau
2026-11-01  8:30 ` Marc-André Lureau
2026-11-02 10:09 ` Daniel P. Berrangé
2026-11-02 13:29   ` Marc-André Lureau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.