168
static int do_copy(IoCtx& io_ctx, const char *objname, IoCtx& target_ctx, const char *target_obj)
172
librados::ObjectReadOperation read_op;
175
#define COPY_CHUNK_SIZE (4 * 1024 * 1024)
176
read_op.read(0, COPY_CHUNK_SIZE, &outdata, NULL);
178
map<std::string, bufferlist> attrset;
179
read_op.getxattrs(&attrset, NULL);
181
bufferlist omap_header;
182
read_op.omap_get_header(&omap_header, NULL);
184
#define OMAP_CHUNK 1000
185
map<string, bufferlist> omap;
186
read_op.omap_get_vals(start_after, OMAP_CHUNK, &omap, NULL);
189
int ret = io_ctx.operate(oid, &read_op, &opbl);
194
librados::ObjectWriteOperation write_op;
195
string target_oid(target_obj);
197
/* reset dest if exists */
198
write_op.create(false);
201
write_op.write_full(outdata);
202
write_op.omap_set_header(omap_header);
204
map<std::string, bufferlist>::iterator iter;
205
for (iter = attrset.begin(); iter != attrset.end(); ++iter) {
206
write_op.setxattr(iter->first.c_str(), iter->second);
209
write_op.omap_set(omap);
211
ret = target_ctx.operate(target_oid, &write_op);
218
while (outdata.length() == COPY_CHUNK_SIZE) {
219
off += outdata.length();
221
ret = io_ctx.read(oid, outdata, COPY_CHUNK_SIZE, off);
225
ret = target_ctx.write(target_oid, outdata, outdata.length(), off);
230
/* iterate through source omap and update target. This is not atomic */
231
while (omap.size() == OMAP_CHUNK) {
232
/* now start_after should point at the last entry */
233
map<string, bufferlist>::iterator iter = omap.end();
235
start_after = iter->first;
238
ret = io_ctx.omap_get_vals(oid, start_after, OMAP_CHUNK, &omap);
245
ret = target_ctx.omap_set(target_oid, omap);
253
target_ctx.remove(target_oid);
257
static int do_copy_pool(Rados& rados, const char *src_pool, const char *target_pool)
259
IoCtx src_ctx, target_ctx;
260
int ret = rados.ioctx_create(src_pool, src_ctx);
262
cerr << "cannot open source pool: " << src_pool << std::endl;
265
ret = rados.ioctx_create(target_pool, target_ctx);
267
cerr << "cannot open target pool: " << target_pool << std::endl;
270
librados::ObjectIterator i = src_ctx.objects_begin();
271
librados::ObjectIterator i_end = src_ctx.objects_end();
272
for (; i != i_end; ++i) {
273
string oid = i->first;
274
string locator = i->second;
275
if (i->second.size())
276
cout << src_pool << ":" << oid << "(@" << locator << ")" << " => "
277
<< target_pool << ":" << oid << "(@" << locator << ")" << std::endl;
279
cout << src_pool << ":" << oid << " => "
280
<< target_pool << ":" << oid << std::endl;
283
target_ctx.locator_set_key(locator);
284
ret = do_copy(src_ctx, oid.c_str(), target_ctx, oid.c_str());
287
cerr << "error copying object: " << strerror_r(errno, buf, sizeof(buf)) << std::endl;
163
295
static int do_put(IoCtx& io_ctx, const char *objname, const char *infile, int op_size, bool check_stdio)
165
297
string oid(objname);
1234
1375
} while (ret == MAX_READ);
1378
else if (strcmp(nargs[0], "cp") == 0) {
1382
if (nargs.size() < 2 || nargs.size() > 3)
1385
const char *target = target_pool_name;
1389
const char *target_obj;
1390
if (nargs.size() < 3) {
1391
if (strcmp(target, pool_name) == 0) {
1392
cerr << "cannot copy object into itself" << std::endl;
1395
target_obj = nargs[1];
1397
target_obj = nargs[2];
1402
ret = rados.ioctx_create(target, target_ctx);
1404
cerr << "error opening target pool " << target << ": "
1405
<< strerror_r(-ret, buf, sizeof(buf)) << std::endl;
1408
if (target_oloc.size()) {
1409
target_ctx.locator_set_key(target_oloc);
1412
ret = do_copy(io_ctx, nargs[1], target_ctx, target_obj);
1414
cerr << "error copying " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
1237
1418
else if (strcmp(nargs[0], "rm") == 0) {
1238
1419
if (!pool_name || nargs.size() < 2)
1324
1505
cout << "successfully created pool " << nargs[1] << std::endl;
1507
else if (strcmp(nargs[0], "cppool") == 0) {
1508
if (nargs.size() != 3)
1510
const char *src_pool = nargs[1];
1511
const char *target_pool = nargs[2];
1513
if (strcmp(src_pool, target_pool) == 0) {
1514
cerr << "cannot copy pool into itself" << std::endl;
1518
ret = do_copy_pool(rados, src_pool, target_pool);
1520
cerr << "error copying pool " << src_pool << " => " << target_pool << ": "
1521
<< strerror_r(-ret, buf, sizeof(buf)) << std::endl;
1524
cout << "successfully copied pool " << nargs[1] << std::endl;
1326
1526
else if (strcmp(nargs[0], "rmpool") == 0) {
1327
1527
if (nargs.size() < 2)
1545
1745
opts["show-time"] = "true";
1546
1746
} else if (ceph_argparse_witharg(args, i, &val, "-p", "--pool", (char*)NULL)) {
1547
1747
opts["pool"] = val;
1748
} else if (ceph_argparse_witharg(args, i, &val, "--target-pool", (char*)NULL)) {
1749
opts["target_pool"] = val;
1548
1750
} else if (ceph_argparse_witharg(args, i, &val, "--object-locator" , (char *)NULL)) {
1549
1751
opts["object_locator"] = val;
1752
} else if (ceph_argparse_witharg(args, i, &val, "--target-locator" , (char *)NULL)) {
1753
opts["target_locator"] = val;
1550
1754
} else if (ceph_argparse_witharg(args, i, &val, "--category", (char*)NULL)) {
1551
1755
opts["category"] = val;
1552
1756
} else if (ceph_argparse_witharg(args, i, &val, "-t", "--concurrent-ios", (char*)NULL)) {