editorial improvements
[rrq/nbd-mount-helper.git] / mount.nbdfuse
1 #!/bin/sh
2 #
3 # Helper script to run an nbd client and mount its device to the given
4 # mount point. This script is invoked by "mount" with
5 # $1 = source (here it's an nbd URL like nbd://server/export
6 # $2 = mount point
7 # $3 = -o
8 # $4 = mount options
9 #
10 # The script starts a nbdfuse service client before mounting, and
11 # spawns a cleanup daemon that uses inotify to "discover" unmount to
12 # terminate the service client.
13
14 # Use an /run directory mangled from the source URL as "device node"
15 ADM="/run/$(echo -n "$1" | tr -c "[[:alnum:]-]" "_")"
16 if grep -qF " $ADM "  /proc/mounts ; then
17     echo "*** $1 is already mounted" >&2
18     exit 1
19 fi
20 mkdir -p $ADM
21
22 # Split up options between partition and loop options
23 POPTS=""
24 LOPTS=""
25 for X in $(echo $4 | tr , ' ') ; do
26     case $X in
27         kernel_cache|allow_other) POPTS="$POPTS -o $X" ;;
28         *) LOPTS="$LOPTS,$X" ;;
29     esac
30 done
31
32 # Set up the device node service
33 modprobe fuse || exit 1
34 nohup nbdfuse -C 1 $POPTS $ADM "$1" > /dev/null 2>&1 &
35
36 sleep 0.2
37 for i in 1 2 3 4 5 6 7 8 9 ; do
38     # Loop-mount the nbdfuse "device" and spawn a cleanup daemon
39     if mount -oloop,$LOPTS $ADM/nbd "$2" 2> /dev/null ; then
40         # Spawn a process to umount $ADM when "$2" is umount-ed
41         ( (
42             inotifywait -e delete_self "$2" > /dev/null 2>&1
43             sleep 0.2
44             for i in 1 2 3 4 ; do
45                 umount $ADM 2> /dev/null && exit 0
46                 sleep 0.2
47             done
48         ) & ) &
49         exit 0
50     fi
51     sleep 0.2
52 done
53
54 # Coming here if something wrong
55 umount $ADM