2017-06-21 4 views
3

Ich experimentiere mit Linux Namespaces. Insbesondere der PID-Namespace.unshare --pid/bin/bash - fork kann Speicher nicht reservieren

Ich dachte, ich etwas aus mit bash testen würde, aber dieses Problem auftreten:

unshare -p /bin/bash 
bash: fork: Cannot allocate memory 

Lauf ls von dort einen Core Dump gab. Exit ist das einzig mögliche.

Warum macht es das?

Antwort

3

Der Fehler wird durch die PID-1-Prozess beendet im neuen Namensraum verursacht.

Nach Bash zu starten, Bash wird mehrere neue Teilprozesse fork etwas zu tun. Wenn Sie unshare ohne -f ausführen, hat bash dieselbe PID wie der aktuelle "unshare" -Prozess. Der aktuelle "unshare" -Prozess ruft den unshare-Systemaufruf auf, erstellt einen neuen PID-Namespace, aber der aktuelle "unshare" -Prozess befindet sich nicht im neuen PID-Namespace. Es ist das gewünschte Verhalten des Linux-Kernels: Prozess A erstellt einen neuen Namespace, der Prozess A selbst wird nicht in den neuen Namespace eingefügt, nur die Unterprozesse von Prozess A werden in den neuen Namespace eingefügt. Also, wenn Sie laufen:

 
unshare -p /bin/bash 

Der unshare Prozess wird exec/bin/bash und/bin/bash Gabeln mehrere Teilprozesse, die erste Teilprozess von bash PID werden 1 des neuen Namensraum, und Der Subprozess wird beendet, nachdem er seinen Job abgeschlossen hat. Daher wird die PID 1 des neuen Namespace beendet.

Der PID-1-Prozess hat eine spezielle Funktion: Er sollte zum übergeordneten Prozess aller verwaisten Prozesse werden. Wenn der PID 1-Prozess im Root-Namespace beendet wird, wird der Kernel in Panik versetzt. Wenn der Prozess PID 1 in einem Sub-Namespace beendet wird, ruft der Linux-Kernel die Funktion disable_pid_allocation auf, die das Flag PIDNS_HASH_ADDING in diesem Namespace bereinigt. Wenn der Linux-Kernel einen neuen Prozess erstellt, ruft der Kernel die Funktion alloc_pid auf, um eine PID in einem Namespace zuzuweisen, und wenn das PIDNS_HASH_ADDING-Flag nicht gesetzt ist, gibt die Funktion alloc_pid einen -ENOMEM-Fehler zurück. Deshalb haben Sie den Fehler "Speicher nicht zuordnen" erhalten.

Sie können dieses Problem durch die Verwendung lösen die ‚-f‘ Option:

 
unshare -fp /bin/bash 

Wenn Sie laufen unshare mit ‚f‘ Option, unshare wird einen neuen Prozess Gabel, nachdem er den neuen pid Namespace erstellen. Und run/bin/bash im neuen Prozess. Der neue Prozess wird die PID 1 des neuen PID-Namespace sein. Dann wird Bash auch mehrere Unterprozesse forkieren, um einige Jobs zu erledigen. Da bash selbst die PID 1 des neuen PID-Namespaces ist, können seine Unterprozesse problemlos beendet werden.

+0

Um diese sehr hilfreiche Antwort mit einigen Manpage Referenzen zu unterstützen: ['man 2 unshare'] (http://man7.org/linux/man-pages/man2/unshare.2.html) sagt über' CLONE_NEWPID ': _Nehmen Sie den PID-Namespace auf, so dass der aufrufende Prozess einen neuen PID-Namespace für seine untergeordneten Elemente hat, der nicht mit einem zuvor vorhandenen Prozess gemeinsam genutzt wird. Der aufrufende Prozess wird nicht in den neuen Namespace verschoben. ** Das erste Kind, das vom aufrufenden Prozess erstellt wurde, hat die Prozess-ID 1 ** und übernimmt die Rolle von init (1) im neuen Namespace._ – nh2

1

Dies erklärt nicht warum dies geschieht, zeigt aber, wie man richtig in einem neuen pid Namespace eine Shell starten:

Verwenden Sie die -f Flagge die Schale von unshare Gabel aus:

unshare -fp /bin/bash 

Sie müssen auch die --mount-proc-Option übergeben, um sicherzustellen, dass die Shell PID 1 im neu erstellten Namespace erhält:

unshare -fp --mount-proc /bin/bash 

Jetzt laufen ps:

# ps 
    PID TTY   TIME CMD 
1 pts/1 00:00:00 bash 
11 pts/1 00:00:00 ps 
Verwandte Themen