--- /dev/null
+#!/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 <<EOF
+$(echo "${1#nbd://}" | sed 's|/| |;s|[ :]| |')
+EOF
+[ -z "$N" ] && N=$P && P=
+[ -z "$P" ] || P="-port $P"
+POPTS="-persist $POPTS"
+nbd-client $S $P -name $N $POPTS > /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
--- /dev/null
+#!/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