How To... | Why not..? | Scripts | Patches | ![]() |
Last update: 2018-11-03
This post shows you how to automate the mounting of removable storage. This can be a USB stick, a SD card or iSCSI LUNs. OpenBSD has a very handy daemon for this task in the base system: hotplugd(8)
The hotplugd(8) runs the shell script /etc/hotplug/attach
when a
device is attached to the system. And the script /etc/hotplug/detach
when a device is detached from the system.
You need a way to identify the devices you want to mount automatically when you connect them to the system. This can be a string within the label of the disks, e. g. if you always use the same brand of USB sticks. You can get this information from disklabel(8) or dmesg(8).
$ dmesg
umass2 at uhub3 port 2 configuration 1 interface 0 "SanDisk Cruzer" rev 2.00/1.03 addr 14
umass2: using SCSI over Bulk-Only
scsibus6 at umass2: 2 targets, initiator 0
sd3 at scsibus6 targ 1 lun 0: <SanDisk, Cruzer, 1.20> SCSI3 0/direct removable
serial.0781553073167CF0A18D
sd3: 15267MB, 512 bytes/sector, 31266816 sectors
$ disklabel sd3
# /dev/rsd3c:
type: SCSI
disk: SCSI disk
label: SanDisk Cruzer
duid: 0000000000000000
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 255
sectors/cylinder: 16065
cylinders: 1946
total sectors: 31266816
boundstart: 0
boundend: 31266816
drivedata: 0
16 partitions:
# size offset fstype [fsize bsize cpg]
c: 31266816 0 unused
i: 31262720 2048 MSDOS
You can keep the attach script simpler if you put entries in fstab(5) for the disks you want to mount automatically. This allows you to simply call mount(8) with the device name or DUID. You don’t need to specify all the options for mount(8) in the script.
This is a sample script that works with SD cards and USB drives:
#!/bin/ksh
#
# $Header$
DEVCLASS=$1
DEVNAME=$2
[[ $DEVCLASS != 2 ]] && exit 0
case $DEVNAME in
sd1) # SD card reader
disklabel $DEVNAME | grep i:.*MSDOS > /dev/null
[[ $? -eq 0 ]] && mount /dev/"$DEVNAME"i
;;
sd3) # First USB drive plugged in
disklabel $DEVNAME | grep i:.*MSDOS > /dev/null
[[ $? -eq 0 ]] && mount /dev/"$DEVNAME"i
;;
esac
I have two entries in my /etc/fstab
to make the mount(8) commands
simple:
/dev/sd1i /home/user/sd msdos rw,noauto 0 0
/dev/sd3i /home/user/usb msdos rw,noauto 0 0
My home server runs Nextcloud. The data is stored on a iSCSI LUN on my storage server. I use this script to automatically fsck(8) and mount(8) the LUNs during boot time:
#!/bin/ksh
#
# $Header$
[[ $DEVCLASS != 2 ]] && exit 0
label=$(disklabel $DEVNAME 2>&1 | sed -n '/^label: /s/^label: //p')
case $label in
iSCSI*)
duid=$(disklabel $DEVNAME 2>&1 | sed -n '/^duid: /s/^duid: //p')
sleep 5
set -A parts $(cat /etc/fstab | sed -n "/^$duid/s/ .*//;s/^$duid.//p")
for part in ${parts[@]} ; do
fsck -y /dev/"$DEVNAME"$part
mount $duid.$part
done
esac
The following entry in /etc/fstab
keeps the mount command simple:
fedcba9876543210.a /var/www/nextcloud/data ffs rw,noauto,nodev,nosuid,noatime 1 0