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