Georg Grabler (STiAT) - blog

Life is like an endlessly recursive fractal of perverse pain and suffering.

Monthly Archives: April 2015

Automount with AutoFS

Well, since udev is the “old” way of doing things, and you can run into troubels with Ubuntu 15.04 due to using systemd (fuseblk file systems need mount running in the background, and systemd will kill your mount process after some time), I decided for another solution for my former blog post: AutoFS.

Please note that the current AutoFS in Ubuntu 15.04 has a bug, this is why you’ll need to rebuild the package until a patch is released either by debian or ubuntu upstream. This patch applies to the debian package 5.0.8-2 and the Ubuntu package autofs_5.0.8-1ubuntu3. Fedora and OpenSUSE already do have a patch released, but this post is mostly towards debian/ubuntu users, it should adopt to most other systems as well.

Bug Reports:
Debian bug report
Ubuntu bug report

Patch & Install autofs

apt-get source autofs
cd autofs-5.0.8
vi ./debian/patches/autofs-5.1.0-dont-pass-sloppy-option-for-other-than-nfs-mounts.patch

The patch source can be downloaded from OpenSUSE:

Just Copy/Paste it into the editor and save the file.

Now, you need to edit the ./debian/patches/series and add our patch:

echo "autofs-5.1.0-dont-pass-sloppy-option-for-other-than-nfs-mounts.patch" >> ./debian/patches/series

And of course we need to apply it:

quilt push

Now, we finally can build the package:

dpkg-buildpackage -us -uc -nc

After that, I recommend to install autofs, and patch “over” the original autofs, just expecting Ubuntu/Debian to fix the issue before the next version auf AutoFS:

sudo apt-get install autofs
cd ..
sudo dpkg --install autofs_5.0.8-1ubuntu3_amd64.deb

Now, your AutoFS is without the bug and you can start with your configuration.

UDEV configuration
As in my previews blog post, I want the filesystem to be “always the same”. For this, I simply created the /etc/udev/rules.d/00-WD-Elements.rules as follows:

sudo vi /etc/udev/rules.d/99-WD-Elements.rules

and added the following line, which results in a symlink to /dev/Elements:

KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{product}=="Elements 10B8", ATTRS{serial}=="575836314134345334343938",ATTRS{manufacturer}=="Western Digital", SYMLINK+="Elements"

You can find what’s the right configuration by looking at your own device in /dev, with the following command. Note that you see a lot of device nodes / information blocks there, but you may only use two for identifying your device!

udevadm info -n /dev/sdb1 –attribute-walk

To activate your newly created rule, you can use udevadm

sudo udevadm control --reload-rules

If your created SYMLINK does not appear in /dev, your rule is wrong and you need to check this again.

AutoFS configuration
After that we can finally configure AutoFS. By default, the file /etc/auto.master is created, which we use to add our own mtab file:

sudo vi /etc/auto.master

Add the following line, and make sure you have a newline / blank line at the end of the file, otherwhise the configuration can fail!

/media/usb /etc/auto.usb --timeout=5

Now, we need to add the auto.usb file, which actually specifies our mount:

sudo vi /etc/auto.usb

Add the following line, and make sure there is a newline at the end of file again:

Elements -fstype=ntfs-3g,gid=100,dmask=002,fmask=113,utf8,flush,rw,noatime,user :/dev/Elements

For what the options are, I’ll refer you to my previews blog post.

And you’re done. Restart autofs for reloading the configuration, and your device should appear in /media/usb

sudo systemctl restart autofs

Automounting USB-Disks

There are several solutions out there for automounting USB filesystems, though, none of them satisfied me, and most made more problems and were very unreliable, so I went for the “classic” way using udev rules and fstab.

I’ve a home-server running my ownCloud for syncing my contacts/calendar/files when I’m at home (not accessible from the outside world). Though, I’ve an external harddisk at this server which may be plugged, and maybe isn’t when I’m using it somewhere else or when I just don’t use it holding a lot of my files, which is a NTFS partition.

Interestingly mounting directly via udev brought up folder permissions to be d?????????, so an inaccessible directory. Adding the line to fstab and using udev works just perfectly fine though.

Note that I added a very specific rule for the disk, since it always needs the same mountpoint to be accessible via ownCloud (if plugged in :D).

/etc/udev/rules.d/99-WDElements.rules

KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{product}=="Elements 10B8", ATTRS{serial}=="5758363141343453343439
38",ATTRS{manufacturer}=="Western Digital", SYMLINK+="Elements"ACTION=="add", KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{product}=="Elements 10B8", ATTRS{serial}=="5758363
14134345334343938",ATTRS{manufacturer}=="Western Digital", RUN+="/bin/mount /media/Elements"ACTION=="remove", KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{product}=="Elements 10B8", ATTRS{serial}=="5758
36314134345334343938",ATTRS{manufacturer}=="Western Digital", RUN+="/bin/umount /media/Elements"

Now, how I’m getting there? What are the Parameters?
It’s pretty simple, you can identify the parameters you’ll need to identify a harddisk by using udevadm. It’s a simple tool which outputs udev information about the device and it’s parent devices. You can use all parameters from the specified device and one parent device. This is important, because if you use information from more than one parent device, the udev rule will never ever work.
The command to use to identify the parameters is as follows, in my case at the time plugging in the USB device was /dev/sdb1

udevadm info -n /dev/sdb1 --attribute-walk

So, what does it actually do? It identifies the hardware by KERNEL, SUBSYSEMS, ATTRS{product} ATTRS{serial} ATTRS{manufacturer}, and adds a Symlink called “Elements”, which will show up as /dev/Elements. This is an important step to be able to mount it using fstab, because if you have more than one removable device plugged, it may not be sdb1, but sd?1, which is why i have the ? in the KERNEL line, which basically means every character. You could go for KERNEL==”sd[b-z]1″ or similar too, but I didn’t see a reason for that in my configuration.

This means we’re now left with a /dev/Elements node, pointing to /dev/sd?1 which is my partition on the disk. All we need to do is create the directory we want to mount the disk to, in my case a simple “mkdir /media/Elements”. But you can basically mount it everywhere you want in your filesystem.

The ACTION==”add” is what’s being executed for the device (same options to identify the device of course), when it’s plugged in. In our case, we want to mount it, and use the fstab options when mounting.

The ACTION==”remove” is what’s being executed for the device when it’s unplugged. When we unplug it, we want to unmount the filesystem. Will be re-mounted when re-plugged anyway.

/etc/fstab

/dev/Elements   /media/Elements ntfs-3g    gid=100,dmask=002,fmask=113,utf8,flush,rw,noatime,user, noauto        0       0

Parameter explaination

  • /dev/Elements
    The SYMLINK we create by the udev rule, which represents our physical device.
  • /media/Elements
    The folder you created, and want the filesystem mounted to
  • ntfs
    The corresponding file system
  • gid=100
    The group-id you want to mount the device with. The group “100” represents “users” in my case, which every user I have is in (as www-data, so ownCloud can write there too). You certainly could even set a uid if you want to, but for my configuration it’s not necessary
  • dmask=002
    This is the permission for the “folders”, means who can open, read and write folders. This is a fat/ntfs specific option, which are used on the whole filesystem. You can not set permissions on a folder basis as it’s in ext4 or other UNIX filesystems.
    The options “00” represent “read, write, execute” (rwx) for the owner (root) and the group (users).
    The option “2” is for “everyone”, which is the read and execute permission. So “everyone” may not create, write or delte in the filesystem, but they can open and read it (r-x). The table explaining the options you have in dmask and fmask is below this list.
  • dmask=113
    This is the permission for “files”, means who can read or write files. This as well is a fat/ntfs specific option, which are used on the whole filesystem. You can not set file permissions on a file basis as you can on ext4 and other unix filesystems.
    The options “11” represent the permission of the owner (root), and the group (users), and represent the read and write permission. (rw-)
    The option “3” represents the permission for “everyone”, and represents read only permission (r–).
  • utf8
    This simply specifies that utf8 characters may be used on this filesystem, which basically is a standard today.
  • flush
    This specifies that the system should use the flush data option more often on this filesystem, and as a result copy, move, delete dialogs stay up until the data is actually on the disk, otherwhise it can happen that your data is actually not on the disk when the copy is finished.
  • rw
    Specifies that the system should mount the system in rw mode, so you can read and write files from/to disk (other option would be “ro”, where nobody would be able to write the filesystem, despite the dmask and umask options)
  • noatime
    Defines that inode access times may not be updated on this filesystem. Improves performance for  FAT/NTFS filesystemss.
  • user
    Specifies that only the user mounting the filesystem (and root) can unmount it again. Since I want dbus to handle it, that option makes sense, so no other user may unmount the filesystem. The other option would be “users”, where users with the proper permission in /etc/group could mount or unmount the filesystem, which I don’t want.
  • noauto
    Specifies that the file system is not mounted by fstab, but another way. In our case, it’s udev mounting and unmounting the filesystem for us.

fmask/dmask permission option table

    0   1   2   3   4   5   6   7
r   +   +   +   +   -   -   -   -
w   +   +   -   -   +   +   -   -
x   +   -   +   -   +   -   +   -

That’s basically all you need to know for automounting specific USB devices. You can adopt adding more RUN+= options to automount all file systems being plugged in, reducing the parameters to check for which harddisk exactly was plugged in. I didn’t go for that, since it’s a very specific use-case. Tools like “autofs” claim to do that for you, but in fact – they didn’t for me, I ended up with a hell of devices and folders. A more generic UDEV rule would be the following (it does not use FSTAB):

# Don't do anything if it isn't a device
KERNEL!="sd[b-z]*", GOTO="exit"
# Don't do anything if it's not added by blkid, another check for filesystem
ACTION=="add", PROGRAM!="/sbin/blkid %N", GOTO="exit"

# Import filesystem variables as ID_FS_LABEL and ID_FS_TYPE
IMPORT{program}="/sbin/blkid -o udev -p %N

#make sure we're adding/removing a filesystem here
ACTION=="add", ENV{ID_FS_USAGE}!="filesystem", GOTO="exit"
ACTION=="remove", ENV{ID_FS_USAGE}!="filesystem", GOTO="exit"

# if we have a filesystem label, we want to use it for the mountpoint
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="%k"

# mount options - for all the same
ACTION=="add", ENV{mount_options}="gid=100,dmask=000,fmask=111,utf8,flush,rw,noatime,users"

# ntfs mount, we need to specify ntfs as file system
ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", RUN+="/bin/mkdir -p '/media/%E{dir_name}'", RUN+="/bin/mount -t ntfs-3g -o %E{mount_options} /dev/%k '/media/%E{dir_name}'"

# all others we just can use "auto" type
ACTION=="add", ENV{ID_FS_TYPE}!="ntfs",RUN+="/bin/mkdir -p '/media/%E{dir_name}'", RUN+="/bin/mount -t auto -o %E{mount_options} /dev/%k '/media/%E{dir_name}'"

# on unplugging, we unmount and delete the mountpoint again
ACTION=="remove", RUN+="/bin/umount '/media/%E{dir_name}'", RUN+="/bin/rmdir '/media/%E{dir_name}"

# the exit point, we need this so we can GOTO here if it's not a filesystem
LABEL="exit"