Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / rbd / import_export.sh
1 #!/bin/sh -ex
2
3 # returns data pool for a given image
4 get_image_data_pool () {
5     image=$1
6     data_pool=$(rbd info $image | grep "data_pool: " | awk -F':' '{ print $NF }')
7     if [ -z $data_pool ]; then
8        data_pool='rbd'
9     fi
10
11     echo $data_pool
12 }
13
14 # return list of object numbers populated in image
15 objects () {
16    image=$1
17    prefix=$(rbd info $image | grep block_name_prefix | awk '{print $NF;}')
18
19    # strip off prefix and leading zeros from objects; sort, although
20    # it doesn't necessarily make sense as they're hex, at least it makes
21    # the list repeatable and comparable
22    objects=$(rados ls -p $(get_image_data_pool $image) | grep $prefix | \
23        sed -e 's/'$prefix'\.//' -e 's/^0*\([0-9a-f]\)/\1/' | sort -u)
24    echo $objects
25 }
26
27 # return false if either files don't compare or their ondisk
28 # sizes don't compare
29
30 compare_files_and_ondisk_sizes () {
31     cmp -l $1 $2 || return 1
32     origsize=$(stat $1 --format %b)
33     exportsize=$(stat $2 --format %b)
34     difference=$(($exportsize - $origsize))
35     difference=${difference#-} # absolute value
36     test $difference -ge 0 -a $difference -lt 4096
37 }
38
39 TMPDIR=/tmp/rbd_import_export_$$
40 rm -rf $TMPDIR
41 mkdir $TMPDIR
42 trap "rm -rf $TMPDIR" INT TERM EXIT
43
44 # cannot import a dir
45 mkdir foo.$$
46 rbd import foo.$$ foo.dir && exit 1 || true   # should fail
47 rmdir foo.$$
48
49 # create a sparse file
50 dd if=/bin/sh of=${TMPDIR}/img bs=1k count=1 seek=10
51 dd if=/bin/dd of=${TMPDIR}/img bs=1k count=10 seek=100
52 dd if=/bin/rm of=${TMPDIR}/img bs=1k count=100 seek=1000
53 dd if=/bin/ls of=${TMPDIR}/img bs=1k seek=10000
54 dd if=/bin/ln of=${TMPDIR}/img bs=1k seek=100000
55 dd if=/bin/grep of=${TMPDIR}/img bs=1k seek=1000000
56
57 rbd rm testimg || true
58
59 rbd import $RBD_CREATE_ARGS ${TMPDIR}/img testimg
60 rbd export testimg ${TMPDIR}/img2
61 rbd export testimg - > ${TMPDIR}/img3
62 rbd rm testimg
63 cmp ${TMPDIR}/img ${TMPDIR}/img2
64 cmp ${TMPDIR}/img ${TMPDIR}/img3
65 rm ${TMPDIR}/img2 ${TMPDIR}/img3
66
67 # try again, importing from stdin
68 rbd import $RBD_CREATE_ARGS - testimg < ${TMPDIR}/img
69 rbd export testimg ${TMPDIR}/img2
70 rbd export testimg - > ${TMPDIR}/img3
71 rbd rm testimg
72 cmp ${TMPDIR}/img ${TMPDIR}/img2
73 cmp ${TMPDIR}/img ${TMPDIR}/img3
74
75 rm ${TMPDIR}/img ${TMPDIR}/img2 ${TMPDIR}/img3
76
77 if rbd help export | grep -q export-format; then
78     # try with --export-format for snapshots
79     dd if=/bin/dd of=${TMPDIR}/img bs=1k count=10 seek=100
80     rbd import $RBD_CREATE_ARGS ${TMPDIR}/img testimg
81     rbd snap create testimg@snap
82     rbd export --export-format 2 testimg ${TMPDIR}/img_v2
83     rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import
84     rbd info testimg_import
85     rbd info testimg_import@snap
86
87     # compare the contents between testimg and testimg_import
88     rbd export testimg_import ${TMPDIR}/img_import
89     compare_files_and_ondisk_sizes ${TMPDIR}/img ${TMPDIR}/img_import
90
91     rbd export testimg@snap ${TMPDIR}/img_snap
92     rbd export testimg_import@snap ${TMPDIR}/img_snap_import
93     compare_files_and_ondisk_sizes ${TMPDIR}/img_snap ${TMPDIR}/img_snap_import
94
95     rm ${TMPDIR}/img_v2
96     rm ${TMPDIR}/img_import
97     rm ${TMPDIR}/img_snap
98     rm ${TMPDIR}/img_snap_import
99
100     rbd snap rm testimg_import@snap
101     rbd remove testimg_import
102     rbd snap rm testimg@snap
103     rbd rm testimg
104
105     # order
106     rbd import --order 20 ${TMPDIR}/img testimg
107     rbd export --export-format 2 testimg ${TMPDIR}/img_v2
108     rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import
109     rbd info testimg_import|grep order|awk '{print $2}'|grep 20
110     
111     rm ${TMPDIR}/img_v2
112
113     rbd remove testimg_import
114     rbd remove testimg
115
116     # features
117     rbd import --image-feature layering ${TMPDIR}/img testimg
118     FEATURES_BEFORE=`rbd info testimg|grep features`
119     rbd export --export-format 2 testimg ${TMPDIR}/img_v2
120     rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import
121     FEATURES_AFTER=`rbd info testimg_import|grep features`
122     if [ "$FEATURES_BEFORE" != "$FEATURES_AFTER" ]; then
123         false
124     fi
125
126     rm ${TMPDIR}/img_v2
127
128     rbd remove testimg_import
129     rbd remove testimg
130
131     # stripe
132     rbd import --stripe-count 1000 --stripe-unit 4096 ${TMPDIR}/img testimg
133     rbd export --export-format 2 testimg ${TMPDIR}/img_v2
134     rbd import --export-format 2 ${TMPDIR}/img_v2 testimg_import
135     rbd info testimg_import|grep "stripe unit"|awk '{print $3}'|grep 4096
136     rbd info testimg_import|grep "stripe count"|awk '{print $3}'|grep 1000
137
138     rm ${TMPDIR}/img_v2
139
140     rbd remove testimg_import
141     rbd remove testimg
142 fi
143
144 tiered=0
145 if ceph osd dump | grep ^pool | grep "'rbd'" | grep tier; then
146     tiered=1
147 fi
148
149 # create specifically sparse files
150 # 1 1M block of sparse, 1 1M block of random
151 dd if=/dev/urandom bs=1M seek=1 count=1 of=${TMPDIR}/sparse1
152
153 # 1 1M block of random, 1 1M block of sparse
154 dd if=/dev/urandom bs=1M count=1 of=${TMPDIR}/sparse2; truncate ${TMPDIR}/sparse2 -s 2M
155
156 # 1M-block images; validate resulting blocks
157
158 # 1M sparse, 1M data
159 rbd rm sparse1 || true
160 rbd import $RBD_CREATE_ARGS --order 20 ${TMPDIR}/sparse1
161 rbd ls -l | grep sparse1 | grep -Ei '(2M|2048k)'
162 [ $tiered -eq 1 -o "$(objects sparse1)" = '1' ]
163
164 # export, compare contents and on-disk size
165 rbd export sparse1 ${TMPDIR}/sparse1.out
166 compare_files_and_ondisk_sizes ${TMPDIR}/sparse1 ${TMPDIR}/sparse1.out
167 rm ${TMPDIR}/sparse1.out
168 rbd rm sparse1
169
170 # 1M data, 1M sparse
171 rbd rm sparse2 || true
172 rbd import $RBD_CREATE_ARGS --order 20 ${TMPDIR}/sparse2
173 rbd ls -l | grep sparse2 | grep -Ei '(2M|2048k)'
174 [ $tiered -eq 1 -o "$(objects sparse2)" = '0' ]
175 rbd export sparse2 ${TMPDIR}/sparse2.out
176 compare_files_and_ondisk_sizes ${TMPDIR}/sparse2 ${TMPDIR}/sparse2.out
177 rm ${TMPDIR}/sparse2.out
178 rbd rm sparse2
179
180 # extend sparse1 to 10 1M blocks, sparse at the end
181 truncate ${TMPDIR}/sparse1 -s 10M
182 # import from stdin just for fun, verify still sparse
183 rbd import $RBD_CREATE_ARGS --order 20 - sparse1 < ${TMPDIR}/sparse1
184 rbd ls -l | grep sparse1 | grep -Ei '(10M|10240k)'
185 [ $tiered -eq 1 -o "$(objects sparse1)" = '1' ]
186 rbd export sparse1 ${TMPDIR}/sparse1.out
187 compare_files_and_ondisk_sizes ${TMPDIR}/sparse1 ${TMPDIR}/sparse1.out
188 rm ${TMPDIR}/sparse1.out
189 rbd rm sparse1
190
191 # extend sparse2 to 4M total with two more nonsparse megs
192 dd if=/dev/urandom bs=2M count=1 of=${TMPDIR}/sparse2 oflag=append conv=notrunc
193 # again from stding
194 rbd import $RBD_CREATE_ARGS --order 20 - sparse2 < ${TMPDIR}/sparse2
195 rbd ls -l | grep sparse2 | grep -Ei '(4M|4096k)'
196 [ $tiered -eq 1 -o "$(objects sparse2)" = '0 2 3' ]
197 rbd export sparse2 ${TMPDIR}/sparse2.out
198 compare_files_and_ondisk_sizes ${TMPDIR}/sparse2 ${TMPDIR}/sparse2.out
199 rm ${TMPDIR}/sparse2.out
200 rbd rm sparse2
201
202 # zeros import to a sparse image.  Note: all zeros currently
203 # doesn't work right now due to the way we handle 'empty' fiemaps;
204 # the image ends up zero-filled.
205
206 echo "partially-sparse file imports to partially-sparse image"
207 rbd import $RBD_CREATE_ARGS --order 20 ${TMPDIR}/sparse1 sparse
208 [ $tiered -eq 1 -o "$(objects sparse)" = '1' ]
209 rbd rm sparse
210
211 echo "zeros import through stdin to sparse image"
212 # stdin
213 dd if=/dev/zero bs=1M count=4 | rbd import $RBD_CREATE_ARGS - sparse
214 [ $tiered -eq 1 -o "$(objects sparse)" = '' ]
215 rbd rm sparse
216
217 echo "zeros export to sparse file"
218 #  Must be tricky to make image "by hand" ; import won't create a zero image
219 rbd create $RBD_CREATE_ARGS sparse --size 4
220 prefix=$(rbd info sparse | grep block_name_prefix | awk '{print $NF;}')
221 # drop in 0 object directly
222 dd if=/dev/zero bs=4M count=1 | rados -p $(get_image_data_pool sparse) \
223                                       put ${prefix}.000000000000 -
224 [ $tiered -eq 1 -o "$(objects sparse)" = '0' ]
225 # 1 object full of zeros; export should still create 0-disk-usage file
226 rm ${TMPDIR}/sparse || true
227 rbd export sparse ${TMPDIR}/sparse
228 [ $(stat ${TMPDIR}/sparse --format=%b) = '0' ]
229 rbd rm sparse
230
231 rm ${TMPDIR}/sparse ${TMPDIR}/sparse1 ${TMPDIR}/sparse2 ${TMPDIR}/sparse3 || true
232
233 echo OK