$_ BSDHowTo.ch
How To... Why not..? Scripts RSS logo

How to automate the mounting of removable storage

Last update: 2018-08-14

Introduction

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.

Preparation

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.

The attach script for desktop/laptop

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

The attach script for iSCSI

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")
	c=${#parts[*]}
	i=0
	while [ $i -lt $c ] ; do
		fsck -y /dev/"$DEVNAME"${parts[$i]}
		mount $duid.${parts[$i]}
		i=$((i+1))
	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