ich erstelle einige VMs über ein Skript. Dabei ändere ich die Namen der VMs mithilfe von SSH. Aus irgendeinem Grund funktioniert der folgende Befehl, wenn ich ihn für drei VMs ausführe, aber bei der magischen Zahl beim Erstellen von sieben VMs bleibt SSH hängen. Kann jemand bitte das Verhalten erklären?
Teil des Skripts. Dieses Skript wird gleichzeitig für angegebene X-VMs ausgeführt.
...
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
...
nicht endende SSH-Prozesse
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
ich habe Strace bei einem der laufenden Prozesse bekommen.
...
--- 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)
...
Antwort1
Das klingt nach einem Wettlaufzustand, und wenn ich mir Ihr Skript anschaue, glaube ich zu wissen, wo.
So wie ich es verstehe, haben Sie ein Skript, das (unter anderem) die folgenden 2 Zeilen enthält:
ssh-keygen -f ~/.ssh/known_hosts -R $IP
ssh-keyscan $IP >> ~/.ssh/known_hosts
Und dann starten Sie das Skript mehrmals.
Die folgende Abfolge von Ereignissen kann Ihr Problem erklären:
- Eines der Skripts wird geöffnet,
~/.ssh/known_hosts
um den Befehl auszuführenssh-keygen -R
. An diesem Punktssh-keygen
liest der Befehl die gesamte Datei in den Speicher, damit er die Zielzeile entfernen kann. - Ein anderes Skript wurde gerade ausgeführt
ssh-keyscan
und die Zeile in die Datei geschrieben. - Der Prozess des ersten Skripts
ssh-keygen
(der aus Schritt 1) beginnt mit dem Schreiben der Datei, aber da er die Datei gelesen hat, bevor Schritt 2 abgeschlossen war, enthält die geschriebene Datei nicht die Zeile, die Schritt 2 hinzugefügt hat. Daher wird die Zeile aus Schritt 2 gelöscht. - Das zweite Skript führt dies aus
ssh
, aber der Hostschlüssel fehltknown_hosts
aufgrund des in Schritt 3 genannten Problems. Daher bleibt SSH hängen und der Benutzer muss den Schlüssel bestätigen.
Genauere Einzelheiten:
Hintergrundprogramme können nicht vom Terminal lesen. Wenn Sie dies versuchen, wird dem Programm eine SIGTTIN gesendet. In Ihrem Strace wird jedoch angezeigt, dass das Programm eine SIGTTOU erhält. Normalerweise können Hintergrundprogramme problemlos in das Terminal schreiben, OpenSSH aktiviert jedoch ausdrücklich eine Terminaleinstellung namens , tostop
die zu diesem Verhalten führt. OpenSSH geht sogar noch weiter und verfügt über einen Signalhandler für SIGTTOU (unter anderem), der dazu führt, dass der OpenSSH-Code in eine Endlosschleife gerät, bis Sie den Prozess in den Vordergrund bringen (an diesem Punkt kann er die Eingabeaufforderung anzeigen und keine Signale mehr erhalten).
Wie Sie dieses Problem lösen möchten, ist eine andere Frage.
- Eine Lösung wäre, eine Sperre hinzuzufügen (dafür gibt es ein
flock
Dienstprogramm, das Sie verwenden können) und dieknown_hosts
Datei vor diesen beiden Zeilen zu sperren und sie danach zu entsperren. - Eine andere Lösung wäre, die Option „ssh“ hinzuzufügen
StrictHostKeyChecking=no
. Mit diesen beiden Zeilen des Skripts machen Sie den Zweck derknown_hosts
Datei bereits zunichte, daher können Sie sie auch gleich ganz deaktivieren.