From fe3d3821cbdee6600af15c1d56f7366f6c39b593 Mon Sep 17 00:00:00 2001 From: liuchang0812 Date: Tue, 27 Dec 2016 10:42:38 +0800 Subject: [PATCH] tools/rados: add parameter offset for put cmd and test case for it add a parameter "--offset" for put command add a test case for rados put command Signed-off-by: liuchang0812 --- qa/workunits/rados/test_rados_tool.sh | 31 ++++++++++++++++++++++++++ src/tools/rados/rados.cc | 32 ++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/qa/workunits/rados/test_rados_tool.sh b/qa/workunits/rados/test_rados_tool.sh index c0b6d8ceecc83..59c1750bbc13a 100755 --- a/qa/workunits/rados/test_rados_tool.sh +++ b/qa/workunits/rados/test_rados_tool.sh @@ -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` @@ -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 diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index fe1212dba562f..6eb6405013fc8 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -85,7 +85,8 @@ void usage(ostream& out) "\n" "OBJECT COMMANDS\n" " get [outfile] fetch object\n" -" put [infile] write object\n" +" put [infile] [--offset offset]\n" +" write object write object start offset(default:0)\n" " append [infile] append object\n" " truncate length truncate object\n" " create create object\n" @@ -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); @@ -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); @@ -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 { @@ -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; } @@ -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; @@ -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(); @@ -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; @@ -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)) { -- 2.39.5