Last active
February 4, 2024 00:18
-
-
Save papamoose/826a975b19f10926360c032cd982687c to your computer and use it in GitHub Desktop.
Wait for ThunderBay 6 to be connected via Thunderbolt 3 before attempting to mount zpool.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This exists because I couldn't figure out to to make | |
# any of the relevant system units wait for my zpool to become available | |
# before importing it. | |
# | |
# zpool `tank` is a ThunderBay 6 connected via Thunderbolt 3. | |
# | |
# bolt.service -> ? -> zfs-import-cache | |
# ? is possibly just time as it takes a bit for the drives to spin up. | |
# The nvme pools work fine, for example. | |
# | |
# I hate that this script has to exist. | |
# If you have better ideas let me know. | |
# Good luck... | |
function is_zpool_imported(){ | |
zpool="$1" | |
ec=$(zpool status $zpool >/dev/null 2>&1; echo $?) | |
echo $ec | |
# 0: yes it is imported | |
# anything else you have a problem | |
} | |
function is_zpool_mounted(){ | |
# 0: imported, mounted | |
# 1: NOT imported, NOT mounted | |
# 2: imported, NOT mounted, directory does NOT exist | |
# 3: imported, NOT mounted, directory exists | |
zpool="$1" | |
if [[ $(is_zpool_imported $zpool) -eq 0 ]]; then | |
# check /proc/mount | |
ec=$(grep -qs "^${zpool} " /proc/mounts; echo $?) | |
if [[ $ec -eq 0 ]]; then | |
echo 0 | |
else | |
# imported but NOT mounted | |
# check if directory exists | |
d=$(zfs get mountpoint $zpool -H -o value) | |
if [[ -d $d ]]; then | |
# imported, NOT mounted, directory exists | |
echo 3 | |
else | |
#imported, NOT mounted, directory does NOT exist | |
echo 2 | |
fi | |
fi | |
else | |
# zpool not imported | |
echo 1 | |
fi | |
} | |
function findboltdevice(){ | |
pattern="$1" # user provides a pattern to match | |
ret=1 # default is no match | |
for m in /sys/bus/thunderbolt/devices/*/device_name; do | |
c=$(cat $m) | |
if [[ $c =~ $pattern ]]; then | |
ret=0 # matched | |
fi | |
done | |
echo $ret # 0:matched, 1: not matched | |
} | |
function zpoolavail(){ | |
zpool="$1" | |
ret=1 | |
c=$(zpool import|grep -qs "pool: ${zpool}"; echo $?) | |
if [[ $c -eq 0 ]]; then | |
ret=0 | |
fi | |
echo $ret | |
} | |
function importzpool(){ | |
zpool="$1" | |
while true; do | |
ec=$( zpoolavail $zpool ) | |
if [[ $ec -eq 0 ]]; then | |
echo "Importing $zpool" | |
zpool import $zpool | |
break | |
fi | |
echo "Waiting on zpool to become available" | |
/bin/sleep 5 | |
done | |
} | |
function main(){ | |
zpool="$1" | |
# Start bolt if it's not active already | |
# wait cause it takes time for the external disks to become available. I hate this. | |
# https://www.kernel.org/doc/html/v5.5/admin-guide/thunderbolt.html | |
systemctl is-active --quiet bolt.service || systemd start bolt.service | |
# wait until Thunderbay is recognized | |
# This is NOT a good test because we still need a loop to determine when the pool is available to 'zpool import' | |
while true; do | |
ec=$( findboltdevice 'ThunderBay') | |
if [[ $ec -eq 0 ]]; then | |
break | |
fi | |
echo 'Waiting for ThunderBay to activate...' | |
/bin/sleep 5 | |
done | |
ec=$(is_zpool_mounted $zpool) | |
if [[ $ec -eq 0 ]]; then | |
echo "$zpool already imported and mounted!" | |
elif [[ $ec -eq 1 ]]; then | |
echo "Import then mount $zpool" | |
# there could be problems if the directory already exists | |
# at this point we don't know what the directory it mounts to is | |
importzpool $zpool # this should also automount so the next few lines are probably useless | |
ec=$(is_zpool_mounted $zpool) | |
if [[ $ec -gt 1 ]]; then | |
zfs mount $zpool | |
fi | |
elif [[ $ec -eq 2 ]]; then | |
echo "Mounting $zpool" | |
zfs mount $zpool | |
elif [[ $ec -eq 3 ]]; then | |
echo "Remove directory then mount" | |
d=$(zfs get mountpoint $zpool -H -o value) | |
if [[ -d "$d" ]]; then | |
# I'm not confident in this script to actually remove data directories | |
# Just printing it out here so you know what to do. | |
echo "rm -rI $d" | |
fi | |
zfs mount $zpool | |
fi | |
# before starting docker ensure zpool is mounted | |
ec=$(is_zpool_mounted $zpool) | |
if [[ $ec -eq 0 ]]; then | |
echo "Starting docker" | |
systemctl start docker | |
else | |
echo "Something went wrong mounting $zpool. Not starting docker." | |
fi | |
} | |
main 'tank' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description="Mount zpool 'tank' after bolt.service and start docker" | |
Requires=bolt.service | |
Requires=zfs.target | |
After=bolt.service | |
Before=zfs.target | |
[Service] | |
Type=oneshot | |
#ExecStartPre=/bin/sleep 30 | |
ExecStart=/usr/local/sbin/bolt-zfs-docker-startup | |
[Install] | |
WantedBy=multi-user.target |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment