]> git.proxmox.com Git - mirror_qemu.git/blob - tests/acceptance/virtiofs_submounts.py.data/guest.sh
tests/acceptance: Add virtiofs_submounts.py
[mirror_qemu.git] / tests / acceptance / virtiofs_submounts.py.data / guest.sh
1 #!/bin/bash
2
3 function 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
14 shared_dir=$1
15 if [ -z "$shared_dir" ]; then
16 print_usage "$0" 'Shared dir not given' >&2
17 exit 1
18 fi
19
20 cd "$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
36 mnt_i=0
37
38 function 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
54 recursively_visit .
55 echo
56
57
58 if [ -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
62 fi
63
64 if [ ! -f some-file -o "$(cat some-file)" != 'root' ]; then
65 echo "Error: Bad file in the share root" >&2
66 exit 1
67 fi
68
69 shopt -s nullglob
70
71 function 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
127 root_dev=$(stat -c '%D' some-file)
128 devs=()
129 check_submounts ''
130 echo
131
132 reused_devs=$(echo "$root_dev ${devs[@]}" | tr ' ' '\n' | sort | uniq -d)
133 if [ -n "$reused_devs" ]; then
134 echo "Error: Reused device IDs: $reused_devs" >&2
135 exit 1
136 fi
137
138 echo "Test passed for ${#devs[@]} submounts."