Skip to content

Commit

Permalink
Merge pull request #12286 from dillaman/wip-18123
Browse files Browse the repository at this point in the history
rados: optionally support reading omap key from file

Reviewed-by: Kefu Chai <kchai@redhat.com>
  • Loading branch information
liewegas committed Dec 15, 2016
2 parents 1c8903f + 286ceb1 commit 61e592a
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 26 deletions.
12 changes: 8 additions & 4 deletions doc/man/8/rados.rst
Expand Up @@ -137,13 +137,17 @@ Pool specific commands
List all key/value pairs stored in the object map of object name.
The values are dumped in hexadecimal.

:command:`getomapval` *name* *key*
:command:`getomapval` [ --omap-key-file *file* ] *name* *key* [ *out-file* ]
Dump the hexadecimal value of key in the object map of object name.
If the optional *out-file* argument isn't provided, the value will be
written to standard output.

:command:`setomapval` *name* *key* *value*
Set the value of key in the object map of object name.
:command:`setomapval` [ --omap-key-file *file* ] *name* *key* [ *value* ]
Set the value of key in the object map of object name. If the optional
*value* argument isn't provided, the value will be read from standard
input.

:command:`rmomapkey` *name* *key*
:command:`rmomapkey` [ --omap-key-file *file* ] *name* *key*
Remove key from the object map of object name.

:command:`getomapheader` *name*
Expand Down
23 changes: 21 additions & 2 deletions qa/workunits/rados/test_rados_tool.sh
Expand Up @@ -281,7 +281,7 @@ cleanup() {

test_omap() {
cleanup
for i in $(seq 1 1 600)
for i in $(seq 1 1 10)
do
if [ $(($i % 2)) -eq 0 ]; then
$RADOS_TOOL -p $POOL setomapval $OBJ $i $i
Expand All @@ -290,7 +290,26 @@ test_omap() {
fi
$RADOS_TOOL -p $POOL getomapval $OBJ $i | grep -q "|$i|\$"
done
$RADOS_TOOL -p $POOL listomapvals $OBJ | grep -c value | grep 600
$RADOS_TOOL -p $POOL listomapvals $OBJ | grep -c value | grep 10
for i in $(seq 1 1 5)
do
$RADOS_TOOL -p $POOL rmomapkey $OBJ $i
done
$RADOS_TOOL -p $POOL listomapvals $OBJ | grep -c value | grep 5
cleanup

for i in $(seq 1 1 10)
do
dd if=/dev/urandom bs=128 count=1 > $TDIR/omap_key
if [ $(($i % 2)) -eq 0 ]; then
$RADOS_TOOL -p $POOL --omap-key-file $TDIR/omap_key setomapval $OBJ $i
else
echo -n "$i" | $RADOS_TOOL -p $POOL --omap-key-file $TDIR/omap_key setomapval $OBJ
fi
$RADOS_TOOL -p $POOL --omap-key-file $TDIR/omap_key getomapval $OBJ | grep -q "|$i|\$"
$RADOS_TOOL -p $POOL --omap-key-file $TDIR/omap_key rmomapkey $OBJ
$RADOS_TOOL -p $POOL listomapvals $OBJ | grep -c value | grep 0
done
cleanup
}

Expand Down
80 changes: 60 additions & 20 deletions src/tools/rados/rados.cc
Expand Up @@ -225,7 +225,8 @@ void usage(ostream& out)
" --run-length total time (in seconds)\n"
"CACHE POOLS OPTIONS:\n"
" --with-clones include clones when doing flush or evict\n"
;
"OMAP OPTIONS:\n"
" --omap-key-file file read the omap key from a file\n";
}

unsigned default_op_size = 1 << 22;
Expand Down Expand Up @@ -1649,6 +1650,9 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
Formatter *formatter = NULL;
bool pretty_format = false;
const char *output = NULL;
bool omap_key_valid = false;
std::string omap_key;
std::string omap_key_pretty;

Rados rados;
IoCtx io_ctx;
Expand Down Expand Up @@ -1840,6 +1844,24 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
if (i != opts.end()) {
with_clones = true;
}
i = opts.find("omap-key-file");
if (i != opts.end()) {
string err;
bufferlist indata;
ret = indata.read_file(i->second.c_str(), &err);
if (ret < 0) {
cerr << err << std::endl;
return 1;
}

omap_key_valid = true;
omap_key = std::string(indata.c_str(), indata.length());
omap_key_pretty = omap_key;
if (std::find_if_not(omap_key.begin(), omap_key.end(),
(int (*)(int))isprint) != omap_key.end()) {
omap_key_pretty = "(binary key)";
}
}

// open rados
ret = rados.init_with_context(g_ceph_context);
Expand Down Expand Up @@ -2414,15 +2436,20 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
ret = 0;
}
} else if (strcmp(nargs[0], "setomapval") == 0) {
if (!pool_name || nargs.size() < 3 || nargs.size() > 4)
uint32_t min_args = (omap_key_valid ? 2 : 3);
if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) {
usage_exit();
}

string oid(nargs[1]);
string key(nargs[2]);
if (!omap_key_valid) {
omap_key = nargs[2];
omap_key_pretty = omap_key;
}

bufferlist bl;
if (nargs.size() == 4) {
string val(nargs[3]);
if (nargs.size() > min_args) {
string val(nargs[min_args]);
bl.append(val);
} else {
do {
Expand All @@ -2434,41 +2461,47 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
}

map<string, bufferlist> values;
values[key] = bl;
values[omap_key] = bl;

ret = io_ctx.omap_set(oid, values);
if (ret < 0) {
cerr << "error setting omap value " << pool_name << "/" << oid << "/"
<< key << ": " << cpp_strerror(ret) << std::endl;
<< omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
goto out;
} else {
ret = 0;
}
} else if (strcmp(nargs[0], "getomapval") == 0) {
if (!pool_name || nargs.size() < 3)
uint32_t min_args = (omap_key_valid ? 2 : 3);
if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) {
usage_exit();
}

string oid(nargs[1]);
string key(nargs[2]);
if (!omap_key_valid) {
omap_key = nargs[2];
omap_key_pretty = omap_key;
}

set<string> keys;
keys.insert(key);
keys.insert(omap_key);

std::string outfile;
if (nargs.size() >= 4) {
outfile = nargs[3];
if (nargs.size() > min_args) {
outfile = nargs[min_args];
}

map<string, bufferlist> values;
ret = io_ctx.omap_get_vals_by_keys(oid, keys, &values);
if (ret < 0) {
cerr << "error getting omap value " << pool_name << "/" << oid << "/"
<< key << ": " << cpp_strerror(ret) << std::endl;
<< omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
goto out;
} else {
ret = 0;
}

if (values.size() && values.begin()->first == key) {
if (values.size() && values.begin()->first == omap_key) {
if (!outfile.empty()) {
cerr << "Writing to " << outfile << std::endl;
dump_data(outfile, values.begin()->second);
Expand All @@ -2479,24 +2512,29 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
}
ret = 0;
} else {
cout << "No such key: " << pool_name << "/" << oid << "/" << key
<< std::endl;
cout << "No such key: " << pool_name << "/" << oid << "/"
<< omap_key_pretty << std::endl;
ret = -1;
goto out;
}
} else if (strcmp(nargs[0], "rmomapkey") == 0) {
if (!pool_name || nargs.size() < 3)
uint32_t num_args = (omap_key_valid ? 2 : 3);
if (!pool_name || nargs.size() != num_args) {
usage_exit();
}

string oid(nargs[1]);
string key(nargs[2]);
if (!omap_key_valid) {
omap_key = nargs[2];
omap_key_pretty = omap_key;
}
set<string> keys;
keys.insert(key);
keys.insert(omap_key);

ret = io_ctx.omap_rm_keys(oid, keys);
if (ret < 0) {
cerr << "error removing omap key " << pool_name << "/" << oid << "/"
<< key << ": " << cpp_strerror(ret) << std::endl;
<< omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
goto out;
} else {
ret = 0;
Expand Down Expand Up @@ -3672,6 +3710,8 @@ int main(int argc, const char **argv)
opts["write-dest-xattr"] = "true";
} else if (ceph_argparse_flag(args, i, "--with-clones", (char*)NULL)) {
opts["with-clones"] = "true";
} else if (ceph_argparse_witharg(args, i, &val, "--omap-key-file", (char*)NULL)) {
opts["omap-key-file"] = val;
} else {
if (val[0] == '-')
usage_exit();
Expand Down

0 comments on commit 61e592a

Please sign in to comment.