Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / rbd / krbd_exclusive_option.sh
1 #!/bin/bash
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
129 [ "$(ps -o stat= $PID)" = "D" ]
130 sudo rbd unmap $DEV
131 wait $PID
132 assert_locked $OTHER_DEV
133 sudo rbd unmap $OTHER_DEV
134 assert_unlocked
135
136 DEV=$(sudo rbd map -o exclusive $IMAGE_NAME)
137 assert_locked $DEV
138 sudo rbd map -o noshare,lock_on_read $IMAGE_NAME &
139 SUDO_PID=$!
140 sleep 20
141 assert_locked $DEV
142 PID="$(ps -o pid= --ppid $SUDO_PID)"
143 [ "$(ps -o stat= $PID)" = "Dl" ]
144 sudo rbd unmap $DEV
145 wait $SUDO_PID
146 assert_locked $OTHER_DEV
147 sudo rbd unmap $OTHER_DEV
148 assert_unlocked
149
150 # induce a watch error after 30 seconds
151 DEV=$(sudo rbd map -o exclusive,osdkeepalive=60 $IMAGE_NAME)
152 assert_locked $DEV
153 OLD_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)"
154 sleep 40
155 assert_locked $DEV
156 NEW_WATCHER="$(rados -p rbd listwatchers rbd_header.$IMAGE_ID)"
157 # same client_id, old cookie < new cookie
158 [ "$(echo "$OLD_WATCHER" | cut -d ' ' -f 2)" = \
159     "$(echo "$NEW_WATCHER" | cut -d ' ' -f 2)" ]
160 [[ $(echo "$OLD_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) -lt \
161     $(echo "$NEW_WATCHER" | cut -d ' ' -f 3 | cut -d '=' -f 2) ]]
162 sudo rbd unmap $DEV
163 assert_unlocked
164
165 echo OK