aboutsummaryrefslogtreecommitdiff
path: root/tests/acceptance/virtiofs_submounts.py.data/guest.sh
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."