lakpa.net

journal de bord

Entrées marquées "debian-fr"

Udev is good
28 novembre 2010

Ç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

Le code est ici.

Bien évidemment, les commentaires et remarques sont les bienvenus.

Tags: automount, debian-fr, udev

RSS Feed

Généré par Chronicle v4.6