thiezn / iperf3-python

Python wrapper around iperf3
https://iperf3-python.readthedocs.org/
MIT License
109 stars 52 forks source link

OSError: [Errno 9] Bad file descriptor #50

Open karlism opened 4 years ago

karlism commented 4 years ago

Running following code, based mostly on this example produces error:

#!/usr/bin/env python3

import iperf3

client = iperf3.Client()
client.duration = 1
client.server_hostname = '127.0.0.1'
client.port = 5201

while True:
    print('Connecting to {0}:{1}'.format(client.server_hostname, client.port))
    result = client.run()

    if result.error:
        print(result.error)
    else:
        print('')
        print('Test completed:')
        print('  started at         {0}'.format(result.time))
        print('  bytes transmitted  {0}'.format(result.sent_bytes))
        print('  retransmits        {0}'.format(result.retransmits))
        print('  avg cpu load       {0}%\n'.format(result.local_cpu_total))

        print('Average transmitted data in all sorts of networky formats:')
        print('  bits per second      (bps)   {0}'.format(result.sent_bps))
        print('  Kilobits per second  (kbps)  {0}'.format(result.sent_kbps))
        print('  Megabits per second  (Mbps)  {0}'.format(result.sent_Mbps))
        print('  KiloBytes per second (kB/s)  {0}'.format(result.sent_kB_s))
        print('  MegaBytes per second (MB/s)  {0}'.format(result.sent_MB_s))
$ python3 iperf_client_test.py 
Connecting to 127.0.0.1:5201

Test completed:
  started at         Fri, 27 Sep 2019 07:42:40 GMT
  bytes transmitted  3696230400
  retransmits        28
  avg cpu load       61.11677%

Average transmitted data in all sorts of networky formats:
  bits per second      (bps)   29553560000.0
  Kilobits per second  (kbps)  29553560.0
  Megabits per second  (Mbps)  29553.56
  KiloBytes per second (kB/s)  3607612.3046875
  MegaBytes per second (MB/s)  3523.0588912963867
Connecting to 127.0.0.1:5201
Traceback (most recent call last):
  File "iperf_client_test.py", line 12, in <module>
    result = client.run()
  File "/usr/local/lib/python3.6/site-packages/iperf3/iperf3.py", line 629, in run
    output_to_screen(self._stdout_fd, self._stderr_fd)  # enable stdout
  File "/usr/local/lib/python3.6/site-packages/iperf3/iperf3.py", line 80, in output_to_screen
    os.dup2(stdout_fd, 1)
OSError: [Errno 9] Bad file descriptor
Exception ignored in: <bound method IPerf3.__del__ of <iperf3.iperf3.Client object at 0x7f2a943b27f0>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/iperf3/iperf3.py", line 213, in __del__
OSError: [Errno 9] Bad file descriptor

Same issue experienced with UDP client example. It always fails on second iteration of the test. Additional details about test environment:

$ cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)

$ pip3 list
attrs (19.1.0)
Automat (0.7.0)
constantly (15.1.0)
filelock (3.0.12)
hyperlink (19.0.0)
idna (2.8)
incremental (17.5.0)
iperf3 (0.1.11)
pip (9.0.3)
prometheus-client (0.7.1)
PyHamcrest (1.9.0)
setuptools (39.2.0)
six (1.12.0)
Twisted (19.7.0)
zope.interface (4.6.0)

$ iperf3 -v 
iperf 3.1.7
Linux hostname 3.10.0-1062.1.1.el7.x86_64 #1 SMP Fri Sep 13 22:55:44 UTC 2019 x86_64
Optional features available: CPU affinity setting, IPv6 flow label, TCP congestion algorithm setting, sendfile / zerocopy, socket pacing

$ ps aux | grep iperf
nobody     1092  0.4  0.0   9616   992 ?        Ss   06:17   0:25 /usr/bin/iperf3 -s -f m -p 5201

Any ideas why it fails?

xsherlockpl commented 3 years ago

I have that very same error if I use the library twice in he same python script.

client2 = iperf3.Client()
client2.duration=5
client2.server_hostname = "xxx"
client2.reverse=True
print ("testing download...")
result2=client2.run()
print ("DL Sent: " + str(result2.sent_Mbps))

time.sleep(3)
client = iperf3.Client()
client.duration=5
client.server_hostname = "xxx"
print ("testing upload...")
result=client.run()
print ("UL Sent: " + str(result.sent_Mbps))

If will crash on the end of second test, if I run just one direction and create just 1 client then it is fine.

perfecto25 commented 2 years ago

easy way to fix this , just unset the client var

    targets = ['server1', 'server2']

    for target in targets:
        client = iperf3.Client()
        ## do iperf stuff
        client = None

this makes the For loop work

rexlim820220 commented 3 months ago

I also encounter the same issue. No matter if client runs in either udp or tcp mode:

Differ from @xsherlockpl's case, I use a multiprocessing to create two threads to the reproduce issue, in which both of the threads mainly run iperf client.

The following shows most recent call trace back log:

Traceback (most recent call last):
  File "/usr/lib/python3.9/multiprocessing/util.py", line 300, in _run_finalizers
    finalizer()
  File "/usr/lib/python3.9/multiprocessing/util.py", line 224, in __call__
    res = self._callback(*self._args, **self._kwargs)
  File "/usr/lib/python3.9/multiprocessing/managers.py", line 874, in _decref
    tls.connection.close()
  File "/usr/lib/python3.9/multiprocessing/connection.py", line 182, in close
    self._close()
  File "/usr/lib/python3.9/multiprocessing/connection.py", line 366, in _close
    _close(self._handle)
OSError: [Errno 9] Bad file descriptor

It seems that repeatedly create iperf3.Client() object will raise this problem due to the library's own pitfall.