A small email to sumarize some thoughts about udev, removable
storage and incron to make the job of hal and re-invent the wheel.

---- context (skipable) -----
there is ONE common thing where gnome is quicker than bash : mounting
an unknown usb stick.

For my own stuff, I already used labels and uuids for ages but for
stranger devices it's not possible.

So those are the steps I did thousands of times :
- grab root (the device can be sdc3 as sde1 so there is no specific fstab entry)
- [dmesg|tail to check the device name or bash completion]
- mount -o users,rw /dev/new_device_X /mnt/remusb
- ^D
- cd /mnt/remusb

So what I needed was to get my plugged devices automounted to have
quickly a terminal in the directory. (I use fluxbox without idesk or
whatever)

Here comes the solution I found :

---- configuration -----------

FSTAB : some lines of /etc/fstab

LABEL=docus     /home/ftp/pub/Docus     ext3            users,auto              
0 0
UUID=0467-FFC1  /mnt/mp3                vfat            users,rw,noatime        
0 0

UDEV : some lines of /etc/udev/rules.d/80-custom.rules

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="docus", "RUN+="/bin/mount 
-L docus"
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="0467-FFC1", 
RUN+="/bin/mkdir -p /mnt/mp3", RUN+="/bin/mount -U 0467-FFC1"

Ok, so this UDEV rules only make KNOWN devices automounted (but
nothing for unknown devices)

I then needed to have unknown devices mounted into /mnt/remusb, so the
other devices are given a $ENV{} variable.

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="docus", RUN+="/bin/mount 
-L docus", ENV{custom_rules}="add"
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="0467-FFC1", 
RUN+="/bin/mkdir -p /mnt/mp3", RUN+="/bin/mount -U 0467-FFC1", 
ENV{custom_rules}="add"
# so I can add :
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[b-z][1-9]", 
ENV{custom_rules}=="", RUN="mkdir -p /mnt/remusb", RUN+="mount /dev/%k 
/mnt/remusb"

But as I have many more removable medias, I factorised the code and used
exclusively ENV{} like the following :

## definitions examples :
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="integral", 
ENV{mount_point}="integral", ENV{mount_cmd}="-L integral", 
ENV{custom_rules}="add"ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_LABEL}=="docus", ENV{mount_cmd}="-L docus", ENV{custom_rules}="add"

## actions :
ENV{custom_rules}=="add", ENV{mount_point}!="", RUN+="/bin/mkdir -p 
/mnt/$env{mount_point}"
ENV{custom_rules}=="add", ENV{mount_cmd}!="", RUN+="/bin/mount $env{mount_cmd}"

--------------------
Now I want to be notified !
2 solutions :
- the bad one, udev runs as root : who && su -l my_user && DISPLAY=:0 osd_cat 
"new
  device"
- another one, use a per-session user daemon (as I ignored the hal
  documentation I didn't even looked at dbus-launch or others hal
  "plugins").

I decided to be notified by a file creation : INCRON
UDEV has to create a file in a directory monitored by incron.
[The creation a file whose name gives some useful information monitored by a 
daemon
is a kind a replacement of a real bus messaging system]

So, in the udev rule for my mp3 player I add the following :
RUN+="/bin/mkdir /tmp/.incron.device/%k"
(in fact I added it as the last one of the "actions" part of the udev rules 
file)

For my user I create a incrontab like :
/tmp/.incron.device IN_CREATE,IN_DELETE /home/myuser/.automount-script.sh $@ $# 
$%
So it's now possible to control what to do as udev notify us by incron,
better, monitoring /proc/partitions or whatever is useless as udev passes the
device name to incron which forward it to the script.

Example of automount-script.sh :
if [[ $theevent =~ IN_CREATE ]]; then
        destdir=$(mount|sed -n "s;^/dev/$thedevice on \(.*\) type.*$;\1;p")
        urxvtc -cd $destdir
fi

In that way I have a terminal spawned in the mount point each time
a removable device is plugged.

I attached my fstab, udev rule, incrontab -l and custom script.

I would be curious to read some advices about this architecture.

I also have 2 questions :
- what's the way to have a incremental number for unknown devices like
  /mnt/remusb1 then /mnt/remusb2 instead of /mnt/remusb (within udev) ?
- where to put the creation of /tmp/.incron.device in the init scripts
  to be sure it will be created BEFORE incron starts (without having to
  create a new startup script) ?

Raph
/tmp/.incron-device IN_CREATE,IN_DELETE /home/yug/.incron-script.sh $@ $# $%
LABEL=swap      none                    swap            sw                      
0 0
LABEL=boot      /boot                   ext2            noauto,noatime          
1 2
LABEL=slash     /                       reiserfs        noatime                 
0 1
LABEL=usr       /usr                    reiserfs        noatime                 
0 0
LABEL=var       /var                    reiserfs        noatime                 
0 0
LABEL=log       /var/log                reiserfs        noatime                 
0 0
LABEL=home      /home                   reiserfs        noatime                 
0 1
LABEL=compilationdir    /var/tmp                reiserfs        noatime         
        0 0
/dev/scd0       /mnt/cdrom              iso9660         noauto,ro,user          
0 0

LABEL=integral  /mnt/integral           ext3            users,noauto            
0 0
LABEL=docus     /home/ftp/pub/Docus     ext3            users,auto              
0 0
LABEL=films     /home/ftp/pub/Films2    ext3            users,auto              
0 0
LABEL=gris2     /mnt/gris2              ext2            users,rw,noauto,noatime 
        0 0
UUID=0467-FFC1  /mnt/mp3                vfat            users,rw,noatime        
0 0

none            /proc                   proc            defaults                
0 0
none            /dev/shm                tmpfs           nodev,nosuid,noexec     
0 0
none            /tmp                    tmpfs           
defaults,mode=1777,size=100m    0 0
none            /var/run                tmpfs           
defaults,noexec,size=150k       0 0
/dev/fd0        /media/floppy           auto            rw,user,noauto          
0 0
none            /mnt/debugfs            debugfs         auto                    
0 0
## WE DOESN'T CREATE A SPECIFIC SYMLINKS IF OUR FSTAB CONFIGURED THE LABELS

## USB STICK GRIS

ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_UUID}=="0e2bd8c1-d14d-4bf9-bed9-a5e5acfd7b08", SYMLINK+="gris1", 
ENV{custom_rules}="notyet"

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="gris2", 
ENV{mount_point}="gris2", ENV{mount_cmd}="-L gris2", ENV{custom_rules}="add"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="gris2", 
ENV{mount_point}="gris2", ENV{custom_rules}="remove"
#ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_UUID}=="425a5f7d-d75c-4470-bd19-fc56b2724210", SYMLINK+="gris2"

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="B109-EE46", 
SYMLINK+="gris3", ENV{custom_rules}="notyet"



## TESTS

#KERNEL=="sdb[123]", ENV{ID_SERIAL}=="USB_2.0_Flash_Disk_A000000000000233", 
SYMLINK+="gris_ker_env_ser"
#KERNEL=="sdb[123]", ATTRS{serial}=="USB_2.0_Flash_Disk_A000000000000233", 
SYMLINK+="gris_ker_attrs_ser"
#KERNEL=="sdb[123]", ENV{ID_SHORT_SERIAL}=="A000000000000233", 
SYMLINK+="gris_ker_env_shser"
#KERNEL=="sdb[123]", ATTRS{short_serial}=="A000000000000233", 
SYMLINK+="gris_ker_attrs_shser"



## WESTERN DIGITAL

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="docus", 
ENV{mount_cmd}="-L docus", ENV{custom_rules}="add"
#ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_UUID}=="f2574b18-3fa6-4649-9908-eaa8503cab33", SYMLINK+="wd1"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="docus", 
ENV{custom_rules}="remove"

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="films", 
ENV{mount_cmd}="-L films", ENV{custom_rules}="add"
#ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_UUID}=="08fea226-c5a5-49de-a8e7-bfc2a9975232", SYMLINK+="wd2"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="films", 
ENV{custom_rules}="remove"



## MP3 PLAYER

#ATTRS|ENV : "Samsung_YP-U1_0002F6916425CF08-0:0", SYMLINK+="mp3"
ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="0467-FFC1", 
ENV{mount_point}="mp3", ENV{mount_cmd}="-U 0467-FFC1", ENV{custom_rules}="add"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="0467-FFC1", 
ENV{mount_point}="mp3", ENV{custom_rules}="remove"



## INTEGRAL USB HD

ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="integral", 
ENV{mount_point}="integral", ENV{mount_cmd}="-L integral", 
ENV{custom_rules}="add"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_FS_LABEL}=="integral", 
ENV{mount_point}="integral", ENV{custom_rules}="remove"
#ACTION=="add", SUBSYSTEM=="block", 
ENV{ID_FS_UUID}=="d588d4d2-6904-4623-960c-707409bcb9c3", SYMLINK+="integral"


## UNKNOWN DEVICES
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd[b-z][1-9]", 
ENV{custom_rules}=="", RUN="mount /dev/%k /mnt/remusb", RUN+="/bin/mkdir 
/tmp/.incron.yug/%k"


## RUN THE FACTORIZED BABE

ENV{custom_rules}=="add", ENV{mount_point}!="", RUN+="/bin/mkdir -p 
/mnt/$env{mount_point}"
ENV{custom_rules}=="add", ENV{mount_cmd}!="", RUN+="/bin/mount $env{mount_cmd}"
ENV{custom_rules}=="add", RUN+="/bin/mkdir /tmp/.incron.yug/%k"

ENV{custom_rules}=="remove", ENV{mount_point}!="", RUN+="/bin/rmdir 
/mnt/$env{mount_point}"
ENV{custom_rules}=="remove", RUN+="/bin/rmdir /tmp/.incron-device/%k"

Attachment: automount-script.sh
Description: Bourne shell script

Reply via email to