[libvirt] [PATCH v2 1/5] util: extract the request sending code from virNetlinkCommand()

Cédric Bosdonnat cbosdonnat at suse.com
Wed Mar 15 14:45:47 UTC 2017


Allow to reuse as much as possible from virNetlinkCommand(). This
comment prepares for the introduction of virNetlindDumpCommand()
only differing by how it handles the responses.
---
 src/util/virnetlink.c | 89 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 54 insertions(+), 35 deletions(-)

diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index a5d10fa8e..be00351db 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -209,61 +209,38 @@ virNetlinkCreateSocket(int protocol)
     goto cleanup;
 }
 
-
-/**
- * virNetlinkCommand:
- * @nlmsg: pointer to netlink message
- * @respbuf: pointer to pointer where response buffer will be allocated
- * @respbuflen: pointer to integer holding the size of the response buffer
- *      on return of the function.
- * @src_pid: the pid of the process to send a message
- * @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
- * @protocol: netlink protocol
- * @groups: the group identifier
- *
- * Send the given message to the netlink layer and receive response.
- * Returns 0 on success, -1 on error. In case of error, no response
- * buffer will be returned.
- */
-int virNetlinkCommand(struct nl_msg *nl_msg,
-                      struct nlmsghdr **resp, unsigned int *respbuflen,
-                      uint32_t src_pid, uint32_t dst_pid,
+static virNetlinkHandle *
+virNetlinkSendRequest(struct nl_msg *nl_msg, uint32_t src_pid,
+                      struct sockaddr_nl nladdr,
                       unsigned int protocol, unsigned int groups)
 {
-    int ret = -1;
-    struct sockaddr_nl nladdr = {
-            .nl_family = AF_NETLINK,
-            .nl_pid    = dst_pid,
-            .nl_groups = 0,
-    };
     ssize_t nbytes;
-    struct pollfd fds[1];
     int fd;
     int n;
-    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
     virNetlinkHandle *nlhandle = NULL;
-    int len = 0;
+    struct pollfd fds[1];
+    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
 
     if (protocol >= MAX_LINKS) {
         virReportSystemError(EINVAL,
                              _("invalid protocol argument: %d"), protocol);
-        goto cleanup;
+        goto error;
     }
 
     if (!(nlhandle = virNetlinkCreateSocket(protocol)))
-        goto cleanup;
+        goto error;
 
     fd = nl_socket_get_fd(nlhandle);
     if (fd < 0) {
         virReportSystemError(errno,
                              "%s", _("cannot get netlink socket fd"));
-        goto cleanup;
+        goto error;
     }
 
     if (groups && nl_socket_add_membership(nlhandle, groups) < 0) {
         virReportSystemError(errno,
                              "%s", _("cannot add netlink membership"));
-        goto cleanup;
+        goto error;
     }
 
     nlmsg_set_dst(nl_msg, &nladdr);
@@ -274,10 +251,11 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
     if (nbytes < 0) {
         virReportSystemError(errno,
                              "%s", _("cannot send to netlink socket"));
-        goto cleanup;
+        goto error;
     }
 
     memset(fds, 0, sizeof(fds));
+
     fds[0].fd = fd;
     fds[0].events = POLLIN;
 
@@ -289,9 +267,51 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
         if (n == 0)
             virReportSystemError(ETIMEDOUT, "%s",
                                  _("no valid netlink response was received"));
-        goto cleanup;
     }
 
+    return nlhandle;
+
+ error:
+    virNetlinkFree(nlhandle);
+    return NULL;
+}
+
+/**
+ * virNetlinkCommand:
+ * @nlmsg: pointer to netlink message
+ * @respbuf: pointer to pointer where response buffer will be allocated
+ * @respbuflen: pointer to integer holding the size of the response buffer
+ *      on return of the function.
+ * @src_pid: the pid of the process to send a message
+ * @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
+ * @protocol: netlink protocol
+ * @groups: the group identifier
+ *
+ * Send the given message to the netlink layer and receive response.
+ * Returns 0 on success, -1 on error. In case of error, no response
+ * buffer will be returned.
+ */
+int virNetlinkCommand(struct nl_msg *nl_msg,
+                      struct nlmsghdr **resp, unsigned int *respbuflen,
+                      uint32_t src_pid, uint32_t dst_pid,
+                      unsigned int protocol, unsigned int groups)
+{
+    int ret = -1;
+    struct sockaddr_nl nladdr = {
+            .nl_family = AF_NETLINK,
+            .nl_pid    = dst_pid,
+            .nl_groups = 0,
+    };
+    struct pollfd fds[1];
+    virNetlinkHandle *nlhandle = NULL;
+    int len = 0;
+
+    memset(fds, 0, sizeof(fds));
+
+    if (!(nlhandle = virNetlinkSendRequest(nl_msg, src_pid, nladdr,
+                                           protocol, groups)))
+        goto cleanup;
+
     len = nl_recv(nlhandle, &nladdr, (unsigned char **)resp, NULL);
     if (len == 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -315,7 +335,6 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
     return ret;
 }
 
-
 /**
  * virNetlinkDumpLink:
  *
-- 
2.11.0




More information about the libvir-list mailing list