]> git.proxmox.com Git - ceph.git/blob - ceph/qa/workunits/rbd/rbd-nbd.sh
f4fe2481186f658e9cb9f8d7aec85cc4b2db6b59
[ceph.git] / ceph / qa / workunits / rbd / rbd-nbd.sh
1 #!/usr/bin/env bash
2 set -ex
3
4 . $(dirname $0)/../../standalone/ceph-helpers.sh
5
6 POOL=rbd
7 NS=ns
8 IMAGE=testrbdnbd$$
9 SIZE=64
10 DATA=
11 DEV=
12
13 _sudo()
14 {
15 local cmd
16
17 if [ `id -u` -eq 0 ]
18 then
19 "$@"
20 return $?
21 fi
22
23 # Look for the command in the user path. If it fails run it as is,
24 # supposing it is in sudo path.
25 cmd=`which $1 2>/dev/null` || cmd=$1
26 shift
27 sudo -nE "${cmd}" "$@"
28 }
29
30 setup()
31 {
32 local ns x
33
34 if [ -e CMakeCache.txt ]; then
35 # running under cmake build dir
36
37 CEPH_SRC=$(readlink -f $(dirname $0)/../../../src)
38 CEPH_ROOT=${PWD}
39 CEPH_BIN=${CEPH_ROOT}/bin
40
41 export LD_LIBRARY_PATH=${CEPH_ROOT}/lib:${LD_LIBRARY_PATH}
42 export PYTHONPATH=${PYTHONPATH}:${CEPH_SRC}/pybind:${CEPH_ROOT}/lib/cython_modules/lib.3
43 PATH=${CEPH_BIN}:${PATH}
44 fi
45
46 _sudo echo test sudo
47
48 trap cleanup INT TERM EXIT
49 TEMPDIR=`mktemp -d`
50 DATA=${TEMPDIR}/data
51 dd if=/dev/urandom of=${DATA} bs=1M count=${SIZE}
52
53 rbd namespace create ${POOL}/${NS}
54
55 for ns in '' ${NS}; do
56 rbd --dest-pool ${POOL} --dest-namespace "${ns}" --no-progress import \
57 ${DATA} ${IMAGE}
58 done
59 }
60
61 function cleanup()
62 {
63 local ns s
64
65 set +e
66 rm -Rf ${TEMPDIR}
67 if [ -n "${DEV}" ]
68 then
69 _sudo rbd-nbd unmap ${DEV}
70 fi
71
72 for ns in '' ${NS}; do
73 if rbd -p ${POOL} --namespace "${ns}" status ${IMAGE} 2>/dev/null; then
74 for s in 0.5 1 2 4 8 16 32; do
75 sleep $s
76 rbd -p ${POOL} --namespace "${ns}" status ${IMAGE} |
77 grep 'Watchers: none' && break
78 done
79 rbd -p ${POOL} --namespace "${ns}" snap purge ${IMAGE}
80 rbd -p ${POOL} --namespace "${ns}" remove ${IMAGE}
81 fi
82 done
83 rbd namespace remove ${POOL}/${NS}
84 }
85
86 function expect_false()
87 {
88 if "$@"; then return 1; else return 0; fi
89 }
90
91 function get_pid()
92 {
93 local ns=$1
94
95 PID=$(rbd-nbd --format xml list-mapped | $XMLSTARLET sel -t -v \
96 "//devices/device[pool='${POOL}'][namespace='${ns}'][image='${IMAGE}'][device='${DEV}']/id")
97 test -n "${PID}"
98 ps -p ${PID} -o cmd | grep rbd-nbd
99 }
100
101 unmap_device()
102 {
103 local unmap_dev=$1
104 local list_dev=${2:-$1}
105 _sudo rbd-nbd unmap ${unmap_dev}
106
107 for s in 0.5 1 2 4 8 16 32; do
108 sleep ${s}
109 rbd-nbd list-mapped | expect_false grep "${list_dev} $" && return 0
110 done
111 return 1
112 }
113
114 #
115 # main
116 #
117
118 setup
119
120 # exit status test
121 expect_false rbd-nbd
122 expect_false rbd-nbd INVALIDCMD
123 if [ `id -u` -ne 0 ]
124 then
125 expect_false rbd-nbd map ${IMAGE}
126 fi
127 expect_false _sudo rbd-nbd map INVALIDIMAGE
128 expect_false _sudo rbd-nbd --device INVALIDDEV map ${IMAGE}
129
130 # list format test
131 expect_false rbd-nbd --format INVALID list-mapped
132 rbd-nbd --format json --pretty-format list-mapped
133 rbd-nbd --format xml list-mapped
134
135 # map test using the first unused device
136 DEV=`_sudo rbd-nbd map ${POOL}/${IMAGE}`
137 get_pid
138 # map test specifying the device
139 expect_false _sudo rbd-nbd --device ${DEV} map ${POOL}/${IMAGE}
140 dev1=${DEV}
141 unmap_device ${DEV}
142 DEV=
143 # XXX: race possible when the device is reused by other process
144 DEV=`_sudo rbd-nbd --device ${dev1} map ${POOL}/${IMAGE}`
145 [ "${DEV}" = "${dev1}" ]
146 rbd-nbd list-mapped | grep "${IMAGE}"
147 get_pid
148
149 # read test
150 [ "`dd if=${DATA} bs=1M | md5sum`" = "`_sudo dd if=${DEV} bs=1M | md5sum`" ]
151
152 # write test
153 dd if=/dev/urandom of=${DATA} bs=1M count=${SIZE}
154 _sudo dd if=${DATA} of=${DEV} bs=1M oflag=direct
155 [ "`dd if=${DATA} bs=1M | md5sum`" = "`rbd -p ${POOL} --no-progress export ${IMAGE} - | md5sum`" ]
156
157 # trim test
158 provisioned=`rbd -p ${POOL} --format xml du ${IMAGE} |
159 $XMLSTARLET sel -t -m "//stats/images/image/provisioned_size" -v .`
160 used=`rbd -p ${POOL} --format xml du ${IMAGE} |
161 $XMLSTARLET sel -t -m "//stats/images/image/used_size" -v .`
162 [ "${used}" -eq "${provisioned}" ]
163 _sudo mkfs.ext4 -E discard ${DEV} # better idea?
164 sync
165 provisioned=`rbd -p ${POOL} --format xml du ${IMAGE} |
166 $XMLSTARLET sel -t -m "//stats/images/image/provisioned_size" -v .`
167 used=`rbd -p ${POOL} --format xml du ${IMAGE} |
168 $XMLSTARLET sel -t -m "//stats/images/image/used_size" -v .`
169 [ "${used}" -lt "${provisioned}" ]
170
171 # resize test
172 devname=$(basename ${DEV})
173 blocks=$(awk -v dev=${devname} '$4 == dev {print $3}' /proc/partitions)
174 test -n "${blocks}"
175 rbd resize ${POOL}/${IMAGE} --size $((SIZE * 2))M
176 rbd info ${POOL}/${IMAGE}
177 blocks2=$(awk -v dev=${devname} '$4 == dev {print $3}' /proc/partitions)
178 test -n "${blocks2}"
179 test ${blocks2} -eq $((blocks * 2))
180 rbd resize ${POOL}/${IMAGE} --allow-shrink --size ${SIZE}M
181 blocks2=$(awk -v dev=${devname} '$4 == dev {print $3}' /proc/partitions)
182 test -n "${blocks2}"
183 test ${blocks2} -eq ${blocks}
184
185 # read-only option test
186 unmap_device ${DEV}
187 DEV=`_sudo rbd-nbd map --read-only ${POOL}/${IMAGE}`
188 PID=$(rbd-nbd list-mapped | awk -v pool=${POOL} -v img=${IMAGE} -v dev=${DEV} \
189 '$2 == pool && $3 == img && $5 == dev {print $1}')
190 test -n "${PID}"
191 ps -p ${PID} -o cmd | grep rbd-nbd
192
193 _sudo dd if=${DEV} of=/dev/null bs=1M
194 expect_false _sudo dd if=${DATA} of=${DEV} bs=1M oflag=direct
195 unmap_device ${DEV}
196
197 # exclusive option test
198 DEV=`_sudo rbd-nbd map --exclusive ${POOL}/${IMAGE}`
199 get_pid
200
201 _sudo dd if=${DATA} of=${DEV} bs=1M oflag=direct
202 expect_false timeout 10 \
203 rbd bench ${IMAGE} --io-type write --io-size=1024 --io-total=1024
204 unmap_device ${DEV}
205 DEV=
206 rbd bench ${IMAGE} --io-type write --io-size=1024 --io-total=1024
207
208 # unmap by image name test
209 DEV=`_sudo rbd-nbd map ${POOL}/${IMAGE}`
210 get_pid
211 unmap_device ${IMAGE} ${DEV}
212 DEV=
213 ps -p ${PID} -o cmd | expect_false grep rbd-nbd
214
215 # map/unmap snap test
216 rbd snap create ${POOL}/${IMAGE}@snap
217 DEV=`_sudo rbd-nbd map ${POOL}/${IMAGE}@snap`
218 get_pid
219 unmap_device "${IMAGE}@snap" ${DEV}
220 DEV=
221 ps -p ${PID} -o cmd | expect_false grep rbd-nbd
222
223 # map/unmap namespace test
224 rbd snap create ${POOL}/${NS}/${IMAGE}@snap
225 DEV=`_sudo rbd-nbd map ${POOL}/${NS}/${IMAGE}@snap`
226 get_pid ${NS}
227 unmap_device "${POOL}/${NS}/${IMAGE}@snap" ${DEV}
228 DEV=
229 ps -p ${PID} -o cmd | expect_false grep rbd-nbd
230
231 # auto unmap test
232 DEV=`_sudo rbd-nbd map ${POOL}/${IMAGE}`
233 get_pid
234 _sudo kill ${PID}
235 for i in `seq 10`; do
236 rbd-nbd list-mapped | expect_false grep "^${PID} *${POOL} *${IMAGE}" && break
237 sleep 1
238 done
239 rbd-nbd list-mapped | expect_false grep "^${PID} *${POOL} *${IMAGE}"
240
241 echo OK