From: Tomy Cheru Date: Fri, 9 Sep 2016 14:54:02 +0000 (+0530) Subject: tools/rados: Added append functionality to rados tool. X-Git-Tag: v11.1.0~525^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cb919cae34ba83b800b13ee5efcd91d28a5ac65f;p=ceph.git tools/rados: Added append functionality to rados tool. Signed-off-by: Tomy Cheru --- diff --git a/doc/man/8/rados.rst b/doc/man/8/rados.rst index 2243a5e79004..23ebb8a8ebc2 100644 --- a/doc/man/8/rados.rst +++ b/doc/man/8/rados.rst @@ -55,12 +55,12 @@ Options .. option:: -b block_size - Set the block size for put/get ops and for write benchmarking. + Set the block size for put/get/append ops and for write benchmarking. .. option:: --striper Uses the striping API of rados rather than the default one. - Available for stat, get, put, truncate, rm, ls and all xattr related operation + Available for stat, get, put, append, truncate, rm, ls and all xattr related operation Global commands @@ -89,6 +89,9 @@ Pool specific commands :command:`put` *name* *infile* Write object name to the cluster with contents from infile. +:command:`append` *name* *infile* + Append object name to the cluster with contents from infile. + :command:`rm` *name* Remove object name. diff --git a/qa/workunits/rados/test_rados_tool.sh b/qa/workunits/rados/test_rados_tool.sh index 56092ed7a35f..08306f6fbcd0 100755 --- a/qa/workunits/rados/test_rados_tool.sh +++ b/qa/workunits/rados/test_rados_tool.sh @@ -427,11 +427,113 @@ test_cleanup() { $RADOS_TOOL rmpool $p $p --yes-i-really-really-mean-it } +function test_append() +{ + # rados append test: + # replicated pool + ceph osd pool create rados_append 100 100 replicated + # create object + touch ./rados_append_null + rados -p rados_append append rados_append_obj ./rados_append_null + rados -p rados_append get rados_append_obj ./rados_append_0_out + orig_size=`ls -l ./rados_append_null | awk -F ' ' '{print $5}'` + rados -p rados_append get rados_append_obj ./rados_append_0_out + orig_size=`ls -l ./rados_append_null | awk -F ' ' '{print $5}'` + read_size=`ls -l ./rados_append_0_out | awk -F ' ' '{print $5}'` + if [ $orig_size -ne $read_size ]; + then + die "Create Failed!" + fi + + # append 4k, total size 4k + dd if=/dev/zero of=./rados_append_4k bs=4k count=1 + rados -p rados_append append rados_append_obj ./rados_append_4k + rados -p rados_append get rados_append_obj ./rados_append_4k_out + orig_size=`ls -l ./rados_append_4k | awk -F ' ' '{print $5}'` + read_size=`ls -l ./rados_append_4k_out | awk -F ' ' '{print $5}'` + if [ $orig_size -ne $read_size ]; + then + die "Append failed expecting $orig_size read $read_size" + fi + + # append 4k, total size 8k + rados -p rados_append append rados_append_obj ./rados_append_4k + rados -p rados_append get rados_append_obj ./rados_append_4k_out + read_size=`ls -l ./rados_append_4k_out | awk -F ' ' '{print $5}'` + rados -p rados_append get rados_append_obj ./rados_append_4k_out + read_size=`ls -l ./rados_append_4k_out | awk -F ' ' '{print $5}'` + if [ 8192 -ne $read_size ]; + then + die "Append failed expecting 8192 read $read_size" + fi + + # append 10M, total size 10493952 + dd if=/dev/zero of=./rados_append_10m bs=10M count=1 + rados -p rados_append append rados_append_obj ./rados_append_10m + rados -p rados_append get rados_append_obj ./rados_append_10m_out + read_size=`ls -l ./rados_append_10m_out | awk -F ' ' '{print $5}'` + if [ 10493952 -ne $read_size ]; + then + die "Append failed expecting 10493952 read $read_size" + fi + + # cleanup + ceph osd pool delete rados_append rados_append --yes-i-really-really-mean-it + + #erasure coded pool + ceph osd erasure-code-profile set myprofile k=2 m=1 ruleset-failure-domain=osd + ceph osd pool create rados_append 100 100 erasure myprofile + + # create object + rados -p rados_append append rados_append_obj ./rados_append_null + rados -p rados_append get rados_append_obj ./rados_append_0_out + orig_size=`ls -l ./rados_append_null | awk -F ' ' '{print $5}'` + read_size=`ls -l ./rados_append_0_out | awk -F ' ' '{print $5}'` + if [ $orig_size -ne $read_size ]; + then + die "Create Failed!" + fi + + # append 4k, total size 4k + rados -p rados_append append rados_append_obj ./rados_append_4k + rados -p rados_append get rados_append_obj ./rados_append_4k_out + orig_size=`ls -l ./rados_append_4k | awk -F ' ' '{print $5}'` + read_size=`ls -l ./rados_append_4k_out | awk -F ' ' '{print $5}'` + if [ $orig_size -ne $read_size ]; + then + die "Append failed expecting $orig_size read $read_size" + fi + + # append 4k, total size 8k + rados -p rados_append append rados_append_obj ./rados_append_4k + rados -p rados_append get rados_append_obj ./rados_append_4k_out + read_size=`ls -l ./rados_append_4k_out | awk -F ' ' '{print $5}'` + if [ 8192 -ne $read_size ]; + then + die "Append failed expecting 8192 read $read_size" + fi + + # append 10M, total size 10493952 + rados -p rados_append append rados_append_obj ./rados_append_10m + rados -p rados_append get rados_append_obj ./rados_append_10m_out + read_size=`ls -l ./rados_append_10m_out | awk -F ' ' '{print $5}'` + if [ 10493952 -ne $read_size ]; + then + die "Append failed expecting 10493952 read $read_size" + fi + + # cleanup + ceph osd pool delete rados_append rados_append --yes-i-really-really-mean-it + rm -rf ./rados_append_null ./rados_append_0_out + rm -rf ./rados_append_4k ./rados_append_4k_out ./rados_append_10m ./rados_append_10m_out +} + test_xattr test_omap test_rmobj test_ls test_cleanup +test_append echo "SUCCESS!" exit 0 diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index f3d3da4eaae4..f5b146b75bce 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -85,6 +85,7 @@ void usage(ostream& out) "OBJECT COMMANDS\n" " get [outfile] fetch object\n" " put [infile] write object\n" +" append [infile] append object\n" " truncate length truncate object\n" " create create object\n" " rm ...[--force-full] [force no matter full or not]remove object(s)\n" @@ -460,6 +461,46 @@ static int do_put(IoCtx& io_ctx, RadosStriper& striper, return ret; } +static int do_append(IoCtx& io_ctx, RadosStriper& striper, + const char *objname, const char *infile, int op_size, + 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); + if (fd < 0) { + cerr << "error reading input file " << infile << ": " << cpp_strerror(errno) << std::endl; + return 1; + } + int count = op_size; + while (count != 0) { + bufferlist indata; + count = indata.read_fd(fd, op_size); + if (count < 0) { + ret = -errno; + cerr << "error reading input file " << infile << ": " << cpp_strerror(ret) << std::endl; + goto out; + } + if (use_striper) { + ret = striper.append(oid, indata, count); + } else { + ret = io_ctx.append(oid, indata, count); + } + + if (ret < 0) { + goto out; + } + } + ret = 0; +out: + if (fd != STDOUT_FILENO) + VOID_TEMP_FAILURE_RETRY(close(fd)); + return ret; +} + class RadosWatchCtx : public librados::WatchCtx2 { IoCtx& ioctx; string name; @@ -2147,6 +2188,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, goto out; } } + else if (strcmp(nargs[0], "append") == 0) { + if (!pool_name || nargs.size() < 3) + usage_exit(); + ret = do_append(io_ctx, striper, nargs[1], nargs[2], op_size, use_striper); + if (ret < 0) { + cerr << "error appending " << pool_name << "/" << nargs[1] << ": " << cpp_strerror(ret) << std::endl; + goto out; + } + } else if (strcmp(nargs[0], "truncate") == 0) { if (!pool_name || nargs.size() < 3) usage_exit();