[libvirt] [PATCH 1/2 V2] cleanup: make nlComm commonly available

Stefan Berger stefanb at linux.vnet.ibm.com
Tue Jun 21 23:48:10 UTC 2011


In a first cleanup step, make nlComm from macvtap.c commonly available
for other code to use. Since nlComm uses Linux-specific structures as
parameters it's prototype is only visible on Linux.

v2:
  - making nlComm visible also on non-Linux platforms

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>

---
 src/Makefile.am          |    1 
 src/libvirt_private.syms |    4 +
 src/util/macvtap.c       |   98 ------------------------------
 src/util/netlink.c       |  152 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/netlink.h       |   18 +++++
 5 files changed, 176 insertions(+), 97 deletions(-)

Index: libvirt-acl/src/Makefile.am
===================================================================
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -63,6 +63,7 @@ UTIL_SOURCES =							\
 		util/logging.c util/logging.h			\
 		util/macvtap.c util/macvtap.h			\
 		util/memory.c util/memory.h			\
+		util/netlink.c util/netlink.h			\
 		util/pci.c util/pci.h				\
 		util/processinfo.c util/processinfo.h		\
 		util/hostusb.c util/hostusb.h			\
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -39,12 +39,8 @@
 # include <sys/ioctl.h>
 
 # include <linux/if.h>
-# include <linux/netlink.h>
-# include <linux/rtnetlink.h>
 # include <linux/if_tun.h>
 
-# include <netlink/msg.h>
-
 /* Older kernels lacked this enum value.  */
 # if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
 #  define MACVLAN_MODE_PASSTHRU 8
@@ -64,6 +60,7 @@
 # include "virterror_internal.h"
 # include "uuid.h"
 # include "files.h"
+# include "netlink.h"
 
 # define VIR_FROM_THIS VIR_FROM_NET
 
@@ -79,8 +76,6 @@
 # define NLMSGBUF_SIZE  256
 # define RATTBUF_SIZE   64
 
-# define NETLINK_ACK_TIMEOUT_S  2
-
 # define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC)
 # define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8)
 
@@ -96,97 +91,6 @@ enum virVirtualPortOp {
 };
 
 
-/**
- * nlComm:
- * @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.
- * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
- *
- * 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.
- */
-static
-int nlComm(struct nl_msg *nl_msg,
-           unsigned char **respbuf, unsigned int *respbuflen,
-           int nl_pid)
-{
-    int rc = 0;
-    struct sockaddr_nl nladdr = {
-            .nl_family = AF_NETLINK,
-            .nl_pid    = nl_pid,
-            .nl_groups = 0,
-    };
-    ssize_t nbytes;
-    struct timeval tv = {
-        .tv_sec = NETLINK_ACK_TIMEOUT_S,
-    };
-    fd_set readfds;
-    int fd;
-    int n;
-    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
-    struct nl_handle *nlhandle = nl_handle_alloc();
-
-    if (!nlhandle) {
-        virReportSystemError(errno,
-                             "%s", _("cannot allocate nlhandle for netlink"));
-        return -1;
-    }
-
-    if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
-        virReportSystemError(errno,
-                             "%s", _("cannot connect to netlink socket"));
-        rc = -1;
-        goto err_exit;
-    }
-
-    nlmsg_set_dst(nl_msg, &nladdr);
-
-    nlmsg->nlmsg_pid = getpid();
-
-    nbytes = nl_send_auto_complete(nlhandle, nl_msg);
-    if (nbytes < 0) {
-        virReportSystemError(errno,
-                             "%s", _("cannot send to netlink socket"));
-        rc = -1;
-        goto err_exit;
-    }
-
-    fd = nl_socket_get_fd(nlhandle);
-
-    FD_ZERO(&readfds);
-    FD_SET(fd, &readfds);
-
-    n = select(fd + 1, &readfds, NULL, NULL, &tv);
-    if (n <= 0) {
-        if (n < 0)
-            virReportSystemError(errno, "%s",
-                                 _("error in select call"));
-        if (n == 0)
-            virReportSystemError(ETIMEDOUT, "%s",
-                                 _("no valid netlink response was received"));
-        rc = -1;
-        goto err_exit;
-    }
-
-    *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
-    if (*respbuflen <= 0) {
-        virReportSystemError(errno,
-                             "%s", _("nl_recv failed"));
-        rc = -1;
-    }
-err_exit:
-    if (rc == -1) {
-        VIR_FREE(*respbuf);
-        *respbuf = NULL;
-        *respbuflen = 0;
-    }
-
-    nl_handle_destroy(nlhandle);
-    return rc;
-}
 
 
 # if WITH_MACVTAP
Index: libvirt-acl/src/util/netlink.c
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Authors:
+ *     Stefan Berger <stefanb at us.ibm.com>
+ *
+ * Notes:
+ * netlink: http://lovezutto.googlepages.com/netlink.pdf
+ *          iproute2 package
+ *
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "netlink.h"
+#include "memory.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_NET
+
+# define netlinkError(code, ...)                                           \
+        virReportErrorHelper(VIR_FROM_NET, code, __FILE__,                 \
+                             __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define NETLINK_ACK_TIMEOUT_S  2
+
+/**
+ * nlComm:
+ * @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.
+ * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
+ *
+ * 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.
+ */
+#if __linux__
+int nlComm(struct nl_msg *nl_msg,
+           unsigned char **respbuf, unsigned int *respbuflen,
+           int nl_pid)
+{
+    int rc = 0;
+    struct sockaddr_nl nladdr = {
+            .nl_family = AF_NETLINK,
+            .nl_pid    = nl_pid,
+            .nl_groups = 0,
+    };
+    ssize_t nbytes;
+    struct timeval tv = {
+        .tv_sec = NETLINK_ACK_TIMEOUT_S,
+    };
+    fd_set readfds;
+    int fd;
+    int n;
+    struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
+    struct nl_handle *nlhandle = nl_handle_alloc();
+
+    if (!nlhandle) {
+        virReportSystemError(errno,
+                             "%s", _("cannot allocate nlhandle for netlink"));
+        return -1;
+    }
+
+    if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
+        virReportSystemError(errno,
+                             "%s", _("cannot connect to netlink socket"));
+        rc = -1;
+        goto err_exit;
+    }
+
+    nlmsg_set_dst(nl_msg, &nladdr);
+
+    nlmsg->nlmsg_pid = getpid();
+
+    nbytes = nl_send_auto_complete(nlhandle, nl_msg);
+    if (nbytes < 0) {
+        virReportSystemError(errno,
+                             "%s", _("cannot send to netlink socket"));
+        rc = -1;
+        goto err_exit;
+    }
+
+    fd = nl_socket_get_fd(nlhandle);
+
+    FD_ZERO(&readfds);
+    FD_SET(fd, &readfds);
+
+    n = select(fd + 1, &readfds, NULL, NULL, &tv);
+    if (n <= 0) {
+        if (n < 0)
+            virReportSystemError(errno, "%s",
+                                 _("error in select call"));
+        if (n == 0)
+            virReportSystemError(ETIMEDOUT, "%s",
+                                 _("no valid netlink response was received"));
+        rc = -1;
+        goto err_exit;
+    }
+
+    *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
+    if (*respbuflen <= 0) {
+        virReportSystemError(errno,
+                             "%s", _("nl_recv failed"));
+        rc = -1;
+    }
+err_exit:
+    if (rc == -1) {
+        VIR_FREE(*respbuf);
+        *respbuf = NULL;
+        *respbuflen = 0;
+    }
+
+    nl_handle_destroy(nlhandle);
+    return rc;
+}
+
+#else
+
+int nlComm(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
+           unsigned char **respbuf ATTRIBUTE_UNUSED,
+           unsigned int *respbuflen ATTRIBUTE_UNUSED,
+           int nl_pid ATTRIBUTE_UNUSED)
+{
+    netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
+                 _("nlComm is not supported on non-linux platforms"));
+    return -1;
+}
+
+
+#endif /* __linux__ */
+
Index: libvirt-acl/src/util/netlink.h
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.h
@@ -0,0 +1,18 @@
+#ifndef __VIR_NETLINK_H__
+# define __VIR_NETLINK_H__
+
+# if __linux__
+
+#  include <netlink/msg.h>
+
+# else
+
+struct nl_msg;
+
+#endif /* __linux__ */
+
+int nlComm(struct nl_msg *nl_msg,
+           unsigned char **respbuf, unsigned int *respbuflen,
+           int nl_pid);
+
+#endif /* __VIR_NETLINK_H__ */
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -668,6 +668,10 @@ virResizeN;
 virShrinkN;
 
 
+#netlink.h
+nlComm;
+
+
 # network.h
 virSocketAddrBroadcast;
 virSocketAddrBroadcastByPrefix;




More information about the libvir-list mailing list