From 49825dcf31e858e88525db3f31d73a4780c9a64b Mon Sep 17 00:00:00 2001 From: Nikolay Shirokovskiy Date: Fri, 12 Oct 2018 10:23:07 +0300 Subject: [PATCH] nwfilter: Fix learning address thread shutdown If the learning thread is configured to learn on all ethernet frames (which is hardcoded) then chances are high that there is a packet on every iteration of inspecting frames loop. As result we will hang on shutdown because we don't check threadsTerminate if there is packet. Let's just check termination conditions on every iteration. Since we'll check each iteration, the check after pcap_next essentially is unnecessary since on failure we'd loop back to the top and timeout and then fail. Signed-off-by: Nikolay Shirokovskiy Reviewed-by: John Ferlan --- src/nwfilter/nwfilter_learnipaddr.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c index 008c24bc14..e6cb9964ac 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -483,6 +483,12 @@ learnIPAddressThread(void *arg) while (req->status == 0 && vmaddr == 0) { int n = poll(fds, ARRAY_CARDINALITY(fds), PKT_TIMEOUT_MS); + if (threadsTerminate || req->terminate) { + req->status = ECANCELED; + showError = false; + break; + } + if (n < 0) { if (errno == EAGAIN || errno == EINTR) continue; @@ -492,15 +498,8 @@ learnIPAddressThread(void *arg) break; } - if (n == 0) { - if (threadsTerminate || req->terminate) { - VIR_DEBUG("Terminate request seen, cancelling pcap"); - req->status = ECANCELED; - showError = false; - break; - } + if (n == 0) continue; - } if (fds[0].revents & (POLLHUP | POLLERR)) { VIR_DEBUG("Error from FD probably dev deleted"); @@ -512,13 +511,6 @@ learnIPAddressThread(void *arg) packet = pcap_next(handle, &header); if (!packet) { - /* Already handled with poll, but lets be sure */ - if (threadsTerminate || req->terminate) { - req->status = ECANCELED; - showError = false; - break; - } - /* Again, already handled above, but lets be sure */ if (virNetDevValidateConfig(req->binding->portdevname, NULL, req->ifindex) <= 0) { virResetLastError(); -- 2.47.2