[libvirt] [PATCH 2/2] Implement interface stats for BSD

Roman Bogorodskiy bogorodskiy at gmail.com
Sun Jul 6 16:28:44 UTC 2014


---
 configure.ac        | 13 ++++++++++++-
 src/util/virstats.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index a12186b..8001e24 100644
--- a/configure.ac
+++ b/configure.ac
@@ -275,7 +275,7 @@ dnl and various less common threadsafe functions
 AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \
   getmntent_r getpwuid_r getuid kill mmap newlocale posix_fallocate \
   posix_memalign prlimit regexec sched_getaffinity setgroups setns \
-  setrlimit symlink sysctlbyname])
+  setrlimit symlink sysctlbyname getifaddrs])
 
 dnl Availability of pthread functions. Because of $LIB_PTHREAD, we
 dnl cannot use AC_CHECK_FUNCS_ONCE. LIB_PTHREAD and LIBMULTITHREAD
@@ -2691,6 +2691,17 @@ if test $with_freebsd = yes; then
                  )
 fi
 
+# FreeBSD 10-STABLE requires _IFI_OQDROPS to be defined for if_data.ifi_oqdrops
+# field be available
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -D_IFI_OQDROPS"
+
+AC_CHECK_MEMBERS([struct if_data.ifi_oqdrops],
+		 [],
+		 [CFLAGS="$old_CFLAGS"],
+		 [#include <net/if.h>
+		 ])
+
 # Check if we need to look for ifconfig
 if test "$want_ifconfig" = "yes"; then
      AC_PATH_PROG([IFCONFIG_PATH], [ifconfig])
diff --git a/src/util/virstats.c b/src/util/virstats.c
index 17ef5b6..910803f 100644
--- a/src/util/virstats.c
+++ b/src/util/virstats.c
@@ -29,6 +29,11 @@
 #include <unistd.h>
 #include <regex.h>
 
+#ifdef HAVE_GETIFADDRS
+# include <net/if.h>
+# include <ifaddrs.h>
+#endif
+
 #include "virerror.h"
 #include "datatypes.h"
 #include "virstats.h"
@@ -114,6 +119,52 @@ virNetInterfaceStats(const char *path,
                    _("/proc/net/dev: Interface not found"));
     return -1;
 }
+#elif defined(HAVE_GETIFADDRS)
+int
+virNetInterfaceStats(const char *path,
+                     struct _virDomainInterfaceStats *stats)
+{
+    struct ifaddrs *ifap, *ifa;
+    struct if_data *ifd;
+    int ret = -1;
+
+    if (getifaddrs(&ifap) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("Could not get interface list"));
+        return -1;
+    }
+
+    for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+        if (ifa->ifa_addr->sa_family != AF_LINK)
+            continue;
+
+        if (STREQ(ifa->ifa_name, path)) {
+            ifd = (struct if_data *)ifa->ifa_data;
+            stats->tx_bytes = ifd->ifi_ibytes;
+            stats->tx_packets = ifd->ifi_ipackets;
+            stats->tx_errs = ifd->ifi_ierrors;
+            stats->tx_drop = ifd->ifi_iqdrops;
+            stats->rx_bytes = ifd->ifi_obytes;
+            stats->rx_packets = ifd->ifi_opackets;
+            stats->rx_errs = ifd->ifi_oerrors;
+# ifdef HAVE_STRUCT_IF_DATA_IFI_OQDROPS
+            stats->rx_drop = ifd->ifi_oqdrops;
+# else
+            stats->rx_drop = 0;
+# endif
+
+            ret = 0;
+            break;
+        }
+    }
+
+    if (ret < 0)
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Interface not found"));
+
+    freeifaddrs(ifap);
+    return ret;
+}
 #else
 int
 virNetInterfaceStats(const char *path ATTRIBUTE_UNUSED,
-- 
1.9.0




More information about the libvir-list mailing list