Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / rbd / krbd_fallocate.sh
1 #!/bin/bash
2
3 # This documents the state of things as of 4.12-rc4.
4 #
5 # - fallocate -z deallocates because BLKDEV_ZERO_NOUNMAP hint is ignored by
6 # krbd
7 #
8 # - unaligned fallocate -z/-p appear to not deallocate -- see caveat #2 in
9 # linux.git commit 6ac56951dc10 ("rbd: implement REQ_OP_WRITE_ZEROES")
10
11 set -ex
12
13 # no blkdiscard(8) in trusty
14 function py_blkdiscard() {
15     local offset=$1
16
17     python <<EOF
18 import fcntl, struct
19 BLKDISCARD = 0x1277
20 with open('$DEV', 'w') as dev:
21     fcntl.ioctl(dev, BLKDISCARD, struct.pack('QQ', $offset, $IMAGE_SIZE - $offset))
22 EOF
23 }
24
25 # fallocate(1) in trusty doesn't support -z/-p
26 function py_fallocate() {
27     local mode=$1
28     local offset=$2
29
30     python <<EOF
31 import os, ctypes, ctypes.util
32 FALLOC_FL_KEEP_SIZE = 0x01
33 FALLOC_FL_PUNCH_HOLE = 0x02
34 FALLOC_FL_ZERO_RANGE = 0x10
35 libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
36 with open('$DEV', 'w') as dev:
37     if libc.fallocate(dev.fileno(), ctypes.c_int($mode), ctypes.c_long($offset), ctypes.c_long($IMAGE_SIZE - $offset)):
38         err = ctypes.get_errno()
39         raise OSError(err, os.strerror(err))
40 EOF
41 }
42
43 function allocate() {
44     xfs_io -c "pwrite -b $OBJECT_SIZE -W 0 $IMAGE_SIZE" $DEV
45     cmp <(od -xAx $DEV) - <<EOF
46 000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd
47 *
48 $(printf %x $IMAGE_SIZE)
49 EOF
50     [[ $(rados -p rbd ls | grep -c rbd_data.$IMAGE_ID) -eq $NUM_OBJECTS ]]
51 }
52
53 function assert_deallocated() {
54     cmp <(od -xAx $DEV) - <<EOF
55 000000 0000 0000 0000 0000 0000 0000 0000 0000
56 *
57 $(printf %x $IMAGE_SIZE)
58 EOF
59     [[ $(rados -p rbd ls | grep -c rbd_data.$IMAGE_ID) -eq 0 ]]
60 }
61
62 function assert_deallocated_unaligned() {
63     local num_objects_expected=$1
64
65     cmp <(od -xAx $DEV) - <<EOF
66 000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd
67 *
68 $(printf %x $((OBJECT_SIZE / 2))) 0000 0000 0000 0000 0000 0000 0000 0000
69 *
70 $(printf %x $IMAGE_SIZE)
71 EOF
72     [[ $(rados -p rbd ls | grep -c rbd_data.$IMAGE_ID) -eq $num_objects_expected ]]
73     for ((i = 0; i < $num_objects_expected; i++)); do
74         rados -p rbd stat rbd_data.$IMAGE_ID.$(printf %016x $i) | grep "size $((OBJECT_SIZE / 2))"
75     done
76 }
77
78 IMAGE_NAME="fallocate-test"
79
80 rbd create --size 200 $IMAGE_NAME
81
82 IMAGE_SIZE=$(rbd info --format=json $IMAGE_NAME | python -c 'import sys, json; print json.load(sys.stdin)["size"]')
83 OBJECT_SIZE=$(rbd info --format=json $IMAGE_NAME | python -c 'import sys, json; print json.load(sys.stdin)["object_size"]')
84 NUM_OBJECTS=$((IMAGE_SIZE / OBJECT_SIZE))
85 [[ $((IMAGE_SIZE % OBJECT_SIZE)) -eq 0 ]]
86
87 IMAGE_ID="$(rbd info --format=json $IMAGE_NAME |
88     python -c "import sys, json; print json.load(sys.stdin)['block_name_prefix'].split('.')[1]")"
89
90 DEV=$(sudo rbd map $IMAGE_NAME)
91
92 # blkdev_issue_discard
93 allocate
94 py_blkdiscard 0
95 assert_deallocated
96
97 # blkdev_issue_zeroout w/ BLKDEV_ZERO_NOUNMAP
98 allocate
99 py_fallocate FALLOC_FL_ZERO_RANGE\|FALLOC_FL_KEEP_SIZE 0
100 assert_deallocated
101
102 # blkdev_issue_zeroout w/ BLKDEV_ZERO_NOFALLBACK
103 allocate
104 py_fallocate FALLOC_FL_PUNCH_HOLE\|FALLOC_FL_KEEP_SIZE 0
105 assert_deallocated
106
107 # unaligned blkdev_issue_discard
108 allocate
109 py_blkdiscard $((OBJECT_SIZE / 2))
110 assert_deallocated_unaligned 1
111
112 # unaligned blkdev_issue_zeroout w/ BLKDEV_ZERO_NOUNMAP
113 allocate
114 py_fallocate FALLOC_FL_ZERO_RANGE\|FALLOC_FL_KEEP_SIZE $((OBJECT_SIZE / 2))
115 assert_deallocated_unaligned $NUM_OBJECTS
116
117 # unaligned blkdev_issue_zeroout w/ BLKDEV_ZERO_NOFALLBACK
118 allocate
119 py_fallocate FALLOC_FL_PUNCH_HOLE\|FALLOC_FL_KEEP_SIZE $((OBJECT_SIZE / 2))
120 assert_deallocated_unaligned $NUM_OBJECTS
121
122 sudo rbd unmap $DEV
123
124 echo OK