From: Jason Dillaman Date: Fri, 2 Dec 2016 18:36:35 +0000 (-0500) Subject: rados: optionally support reading omap key from file X-Git-Tag: v11.1.1~52^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=286ceb1e035f060cc564c1ef7400382331893101;p=ceph.git rados: optionally support reading omap key from file Fixes: http://tracker.ceph.com/issues/18123 Signed-off-by: Jason Dillaman --- diff --git a/doc/man/8/rados.rst b/doc/man/8/rados.rst index 2b02aea7c9aa..82e47d7afdb1 100644 --- a/doc/man/8/rados.rst +++ b/doc/man/8/rados.rst @@ -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* diff --git a/qa/workunits/rados/test_rados_tool.sh b/qa/workunits/rados/test_rados_tool.sh index c0b6d8ceecc8..95cf4774adc7 100755 --- a/qa/workunits/rados/test_rados_tool.sh +++ b/qa/workunits/rados/test_rados_tool.sh @@ -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 } diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index fe1212dba562..a334ada42a9b 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -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 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 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 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 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();