File 2703b0b5-qemu-dont-report-eof.patch of Package libvirt
xxxxxxxxxx
1
commit 2703b0b5bf2751d523a4d8d61901e473c92ba198
2
Author: Jim Fehlig <jfehlig@suse.com>
3
Date: Tue Oct 5 22:23:51 2021 -0600
4
5
qemu: Do not report eof when processing monitor IO
6
7
There have been countless reports from users concerned about the following
8
error reported by libvirtd when qemu domains are shutdown
9
10
internal error: End of file from qemu monitor
11
12
While the error is harmless, users often mistaken it for real problem with
13
their deployments. EOF from the monitor can't be entirely ignored since
14
other threads may be using the monitor and must be able to detect the EOF
15
condition.
16
17
One potential fix is to delay reporting EOF until the monitor is used
18
after EOF is detected. This patch adds a 'goteof' member to the
19
qemuMonitor structure, which is set when EOF is detected on the monitor
20
socket. If another thread later tries to send data on the monitor, the
21
EOF error is reported.
22
23
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
24
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
25
26
Index: libvirt-7.1.0/src/qemu/qemu_monitor.c
27
===================================================================
28
--- libvirt-7.1.0.orig/src/qemu/qemu_monitor.c
29
+++ libvirt-7.1.0/src/qemu/qemu_monitor.c
30
31
* the next monitor msg */
32
virError lastError;
33
34
+ /* Set to true when EOF is detected on the monitor */
35
+ bool goteof;
36
+
37
int nextSerial;
38
39
bool waitGreeting;
40
41
{
42
qemuMonitorPtr mon = opaque;
43
bool error = false;
44
- bool eof = false;
45
bool hangup = false;
46
47
virObjectRef(mon);
48
49
50
if (mon->lastError.code != VIR_ERR_OK) {
51
if (cond & (G_IO_HUP | G_IO_ERR))
52
- eof = true;
53
+ mon->goteof = true;
54
error = true;
55
} else {
56
if (cond & G_IO_OUT) {
57
58
if (errno == ECONNRESET)
59
hangup = true;
60
} else if (got == 0) {
61
- eof = true;
62
+ mon->goteof = true;
63
} else {
64
/* Ignore hangup/error cond if we read some data, to
65
* give time for that data to be consumed */
66
67
68
if (cond & G_IO_HUP) {
69
hangup = true;
70
- if (!error) {
71
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
72
- _("End of file from qemu monitor"));
73
- eof = true;
74
- }
75
+ if (!error)
76
+ mon->goteof = true;
77
}
78
79
- if (!error && !eof &&
80
+ if (!error && !mon->goteof &&
81
cond & G_IO_ERR) {
82
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
83
_("Invalid file descriptor while waiting for monitor"));
84
- eof = true;
85
+ mon->goteof = true;
86
}
87
}
88
89
- if (error || eof) {
90
+ if (error || mon->goteof) {
91
if (hangup && mon->logFunc != NULL) {
92
/* Check if an error message from qemu is available and if so, use
93
* it to overwrite the actual message. It's done only in early
94
95
/* Already have an error, so clear any new error */
96
virResetLastError();
97
} else {
98
- if (virGetLastErrorCode() == VIR_ERR_OK)
99
+ if (virGetLastErrorCode() == VIR_ERR_OK && !mon->goteof)
100
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
101
_("Error while processing monitor IO"));
102
virCopyLastError(&mon->lastError);
103
104
/* We have to unlock to avoid deadlock against command thread,
105
* but is this safe ? I think it is, because the callback
106
* will try to acquire the virDomainObjPtr mutex next */
107
- if (eof) {
108
+ if (mon->goteof) {
109
qemuMonitorEofNotifyCallback eofNotify = mon->cb->eofNotify;
110
virDomainObjPtr vm = mon->vm;
111
112
113
virSetError(&mon->lastError);
114
return -1;
115
}
116
+ if (mon->goteof) {
117
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
118
+ _("End of file from qemu monitor"));
119
+ return -1;
120
+ }
121
122
mon->msg = msg;
123
qemuMonitorUpdateWatch(mon);
124