1 votes

Pourquoi systemd n'exécute-t-il pas mon ExecStartPre script ?

J'ai deux cartes graphiques, et je dois configurer xorg pour utiliser la bonne carte en fonction de l'option de démarrage que je sélectionne dans Grub. Pour y parvenir, j'ai ajouté une chaîne arbitraire aux paramètres du noyau d'une option de démarrage ("FORCENVIDIA" dans ce cas), et j'ai un Grub qui vérifie la présence de cette chaîne, puis établit un lien symbolique entre un fichier .conf et l'un des deux autres fichiers en fonction de sa présence ou non :

#!/bin/sh

if cat /proc/cmdline | grep FORCENVIDIA > /dev/null; then
        rm -f /usr/share/X11/xorg.conf.d/old-config
        cp /usr/share/X11/xorg.conf.d/40-force-gpu.conf /usr/share/X11/xorg.conf.d/old-config
        rm -f /usr/share/X11/xorg.conf.d/40-force-gpu.conf
        ln -s /usr/share/X11/xorg.conf.d/XX-force-nvidia /usr/share/X11/xorg.conf.d/40-force-gpu.conf
else
        rm -f /usr/share/X11/xorg.conf.d/old-config
        cp /usr/share/X11/xorg.conf.d/40-force-gpu.conf /usr/share/X11/xorg.conf.d/old-config
        rm -f /usr/share/X11/xorg.conf.d/40-force-gpu.conf
        ln -s /usr/share/X11/xorg.conf.d/XX-force-amd /usr/share/X11/xorg.conf.d/40-force-gpu.conf
fi

Donc, si FORCENVIDIA est dans /proc/cmdline, il supprime l'ancien .conf et le recrée en faisant un lien symbolique vers XX-force-nvidia (qui contient évidemment la bonne configuration pour ma carte nvidia). Si FORCENVIDIA n'est PAS dans /proc/cmdline, il fait la même chose pour XX-force-amd.

Pour que cela soit exécuté avant le démarrage de X, je l'ai inclus en tant que ExecStartPre pour mon gestionnaire d'affichage - sddm en utilisant sudo systemctl edit sddm.service pour créer un fichier de configuration comme ceci :

[Service]
# select the primary GPU to display X
ExecStartPre=@/bin/sh /usr/share/select_primary_card.sh

et je peux utiliser systemctl status sddm.service pour vérifier que systemd pense c'est en cours :

 sddm.service - Simple Desktop Display Manager
   Loaded: loaded (/lib/systemd/system/sddm.service; indirect; vendor preset: enabled)
  Drop-In: /etc/systemd/system/sddm.service.d
           override.conf
   Active: active (running) since Thu 2020-05-28 06:28:36 BST; 9min ago
     Docs: man:sddm(1)
           man:sddm.conf(5)
 Main PID: 1350 (sddm)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/sddm.service
           1350 /usr/bin/sddm
           1352 /usr/lib/xorg/Xorg -nolisten tcp -auth /var/run/sddm/{eea7054b-d749-4569-9c3f-e44f13be8942} -background none -noreset -displayfd 18 -seat seat0 vt1

May 28 06:30:55 PC sddm-helper[1731]: Starting: "/etc/sddm/Xsession \"/usr/bin/startkde\""
May 28 06:30:56 PC sddm[1350]: Auth: sddm-helper exited successfully
May 28 06:30:56 PC sddm[1350]: Greeter stopped.
May 28 06:30:56 PC sddm[1350]: Session started                                                                                                                                                                                                                                 
May 28 06:30:57 PC sddm[1350]: Checking for pam module                                                                                                                                                                                                                         
May 28 06:30:57 PC sddm[1350]: Got pam-login                                                                                                                                                                                                                                   
May 28 06:30:57 PC sddm[1350]: kwalletd: Waiting for hash on 15-                                                                                                                                                                                                               
May 28 06:30:57 PC sddm[1350]: kwalletd: waitingForEnvironment on: 3                                                                                                                                                                                                           
May 28 06:30:57 PC sddm[1350]: kwalletd: client connected                                                                                                                                                                                                                      
May 28 06:30:57 PC sddm[1350]: kwalletd: client disconnected

Le problème est que, c'est no à courir. Dans le script, j'ai inclus des lignes pour copier le fichier .conf existant dans un fichier appelé "old-config", afin que je puisse voir à quoi ressemblait le fichier conf lors du démarrage précédent (l'option de démarrage nvidia ne fonctionne pas et il est difficile de diagnostiquer lorsque vous redémarrez sur celui qui fonctionne et qu'il remplace le .conf). Cet ancien fichier de configuration n'existe pas lorsque je démarre et me connecte. Pour autant que je puisse dire, le script fonctionne bien. Si je l'exécute manuellement avec sudo /usr/share/select_primary_card.sh il semble faire ce qu'il doit faire.

Quelqu'un peut-il voir ce qui se passe ici ?

1voto

James Mertz Points 390

Vous avez utilisé le @ préfixe, ce qui signifie que le /bin/sh L'exécutable recevra cette liste d'arguments :

{[0] = "/usr/share/select_primary_card.sh"}

au lieu de celui attendu :

{[0] = "/bin/sh", [1] = "/usr/share/select_primary_card.sh"}

Par convention, le troisième élément de la liste des arguments contient toujours le nom du programme et est plus ou moins ignoré par la plupart des logiciels.

Mais lorsque les scripts sont exécutés par le biais d'un interpréteur, argv[0] contient l'élément l'interprète et le chemin vers script est normalement l'élément #1 - c'est-à-dire juste une partie normale de la ligne de commande de l'interpréteur. Ainsi, lorsque le @ est utilisé, /bin/sh pense qu'il est exécuté avec une ligne de commande vide et essaie de passer en mode interactif, échoue et sort.

Vous ne pas n'a besoin d'aucune astuce spéciale d'argv[0] pour exécuter un script. Il suffit de l'exécuter comme ceci (en honorant l'attribut #! en-tête) :

ExecStartPre=/usr/share/select_primary_card.sh

ou comme ceci (en contournant le #! en-tête) :

ExecStartPre=/bin/sh /usr/share/select_primary_card.sh

En passant, ne mettez pas vos configurations personnalisées dans /usr/share - c'est à cela que sert /etc/X11.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X