RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1080376 - Pass close from qemu-ga
Summary: Pass close from qemu-ga
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: qemu-kvm
Version: 6.6
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Laszlo Ersek
QA Contact: Virtualization Bugs
URL:
Whiteboard:
Depends On: 970161
Blocks: 892079 896690 1028927 1112686
TreeView+ depends on / blocked
 
Reported: 2014-03-25 09:59 UTC by Michal Privoznik
Modified: 2015-01-08 14:30 UTC (History)
20 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of: 890648
: 1122151 (view as bug list)
Environment:
Last Closed: 2015-01-08 14:29:04 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Michal Privoznik 2014-03-25 09:59:10 UTC
+++ This bug was initially created as a clone of Bug #890648 +++

Description of problem:

--- Additional comment from Michal Privoznik on 2014-03-25 10:41:21 CET ---

(In reply to zhenfeng wang from comment #11)
> # virsh restore /tmp/rhel65.save 
> Domain restored from /tmp/rhel65.save
> 
> # virsh dompmsuspend rhel65 --target mem
> ^C                                                                <======hung here.
> 
> # virsh save rhel65 /tmp/rhel65.save 
> error: Failed to save domain rhel65 to /tmp/rhel65.save
> error: Timed out during operation: cannot acquire state change lock
> 

In order to fix this bug libvirt needs to know if the qemu-ga is listening or not. Currently, we do something which is not bulletproof: prior to executing any real command that may change guest's state (e.g. dompmsuspend), libvirt pings the guest agent. If it replies, we know it's listening and then issue the real command. However, qemu-ga may be stopped meanwhile (e.g. be killed) resulting in libvirt being stuck on the domain (libvirt serializes status changing calls on a domain).

Long story short, libvirt (or any other client listening on a unix channel) doesn't know whether there's somebody listening within the guest or not. We should learn qemu to not buffer channels or learn the buffering code to pass EOF/close() from qemu-ga to client connected to the unix channel.

Comment 2 Laszlo Ersek 2014-04-17 08:04:01 UTC
Michal, is what you want basically that an EOF be reported on the host-side end of the virtio-serial port (ie. read() == 0) when the last guest-side process that keeps it open exits? Because if so, that sounds to me like a kernel BZ.

Comment 3 Laszlo Ersek 2014-04-17 08:08:32 UTC
... and/or a qemu chardev change. That sounds quite horrible to me; I'm not a chardev expert. Maybe Amit or Gerd could help?...

Comment 5 Gerd Hoffmann 2014-04-17 10:31:25 UTC
We have open/close inside qemu for chardevs, so qemu knows whenever someone is listening inside the guest.  So I think it boils down to how communicate that to libvirt.

We could add the info to query-chardev and send qmp events on open/close, I suspect that is the only way to make it work in general.

For some chardev types we can try use the data channel directly, for example by using out-of-band messages on unix/tcp sockets.

Comment 6 Michal Privoznik 2014-04-28 07:36:12 UTC
(In reply to Laszlo Ersek from comment #2)
> Michal, is what you want basically that an EOF be reported on the host-side
> end of the virtio-serial port (ie. read() == 0) when the last guest-side
> process that keeps it open exits? Because if so, that sounds to me like a
> kernel BZ.

Yes, that's what I'm trying to achieve. Libvirt allows some API execution depending on qemu-ga being set up and listening within the guest (virDomainFSTrim being an example). However, as described in the description, it may happen that the API will hang up indefinitely - i.e. if the guest agent sigsegvs meanwhile. So it would be really great if libvirt could see EOF on the host side of the virtio-serial port. Because then libvirt can undertake some actions.

Comment 7 Laszlo Ersek 2014-04-28 14:44:35 UTC
I'm not sure what would be easier / cleaner to do in qemu, while keeping the chardev infrastructure general:
- keep the host side (unix) fd and the guest-side (virtio-serial) fd in tight correspondence (EOF seen on the host-side end of virtio-serial would cause qemu to close its server side of the unix domain socket, making libvirt read EOF)
- emit an event at guest-initiated closure (Gerd's comment 5)

This thing should be redetectable for libvirt. For example, if libvirt is restarted, the new instance won't get a new event from qemu. The new instance of libvirt should somehow immediately see that the agent is not connected, eg. by getting ECONNREFUSED when connecting to the unix domain socket.

I'm not sure if qemu can close() and then re-run socket()+bind()+listen()+accept() on the unix domain socket *in sync* with what it sees on the host-side of the virtio-serial port.

Comment 8 Amit Shah 2014-05-02 07:23:26 UTC
virtio-console gets notification when the guest-side port is opened or closed:

/* Callback function that's called when the guest opens/closes the port */
static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)


An event can be exposed for libvirt so libvirt knows too.  Also, 'info qtree' mentions 'guest off' if the guest is not connected; a restarted libvirt could check that (albeit it's a hacky way; there's no standard way of reporting that).

Comment 9 Laszlo Ersek 2014-05-29 19:37:52 UTC
Upstream v1 posted:
http://thread.gmane.org/gmane.comp.emulators.qemu/276342

Comment 10 Laszlo Ersek 2014-06-26 11:13:22 UTC
Posted upstream v2:
http://thread.gmane.org/gmane.comp.emulators.qemu/283238

Comment 11 Laszlo Ersek 2014-06-26 16:11:34 UTC
Posted upstream v3:
http://lists.nongnu.org/archive/html/qemu-devel/2014-06/msg06560.html

Comment 12 Laszlo Ersek 2014-07-02 13:10:59 UTC
Now upstream:

1  e2ae615 virtio-serial: report frontend connection state via monitor
2  32a97ea char: report frontend open/closed state in 'query-chardev'

Comment 20 Ademar Reis 2015-01-08 14:29:04 UTC
Laszlo did some analysis and the backport of this feature is too risky for RHEL6. Customers who need this feature are advised to move to RHEL7.


Note You need to log in before you can comment on or make changes to this bug.