Ça faisait un moment que je cherchais le truc pour monter mes périphériques USB sans utiliser ni les gestionnaires de fichiers qui le font (pcmanFM, Thunar, nautilus, etc.), ni une entrée statique du fstab (mon noyeau reconnait tout en sd?, donc trop aléatoire et limité). Et en plus je voulais un montage par LABEL (cerise !). Sauf que je ne trouvais pas d'explication claire des règles udev, que je ne comprenais pas le fonctionnement d'ivman et que je suis un carafon jamais content !
Udev pur
Après de longues recherches, j'ai trouvé quelque chose sur le forum debian-fr. Évidemment, comme je n'avais toujours pas compris le fonctionnement de udev, les règles de Knucky m'étaient obscures. Mais plus loin sur le fil, fran.b expose son paquet plugusb. Et là ça devient plus intéressant. En effet, ses règles sont simples, on modifie le fstab en direct, et on bascule directement sur un script : ça, j'aime ! Mais quand même, il ne monte pas par LABEL et il ne monte même pas du tout. Alors je me vois contraint de passer quelques heures à décortiquer les règles udev de Knucky et celles de fran.b pour trouver ZE solution à mon problème.
Où j'ai appris
A force de continuer à lire (in english of course) les docs de udev (man udev et ... man udev ! ), j'arrive maintenant à quelque chose.
Le /etc/udev/rules.d/z99_clef.rules
# ne jamais laisser une variable d'environnement vide
ACTION=="add", ENV{mntopt}="-t auto"
ACTION=="add", ENV{mntpnt}="/home/batbat/media/%k"
ACTION=="add", ENV{mntname}="usb_disk"
# détermination du point de montage et du FS
ACTION=="add", ENV{ID_BUS}=="usb", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , PROGRAM=="/sbin/blkid -c /dev/null -s TYPE -o value %N", RESULT=="vfat",ENV{mntopt}="-t vfat -o uid=1000"
ACTION=="add", ENV{ID_BUS}=="usb", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , PROGRAM=="/sbin/blkid -c /dev/null -s LABEL -o value %N", RESULT!="", ENV{mntname}="%c",ENV{mntpnt}="/home/batbat/media/$env{mntname}",
# on vérifie que le point de montage n'est pas déjà utilisé
# s'il l'est on redéfinit le point de montage à /home/batbat/media/%k qui est unique
ACTION=="add", PROGRAM!="/bin/mountpoint $env{mntpnt}", GOTO="MONTER"
ACTION=="add", ENV{mntpnt}="/home/batbat/media/%k", ENV{mntname}="usb_disk"
# Quoi faire
LABEL="MONTER"
ACTION=="add", ENV{ID_BUS}=="usb", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="", RUN+="/lib/udev/usb_bat_fstab.sh %k"
ACTION=="remove", ENV{ID_BUS}=="usb", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , RUN+="/lib/udev/usb_bat_fstab.sh %k"
Et le /lib/udev/usb_bat_fstab.sh
#!/bin/bash
date >> /tmp/dev_usb
echo $ACTION >> /tmp/dev_usb
echo $1 $ID_FS_TYPE $ID_TYPE >> /tmp/dev_usb
echo $ID_SERIAL >> /tmp/dev_usb
echo `echo $mntpnt | tr ' ' '_'` $mntopt >> /tmp/dev_usb
echo "----------">> /tmp/dev_usb
#Ajustement pour les noms avec espace
v_=$IFS
IFS='
'
# Action ADD
if [ "$ACTION" = "add" ] ; then
NOM=$1_$ID_SERIAL
DEVICE=/dev/$1
if [ "$ID_FS_TYPE" = "" ] ; then
ID_FS_TYPE=auto
fi
while [ -f /tmp/__insertusb ] ; do /bin/true ; done
touch /tmp/__insertusb
mkdir -p `echo $mntpnt | tr ' ' '_'`
echo "#$NOM" >> /etc/fstab
if grep -q "$DEVICE " /etc/fstab > /dev/null ; then
echo -n "#" >> /etc/fstab
fi
if [ $ID_FS_TYPE = ntfs ] ; then
ID_FS_TYPE=ntfs-3g
chmod 777 `echo $mntpnt | tr ' ' '_'`
fi
echo $DEVICE `echo $mntpnt | tr ' ' '_'` $ID_FS_TYPE users,defaults,uid=1000,gid=1000 0 0 >> /etc/fstab
/bin/mount $DEVICE
rm /tmp/__insertusb
fi
# Action REMOVE
if [ "$ACTION" = "remove" ] ; then
NOM=$1_$ID_SERIAL
DEVICE=/dev/$1
while [ -f /tmp/fstab_mod ] ; do /bin/true ; done
touch /tmp/fstab_mod
/bin/umount -f `echo $mntpnt | tr ' ' '_'`
/bin/rmdir `echo $mntpnt | tr ' ' '_'`
# echo "sed -e '/^#"$NOM"/{N;d}' /etc/fstab > /tmp/fstab_$1"> /tmp/edite.$1
# cp /etc/fstab /tmp/fstab.$1
# sh /tmp/edite.$1
LISTE=`cat /etc/fstab | grep " /home/batbat/media" | awk '{print $2}' | sed -e 's|/home/batbat/media/||' | sort -u`
cp /etc/fstab /tmp/fstab
for device in $LISTE ; do
if [ ! -d /home/batbat/media/$device ] ; then
grep -v $device' ' /tmp/fstab | grep -v $device'_' > /tmp/fstab_$device
cp /tmp/fstab_$device /tmp/fstab
fi
done
if [ `ls -l /tmp/fstab_$device | awk '{print $5}'` = "0" ] ; then
touch /tmp/panique.$1
else
mv /tmp/fstab_$device /etc/fstab
fi
rm /tmp/fstab_mod
fi
IFS=$v_
exit 0
N.B. Le /sbin/blkid -c /dev/null
sert à « outrepasser /etc/blkid.tab » (cf. cette page du blog de cep (lien mort))
Conclusion
Il me reste encore quelques tests à faire (par exemple, mettre plusieurs clefs usb qui ont le même label ou qui n'en ont pas du tout), mais je suis assez content de moi. J'avais même réussi à créer une icone dans idesk mais j'étais alors obligé de relancer idesk et ça, c'est un peu lourd. Plus un truc bizarre qui fait qu'il ne me supprimait pas le *.lnk et il le remplissait avec la config par défaut, lors du remove. (Bug ? À voir) Maintenant, quand je branche un périphérique usb, il apparait dans xfe, tux-commander et gnome-commander, et je peut faire ce que je veut avec, même le démonter !
Mise à jour (25 octobre 2014)
Ça fait un bon moment que j'ai nettoyé le code ci-dessus. En particulier pour
- pouvoir le déployer sur plusieurs postes sans avoir à modifier les scripts ;
- le rendre le plus indépendant de udev possible ;
- voire le porter sur devd (FreeBSD et Debian GNU/kfreebsd).
Le code est ici.
Bien évidemment, les commentaires et remarques sont les bienvenus.