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`
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
"\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"
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);
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);
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 {
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;
}
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;
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();
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;
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)) {