/*
* Note about lock-order:
* 1st: virNWFilterSnoopState.snoopLock
- * 2nd: virNWFilterSnoopReqLock(req)
+ * 2nd: &req->lock
*
* Rationale: Former protects the SnoopReqs hash, latter its contents
*/
bool update_leasefile,
bool instantiate);
-static void virNWFilterSnoopReqLock(virNWFilterSnoopReq *req);
-static void virNWFilterSnoopReqUnlock(virNWFilterSnoopReq *req);
-
static void virNWFilterSnoopLeaseFileLoad(void);
static void virNWFilterSnoopLeaseFileSave(virNWFilterSnoopIPLease *ipl);
virNWFilterSnoopReq *req = plnew->snoopReq;
/* protect req->start / req->end */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
virNWFilterSnoopListAdd(plnew, &req->start, &req->end);
-
- virNWFilterSnoopReqUnlock(req);
}
/*
virNWFilterSnoopReq *req = ipl->snoopReq;
/* protect req->start / req->end */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
virNWFilterSnoopListDel(ipl, &req->start, &req->end);
-
- virNWFilterSnoopReqUnlock(req);
-
ipl->timeout = 0;
}
bool instantiate)
{
g_autofree char *ipaddr = virSocketAddrFormat(&ipl->ipAddress);
- int rc = -1;
- virNWFilterSnoopReq *req;
+ virNWFilterSnoopReq *req = ipl->snoopReq;
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
if (!ipaddr)
return -1;
- req = ipl->snoopReq;
-
- /* protect req->binding->portdevname */
- virNWFilterSnoopReqLock(req);
-
if (virNWFilterIPAddrMapAddIPAddr(req->binding->portdevname, ipaddr) < 0)
- goto cleanup;
+ return -1;
- if (!instantiate) {
- rc = 0;
- goto cleanup;
- }
+ if (!instantiate)
+ return 0;
/* instantiate the filters */
- if (req->binding->portdevname) {
- rc = virNWFilterInstantiateFilterLate(req->driver,
- req->binding,
- req->ifindex);
- }
+ if (!req->binding->portdevname)
+ return -1;
- cleanup:
- virNWFilterSnoopReqUnlock(req);
- return rc;
+ return virNWFilterInstantiateFilterLate(req->driver, req->binding, req->ifindex);
}
/*
bool is_last = false;
/* protect req->start */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
while (req->start && req->start->timeout <= now) {
if (req->start->next == NULL ||
is_last);
}
- virNWFilterSnoopReqUnlock(req);
-
return 0;
}
g_free(req);
}
-/*
- * Lock a Snoop request 'req'
- */
-static void
-virNWFilterSnoopReqLock(virNWFilterSnoopReq *req)
-{
- virMutexLock(&req->lock);
-}
-
-/*
- * Unlock a Snoop request 'req'
- */
-static void
-virNWFilterSnoopReqUnlock(virNWFilterSnoopReq *req)
-{
- virMutexUnlock(&req->lock);
-}
-
/*
* virNWFilterSnoopReqRelease - hash table free function to kill a request
*/
return;
/* protect req->threadkey */
- virNWFilterSnoopReqLock(req);
-
- if (req->threadkey)
- virNWFilterSnoopCancel(&req->threadkey);
-
- virNWFilterSnoopReqUnlock(req);
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ if (req->threadkey)
+ virNWFilterSnoopCancel(&req->threadkey);
+ }
virNWFilterSnoopReqFree(req);
}
virNWFilterSnoopIPLease *plnew,
bool update_leasefile)
{
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
virNWFilterSnoopIPLease *pl;
plnew->snoopReq = req;
- /* protect req->start and the lease */
- virNWFilterSnoopReqLock(req);
-
pl = virNWFilterSnoopIPLeaseGetByIP(req->start, &plnew->ipAddress);
if (pl) {
virNWFilterSnoopIPLeaseUpdate(pl, plnew->timeout);
+ virLockGuardUnlock(&lock);
+ } else {
+ pl = g_new0(virNWFilterSnoopIPLease, 1);
+ *pl = *plnew;
- virNWFilterSnoopReqUnlock(req);
-
- goto cleanup;
- }
-
- virNWFilterSnoopReqUnlock(req);
+ if (req->threadkey && virNWFilterSnoopIPLeaseInstallRule(pl, true) < 0) {
+ g_free(pl);
+ return -1;
+ }
- pl = g_new0(virNWFilterSnoopIPLease, 1);
- *pl = *plnew;
+ virLockGuardUnlock(&lock);
- /* protect req->threadkey */
- virNWFilterSnoopReqLock(req);
+ /* put the lease on the req's list */
+ virNWFilterSnoopIPLeaseTimerAdd(pl);
- if (req->threadkey && virNWFilterSnoopIPLeaseInstallRule(pl, true) < 0) {
- virNWFilterSnoopReqUnlock(req);
- g_free(pl);
- return -1;
+ g_atomic_int_add(&virNWFilterSnoopState.nLeases, 1);
}
- virNWFilterSnoopReqUnlock(req);
-
- /* put the lease on the req's list */
- virNWFilterSnoopIPLeaseTimerAdd(pl);
-
- g_atomic_int_add(&virNWFilterSnoopState.nLeases, 1);
-
- cleanup:
if (update_leasefile)
virNWFilterSnoopLeaseFileSave(pl);
static int
virNWFilterSnoopReqRestore(virNWFilterSnoopReq *req)
{
- int ret = 0;
virNWFilterSnoopIPLease *ipl;
/* protect req->start */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
for (ipl = req->start; ipl; ipl = ipl->next) {
/* instantiate the rules at the last lease */
bool is_last = (ipl->next == NULL);
- if (virNWFilterSnoopIPLeaseInstallRule(ipl, is_last) < 0) {
- ret = -1;
- break;
- }
+ if (virNWFilterSnoopIPLeaseInstallRule(ipl, is_last) < 0)
+ return -1;
}
- virNWFilterSnoopReqUnlock(req);
-
- return ret;
+ return 0;
}
/*
g_autofree char *ipstr = NULL;
/* protect req->start, req->ifname and the lease */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
ipl = virNWFilterSnoopIPLeaseGetByIP(req->start, ipaddr);
if (ipl == NULL)
- goto lease_not_found;
+ return 0;
ipstr = virSocketAddrFormat(&ipl->ipAddress);
if (!ipstr) {
- ret = -1;
- goto lease_not_found;
+ return -1;
}
virNWFilterSnoopIPLeaseTimerDel(ipl);
g_free(ipl);
ignore_value(!!g_atomic_int_dec_and_test(&virNWFilterSnoopState.nLeases));
-
- lease_not_found:
- virNWFilterSnoopReqUnlock(req);
-
return ret;
}
/* whoever started us increased the reference counter for the req for us */
/* protect req->binding->portdevname & req->threadkey */
- virNWFilterSnoopReqLock(req);
-
- if (req->binding->portdevname && req->threadkey) {
- for (i = 0; i < G_N_ELEMENTS(pcapConf); i++) {
- pcapConf[i].handle =
- virNWFilterSnoopDHCPOpen(req->binding->portdevname,
- &req->binding->mac,
- pcapConf[i].filter,
- pcapConf[i].dir);
- if (!pcapConf[i].handle) {
- error = true;
- break;
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ if (req->binding->portdevname && req->threadkey) {
+ for (i = 0; i < G_N_ELEMENTS(pcapConf); i++) {
+ pcapConf[i].handle =
+ virNWFilterSnoopDHCPOpen(req->binding->portdevname,
+ &req->binding->mac,
+ pcapConf[i].filter,
+ pcapConf[i].dir);
+ if (!pcapConf[i].handle) {
+ error = true;
+ break;
+ }
+ fds[i].fd = pcap_fileno(pcapConf[i].handle);
}
- fds[i].fd = pcap_fileno(pcapConf[i].handle);
+ tmp = virNetDevGetIndex(req->binding->portdevname, &ifindex);
+ threadkey = g_strdup(req->threadkey);
+ worker = virThreadPoolNewFull(1, 1, 0, virNWFilterDHCPDecodeWorker,
+ "dhcp-decode", NULL, req);
}
- tmp = virNetDevGetIndex(req->binding->portdevname, &ifindex);
- threadkey = g_strdup(req->threadkey);
- worker = virThreadPoolNewFull(1, 1, 0,
- virNWFilterDHCPDecodeWorker,
- "dhcp-decode",
- NULL,
- req);
- }
-
- /* let creator know how well we initialized */
- if (error || !threadkey || tmp < 0 || !worker ||
- ifindex != req->ifindex) {
- virErrorPreserveLast(&req->threadError);
- req->threadStatus = THREAD_STATUS_FAIL;
- } else {
- req->threadStatus = THREAD_STATUS_OK;
- }
- virCondSignal(&req->threadStatusCond);
+ /* let creator know how well we initialized */
+ if (error || !threadkey || tmp < 0 || !worker || ifindex != req->ifindex) {
+ virErrorPreserveLast(&req->threadError);
+ req->threadStatus = THREAD_STATUS_FAIL;
+ } else {
+ req->threadStatus = THREAD_STATUS_OK;
+ }
- virNWFilterSnoopReqUnlock(req);
+ virCondSignal(&req->threadStatusCond);
+ }
if (req->threadStatus != THREAD_STATUS_OK)
goto cleanup;
tmp = -1;
/* protect req->binding->portdevname */
- virNWFilterSnoopReqLock(req);
-
- if (req->binding->portdevname)
- tmp = virNetDevValidateConfig(req->binding->portdevname, NULL, ifindex);
-
- virNWFilterSnoopReqUnlock(req);
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ if (req->binding->portdevname)
+ tmp = virNetDevValidateConfig(req->binding->portdevname, NULL, ifindex);
+ }
if (tmp <= 0) {
error = true;
g_clear_pointer(&pcapConf[i].handle, pcap_close);
/* protect req->binding->portdevname */
- virNWFilterSnoopReqLock(req);
-
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("interface '%s' failing; "
- "reopening"),
- req->binding->portdevname);
- if (req->binding->portdevname)
- pcapConf[i].handle =
- virNWFilterSnoopDHCPOpen(req->binding->portdevname,
- &req->binding->mac,
- pcapConf[i].filter,
- pcapConf[i].dir);
-
- virNWFilterSnoopReqUnlock(req);
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("interface '%s' failing; reopening"),
+ req->binding->portdevname);
+ if (req->binding->portdevname)
+ pcapConf[i].handle =
+ virNWFilterSnoopDHCPOpen(req->binding->portdevname,
+ &req->binding->mac,
+ pcapConf[i].filter,
+ pcapConf[i].dir);
+ }
if (!pcapConf[i].handle) {
error = true;
/* protect IfNameToKey */
VIR_WITH_MUTEX_LOCK_GUARD(&virNWFilterSnoopState.snoopLock) {
/* protect req->binding->portdevname & req->threadkey */
- virNWFilterSnoopReqLock(req);
-
- virNWFilterSnoopCancel(&req->threadkey);
-
- ignore_value(virHashRemoveEntry(virNWFilterSnoopState.ifnameToKey,
- req->binding->portdevname));
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ virNWFilterSnoopCancel(&req->threadkey);
- g_clear_pointer(&req->binding->portdevname, g_free);
+ ignore_value(virHashRemoveEntry(virNWFilterSnoopState.ifnameToKey,
+ req->binding->portdevname));
- virNWFilterSnoopReqUnlock(req);
+ g_clear_pointer(&req->binding->portdevname, g_free);
+ }
}
cleanup:
}
/* prevent thread from holding req */
- virNWFilterSnoopReqLock(req);
+ virMutexLock(&req->lock);
if (virThreadCreateFull(&thread, false, virNWFilterDHCPSnoopThread,
"dhcp-snoop", false, req) != 0) {
goto exit_snoop_cancel;
}
- virNWFilterSnoopReqUnlock(req);
+ virMutexUnlock(&req->lock);
virMutexUnlock(&virNWFilterSnoopState.snoopLock);
exit_snoop_cancel:
virNWFilterSnoopCancel(&req->threadkey);
exit_snoopreq_unlock:
- virNWFilterSnoopReqUnlock(req);
+ virMutexUnlock(&req->lock);
exit_rem_ifnametokey:
virHashRemoveEntry(virNWFilterSnoopState.ifnameToKey, binding->portdevname);
exit_snoopunlock:
const void *data G_GNUC_UNUSED)
{
virNWFilterSnoopReq *req = (virNWFilterSnoopReq *)payload;
- bool del_req;
/* clean up orphaned, expired leases */
/* protect req->threadkey */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
if (!req->threadkey)
virNWFilterSnoopReqLeaseTimerRun(req);
/*
* have the entry removed if it has no leases and no one holds a ref
*/
- del_req = ((req->start == NULL) && (g_atomic_int_get(&req->refctr) == 0));
-
- virNWFilterSnoopReqUnlock(req);
-
- return del_req;
+ return ((req->start == NULL) && (g_atomic_int_get(&req->refctr) == 0));
}
/*
virNWFilterSnoopIPLease *ipl;
/* protect req->start */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
for (ipl = req->start; ipl; ipl = ipl->next)
ignore_value(virNWFilterSnoopLeaseFileWrite(tfd, req->ifkey, ipl));
- virNWFilterSnoopReqUnlock(req);
return 0;
}
virNWFilterSnoopReq *req = (virNWFilterSnoopReq *)payload;
/* protect req->binding->portdevname */
- virNWFilterSnoopReqLock(req);
+ VIR_LOCK_GUARD lock = virLockGuardLock(&req->lock);
if (req->binding && req->binding->portdevname) {
ignore_value(virHashRemoveEntry(virNWFilterSnoopState.ifnameToKey,
g_clear_pointer(&req->binding->portdevname, g_free);
}
- virNWFilterSnoopReqUnlock(req);
-
/* removal will call virNWFilterSnoopCancel() */
return 1;
}
}
/* protect req->binding->portdevname & req->threadkey */
- virNWFilterSnoopReqLock(req);
-
- /* keep valid lease req; drop interface association */
- virNWFilterSnoopCancel(&req->threadkey);
+ VIR_WITH_MUTEX_LOCK_GUARD(&req->lock) {
+ /* keep valid lease req; drop interface association */
+ virNWFilterSnoopCancel(&req->threadkey);
- g_clear_pointer(&req->binding->portdevname, g_free);
-
- virNWFilterSnoopReqUnlock(req);
+ g_clear_pointer(&req->binding->portdevname, g_free);
+ }
virNWFilterSnoopReqPut(req);
} else { /* free all of them */