The Daily Shaarli
Si un programme affiche cette erreur, ou si incrond affiche l'erreur « Inotify::Inotify(): inotify init failed », et qu'il est normal que cette machine ait autant de fichiers ouverts et/ou suivis par inotify, alors on peut augmenter le nombre maximal de fichiers surveillés par inotify avec la commande sysctl -w fs.inotify.max_user_instances=256. La valeur "standard" est 128. On peut bien sûr pérenniser ceci dans un fichier posé dans /etc/sysctl.d.
ÉDIT DU 06/04/2018 À 13H25 : le paramètre à modifier est fs.inotify.max_user_instances, pas fs.inotify.max_user_watches ! FIN DE L'ÉDIT.
J'ai un ordinateur portable avec une station d'accueil. Sur cette station d'accueil, je branche un casque audio + micro USB. Il m'arrive très souvent de débrancher cet ordinateur portable de sa station d'accueil. À chaque rebranchement, je suis obligé de refaire la configuration PulseAudio afin de définir mon casque et son micro comme périphérique de sortie et d'entrée. Ce n'est plus possible, il faut rendre ça automatique.
La méthode consistant à utiliser udev pour passer des commandes à PulseAudio via pamcmd ou pactl ne fonctionne plus. Avant, il suffisait de lancer un script udev qui se fork en arrière-plan, ce qui permettait à PulseAudio de continuer son déroulement, donc de détecter le matériel audio puis à notre script de passer des commandes PulseAudio concernant ce matériel. Désormais, au moins dans Debian Stretch, l'implémentation habituelle d'udev est remplacée par celle de systemd-udevd. Ainsi, un fork (+ sleep) est désormais pris en compte par systemd-udevd et bloque la découverte du matériel par PulseAudio. Cela se constate avec sudo systemctl status udev.service (on constate l'arborescence des processus sous systemd-udevd, dont notre sleep).
Passons à la méthode que j'utilise :
On crée le fichier ~/.config/pulse/default.pa avec le contenu suivant :
.include /etc/pulse/default.pa
load-module module-switch-on-connect
pactl load-module module-switch-on-connect ;À partir d'ici, PulseAudio basculera automatiquement sur tout nouveau périphérique audio qui sera connecté. Le dernier périphérique audio branché à un instant T sera celui qui sera utilisé. En entrée comme en sortie. Or, mon dock monte aussi un périphérique audio (probablement lié au port HDMI). Si jamais cette interface monte après mon casque, PulseAudio l'utilisera. Nous allons empêcher cela via un script udev dans /usr/local/bin/headset-delay.sh :
#!/bin/bash
logger -t /usr/local/bin/headset-delay.sh HEADSET ON
sleep 2
logger -t /usr/local/bin/headset-delay.sh HEADSET CONFIGURED
sudo chmod +x /usr/local/bin/headset-delay.sh ;On ajoute une règle udev qui exécute le script précédent dès que le casque est branché dans /etc/udev/rules.d/01-headset.rules (les ID se trouvent dans /var/log/kern.log quand on branche le casque) :
ACTION=="add", ATTR{idVendor}=="1395", ATTR{idProduct}=="0029", RUN+="/usr/local/bin/headset-delay.sh"
Plein de bonnes choses sur inotify et incrond. Notamment :
Je veux utiliser inotify pour surveiller les modifications du contenu d'un fichier. L'objectif est de lancer un script de vérification sémantique sur ce fichier et de les faire remonter aux admins via l’envoi d’un mail. Une erreur sémantique est une erreur qui ne plantera pas le démon/programme qui lit son fichier de conf’, mais qui empêchera d'atteindre le service attendu.
Pour ce faire, j'utilise incrond, donc j’ai ceci dans incrontab -e : <chemin_vers_fichier> IN_MODIFY <programme>.
Ça fonctionne sur le vif, mais plus après quelques semaines… Je relance le démon avec service incron restart. Ça fonctionne à nouveau… pour quelque temps seulement…
Explication : les éditeurs de texte en ligne de commande sérieux (vim, emacs, etc.) ne modifient jamais un fichier. L’événement inotify « IN_MODIFY » n’est donc jamais levé.
En effet, ils créent un fichier temporaire contenant le nouveau contenu puis ils déplacent ce fichier temporaire à l'emplacement du fichier visé par les modifications. L'objectif est de garantir l'absence de corruption du fichier modifié. En effet, mv (et l'appel système sous-jacent, rename) est la seule opération atomique sur un même système de fichiers : tant que le fichier reste au sein d'un même système de fichiers, mv consiste simplement à changer l'inode associé à un nom de fichier dans la liste des fichiers d'un dossier, et à virer l'ancienne entrée nom+inode.
Forcément, cette opération change l’inode (identifiant numérique d'un fichier dans la table des fichiers d'un système de fichiers) pointé par un nom de fichier dans la liste des fichiers d'un dossier. On peut vérifier cette hypothèse en exécutant un ls -lhi <fichier> avant et après la modification. Cela fait qu’inotify n’émet plus d’événements pour ce fichier qui a disparu, donc mon script n'est pas lancé par incrond.
Solution :
Sans grande surprise, j’ai choisi la deuxième solution, donc ma ligne dans incrontab devient : <chemin_vers_fichier> IN_MODIFY,IN_MOVE_SELF <programme>. « IN_MODIFY » pour surveiller les modifs effectuées à l'arrache (echo, redirection shell, nano, etc.) et « IN_MOVE_SELF » pour les autres modifs (vim, etc.).
Merci Gradator pour le rappel sur le comportement des "vrais" éditeurs de texte. :)
