5 function expect_false
() {
6 if "$@"; then return 1; else return 0; fi
9 function assert_locked
() {
10 local dev_id
="${1#/dev/rbd}"
13 client_addr
="$(< $SYSFS_DIR/$dev_id/client_addr)"
16 client_id
="$(< $SYSFS_DIR/$dev_id/client_id)"
17 # client4324 -> client.4324
18 client_id
="client.${client_id#client}"
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 ]]
26 actual
="$(rados -p rbd --format=json lock info rbd_header.$IMAGE_ID rbd_lock |
30 expected
="$(cat <<EOF | python -m json.tool
34 "addr
": "$client_addr",
35 "cookie
": "auto
$watch_cookie",
37 "expiration
": "0.000000",
48 [ "$actual" = "$expected" ]
51 function assert_unlocked
() {
52 rados
-p rbd
--format=json lock info rbd_header.
$IMAGE_ID rbd_lock |
56 function blacklist_add
() {
57 local dev_id
="${1#/dev/rbd}"
60 client_addr
="$(< $SYSFS_DIR/$dev_id/client_addr)"
62 ceph osd blacklist add
$client_addr
65 SYSFS_DIR
="/sys/bus/rbd/devices"
66 IMAGE_NAME
="exclusive-option-test"
68 rbd create
--size 1 --image-feature '' $IMAGE_NAME
70 IMAGE_ID
="$(rbd info --format=json $IMAGE_NAME |
71 python -c "import sys
, json
; print json.load
(sys.stdin
)['block_name_prefix'].
split('.')[1]")"
73 DEV
=$
(sudo rbd map
$IMAGE_NAME)
78 expect_false sudo rbd map
-o exclusive
$IMAGE_NAME
81 expect_false sudo rbd map
-o lock_on_read
$IMAGE_NAME
84 rbd feature
enable $IMAGE_NAME exclusive-lock
85 rbd snap create
$IMAGE_NAME@snap
87 DEV
=$
(sudo rbd map
$IMAGE_NAME)
89 [[ $
(blockdev
--getro $DEV) -eq 0 ]]
93 DEV
=$
(sudo rbd map
$IMAGE_NAME@snap
)
95 [[ $
(blockdev
--getro $DEV) -eq 1 ]]
99 DEV
=$
(sudo rbd map
-o ro
$IMAGE_NAME)
101 [[ $
(blockdev
--getro $DEV) -eq 1 ]]
105 DEV
=$
(sudo rbd map
-o exclusive
$IMAGE_NAME)
107 [[ $
(blockdev
--getro $DEV) -eq 0 ]]
111 DEV
=$
(sudo rbd map
-o exclusive
$IMAGE_NAME@snap
)
113 [[ $
(blockdev
--getro $DEV) -eq 1 ]]
117 DEV
=$
(sudo rbd map
-o exclusive
,ro
$IMAGE_NAME)
119 [[ $
(blockdev
--getro $DEV) -eq 1 ]]
124 DEV
=$
(sudo rbd map
--exclusive --read-only $IMAGE_NAME)
126 [[ $
(blockdev
--getro $DEV) -eq 1 ]]
130 DEV
=$
(sudo rbd map
$IMAGE_NAME)
132 OTHER_DEV
=$
(sudo rbd map
-o noshare
$IMAGE_NAME)
133 assert_locked
$OTHER_DEV
134 dd if=/dev
/urandom of
=$DEV bs
=4k count
=10 oflag
=direct
136 dd if=/dev
/urandom of
=$OTHER_DEV bs
=4k count
=10 oflag
=direct
137 assert_locked
$OTHER_DEV
139 sudo rbd unmap
$OTHER_DEV
142 DEV
=$
(sudo rbd map
$IMAGE_NAME)
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
151 dd if=$DEV of
=/dev
/null bs
=4k count
=10 iflag
=direct
153 dd if=/dev
/urandom of
=$DEV bs
=4k count
=10 oflag
=direct
158 DEV
=$
(sudo rbd map
-o lock_on_read
$IMAGE_NAME)
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
165 assert_locked
$OTHER_DEV
166 sudo rbd unmap
$OTHER_DEV
168 dd if=$DEV of
=/dev
/null bs
=4k count
=10 iflag
=direct
170 dd if=/dev
/urandom of
=$DEV bs
=4k count
=10 oflag
=direct
175 DEV
=$
(sudo rbd map
-o exclusive
$IMAGE_NAME)
177 expect_false sudo rbd map
-o noshare
$IMAGE_NAME
182 DEV
=$
(sudo rbd map
-o exclusive
$IMAGE_NAME)
184 expect_false sudo rbd map
-o noshare
,exclusive
$IMAGE_NAME
189 DEV
=$
(sudo rbd map
$IMAGE_NAME)
191 rbd resize
--size 1G
$IMAGE_NAME
196 DEV
=$
(sudo rbd map
-o exclusive
$IMAGE_NAME)
198 expect_false rbd resize
--size 2G
$IMAGE_NAME
203 DEV
=$
(sudo rbd map
$IMAGE_NAME)
205 dd if=/dev
/urandom of
=$DEV bs
=4k count
=10 oflag
=direct
206 { sleep 10; blacklist_add
$DEV; } &
208 expect_false
dd if=/dev
/urandom of
=$DEV bs
=4k count
=200000 oflag
=direct
211 OTHER_DEV
=$
(sudo rbd map
-o noshare
$IMAGE_NAME)
212 assert_locked
$OTHER_DEV
214 assert_locked
$OTHER_DEV
215 sudo rbd unmap
$OTHER_DEV
218 # induce a watch error after 30 seconds
219 DEV
=$
(sudo rbd map
-o exclusive
,osdkeepalive
=60 $IMAGE_NAME)
221 OLD_WATCHER
="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)"
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) ]]