Explorar el Código

Merge pull request #11326 from mckellyln/eth_fix

HPCC-16017 Network stats use correct interface

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday hace 7 años
padre
commit
a7eacaaeab
Se han modificado 3 ficheros con 62 adiciones y 7 borrados
  1. 18 6
      system/jlib/jdebug.cpp
  2. 43 1
      system/jlib/jsocket.cpp
  3. 1 0
      system/jlib/jsocket.hpp

+ 18 - 6
system/jlib/jdebug.cpp

@@ -1648,6 +1648,8 @@ class CExtendedStats  // Disk network and cpu stats
 
     unsigned ndisks;
 
+    StringBuffer ifname;
+
     int isdisk(unsigned int major, unsigned int minor)
     {
         if (IDE_DISK_MAJOR(major)) 
@@ -1795,8 +1797,10 @@ class CExtendedStats  // Disk network and cpu stats
         while (fgets(ln, sizeof(ln), netfp)) {
             const char *s = ln;
             skipSp(s);
-            if (strncmp(s, "eth0:", 5)==0) {  // may want eth1 at some point!
-                s+=5;
+            size_t ilen = ifname.length();
+            if ( (strncmp(s, ifname.str(), ilen)==0) && (s[ilen]==':') ) {
+                s+=(ilen+1);
+                skipSp(s);
                 if (hasbyt) {
                     newnet.rxbytes = readDecNum(s);
                     skipSp(s);
@@ -1959,6 +1963,9 @@ public:
         }
         else
             kbufmax = 0;
+
+        if (!getInterfaceName(ifname))
+            ifname.set("eth0");
     }
 
     ~CExtendedStats()
@@ -2014,16 +2021,21 @@ public:
             }
         }
         if (gotnet) {
-            out.append("NIC: ");
+            out.appendf("NIC: [%s] ", ifname.str());
             __uint64 rxbytes = newnet.rxbytes-oldnet.rxbytes;
             __uint64 rxpackets = newnet.rxpackets-oldnet.rxpackets;
             __uint64 txbytes = newnet.txbytes-oldnet.txbytes;
             __uint64 txpackets = newnet.txpackets-oldnet.txpackets;
-            out.appendf("rxp/s=%0.1f rxk/s=%0.1f txp/s=%0.1f txk/s=%0.1f",
+            __uint64 rxerrors = newnet.rxerrors-oldnet.rxerrors;
+            __uint64 rxdrops = newnet.rxdrops-oldnet.rxdrops;
+            __uint64 txerrors = newnet.txerrors-oldnet.txerrors;
+            __uint64 txdrops = newnet.txdrops-oldnet.txdrops;
+            out.appendf("rxp/s=%0.1f rxk/s=%0.1f txp/s=%0.1f txk/s=%0.1f rxerrs=%" I64F "d rxdrps=%" I64F "d txerrs=%" I64F "d txdrps=%" I64F "d",
                        perSec(rxpackets,deltams),
                        perSec(rxbytes/1024.0,deltams),
                        perSec(txpackets,deltams),
-                       perSec(txbytes/1024.0,deltams));
+                       perSec(txbytes/1024.0,deltams),
+                       rxerrors, rxdrops, txerrors, txdrops);
             out.append(' ');
         }
         if (totalcpu)
@@ -2035,7 +2047,7 @@ public:
 #define KERN_ALERT   "<1>"   // action must be taken immediately
 #define KERN_CRIT    "<2>"   // critical conditions
 #define KERN_ERR     "<3>"   // error conditions
-#define KERN_WARNING "<4>"  // warning conditions
+#define KERN_WARNING "<4>"   // warning conditions
 #define KERN_NOTICE  "<5>"   // normal but significant condition
 #define KERN_INFO    "<6>"   // informational
 #define KERN_DEBUG   "<7>"   // debug-level messages

+ 43 - 1
system/jlib/jsocket.cpp

@@ -3016,6 +3016,48 @@ IpAddress &localHostToNIC(IpAddress &ip)
 
 // IpAddress
 
+bool getInterfaceName(StringBuffer &ifname)
+{
+#if defined(_WIN32) || defined(__APPLE__)
+    return false;
+#else
+    IpAddress myIp;
+    GetHostIp(myIp);
+
+    int fd = socket(AF_INET, SOCK_DGRAM, 0);  // IPV6 TBD
+    if (fd<0)
+        return false;
+
+    MemoryAttr ma;
+    char *buf = (char *)ma.allocate(1024);
+
+    struct ifconf ifc;
+    ifc.ifc_len = 1024;
+    ifc.ifc_buf = buf;
+    if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) // query interfaces
+    {
+        close(fd);
+        return false;
+    }
+
+    struct ifreq *ifr = ifc.ifc_req;
+    unsigned n = ifc.ifc_len/sizeof(struct ifreq);
+    for (unsigned i=0; i<n; i++)
+    {
+        struct ifreq *item = &ifr[i];
+        IpAddress iptest((inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr)));
+        if (iptest.ipequals(myIp))
+        {
+            ifname.set(item->ifr_name);
+            close(fd);
+            return true;
+        }
+    }
+
+    close(fd);
+    return false;
+#endif
+}
 
 inline bool isIp4(const unsigned *netaddr)
 {
@@ -3114,7 +3156,7 @@ static bool lookupHostAddress(const char *name,unsigned *netaddr)
     // if IP4only or using MS V6 can only resolve IPv4 using 
     static bool recursioncheck = false; // needed to stop error message recursing
     unsigned retry=10;
-#if defined(__linux__) || defined (__APPLE__) ||defined(getaddrinfo)
+#if defined(__linux__) || defined (__APPLE__) || defined(getaddrinfo)
     if (IP4only) {
 #else
     {

+ 1 - 0
system/jlib/jsocket.hpp

@@ -615,6 +615,7 @@ extern jlib_decl StringBuffer lookupHostName(const IpAddress &ip,StringBuffer &r
 
 extern jlib_decl bool isInterfaceIp(const IpAddress &ip, const char *ifname);
 extern jlib_decl bool getInterfaceIp(IpAddress &ip, const char *ifname);
+extern jlib_decl bool getInterfaceName(StringBuffer &ifname);
 
 //Given a list of server sockets, wait until any one or more are ready to be read/written (wont block)
 //return array of ready sockets