Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / workunits / rados / test_alloc_hint.sh
1 #!/bin/bash
2
3 set -ex
4 shopt -s nullglob # fns glob expansion in expect_alloc_hint_eq()
5
6 #
7 # Helpers
8 #
9
10 function get_xml_val() {
11     local xml="$1"
12     local tag="$2"
13
14     local regex=".*<${tag}>(.*)</${tag}>.*"
15     if [[ ! "${xml}" =~ ${regex} ]]; then
16         echo "'${xml}' xml doesn't match '${tag}' tag regex" >&2
17         return 2
18     fi
19
20     echo "${BASH_REMATCH[1]}"
21 }
22
23 function get_conf_val() {
24     set -e
25
26     local entity="$1"
27     local option="$2"
28
29     local val
30     val="$(sudo ceph daemon "${entity}" config get --format=xml "${option}")"
31     val="$(get_xml_val "${val}" "${option}")"
32
33     echo "${val}"
34 }
35
36 function setup_osd_data() {
37     for (( i = 0 ; i < "${NUM_OSDS}" ; i++ )); do
38         OSD_DATA[i]="$(get_conf_val "osd.$i" "osd_data")"
39     done
40 }
41
42 function setup_pgid() {
43     local poolname="$1"
44     local objname="$2"
45
46     local pgid
47     pgid="$(ceph osd map "${poolname}" "${objname}" --format=xml)"
48     pgid="$(get_xml_val "${pgid}" "pgid")"
49
50     PGID="${pgid}"
51 }
52
53 function expect_alloc_hint_eq() {
54     local expected_extsize="$1"
55
56     for (( i = 0 ; i < "${NUM_OSDS}" ; i++ )); do
57         # Make sure that stuff is flushed from the journal to the store
58         # by the time we get to it, as we prod the actual files and not
59         # the journal.
60         sudo ceph daemon "osd.${i}" "flush_journal"
61
62         # e.g., .../25.6_head/foo__head_7FC1F406__19
63         #       .../26.bs1_head/bar__head_EFE6384B__1a_ffffffffffffffff_1
64         local fns=$(sudo sh -c "ls ${OSD_DATA[i]}/current/${PGID}*_head/${OBJ}_*")
65         local count="${#fns[@]}"
66         if [ "${count}" -ne 1 ]; then
67             echo "bad fns count: ${count}" >&2
68             return 2
69         fi
70
71         local extsize
72         extsize="$(sudo xfs_io -c extsize "${fns[0]}")"
73         local extsize_regex="^\[(.*)\] ${fns[0]}$"
74         if [[ ! "${extsize}" =~ ${extsize_regex} ]]; then
75             echo "extsize doesn't match extsize_regex: ${extsize}" >&2
76             return 2
77         fi
78         extsize="${BASH_REMATCH[1]}"
79
80         if [ "${extsize}" -ne "${expected_extsize}" ]; then
81             echo "FAIL: alloc_hint: actual ${extsize}, expected ${expected_extsize}" >&2
82             return 1
83         fi
84     done
85 }
86
87 #
88 # Global setup
89 #
90
91 EC_K="2"
92 EC_M="1"
93 NUM_OSDS="$((EC_K + EC_M))"
94
95 NUM_PG="12"
96 NUM_PGP="${NUM_PG}"
97
98 LOW_CAP="$(get_conf_val "osd.0" "filestore_max_alloc_hint_size")"
99 HIGH_CAP="$((LOW_CAP * 10))" # 10M, assuming 1M default cap
100 SMALL_HINT="$((LOW_CAP / 4))" # 256K, assuming 1M default cap
101 BIG_HINT="$((LOW_CAP * 6))" # 6M, assuming 1M default cap
102
103 setup_osd_data
104
105 #
106 # ReplicatedBackend tests
107 #
108
109 POOL="alloc_hint-rep"
110 ceph osd pool create "${POOL}" "${NUM_PG}"
111 ceph osd pool set "${POOL}" size "${NUM_OSDS}"
112 ceph osd pool application enable "${POOL}" rados
113
114 OBJ="foo"
115 setup_pgid "${POOL}" "${OBJ}"
116 rados -p "${POOL}" create "${OBJ}"
117
118 # Empty object, SMALL_HINT - expect SMALL_HINT
119 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
120 expect_alloc_hint_eq "${SMALL_HINT}"
121
122 # Try changing to BIG_HINT (1) - expect LOW_CAP (BIG_HINT > LOW_CAP)
123 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${BIG_HINT}" "${BIG_HINT}"
124 expect_alloc_hint_eq "${LOW_CAP}"
125
126 # Bump the cap to HIGH_CAP
127 ceph tell 'osd.*' injectargs "--filestore_max_alloc_hint_size ${HIGH_CAP}"
128
129 # Try changing to BIG_HINT (2) - expect BIG_HINT (BIG_HINT < HIGH_CAP)
130 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${BIG_HINT}" "${BIG_HINT}"
131 expect_alloc_hint_eq "${BIG_HINT}"
132
133 ceph tell 'osd.*' injectargs "--filestore_max_alloc_hint_size ${LOW_CAP}"
134
135 # Populate object with some data
136 rados -p "${POOL}" put "${OBJ}" /etc/passwd
137
138 # Try changing back to SMALL_HINT - expect BIG_HINT (non-empty object)
139 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
140 expect_alloc_hint_eq "${BIG_HINT}"
141
142 OBJ="bar"
143 setup_pgid "${POOL}" "${OBJ}"
144
145 # Non-existent object, SMALL_HINT - expect SMALL_HINT (object creation)
146 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
147 expect_alloc_hint_eq "${SMALL_HINT}"
148
149 ceph osd pool delete "${POOL}" "${POOL}" --yes-i-really-really-mean-it
150
151 #
152 # ECBackend tests
153 #
154
155 PROFILE="alloc_hint-ecprofile"
156 POOL="alloc_hint-ec"
157 ceph osd erasure-code-profile set "${PROFILE}" k=2 m=1 crush-failure-domain=osd
158 ceph osd erasure-code-profile get "${PROFILE}" # just so it's logged
159 ceph osd pool create "${POOL}" "${NUM_PG}" "${NUM_PGP}" erasure "${PROFILE}"
160 ceph osd pool application enable "${POOL}" rados
161
162 OBJ="baz"
163 setup_pgid "${POOL}" "${OBJ}"
164 rados -p "${POOL}" create "${OBJ}"
165
166 # Empty object, SMALL_HINT - expect scaled-down SMALL_HINT
167 rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
168 expect_alloc_hint_eq "$((SMALL_HINT / EC_K))"
169
170 ceph osd pool delete "${POOL}" "${POOL}" --yes-i-really-really-mean-it
171
172 #
173 # Global teardown
174 #
175
176 echo "OK"