スクリプトで開始されたSSHプロセスの一時停止

スクリプトで開始されたSSHプロセスの一時停止

スクリプトを通じていくつかの仮想マシンを作成しています。その一環として、SSHを使用して仮想マシンの名前を変更します。何らかの理由で3つのVMに対して次のコマンドを実行すると機能しますが、7つのVMを作成するとマジック番号の場合はSSHがハングします。誰かがこの動作を説明できますか?

スクリプトの一部。このスクリプトは、指定されたX仮想マシンに対して同時に実行されます。

...
ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts
SSH="ssh -i $SSH_KEY -o PasswordAuthentication=no"

echo "hostname $hostname && 
    echo HOSTNAME=$hostname >> /etc/sysconfig/network && 
    echo 127.0.0.1 $hostname >> /etc/hosts " | ssh -i $SSH_KEY -o PasswordAuthentication=no root@IP
...

中断のないSSHプロセス

rag       2867  2808  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm4
rag       2869  2812  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm7
rag       2872  2818  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm1
rag       2875  2811  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm6
rag       2879  2814  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm5
rag       2881  2813  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm3
rag       2884  2807  0 01:05 pts/5  T  00:00:00 ssh -i ssh_key -o PasswordAuthentication=no root@vm2

実行中のプロセスの1つを追跡しました。

...
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
rt_sigreturn(0x16)                      = -1 EINTR (Interrupted system call)
rt_sigaction(SIGALRM, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGHUP, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTSTP, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTTIN, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, NULL, 8) = 0
close(4)                                = 0
kill(2867, SIGTTOU)                     = 0
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
--- SIGTTOU (Stopped (tty output)) @ 0 (0) ---
open("/dev/tty", O_RDWR)                = 4
rt_sigaction(SIGALRM, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGHUP, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGINT, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGPIPE, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_IGN, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGQUIT, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTERM, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTSTP, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTTIN, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
rt_sigaction(SIGTTOU, {0x7fd26e1ef540, [], SA_RESTORER, 0x7fd26cd9d4a0}, {SIG_DFL, [], SA_RESTORER, 0x7fd26cd9d4a0}, 8) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(4, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 opost isig icanon echo ...}) = ? ERESTARTSYS (To be restarted)
...

ベストアンサー1

これは競合状態のように聞こえますが、スクリプトを見ると理解になるようです。

私が理解したのは、次の2行を含むスクリプトです。

ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts

その後、スクリプトを数回起動します。

次の一連のイベントによって問題が説明されることがあります。

  1. コマンドを~/.ssh/known_hosts実行するためにスクリプトの1つが開きます。ssh-keygen -Rこの時点で、ssh-keygenコマンドはターゲット行を削除できるようにファイル全体をメモリに読み込みました。
  2. 他のスクリプトが実行したばかりで、ファイルにその行を書きssh-keyscanました。
  3. 最初のスクリプトのssh-keygenプロセス(ステップ1のプロセス)はファイルの書き込みを開始しますが、ステップ2が完了する前にファイルを読み取るため、作成するファイルにはステップ2で追加された行は含まれません。したがって、2 段階の行が消去されます。
  4. ssh手順3で説明した問題により、ホストキーが入力されていないことを除いて2番目のスクリプトが実行されます。known_hostsそのため、ssh が中断され、ユーザーに鍵の確認を要求します。

詳細:
バックグラウンドプログラムは端末からデータを読み取ることができません。そうしようとすると、プログラムはSIGTTINを受け取ります。しかし、あなたの追跡は、プログラムがSIGTTOUを受け取ったことを示しています。通常、デーモンは問題なく端末に書き込むことができますが、OpenSSHは明示的に呼ばれる端末設定を開いてtostopこの動作を引き起こします。また、OpenSSHにはSIGTTOUにシグナルハンドラがあり、プロセスをフォアグラウンドにインポートするまで(プロンプトが表示され、信号の受信が停止するまで)OpenSSHコードが無限ループに陥ります。

この問題をどのように解決したいのかは別の問題です。

  • 1つの解決策は、ロックを追加し(flockユーティリティを使用できます)、known_hostsこの2行の前にファイルをロックし、完了したらロックを解除することです。
  • 別の解決策はSSHオプションを追加することですStrictHostKeyChecking=no。これらの2行のスクリプトでファイルの目的が失われたので、両方をknown_hosts無効にすることをお勧めします。

おすすめ記事