#include <climits>
#include <locale>
#include <memory>
+#include <optional>
#include "cls/lock/cls_lock_client.h"
#include "include/compat.h"
" listomapvals <obj-name> list the keys and vals in the object map \n"
" getomapval <obj-name> <key> [file] show the value for the specified key\n"
" in the object's object map\n"
-" setomapval <obj-name> <key> <val>\n"
+" setomapval <obj-name> <key> <val | --input-file file>\n"
" rmomapkey <obj-name> <key>\n"
" clearomap <obj-name> [obj-name2 obj-name3...] clear all the omap keys for the specified objects\n"
" getomapheader <obj-name> [file]\n"
" tier-promote <obj-name> promote the object to the base tier\n"
" unset-manifest <obj-name> unset redirect or chunked object\n"
" tier-flush <obj-name> flush the chunked object\n"
+" tier-evict <obj-name> evict the chunked object\n"
"\n"
"IMPORT AND EXPORT\n"
" export [filename]\n"
" cache-try-flush-evict-all try-flush+evict all objects\n"
"\n"
"GLOBAL OPTIONS:\n"
-" --object_locator object_locator\n"
+" --object-locator object_locator\n"
" set object_locator for operation\n"
" -p pool\n"
" --pool=pool\n"
" set the object size for put/get ops and for write benchmarking\n"
" --max-objects\n"
" set the max number of objects for write benchmarking\n"
+" --obj-name-file file\n"
+" use the content of the specified file in place of <obj-name>\n"
" -s name\n"
" --snap name\n"
" select given snap name for (read) IO\n"
+" --input-file file\n"
+" use the content of the specified file in place of <val>\n"
" --create\n"
" create the pool or directory that was specified\n"
" -N namespace\n"
" --read-percent percent of operations that are read\n"
" --target-throughput target throughput (in bytes)\n"
" --run-length total time (in seconds)\n"
-" --offset-align at what boundary to align random op offsets"
+" --offset-align at what boundary to align random op offsets\n"
+"\n"
"CACHE POOLS OPTIONS:\n"
" --with-clones include clones when doing flush or evict\n"
+"\n"
"OMAP OPTIONS:\n"
-" --omap-key-file file read the omap key from a file\n";
+" --omap-key-file file read the omap key from a file\n"
+"\n"
+"GENERIC OPTIONS:\n";
+ generic_client_usage();
}
namespace detail {
if (filename == "-") {
fd = STDOUT_FILENO;
} else {
- fd = TEMP_FAILURE_RETRY(::open(filename.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644));
+ fd = TEMP_FAILURE_RETRY(::open(filename.c_str(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644));
if (fd < 0) {
int err = errno;
cerr << "failed to open file: " << cpp_strerror(err) << std::endl;
}
-static int do_get(IoCtx& io_ctx, const char *objname, const char *outfile, unsigned op_size, [[maybe_unused]] const bool use_striper)
+static int do_get(IoCtx& io_ctx, const std::string& oid, const char *outfile, unsigned op_size, [[maybe_unused]] const bool use_striper)
{
- string oid(objname);
-
int fd;
if (strcmp(outfile, "-") == 0) {
fd = STDOUT_FILENO;
} else {
- fd = TEMP_FAILURE_RETRY(::open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0644));
+ fd = TEMP_FAILURE_RETRY(::open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644));
if (fd < 0) {
int err = errno;
cerr << "failed to open file: " << cpp_strerror(err) << std::endl;
}
static int do_put(IoCtx& io_ctx,
- const char *objname, const char *infile, int op_size,
+ const std::string& oid, const char *infile, int op_size,
uint64_t obj_offset, bool create_object,
const bool use_striper)
{
- string oid(objname);
bool stdio = (strcmp(infile, "-") == 0);
int ret = 0;
int fd = STDIN_FILENO;
if (!stdio)
- fd = open(infile, O_RDONLY);
+ fd = open(infile, O_RDONLY|O_BINARY);
if (fd < 0) {
cerr << "error reading input file " << infile << ": " << cpp_strerror(errno) << std::endl;
return 1;
}
static int do_append(IoCtx& io_ctx,
- const char *objname, const char *infile, int op_size,
+ const std::string& oid, const char *infile, int op_size,
const bool use_striper)
{
- string oid(objname);
bool stdio = (strcmp(infile, "-") == 0);
int ret = 0;
int fd = STDIN_FILENO;
if (!stdio)
- fd = open(infile, O_RDONLY);
+ fd = open(infile, O_RDONLY|O_BINARY);
if (fd < 0) {
cerr << "error reading input file " << infile << ": " << cpp_strerror(errno) << std::endl;
return 1;
string lock_cookie;
string lock_description;
int lock_duration = 0;
- ClsLockType lock_type = LOCK_EXCLUSIVE;
+ ClsLockType lock_type = ClsLockType::EXCLUSIVE;
map<string, string>::const_iterator i;
i = opts.find("lock-tag");
if (i != opts.end()) {
const string& type_str = i->second;
if (type_str.compare("exclusive") == 0) {
- lock_type = LOCK_EXCLUSIVE;
+ lock_type = ClsLockType::EXCLUSIVE;
} else if (type_str.compare("shared") == 0) {
- lock_type = LOCK_SHARED;
+ lock_type = ClsLockType::SHARED;
} else {
cerr << "unknown lock type was specified, aborting" << std::endl;
return -EINVAL;
if (cmd.compare("info") == 0) {
map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t> lockers;
- ClsLockType type = LOCK_NONE;
+ ClsLockType type = ClsLockType::NONE;
string tag;
int ret = rados::cls::lock::get_lock_info(ioctx, oid, lock_name, &lockers, &type, &tag);
if (ret < 0) {
l.set_description(lock_description);
int ret;
switch (lock_type) {
- case LOCK_SHARED:
+ case ClsLockType::SHARED:
ret = l.lock_shared(ioctx, oid);
break;
default:
return ret;
}
+static std::string prettify(const std::string& s)
+{
+ if (std::find_if_not(s.begin(), s.end(),
+ (int (*)(int))isprint) != s.end()) {
+ return "(binary key)";
+ } else {
+ return s;
+ }
+}
+
/**********************************************
**********************************************/
unique_ptr<Formatter> formatter = nullptr;
bool pretty_format = false;
const char *output = NULL;
- bool omap_key_valid = false;
- std::string omap_key;
- std::string omap_key_pretty;
+ std::optional<std::string> omap_key;
+ std::optional<std::string> obj_name;
+ std::string input_file;
bool with_reference = false;
Rados rados;
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)";
+ }
+ i = opts.find("obj-name-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;
}
+ obj_name = std::string(indata.c_str(), indata.length());
}
i = opts.find("offset_align");
if (i != opts.end()) {
if (i != opts.end()) {
with_reference = true;
}
+ i = opts.find("input_file");
+ if (i != opts.end()) {
+ input_file = i->second;
+ }
// open rados
ret = rados.init_with_context(g_ceph_context);
}
if (oloc.size()) {
if (!pool_name) {
- cerr << "pool name must be specified with --object_locator" << std::endl;
+ cerr << "pool name must be specified with --object-locator" << std::endl;
return 1;
}
io_ctx.locator_set_key(oloc);
}
}
else if (strcmp(nargs[0], "mapext") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
std::map<uint64_t,uint64_t> m;
- ret = io_ctx.mapext(oid, 0, -1, m);
+ ret = io_ctx.mapext(*obj_name, 0, -1, m);
if (ret < 0) {
- cerr << "mapext error on " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "mapext error on " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
std::map<uint64_t,uint64_t>::iterator iter;
}
}
else if (strcmp(nargs[0], "stat") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
uint64_t size;
time_t mtime;
- ret = detail::stat(io_ctx, oid, size, mtime, use_striper);
+ ret = detail::stat(io_ctx, *obj_name, size, mtime, use_striper);
if (ret < 0) {
- cerr << " error stat-ing " << pool_name << "/" << oid << ": "
+ cerr << " error stat-ing " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
} else {
utime_t t(mtime, 0);
- cout << pool_name << "/" << oid
+ cout << pool_name << "/" << prettify(*obj_name)
<< " mtime " << t << ", size " << size << std::endl;
}
}
else if (strcmp(nargs[0], "stat2") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
uint64_t size;
struct timespec mtime;
- ret = detail::stat2(io_ctx, oid, size, mtime, use_striper);
+ ret = detail::stat2(io_ctx, *obj_name, size, mtime, use_striper);
if (ret < 0) {
- cerr << " error stat-ing " << pool_name << "/" << oid << ": "
+ cerr << " error stat-ing " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
} else {
utime_t t(mtime);
- cout << pool_name << "/" << oid
+ cout << pool_name << "/" << prettify(*obj_name)
<< " mtime " << t << ", size " << size << std::endl;
}
}
else if (strcmp(nargs[0], "touch") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
time_t timestamp = time(NULL);
- if (nargs.size() > 2) {
+ if (nargs.size() > (obj_name ? 1 : 2)) {
char* endptr = NULL;
- timestamp = static_cast<time_t>(strtoll(nargs[2], &endptr, 10));
+ timestamp = static_cast<time_t>(strtoll(nargs[obj_name ? 1 : 2], &endptr, 10));
if (*endptr) {
- cerr << "Invalid value for timestamp: '" << nargs[2] << "'" << std::endl;
+ cerr << "Invalid value for timestamp: '" << nargs[obj_name ? 1 : 2] << "'" << std::endl;
ret = -EINVAL;
return 1;
}
}
-
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
ObjectWriteOperation op;
op.create(false);
op.mtime(×tamp);
- ret = io_ctx.operate(oid, &op);
+ ret = io_ctx.operate(*obj_name, &op);
if (ret < 0) {
- cerr << " error touch-ing " << pool_name << "/" << oid << ": "
+ cerr << " error touch-ing " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
else if (strcmp(nargs[0], "get") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
- ret = do_get(io_ctx, nargs[1], nargs[2], op_size, use_striper);
+ const char* out_filename;
+ if (obj_name) {
+ out_filename = nargs[1];
+ } else {
+ obj_name = nargs[1];
+ out_filename = nargs[2];
+ }
+ ret = do_get(io_ctx, *obj_name, out_filename, op_size, use_striper);
if (ret < 0) {
- cerr << "error getting " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error getting " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
}
else if (strcmp(nargs[0], "put") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
+ const char* in_filename;
+ if (obj_name) {
+ in_filename = nargs[1];
+ } else {
+ obj_name = nargs[1];
+ in_filename = nargs[2];
+ }
bool create_object = !obj_offset_specified;
- ret = do_put(io_ctx, nargs[1], nargs[2], op_size, obj_offset, create_object, use_striper);
+ ret = do_put(io_ctx, *obj_name, in_filename, op_size, obj_offset, create_object, use_striper);
if (ret < 0) {
- cerr << "error putting " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error putting " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
}
else if (strcmp(nargs[0], "append") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
- ret = do_append(io_ctx, nargs[1], nargs[2], op_size, use_striper);
+ const char* in_filename;
+ if (obj_name) {
+ in_filename = nargs[1];
+ } else {
+ obj_name = nargs[1];
+ in_filename = nargs[2];
+ }
+ ret = do_append(io_ctx, *obj_name, in_filename, op_size, use_striper);
if (ret < 0) {
- cerr << "error appending " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error appending " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
}
else if (strcmp(nargs[0], "truncate") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
char* endptr = NULL;
- long size = strtoll(nargs[2], &endptr, 10);
+ long size;
+ if (!obj_name) {
+ obj_name = nargs[1];
+ size = strtoll(nargs[2], &endptr, 10);
+ } else {
+ size = strtoll(nargs[1], &endptr, 10);
+ }
if (*endptr) {
cerr << "Invalid value for size: '" << nargs[2] << "'" << std::endl;
ret = -EINVAL;
return 1;
}
- ret = detail::trunc(io_ctx, oid, size, use_striper);
+ ret = detail::trunc(io_ctx, *obj_name, size, use_striper);
if (ret < 0) {
cerr << "error truncating oid "
- << oid << " to " << size << ": "
+ << prettify(*obj_name) << " to " << size << ": "
<< cpp_strerror(ret) << std::endl;
} else {
ret = 0;
}
}
else if (strcmp(nargs[0], "setxattr") == 0) {
- if (!pool_name || nargs.size() < 3 || nargs.size() > 4) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3) ||
+ nargs.size() > (obj_name ? 3 : 4)) {
usage(cerr);
return 1;
}
-
- string oid(nargs[1]);
- string attr_name(nargs[2]);
+ string attr_name(nargs[obj_name ? 1 : 2]);
bufferlist bl;
- if (nargs.size() == 4) {
- string attr_val(nargs[3]);
+ if (nargs.size() == (obj_name ? 3 : 4)) {
+ string attr_val(nargs[obj_name ? 2 : 3]);
bl.append(attr_val.c_str(), attr_val.length());
} else {
do {
return 1;
} while (ret > 0);
}
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
- ret = detail::setxattr(io_ctx, oid, attr_name, bl, use_striper);
+ ret = detail::setxattr(io_ctx, *obj_name, attr_name, bl, use_striper);
if (ret < 0) {
- cerr << "error setting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error setting xattr " << pool_name << "/" << prettify(*obj_name) << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
else
ret = 0;
}
else if (strcmp(nargs[0], "getxattr") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
-
- string oid(nargs[1]);
- string attr_name(nargs[2]);
-
+ string attr_name(nargs[obj_name ? 1 : 2]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
bufferlist bl;
- ret = detail::getxattr(io_ctx, oid, attr_name, bl, use_striper);
+ ret = detail::getxattr(io_ctx, *obj_name, attr_name, bl, use_striper);
if (ret < 0) {
- cerr << "error getting xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error getting xattr " << pool_name << "/" << prettify(*obj_name) << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
else
string s(bl.c_str(), bl.length());
cout << s;
} else if (strcmp(nargs[0], "rmxattr") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
- string attr_name(nargs[2]);
-
- ret = detail::rmxattr(io_ctx, oid, attr_name, use_striper);
+ string attr_name(nargs[obj_name ? 1 : 2]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
+ ret = detail::rmxattr(io_ctx, *obj_name, attr_name, use_striper);
if (ret < 0) {
- cerr << "error removing xattr " << pool_name << "/" << oid << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error removing xattr " << pool_name << "/" << prettify(*obj_name) << "/" << attr_name << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
} else if (strcmp(nargs[0], "listxattr") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
-
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
bufferlist bl;
map<std::string, bufferlist> attrset;
- ret = detail::getxattrs(io_ctx, oid, attrset, use_striper);
+ ret = detail::getxattrs(io_ctx, *obj_name, attrset, use_striper);
if (ret < 0) {
- cerr << "error getting xattr set " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error getting xattr set " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
cout << iter->first << std::endl;
}
} else if (strcmp(nargs[0], "getomapheader") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
-
- string oid(nargs[1]);
string outfile;
- if (nargs.size() >= 3) {
- outfile = nargs[2];
+ if (nargs.size() >= (obj_name ? 2 : 3)) {
+ outfile = nargs[obj_name ? 1 : 2];
+ }
+ if (!obj_name) {
+ obj_name = nargs[1];
}
-
bufferlist header;
- ret = io_ctx.omap_get_header(oid, &header);
+ ret = io_ctx.omap_get_header(*obj_name, &header);
if (ret < 0) {
- cerr << "error getting omap header " << pool_name << "/" << oid
+ cerr << "error getting omap header " << pool_name << "/" << prettify(*obj_name)
<< ": " << cpp_strerror(ret) << std::endl;
return 1;
} else {
ret = 0;
}
} else if (strcmp(nargs[0], "setomapheader") == 0) {
- if (!pool_name || nargs.size() < 3) {
+ if (!pool_name || nargs.size() < (obj_name ? 2 : 3)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
- string val(nargs[2]);
-
bufferlist bl;
- bl.append(val);
-
- ret = io_ctx.omap_set_header(oid, bl);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ bl.append(nargs[2]); // val
+ } else {
+ bl.append(nargs[1]); // val
+ }
+ ret = io_ctx.omap_set_header(*obj_name, bl);
if (ret < 0) {
- cerr << "error setting omap value " << pool_name << "/" << oid
+ cerr << "error setting omap value " << pool_name << "/" << prettify(*obj_name)
<< ": " << cpp_strerror(ret) << std::endl;
return 1;
} else {
ret = 0;
}
} else if (strcmp(nargs[0], "setomapval") == 0) {
- uint32_t min_args = (omap_key_valid ? 2 : 3);
+ uint32_t min_args = (omap_key ? 2 : 3);
if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) {
usage(cerr);
return 1;
}
string oid(nargs[1]);
- if (!omap_key_valid) {
+ if (!omap_key) {
omap_key = nargs[2];
- omap_key_pretty = omap_key;
}
bufferlist bl;
- if (nargs.size() > min_args) {
+ if (!input_file.empty()) {
+ string err;
+ ret = bl.read_file(input_file.c_str(), &err);
+ if (ret < 0) {
+ cerr << "error reading file " << input_file.c_str() << ": " << err << std::endl;
+ return 1;
+ }
+ } else if (nargs.size() > min_args) {
string val(nargs[min_args]);
bl.append(val);
} else {
}
map<string, bufferlist> values;
- values[omap_key] = bl;
+ values[*omap_key] = bl;
ret = io_ctx.omap_set(oid, values);
if (ret < 0) {
cerr << "error setting omap value " << pool_name << "/" << oid << "/"
- << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
+ << prettify(*omap_key) << ": " << cpp_strerror(ret) << std::endl;
return 1;
} else {
ret = 0;
}
} else if (strcmp(nargs[0], "getomapval") == 0) {
- uint32_t min_args = (omap_key_valid ? 2 : 3);
+ uint32_t min_args = (omap_key ? (obj_name ? 1 : 2)
+ : (obj_name ? 2 : 3));
if (!pool_name || nargs.size() < min_args || nargs.size() > min_args + 1) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
- if (!omap_key_valid) {
- omap_key = nargs[2];
- omap_key_pretty = omap_key;
+ if (!omap_key) {
+ omap_key = nargs[obj_name ? 1 : 2];
}
set<string> keys;
- keys.insert(omap_key);
+ keys.insert(*omap_key);
std::string outfile;
if (nargs.size() > min_args) {
outfile = nargs[min_args];
}
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
map<string, bufferlist> values;
- ret = io_ctx.omap_get_vals_by_keys(oid, keys, &values);
+ ret = io_ctx.omap_get_vals_by_keys(*obj_name, keys, &values);
if (ret < 0) {
- cerr << "error getting omap value " << pool_name << "/" << oid << "/"
- << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error getting omap value " << pool_name << "/" << prettify(*obj_name) << "/"
+ << prettify(*omap_key) << ": " << cpp_strerror(ret) << std::endl;
return 1;
} else {
ret = 0;
}
- if (values.size() && values.begin()->first == omap_key) {
+ if (values.size() && values.begin()->first == *omap_key) {
if (!outfile.empty()) {
cerr << "Writing to " << outfile << std::endl;
dump_data(outfile, values.begin()->second);
}
ret = 0;
} else {
- cout << "No such key: " << pool_name << "/" << oid << "/"
- << omap_key_pretty << std::endl;
+ cout << "No such key: " << pool_name << "/" << prettify(*obj_name) << "/"
+ << prettify(*omap_key) << std::endl;
return 1;
}
} else if (strcmp(nargs[0], "rmomapkey") == 0) {
- uint32_t num_args = (omap_key_valid ? 2 : 3);
+ uint32_t num_args = (omap_key ? (obj_name ? 1 : 2)
+ : (obj_name ? 2 : 3));
if (!pool_name || nargs.size() != num_args) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
- if (!omap_key_valid) {
- omap_key = nargs[2];
- omap_key_pretty = omap_key;
+ if (!omap_key) {
+ omap_key = nargs[obj_name ? 1 : 2];
+ }
+ if (!obj_name) {
+ obj_name = nargs[1];
}
set<string> keys;
- keys.insert(omap_key);
+ keys.insert(*omap_key);
- ret = io_ctx.omap_rm_keys(oid, keys);
+ ret = io_ctx.omap_rm_keys(*obj_name, keys);
if (ret < 0) {
- cerr << "error removing omap key " << pool_name << "/" << oid << "/"
- << omap_key_pretty << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error removing omap key " << pool_name << "/" << prettify(*obj_name) << "/"
+ << prettify(*omap_key) << ": " << cpp_strerror(ret) << std::endl;
return 1;
} else {
ret = 0;
}
} else if (strcmp(nargs[0], "clearomap") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
+ // strip nargs[0] which is "clearomap"
+ std::vector<std::string> oids(std::next(std::begin(nargs)),
+ std::end(nargs));
+ if (obj_name) {
+ oids.push_back(*obj_name);
+ }
- for (unsigned i=1; i < nargs.size(); i++){
- string oid(nargs[i]);
+ for (const auto& oid : oids) {
ret = io_ctx.omap_clear(oid);
if (ret < 0) {
- cerr << "error clearing omap keys " << pool_name << "/" << oid << "/"
+ cerr << "error clearing omap keys " << pool_name << "/" << prettify(*obj_name) << "/"
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
ret = 0;
} else if (strcmp(nargs[0], "listomapvals") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
-
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
string last_read = "";
do {
map<string, bufferlist> values;
- ret = io_ctx.omap_get_vals(oid, last_read, MAX_OMAP_BYTES_PER_REQUEST, &values);
+ ret = io_ctx.omap_get_vals(*obj_name, last_read, MAX_OMAP_BYTES_PER_REQUEST, &values);
if (ret < 0) {
- cerr << "error getting omap keys " << pool_name << "/" << oid << ": "
+ cerr << "error getting omap keys " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
ret = 0;
}
else if (strcmp(nargs[0], "cp") == 0) {
+ // XXX: binary names aren't supported for this operation
if (!pool_name) {
usage(cerr);
return 1;
return 1;
}
} else if (strcmp(nargs[0], "rm") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- vector<const char *>::iterator iter = nargs.begin();
- ++iter;
- for (; iter != nargs.end(); ++iter) {
- const string & oid = *iter;
-
- if (forcefull) {
- ret = detail::remove(io_ctx, oid, (CEPH_OSD_FLAG_FULL_FORCE |
- CEPH_OSD_FLAG_FULL_TRY), use_striper);
- } else {
- ret = detail::remove(io_ctx, oid, use_striper);
+ // strip nargs[0] which is "rm"
+ std::vector<std::string> oids(std::next(std::begin(nargs)),
+ std::end(nargs));
+ if (obj_name) {
+ oids.push_back(*obj_name);
}
+ for (const auto& oid : oids) {
+ if (forcefull) {
+ ret = detail::remove(io_ctx, oid, (CEPH_OSD_FLAG_FULL_FORCE |
+ CEPH_OSD_FLAG_FULL_TRY), use_striper);
+ } else {
+ ret = detail::remove(io_ctx, oid, use_striper);
+ }
- if (ret < 0) {
- string name = (nspace.size() ? nspace + "/" : "" ) + oid;
- cerr << "error removing " << pool_name << ">" << name << ": " << cpp_strerror(ret) << std::endl;
- return 1;
+ if (ret < 0) {
+ string name = (nspace.size() ? nspace + "/" : "" ) + prettify(oid);
+ cerr << "error removing " << pool_name << ">" << name << ": " << cpp_strerror(ret) << std::endl;
+ return 1;
}
}
}
else if (strcmp(nargs[0], "create") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
- ret = io_ctx.create(oid, true);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
+ ret = io_ctx.create(*obj_name, true);
if (ret < 0) {
- cerr << "error creating " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error creating " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
}
}
}
} else if (strcmp(nargs[0], "set-alloc-hint") == 0) {
- if (!pool_name || nargs.size() < 4) {
+ // cmd, [oid, ] obj_size, write_size
+ if (!pool_name || nargs.size() < (obj_name ? 3 : 4)) {
usage(cerr);
return 1;
}
string err;
- string oid(nargs[1]);
- uint64_t expected_object_size = strict_strtoll(nargs[2], 10, &err);
+ uint64_t expected_object_size = strict_strtoll(nargs[obj_name ? 1 : 2], 10, &err);
if (!err.empty()) {
cerr << "couldn't parse expected_object_size: " << err << std::endl;
usage(cerr);
return 1;
}
- uint64_t expected_write_size = strict_strtoll(nargs[3], 10, &err);
+ uint64_t expected_write_size = strict_strtoll(nargs[obj_name ? 2 : 3], 10, &err);
if (!err.empty()) {
cerr << "couldn't parse expected_write_size: " << err << std::endl;
usage(cerr);
return 1;
}
- ret = io_ctx.set_alloc_hint(oid, expected_object_size, expected_write_size);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
+ ret = io_ctx.set_alloc_hint(*obj_name, expected_object_size, expected_write_size);
if (ret < 0) {
- cerr << "error setting alloc-hint " << pool_name << "/" << oid << ": "
+ cerr << "error setting alloc-hint " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
lg.run();
lg.cleanup();
} else if (strcmp(nargs[0], "listomapkeys") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
-
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
string last_read;
bool more = true;
do {
set<string> out_keys;
- ret = io_ctx.omap_get_keys2(nargs[1], last_read, MAX_OMAP_BYTES_PER_REQUEST, &out_keys, &more);
+ ret = io_ctx.omap_get_keys2(*obj_name, last_read, MAX_OMAP_BYTES_PER_REQUEST, &out_keys, &more);
if (ret < 0) {
cerr << "error getting omap key set " << pool_name << "/"
- << nargs[1] << ": " << cpp_strerror(ret) << std::endl;
+ << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
cout << "watcher=" << i->addr << " client." << i->watcher_id << " cookie=" << i->cookie << std::endl;
}
} else if (strcmp(nargs[0], "listsnaps") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
- string oid(nargs[1]);
snap_set_t ls;
-
io_ctx.snap_set_read(LIBRADOS_SNAP_DIR);
- ret = io_ctx.list_snaps(oid, &ls);
+ ret = io_ctx.list_snaps(*obj_name, &ls);
if (ret < 0) {
- cerr << "error listing snap shots " << pool_name << "/" << oid << ": " << cpp_strerror(ret) << std::endl;
+ cerr << "error listing snap shots " << pool_name << "/" << prettify(*obj_name) << ": " << cpp_strerror(ret) << std::endl;
return 1;
}
else
if (formatter) {
formatter->open_object_section("object");
- formatter->dump_string("name", oid);
+ formatter->dump_string("name", *obj_name);
formatter->open_array_section("clones");
} else {
- cout << oid << ":" << std::endl;
+ cout << prettify(*obj_name) << ":" << std::endl;
cout << "cloneid snaps size overlap" << std::endl;
}
}
ret = do_get_inconsistent_cmd<inconsistent_snapset_t>(nargs, rados, *formatter);
} else if (strcmp(nargs[0], "cache-flush") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
if (with_clones) {
snap_set_t ls;
io_ctx.snap_set_read(LIBRADOS_SNAP_DIR);
- ret = io_ctx.list_snaps(oid, &ls);
+ ret = io_ctx.list_snaps(*obj_name, &ls);
if (ret < 0) {
- cerr << "error listing snapshots " << pool_name << "/" << oid << ": "
+ cerr << "error listing snapshots " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
if (snapid != CEPH_NOSNAP && ci->cloneid > snapid)
break;
io_ctx.snap_set_read(ci->cloneid);
- ret = do_cache_flush(io_ctx, oid);
+ ret = do_cache_flush(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
} else {
- ret = do_cache_flush(io_ctx, oid);
+ ret = do_cache_flush(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
} else if (strcmp(nargs[0], "cache-try-flush") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
if (with_clones) {
snap_set_t ls;
io_ctx.snap_set_read(LIBRADOS_SNAP_DIR);
- ret = io_ctx.list_snaps(oid, &ls);
+ ret = io_ctx.list_snaps(*obj_name, &ls);
if (ret < 0) {
- cerr << "error listing snapshots " << pool_name << "/" << oid << ": "
+ cerr << "error listing snapshots " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
if (snapid != CEPH_NOSNAP && ci->cloneid > snapid)
break;
io_ctx.snap_set_read(ci->cloneid);
- ret = do_cache_try_flush(io_ctx, oid);
+ ret = do_cache_try_flush(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
} else {
- ret = do_cache_try_flush(io_ctx, oid);
+ ret = do_cache_try_flush(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
} else if (strcmp(nargs[0], "cache-evict") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
if (with_clones) {
snap_set_t ls;
io_ctx.snap_set_read(LIBRADOS_SNAP_DIR);
- ret = io_ctx.list_snaps(oid, &ls);
+ ret = io_ctx.list_snaps(*obj_name, &ls);
if (ret < 0) {
- cerr << "error listing snapshots " << pool_name << "/" << oid << ": "
+ cerr << "error listing snapshots " << pool_name << "/" << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
if (snapid != CEPH_NOSNAP && ci->cloneid > snapid)
break;
io_ctx.snap_set_read(ci->cloneid);
- ret = do_cache_evict(io_ctx, oid);
+ ret = do_cache_evict(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
}
} else {
- ret = do_cache_evict(io_ctx, oid);
+ ret = do_cache_evict(io_ctx, *obj_name);
if (ret < 0) {
- cerr << "error from cache-flush " << oid << ": "
+ cerr << "error from cache-flush " << prettify(*obj_name) << ": "
<< cpp_strerror(ret) << std::endl;
return 1;
}
IoCtx target_ctx;
ret = rados.ioctx_create(target, target_ctx);
- ObjectWriteOperation op;
- if (with_reference) {
- op.set_chunk(offset, length, target_ctx, tgt_oid, tgt_offset, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
- } else {
- op.set_chunk(offset, length, target_ctx, tgt_oid, tgt_offset);
- }
- ret = io_ctx.operate(nargs[1], &op);
+ ObjectReadOperation op;
+ op.set_chunk(offset, length, target_ctx, tgt_oid, tgt_offset, CEPH_OSD_OP_FLAG_WITH_REFERENCE);
+ ret = io_ctx.operate(nargs[1], &op, NULL);
if (ret < 0) {
cerr << "error set-chunk " << pool_name << "/" << nargs[1] << " " << " offset " << offset
<< " length " << length << " target_pool " << target
return 1;
}
} else if (strcmp(nargs[0], "tier-promote") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
-
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
ObjectWriteOperation op;
op.tier_promote();
- ret = io_ctx.operate(oid, &op);
+ ret = io_ctx.operate(*obj_name, &op);
if (ret < 0) {
- cerr << "error tier-promote " << pool_name << "/" << oid << " : "
+ cerr << "error tier-promote " << pool_name << "/" << prettify(*obj_name) << " : "
<< cpp_strerror(ret) << std::endl;
return 1;
}
} else if (strcmp(nargs[0], "unset-manifest") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
-
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
ObjectWriteOperation op;
op.unset_manifest();
- ret = io_ctx.operate(oid, &op);
+ ret = io_ctx.operate(*obj_name, &op);
if (ret < 0) {
- cerr << "error unset-manifest " << pool_name << "/" << oid << " : "
+ cerr << "error unset-manifest " << pool_name << "/" << prettify(*obj_name) << " : "
<< cpp_strerror(ret) << std::endl;
return 1;
}
} else if (strcmp(nargs[0], "tier-flush") == 0) {
- if (!pool_name || nargs.size() < 2) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
usage(cerr);
return 1;
}
- string oid(nargs[1]);
-
- ObjectWriteOperation op;
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
+ ObjectReadOperation op;
op.tier_flush();
- ret = io_ctx.operate(oid, &op);
+ librados::AioCompletion *completion =
+ librados::Rados::aio_create_completion();
+ io_ctx.aio_operate(*obj_name, completion, &op,
+ librados::OPERATION_IGNORE_CACHE |
+ librados::OPERATION_IGNORE_OVERLAY,
+ NULL);
+ completion->wait_for_complete();
+ ret = completion->get_return_value();
+ completion->release();
+ if (ret < 0) {
+ cerr << "error tier-flush " << pool_name << "/" << prettify(*obj_name) << " : "
+ << cpp_strerror(ret) << std::endl;
+ return 1;
+ }
+ } else if (strcmp(nargs[0], "tier-evict") == 0) {
+ if (!pool_name || (nargs.size() < 2 && !obj_name)) {
+ usage(cerr);
+ return 1;
+ }
+ if (!obj_name) {
+ obj_name = nargs[1];
+ }
+ ObjectReadOperation op;
+ op.tier_evict();
+ librados::AioCompletion *completion =
+ librados::Rados::aio_create_completion();
+ io_ctx.aio_operate(*obj_name, completion, &op,
+ librados::OPERATION_IGNORE_CACHE |
+ librados::OPERATION_IGNORE_OVERLAY,
+ NULL);
+ completion->wait_for_complete();
+ ret = completion->get_return_value();
+ completion->release();
if (ret < 0) {
- cerr << "error tier-flush " << pool_name << "/" << oid << " : "
+ cerr << "error tier-evict " << pool_name << "/" << prettify(*obj_name) << " : "
<< cpp_strerror(ret) << std::endl;
return 1;
}
if (nargs.size() < 2 || std::string(nargs[1]) == "-") {
file_fd = STDOUT_FILENO;
} else {
- file_fd = open(nargs[1], O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ file_fd = open(nargs[1], O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
if (file_fd < 0) {
cerr << "Error opening '" << nargs[1] << "': "
<< cpp_strerror(file_fd) << std::endl;
if (filename == "-") {
file_fd = STDIN_FILENO;
} else {
- file_fd = open(filename.c_str(), O_RDONLY);
+ file_fd = open(filename.c_str(), O_RDONLY|O_BINARY);
if (file_fd < 0) {
cerr << "Error opening '" << filename << "': "
<< cpp_strerror(file_fd) << std::endl;
opts["with-clones"] = "true";
} else if (ceph_argparse_witharg(args, i, &val, "--omap-key-file", (char*)NULL)) {
opts["omap-key-file"] = val;
+ } else if (ceph_argparse_witharg(args, i, &val, "--obj-name-file", (char*)NULL)) {
+ opts["obj-name-file"] = val;
} else if (ceph_argparse_flag(args, i, "--with-reference", (char*)NULL)) {
opts["with-reference"] = "true";
} else if (ceph_argparse_witharg(args, i, &val, "--pgid", (char*)NULL)) {
opts["pgid"] = val;
+ } else if (ceph_argparse_witharg(args, i, &val, "--input-file", (char*)NULL)) {
+ opts["input_file"] = val;
} else {
if (val[0] == '-')
usage_exit();