#!/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