Automount en règles udev uniquement :)

(Ca n’est pas un problème mais une solution, ça pourrait aller dans t&a mais ça requiert plus de tests)

J’ai récemment viré hal et dbus, seulement voilà, l’automount des clés USB j’aime bien, et je me voyais pas remplir mon fstab et je peux pas utiliser pmount (qui utilise hal vu qu’il foire en utilisant sysfs).

Ca me laisse donc comme seul choix de créer mon propre automounter dynamique avec udev directement, usbmount ne montant pas par label. Je pensais que celà se trouverait facilement sur google mais c’était pas le cas, notamment dans certains exemples, y a un problème d’accès concurrent sur le point de montage (cas des labels identiques non géré).

L’execution de commandes externes dans des règles udev étant bloquant, et connaissant la pauvreté syntaxique des règles udev, c’était pas forcément gagné, en plus je voulais pas de dépendances sur un script externe :unamused:

Le plus gros problème est que, mon ipod pointe en /dev/sdX(sans chiffre), or j’ai une de mes clés usb avec une table des partitions foireuses où le block principal se monte alors qu’il ne le devrait pas - donc les régles fonctionnent mais toute partition valide pointant en /dev/sdX doit être mise en “liste blanche”.

Talk is cheap. Show me the code. - Linus Torvalds

# [b-z] car mon disque dur est en SATA.
KERNEL!="sd[b-z]*", GOTO="FIN"

# ne jamais laisser une variable d'environnement vide
ACTION=="add", ENV{mntopt}="-t auto"
ACTION=="add", ENV{mntpnt}="/media/%k"

# détermination du point de montage et du FS
ACTION=="add", PROGRAM=="/sbin/blkid -s TYPE -o value %N", RESULT=="vfat",\
        ENV{mntopt}="-t vfat -o uid=1000"
ACTION=="add", PROGRAM=="/sbin/blkid -s LABEL -o value %N", RESULT!="" \
        ENV{mntpnt}="/media/%c"
# 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 à /media/%k qui est unique
ACTION=="add", PROGRAM!="/bin/mountpoint $env{mntpnt}", \
        GOTO="MONTER"
ACTION=="add", ENV{mntpnt}="/media/%k"


LABEL="MONTER"

# montage commun
ACTION=="add", KERNEL=="sd[b-z]?", \
        RUN+="/bin/mkdir -p $env{mntpnt}"
ACTION=="add", KERNEL=="sd[b-z]?", \
        RUN+="/bin/mount $env{mntopt} %N $env{mntpnt}"
# exception de l'Ipod >.<
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{product}=="iPod", \
        RUN+="/bin/mkdir $env{mntpnt}"
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{product}=="iPod", \
        RUN+="/bin/mount $env{mntopt} %N $env{mntpnt}"

# umount commun à tous les périphs
ACTION=="remove", KERNEL=="sd[b-z]*", \
        RUN+="/bin/umount -l %N"
ACTION=="remove", KERNEL=="sd[b-z]*", \
        RUN+="/bin/rmdir $env{mntpnt}"

LABEL="FIN"

A noter que /media aurait pu être mis dans une variable…

Ca marche impecc sur mes 2 machines, comme avec hal+dbus+ivman - 20MB de ram et du polling en moins en bonus - c’est appréciable ! De plus toutes les commandes utilisées appartiennent à des paquets de base et vitaux (e2fsprogs, initscripts, coreutils), on peut donc mettre en place le script dès le premier reboot après installation !

:wq! :smt006

Salut,

J’attends les tests et l’approbation de le passer en T&A.

Je n’ai pas les moyens de participer aux tests. Un MP quand vous serez fixé :slightly_smiling:

Sur ce point, j’ai déjà fait un paquet modifiant /etc/fstab à la volée et créant le répertoire /media/ correspondant avec udev. Paquet plugusb sur
deb boisson.homeip.net/debian lenny divers
(ou squeeze, etch sarge, woody…)

[quote=“fran.b”]Sur ce point, j’ai déjà fait un paquet modifiant /etc/fstab à la volée et créant le répertoire /media/ correspondant avec udev. Paquet plugusb sur
deb boisson.homeip.net/debian lenny divers
(ou squeeze, etch sarge, woody…)[/quote]
J’avais essayé en premier lieu, mais le problème c’est que j’ai absolumenet besoin d’un point de montage suivant le label s’il existe, donc j’aurais du modifier ton script, ce qui me revient au même que faire mes propres règles.

Je t’explique, j’ai un script qui selon le périphérique de stockage de masse USB branché, effectue certaines actions, ça va du rsync à l’import de photos, le problème est que je veux que cela ne soit pas automatique. J’ai donc besoin de savoir si tel périphérique avec le label X est monté.

Si je monte par noeud, je suis obligé de faire:

if mountpoint /media/$(basename /dev/disk/by-label/UNLABEL); then
# quelque chose, et je devrais assigner le point de montage à une variable en plus
fi

Par label maintenant:

# avec les règles udev plus haut, c'est déjà monté - pas besoin de vérifier
if [ -d /media/label ]; then 
# quelque chose
fi

Forcément l’execution du deuxième code est largement plus rapide, je sors mon vieux thinkpad, et je regarde la difference, le script gérant 17 périphériques USB, sans en brancher un:

# montage par noeud:
$ time usbmagic 
real    0m1.001s
user    0m0.274s
sys     0m0.658s

# montage par label:
$ time usbmagic
real    0m0.364s
user    0m0.000s
sys     0m0.020s

Bon, ok, on reste dans le domaine de la seconde, je ratiocine là, par contre le pire reste dans les accès disques - et ça niveau batterie de portable, ça pardonne pas :wink:

Ça m’intéresserais bien mais je ne sais pas comment virer hal sans virer xorg…

Y a une dépendance dure sur xorg en testing/sid, ça a fait des vagues sur certaines ml :unamused: La solution la plus sale c’est de virer hald au boot avec update-rc.d - et ce à chaque update.

La plus longue mais qui s’avère la plus propre est de repackager via les sources de xorg, je te fais pas de dessins, par contre tu “localises” ton build de xorg, en gros:

apt-get source xserver-xorg
mv xserver-xorg_x.x xserver-xorg_x.x-misterfreez0
cat <<EOF > xserver-xorg_x.x-misterfreez0/debian/changelog
xserver-xorg (x.x-misterfreez0) testing; urgency=low

  * quelque chose, c'est important
 
 -- Misterfreez <mister@freez.fr>  Sat, 26 Dec 2009 18:52:46 +0100
EOF
dpkg-buildpackage ...

La version locale sera toujours préférée à celle du dépot, sauf si ton /etc/apt/preferences differe des valeurs par défaut.

Ensuite, tu vas surement avoir besoin de ça:

$ cat /etc/apt/apt.conf
APT::Install-Recommends "0";
APT::Install-Suggests "0";
# apt-get update

dans la mesure où par défaut apt installe les recommends - dont dbus(-x11), néanmoins certains paquets devront être tout de même repackagés, ce qui est un peu chiant en testing…

Et enfin, pas oublier:

# apt-get install xserver-xorg-input-mouse xserver-xorg-input-keyboard
# cat /etc/X11/xorg.conf
[...]
Section "ServerLayout"
        [...]
        # desactivation du support hal pour le hotplug
        Option "AutoAddDevices" "False"
        Option "AllowEmptyInput" "False"
EndSection
[...]

Bref, prépares toi à un peu de bricolage si tu veux vraiment le faire, surtout que l’interet n’est pas si énorme que ça sur une machine récente.

Houla houla, non quitte à être crade autant le faire proprement. Pour virer une dépendance d’un paquet:

[code]# cp paquet.deb /tmp

cd /tmp

mkdir gre

dpkg-deb -x paquet.deb gre

cd gre

dpkg-deb -e …/paquet.deb

emacs DEBIAN/control

[/code]
là virer les dépendances enquiquinantes

et voilà…

[quote=“fran.b”]Houla houla, non quitte à être crade autant le faire proprement. Pour virer une dépendance d’un paquet:
[/quote]
Ca ne marche pas si le rules est pas modifié:
gtkpod: missing ‘/usr/lib/libdbus-1.so.3’

Je vois pas ce qu’il y a de sale à prendre un paquet Debian, le “localiser” en modifiant le nécessaire dans /debian, ça marche nickel:
frwendling.free.fr/slimfast/lenn … 1_i386.deb

$ lintian  gtkpod_0.99.12-3-knuck1_i386.deb
W: gtkpod: debian-changelog-line-too-long line 3
W: gtkpod: spelling-error-in-changelog dependancies dependencies

J’ai oublié la mise en forme du changelog :unamused:

Enfin, tu dois avoir tes raisons de dire ça :slightly_smiling: (edit: ah j’ai compris, je presuppose que Misterfreez le sais déjà !)

Ta méthode consiste à recompiler le paquet en virant les dépendances. Il faut dans ce cas non seulement virer les dépendances mais aussi adapter le «rules» i.e les options de fabrication sinon ça ne marchera pas à tous les coups. Ma méthode consiste juste à virer la dépendance avec hal du paquet. Ce sont les mêmes binaires simplement le paquet ne demande plus l’installation d’autres paquets. C’est plus simple mais plus «crade». Ici tu as constaté que tout marchait bien sans hal. Il te suffit juste de virer «hal» des dépendances du paquet binaire parce que là, tu lui demandes de recompiler tout Xorg à vue de nez…

Ok, je comprends mieux, trop l’habitude faire avec les “moyens du bord” (et de l’interface chaise clavier), je modifie toujours le rules, control, changelog et je repackage - j’aurais pas oser toucher directement au paquet binaire :wink:

Sinon, oui je suis sur ca se désactive à la compilation si on le précise dans rules, je peux mettre ma main à couper (–disable-config-dbus, --disable-config-hal).

J’appelle ça du prosélytisme :laughing:

Pourquoi ne pas utiliser editor ?
Surtout que chez moi je me suis fais un petit wrapper :

[code]#!/bin/sh

if [ $[$RANDOM%2] -eq 0 ] ; then
exec vim $@
else
exec emacs -nw $@
fi[/code]

Sinon je verrais plus tard pour faire ces changements.

[quote=“MisterFreez”]Ça m’intéresserais bien mais je ne sais pas comment virer hal sans virer xorg…[/quote]Ça doit pas être très compliqué, sur ma machine il n’y a pas hal et concernant xorg, j’ai tout ces paquets d’installé :~$ dpkg -l |grep xorg ii xserver-xorg 1:7.5+3 the X.Org X server ii xserver-xorg-core 2:1.7.4-2 Xorg X server - core server ii xserver-xorg-input-evdev 1:2.3.2-3 X.Org X server -- evdev input driver ii xserver-xorg-input-kbd 1:1.4.0-1 X.Org X server -- keyboard input driver ii xserver-xorg-input-mouse 1:1.5.0-1 X.Org X server -- mouse input driver ii xserver-xorg-input-synaptics 1.2.1-1 Synaptics TouchPad driver for X.Org server ii xserver-xorg-video-intel 2:2.9.1-2 X.Org X server -- Intel i8xx, i9xx display dCe qui est largement suffisant pour profiter de X.
J’ai rien eu besoin de recompiler, aptitude permet ça tout seul.

@ knucky, pour l’instant j’utilise pmount (qui n’utilise pas forcément hal, juste libhal) mais si j’arrive à mettre ton topic en pratique je vais m’en débarasser ainsi que des derniers résidus de libhal.

Comment on fait pour l’installer (maintenant j’ai pu virer hal) ?
J’ai copier dans un fichier /etc/udev/rules.d/60-automount.rules puis j’ai relancé udev.

Puis pleins d’espoire je branche ma clef usb et puis rien…

J’ai raté un truc ?

@fran > plugusb monte par exemple dans /media/sdc1 ?

plugusb crée le répertoire et fait une modification de /etc/fstab, c’est un peuy différent. Pour ce que tu veux faire, il te suffit de t’inspirer du script:

regle udev.sh

ACTION=="add", ENV{SUBSYSTEM}=="block", ENV{ID_TYPE}=="floppy" , PROGRAM="/lib/udev/usb_fstab.sh %k" ACTION=="add", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , PROGRAM="/lib/udev/usb_fstab.sh %k" ACTION=="remove", ENV{SUBSYSTEM}=="block", ENV{ID_TYPE}=="floppy" , PROGRAM="/lib/udev/usb_fstab.sh %k" ACTION=="remove", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , PROGRAM="/lib/udev/usb_fstab.sh %k"

fichier /lib/udev/usb_fstab.sh que tu modifies:

[code]#!/bin/sh
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 “----------”>> /tmp/dev_usb

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 /media/$1
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 /media/$1
fi
echo $DEVICE /media/$1 $ID_FS_TYPE user,defaults 0 0 >> /etc/fstab

ici tu peux faire le montage automatique…

rm /tmp/__insertusb

fi
if [ “$ACTION” = “remove” ] ; then
NOM=$1_$ID_SERIAL
DEVICE=/dev/$1
while [ -f /tmp/fstab_mod ] ; do /bin/true ; done
touch /tmp/fstab_mod
umount -f /media/$1
rmdir /media/$1
LISTE=cat /etc/fstab | grep " /media" | awk '{print $2}' | sed -e 's|/media/||' | sort -u
cp /etc/fstab /tmp/fstab
for device in $LISTE ; do
if [ ! -d /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
[/code]

[quote=“MisterFreez”]Comment on fait pour l’installer (maintenant j’ai pu virer hal) ?
[/quote]
J’ai mis ça dans /etc/udev/rules.d/10-local.rules, c’est à dire en première position - c’est peut être mauvais, mais j’ai jamais eu de problèmes, je mets aussi le démarrage/arret automatique de cups etc. dedans.

Non, mais faut pas oublier qu’un automounter en règles udev uniquement est encore considéré comme “fantaisiste” à l’heure actuelle, notamment parce que tu n’as aucune sortie de déboguage, c’est tout l’interêt des scripts comme plugusb où là t’as un controle intégral de ce qu’il se passe !

Attention, j’ai oublié de préciser que /dev/sdb1 (par exemple) n’existe pas forcément au moment de l’appel du script, il faut donc en tenir compte (le créer si besoin…)

Bonjour à tous,

Excusez moi de déterrer le sujet, mais je ne pense pas qu’il soit utile d’ouvrir un nouveau fil pour ça.

Ca fait quelques temps que je cherche une solution pour l’automount simple et perso (n’aime pas les FM qui le font, j’utilise XFE), et j’ai l’impression d’avoir presque trouvé. Par contre, je me pose quelques questions :

ACTION=="add", PROGRAM=="/sbin/blkid -s TYPE -o value %N", RESULT=="vfat",\
        ENV{mntopt}="-t vfat -o uid=1000"

C’est qui ce %N, j’ai trouvé %k, %n dans udev, mais lui ?

Pourquoi on ne retrouve pas cette condition dans le plugusb de fran.b ? Est ce que c’est grâce au ENV{SUBSYSTEM}==“block” ?

ACTION=="add", ENV{SUBSYSTEM}=="block", ENV{ID_FS_TYPE}!="" , PROGRAM="/lib/udev/usb_fstab.sh %k"
Si j’ai tout compris la doc de udev (http://www.reactivated.net/writing_udev_rules.html#external-run “PROGRAM is used for running programs which produce device names (and they shouldn’t do anything other than that).”), ne faudrait il pas plutôt utiliser RUN+= ?

J’ai quand même dpkg -i plugusb et je le trouve très bien, mais je cherche aussi à monter par label. Je voudrais donc modifier un peu le script et la règle (car je veux bien un script externe) ou modifier les règles de Knucky (quand même, j’aime bien la modif du fstab à la volée…)

Merci de vos lumières.

mougly

Salut,

Oui, c’est possible de faire passer le nom du noeud crée et aussi le label de la partition.

A noter que j’utilise à présent les règles qui se trouvent la : wiki.archlinux.org/index.php/Udev, et que cela fonctionne parfaitement.

Aussi reactivated.net/writing_udev_rules.html n’est pas obsolète, mais n’est plus exhaustif.

Salut,

Finalement, j’ai bien tout lu les docs et je me suis concoté mon propre automount. Je vous le met si ça intéresse quelqu’un.

/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. http://www.cepcasa.info/blog/?p=143)

On remarque quelques similitudes avec ce qui est publié plus haut …
Merci à vous

mougly

EDIT du 4/12 : remplace $mntpnt par echo $mntpnt | tr ' ' '_' pour une meilleure gestion des noms avec espaces. Peut-être redondant avec v_=$IFS ?

belle amélioration…