Control: forwarded 913520 https://github.com/mattthias/slurm/issues/12
Control: tags 913520 +patch

There's already an issue upstream (see above) and I provided a PR there
as well to fix the issue, which seems to work well in my tests.

https://github.com/mattthias/slurm/pull/29

Patch attached.

Cheers!

A.
-- 
Freedom is being able to make decisions that affect mainly you. Power
is being able to make decisions that affect others more than you. If
we confuse power with freedom, we will fail to uphold real freedom.
                        - Richard Stallman
From 55d48c5c39552973c0f1c40244f45474200fd4fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= <anar...@debian.org>
Date: Sun, 11 Nov 2018 15:51:04 -0500
Subject: [PATCH] implement iface speed detection on Linux (closes #12)

This follows the deprecated SIOCETHTOOL interface, but should be
generally more portable. Was tested on Debian GNU/Linux "buster" with
a 4.18.0 Linux kernel.

Note that the interface is similar to the the BSD media.h pattern
(create a socket and pass it to ioctl) but I felt it was clearer to
just create another #if block than mangle the already quite complex

This was mostly cargo-culted from:

https://stackoverflow.com/questions/2872058/get-link-speed-programmatically
---
 slurm.c        |  2 +-
 src/if_media.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/slurm.c b/slurm.c
index e2c3014..f38af17 100644
--- a/slurm.c
+++ b/slurm.c
@@ -1300,7 +1300,7 @@ int main(int argc, char *argv[])
      * if the speed could not determined due to errors or lack of
      * this feature on the host operating system
      */
-#if defined(_HAVE_BSD) || defined(__HPUX__) || defined(__Solaris__) || defined(__APPLE__)
+#if defined(_HAVE_BSD) || defined(__HPUX__) || defined(__Solaris__) || defined(__APPLE__) || defined(__linux__)
     ifdata.if_speed = get_if_speed(ifdata.if_name);
 
     /* if ERR_IFACE_NO_SPEED we could not determine the interface speed
diff --git a/src/if_media.c b/src/if_media.c
index 9f5b51d..9544db8 100644
--- a/src/if_media.c
+++ b/src/if_media.c
@@ -26,6 +26,17 @@
 #endif
 #endif
 
+#if defined(__linux__)
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <linux/sockios.h>
+#include <linux/if.h>
+#include <linux/ethtool.h>
+#include <string.h>
+#include <stdlib.h>
+#endif
 
 
 /******************************************************************************
@@ -296,6 +307,39 @@ int get_if_speed(char *ifstring)
 
     return speed;
 }
+#elif defined(__linux__)
+int get_if_speed(char *ifstring)
+{
+    int sock;
+    struct ifreq ifr;
+    struct ethtool_cmd edata;
+    int rc;
+
+    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+    if (sock < 0) {
+        fprintf(stderr, "cannot create socket to guess interface speed");
+        return -1;
+    }
+
+    strncpy(ifr.ifr_name, ifstring, sizeof(ifr.ifr_name));
+    ifr.ifr_data = &edata;
+
+    edata.cmd = ETHTOOL_GSET;
+
+    rc = ioctl(sock, SIOCETHTOOL, &ifr);
+    if (rc < 0) {
+        fprintf(stderr, "failed to guess interface speed");
+        return -1;
+    }
+    switch (ethtool_cmd_speed(&edata)) {
+    case SPEED_10: return 10*1000;
+    case SPEED_100: return 100*1000;
+    case SPEED_1000: return 1000*1000;
+    case SPEED_2500: return 2500*1000;
+    case SPEED_10000: return 10000*1000;
+    default: return edata.speed*1000;
+    }
+}
 #else
 int get_if_speed(char *ifstring)
 {
-- 
2.19.1

Attachment: signature.asc
Description: PGP signature

Reply via email to