]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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}" | |
c07f9fc5 | 112 | ceph osd pool application enable "${POOL}" rados |
7c673cae FG |
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" | |
224ce89b | 157 | ceph osd erasure-code-profile set "${PROFILE}" k=2 m=1 crush-failure-domain=osd |
7c673cae FG |
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}" | |
c07f9fc5 | 160 | ceph osd pool application enable "${POOL}" rados |
7c673cae FG |
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" |