2

I used fstab to mount a specific device automatically at boot in a specific location. That is very simple but not what I need now.

Is there a way to setup the automount of any mountable USB device I plug in more or less like Ubuntu does in Raspbian? Like in /media/ or /media/ or something else?

I tried usbmount and it works, but doesn't seem to be perfect and also seems to be discontinued. Any other option?

2
  • What don't you like with usbmount? I use it and have to say I'm quite happy with it.
    – Bex
    Apr 26, 2014 at 6:48
  • It seems that after unmounting the device and unplugging it, the mount points it created persist in /var creating a little confusion. Also it seems the last version is from 2007... Apr 26, 2014 at 9:49

3 Answers 3

3

pmount is a richer alternative to usbmount. It has knowledge about some desktop environments and is able to show an icon and so forth.

Also have a look on the package hal. It is a feature rich hardware manipulation suite, that can do automounting among other things.

2
  • 1
    pmount is magic. Definitely a must-have for Jessie. Now to find the documentation so I can have it make an icon and everything. Also, I have several Pi3s that are accessible by WiFi but aren't in physical locations conducive to unplugging and replugging the USB drives, and it restored their mount points perfectly. Thank you for this tip!
    – SDsolar
    Apr 13, 2017 at 4:16
  • Looks like hal is just for Wheezy.
    – SDsolar
    Apr 13, 2017 at 4:26
2

I recently had almost the same problem, so I wrote a little script myself and the according udev rules. Your can find a longer explanation on my website solvedforhome.com

With this script any usb stick/drive or hdd/sdd will automatically be mounted under /media/<USB_DEVICE_LABEL>/ and unmounted when the device is plugged off (logging included).

The short version here:

First you create the udev rules with

sudo nano /etc/udev/rules.d/00-mount_manager

and write this into the file:

ACTION=="add",SUBSYSTEM=="block",KERNEL=="sd*[!0-9]",RUN+="/root/mount_manager/mount_manager add"
ACTION=="remove",SUBSYSTEM=="block",KERNEL=="sd*[!0-9]",RUN+="/root/mount_manager/mount_manager remove"

Then create the script with

sudo mkdir /root/mount_manager
sudo nano /root/mount_manager/mount_manager

and copy this into the file:

#!/bin/bash

APP_DIR=/root/mount_manager
LOG_DIR=$APP_DIR
LOG_FILE="${LOG_DIR}/mount_manager.log"
MOUNT_DIR=/media/

log_private=true
log_syslog=true

user=root
group=root

arr_media_mounted=()
arr_media_unmounted=()
arr_plugged_in_path=()
arr_plugged_in_label=()
arr_plugged_in_type=()

# function for mounting different file systems
function mounter {
    # $1 device path /dev/sd*
    # $2 name or label of device
    # $3 format or type

    if [ "vfat" == "$3" ]; then
        mount -t vfat -o utf8,uid=${user},gid=${group} $2 $MOUNT_DIR$1 >> $LOG_FILE 2>&1
    fi
        if [ "ntfs" == "$3" ]; then
        mount -t ntfs -o rw $2 $MOUNT_DIR$1 >> $LOG_FILE 2>&1 #not tested
    fi
        if [ "hfsplus" == "$3" ]; then
        mount -t hfsplus -o utf8,uid=${user},gid=${group} $2 $MOUNT_DIR$1 >> $LOG_FILE 2>&1 #not tested
    fi
        if [ "exfat" == "$3" ]; then
        mount -t exfat -o utf8,uid=${user},gid=${group} $2 $MOUNT_DIR$1 >> $LOG_FILE 2>&1 #not tested
    fi
        if [ "ext4" == "$3" ]; then
        mount -t ext4 -o defaults $2 $MOUNT_DIR$1 >> $LOG_FILE 2>&1
    fi
}

# functions for loggin output
function log {
    if [ "$log_private" = true ] ; then
        echo "$(date +"%Y.%m.%d %H:%M:%S") $1" >> $LOG_FILE
    fi
}
function log_info {
    log "INFO: $1"
        if [ "$log_syslog" = true ] ; then
        logger $1 -p info -t ${0#./}
    fi
}
function log_warn {
    log "WARNING: $1"
        if [ "$log_syslog" = true ] ; then
                logger $1 -p warning -t ${0#./}
    fi
}
function log_err {
        log "ERROR: $1"
        if [ "$log_syslog" = true ] ; then
                logger $1 -p error -t ${0#./}
    fi
}

# backup log
if [ "$(wc -l < $LOG_FILE)" -gt 200 ]; then
    mv $LOG_FILE ${LOG_FILE}.1
fi


######################################################
#
#       start main routine

log_info "========== mount_manager called by udev $1 =========="


# get directories in mounting directory $MOUNT_DIR
for dir in $(ls -d "${MOUNT_DIR}"*); do
    if mount | grep $dir > /dev/null; then
        arr_media_mounted+=(${dir#$MOUNT_DIR})
    else
        arr_media_unmounted+=(${dir#$MOUNT_DIR})
    fi
done


# get plugged in devices
regex='(/dev/sd[a-z]1): LABEL=\"([A-Za-z0-9_\-]+)\".*TYPE=\"([a-zA-Z0-9]+)\"'
while IFS= read -r line; do
    if [[ $line =~ $regex ]];then
        name="${BASH_REMATCH[1]}"
        label="${BASH_REMATCH[2]}"
        type="${BASH_REMATCH[3]}"
        arr_plugged_in_path+=($name)
        arr_plugged_in_label+=($label)
        arr_plugged_in_type+=($type)
    fi
done < <(blkid)


# check directories in /media yet not plugged in devices
for mounted_item in ${arr_media_mounted[*]}
do
    if ! [[ " ${arr_plugged_in_label[*]} " == *" ${mounted_item} "* ]]; then
        log_info "Mounted yet unplugged directory '${mounted_item}' found."
        umount $MOUNT_DIR$mounted_item >> $LOG_FILE 2>&1
        if ! [ "$(ls -A $MOUNT_DIR$mounted_item)" ]; then
            log_info " - Directory now unmounted and empty and will be deleted."
            rm -rf $MOUNT_DIR$mounted_item >> $LOG_FILE 2>&1
        else
            log_err " - Directory not empty. This should not happen after unmount. Please check '${$MOUNT_DIR$mounted_item}'"
        fi
    fi
done
for unmounted_item in ${arr_media_unmounted[*]}
do
        if ! [[ " ${arr_plugged_in_label[*]} " == *" ${unmounted_item} "* ]]; then
                log_info "Unmounted and unplugged directory '${unmounted_item}' found."
        if ! [ "$(ls -A $MOUNT_DIR$unmounted_item)" ]; then
            log_info " - Directory is empty and will be deleted."
            rm -rf $MOUNT_DIR$unmounted_item >> $LOG_FILE 2>&1
        else
            log_warn " - Directory not empty. No further action."
        fi
        fi
done

# check plugged in devices
i=0
for plugged_in_item in ${arr_plugged_in_label[*]}
do
    log_info "Plugged in device '${plugged_in_item}' will be checked."
    if [[ " ${arr_media_mounted[*]} " == *" ${plugged_in_item} "* ]]; then
        log_info " - Mounted device '${plugged_in_item}' found. Great."
    else
        if [[ " ${arr_media_unmounted[*]} " == *" ${plugged_in_item} "* ]]; then
            log_info " - Unmounted yet plugged in device '${plugged_in_item}' found. It will be mounted."
            else
            log_info " - Newly plugged in device '${plugged_in_item}' found. Directory will be created and device will be mounted."
            mkdir $MOUNT_DIR$plugged_in_item >> $LOG_FILE 2>&1
        fi
        mounter $plugged_in_item ${arr_plugged_in_path[i]} ${arr_plugged_in_type[i]}
    fi
    ((i++))
done

Now make the script executable

sudo chmod o+x /root/mount_manager/mount_manager

and reload udev rules with

sudo udevadm control --reload-rules

Done! Enjoy it and maybe leave a comment on solvedforhome.com.

0

I have implemented the solution from SolvedAtHome on a Raspberry Pi running Buster Lite. After debugging my code I have everything working without any errors, at least that's what appears to be the case when viewing the syslog.

The directory is created, but the mount is not. No errors in the log, but there is systemd-udev activity after the mount_manager script exits. I found multiple references that suggest that systemd daemon unmounts the drive after the mount_manager exits.

I have created a script with just the mkdir and the mount, and it works fine. Only when run via mount_manager.sh during the udev add process does the mount silent fail.

Does anyone have any ideas on what could be happening and maybe suggest a work around?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.