]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | #!/usr/bin/env bash |
7c673cae FG |
2 | |
3 | set -ex | |
4 | ||
5 | function expect_false() { | |
6 | if "$@"; then return 1; else return 0; fi | |
7 | } | |
8 | ||
9 | function assert_locked() { | |
10 | local dev_id="${1#/dev/rbd}" | |
11 | ||
12 | local client_addr | |
13 | client_addr="$(< $SYSFS_DIR/$dev_id/client_addr)" | |
14 | ||
15 | local client_id | |
16 | client_id="$(< $SYSFS_DIR/$dev_id/client_id)" | |
17 | # client4324 -> client.4324 | |
18 | client_id="client.${client_id#client}" | |
19 | ||
20 | local watch_cookie | |
21 | watch_cookie="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID | | |
22 | grep $client_id | cut -d ' ' -f 3 | cut -d '=' -f 2)" | |
23 | [[ $(echo -n "$watch_cookie" | grep -c '^') -eq 1 ]] | |
24 | ||
25 | local actual | |
26 | actual="$(rados -p rbd --format=json lock info rbd_header.$IMAGE_ID rbd_lock | | |
27 | python -m json.tool)" | |
28 | ||
29 | local expected | |
30 | expected="$(cat <<EOF | python -m json.tool | |
31 | { | |
32 | "lockers": [ | |
33 | { | |
34 | "addr": "$client_addr", | |
35 | "cookie": "auto $watch_cookie", | |
36 | "description": "", | |
37 | "expiration": "0.000000", | |
38 | "name": "$client_id" | |
39 | } | |
40 | ], | |
41 | "name": "rbd_lock", | |
42 | "tag": "internal", | |
43 | "type": "exclusive" | |
44 | } | |
45 | EOF | |
46 | )" | |
47 | ||
48 | [ "$actual" = "$expected" ] | |
49 | } | |
50 | ||
51 | function assert_unlocked() { | |
52 | rados -p rbd --format=json lock info rbd_header.$IMAGE_ID rbd_lock | | |
53 | grep '"lockers":\[\]' | |
54 | } | |
55 | ||
56 | SYSFS_DIR="/sys/bus/rbd/devices" | |
57 | IMAGE_NAME="exclusive-option-test" | |
58 | ||
59 | rbd create --size 1 --image-feature '' $IMAGE_NAME | |
60 | ||
61 | IMAGE_ID="$(rbd info --format=json $IMAGE_NAME | | |
62 | python -c "import sys, json; print json.load(sys.stdin)['block_name_prefix'].split('.')[1]")" | |
63 | ||
64 | DEV=$(sudo rbd map $IMAGE_NAME) | |
65 | assert_unlocked | |
66 | sudo rbd unmap $DEV | |
67 | assert_unlocked | |
68 | ||
69 | expect_false sudo rbd map -o exclusive $IMAGE_NAME | |
70 | assert_unlocked | |
71 | ||
72 | rbd feature enable $IMAGE_NAME exclusive-lock | |
73 | rbd snap create $IMAGE_NAME@snap | |
74 | ||
75 | DEV=$(sudo rbd map $IMAGE_NAME) | |
76 | assert_unlocked | |
77 | sudo rbd unmap $DEV | |
78 | assert_unlocked | |
79 | ||
80 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) | |
81 | assert_locked $DEV | |
82 | [[ $(blockdev --getro $DEV) -eq 0 ]] | |
83 | sudo rbd unmap $DEV | |
84 | assert_unlocked | |
85 | ||
86 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME@snap) | |
87 | assert_locked $DEV | |
88 | [[ $(blockdev --getro $DEV) -eq 1 ]] | |
89 | sudo rbd unmap $DEV | |
90 | assert_unlocked | |
91 | ||
92 | DEV=$(sudo rbd map -o exclusive,ro $IMAGE_NAME) | |
93 | assert_locked $DEV | |
94 | [[ $(blockdev --getro $DEV) -eq 1 ]] | |
95 | sudo rbd unmap $DEV | |
96 | assert_unlocked | |
97 | ||
98 | # alternate syntax | |
99 | DEV=$(sudo rbd map --exclusive --read-only $IMAGE_NAME) | |
100 | assert_locked $DEV | |
101 | [[ $(blockdev --getro $DEV) -eq 1 ]] | |
102 | sudo rbd unmap $DEV | |
103 | assert_unlocked | |
104 | ||
105 | DEV=$(sudo rbd map $IMAGE_NAME) | |
106 | assert_unlocked | |
107 | dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
108 | assert_locked $DEV | |
109 | OTHER_DEV=$(sudo rbd map -o noshare,exclusive $IMAGE_NAME) | |
110 | assert_locked $OTHER_DEV | |
111 | sudo rbd unmap $DEV | |
112 | sudo rbd unmap $OTHER_DEV | |
113 | assert_unlocked | |
114 | ||
115 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) | |
116 | assert_locked $DEV | |
117 | expect_false sudo rbd map -o noshare,exclusive $IMAGE_NAME | |
118 | assert_locked $DEV | |
119 | sudo rbd unmap $DEV | |
120 | assert_unlocked | |
121 | ||
122 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) | |
123 | assert_locked $DEV | |
124 | OTHER_DEV=$(sudo rbd map -o noshare $IMAGE_NAME) | |
125 | dd if=/dev/urandom of=$OTHER_DEV bs=4k count=10 oflag=direct & | |
126 | PID=$! | |
127 | sleep 20 | |
128 | assert_locked $DEV | |
11fdf7f2 | 129 | [[ "$(ps -o stat= $PID)" =~ ^D ]] |
7c673cae FG |
130 | sudo rbd unmap $DEV |
131 | wait $PID | |
132 | assert_locked $OTHER_DEV | |
133 | sudo rbd unmap $OTHER_DEV | |
134 | assert_unlocked | |
135 | ||
11fdf7f2 TL |
136 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) |
137 | assert_locked $DEV | |
138 | OTHER_DEV=$(sudo rbd map -o noshare,lock_timeout=60 $IMAGE_NAME) | |
139 | dd if=/dev/urandom of=$OTHER_DEV bs=4k count=10 oflag=direct & | |
140 | PID=$! | |
141 | sleep 20 | |
142 | assert_locked $DEV | |
143 | [[ "$(ps -o stat= $PID)" =~ ^D ]] | |
144 | expect_false wait $PID | |
145 | assert_locked $DEV | |
146 | sudo rbd unmap $DEV | |
147 | sudo rbd unmap $OTHER_DEV | |
148 | assert_unlocked | |
149 | ||
7c673cae FG |
150 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) |
151 | assert_locked $DEV | |
152 | sudo rbd map -o noshare,lock_on_read $IMAGE_NAME & | |
153 | SUDO_PID=$! | |
154 | sleep 20 | |
155 | assert_locked $DEV | |
156 | PID="$(ps -o pid= --ppid $SUDO_PID)" | |
11fdf7f2 | 157 | [[ "$(ps -o stat= $PID)" =~ ^D ]] |
7c673cae FG |
158 | sudo rbd unmap $DEV |
159 | wait $SUDO_PID | |
160 | assert_locked $OTHER_DEV | |
161 | sudo rbd unmap $OTHER_DEV | |
162 | assert_unlocked | |
163 | ||
164 | # induce a watch error after 30 seconds | |
165 | DEV=$(sudo rbd map -o exclusive,osdkeepalive=60 $IMAGE_NAME) | |
166 | assert_locked $DEV | |
167 | OLD_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)" | |
168 | sleep 40 | |
169 | assert_locked $DEV | |
170 | NEW_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)" | |
171 | # same client_id, old cookie < new cookie | |
172 | [ "$(echo "$OLD_WATCHER" | cut -d ' ' -f 2)" = \ | |
173 | "$(echo "$NEW_WATCHER" | cut -d ' ' -f 2)" ] | |
174 | [[ $(echo "$OLD_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) -lt \ | |
175 | $(echo "$NEW_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) ]] | |
176 | sudo rbd unmap $DEV | |
177 | assert_unlocked | |
178 | ||
179 | echo OK |