[libvirt PATCH v2 11/13] virnetlink: Use automatic memory management

Tim Wiederhake twiederh at redhat.com
Wed Mar 16 22:10:40 UTC 2022


Signed-off-by: Tim Wiederhake <twiederh at 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



More information about the libvir-list mailing list