Ihr wisst noch, daĂ man nicht so genau hinsehen sollte, wenn man mehr Freizeit haben will? đ Den Grundsatz habe ich mal wieder bei RDP ignoriert und bin prompt in die Falle getappt.
XRDP, die Session und das screen-Tool
Wer von Euch weiĂ, was PID 1 ist? Ok, eine rhetorische Frage, jeder weiĂ das. FĂŒr die, die das vergessen haben, kleine Auffrischung:
Der erste Prozess, der beim Start des PCs erstellt wird, hat die Process-ID 1 ( PID ). Jeder andere Prozess danach, ist ein Kind(Child) vom Prozess mit PID 1. Der Prozess ist also das Elternteil(Parent) von dem gestarteten Prozess. Beim Systemd-Init-System heiĂt der PID 1 Prozess sinnigerweise „systemd“, beim VorgĂ€nger System-V wars noch „init“.
Beispiel:
systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352) | `-{ModemManager}(1354) |-NetworkManager(1319)-+-{NetworkManager}(1360) | `-{NetworkManager}(1362)
Hier im Beispiel, ist systemd(1) der Eltern-Prozess und ModemManager(1300) und NetworkManager(1319) sind die Kinder-Prozesse. Wenn der Rechner runtergefahren wird, terminiert der PID1 Prozess alle seine Kinder-Prozesse und wenn keins mehr da ist, beendet er sich selbst, in dem er der HW das Strom-Aus-Kommando sendet.
Merke: Alle Prozesse sind Kinder oder Kinds-Kinder von PID1, weil das eine baumartige Struktur ist.
Wer sich das mal selbst ansehen will: einfach „pstree -up | less“ in ein Terminalfenster eingeben.
Was passiert, wenn der Elternprozess eines Kindes terminiert wird und dieser Elternprozess nicht PID1 ist?
Im Beispiel oben, terminieren wir mal gedanklich den NetworkManager(1319) der ja 1360 und 1362 als Kinder hat. Was jetzt passiert ist, daĂ die Kinder-Prozesse als Waisen dem PID1 ĂŒbertragen werden. Sie bekommen also einen neuen Eltern-Prozess, aber sonst Ă€ndert sich nichts: Sie laufen i.d.R. weiter.
Es gibt auch Situationen, wo das nicht der Fall ist, aber die lassen wir mal aus.
Ich merke gerade ich muĂ weiter ausholen, sonst verstehen das nicht alle Leser, daher nicht wundern, wenn alles etwas schlicht gehalten ist und es einem trotzdem wie eine WĂŒstenwanderung ohne Wasser vorkommt.
Der Benutzer meldet sich an
Stellen wir uns vor, Systemd hat das System(PC) soweit hochgefahren, daĂ uns am Monitor eine Anmeldemaske(Login-Dialog) begrĂŒĂt. Wenn der Benutzer einloggt(sich anmeldet), wird die Desktop-Session gestartet, das kann z.b. Gnome, Cinnamon oder sonst eine andere Deskopumgebung sein. Die Startet dann wieder Programme bis so eine ArbeitsoberflĂ€che entstanden ist, wie man die von Fotos kennt:
Es laufen jetzt rudelweise Prozesse im Namen des Benutzers:
systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352) ... Â |-csd-printer(2448,marius)-+-{csd-printer}(2449) | `-{csd-printer}(2450) |-cupsd(1364) |-dbus-broker-lau(1276,dbus)---dbus-broker(1277) |-dbus-daemon(5007,marius)---{dbus-daemon}(5011) |-dbus-daemon(5153,marius)---{dbus-daemon}(5154) |-dbus-daemon(5282,marius)---{dbus-daemon}(5283) |-dbus-daemon(5868,marius)---{dbus-daemon}(5869) |-dbus-daemon(8160,marius)---{dbus-daemon}(8161) |-dbus-daemon(12280,marius)---{dbus-daemon}(12281) |-dbus-daemon(27861,marius)---{dbus-daemon}(27862) |-dconf-service(5201,marius)-+-{dconf-service}(5202) | `-{dconf-service}(5203) |-dconf-service(5330,marius)-+-{dconf-service}(5331) | `-{dconf-service}(5332) |-dconf-service(5372,marius)-+-{dconf-service}(5378) | `-{dconf-service}(5379) |-dconf-service(5924,marius)-+-{dconf-service}(5925) | `-{dconf-service}(5926) |-dconf-service(12329,marius)-+-{dconf-service}(12330) | `-{dconf-service}(12331) |-dconf-service(28004,marius)-+-{dconf-service}(28007) | `-{dconf-service}(28008) ...
und die sind, wie man oben sehen kann, Kinder vom PID1. Die „AusreiĂer“-Prozesse die auch laufen, wenn sich kein Benutzer anmeldet, habe ich mal rot markiert. Die gehören i.d.R. root oder einem Servicebenutzer „nobody“,“www-data“,“mysql“ so in der Art. Die werden gleich wichtig.
Wenn der Benutzer sich ausloggt
Kommen wir zu dem Punkt, wo sich der Benutzer aus dem PC ausloggt. Der Abmelden-Vorgang(Logout) stöĂt eine Kaskade an, die alle Benutzerprozesse terminiert. Wenn keine anderen Prozesse mehr laufen, dann terminiert sich der PID1 auch. I.d.R. ist das aber nicht der Fall, weil Root ja auch ein ganzes Rudel an Diensten gestartet hat, die alle Kind von PID1 sind.
Screen
Wenn man auf verschiedenen Servern zu tun hat, kommt man unweigerlich an den Punkt, wo man Programme laufen lassen muĂ die tage- oder wochenlang laufen mĂŒssen (ggf. auch ewig) oder man muĂ einfach zwischenzeitlich mal weg und will den Arbeitsstand den man erreicht hat nicht verlieren.
Einen Desktop-PC wĂŒrde man einfach nicht abschalten und als Benutzer nur den Bildschirm sperren. Wenn man sich aber doch mal als anderer Benutzer an dem PC anmelden muĂ, und die Programme trotzdem nicht beendet werden sollen, kommt „screen“ ins Spiel.
Dies startet man in einer Konsole bevor man mit der Arbeit anfĂ€ngt. Wenn man sich auf einem entfernten Server per SSH anmeldet, ist es oft der einzige Weg, wie man sicherstellen kann, daĂ ein Verbindungsverlust nicht im Desaster endet. Screen kann man aber natĂŒrlich auch in einem Desktop-Terminal starten.
Ich kann also als Benutzer meinem PC auch in einer Screensitzung lÀngerfristig mit Aufgaben versorgen, mich dann ausloggen oder Bildschirm sperren und per SSH von Zuhause aus nachsehen, ob die Prozesse noch laufen oder schon fertig sind. Da jeder mit der richtigen Berechtigung eine Screensitzung betreten kann, kann ich dann also auch von Zuhause aus an der Stelle weiter machen, wo ich aufgehört habe.
Wenn ich das nur in einem Terminalfenster als eingeloggter Desktopbenutzer mache, kann ich das nicht tun, da man das Terminal nicht von auĂen betreten kann.
Damit dĂŒrfte die Idee hinter Screen klar sein:
Screen starten, Programme arbeiten lassen, die Benutzersitzung am Desktop oder per SSH beenden und dann spÀter von irgendwo anders fortsetzen.
Jetzt kommt XRDP ins Spiel
Nun hatte ich einen PC bei einer Firma, den ich per getunneltem RDP von auĂen mit einer Desktop-Session benutzt habe und wollte die stundenlange Kopieraktion in einer Screensitzung laufen lassen und mich dann ausloggen. RDP hat das Problem, daĂ man nicht gleichzeitig per RDP und am Bildschirm eingeloggt sein kann.
Also muĂ man die Remote-RDP-Sitzung beenden, falls man am Bildschirm einloggen muĂ, weil der Job so lange lief, daĂ man schon wieder im BĂŒro ist. Das passiert öfters als man glauben mag.
Wenn man das tut, vertraut man darauf, daĂ man ja screen gestartet hatte und der Prozess noch da ist, wenn man wieder ins BĂŒro kommt. War er aber nicht.
Ta Ta Daaaaaaa !!!
Eine per XRDP gestartete Desktop-Session bekommt nĂ€mlich einen eigenen systemd Prozess als Startprozess, genau wie der PC beim hochfahren auch, nur das dieser systemd Prozess keine anderen Dienste gestartet hat und daher alle seine Kinderprozesse terminiert, wenn die Sitzung endet… auch Screen!
Beispiel:
systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352) | `-{ModemManager}(1354) |-NetworkManager(1319)-+-{NetworkManager}(1360) | `-{NetworkManager}(1362) ... |-gnome-terminal-(5111,marius)-+-bash(5412)---screen(13881)---screen(13882)---bash(13883)-+-less(14632) | | `-pstree(14631) ... |-systemd(5996,remote)-+-(sd-pam)(6006) | |-abrt-applet(6657)-+-{abrt-applet}(6671) | | |-{abrt-applet}(6672) ... | | `-{evolution-calen}(7037) | |-evolution-sourc(6381)-+-{evolution-sourc}(6383) | | |-{evolution-sourc}(6384) | | `-{evolution-sourc}(6385) | |-gnome-shell-cal(6374)-+-{gnome-shell-cal}(6378) | | |-{gnome-shell-cal}(6380) | | |-{gnome-shell-cal}(6432) | | |-{gnome-shell-cal}(6433) | | `-{gnome-shell-cal}(7050) | |-gnome-terminal-(11250)-+-bash(11424)---screen(21255)---screen(21326)---bash(21331)---les+ | | |-{gnome-terminal-}(11277) | | |-{gnome-terminal-}(11278) | | `-{gnome-terminal-}(11310) ...
In dem Auszug oben seht Ihr den Unterschied:
systemd(1) -> systemd(????) -> gnome-terminal -> bash -> screen
statt:
systemd(1) -> gnome-terminal -> bash -> screen
Da systemd(????) (die ???? stehen fĂŒr eine beliebige PID) nach dem Logout keine Prozesse von „anderen“ Benutzer gestartet hat, terminiert er sich auch selbst, was dann in Folge auch das Screen noch terminiert.
In der Desktopkette (in grĂŒn) bleibt der systemd (1) Prozess stehen, weil noch andere Prozesse von anderen Benutzern laufen (inkl. root), deswegen wird Screen dann nicht terminiert und lĂ€uft weiter.(denkt dran, einfache Darstellung đ )
Am Beispiel von SSH schön zu sehen:
|-sshd(20153)-+-sshd(21640)—sshd(21661)—bash(21671)—screen(22867)—screen(22881)—bash(22882)
wird zu
|-screen(22881)—bash(22882)
Merke:
Wenn Du per XRDP eingeloggt bist und screen benutzen willst, melde Dich lokal per SSH an, starte dann screen und arbeite damit.
Es klingt bescheuert, weil man von Screen genau erwarten wĂŒrde, daĂ es weiterlĂ€uft, aber es passiert halt nicht, weil der das screen in der Konsequenz startende Prozess ( systemd(????) ), alles terminert, weil er selbst terminieren will/muĂ.
Ich befĂŒrchte wir bekommen Pöttering nicht dazu, dafĂŒr eine Ausnahme in systemd einzubauen und mĂŒssen damit leben.