From nobody Sun May 5 22:14:41 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1526904964605522.152544712012; Mon, 21 May 2018 05:16:04 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2FC86C10EA72; Mon, 21 May 2018 12:16:02 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4A9072708B; Mon, 21 May 2018 12:16:01 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id A633C4BB79; Mon, 21 May 2018 12:15:59 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4LCFuog024890 for ; Mon, 21 May 2018 08:15:56 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4ED602024CC7; Mon, 21 May 2018 12:15:56 +0000 (UTC) Received: from t460.redhat.com (unknown [10.33.36.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 91A482024CBD; Mon, 21 May 2018 12:15:55 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Mon, 21 May 2018 13:15:54 +0100 Message-Id: <20180521121554.11952-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH] nwfilter: directly use poll to wait for packets instead of pcap_next X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 21 May 2018 12:16:03 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 When a QEMU VM shuts down its TAP device gets deleted while nwfilter IP address learning thread is still capturing packets. It is seen that with TPACKET_V3 support in libcap, the pcap_next() call will not always exit its poll() when the NIC is removed. This prevents the learning thread from exiting which blocks the rest of libvirtd waiting on mutex acquisition. By switching to do poll() in libvirt code, we can ensure that we always exit the poll() at a time that is right for libvirt. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: John Ferlan --- src/nwfilter/nwfilter_learnipaddr.c | 37 +++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_le= arnipaddr.c index 061b39d72b..e117be9ce2 100644 --- a/src/nwfilter/nwfilter_learnipaddr.c +++ b/src/nwfilter/nwfilter_learnipaddr.c @@ -31,6 +31,7 @@ =20 #include #include +#include =20 #include #include @@ -414,6 +415,7 @@ learnIPAddressThread(void *arg) bool showError =3D true; enum howDetect howDetected =3D 0; virNWFilterTechDriverPtr techdriver =3D req->techdriver; + struct pollfd fds[1]; =20 if (virNWFilterLockIface(req->ifname) < 0) goto err_no_lock; @@ -435,6 +437,9 @@ learnIPAddressThread(void *arg) goto done; } =20 + fds[0].fd =3D pcap_fileno(handle); + fds[0].events =3D POLLIN | POLLERR; + virMacAddrFormat(&req->macaddr, macaddr); =20 switch (req->howDetect) { @@ -483,17 +488,45 @@ learnIPAddressThread(void *arg) pcap_freecode(&fp); =20 while (req->status =3D=3D 0 && vmaddr =3D=3D 0) { + int n =3D poll(fds, ARRAY_CARDINALITY(fds), PKT_TIMEOUT_MS); + + if (n < 0) { + if (errno =3D=3D EAGAIN || errno =3D=3D EINTR) + continue; + + req->status =3D errno; + showError =3D true; + break; + } + + if (n =3D=3D 0) { + if (threadsTerminate || req->terminate) { + VIR_DEBUG("Terminate request seen, cancelling pcap"); + req->status =3D ECANCELED; + showError =3D false; + break; + } + continue; + } + + if (fds[0].revents & (POLLHUP | POLLERR)) { + VIR_DEBUG("Error from FD probably dev deleted"); + req->status =3D ENODEV; + showError =3D false; + break; + } + packet =3D pcap_next(handle, &header); =20 if (!packet) { - + /* Already handled with poll, but lets be sure */ if (threadsTerminate || req->terminate) { req->status =3D ECANCELED; showError =3D false; break; } =20 - /* check whether VM's dev is still there */ + /* Again, already handled above, but lets be sure */ if (virNetDevValidateConfig(req->ifname, NULL, req->ifindex) <= =3D 0) { virResetLastError(); req->status =3D ENODEV; --=20 2.17.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list