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