From: Ralph Ronnquist Date: Sat, 20 Apr 2024 13:03:09 +0000 (+1000) Subject: Added scripts. X-Git-Tag: v0.1 X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=096f6d6470ba6972db449e0d69c20ab12cc7a9a3;p=rrq%2Fnbd-mount-helper.git Added scripts. --- 096f6d6470ba6972db449e0d69c20ab12cc7a9a3 diff --git a/mount.nbd b/mount.nbd new file mode 100755 index 0000000..df07503 --- /dev/null +++ b/mount.nbd @@ -0,0 +1,67 @@ +#!/bin/sh +# +# Helper script to run an nbd client and mount its device to the given +# mount point. This script is invoked by "mount" with +# $1 = source (here it's an nbd URL like nbd://server/export +# $2 = mount point +# $3 = -o +# $4 = client and mount options separated by comma +# block-size=N => "-b N" +# connections=N => "-C N" +# timeout=N => "-t N" +# +# The script starts a nbd-client service client before mounting, and +# spawns a cleanup daemon that uses inotify to "discover" unmount to +# terminate the service client. + +# Find a free /dev/nbd* +for ADM in /dev/nbd* ; do nbd-client -c $ADM > /dev/null || break ; done + +if [ -z "$ADM" ] ; then + echo "** No available /dev/nbd* device node" >&2 + exit 1 +fi + +if grep -qF " $ADM " /proc/mounts ; then + echo "*** $1 is already mounted" >&2 + exit 1 +fi + +# Split up options between partition and loop options +POPTS="" +LOPTS="" +for X in $(echo $4 | tr , ' ') ; do + case $X in + block-size=*) POPTS="$POPTS -b ${X#*=}" ;; + connections=*) POPTS="$POPTS -C ${X#*=}" ;; + timeout=*) POPTS="$POPTS -t ${X#*=}" ;; + *) LOPTS="$LOPTS,$X" ;; + esac +done + +# Set up the device node service +# $1 = nbd://$host[:$port]/$export +read S P N < /dev/null || exit 1 + +sleep 0.2 +for i in 0 1 2 3 4 5 6 7 8 9 ; do + # Loop-mount the nbdfuse "device" and spawn a cleanup daemon + if mount -o$LOPTS $ADM "$2" 2> /dev/null ; then + # Spawn a process to stop $ADM service when "$2" is umount-ed + ( ( + inotifywait -e delete_self "$2" > /dev/null 2>&1 + nbd-client -d $ADM + ) & ) & + exit 0 + fi + sleep 0.2 +done + +# Coming here if something wrong +nbd-client -d $ADM diff --git a/mount.nbdfuse b/mount.nbdfuse new file mode 100755 index 0000000..3bdb322 --- /dev/null +++ b/mount.nbdfuse @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Helper script to run an nbd client and mount its device to the given +# mount point. This script is invoked by "mount" with +# $1 = source (here it's an nbd URL like nbd://server/export +# $2 = mount point +# $3 = -o +# $4 = mount options +# +# The script starts a nbdfuse service client before mounting, and +# spawns a cleanup daemon that uses inotify to "discover" unmount to +# terminate the service client. + +# Use an /run directory mangled from the source URL as "device node" +ADM="/run/$(echo -n "$1" | tr -c "[[:alnum:]-]" "_")" +if grep -qF " $ADM " /proc/mounts ; then + echo "*** $1 is already mounted" >&2 + exit 1 +fi +mkdir -p $ADM + +# Split up options between partition and loop options +POPTS="" +LOPTS="" +for X in $(echo $4 | tr , ' ') ; do + case $X in + kernel_cache|allow_other) POPTS="$POPTS -o $X" ;; + *) LOPTS="$LOPTS,$X" ;; + esac +done + +# Set up the device node service +modprobe fuse || exit 1 +nohup nbdfuse -C 1 $POPTS $ADM "$1" > /dev/null 2>&1 & + +sleep 0.2 +for i in 1 2 3 4 5 6 7 8 9 ; do + # Loop-mount the nbdfuse "device" and spawn a cleanup daemon + if mount -oloop,$LOPTS $ADM/nbd "$2" 2> /dev/null ; then + # Spawn a process to umount $ADM when "$2" is umount-ed + ( ( + inotifywait -e delete_self "$2" > /dev/null 2>&1 + sleep 0.2 + for i in 1 2 3 4 ; do + umount $ADM 2> /dev/null && exit 0 + sleep 0.2 + done + ) & ) & + exit 0 + fi + sleep 0.2 +done + +# Coming here if something wrong +umount $ADM