54 lines
2.4 KiB
Diff
54 lines
2.4 KiB
Diff
|
|
From c8f5445399e057a8974a77a882be502dba605301 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Christian Ehrhardt <christian.ehrhardt@canonical.com>
|
||
|
|
Date: Thu, 10 Nov 2022 10:36:28 +0100
|
||
|
|
Subject: [PATCH] nodedev: ignore EINVAL from libudev in udevEventHandleThread
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
Certain udev entries might be of a size that makes libudev emit EINVAL
|
||
|
|
which right now leads to udevEventHandleThread exiting. Due to no more
|
||
|
|
handling events other elements of libvirt will start pushing for events
|
||
|
|
to be consumed which never happens causing a busy loop burning a cpu
|
||
|
|
without any gain.
|
||
|
|
|
||
|
|
After evaluation of the example case discussed in in #245 and a test
|
||
|
|
run ignoring EINVAL it was considered safe to add EINVAL to the ignored
|
||
|
|
errnos to not exit udevEventHandleThread giving it more resilience.
|
||
|
|
|
||
|
|
The root cause is in systemd and by now was discussed and fixed via
|
||
|
|
https://github.com/systemd/systemd/issues/24987, but hardening libvirt
|
||
|
|
to be able to better deal with EINVAL returned still is the right thing
|
||
|
|
to avoid the reported busy loops on systemd with older systemd versions.
|
||
|
|
|
||
|
|
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/245
|
||
|
|
|
||
|
|
Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
|
||
|
|
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
|
---
|
||
|
|
src/node_device/node_device_udev.c | 6 ++++--
|
||
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
|
||
|
|
index a674380f19..0d8a7db5c6 100644
|
||
|
|
--- a/src/node_device/node_device_udev.c
|
||
|
|
+++ b/src/node_device/node_device_udev.c
|
||
|
|
@@ -1594,10 +1594,12 @@ udevEventHandleThread(void *opaque G_GNUC_UNUSED)
|
||
|
|
}
|
||
|
|
|
||
|
|
/* POSIX allows both EAGAIN and EWOULDBLOCK to be used
|
||
|
|
- * interchangeably when the read would block or timeout was fired
|
||
|
|
+ * interchangeably when the read would block or timeout was fired.
|
||
|
|
+ * EINVAL might happen on too large udev entries, ignore those for
|
||
|
|
+ * the robustness of udevEventHandleThread.
|
||
|
|
*/
|
||
|
|
VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR
|
||
|
|
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||
|
|
+ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINVAL) {
|
||
|
|
VIR_WARNINGS_RESET
|
||
|
|
virReportSystemError(errno, "%s",
|
||
|
|
_("failed to receive device from udev "
|
||
|
|
--
|
||
|
|
2.25.1
|
||
|
|
|