~ubuntu-branches/ubuntu/quantal/ceph/quantal

« back to all changes in this revision

Viewing changes to src/rados.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-08-27 08:23:21 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120827082321-2cfej6ddvk63vsqq
Tags: upstream-0.48.1
ImportĀ upstreamĀ versionĀ 0.48.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
  out <<                                        \
53
53
"usage: rados [options] [commands]\n"
54
54
"POOL COMMANDS\n"
55
 
"   lspools                         list pools\n"
 
55
"   lspools                          list pools\n"
56
56
"   mkpool <pool-name> [123[ 4]]     create pool <pool-name>'\n"
57
57
"                                    [with auid 123[and using crush rule 4]]\n"
 
58
"   cppool <pool-name> <dest-pool>   copy content of a pool\n"
58
59
"   rmpool <pool-name>               remove pool <pool-name>'\n"
59
 
"   mkpool <pool-name>               create the pool <pool-name>\n"
60
 
"   df                              show per-pool and total usage\n"
 
60
"   df                               show per-pool and total usage\n"
61
61
"   ls                               list objects in pool\n\n"
62
62
"   chown 123                        change the pool owner to auid 123\n"
63
63
"\n"
66
66
"   put <obj-name> [infile]          write object\n"
67
67
"   create <obj-name> [category]     create object\n"
68
68
"   rm <obj-name>                    remove object\n"
 
69
"   cp <obj-name> [target-obj]       copy object\n"
69
70
"   listxattr <obj-name>\n"
70
71
"   getxattr <obj-name> attr\n"
71
72
"   setxattr <obj-name> attr val\n"
101
102
STR(DEFAULT_NUM_RADOS_WORKER_THREADS) ")\n"
102
103
"\n"
103
104
"GLOBAL OPTIONS:\n"
104
 
"   --object_locator object_locator\n"
 
105
"   --object-locator object_locator\n"
105
106
"        set object_locator for operation"
 
107
"   --target-locator object_locator\n"
 
108
"        set object_locator for operation target"
106
109
"   -p pool\n"
107
110
"   --pool=pool\n"
108
111
"        select given pool by name\n"
 
112
"   --target-pool=pool\n"
 
113
"        select target pool by name\n"
109
114
"   -b op_size\n"
110
115
"        set the size of write ops for put or benchmarking"
111
116
"   -s name\n"
160
165
  return 0;
161
166
}
162
167
 
 
168
static int do_copy(IoCtx& io_ctx, const char *objname, IoCtx& target_ctx, const char *target_obj)
 
169
{
 
170
  string oid(objname);
 
171
  bufferlist outdata;
 
172
  librados::ObjectReadOperation read_op;
 
173
  string start_after;
 
174
 
 
175
#define COPY_CHUNK_SIZE (4 * 1024 * 1024)
 
176
  read_op.read(0, COPY_CHUNK_SIZE, &outdata, NULL);
 
177
 
 
178
  map<std::string, bufferlist> attrset;
 
179
  read_op.getxattrs(&attrset, NULL);
 
180
 
 
181
  bufferlist omap_header;
 
182
  read_op.omap_get_header(&omap_header, NULL);
 
183
 
 
184
#define OMAP_CHUNK 1000
 
185
  map<string, bufferlist> omap;
 
186
  read_op.omap_get_vals(start_after, OMAP_CHUNK, &omap, NULL);
 
187
 
 
188
  bufferlist opbl;
 
189
  int ret = io_ctx.operate(oid, &read_op, &opbl);
 
190
  if (ret < 0) {
 
191
    return ret;
 
192
  }
 
193
 
 
194
  librados::ObjectWriteOperation write_op;
 
195
  string target_oid(target_obj);
 
196
 
 
197
  /* reset dest if exists */
 
198
  write_op.create(false);
 
199
  write_op.remove();
 
200
 
 
201
  write_op.write_full(outdata);
 
202
  write_op.omap_set_header(omap_header);
 
203
 
 
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);
 
207
  }
 
208
  if (omap.size()) {
 
209
    write_op.omap_set(omap);
 
210
  }
 
211
  ret = target_ctx.operate(target_oid, &write_op);
 
212
  if (ret < 0) {
 
213
    return ret;
 
214
  }
 
215
 
 
216
  uint64_t off = 0;
 
217
 
 
218
  while (outdata.length() == COPY_CHUNK_SIZE) {
 
219
    off += outdata.length();
 
220
    outdata.clear();
 
221
    ret = io_ctx.read(oid, outdata, COPY_CHUNK_SIZE, off); 
 
222
    if (ret < 0)
 
223
      goto err;
 
224
 
 
225
    ret = target_ctx.write(target_oid, outdata, outdata.length(), off);
 
226
    if (ret < 0)
 
227
      goto err;
 
228
  }
 
229
 
 
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();
 
234
    --iter;
 
235
    start_after = iter->first;
 
236
 
 
237
    omap.clear();
 
238
    ret = io_ctx.omap_get_vals(oid, start_after, OMAP_CHUNK, &omap);
 
239
    if (ret < 0)
 
240
      goto err;
 
241
 
 
242
    if (!omap.size())
 
243
      break;
 
244
 
 
245
    ret = target_ctx.omap_set(target_oid, omap);
 
246
    if (ret < 0)
 
247
      goto err;
 
248
  }
 
249
 
 
250
  return 0;
 
251
 
 
252
err:
 
253
  target_ctx.remove(target_oid);
 
254
  return ret;
 
255
}
 
256
 
 
257
static int do_copy_pool(Rados& rados, const char *src_pool, const char *target_pool)
 
258
{
 
259
  IoCtx src_ctx, target_ctx;
 
260
  int ret = rados.ioctx_create(src_pool, src_ctx);
 
261
  if (ret < 0) {
 
262
    cerr << "cannot open source pool: " << src_pool << std::endl;
 
263
    return ret;
 
264
  }
 
265
  ret = rados.ioctx_create(target_pool, target_ctx);
 
266
  if (ret < 0) {
 
267
    cerr << "cannot open target pool: " << target_pool << std::endl;
 
268
    return ret;
 
269
  }
 
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;
 
278
    else
 
279
      cout << src_pool << ":" << oid << " => "
 
280
           << target_pool << ":" << oid << std::endl;
 
281
 
 
282
 
 
283
    target_ctx.locator_set_key(locator);
 
284
    ret = do_copy(src_ctx, oid.c_str(), target_ctx, oid.c_str());
 
285
    if (ret < 0) {
 
286
      char buf[64];
 
287
      cerr << "error copying object: " << strerror_r(errno, buf, sizeof(buf)) << std::endl;
 
288
      return ret;
 
289
    }
 
290
  }
 
291
 
 
292
  return 0;
 
293
}
 
294
 
163
295
static int do_put(IoCtx& io_ctx, const char *objname, const char *infile, int op_size, bool check_stdio)
164
296
{
165
297
  string oid(objname);
658
790
  int ret;
659
791
  bool create_pool = false;
660
792
  const char *pool_name = NULL;
661
 
  string oloc;
 
793
  const char *target_pool_name = NULL;
 
794
  string oloc, target_oloc;
662
795
  int concurrent_ios = 16;
663
796
  int op_size = 1 << 22;
664
797
  const char *snapname = NULL;
690
823
  if (i != opts.end()) {
691
824
    pool_name = i->second.c_str();
692
825
  }
 
826
  i = opts.find("target_pool");
 
827
  if (i != opts.end()) {
 
828
    target_pool_name = i->second.c_str();
 
829
  }
693
830
  i = opts.find("object_locator");
694
831
  if (i != opts.end()) {
695
832
    oloc = i->second;
696
833
  }
 
834
  i = opts.find("target_locator");
 
835
  if (i != opts.end()) {
 
836
    target_oloc = i->second;
 
837
  }
697
838
  i = opts.find("category");
698
839
  if (i != opts.end()) {
699
840
    category = i->second;
1234
1375
    } while (ret == MAX_READ);
1235
1376
    ret = 0;
1236
1377
  }
 
1378
  else if (strcmp(nargs[0], "cp") == 0) {
 
1379
    if (!pool_name)
 
1380
      usage_exit();
 
1381
 
 
1382
    if (nargs.size() < 2 || nargs.size() > 3)
 
1383
      usage_exit();
 
1384
 
 
1385
    const char *target = target_pool_name;
 
1386
    if (!target)
 
1387
      target = pool_name;
 
1388
 
 
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;
 
1393
        return 1;
 
1394
      }
 
1395
      target_obj = nargs[1];
 
1396
    } else {
 
1397
      target_obj = nargs[2];
 
1398
    }
 
1399
 
 
1400
    // open io context.
 
1401
    IoCtx target_ctx;
 
1402
    ret = rados.ioctx_create(target, target_ctx);
 
1403
    if (ret < 0) {
 
1404
      cerr << "error opening target pool " << target << ": "
 
1405
           << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
 
1406
      return 1;
 
1407
    }
 
1408
    if (target_oloc.size()) {
 
1409
      target_ctx.locator_set_key(target_oloc);
 
1410
    }
 
1411
 
 
1412
    ret = do_copy(io_ctx, nargs[1], target_ctx, target_obj);
 
1413
    if (ret < 0) {
 
1414
      cerr << "error copying " << pool_name << "/" << nargs[1] << " => " << target << "/" << target_obj << ": " << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
 
1415
      return 1;
 
1416
    }
 
1417
  }
1237
1418
  else if (strcmp(nargs[0], "rm") == 0) {
1238
1419
    if (!pool_name || nargs.size() < 2)
1239
1420
      usage_exit();
1323
1504
    }
1324
1505
    cout << "successfully created pool " << nargs[1] << std::endl;
1325
1506
  }
 
1507
  else if (strcmp(nargs[0], "cppool") == 0) {
 
1508
    if (nargs.size() != 3)
 
1509
      usage_exit();
 
1510
    const char *src_pool = nargs[1];
 
1511
    const char *target_pool = nargs[2];
 
1512
 
 
1513
    if (strcmp(src_pool, target_pool) == 0) {
 
1514
      cerr << "cannot copy pool into itself" << std::endl;
 
1515
      return 1;
 
1516
    }
 
1517
 
 
1518
    ret = do_copy_pool(rados, src_pool, target_pool);
 
1519
    if (ret < 0) {
 
1520
      cerr << "error copying pool " << src_pool << " => " << target_pool << ": "
 
1521
           << strerror_r(-ret, buf, sizeof(buf)) << std::endl;
 
1522
      return 1;
 
1523
    }
 
1524
    cout << "successfully copied pool " << nargs[1] << std::endl;
 
1525
  }
1326
1526
  else if (strcmp(nargs[0], "rmpool") == 0) {
1327
1527
    if (nargs.size() < 2)
1328
1528
      usage_exit();
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)) {