Мы используем paramiko для создания библиотеки соединений, которая активно использует свои функции get_pty
или invoke_shell
. Наша библиотека использует эти каналы для взаимодействия с целевым устройством.
Но всякий раз, когда мы используем библиотеку multiprocessing
, мы не можем использовать дескрипторы соединения paramiko в дочернем процессе. transport
закрывается в дочернем процессе.
Is there a way to tell paramiko not to close the connection/channel at fork.
Это пример программы для воспроизведения проблемы
from paramiko import SSHClient, AutoAddPolicy
from multiprocessing import Process
import logging
log = logging.getLogger("paramiko.transport").setLevel(1)
client = SSHClient()
client.set_missing_host_key_policy(AutoAddPolicy())
client.connect(hostname="localhost")
def simple_work(handle):
print("==== ENTERED CHILD PROCESS =====")
stdin, stdout, stderr = handle.exec_command("ifconfig")
print(stdout.read())
print("==== EXITING CHILD PROCESS =====")
p = Process(target=simple_work, args=(client,))
p.start()
p.join(2)
print("==== MAIN PROCESS AFTER JOIN =====")
stdin, stdout, stderr = client.exec_command("ls")
print(stdout.read())
и это ошибка
==== ENTERED CHILD PROCESS =====
Success for unrequested channel! [??]
==== MAIN PROCESS AFTER JOIN =====
Traceback (most recent call last):
File "repro.py", line 22, in <module>
stdin, stdout, stderr = client.exec_command("ls")
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/client.py", line 401, in exec_command
chan = self._transport.open_session(timeout=timeout)
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/transport.py", line 702, in open_session
timeout=timeout)
File "/Users/vivejha/Projects/cisco/lib/python3.4/site-packages/paramiko/transport.py", line 823, in open_channel
raise e
paramiko.ssh_exception.SSHException: Unable to open channel.
Несколько важных вещей, на которые стоит обратить внимание
Если я попытаюсь получить доступ к
client
в дочернем процессе. Во-первых, он вообще не работает.Во-вторых, ручка в основном процессе тоже отмирает на удивление. Я не знаю, как облегчается это общение между детьми и родителями и почему.
И самая большая проблема в том, что программа зависает в конце, исключение в порядке, но зависания менее всего ожидаемы.
Если я не использую
client
в дочернем процессе и выполняю какую-то другую работу, тоclient
в родительском процессе не затрагивается и работает как обычно.
ПРИМЕЧАНИЕ. В файле transport.py есть что-то под названием atfork
, которое утверждает, что управляет этим поведением. Но, что удивительно, даже комментирование кода в этом методе не имеет никакого значения. Также во всей кодовой базе paramiko нет ссылок на atfork
.
PS: я использую последнюю версию paramiko, и эта программа была запущена на Mac.