From 0041eda1e498976bcbde26de6df7366d26862162 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Thu, 23 Aug 2018 11:49:32 +0300 Subject: [PATCH] util: eventpoll: Survive EBADF on macOS Fixes: https://www.redhat.com/archives/libvir-list/2017-January/msg00978.html QEMU is probed through monitor fd to check capabilities during libvirtd init. The monitor fd is closed after probing by virQEMUCapsInitQMPCommandFree that calls virQEMUCapsInitQMPCommandAbort that calls qemuMonitorClose, the latter one notifies the event loop via an interrupt handle in qemuMonitorUnregister and after then closes monitor fd. There could be a case when interrupt is sent after eventLoop is unlocked but before virEventPollRunOnce blocks in poll, shortly before file descriptor is closed by qemuMonitorClose. Then poll receives closed monitor fd in fdset and returns EBADF. EBADF is not mentioned as a valid errno on macOS poll man-page but such behaviour can appear release-to-release, according to cpython: https://github.com/python/cpython/blob/master/Modules/selectmodule.c#L1161 The change also fixes the issue in qemucapabilitiestest. It returns Bad file descriptor message 25 times without the fix. Signed-off-by: Roman Bolshakov Signed-off-by: Michal Privoznik --- src/util/vireventpoll.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c index 13d278df13..2fe58c7c12 100644 --- a/src/util/vireventpoll.c +++ b/src/util/vireventpoll.c @@ -643,6 +643,12 @@ int virEventPollRunOnce(void) EVENT_DEBUG("Poll got error event %d", errno); if (errno == EINTR || errno == EAGAIN) goto retry; +#ifdef __APPLE__ + if (errno == EBADF) { + virMutexLock(&eventLoop.lock); + goto cleanup; + } +#endif virReportSystemError(errno, "%s", _("Unable to poll on file handles")); return -1; @@ -660,6 +666,9 @@ int virEventPollRunOnce(void) virEventPollCleanupTimeouts(); virEventPollCleanupHandles(); +#ifdef __APPLE__ + cleanup: +#endif eventLoop.running = 0; virMutexUnlock(&eventLoop.lock); return 0;