rados: optionally support reading omap key from file

Fixes: http://tracker.ceph.com/issues/18123
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2016-12-02 13:36:35 -05:00
parent d009a6cb68
commit 286ceb1e03
3 changed files with 89 additions and 26 deletions

View File

@ -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*

View File

@ -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
@ -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
}

View File

@ -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;
@ -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;
@ -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);
@ -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 {
@ -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);
@ -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;
@ -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();