guest.sh (3739B)
1#!/bin/bash 2 3function print_usage() 4{ 5 if [ -n "$2" ]; then 6 echo "Error: $2" 7 echo 8 fi 9 echo "Usage: $1 <shared dir>" 10 echo '(The shared directory is the "share" directory in the scratch' \ 11 'directory)' 12} 13 14shared_dir=$1 15if [ -z "$shared_dir" ]; then 16 print_usage "$0" 'Shared dir not given' >&2 17 exit 1 18fi 19 20cd "$shared_dir" 21 22# FIXME: This should not be necessary, but it is. In order for all 23# submounts to be proper mount points, we need to visit them. 24# (Before we visit them, they will not be auto-mounted, and so just 25# appear as normal directories, with the catch that their st_ino will 26# be the st_ino of the filesystem they host, while the st_dev will 27# still be the st_dev of the parent.) 28# `find` does not work, because it will refuse to touch the mount 29# points as long as they are not mounted; their st_dev being shared 30# with the parent and st_ino just being the root node's inode ID 31# will practically ensure that this node exists elsewhere on the 32# filesystem, and `find` is required to recognize loops and not to 33# follow them. 34# Thus, we have to manually visit all nodes first. 35 36mnt_i=0 37 38function recursively_visit() 39{ 40 pushd "$1" >/dev/null 41 for entry in *; do 42 if [[ "$entry" == mnt* ]]; then 43 mnt_i=$((mnt_i + 1)) 44 printf "Triggering auto-mount $mnt_i...\r" 45 fi 46 47 if [ -d "$entry" ]; then 48 recursively_visit "$entry" 49 fi 50 done 51 popd >/dev/null 52} 53 54recursively_visit . 55echo 56 57 58if [ -n "$(find -name not-mounted)" ]; then 59 echo "Error: not-mounted files visible on mount points:" >&2 60 find -name not-mounted >&2 61 exit 1 62fi 63 64if [ ! -f some-file -o "$(cat some-file)" != 'root' ]; then 65 echo "Error: Bad file in the share root" >&2 66 exit 1 67fi 68 69shopt -s nullglob 70 71function check_submounts() 72{ 73 local base_path=$1 74 75 for mp in mnt*; do 76 printf "Checking submount %i...\r" "$((${#devs[@]} + 1))" 77 78 mp_i=$(echo "$mp" | sed -e 's/mnt//') 79 dev=$(stat -c '%D' "$mp") 80 81 if [ -n "${devs[mp_i]}" ]; then 82 echo "Error: $mp encountered twice" >&2 83 exit 1 84 fi 85 devs[mp_i]=$dev 86 87 pushd "$mp" >/dev/null 88 path="$base_path$mp" 89 while true; do 90 expected_content="$(printf '%s\n%s\n' "$mp_i" "$path")" 91 if [ ! -f some-file ]; then 92 echo "Error: $PWD/some-file does not exist" >&2 93 exit 1 94 fi 95 96 if [ "$(cat some-file)" != "$expected_content" ]; then 97 echo "Error: Bad content in $PWD/some-file:" >&2 98 echo '--- found ---' 99 cat some-file 100 echo '--- expected ---' 101 echo "$expected_content" 102 exit 1 103 fi 104 if [ "$(stat -c '%D' some-file)" != "$dev" ]; then 105 echo "Error: $PWD/some-file has the wrong device ID" >&2 106 exit 1 107 fi 108 109 if [ -d sub ]; then 110 if [ "$(stat -c '%D' sub)" != "$dev" ]; then 111 echo "Error: $PWD/some-file has the wrong device ID" >&2 112 exit 1 113 fi 114 cd sub 115 path="$path/sub" 116 else 117 if [ -n "$(echo mnt*)" ]; then 118 check_submounts "$path/" 119 fi 120 break 121 fi 122 done 123 popd >/dev/null 124 done 125} 126 127root_dev=$(stat -c '%D' some-file) 128devs=() 129check_submounts '' 130echo 131 132reused_devs=$(echo "$root_dev ${devs[@]}" | tr ' ' '\n' | sort | uniq -d) 133if [ -n "$reused_devs" ]; then 134 echo "Error: Reused device IDs: $reused_devs" >&2 135 exit 1 136fi 137 138echo "Test passed for ${#devs[@]} submounts."