Signed-off-by: Tim Wiederhake <twiederh(a)redhat.com>
---
src/util/virnetlink.c | 222 +++++++++++++++++++-----------------------
1 file changed, 101 insertions(+), 121 deletions(-)
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index c6c8c33c7c..04a39a905b 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -799,18 +799,6 @@ virNetlinkGetErrorCode(struct nlmsghdr *resp, unsigned int
recvbuflen)
}
-static void
-virNetlinkEventServerLock(virNetlinkEventSrvPrivate *driver)
-{
- virMutexLock(&driver->lock);
-}
-
-static void
-virNetlinkEventServerUnlock(virNetlinkEventSrvPrivate *driver)
-{
- virMutexUnlock(&driver->lock);
-}
-
/**
* virNetlinkEventRemoveClientPrimitive:
*
@@ -869,25 +857,23 @@ virNetlinkEventCallback(int watch,
return;
}
- virNetlinkEventServerLock(srv);
-
VIR_DEBUG("dispatching to max %d clients, called from event watch %d",
(int)srv->handlesCount, watch);
- for (i = 0; i < srv->handlesCount; i++) {
- if (srv->handles[i].deleted != VIR_NETLINK_HANDLE_VALID)
- continue;
+ VIR_WITH_MUTEX_LOCK_GUARD(&srv->lock) {
+ for (i = 0; i < srv->handlesCount; i++) {
+ if (srv->handles[i].deleted != VIR_NETLINK_HANDLE_VALID)
+ continue;
- VIR_DEBUG("dispatching client %zu.", i);
+ VIR_DEBUG("dispatching client %zu.", i);
- (srv->handles[i].handleCB)(msg, length, &peer, &handled,
- srv->handles[i].opaque);
+ (srv->handles[i].handleCB)(msg, length, &peer, &handled,
+ srv->handles[i].opaque);
+ }
}
if (!handled)
VIR_DEBUG("event not handled.");
-
- virNetlinkEventServerUnlock(srv);
}
/**
@@ -916,21 +902,21 @@ virNetlinkEventServiceStop(unsigned int protocol)
if (!server[protocol])
return 0;
- virNetlinkEventServerLock(srv);
- nl_close(srv->netlinknh);
- virNetlinkFree(srv->netlinknh);
- virEventRemoveHandle(srv->eventwatch);
+ VIR_WITH_MUTEX_LOCK_GUARD(&srv->lock) {
+ nl_close(srv->netlinknh);
+ virNetlinkFree(srv->netlinknh);
+ virEventRemoveHandle(srv->eventwatch);
+
+ /* free any remaining clients on the list */
+ for (i = 0; i < srv->handlesCount; i++) {
+ if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
+ virNetlinkEventRemoveClientPrimitive(i, protocol);
+ }
- /* free any remaining clients on the list */
- for (i = 0; i < srv->handlesCount; i++) {
- if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
- virNetlinkEventRemoveClientPrimitive(i, protocol);
+ server[protocol] = NULL;
+ VIR_FREE(srv->handles);
}
- server[protocol] = NULL;
- VIR_FREE(srv->handles);
- virNetlinkEventServerUnlock(srv);
-
virMutexDestroy(&srv->lock);
VIR_FREE(srv);
return 0;
@@ -1036,53 +1022,52 @@ virNetlinkEventServiceStart(unsigned int protocol, unsigned int
groups)
return -1;
}
- virNetlinkEventServerLock(srv);
-
- /* Allocate a new socket and get fd */
- if (!(srv->netlinknh = virNetlinkCreateSocket(protocol)))
- goto error_locked;
+ VIR_WITH_MUTEX_LOCK_GUARD(&srv->lock) {
+ /* Allocate a new socket and get fd */
+ if (!(srv->netlinknh = virNetlinkCreateSocket(protocol)))
+ goto error;
- fd = nl_socket_get_fd(srv->netlinknh);
- if (fd < 0) {
- virReportSystemError(errno,
- "%s", _("cannot get netlink socket
fd"));
- goto error_server;
- }
+ fd = nl_socket_get_fd(srv->netlinknh);
+ if (fd < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot get netlink socket
fd"));
+ goto error;
+ }
- if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
- virReportSystemError(errno,
- "%s", _("cannot add netlink
membership"));
- goto error_server;
- }
+ if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0)
{
+ virReportSystemError(errno,
+ "%s", _("cannot add netlink
membership"));
+ goto error;
+ }
- if (nl_socket_set_nonblocking(srv->netlinknh)) {
- virReportSystemError(errno, "%s",
- _("cannot set netlink socket nonblocking"));
- goto error_server;
- }
+ if (nl_socket_set_nonblocking(srv->netlinknh)) {
+ virReportSystemError(errno, "%s",
+ _("cannot set netlink socket nonblocking"));
+ goto error;
+ }
- if ((srv->eventwatch = virEventAddHandle(fd,
- VIR_EVENT_HANDLE_READABLE,
- virNetlinkEventCallback,
- srv, NULL)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Failed to add netlink event handle watch"));
- goto error_server;
- }
+ if ((srv->eventwatch = virEventAddHandle(fd,
+ VIR_EVENT_HANDLE_READABLE,
+ virNetlinkEventCallback,
+ srv, NULL)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Failed to add netlink event handle watch"));
+ goto error;
+ }
- srv->netlinkfd = fd;
- VIR_DEBUG("netlink event listener on fd: %i running", fd);
+ srv->netlinkfd = fd;
+ VIR_DEBUG("netlink event listener on fd: %i running", fd);
- ret = 0;
- server[protocol] = srv;
+ ret = 0;
+ server[protocol] = srv;
- error_server:
- if (ret < 0) {
- nl_close(srv->netlinknh);
- virNetlinkFree(srv->netlinknh);
+ error:
+ if (ret < 0 && srv->netlinknh) {
+ nl_close(srv->netlinknh);
+ virNetlinkFree(srv->netlinknh);
+ }
}
- error_locked:
- virNetlinkEventServerUnlock(srv);
+
if (ret < 0) {
virMutexDestroy(&srv->lock);
VIR_FREE(srv);
@@ -1129,45 +1114,44 @@ virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
return -1;
}
- virNetlinkEventServerLock(srv);
+ VIR_WITH_MUTEX_LOCK_GUARD(&srv->lock) {
+ VIR_DEBUG("adding client: %d.", nextWatch);
- VIR_DEBUG("adding client: %d.", nextWatch);
-
- /* first try to re-use deleted free slots */
- for (i = 0; i < srv->handlesCount; i++) {
- if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_DELETED) {
- r = i;
- break;
+ /* first try to re-use deleted free slots */
+ for (i = 0; i < srv->handlesCount; i++) {
+ if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_DELETED) {
+ r = i;
+ break;
+ }
}
- }
- if (r < 0) {
- /* Resize the eventLoop array if needed */
- if (srv->handlesCount == srv->handlesAlloc) {
- VIR_DEBUG("Used %zu handle slots, adding at least %d more",
- srv->handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT);
- VIR_RESIZE_N(srv->handles, srv->handlesAlloc,
- srv->handlesCount, NETLINK_EVENT_ALLOC_EXTENT);
+ if (r < 0) {
+ /* Resize the eventLoop array if needed */
+ if (srv->handlesCount == srv->handlesAlloc) {
+ VIR_DEBUG("Used %zu handle slots, adding at least %d more",
+ srv->handlesAlloc, NETLINK_EVENT_ALLOC_EXTENT);
+ VIR_RESIZE_N(srv->handles, srv->handlesAlloc,
+ srv->handlesCount, NETLINK_EVENT_ALLOC_EXTENT);
+ }
+ r = srv->handlesCount++;
}
- r = srv->handlesCount++;
- }
- srv->handles[r].watch = nextWatch;
- srv->handles[r].handleCB = handleCB;
- srv->handles[r].removeCB = removeCB;
- srv->handles[r].opaque = opaque;
- srv->handles[r].deleted = VIR_NETLINK_HANDLE_VALID;
- if (macaddr)
- virMacAddrSet(&srv->handles[r].macaddr, macaddr);
- else
- virMacAddrSetRaw(&srv->handles[r].macaddr,
- (unsigned char[VIR_MAC_BUFLEN]){0, 0, 0, 0, 0, 0});
+ srv->handles[r].watch = nextWatch;
+ srv->handles[r].handleCB = handleCB;
+ srv->handles[r].removeCB = removeCB;
+ srv->handles[r].opaque = opaque;
+ srv->handles[r].deleted = VIR_NETLINK_HANDLE_VALID;
+ if (macaddr)
+ virMacAddrSet(&srv->handles[r].macaddr, macaddr);
+ else
+ virMacAddrSetRaw(&srv->handles[r].macaddr,
+ (unsigned char[VIR_MAC_BUFLEN]){0, 0, 0, 0, 0, 0});
- VIR_DEBUG("added client to loop slot: %d. with macaddr ptr=%p", r,
macaddr);
+ ret = nextWatch++;
- ret = nextWatch++;
+ VIR_DEBUG("added client to loop slot: %d. with macaddr ptr=%p", r,
macaddr);
+ }
- virNetlinkEventServerUnlock(srv);
return ret;
}
@@ -1189,7 +1173,6 @@ virNetlinkEventRemoveClient(int watch, const virMacAddr *macaddr,
unsigned int protocol)
{
size_t i;
- int ret = -1;
virNetlinkEventSrvPrivate *srv = NULL;
if (protocol >= MAX_LINKS)
@@ -1204,28 +1187,25 @@ virNetlinkEventRemoveClient(int watch, const virMacAddr *macaddr,
return -1;
}
- virNetlinkEventServerLock(srv);
+ VIR_WITH_MUTEX_LOCK_GUARD(&srv->lock) {
+ for (i = 0; i < srv->handlesCount; i++) {
+ if (srv->handles[i].deleted != VIR_NETLINK_HANDLE_VALID)
+ continue;
- for (i = 0; i < srv->handlesCount; i++) {
- if (srv->handles[i].deleted != VIR_NETLINK_HANDLE_VALID)
- continue;
+ if ((watch && srv->handles[i].watch == watch) ||
+ (!watch &&
+ virMacAddrCmp(macaddr, &srv->handles[i].macaddr) == 0)) {
- if ((watch && srv->handles[i].watch == watch) ||
- (!watch &&
- virMacAddrCmp(macaddr, &srv->handles[i].macaddr) == 0)) {
-
- VIR_DEBUG("removed client: %d by %s.",
- srv->handles[i].watch, watch ? "index" :
"mac");
- virNetlinkEventRemoveClientPrimitive(i, protocol);
- ret = 0;
- goto cleanup;
+ VIR_DEBUG("removed client: %d by %s.",
+ srv->handles[i].watch, watch ? "index" :
"mac");
+ virNetlinkEventRemoveClientPrimitive(i, protocol);
+ return 0;
+ }
}
}
VIR_DEBUG("no client found to remove.");
- cleanup:
- virNetlinkEventServerUnlock(srv);
- return ret;
+ return -1;
}
#else
--
2.31.1