Skip to content

Commit

Permalink
Merge pull request ceph#1400 from ceph/wip-hint-tests
Browse files Browse the repository at this point in the history
wip-hint-tests

Reviewed-by: Sage Weil <[email protected]>
  • Loading branch information
Sage Weil committed Mar 12, 2014
2 parents 2fbd772 + 55c23a1 commit d72c2bb
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
168 changes: 168 additions & 0 deletions qa/workunits/rados/test_alloc_hint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/bin/bash

set -ex
shopt -s nullglob # fns glob expansion in expect_alloc_hint_eq()

#
# Helpers
#

function get_xml_val() {
local xml="$1"
local tag="$2"

local regex=".*<${tag}>(.*)</${tag}>.*"
if [[ ! "${xml}" =~ ${regex} ]]; then
echo "'${xml}' xml doesn't match '${tag}' tag regex" >&2
return 2
fi

echo "${BASH_REMATCH[1]}"
}

function get_conf_val() {
set -e

local entity="$1"
local option="$2"

local val
val="$(sudo ceph daemon "${entity}" config get --format=xml "${option}")"
val="$(get_xml_val "${val}" "${option}")"

echo "${val}"
}

function setup_osd_data() {
for (( i = 0 ; i < "${NUM_OSDS}" ; i++ )); do
OSD_DATA[i]="$(get_conf_val "osd.$i" "osd_data")"
done
}

function setup_pgid() {
local poolname="$1"
local objname="$2"

local pgid
pgid="$(ceph osd map "${poolname}" "${objname}" --format=xml)"
pgid="$(get_xml_val "${pgid}" "pgid")"

PGID="${pgid}"
}

function expect_alloc_hint_eq() {
local expected_extsize="$1"

for (( i = 0 ; i < "${NUM_OSDS}" ; i++ )); do
# e.g., .../25.6_head/foo__head_7FC1F406__19
# .../26.bs1_head/bar__head_EFE6384B__1a_ffffffffffffffff_1
local fns=(${OSD_DATA[i]}/current/${PGID}*_head/${OBJ}_*)
local count="${#fns[@]}"
if [ "${count}" -ne 1 ]; then
echo "bad fns count: ${count}" >&2
return 2
fi

local extsize
extsize="$(sudo xfs_io -c extsize "${fns[0]}")"
local extsize_regex="^\[(.*)\] ${fns[0]}$"
if [[ ! "${extsize}" =~ ${extsize_regex} ]]; then
echo "extsize doesn't match extsize_regex: ${extsize}" >&2
return 2
fi
extsize="${BASH_REMATCH[1]}"

if [ "${extsize}" -ne "${expected_extsize}" ]; then
echo "FAIL: alloc_hint: actual ${extsize}, expected ${expected_extsize}" >&2
return 1
fi
done
}

#
# Global setup
#

EC_K="2"
EC_M="1"
NUM_OSDS="$((EC_K + EC_M))"

NUM_PG="12"
NUM_PGP="${NUM_PG}"

LOW_CAP="$(get_conf_val "osd.0" "filestore_max_alloc_hint_size")"
HIGH_CAP="$((LOW_CAP * 10))" # 10M, assuming 1M default cap
SMALL_HINT="$((LOW_CAP / 4))" # 256K, assuming 1M default cap
BIG_HINT="$((LOW_CAP * 6))" # 6M, assuming 1M default cap

setup_osd_data

#
# ReplicatedBackend tests
#

POOL="alloc_hint-rep"
ceph osd pool create "${POOL}" "${NUM_PG}"
ceph osd pool set "${POOL}" size "${NUM_OSDS}" # just in case

OBJ="foo"
setup_pgid "${POOL}" "${OBJ}"
rados -p "${POOL}" create "${OBJ}"

# Empty object, SMALL_HINT - expect SMALL_HINT
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
expect_alloc_hint_eq "${SMALL_HINT}"

# Try changing to BIG_HINT (1) - expect LOW_CAP (BIG_HINT > LOW_CAP)
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${BIG_HINT}" "${BIG_HINT}"
expect_alloc_hint_eq "${LOW_CAP}"

# Bump the cap to HIGH_CAP
ceph tell 'osd.*' injectargs "--filestore_max_alloc_hint_size ${HIGH_CAP}"

# Try changing to BIG_HINT (2) - expect BIG_HINT (BIG_HINT < HIGH_CAP)
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${BIG_HINT}" "${BIG_HINT}"
expect_alloc_hint_eq "${BIG_HINT}"

ceph tell 'osd.*' injectargs "--filestore_max_alloc_hint_size ${LOW_CAP}"

# Populate object with some data
rados -p "${POOL}" put "${OBJ}" /etc/passwd

# Try changing back to SMALL_HINT - expect BIG_HINT (non-empty object)
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
expect_alloc_hint_eq "${BIG_HINT}"

OBJ="bar"
setup_pgid "${POOL}" "${OBJ}"

# Non-existent object, SMALL_HINT - expect SMALL_HINT (object creation)
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
expect_alloc_hint_eq "${SMALL_HINT}"

ceph osd pool delete "${POOL}" "${POOL}" --yes-i-really-really-mean-it

#
# ECBackend tests
#

POOL="alloc_hint-ec"
RULE="ecruleset"
ceph osd crush rule create-erasure "${RULE}" erasure-code-k="${EC_K}" erasure-code-m="${EC_M}" erasure-code-ruleset-failure-domain=osd
ceph osd pool create "${POOL}" "${NUM_PG}" "${NUM_PGP}" erasure crush_ruleset="${RULE}" erasure-code-k="${EC_K}" erasure-code-m="${EC_M}" erasure-code-ruleset-failure-domain=osd

OBJ="baz"
setup_pgid "${POOL}" "${OBJ}"
rados -p "${POOL}" create "${OBJ}"

# Empty object, SMALL_HINT - expect scaled-down SMALL_HINT
rados -p "${POOL}" set-alloc-hint "${OBJ}" "${SMALL_HINT}" "${SMALL_HINT}"
expect_alloc_hint_eq "$((SMALL_HINT / EC_K))"

ceph osd pool delete "${POOL}" "${POOL}" --yes-i-really-really-mean-it

#
# Global teardown
#

echo "OK"
23 changes: 23 additions & 0 deletions src/tools/rados/rados.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ void usage(ostream& out)
" setomapheader <obj-name> <val>\n"
" tmap-to-omap <obj-name> convert tmap keys/values to omap\n"
" listwatchers <obj-name> list the watchers of this object\n"
" set-alloc-hint <obj-name> <expected-object-size> <expected-write-size>\n"
" set allocation hint for an object\n"
"\n"
"IMPORT AND EXPORT\n"
" import [options] <local-directory> <rados-pool>\n"
Expand Down Expand Up @@ -2197,6 +2199,27 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
ret = io_ctx.notify(oid, 0, bl);
if (ret != 0)
cerr << "error calling notify: " << ret << std::endl;
} else if (strcmp(nargs[0], "set-alloc-hint") == 0) {
if (!pool_name || nargs.size() < 4)
usage_exit();
string err;
string oid(nargs[1]);
uint64_t expected_object_size = strict_strtoll(nargs[2], 10, &err);
if (!err.empty()) {
cerr << "couldn't parse expected_object_size: " << err << std::endl;
usage_exit();
}
uint64_t expected_write_size = strict_strtoll(nargs[3], 10, &err);
if (!err.empty()) {
cerr << "couldn't parse expected_write_size: " << err << std::endl;
usage_exit();
}
ret = io_ctx.set_alloc_hint(oid, expected_object_size, expected_write_size);
if (ret < 0) {
cerr << "error setting alloc-hint " << pool_name << "/" << oid << ": "
<< strerror_r(-ret, buf, sizeof(buf)) << std::endl;
goto out;
}
} else if (strcmp(nargs[0], "load-gen") == 0) {
if (!pool_name) {
cerr << "error: must specify pool" << std::endl;
Expand Down

0 comments on commit d72c2bb

Please sign in to comment.