]>
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 | | |
9f95a23c | 27 | python3 -m json.tool --sort-keys)" |
7c673cae FG |
28 | |
29 | local expected | |
9f95a23c | 30 | expected="$(cat <<EOF | python3 -m json.tool --sort-keys |
7c673cae FG |
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 | ||
f67539c2 | 56 | function blocklist_add() { |
92f5a8d4 TL |
57 | local dev_id="${1#/dev/rbd}" |
58 | ||
59 | local client_addr | |
60 | client_addr="$(< $SYSFS_DIR/$dev_id/client_addr)" | |
61 | ||
f67539c2 | 62 | ceph osd blocklist add $client_addr |
92f5a8d4 TL |
63 | } |
64 | ||
7c673cae FG |
65 | SYSFS_DIR="/sys/bus/rbd/devices" |
66 | IMAGE_NAME="exclusive-option-test" | |
67 | ||
68 | rbd create --size 1 --image-feature '' $IMAGE_NAME | |
69 | ||
70 | IMAGE_ID="$(rbd info --format=json $IMAGE_NAME | | |
9f95a23c | 71 | python3 -c "import sys, json; print(json.load(sys.stdin)['block_name_prefix'].split('.')[1])")" |
7c673cae FG |
72 | |
73 | DEV=$(sudo rbd map $IMAGE_NAME) | |
74 | assert_unlocked | |
75 | sudo rbd unmap $DEV | |
76 | assert_unlocked | |
77 | ||
78 | expect_false sudo rbd map -o exclusive $IMAGE_NAME | |
79 | assert_unlocked | |
80 | ||
92f5a8d4 TL |
81 | expect_false sudo rbd map -o lock_on_read $IMAGE_NAME |
82 | assert_unlocked | |
83 | ||
7c673cae FG |
84 | rbd feature enable $IMAGE_NAME exclusive-lock |
85 | rbd snap create $IMAGE_NAME@snap | |
86 | ||
87 | DEV=$(sudo rbd map $IMAGE_NAME) | |
92f5a8d4 TL |
88 | assert_locked $DEV |
89 | [[ $(blockdev --getro $DEV) -eq 0 ]] | |
90 | sudo rbd unmap $DEV | |
91 | assert_unlocked | |
92 | ||
93 | DEV=$(sudo rbd map $IMAGE_NAME@snap) | |
94 | assert_unlocked | |
95 | [[ $(blockdev --getro $DEV) -eq 1 ]] | |
96 | sudo rbd unmap $DEV | |
97 | assert_unlocked | |
98 | ||
99 | DEV=$(sudo rbd map -o ro $IMAGE_NAME) | |
7c673cae | 100 | assert_unlocked |
92f5a8d4 | 101 | [[ $(blockdev --getro $DEV) -eq 1 ]] |
7c673cae FG |
102 | sudo rbd unmap $DEV |
103 | assert_unlocked | |
104 | ||
105 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) | |
106 | assert_locked $DEV | |
107 | [[ $(blockdev --getro $DEV) -eq 0 ]] | |
108 | sudo rbd unmap $DEV | |
109 | assert_unlocked | |
110 | ||
111 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME@snap) | |
92f5a8d4 | 112 | assert_unlocked |
7c673cae FG |
113 | [[ $(blockdev --getro $DEV) -eq 1 ]] |
114 | sudo rbd unmap $DEV | |
115 | assert_unlocked | |
116 | ||
117 | DEV=$(sudo rbd map -o exclusive,ro $IMAGE_NAME) | |
92f5a8d4 | 118 | assert_unlocked |
7c673cae FG |
119 | [[ $(blockdev --getro $DEV) -eq 1 ]] |
120 | sudo rbd unmap $DEV | |
121 | assert_unlocked | |
122 | ||
123 | # alternate syntax | |
124 | DEV=$(sudo rbd map --exclusive --read-only $IMAGE_NAME) | |
92f5a8d4 | 125 | assert_unlocked |
7c673cae FG |
126 | [[ $(blockdev --getro $DEV) -eq 1 ]] |
127 | sudo rbd unmap $DEV | |
128 | assert_unlocked | |
129 | ||
130 | DEV=$(sudo rbd map $IMAGE_NAME) | |
92f5a8d4 TL |
131 | assert_locked $DEV |
132 | OTHER_DEV=$(sudo rbd map -o noshare $IMAGE_NAME) | |
133 | assert_locked $OTHER_DEV | |
7c673cae FG |
134 | dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct |
135 | assert_locked $DEV | |
92f5a8d4 | 136 | dd if=/dev/urandom of=$OTHER_DEV bs=4k count=10 oflag=direct |
7c673cae FG |
137 | assert_locked $OTHER_DEV |
138 | sudo rbd unmap $DEV | |
139 | sudo rbd unmap $OTHER_DEV | |
140 | assert_unlocked | |
141 | ||
92f5a8d4 | 142 | DEV=$(sudo rbd map $IMAGE_NAME) |
7c673cae | 143 | assert_locked $DEV |
92f5a8d4 TL |
144 | OTHER_DEV=$(sudo rbd map -o noshare,exclusive $IMAGE_NAME) |
145 | assert_locked $OTHER_DEV | |
146 | dd if=$DEV of=/dev/null bs=4k count=10 iflag=direct | |
147 | expect_false dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
148 | assert_locked $OTHER_DEV | |
149 | sudo rbd unmap $OTHER_DEV | |
150 | assert_unlocked | |
151 | dd if=$DEV of=/dev/null bs=4k count=10 iflag=direct | |
152 | assert_unlocked | |
153 | dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
154 | assert_locked $DEV | |
155 | sudo rbd unmap $DEV | |
156 | assert_unlocked | |
157 | ||
158 | DEV=$(sudo rbd map -o lock_on_read $IMAGE_NAME) | |
159 | assert_locked $DEV | |
160 | OTHER_DEV=$(sudo rbd map -o noshare,exclusive $IMAGE_NAME) | |
161 | assert_locked $OTHER_DEV | |
162 | expect_false dd if=$DEV of=/dev/null bs=4k count=10 iflag=direct | |
163 | expect_false dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
164 | sudo udevadm settle | |
165 | assert_locked $OTHER_DEV | |
166 | sudo rbd unmap $OTHER_DEV | |
167 | assert_unlocked | |
168 | dd if=$DEV of=/dev/null bs=4k count=10 iflag=direct | |
169 | assert_locked $DEV | |
170 | dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
7c673cae FG |
171 | assert_locked $DEV |
172 | sudo rbd unmap $DEV | |
173 | assert_unlocked | |
174 | ||
175 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) | |
176 | assert_locked $DEV | |
92f5a8d4 | 177 | expect_false sudo rbd map -o noshare $IMAGE_NAME |
7c673cae | 178 | assert_locked $DEV |
7c673cae | 179 | sudo rbd unmap $DEV |
7c673cae FG |
180 | assert_unlocked |
181 | ||
11fdf7f2 TL |
182 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) |
183 | assert_locked $DEV | |
92f5a8d4 | 184 | expect_false sudo rbd map -o noshare,exclusive $IMAGE_NAME |
11fdf7f2 | 185 | assert_locked $DEV |
92f5a8d4 TL |
186 | sudo rbd unmap $DEV |
187 | assert_unlocked | |
188 | ||
189 | DEV=$(sudo rbd map $IMAGE_NAME) | |
11fdf7f2 | 190 | assert_locked $DEV |
92f5a8d4 TL |
191 | rbd resize --size 1G $IMAGE_NAME |
192 | assert_unlocked | |
11fdf7f2 | 193 | sudo rbd unmap $DEV |
11fdf7f2 TL |
194 | assert_unlocked |
195 | ||
7c673cae FG |
196 | DEV=$(sudo rbd map -o exclusive $IMAGE_NAME) |
197 | assert_locked $DEV | |
92f5a8d4 | 198 | expect_false rbd resize --size 2G $IMAGE_NAME |
7c673cae | 199 | assert_locked $DEV |
7c673cae | 200 | sudo rbd unmap $DEV |
92f5a8d4 TL |
201 | assert_unlocked |
202 | ||
203 | DEV=$(sudo rbd map $IMAGE_NAME) | |
204 | assert_locked $DEV | |
205 | dd if=/dev/urandom of=$DEV bs=4k count=10 oflag=direct | |
f67539c2 | 206 | { sleep 10; blocklist_add $DEV; } & |
92f5a8d4 TL |
207 | PID=$! |
208 | expect_false dd if=/dev/urandom of=$DEV bs=4k count=200000 oflag=direct | |
209 | wait $PID | |
210 | # break lock | |
211 | OTHER_DEV=$(sudo rbd map -o noshare $IMAGE_NAME) | |
212 | assert_locked $OTHER_DEV | |
213 | sudo rbd unmap $DEV | |
7c673cae FG |
214 | assert_locked $OTHER_DEV |
215 | sudo rbd unmap $OTHER_DEV | |
216 | assert_unlocked | |
217 | ||
218 | # induce a watch error after 30 seconds | |
219 | DEV=$(sudo rbd map -o exclusive,osdkeepalive=60 $IMAGE_NAME) | |
220 | assert_locked $DEV | |
221 | OLD_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)" | |
222 | sleep 40 | |
223 | assert_locked $DEV | |
224 | NEW_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)" | |
225 | # same client_id, old cookie < new cookie | |
226 | [ "$(echo "$OLD_WATCHER" | cut -d ' ' -f 2)" = \ | |
227 | "$(echo "$NEW_WATCHER" | cut -d ' ' -f 2)" ] | |
228 | [[ $(echo "$OLD_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) -lt \ | |
229 | $(echo "$NEW_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) ]] | |
230 | sudo rbd unmap $DEV | |
231 | assert_unlocked | |
232 | ||
233 | echo OK |