Avec systemd, trois arborescences sont à considérer : /lib/systemd
, /etc/systemd
et /run/systemd
. La première contient les descriptions des services telles qu'elles sont fournies dans les paquets logiciels. La deuxième contient des surcharges locales de ces descriptions, c'est-à-dire des annihilations ou des modifications désirées par l'administrateur système qui ne seront pas écrasées lors d'une mise à jour des paquets (et c'est l'un des apports de systemd-systemd - le gestionnaire de démarrage uniquement - par rapport à sysvinit). La dernière, contient les descriptions des services telles qu'elles sont à l'instant présent. L'ordre est important : /run/systemd
surcharge /etc/systemd
qui surcharge /lib/systemd
.
Prenons un cas concret. Nous souhaitons modifier la description du service OpenVPN.
Nous copions /lib/systemd/system/openvpn@.service
, qui est un modèle (un unique fichier de configuration qui permet de créer facilement plusieurs instances d'un même service), dans /etc/systemd/system/openvpn.service
, nous apportons notre touche personnelle et nous exécutons un systemctl daemon-reload
. On se rend compte que notre modification n'est pas effective. Aller, une petite systemctl disable openvpn@<nom_fichier_conf>
puis une systemctl enable openvpn@<nom_fichier_conf>
, ça devrait l'faire, d'autant que systemctl écrit « Created symlink /etc/systemd/system/multi-user.target.wants/openvpn@systemctl status openvpn@<nom_fichier_conf>
l'affiche explicitement : c'est toujours /lib/systemd/system/openvpn@.service
qui est utilisé.
La description qui fait foi se trouve dans /run/systemd/generator/openvpn.service.wants/openvpn@<nom_fichier_conf>
qui est un lien symbolique vers /lib/systemd/system/openvpn@.service
, la description originale fournie pas le paquet logiciel openvpn. Comment l'avons-nous su ? En nous documentant sur les arborescences utilisées par systemd. Mais la commande suivante aurait également permis de découvrir le pot aux roses : sudo find / -lname /lib/systemd/system/openvpn@.service
.
Qui génère ce fichier ? Un script, /lib/systemd/system-generators/openvpn-generator
, que l'on nomme générateur. Dans le cas présent, son but est de simplifier la vie en démarrant tous les VPN nommés dans /etc/default/openvpn
(par défaut : tous les VPN) et pour lesquels un fichier de conf' existe dans /etc/openvpn/<nom>.conf
. Pour ce faire, un lien est créé depuis /run/systemd/generator/openvpn.service.wants/openvpn@<nom_fichier_conf>
vers… /lib/systemd/system/openvpn@.service
. Un générateur peut aussi servir à générer dynamiquement la description d'un service. Comment avons-nous identifié le fichier qui génère les liens symboliques dans /run/systemd/generator/openvpn.service.wants
? Le chemin contient l'indication « generator ». Un générateur est fourni par un paquet logiciel. La commande dpkg -L openvpn | grep generator
permet donc de l'identifier.
Tout comme il est possible de masquer la description d'un service afin de l'empêcher de démarrer même lors d'une mise à jour des paquets (dans les paquets Debian, la plupart des scripts exécutés après l'installation d'un logiciel - /var/lib/dpkg/info/openvpn.postinst, par exemple - crée un service et l'active), il est possible de masquer un générateur. Pour ce faire :
sudo mkdir /etc/systemd/system-generators/
sudo ln -s /dev/null /etc/systemd/system-generators/openvpn-generator
sudo systemctl daemon-reload
Note : la commande systemctl mask
ne permet apparemment pas de travailler sur les générateurs.
Les commandes systemctl status openvpn@<nom_fichier_conf>
et systemctl show openvpn@<nom_fichier_conf>
confirment que la description utilisée est désormais notre surcharge locale dans /etc, avec nos modifications. \o/