0

Previous details
I need to ssh on a switch to ping different hosts. Earlier I started a thread for each host but turned out to exceed the maximum ssh connection number easily so I created a interactive shell session according to this. But when I ran in parallel it kept hanging in there after sending first command. I have no idea how to fix this.
Simplified code listed below:

import paramiko
import time
from paramiko import SSHClient
from multiprocessing.dummy import Pool

def rping(src, user, passwd, dst):

    def command(des):
        chan.send('ping -s 64 -t 1500 %s\r\n' % des)
        time.sleep(3)
        resp = chan.recv(9999)
        print resp

    ssh = SSHClient()
    ssh.load_system_host_keys()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(src, 22, user, passwd, timeout=3)

    chan = ssh.invoke_shell()

    pool = Pool()
    pool.map(command, dst)
    pool.close()
    pool.join()


if __name__ == '__main__':
    print time.ctime()

    src = '10.130.1.121'
    user = 'user'
    passwd = 'password'
    dst = ['10.130.1.122', '10.130.1.123', 10.130.1.124'']
    rping(src, user, passwd, dst)

    print time.ctime()
Community
  • 1
  • 1
J.Wang
  • 1,241
  • 3
  • 13
  • 17

1 Answers1

0

Bear in mind using multiprocessing.dummy is actually working with the threading module. Given this, your command function is not returning anything.

def rping(src, user, passwd, dst):
    def command(des):
        chan = ssh.invoke_shell()  # new channel 
        chan.send('ping -t 64 -s 1500 -c 3 %s\r\n' % des)
        time.sleep(3)
        resp = chan.recv(9999)
        chan.close()  # close channel
        return resp

    ssh = SSHClient()
    ssh.load_system_host_keys()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(src, 22, user, passwd, timeout=3)

    pool = Pool(len(dst))
    result = pool.map(command, dst)
    pool.close()
    pool.join()
    ssh.close()  # close SSH client
    return result
fernandezcuesta
  • 2,390
  • 1
  • 15
  • 32
  • The process is still hanging, but if I replace `pool.map()` with `for` loop it worked well but consuming more time – J.Wang Apr 11 '16 at 10:49
  • I see that ping arguments seem to be swapped and actually the command is never ending. Edited the answer to fix it and add a `-c 3` so only 3 ICMP echo requests are sent. – fernandezcuesta Apr 11 '16 at 11:19
  • The default number of packets is 5 if not specified. This script worked fine in serial using `for` loop , but failed and hanging there in parallel using `pool.map()` – J.Wang Apr 11 '16 at 12:33
  • OK I see what happens is that you must define a new channel per command/iteration. Running the other way on a for loop obviously works fine. See edit above. – fernandezcuesta Apr 11 '16 at 13:30
  • Not working, it seems one ssh client can only create one channel, and it returns `ChannelException: (4, 'Resource shortage')` @valtuarte – J.Wang Apr 12 '16 at 01:06
  • This might be something related to your SSH server. With OpenSSH that code works. What you can try is to put the ssh client part inside the `command` function and see what happens. – fernandezcuesta Apr 12 '16 at 08:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/108915/discussion-between-valtuarte-and-j-wang). – fernandezcuesta Apr 12 '16 at 10:07