]> xenbits.xensource.com Git - libvirt.git/commitdiff
Implement interface stats for BSD
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Sun, 6 Jul 2014 09:53:40 +0000 (13:53 +0400)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Tue, 15 Jul 2014 18:00:59 +0000 (22:00 +0400)
configure.ac
src/util/virstats.c

index a12186bd143093e360ab4ccb9b7deebc8a879047..8001e24b9cc00aa027874e4ffcbf0c1de730e5ca 100644 (file)
@@ -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])
index 17ef5b6947515f7531746d16d3d8f0def76b4c58..910803f2b33d66eb47801f98641eb3a23675d809 100644 (file)
 #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,