I recently ran into an issue installing FreeBSD on a system that already had some disks & zpools. Because the disks were partitioned previously, automatic multipath was not an option as the last sector of all hard drives isn’t available to store an ID. The remaining option is to do manual multipath, and it needs to be done every time the system boots.
Here’s an rc script that will run early in the sequence and create a multipath “link” between drives based on their serial number.
/etc/rc.d/manual_multipath
#!/bin/sh
# PROVIDES: manual_multipath
# REQUIRE: sysctl
# BEFORE: hostid
. /etc/rc.subr
name="manual_multipath"
start_cmd="${name}_start"
stop_cmd=":"
manual_multipath_start()
{
echo "> manual_multipath script started"
echo "> linking drives with the same serial number with gmultipath"
counter=0
serials=""
devices=`/usr/bin/find /dev -maxdepth 1 -regex '.*da[0-9]*' | /usr/bin/cut -d '/' -f 3`
for device in $devices
do
echo $device
serial=`camcontrol inquiry $device -S`
substring=`echo "$serials" | /usr/bin/sed -n "s/|$serial|.*//p" | /usr/bin/wc -c`
if [ $substring -eq 0 ]
then
found_multi=0
arg1="$device"
arg2="$device"
for newdevice in $devices
do
newserial=`camcontrol inquiry $newdevice -S`
if [ "$device" != "$newdevice" -a "$serial" == "$newserial" ]
then
echo " same as $newdevice!"
counter=`expr $counter + 1`
found_multi=1
arg1=$arg1"$newdevice"
arg2=$arg2" $newdevice"
fi
done
if [ $found_multi -eq 1 ]
then
gmultipath create $arg1 $arg2
fi
fi
serials=$serials"|$serial|"
done
echo "> manual_multipath script finished, found $counter matches"
}
load_rc_config $name
run_rc_command "$1"
Don’t forget to “chmod 555 /etc/rc.d/manual_multipath”.
Lastly, when importing a zpool from the drives you just multipathed, make sure to specify where to look for devices or you might end up importing a mix of multipath and regular devices. Make sure to “zpool import -d /dev/multipath”.
I’m delving pretty deep into FreeBSD, time to grow an epic beard.