Comment configurer D-Bus et SSH X-Forwarding pour empêcher SSH de se bloquer en quittant?

19

J'essaie d'exécuter diverses applications Gnome via X11 Forwarding et SSH. Certaines applications provoqueront le lancement de l'application «dbus-launch» en premier. Le problème est que dbus-launch ne se ferme pas lorsque l'application X est fermée, et doit donc être tué avant que la session SSH puisse être fermée correctement.

Je suppose que le problème est que les applications X / Gnome ne peuvent pas se connecter avec le démon de bus de messages principal et doivent donc lancer leur propre copie? Comment puis-je réparer cela? Ou qu'est-ce qui me manque?

Voici un exemple. J'ai activé le transfert X11, tout semble bien fonctionner.

[me@host ~]$ gnome-calculator &
[1] 4803

(ici le programme gcalctool se lance et s'affiche sur mon serveur X remove (Xming))

[me@host ~]$ ps
  PID TTY          TIME CMD
 4706 pts/0    00:00:00 bash
 4803 pts/0    00:00:00 gnome-calculator
 4807 pts/0    00:00:00 dbus-launch
 4870 pts/0    00:00:00 ps

(maintenant, après avoir fermé l'application gcalctool dans la session distante)

[me@host ~]$ ps
  PID TTY          TIME CMD
 4706 pts/0    00:00:00 bash
 4807 pts/0    00:00:00 dbus-launch
 4898 pts/0    00:00:00 ps

Notez que le lancement de dbus est toujours actif. Et le pire, cela empêche la connexion SSH de se fermer correctement jusqu'à ce qu'elle soit tuée.

Notez que le démon de message à l'échelle du système est en cours d'exécution, comme on peut le voir ici:

[me@host ~]$ ps ax
 4696 ?     Ssl   0:00 dbus-daemon --system

Qu'est-ce que j'oublie ici? Je n'ai jamais vu ce comportement auparavant. Vraisemblablement, je n'ai vu que des applications qui peuvent se connecter au démon de bus de messages sans entrave? J'ai cherché dans / etc / dbus-1 des réponses, mais je ne sais pas quoi chercher.

Merci d'avance pour l'aide.

[ÉDITER]

OK, je me rends compte que je rencontre un problème commun. Il semble que ce soit un comportement assez courant, mais sans une bonne solution. Je rencontre le blocage SSH parce que le lancement de dbus est toujours actif dans le terminal. Mais il n'y a apparemment aucun bon moyen pour que le lancement du dbus se déroule tranquillement.

Regarder /etc/X11/xinit/xinitrc.d/00-start-message-bus.sh donne un indice sur ce qui est censé se passer avec une session X "normale". Bien sûr, cela ne fonctionne pas lorsque vous appelez simplement une application X à un serveur X distant.

Comme solution temporaire, j'ai ajouté ceci à mon .bash_logout:

# ~/.bash_logout
pkill -u $USER -t `tty | cut -d '/' -f 3,4` dbus-launch

Cela permettra à la session SSH de se terminer, mais cela semble délirant. Existe-t-il de meilleures solutions? Quelle est la bonne façon d'exécuter des applications X11 à distance sans que dbus ne gêne?

taftster
la source

Réponses:

15

Par lancement dbus (1):

Si DBUS_SESSION_BUS_ADDRESS n'est pas défini pour un processus qui essaie d'utiliser D-Bus, par défaut, le processus tentera d'appeler dbus-launch avec l'option --autolaunch pour démarrer un nouveau bus de session ou trouver l'adresse de bus existante sur l'écran X ou dans un fichier dans ~ / .dbus / session-bus /

Chaque fois qu'un lancement automatique se produit, l'application qui devait démarrer un nouveau bus sera dans son propre petit monde; il peut effectivement finir par démarrer une toute nouvelle session s'il essaie d'utiliser beaucoup de services de bus. Cela peut être sous-optimal ou même totalement rompu, selon l'application et ce qu'elle essaie de faire.

Il existe deux raisons courantes pour le lancement automatique. L'un est ssh vers une machine distante.

Il semble donc que l'astuce consiste à démarrer dbus-daemon de manière préventive, de telle sorte que les programmes puissent le trouver. J'utilise:

[me@host ~]$ dbus-launch --exit-with-session gnome-terminal

qui, à part gnome-terminal, démarre dbus-daemon et définit $ DBUS_SESSION_BUS_ADDRESS dans gnome-terminal .

Tous les programmes X exécutés à partir de gnome-terminal se comportent ensuite correctement et dbus-launch se nettoie après lui-même lorsque gnome-terminal se ferme.

Nathan
la source
J'ai marqué cela comme la réponse, j'aime votre solution ici. Je vous remercie. Le lancement d'un gnome-terminal d'abord, puis le lancement de programmes supplémentaires à partir de celui-ci semble résoudre mon problème. Mais est-ce un nouveau comportement? Je me souviens apparemment avoir pu lancer de nombreuses fenêtres transférées X sans avoir ce problème. Peut-être que les nouveaux programmes Gnome utilisent Dbus maintenant, donc je ne l'ai pas encore vu?
taftster
2

Je me demande si le problème ne vient pas à cause d'une session dbus inconnue ou inexistante.

En effet, lorsqu'une session SSH est ouverte, elle ne lance pas de session dbus. Certains programmes peuvent le lancer, mais la session ne le sait pas (il ne peut donc pas le fermer).

Ne pas connaître la session dbus signifie également que les programmes qui utilisent dbus mais ne le lancent pas eux-mêmes auront des problèmes.

Les sections dbus sont par machine et par écran X11. Leurs informations sont stockées dans $ HOME / .dbus / session-bus / - cependant, le processus référencé peut être fermé, donc une vérification supplémentaire est nécessaire pour déterminer si le lancement de dbus est nécessaire ou non. Ensuite, les variables doivent être exportées vers la session.

Ensuite, cela fonctionne comme un charme :)

J'ai mis ce qui suit dans mon fichier .bash_profile:

# set dbus for remote SSH connections
if [ -n "$SSH_CLIENT" -a -n "$DISPLAY" ]; then
    machine_id=$(LANGUAGE=C hostnamectl|grep 'Machine ID:'| sed 's/^.*: //')
    x_display=$(echo $DISPLAY|sed 's/^.*:\([0-9]\+\)\(\.[0-9]\+\)*$/\1/')
    dbus_session_file="$HOME/.dbus/session-bus/${machine_id}-${x_display}"
    if [ -r "$dbus_session_file" ]; then
            export $(grep '^DBUS.*=' "$dbus_session_file")
            # check if PID still running, if not launch dbus
            ps $DBUS_SESSION_BUS_PID | tail -1 | grep dbus-daemon >& /dev/null
            [ "$?" != "0" ] && export $(dbus-launch) >& /dev/null
    else
            export $(dbus-launch) >& /dev/null
    fi
fi

notes: hostnamectl fait partie de systemd et permet de récupérer l'id machine le lancement dbus affiche les variables que nous voulons; en utilisant export $(dbus-launch)nous récupérons la sortie de dbus-launch et exportons les variables

si vous voulez que cela se fasse sur sessio non interactif (par exemple lorsque vous exécutez une commande à partir de ssh) essayez plutôt de le mettre dans .bashrc (mais attention à ce que bashrc soit exécuté sur le shell ouvert d'EVEERY)

Pablo Saratxaga
la source
1

J'ai eu le même problème lors de la tentative d'exécution d'une commande X distante et de la fermeture de la session après la fermeture de l'outil X.

Je voulais donc courir

ssh -X user@remotehost "firefox -no-remote"

Mais a dû utiliser:

ssh -X user@remotehost 'export \`dbus-launch\`; dbus-launch firefox -no-remote; kill -TERM $DBUS_SESSION_BUS_PID'

Après la fermeture de Firefox, cela fermerait également la session SSH.

Mise à jour :

Cela semble laisser une charge de processus dbus-daemon en cours d'exécution sur le serveur, donc ce n'est pas optimal, l'ajout de --exit-with-session sur les deux comptes n'aide pas, car cela annule le comportement d'origine

mise à jour 2 : cela fonctionne lorsque j'utilise des guillemets simples (comme suggéré par @lobo) et en ajoutant kill -TERM $DBUS_SESSION_BUS_PIDpour tuer les processus dbus-daemon restants, comme proposé par Holgr Joukl à partir de https://blog.dhampir.no/content/how- pour-empêcher-ssh-x-de-suspendre-sur-sortie-quand-dbus-est-utilisé )

Jens Timmerman
la source
Vous devez utiliser des guillemets simples dans la dernière commande (sinon elle dbus-launchest exécutée localement ), mais cela fonctionne. Merci!
l0b0