I am attempting to automatically mount all ATA/SCSI drives on boot using systemd
and udev
without utilizing /etc/fstab
.
This is necessary because filesystems need to be mounted on directories named for their UUIDs, and the drives are always being cold swapped for new drives, so constantly modifying fstab
becomes tedious.
In order to do this, I used the following script, systemd unit file, and udev rule adapted from an answer to a similar question for USB drives.
However, while that answer works for USB drives, it does not work for ATA/SCSI drives: The script appears to execute successfully and create all necessary directories, but when boot up is complete, nothing is mounted. The script does work when run manually, however.
/usr/local/bin/automount.sh:
#!/bin/bash
ACTION=$1
DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
SAVE="/root/${DEVBASE}"
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')
do_mount()
{
if [[ -n ${MOUNT_POINT} ]]
then
echo "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
exit 1
fi
# Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
eval $(/sbin/blkid -o udev ${DEVICE})
# Check if drive is already mounted / duplicate UUID
LABEL=${ID_FS_UUID}
/bin/grep -q " /media/${LABEL} " /etc/mtab \
&& ( echo "UUID ${LABEL} already in use"'!'; exit 1 )
# Set mount point and save for later (in case of "yanked" unmount)
MOUNT_POINT="/media/${LABEL}"
echo "MOUNT_POINT=${MOUNT_POINT}" | /usr/bin/tee "${SAVE}"
# Create mount point
/bin/mkdir -p ${MOUNT_POINT}
# Global mount options
OPTS="rw,relatime"
# File system type specific mount options
case "${ID_FS_TYPE}" in
vfat)
OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
;;
esac
if ! /bin/mount -o ${OPTS} ${DEVICE} ${MOUNT_POINT}
then
echo "Error mounting ${DEVICE} (status = $?)"
/bin/rmdir ${MOUNT_POINT}
/bin/rm ${SAVE}
exit 1
fi
echo "**** Mounted ${DEVICE} at ${MOUNT_POINT} ****"
}
do_unmount()
{
eval $(/bin/cat "${SAVE}")
[[ -z ${MOUNT_POINT} ]] \
&& ( echo "Warning: ${DEVICE} is not mounted"; exit 0)
/bin/umount -l ${DEVICE} \
&& ( echo "**** Unmounted ${DEVICE}"; /bin/rm ${SAVE} ) \
|| ( echo "Unmounting ${DEVICE} failed"'!'; exit 1 )
}
case "${ACTION}" in
add)
do_mount
;;
remove)
do_unmount
;;
*)
echo "BAD OPTION ${ACTION}"'!'
exit 1
;;
esac
/etc/systemd/system/automount@.service:
[Unit]
Description=Automount ATA/SCSI drive on %i
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/bin/automount.sh add %i
ExecStop=/usr/local/bin/automount.sh remove %i
/etc/udev/rules.d/11-automount-ata-scsi.rules:
KERNEL!="sd[a-z][0-9]", SUBSYSTEMS!="scsi", GOTO="automount_ata_scsi_end"
ACTION=="add", RUN+="/bin/systemctl start automount@%k.service"
ACTION=="remove", RUN+="/bin/systemctl stop automount@%k.service"
LABEL="automount_ata_scsi_end"
(From the looks of it, ATA/SCSI drives actually do mount briefly with this setup, but then somehow unmount down the boot process.)