Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools/rados: add a parameter "--offset" to rados put command #12674

Merged
merged 1 commit into from Dec 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions qa/workunits/rados/test_rados_tool.sh
Expand Up @@ -170,6 +170,7 @@ for i in `seq 1 5`; do
rand_str=`dd if=/dev/urandom bs=4 count=1 | hexdump -x`
run_expect_succ "$RADOS_TOOL" -p "$POOL" setomapheader $objname "$rand_str"
run_expect_succ --tee "$fname.omap.header" "$RADOS_TOOL" -p "$POOL" getomapheader $objname

# a few random omap keys
for j in `seq 1 4`; do
rand_str=`dd if=/dev/urandom bs=4 count=1 | hexdump -x`
Expand Down Expand Up @@ -534,12 +535,42 @@ function test_append()
rm -rf ./rados_append_4k ./rados_append_4k_out ./rados_append_10m ./rados_append_10m_out
}

function test_put()
{
# rados put test:
cleanup

# create file in local fs
dd if=/dev/urandom of=rados_object_10k bs=1KB count=10

# test put command
$RADOS_TOOL -p $POOL put $OBJ ./rados_object_10k
$RADOS_TOOL -p $POOL get $OBJ ./rados_object_10k_out
cmp ./rados_object_10k ./rados_object_10k_out
cleanup

# test put command with offset 0
$RADOS_TOOL -p $POOL put $OBJ ./rados_object_10k --offset 0
$RADOS_TOOL -p $POOL get $OBJ ./rados_object_offset_0_out
cmp ./rados_object_10k ./rados_object_offset_0_out
cleanup

# test put command with offset 1000
$RADOS_TOOL -p $POOL put $OBJ ./rados_object_10k --offset 1000
$RADOS_TOOL -p $POOL get $OBJ ./rados_object_offset_1000_out
cmp ./rados_object_10k ./rados_object_offset_1000_out 0 1000
cleanup

rm -rf ./rados_object_10k ./rados_object_10k_out ./rados_object_offset_0_out ./rados_object_offset_1000_out
}

test_xattr
test_omap
test_rmobj
test_ls
test_cleanup
test_append
test_put

echo "SUCCESS!"
exit 0
32 changes: 27 additions & 5 deletions src/tools/rados/rados.cc
Expand Up @@ -85,7 +85,8 @@ void usage(ostream& out)
"\n"
"OBJECT COMMANDS\n"
" get <obj-name> [outfile] fetch object\n"
" put <obj-name> [infile] write object\n"
" put <obj-name> [infile] [--offset offset]\n"
" write object write object start offset(default:0)\n"
" append <obj-name> [infile] append object\n"
" truncate <obj-name> length truncate object\n"
" create <obj-name> create object\n"
Expand Down Expand Up @@ -396,7 +397,7 @@ static int do_copy_pool(Rados& rados, const char *src_pool, const char *target_p

static int do_put(IoCtx& io_ctx, RadosStriper& striper,
const char *objname, const char *infile, int op_size,
bool use_striper)
uint64_t obj_offset, bool use_striper)
{
string oid(objname);
bool stdio = (strcmp(infile, "-") == 0);
Expand All @@ -409,7 +410,7 @@ static int do_put(IoCtx& io_ctx, RadosStriper& striper,
return 1;
}
int count = op_size;
uint64_t offset = 0;
uint64_t offset = obj_offset;
while (count != 0) {
bufferlist indata;
count = indata.read_fd(fd, op_size);
Expand All @@ -418,8 +419,9 @@ static int do_put(IoCtx& io_ctx, RadosStriper& striper,
cerr << "error reading input file " << infile << ": " << cpp_strerror(ret) << std::endl;
goto out;
}

if (count == 0) {
if (!offset) { // in case we have to create an empty object
if (offset == obj_offset) { // in case we have to create an empty object & if obj_offset > 0 do a hole
if (use_striper) {
ret = striper.write_full(oid, indata); // indata is empty
} else {
Expand All @@ -428,6 +430,17 @@ static int do_put(IoCtx& io_ctx, RadosStriper& striper,
if (ret < 0) {
goto out;
}
if (offset) {
if (use_striper) {
ret = striper.trunc(oid, offset); // before truncate, object must be existed.
} else {
ret = io_ctx.trunc(oid, offset); // before truncate, object must be existed.
}

if (ret < 0) {
goto out;
}
}
}
continue;
}
Expand Down Expand Up @@ -1618,6 +1631,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
unsigned op_size = default_op_size;
unsigned object_size = 0;
unsigned max_objects = 0;
uint64_t obj_offset = 0;
bool block_size_specified = false;
int bench_write_dest = 0;
bool cleanup = true;
Expand Down Expand Up @@ -1717,6 +1731,12 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
return -EINVAL;
}
}
i = opts.find("offset");
if (i != opts.end()) {
if (rados_sistrtoll(i, &obj_offset)) {
return -EINVAL;
}
}
i = opts.find("snap");
if (i != opts.end()) {
snapname = i->second.c_str();
Expand Down Expand Up @@ -2236,7 +2256,7 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts,
else if (strcmp(nargs[0], "put") == 0) {
if (!pool_name || nargs.size() < 3)
usage_exit();
ret = do_put(io_ctx, striper, nargs[1], nargs[2], op_size, use_striper);
ret = do_put(io_ctx, striper, nargs[1], nargs[2], op_size, obj_offset, use_striper);
if (ret < 0) {
cerr << "error putting " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl;
goto out;
Expand Down Expand Up @@ -3616,6 +3636,8 @@ int main(int argc, const char **argv)
opts["object-size"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "--max-objects", (char*)NULL)) {
opts["max-objects"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "--offset", (char*)NULL)) {
opts["offset"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "-o", (char*)NULL)) {
opts["object-size"] = val;
} else if (ceph_argparse_witharg(args, i, &val, "-s", "--snap", (char*)NULL)) {
Expand Down