Automatically mount external drives to /media/LABEL on boot without a user logged in?

74

54

This question is similar, but kind of the opposite of what I want. I want external USB drives to be mounted automatically at boot, without anyone logged in, to locations like /media/<label>.

I don't want to have to enter all the data into fstab, partially because it's tedious and annoying, but mostly because I can't predict what I'll be plugging into it or how the partitions will change in the future.

I want the drives to be accessible to things like MPD, and available when I log in with SSH. gnome-mount seems to only mount things when you are locally logged into a Gnome graphical session.

endolith

Posted 2009-10-11T18:13:30.230

Reputation: 6 626

Also, the solution should not conflict with the way drives are normally mounted when someone IS logged in. – endolith – 2009-10-11T23:00:35.067

I deleted my answer. It seems that the underlying infrastructure has changed since the last time I had to tweak my system's automounting behavior. – Ryan C. Thompson – 2009-10-12T23:56:25.940

Well the file still exists, but it's not in the path and doesn't seem to do anything. There must be a way to do the same thing, though. – endolith – 2009-10-16T13:55:33.903

4Great question, wish I had an answer for you, now I'm curious how this is solved. – invert – 2009-10-30T09:32:51.070

1I updated my answer. – Ryan C. Thompson – 2009-10-30T20:01:05.683

i want to do the same thing on a (mostly) headless Debian install. i absolutely do not want to install GNOME. :( – quack quixote – 2009-10-30T20:08:12.593

gnome-volume-manager is apparently based on HAL, which has been replaced with DeviceKit in Karmic, so maybe DeviceKit has something to do this? – endolith – 2009-11-02T16:09:30.877

1And I, for the record, do not have a problem with Gnome being installed, as I already do, but a solution for headless GUI-less servers would be best. – endolith – 2009-11-02T16:10:19.970

1ARRRGHH... bug in my answer. in the RUN. /usr/local/sbin/udev-automounter.sh mount %k should be /usr/local/sbin/udev-automounter.sh %k. sorry. – quack quixote – 2009-11-04T04:28:55.603

currently debugging the spaces-in-labels issue. what filesystems are you using? my only test device is currently FAT and working but not well; i think NTFS/ext2 will be friendlier. – quack quixote – 2009-11-04T16:28:23.513

1OK, as of Update-3, it works with spaces. it does so by using an "encoded" version of <LABEL> that converts spaces into \x20's. so it's not pretty, but it will work. udev isn't handling the labels-with-spaces nicely, but there is another option that uses underscores instead of \x20's (so it at least looks nice). looks like space-handling has to go into the shellscripts. – quack quixote – 2009-11-04T17:33:52.633

update 5 up, scripts v2.0. rule changed too but nothing will break if you keep the old version. – quack quixote – 2009-11-04T20:09:46.623

Right now I have an EXT3 partition, an NTFS, and three FAT32s. – endolith – 2009-11-04T20:24:37.233

you can get away with a single mount (no case clause) if you just want defaults. ext3 won't like the -o uid=X stuff; it doesn't even mount on my system when i include that option. – quack quixote – 2009-11-04T21:22:43.950

1Much simpler method: Set the computer to auto-login a user, and then lock the screen after login. The automatic mount points created by Gnome/Hal/whatever have real spaces in them, for the record, like /media/EXT3\ backup/ – endolith – 2009-11-14T17:56:16.697

Im glad this worked for your other question :) – invert – 2009-11-16T10:00:49.797

It worked for both! Add it as an answer here so I can vote it up. That's the solution I'm actually using. – endolith – 2009-11-17T05:02:11.870

i figured out how to do this by running halevt as a system daemon; edited my second answer with the how-to. using autologin is a clever hack-a-round but not secure enough for my taste. – quack quixote – 2009-11-21T13:04:21.577

After upgrading to Karmic, drives do not auto-mount on auto-login. >:( – endolith – 2009-12-13T17:55:17.637

@endolith you might want to review my recent answer. this used to be hard few years ago (extreme long and unnecessary accepted answer), however now it's just a matter of apt-getting a package. a short answer will help many who do not scroll down to alternate solutions and thus might miss the easy answer. – Costin Gușă – 2014-04-26T10:41:26.357

Answers

74

  • Note for Ubuntu Server 11.10: This script fails on Ubuntu Server 11.10 due to the obsolete vol_id command. vol_id has been superseded by blkid. To fix the script, replace "vol_id" by "blkid -o udev" in the udev-auto-mount.sh script.

I've been banging my head around this for a while now, and I think I've found a working solution. This is developed and tested on a Debian-based system, so it should work on Ubuntu. I'll point out the assumptions it makes so it can be adapted to other systems as well.

  • It will automatically mount USB drives on plugin, and shouldn't take much to adapt for Firewire.
  • It uses UDEV, so no monkeying with HAL/DeviceKit/GNOME-Anything.
  • It automagically creates a /media/LABEL directory to mount the device to.

  • However, it may interfere with other automounters; I can't test for that. I expect that, with Gnome-VFS active, both may try to do the mount ... if Gnome-VFS fails the mount, it might not configure a desktop icon. Unmounting from Gnome should be possible, but might require gksudo or similar.

I have not tested this on system boot, but the only reason I can see that it might not work is if it tries to mount the USB drive before the system is ready for mounts. If that's the case, you'll probably need one additional tweak to the mount script. (I'm checking with ServerFault to see if there's any advice, but not much interest in it over there.)

On to it, then.


UDEV references:


Background (UDEV? Whuzzat?)

UDEV is the kernel's hotplug system. It's what automagically configures the proper devices and device symlinks (eg /dev/disk/by-label/<LABEL>), both at boot time and for devices added while the system is running.

D-Bus and HAL are used for sending hardware events to listeners like Desktop Environments. So when you log into GNOME and insert a CD or plug in a USB drive, that event follows this chain:

kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount)

And presto, your drive gets mounted. But in a headless system, we don't want to have to log in to get the benefits of automounting.

Udev Rules

Since UDEV lets us write rules and run programs on device insertion, this is an ideal choice. We're going to take advantage of Debian/Ubuntu's existing rules, let them setup the /dev/disk/by-label/<LABEL> symlink for us, and add another rule that will mount the device for us.

UDEV's rules are kept in /etc/udev/rules.d (and /lib/udev/rules.d on Karmic), and are processed in numerical order. Any file not starting with a number gets processed after the numbered files. On my system, HAL rules are in a file called 90-hal.rules, so I put my rules in 89-local.rules so they get processed before they get to HAL. Primarily, you need to make sure these rules happen after the 60-persistent-storage.rules. local.rules may be good enough.

Put this in your new rules file:

# /etc/udev/rules.d/local.rules 
# /etc/udev/rules.d/89-local.rules
# ADD rule: if we have a valid ID_FS_LABEL_ENC, and it's USB, mkdir and mount
ENV{ID_FS_LABEL_ENC}=="?*",   ACTION=="add",      SUBSYSTEMS=="usb", \
         RUN+="/usr/local/sbin/udev-automounter.sh %k"
  • Make sure there's no spaces after the \, just a newline (\n).

  • Change SUBSYSTEMS=="usb" to SUBSYSTEMS=="usb|ieee1394" for Firewire support.

  • If you want the device to always be owned by a particular user, add an OWNER="username" clause. If you just need the files owned by a particular user, tweak the mount script instead.

Reading the Rule

This adds a program to run to the device's list of programs to run. It identifies USB partition devices by <LABEL>, then passes this information to a script that performs the mount. Specifically, this rule is matching:

  1. ENV{ID_FS_LABEL_ENC}=="?*" -- an environment variable set by an earlier system rule. Doesn't exist for non-filesystems, so that's why we check for it. We actually want to use ID_FS_LABEL for the mount point, but I haven't convinced UDEV to escape it for me, so we'll let the mount script handle that.

    This and other environment variables are obtained by udev using the vol_id command (deprecated). It's a handy tool to see nice quick details on a partition:

    $ sudo vol_id /dev/sdc1
    ID_FS_TYPE=ext2
    ID_FS_UUID=a40d282a-4a24-4593-a0ab-6f2600f920dd
    ID_FS_LABEL=Travel Dawgs
    ID_FS_LABEL_ENC=Travel\x20Dawgs
    ID_FS_LABEL_SAFE=Travel_Dawgs
    
  2. ACTION=="add" -- only match add events...

  3. SUBSYSTEMS=="usb" -- only match devices that are on the USB bus. We use SUBSYSTEMS here because this matches against our device's parents; the device we're interested in will actually be SUBSYSTEM=="scsi". Matching against a parent USB device avoids adding our program to the internal drives.

  4. RUN+="..." -- not a match, but an action: add this program to the list of programs to run. In the program's arguments, %k gets expanded to the device name (eg sdc1, not /dev/sdc1) and $env{FOO} gets the contents of environment variable FOO.

Testing the Rule

The first reference link (above) is an excellent UDEV tutorial, but it's slightly out of date. The programs it runs for testing your rules (udevtest in particular) have been replaced by the catch-all udevadm utility.

After you've added the rule, plug in your device. Give it a few seconds, then check to see what device it's been assigned to with:

$ ls -l /dev/disk/by-label/*
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Foo -> ../../sda1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Bar -> ../../sdb1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Baz -> ../../sdc1

If your removeable drive contains label_Baz, it's on device sdc1. Run this and look at the output towards the end:

$ sudo udevadm test /sys/block/sdc/sdc1
parse_file: reading (...)                           (many lines about files it reads)
import_uevent_var: import into environment: (...)   (many lines about env variables)
(...)                                               (many lines tracing rule matches & programs run)
update_link: found 1 devices with name 'disk/by-label/LABEL_BAZ'
update_link: found '/block/sdc/sdc1' for 'disk/by-label/LABEL_BAZ'
update_link: compare (our own) priority of '/block/sdc/sdc1' 0 >= 0
update_link: 'disk/by-label/LABEL_BAZ' with target 'sdc1' has the highest priority 0, create it
udevtest: run: '/usr/local/sbin/udev-automounter.sh sdc1 LABEL_BAZ'
udevtest: run: 'socket:/org/freedesktop/hal/udev_event'
udevtest: run: 'socket:@/org/kernel/udev/monitor'

Look for the script name from our RUN+= rule in the last few lines (3rd from the bottom in this example). You can see the arguments that would be used for this device. You can run that command now to check that the arguments are sound; if it works on your commandline, it should work automatically when a device is inserted.

You can also monitor UDEV events in realtime: run sudo udevadm monitor (see man udevadm for details on the switches). Then just plug in a new device and watch events scroll by. (Probably overkill unless you're into really low-level details...)

Reloading the Rules

Once you've verified the rule is getting read properly, you need to tell UDEV to reload its rules so the new one takes effect. Use any of these methods (if the first doesn't work, the second should... but try the first first):

  • run sudo udevadm control --reload-rules

  • run sudo /etc/init.d/udev reload

  • reboot


Script! Actually, 2 Scripts...


Here's the first script. Since the program we run needs to complete quickly, this just spins the second script off in the background. Put this in /usr/local/sbin/udev-automounter.sh:

#!/bin/sh
#
# USAGE: usb-automounter.sh DEVICE 
#   DEVICE   is the actual device node at /dev/DEVICE

/usr/local/sbin/udev-auto-mount.sh ${1} &

Here's the second script. This does a bit more input checking. Put this in /usr/local/sbin/udev-auto-mount.sh. You may want to tweak the mount options below. This script now handles finding the partition LABEL on its own; UDEV only sends the DEVICE name.

If there's a problem mounting drives at boot-time, you can put a nice long sleep 60 in this script, to give the system time to come all the way up before the script attempts to mount the drive.

I've given a suggestion in the comments for how to check (run ps to see if a webserver is running), but you'll want to tweak that for your system. I think most any network servers you might be using would suffice for this purpose -- nfsd, smbd, apache, etc. The risk, of course, is that the mount script will fail if the service isn't running, so maybe testing a particular file's existence would be a better solution.

#!/bin/sh
#
# USAGE: udev-auto-mount.sh DEVICE
#   DEVICE   is the actual device node at /dev/DEVICE
# 
# This script takes a device name, looks up the partition label and
# type, creates /media/LABEL and mounts the partition.  Mount options
# are hard-coded below.

DEVICE=$1

# check input
if [ -z "$DEVICE" ]; then
   exit 1
fi

# test that this device isn't already mounted
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
   echo "error: seems /dev/${DEVICE} is already mounted"
   exit 1
fi

# If there's a problem at boot-time, this is where we'd put
# some test to check that we're booting, and then run
#     sleep 60
# so the system is ready for the mount below.
#
# An example to experiment with:
# Assume the system is "booted enough" if the HTTPD server is running.
# If it isn't, sleep for half a minute before checking again.
#
# The risk: if the server fails for some reason, this mount script
# will just keep waiting for it to show up.  A better solution would
# be to check for some file that exists after the boot process is complete.
#
# HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# while [ -z "$HTTPD_UP" ]; do
#    sleep 30
#    HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# done


# pull in useful variables from vol_id, quote everything Just In Case
eval `/sbin/vol_id /dev/${DEVICE} | sed 's/^/export /; s/=/="/; s/$/"/'`

if [ -z "$ID_FS_LABEL" ] || [ -z "$ID_FS_TYPE" ]; then
   echo "error: ID_FS_LABEL is empty! did vol_id break? tried /dev/${DEVICE}"
   exit 1
fi


# test mountpoint - it shouldn't exist
if [ ! -e "/media/${ID_FS_LABEL}" ]; then

   # make the mountpoint
   mkdir "/media/${ID_FS_LABEL}"

   # mount the device
   # 
   # If expecting thumbdrives, you probably want 
   #      mount -t auto -o sync,noatime [...]
   # 
   # If drive is VFAT/NFTS, this mounts the filesystem such that all files
   # are owned by a std user instead of by root.  Change to your user's UID
   # (listed in /etc/passwd).  You may also want "gid=1000" and/or "umask=022", eg:
   #      mount -t auto -o uid=1000,gid=1000 [...]
   # 
   # 
   case "$ID_FS_TYPE" in

       vfat)  mount -t vfat -o sync,noatime,uid=1000 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
              ;;

              # I like the locale setting for ntfs
       ntfs)  mount -t auto -o sync,noatime,uid=1000,locale=en_US.UTF-8 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
              ;;

              # ext2/3/4 don't like uid option
       ext*)  mount -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
              ;;
   esac

   # all done here, return successful
   exit 0
fi

exit 1

Super Bonus Cleanup Script!

One more script. All this does is unmount the device and remove the mountpoint directories. It assumes it has privs to do this, so you'll need to run it with sudo. This script now takes the full mountpoint on the commandline, eg:

$ /usr/local/sbin/udev-unmounter.sh "/media/My Random Disk"

Put this in /usr/local/sbin/udev-unmounter.sh:

#!/bin/sh
#
# USAGE: udev-unmounter.sh MOUNTPT
#   MOUNTPT is a mountpoint we want to unmount and delete.
MOUNTPT="$1"

if [ -z "$MOUNTPT" ]; then
   exit 1
fi


# test mountpoint - it should exist
if [ -e "${MOUNTPT}" ]; then

   # very naive; just run and pray
   umount -l "${MOUNTPT}" && rmdir "${MOUNTPT}" && exit 0

   echo "error: ${MOUNTPT} failed to unmount."
   exit 1
fi

echo "error: ${MOUNTPT} does not exist"
exit 1

quack quixote

Posted 2009-10-11T18:13:30.230

Reputation: 37 382

Looks like on my machine scripts are executed properly, but the mount commands are not working. However, when I run the scripts manually, with sudo, they are working as expected. How can I troubleshoot this? – Sfisioza – 2014-08-01T16:14:06.383

Typo: "remov e able drive". – Hello71 – 2010-08-27T15:17:57.353

1

Reference: udev_237 - man udev (Ubuntu_18.04) Note that running programs that access the network or mount/unmount filesystems is not allowed inside of udev rules, due to the default sandbox that is enforced on systemd-udevd.service. source: https://unix.stackexchange.com/questions/200194/how-to-debug-an-udev-rule-in-etc-udev-rules-d#answer-207712 For a solution, have a look at https://serverfault.com/questions/766506/automount-usb-drives-with-systemd

– Pro Backup – 2018-12-25T23:14:57.660

This is a really great answer, and a great little howto also! Thank you for that. Wondering, though - it doesn't seem like the ENV{ID_FS_LABEL_ENC}=="?*" bit is actually doing anything. I'm trying to automount only particularly named partitions (partitions beginning with "XD"), but no value I try to match against will prevent this udev rule from being executed. Even ENV{ID_FS_LABEL_ENC}=="sowhat'supmylittlepony" won't prevent this rule from being run on every drive I plug in. You sure those environment variables exist at the time udev checks against the rule? They seem to be initialized later. – DanielSmedegaardBuus – 2012-08-31T11:11:50.710

My bad - it matches fine. My problem was that I got inspired by your breaking the rule into several lines by escaping line breaks. Seems if you put those in some places, it'll break the rule. I just put everything in one line and it works. Go figure :D – DanielSmedegaardBuus – 2012-08-31T11:48:00.823

3You're great! :) – kolypto – 2009-11-04T02:05:04.520

1If I run auto-mount.sh manually it works, but not if I plug in a drive, and not on boot. :/ – endolith – 2009-11-04T03:41:59.663

so the problem is with the UDEV rules. lemme expand that section a bit to help you debug. – quack quixote – 2009-11-04T04:00:03.243

ARRRGHH... bug in the RUN. turn /usr/local/sbin/udev-automounter.sh mount %k into /usr/local/sbin/udev-automounter.sh %k. sorry. – quack quixote – 2009-11-04T04:28:13.530

Hmmm... Still isn't working on boot, though I'm not local and can't troubleshoot right now. It doesn't seem to like labels with spaces in them, either. Is there a way to fix that? – endolith – 2009-11-04T15:40:03.050

i can't figure out how to make UDEV quote the environment variable but that's ok, the mount script can figure it out. working on the update... – quack quixote – 2009-11-04T18:13:42.210

Wait, you actually have a case for each FS? How did pmount and gnome-volume-manager handle this? – endolith – 2009-11-04T20:51:17.897

i put it in because my ext2 device wasn't get mounted with the -o uid=1000. you should be able to get away with a single mount if you don't need to specify any options and just want the defaults. dunno how pmount/gnome-volume-manager do it, but i suspect it's similar. – quack quixote – 2009-11-04T21:18:39.043

Still not working on boot, but it does work for all partitions when I plug in the drives. Interestingly, when I log in locally, it shows the partitions as they normally appear under "Computer" in Nautilus, but when I click them, it goes to the mount points with underscores. Cool. It can't be unmounted from the GUI, which I don't think is a problem. "The volume 'STORAGE' was probably mounted manually on the command line." – endolith – 2009-11-05T02:12:02.213

sorry it's not working on boot for you (i really haven't had an opportunity to reboot my system so i haven't been able to test). since you've got the mount script working, you could just call it from /etc/rc.local ... say, by looping through /dev/disk/by-label/*, getting the devices, checking if those partitions are mounted, and calling the mount script on them if they aren't. hmm. – quack quixote – 2009-11-05T02:38:23.140

3

I have assembled all the scripts on github: https://github.com/fatso83/Code-Snippets/tree/master/system-utils/ubuntu/automount

They work fine on Ubuntu 10.10, and also include auto-unmount

– oligofren – 2013-05-02T16:57:47.290

TYVM;on debian wheezy, had to fix a few things. ntfs-3g wasn't installed; removed the if block that failed over if the mount point existed; set +x on the scripts; – marinara – 2013-07-19T20:31:37.343

this is way too much explanation for an user looking for a fast straight and easy answer. I've added a clean answer down below. – Costin Gușă – 2014-04-26T10:56:37.723

9

One final option that others have suggested around the net is ivman, but that appears to depend on pmount, which you've already stated doesn't work. pmount is abandoned and ivman is nearly the same.

The replacement for ivman is halevt, and it's available in Karmic. It is a reimplementation of ivman (read: "maintained" and "doesn't depend on pmount"). The package isn't available on Jaunty, although you may be able to build it yourself if you aren't planning to upgrade.

Both of these tools sit above the DBus and HAL layers and respond to events from them. Apparently both can run either as a system daemon or as a user-session mount manager (a la Gnome-VFS) -- the /etc/defaults/{ivman,halevt} files are in charge of system settings.

Here are some instructions for tweaking ivman to use /media/<LABEL> mountpoints. It's likely that halevt has a simpler way to do it, but perhaps they'll help you find an answer.


Working with HALEVT

Update: In the interest of getting automagical CD mounts as well, which my UDEV answer doesn't provide, I looked deeper at halevt. I found this blog post which helped explain a lot about the process. I did have to compile my own halevt package for Debian Lenny (fortunately all dependencies were in the lenny-backports section). Once installed, the process was mostly not-horrible:

  1. Make sure system halevt-daemon is enabled in /etc/default/halevt
  2. Allow the system halevt user to mount devices in /etc/PolicyKit/PolicyKit.conf (see below; source)
  3. Modify HAL policy to copy the volume label into the preferred mountpoint in /etc/hal/fdi/policy/preferences.fdi (see below)
  4. If you want CD/DVD support, grab the eject.hal script from the above blogpost, modify, and save in /usr/local/bin.
  5. Modify halevt system config to enable mounts in /etc/halevt/halevt.xml
  6. Add code to your login manager's pre- and post-session scripts to stop the system halevt-daemon when someone logs on, and restart it when they log off.

If you need to restart the HAL and HALEVT daemons to check your new configurations, use this to get them in the right order:

sudo sh -c "/etc/init.d/halevt stop ; /etc/init.d/hal restart ; /etc/init.d/halevt start"

Step 1

Check that START_DAEMON=yes in /etc/default/halevt.

Step 2

In /etc/PolicyKit/PolicyKit.conf, add this inside the <config></config> section:

<match action="org.freedesktop.hal.storage.mount-removable">
   <match user="halevt">
      <return result="yes"/>
   </match>
</match>

Step 3

In /etc/hal/fdi/policy/preferences.fdi, add this inside the ` section:

<match key="volume.label" empty="false">
    <match key="volume.label" is_absolute_path="false">
        <merge key="volume.policy.desired_mount_point" type="copy_property">volume.label</merge>
    </match>
</match>

Step 4

The script is good but needs to run /bin/bash; some systems may actually use /bin/dash when /bin/sh is called. So change the top line in the script to make sure you get the right one:

#!/bin/sh         <------ old first line

#!/bin/bash       <------ new first line

Step 5

This is the fun part. Your system may provide a basic /etc/halevt/halevt.xml already, so you'll have to tailor this for your own use. In my case, my system already provided basic removeables mounting, but I had to add support for CDROM mounting and the eject button.

The blog post I mentioned has a good example XML configuration to look at for your own tweaks. It's mostly about setting up a gnome-mount replacement for the author's fluxbox environment, so his example XML does more than you'll want, but it's a great way to get a feel for what you can do. There are also some good examples in /usr/share/doc/halevt/examples.

I also had to run sudo sh -c "mkdir /var/halevt ; chown halevt:plugdev /var/halevt" before everything would work.

Here's my additions to make automounting CD/DVD work:

<!-- CD/DVD mount -->
<halevt:Device match="hal.block.device &amp; hal.block.is_volume = true  &amp; hal.volume.is_disc = true &amp; hal.volume.disc.has_data = true">
   <halevt:Property name="hal.volume.is_mounted">
      <halevt:Action value="true" exec="halevt-mount -u $hal.udi$ -p $hal.volume.policy.desired_mount_point$ -m 002"/>
   </halevt:Property>
</halevt:Device>

<!-- CD/DVD eject button support -->
<halevt:Device match="hal.storage.drive_type = cdrom">
   <halevt:Condition name="EjectPressed" exec='/usr/local/bin/eject.hal $hal.block.device$'/>
</halevt:Device>

Step 6

Once you've gotten the system halevt-daemon working, you'll need to disable it when you login to GNOME, and restart it again when you log out. (See my answer to this question for non-GDM login managers.) This stuff is theoretical since I don't use it, but it should work.

In /etc/gdm/PreSession/Default, add this to stop the system halevt-daemon:

/etc/init.d/halevt stop

In /etc/gdm/PostSession/Default, add this to restart the system halevt-daemon:

/etc/init.d/halevt start

quack quixote

Posted 2009-10-11T18:13:30.230

Reputation: 37 382

3For people reading this in 2013, they should now know that HAL has been deprecated, and they should resort to udev based solutions such as the one quack quixote gave above. – oligofren – 2013-05-07T07:28:35.160

6

As time goes by, easier solutions appear.

This solution relies on the udevil software package which was written for this purpose and requires no tinkering with udev rules. It is probably preferable (to new and old users) as a straight-forward solution.

The devmon script from udevil does all the magic while only depending on udev and glib. Works almost out of the box without needing initial configuration.

All I have done on my workstation was to call devmon from rc.local like this:
devmon 2>&1 >> /var/log/devmon &
For your comfort you might want to embed this into an init script instead of rc.local using an automated tool such as pleaserun to create it: https://unix.stackexchange.com/a/124609/42673

After having it running, storage that I plug is inspected (it looks for partitions and if found looks at their filesystem labels) then mounted into /media/FILESYSTEM_LABEL.
Could not imagine anything simpler than that except maybe that the (in)famous systemd to incorporate this functionality at some point in the future.

udevil At A Glance (github.io/udevil)
Script: devmon (igurublog/script-devmon)

Costin Gușă

Posted 2009-10-11T18:13:30.230

Reputation: 637

3

quack quixote's answer doesn't work on Ubuntu Lucid Lynx (10.04) -- there's no /sbin/vol_id command.

Rather than being fancy and using udev, put this into your /etc/rc.local and be done:

for dev in $(ls -1 /dev/disk/by-label/* | grep -v EFI) ; do
  label=$(basename $dev)
  mkdir -p /media/$label
  $(mount | grep -q /media/$label) || mount $dev /media/$label
done

mrm

Posted 2009-10-11T18:13:30.230

Reputation: 151

1THANK YOU.. this was the simplest way for what I wanted to accomplish. Even worked on Ubuntu Server 16 with an ntfs volume – ChrisPrime – 2016-05-30T02:41:40.097

3

To flush out quack quixote's excellent instructions for removal:

Add the following line to the udev rule file you made earlier (/etc/udev/rules.d)"

ENV{ID_FS_LABEL_ENC}=="?*",   ACTION=="remove",      SUBSYSTEMS=="usb", \
         RUN+="/usr/local/sbin/udev-autounmounter.sh %k"

Next create the following script and chmod it executable (/usr/local/sbin/udev-autounmounter.sh) with the following contents:

#!/bin/sh
#
# USAGE: usb-autounmounter.sh DEVICE 
#   DEVICE   is the actual device node at /dev/DEVICE

/usr/local/sbin/udev-auto-unmount.sh ${1} &

Finally the unmount script itself (udev-auto-unmount.sh):

#!/bin/sh
#
# USAGE: udev-auto-unmount.sh DEVICE
#   DEVICE   is the actual device node at /dev/DEVICE
# 
# This script takes a device name, looks up the partition label and
# type, creates /media/LABEL and mounts the partition.  Mount options
# are hard-coded below.

DEVICE=$1

# check input
if [ -z "$DEVICE" ]; then
   exit 1
fi

#test that the device is already mounted
MOUNTPT=`mount | grep ${DEVICE} | cut -d ' ' -f 3`
if [ -z "${MOUNTPT}" ]; then
   echo "error: the device is not already mounted"
   exit 1
fi

# test mountpoint - it should exist
if [ -e "${MOUNTPT}" ]; then

   # very naive; just run and pray
   umount -l "${MOUNTPT}" && rmdir "${MOUNTPT}" && exit 0

   echo "error: ${MOUNTPT} failed to unmount."
   exit 1
fi

echo "error: ${MOUNTPT} does not exist"
exit 1

So with the other instructions, the directory will auto appear and disappear on udev events.

chotchki

Posted 2009-10-11T18:13:30.230

Reputation: 141

I think if [ -n "$device_is_mounted" ]; then should be if [ -z "${MOUNTPT}" ]; then, shouldn't it? – eresonance – 2014-10-19T14:29:31.837

3

For Debian based systems (e.g. Ubuntu etc) there's the usbmount package that automatically mounts USB drives for you. It basically uses a udev based approach as already outlined - only it's just a simple package install. It seems the original author of the package has run out of steam but Ubuntu/Debian still appears to maintain it (I guess it's not that complex) - so it's still available in the latest releases.

The installed scripts can be configured (/etc/usbmount/usbmount.conf) to provide the appropriate mount points.

Pierz

Posted 2009-10-11T18:13:30.230

Reputation: 880

1Usbmount cannot mount by label though, unless you fill in the list of labels in the configuration file. – Gilles 'SO- stop being evil' – 2014-03-17T22:56:37.603

1

See post http://esite.ch/2014/04/11/mounting-external-usb-drives-automatically-to-its-label/ if you want to add mounting to label to usbmount without maintaining a list.

– Oliver Sauder – 2014-04-11T08:48:35.387

2

You can try putting su username -c gnome-volume-manager in /etc/rc.local. It might be enough to simply have gnome-volume-manager running.

Edit: It seems that gnome-volume-manager is no longer part of the default distribution, even on Ubuntu desktop.

wajig policy  gnome-volume-manager
gnome-volume-manager:
  Installed: (none)
  Candidate: 2.24.0-0ubuntu1
  Version table:
     2.24.0-0ubuntu1 0
        500 http://ubuntu.secs.oakland.edu jaunty/universe Packages

However, maybe if you install it, it will still work. It's worth a try. If it doesn't work, remove it again.

There's also the usbmount package, which does what you want, but might possibly interfere with normal automounting.

Ryan C. Thompson

Posted 2009-10-11T18:13:30.230

Reputation: 10 085

Unknown command “gnome-volume-manager”. I'm in Ubuntu Jaunty. – endolith – 2009-10-11T22:50:30.453

There is a /usr/lib/gnome-volume-manager/gnome-volume-manager, but it does nothing. – endolith – 2009-10-11T22:57:55.587

Oh I see. There's a package called gnome-volume-manager, too. Related: http://crunchbanglinux.org/forums/topic/239/gnomevolumemanager-on-intrepid/

– endolith – 2009-10-31T00:04:18.810

It looks like gnome-volume-manager uses HAL to mount things? And "As of 2009, HAL is in process of being deprecated in favor of DeviceKit." Why is everything in Linux always like this? They just start to get something working almost right and then they gut it out and replace it with something new that doesn't work. – endolith – 2009-10-31T01:00:23.790

pmount doesn't even work anymore. > pmount /dev/disk/by-label/STORAGE Error: device /dev/sdc1 is not removable http://www.togaware.com/linux/survivor/Using_Gnome_Volume_Manager.html

– endolith – 2009-10-31T01:06:13.707

"Warning: The original author does not have enough time any more to actively maintain the USBmount package. It is therefore currently unmaintained." – endolith – 2009-11-02T21:55:59.307

2

You might want to try out Pysdm

Sathyajith Bhat

Posted 2009-10-11T18:13:30.230

Reputation: 58 436

That's just another fstab editor, isn't it? – endolith – 2009-10-30T03:20:48.167

Yes, but "It also allows the creation of udev rules for dynamic configuration of storage devices" – Sathyajith Bhat – 2009-10-30T04:40:00.113

Would "creation of udev rules" help me in some way? I have no idea what that even means. Does it mount previously-unknown removable devices without a user logged in locally? – endolith – 2009-11-02T21:52:48.000

Sorry, I don't any any clue on udev rules. You could have a look at http://fredericiana.com/2006/03/15/writing-udev-rules-short-notes/ and http://www.reactivated.net/writing_udev_rules.html

– Sathyajith Bhat – 2009-11-02T23:30:17.650

2

My edited addendums for quack quixote's udev-based solution were rejected, so I'm gonna put them here. Please refer to his post first.

First of all, if you want your udev rule to act when any device is attached via the SCSI subsystem (which includes both USB, FireWire, and eSATA), change the SUBSYSTEMS match in the udev rule to SUBSYSTEMS=="scsi".

Do keep in mind, though, that this will automatically mount pretty much anything, including internal drives if you hotplug them while the system is running, so it may not be what you want.

Secondly, here is the script I'm using which replaces all the scripts in that post. It also automatically cleans up created mountpoints in /media/ as soon as the mounted block device is removed — no need for manual intervention. Further, rather than calling a different script to run in the background, it puts itself in the background when it isn't executed from a terminal (e.g. when executed via udev).

It uses inotifywait to wait until the device which was mounted disappears, and then removes the directory it created. Therefore, you need to have inotify-tools installed on your system. On Debian-based distros (including Ubuntu), sudo apt-get install inotify-tools should suffice.

#!/bin/bash
#
# Auto-mounter script, to be executed by udev on the addition of a
# mass storage device.
#
# Takes one argument; the base block device partition, e.g. "sdb3".
#
# Creates a mountpoint for the partition using its FS label, in
# /media/{fslabel} and mounts it there, read-only, unsynced.
#
# If the filesystem has no label, "Untitled" is used instead.
#
# If another filesystem is already mounted at that location, the
# newcomer will be mounted with an integer number appended to its
# label.

MOUNT_OPTS="ro,noatime,nodiratime"



# If we're called from a non-tty and not explicitly told to continue,
# we call ourselves in a subshell and thus return immediately (udev
# gets impatient):
if [[ "$2" != "backgrounded" ]] && ! tty &> /dev/null; then
    ($0 $1 backgrounded &)
    exit
fi



# Determine the desired mountpoint from the label of the fs on the partition:
MOUNTPOINT="/media/$(blkid /dev/$1 | grep LABEL | sed -E 's:^.+LABEL="([^"]+).+:\1:')"

# If it had no label, use "Untitled":
[[ "$MOUNTPOINT" = "/media/" ]] && MOUNTPOINT="/media/Untitled"

# If something's already mounted there, append a number:
if [[ -e "$MOUNTPOINT" ]] && mountpoint "$MOUNTPOINT" &> /dev/null; then
    NUM=1
    while mountpoint "$MOUNTPOINT $NUM" &> /dev/null; do NUM=$((NUM+1)); done
    MOUNTPOINT="$MOUNTPOINT $NUM"
fi

# Create the mountpoint and mount there:
mkdir "$MOUNTPOINT" && mount -o $MOUNT_OPTS /dev/$1 "$MOUNTPOINT"



# Wait until the device is removed (the block device is "deleted"):
inotifywait -e delete /dev/$1

# Then clean up. If it fails, retry every second for up to 5 mins:
TRIES=0
while [[ -e "$MOUNTPOINT" ]] && [[ $TRIES -lt 300 ]]; do
    rmdir "$MOUNTPOINT"
    sleep 1s
    TRIES=$((TRIES+1))
done

You'll note that I mount devices without sync, and read-only. That's just because 99% of the time, my use case is reading from an external drive, and whenever I need to write to it, I'm gonna be active on the server anyway, and can easily issue a mount -o remount,rw <mountpoint> command. Edit to suit your needs :)

DanielSmedegaardBuus

Posted 2009-10-11T18:13:30.230

Reputation: 645

How do you run this script? halevt doesn't seem to be a current apt-getable package for modern versions. – Campbeln – 2019-09-21T01:03:21.630

Agh... maybe if I follow the TOP / Accepted Answer entry from quack quixote's... Would still be nice to have a fuller answer here :) – Campbeln – 2019-09-21T01:16:10.813

1

Try configuring via mountmanager, so that you do not have to enter data manually.

It should be a part of the ubuntu repository.

Abhinav

Posted 2009-10-11T18:13:30.230

Reputation: 2 030

You'll need to enable the universe section to get it. – quack quixote – 2009-10-11T19:21:52.433

apt:mountmanager?section=universe ;) – endolith – 2009-10-11T22:36:38.280

Is that just going to set up an fstab for me? – endolith – 2009-10-11T22:47:35.467

@endolith: Wouldn't apt:universe?install=mountmanager be more logical? ;) – Bobby – 2009-11-03T13:08:06.630

Does that format work? It doesn't say so in the man page http://manpages.ubuntu.com/manpages/karmic/en/man8/apturl.8.html

– endolith – 2009-11-03T15:25:01.167

-5

If you only have one drive mounted at a time, you can simply edit this into your /etc/fstab file. Something along the lines of:

/dev/sdb1     /mnt/usbdrive     ext3     defaults 0   0

This should mount it at boot, and make it accessible to anyone with perms. If you have more than one drive, you can still do this with:

/dev/sdb1     /mnt/usbdrive1     ext3     defaults 0   0
/dev/sdc1     /mnt/usbdrive2     ext3     defaults 0   0

Jack M.

Posted 2009-10-11T18:13:30.230

Reputation: 3 133

6clearly not what the question asks. – quack quixote – 2009-10-30T21:33:08.710