I use iSCSI LUNs to increase the available disk space on one of my apu2 boxes at home. After patching iscsid(8) so it can connect to my Synology I’ve mounted the LUNs manually. For testing this is fine. Soon I have realized that the LUNs are going to be a permanent solution. Therefore, I have created two entries in fstab(5) to let the system mount the LUNs automatically during boot time:

c2a31a30fd0dcb81.a /var/www/nextcloud/data ffs rw,auto,nodev,nosuid,noatime 1 0
105910001d265494.a /var/www/htdocs/pub ffs rw,auto,nodev,nosuid,noatime 1 0

Sometimes, I am naive though. Just setting the option auto for the two volumes will not make OpenBSD mount them. Why not? Because the mounting of the file systems marked auto takes place before the network starts. And iscsid(8) is started by rc(8) after netstart(8), for obvious reasons. I have learned this the hard way by simply rebooting the system. Due to missing disk volumes marked auto rc(8) dropped me to single user mode. Hello ed(1), my good friend 🙄

I have change /etc/fstab to make the system boot again:

c2a31a30fd0dcb81.a /var/www/nextcloud/data ffs rw,noauto,nodev,nosuid,noatime 1 0
105910001d265494.a /var/www/htdocs/pub ffs rw,noauto,nodev,nosuid,noatime 1 0

Of course, OpenBSD has a solution for this chicken-and-egg problem. It is called hotplugd(8). Whenever a device is attached to the system, hotplugd(8) executes the script /etc/hotplug/attach. As soon as iscsid(8) is started, it connects to the target system and attaches the LUNs configured in iscsi.conf(5) to the system. These events are reported through the hotplug(4) device to hotplugd(8).

I have created the following attach script under /etc/hotplug to mount my LUNs as soon as they are attached:

attach

#!/bin/sh

DEVCLASS=$1
DEVNAME=$2
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

case $DEVCLASS in
2)
	duid=$(disklabel $DEVNAME 2>&1 | sed -n '/^duid: /s/^duid: //p')
	label=$(disklabel $DEVNAME 2>&1 | sed -n '/^label: /s/^label: //p')
	case $label in
	iSCSI*)
		sleep 5
		set -A parts $(sed -n "/^$duid/s/ .*//;s/^$duid.//p" /etc/fstab)
		c=${#parts[*]}
		i=0
		while [ $i -lt $c ] ; do
			fsck -y /dev/"$DEVNAME"${parts[$i]}
			mount $duid.${parts[$i]}
			i=$((i+1))
		done
		;;
	esac
esac

I have written the script in a way that it is independent from the number of iSCSI LUNs I attach to the system. First, it only takes action if disks are attached to the system. Then, it reads the DUID and label from the disk and searches /etc/fstab for entries with this DUID and the option noauto. If it finds such entries it executes fsck(8) for each partition and mounts it.

If I want to attach an additional LUN to the system, I just create an entry in /etc/fstab similar to the existing ones and the LUN will get mounted automatically at the next boot.

With the following commands I make the script usable for hotplugd(8):

$ doas cp hotplug.sh /etc/hotplug/attach
$ doas chmod 755 /etc/hotplug/attach