← Back to team overview

canonical-hw-cert team mailing list archive

[Merge] ~rodsmith/maas-cert-server:sync-start-iperf3-with-network.py into maas-cert-server:main

 

Rod Smith has proposed merging ~rodsmith/maas-cert-server:sync-start-iperf3-with-network.py into maas-cert-server:main.

Commit message:
Fix: Improve start-iperf3 to better support non-NUMA systems and multiple IP addresses per network device


Requested reviews:
  Jeff Lane  (bladernr)

For more details, see:
https://code.launchpad.net/~rodsmith/maas-cert-server/+git/maas-cert-server/+merge/451466

This MR does two things:

* It copies over code recently added to network.py to drop the -A {nodenum}
  option to iperf3 on systems that don't support NUMA. This improves
  performance on such systems.
* It fixes a bug discovered when testing the above change, which causes
  start-iperf3 to not launch against addresses other than the first one
  defined for a device.

I've tested this on lloobee (my own ARM64 system which shows the NUMA bug) and on doopliss, which does not exhibit that bug but where I discovered the multiple-address bug. It's working as expected on both systems.

See:

https://github.com/canonical/checkbox/issues/570
https://bugs.launchpad.net/maas-cert-server/+bug/2036263
-- 
Your team hardware-certification-users is subscribed to branch maas-cert-server:main.
diff --git a/debian/changelog b/debian/changelog
index e210363..1e2d967 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+maas-cert-server (0.7.6-0ppa1) jammy; urgency=medium
+
+  * Copy changes from network.py to better support systems on which
+    NUMA is not supported.
+  * Fix bug that caused script to not launch against anything but the
+    device's first IP address, if multiple addresses are defined.
+
+ -- Rod Smith <rodsmith@xxxxxxxxxxxxxxxxxxxxx>  Fri, 15 Sep 2023 12:50:54 -0400
+
 maas-cert-server (0.7.5-0ppa1) jammy; urgency=medium
 
   * Add code to display MAAS error and terminate if login attempts fail
diff --git a/usr/sbin/start-iperf3 b/usr/sbin/start-iperf3
index c3f819c..507dc4b 100755
--- a/usr/sbin/start-iperf3
+++ b/usr/sbin/start-iperf3
@@ -38,30 +38,29 @@ def find_numa(device):
     """Return the NUMA node of the specified network device."""
     filename = "/sys/class/net/" + device + "/device/numa_node"
     try:
-        file = open(filename, "r")
-        node_num = int(file.read())
+        with open(filename, "r") as file:
+            node_num = int(file.read())
     except FileNotFoundError:
-        print("WARNING: Could not find the NUMA node associated with {}!".
-              format(device))
-        print("Setting the association to NUMA node 0, which may not be "
-              "optimal!")
-        node_num = 0
+        node_num = -1
     # Some systems (that don't support NUMA?) produce a node_num of -1.
-    # Change this to 0, which seems to be correct....
+    # Later in the script, this will be interpreted to omit the -A option
+    # to iperf3, thus disabling NUMA features.
     if node_num == -1:
-        node_num = 0
-    print("NUMA node of {} is {}....".format(device, node_num))
+        print("WARNING: Could not find the NUMA node "
+              "associated with {}!".format(device))
+    else:
+        print("NUMA node of {} is {}....".format(device, node_num))
     return node_num
 
 
 def find_device(ipaddr):
     """Return the device name (e.g., eth0) of the specified IP address."""
-    adapters = psutil.net_if_addrs()
+    interfaces = psutil.net_if_addrs()
     found_nic = None
-    for adapter in adapters:
-        address = adapters[adapter][0].address
-        if address == ipaddr:
-            found_nic = adapter
+    for interface in interfaces:
+        for addr in interfaces[interface]:
+            if addr.address == ipaddr:
+                found_nic = interface
     return found_nic
 
 
@@ -119,8 +118,11 @@ def launch_all_iperf3(core_list, ip_address, num_instances):
               "Performance may be degraded!")
     for thread_num in range(0, num_instances):
         port = start_port + thread_num
-        core = core_list[thread_num % len(core_list)]
-        cmd = "iperf3 -sD -B {} -p {} -A{}".format(ip_address, port, core)
+        if len(core_list) > 1:
+            core = core_list[thread_num % len(core_list)]
+            cmd = "iperf3 -sD -B {} -p {} -A{}".format(ip_address, port, core)
+        else:
+            cmd = "iperf3 -sD -B {} -p {}".format(ip_address, port)
         print("Launching: {}".format(cmd))
         try:
             check_output(shlex.split(cmd), universal_newlines=True)

Follow ups