From: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
https://bugzilla.redhat.com/show_bug.cgi?id=1071181
Commit 49b59a15 fixed one problem but masks another one related to pointer
freeing.
Use virAtomicIntGet() to test for 0 rather than trying to test for 'true'
after virAtomicIntDecAndTest().
Avoid putting of the virNWFilterSnoopReq once the thread has been started.
Signed-off-by: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/nwfilter/nwfilter_dhcpsnoop.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c
index d2a8062..32ca304 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -720,7 +720,10 @@ virNWFilterSnoopReqPut(virNWFilterSnoopReqPtr req)
virNWFilterSnoopLock();
- if (virAtomicIntDecAndTest(&req->refctr)) {
+ virAtomicIntDecAndTest(&req->refctr);
+
+ /* make sure it's 0; virAtomitIntDecAndTest may return true on '1' */
+ if (virAtomicIntGet(&req->refctr) == 0) {
/*
* delete the request:
* - if we don't find req on the global list anymore
@@ -1605,6 +1608,7 @@ virNWFilterDHCPSnoopReq(virNWFilterTechDriverPtr techdriver,
int tmp;
virThread thread;
virNWFilterVarValuePtr dhcpsrvrs;
+ bool threadPuts = false;
virNWFilterSnoopIFKeyFMT(ifkey, vmuuid, macaddr);
@@ -1690,6 +1694,8 @@ virNWFilterDHCPSnoopReq(virNWFilterTechDriverPtr techdriver,
/* prevent thread from holding req */
virNWFilterSnoopReqLock(req);
+ threadPuts = true;
+
if (virThreadCreate(&thread, false, virNWFilterDHCPSnoopThread,
req) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1737,7 +1743,8 @@ exit_rem_ifnametokey:
exit_snoopunlock:
virNWFilterSnoopUnlock();
exit_snoopreqput:
- virNWFilterSnoopReqPut(req);
+ if (!threadPuts)
+ virNWFilterSnoopReqPut(req);
return -1;
}
--
1.8.1.4