]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Merge branch 'wip-2923'
authorYehuda Sadeh <yehuda@inktank.com>
Sat, 15 Sep 2012 22:17:08 +0000 (15:17 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Sat, 15 Sep 2012 22:17:08 +0000 (15:17 -0700)
Conflicts:
src/rgw/rgw_admin.cc
src/rgw/rgw_log.cc
src/rgw/rgw_log.h
src/rgw/rgw_main.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
15 files changed:
1  2 
src/common/config_opts.h
src/rgw/rgw_admin.cc
src/rgw/rgw_common.h
src/rgw/rgw_gc.cc
src/rgw/rgw_log.cc
src/rgw/rgw_log.h
src/rgw/rgw_main.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_rest_swift.cc
src/test/cli/radosgw-admin/help.t

Simple merge
index fcbeed78f46839424072cb97f476461600ad9484,968f9d786d40084567071eb51c2985e0871899d8..837a9c289ed44871f8469bdc7dc5889e990f3783
@@@ -47,8 -48,10 +49,9 @@@ void _usage(
    cerr << "  bucket link                link bucket to specified user\n";
    cerr << "  bucket unlink              unlink bucket from specified user\n";
    cerr << "  bucket stats               returns bucket statistics\n";
 -  cerr << "  bucket info                show bucket information\n";
    cerr << "  bucket rm                  remove bucket\n";
    cerr << "  object rm                  remove object\n";
+   cerr << "  cluster info               show cluster params info\n";
    cerr << "  pool add                   add an existing pool for data placement\n";
    cerr << "  pool rm                    remove an existing pool from data placement set\n";
    cerr << "  pools list                 list placement active set\n";
@@@ -648,25 -652,15 +653,34 @@@ static int remove_bucket(rgw_bucket& bu
    return ret;
  }
  
 +void dump_usage_categories_info(Formatter *formatter, const rgw_usage_log_entry& entry, map<string, bool>& categories)
 +{
 +  formatter->open_array_section("categories");
 +  map<string, rgw_usage_data>::const_iterator uiter;
 +  for (uiter = entry.usage_map.begin(); uiter != entry.usage_map.end(); ++uiter) {
 +    if (categories.size() && !categories.count(uiter->first))
 +      continue;
 +    const rgw_usage_data& usage = uiter->second;
 +    formatter->open_object_section("entry");
 +    formatter->dump_string("category", uiter->first);
 +    formatter->dump_int("bytes_sent", usage.bytes_sent);
 +    formatter->dump_int("bytes_received", usage.bytes_received);
 +    formatter->dump_int("ops", usage.ops);
 +    formatter->dump_int("successful_ops", usage.successful_ops);
 +    formatter->close_section(); // entry
 +  }
 +  formatter->close_section(); // categories
 +}
 +
+ class StoreRef {
+   RGWRados *s;
+ public:
+   StoreRef(RGWRados *_s) : s(_s) {}
+   ~StoreRef() {
+     RGWStoreManager::close_storage(s);
+   }
+ };
  int main(int argc, char **argv) 
  {
    vector<const char*> args;
Simple merge
Simple merge
index bae74a9d127305718456df6b035114471229abaa,26f7af64c453d4dd9bf246ac79d564354c081ae4..5406a2c924b39bd7c25fe731d5b3577e2b91121b
@@@ -189,7 -184,7 +188,7 @@@ static void log_usage(struct req_state 
    usage_logger->insert(ts, entry);
  }
  
- int rgw_log_op(struct req_state *s, const string& op_name)
 -int rgw_log_op(RGWRados *store, struct req_state *s)
++int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name)
  {
    struct rgw_log_entry entry;
    string bucket_id;
index a653fbf1e3d84cea16b3c03d08a3111b041cff3d,e24a157639c3d4e79bc46d587476594663c393f9..f832c1cadebe147964f14d766401e82eb2fc485b
@@@ -117,10 -115,10 +115,10 @@@ struct rgw_intent_log_entry 
  };
  WRITE_CLASS_ENCODER(rgw_intent_log_entry)
  
- int rgw_log_op(struct req_state *s, const string& op_name);
- int rgw_log_intent(rgw_obj& obj, RGWIntentEvent intent, const utime_t& timestamp, bool utc);
- int rgw_log_intent(struct req_state *s, rgw_obj& obj, RGWIntentEvent intent);
- void rgw_log_usage_init(CephContext *cct);
 -int rgw_log_op(RGWRados *store, struct req_state *s);
++int rgw_log_op(RGWRados *store, struct req_state *s, const string& op_name);
+ int rgw_log_intent(RGWRados *store, rgw_obj& obj, RGWIntentEvent intent, const utime_t& timestamp, bool utc);
+ int rgw_log_intent(RGWRados *store, struct req_state *s, rgw_obj& obj, RGWIntentEvent intent);
+ void rgw_log_usage_init(CephContext *cct, RGWRados *store);
  void rgw_log_usage_finalize();
  
  #endif
index 93bae66fe2e963821b2a7c1c598d7d48bdc28eaf,2bfa9215e1a94b140125cd37f6fa05ba6c0beb68..5af00f8d3fd7a5ae738482cba5a4beddeb474da7
@@@ -318,18 -319,18 +319,18 @@@ void RGWProcess::handle_request(RGWRequ
    req->log(s, "executing");
    op->execute();
  done:
-   rgw_log_op(s, (op ? op->name() : "unknown"));
 -  rgw_log_op(store, s);
++  rgw_log_op(store, s, (op ? op->name() : "unknown"));
  
    int http_ret = s->err.http_ret;
  
    req->log_format(s, "http status=%d", http_ret);
  
    handler->put_op(op);
-   rgwstore->destroy_context(s->obj_ctx);
+   store->destroy_context(s->obj_ctx);
    FCGX_Finish_r(fcgx);
 -  delete req;
  
    dout(1) << "====== req done req=" << hex << req << dec << " http_status=" << http_ret << " ======" << dendl;
 +  delete req;
  }
  
  class C_InitTimeout : public Context {
index 2fcc6981c6aecef795be35fe97a0ec299b4fa486,9f33a4057d2c23cc7d96cd43e7c2010042711927..ce38c6c0365083fe15600934daf22f28753efa9e
@@@ -338,197 -315,6 +338,197 @@@ int RGWGetObj::verify_permission(
    return 0;
  }
  
-   void *obj_ctx = rgwstore->create_context(s);
 +
 +int RGWGetObj::read_user_manifest_part(rgw_bucket& bucket, RGWObjEnt& ent, RGWAccessControlPolicy *bucket_policy, off_t start_ofs, off_t end_ofs)
 +{
 +  ldout(s->cct, 0) << "user manifest obj=" << ent.name << dendl;
 +
 +  void *handle = NULL;
 +  off_t cur_ofs = start_ofs;
 +  off_t cur_end = end_ofs;
 +  utime_t start_time = s->time;
 +
 +  rgw_obj part(bucket, ent.name);
 +
 +  map<string, bufferlist> attrs;
 +
 +  uint64_t obj_size, read_size;
-   rgwstore->set_atomic(obj_ctx, part);
-   rgwstore->set_prefetch_data(obj_ctx, part);
-   ret = rgwstore->prepare_get_obj(obj_ctx, part, &cur_ofs, &cur_end, &attrs, NULL,
++  void *obj_ctx = store->create_context(s);
 +  RGWAccessControlPolicy obj_policy(s->cct);
 +
 +  ldout(s->cct, 20) << "reading obj=" << part << " ofs=" << cur_ofs << " end=" << cur_end << dendl;
 +
-     ret = rgwstore->get_obj(obj_ctx, &handle, part, bl, cur_ofs, cur_end);
++  store->set_atomic(obj_ctx, part);
++  store->set_prefetch_data(obj_ctx, part);
++  ret = store->prepare_get_obj(obj_ctx, part, &cur_ofs, &cur_end, &attrs, NULL,
 +                                  NULL, NULL, NULL, NULL, NULL, &obj_size, &handle, &s->err);
 +  if (ret < 0)
 +    goto done_err;
 +
 +  if (obj_size != ent.size) {
 +    // hmm.. something wrong, object not as expected, abort!
 +    ldout(s->cct, 0) << "ERROR: expected read size=" << read_size << ", actual read size=" << ent.size << dendl;
 +    ret = -EIO;
 +    goto done_err;
 +  }
 +
 +  ret = policy_from_attrset(s->cct, attrs, &obj_policy);
 +  if (ret < 0)
 +    goto done_err;
 +
 +  if (!verify_object_permission(s, bucket_policy, &obj_policy, RGW_PERM_READ)) {
 +    ret = -EPERM;
 +    goto done_err;
 +  }
 +
 +  perfcounter->inc(l_rgw_get_b, cur_end - cur_ofs);
 +  while (cur_ofs <= cur_end) {
 +    bufferlist bl;
 +    read_size = cur_end - cur_ofs + 1;
-   rgwstore->destroy_context(obj_ctx);
++    ret = store->get_obj(obj_ctx, &handle, part, bl, cur_ofs, cur_end);
 +    if (ret < 0)
 +      goto done_err;
 +
 +    len = bl.length();
 +    cur_ofs += len;
 +    ofs += len;
 +    ret = 0;
 +    perfcounter->finc(l_rgw_get_lat,
 +                      (ceph_clock_now(s->cct) - start_time));
 +    send_response(bl);
 +
 +    start_time = ceph_clock_now(s->cct);
 +  }
 +
-   rgwstore->finish_get_obj(&handle);
++  store->destroy_context(obj_ctx);
 +  obj_ctx = NULL;
 +
-     rgwstore->destroy_context(obj_ctx);
++  store->finish_get_obj(&handle);
 +
 +  return 0;
 +
 +done_err:
 +  if (obj_ctx)
-     int r = rgwstore->list_objects(bucket, MAX_LIST_OBJS, obj_prefix, delim, marker,
-                                    objs, common_prefixes,
-                                    true, no_ns, &is_truncated, NULL);
++    store->destroy_context(obj_ctx);
 +  return ret;
 +}
 +
 +int RGWGetObj::iterate_user_manifest_parts(rgw_bucket& bucket, string& obj_prefix, RGWAccessControlPolicy *bucket_policy,
 +                                           uint64_t *ptotal_len, bool read_data)
 +{
 +  uint64_t obj_ofs = 0, len_count = 0;
 +  bool found_start = false, found_end = false;
 +  string delim;
 +  string marker;
 +  bool is_truncated;
 +  string no_ns;
 +  map<string, bool> common_prefixes;
 +  vector<RGWObjEnt> objs;
 +
 +  utime_t start_time = ceph_clock_now(s->cct);
 +
 +  do {
 +#define MAX_LIST_OBJS 100
-     int r = rgwstore->get_bucket_info(NULL, bucket_name, bucket_info);
++    int r = store->list_objects(bucket, MAX_LIST_OBJS, obj_prefix, delim, marker,
++                                objs, common_prefixes,
++                                true, no_ns, &is_truncated, NULL);
 +    if (r < 0)
 +      return r;
 +
 +    vector<RGWObjEnt>::iterator viter;
 +
 +    for (viter = objs.begin(); viter != objs.end() && !found_end; ++viter) {
 +      RGWObjEnt& ent = *viter;
 +      uint64_t cur_total_len = obj_ofs;
 +      uint64_t start_ofs = 0, end_ofs = ent.size;
 +
 +      if (!found_start && cur_total_len + ent.size > (uint64_t)ofs) {
 +      start_ofs = ofs - obj_ofs;
 +      found_start = true;
 +      }
 +
 +      obj_ofs += ent.size;
 +
 +      if (!found_end && obj_ofs > (uint64_t)end) {
 +      end_ofs = end - cur_total_len + 1;
 +      found_end = true;
 +      }
 +
 +      perfcounter->finc(l_rgw_get_lat,
 +                       (ceph_clock_now(s->cct) - start_time));
 +
 +      if (found_start) {
 +        len_count += end_ofs - start_ofs;
 +
 +        if (read_data) {
 +          r = read_user_manifest_part(bucket, ent, bucket_policy, start_ofs, end_ofs);
 +          if (r < 0)
 +            return r;
 +        }
 +      }
 +      marker = ent.name;
 +
 +      start_time = ceph_clock_now(s->cct);
 +    }
 +  } while (is_truncated && !found_end);
 +
 +  if (ptotal_len)
 +    *ptotal_len = len_count;
 +
 +  return 0;
 +}
 +
 +int RGWGetObj::handle_user_manifest(const char *prefix)
 +{
 +  ldout(s->cct, 2) << "RGWGetObj::handle_user_manifest() prefix=" << prefix << dendl;
 +
 +  string prefix_str = prefix;
 +  int pos = prefix_str.find('/');
 +  if (pos < 0)
 +    return -EINVAL;
 +
 +  string bucket_name = prefix_str.substr(0, pos);
 +  string obj_prefix = prefix_str.substr(pos + 1);
 +
 +  rgw_bucket bucket;
 +
 +  RGWAccessControlPolicy _bucket_policy(s->cct);
 +  RGWAccessControlPolicy *bucket_policy;
 +
 +  if (bucket_name.compare(s->bucket.name) != 0) {
 +    RGWBucketInfo bucket_info;
-     r = read_policy(s, bucket_info, bucket_policy, bucket, no_obj);
++    int r = store->get_bucket_info(NULL, bucket_name, bucket_info);
 +    if (r < 0) {
 +      ldout(s->cct, 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
 +      return r;
 +    }
 +    bucket = bucket_info.bucket;
 +    string no_obj;
 +    bucket_policy = &_bucket_policy;
++    r = read_policy(store, s, bucket_info, bucket_policy, bucket, no_obj);
 +    if (r < 0) {
 +      ldout(s->cct, 0) << "failed to read bucket policy" << dendl;
 +      return r;
 +    }
 +  } else {
 +    bucket = s->bucket;
 +    bucket_policy = s->bucket_acl;
 +  }
 +
 +  /* dry run to find out total length */
 +  int r = iterate_user_manifest_parts(bucket, obj_prefix, bucket_policy, &total_len, false);
 +  if (r < 0)
 +    return r;
 +
 +  s->obj_size = total_len;
 +
 +  r = iterate_user_manifest_parts(bucket, obj_prefix, bucket_policy, NULL, true);
 +  if (r < 0)
 +    return r;
 +
 +  return 0;
 +}
 +
  void RGWGetObj::execute()
  {
    void *handle = NULL;
    if (ret < 0)
      goto done;
  
 -  ret = store->prepare_get_obj(s->obj_ctx, obj, &ofs, &end, &attrs, mod_ptr,
 -                                  unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &s->obj_size, &handle, &s->err);
 +  new_ofs = ofs;
 +  new_end = end;
 +
-   ret = rgwstore->prepare_get_obj(s->obj_ctx, obj, &new_ofs, &new_end, &attrs, mod_ptr,
-                                   unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &s->obj_size, &handle, &s->err);
++  ret = store->prepare_get_obj(s->obj_ctx, obj, &new_ofs, &new_end, &attrs, mod_ptr,
++                               unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &s->obj_size, &handle, &s->err);
    if (ret < 0)
      goto done;
  
@@@ -917,8 -685,8 +916,8 @@@ int RGWPutObjProcessor_Plain::handle_da
  
  int RGWPutObjProcessor_Plain::complete(string& etag, map<string, bufferlist>& attrs)
  {
-   int r = rgwstore->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs,
-                                  RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL, NULL);
+   int r = store->put_obj_meta(s->obj_ctx, obj, data.length(), NULL, attrs,
 -                                 RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL);
++                              RGW_OBJ_CATEGORY_MAIN, false, NULL, &data, NULL, NULL);
    return r;
  }
  
@@@ -1078,10 -846,10 +1077,10 @@@ int RGWPutObjProcessor_Atomic::complete
  
    manifest.obj_size = obj_len;
  
-   rgwstore->set_atomic(s->obj_ctx, head_obj);
+   store->set_atomic(s->obj_ctx, head_obj);
  
-   int r = rgwstore->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs,
-                                  RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest, NULL);
+   int r = store->put_obj_meta(s->obj_ctx, head_obj, obj_len, NULL, attrs,
 -                                 RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest);
++                              RGW_OBJ_CATEGORY_MAIN, false, NULL, &first_chunk, &manifest, NULL);
  
    return r;
  }
@@@ -1119,7 -887,7 +1118,7 @@@ int RGWPutObjProcessor_Multipart::prepa
  
  int RGWPutObjProcessor_Multipart::complete(string& etag, map<string, bufferlist>& attrs)
  {
-   int r = rgwstore->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
 -  int r = store->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL);
++  int r = store->put_obj_meta(s->obj_ctx, obj, s->obj_size, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
    if (r < 0)
      return r;
  
@@@ -1415,15 -1178,8 +1414,15 @@@ int RGWCopyObj::verify_permission(
  
    dest_bucket = dest_bucket_info.bucket;
  
-   rgwstore->set_atomic(s->obj_ctx, src_obj);
-   rgwstore->set_prefetch_data(s->obj_ctx, src_obj);
 +  rgw_obj src_obj(src_bucket, src_object);
-   rgwstore->set_atomic(s->obj_ctx, dest_obj);
++  store->set_atomic(s->obj_ctx, src_obj);
++  store->set_prefetch_data(s->obj_ctx, src_obj);
 +
 +  rgw_obj dest_obj(dest_bucket, dest_object);
++  store->set_atomic(s->obj_ctx, dest_obj);
 +
    /* check source object permissions */
-   ret = read_policy(s, src_bucket_info, &src_policy, src_bucket, src_object);
+   ret = read_policy(store, s, src_bucket_info, &src_policy, src_bucket, src_object);
    if (ret < 0)
      return ret;
  
@@@ -1672,7 -1428,7 +1671,7 @@@ void RGWInitMultipart::execute(
  
      obj.init_ns(s->bucket, tmp_obj_name, mp_ns);
      // the meta object will be indexed with 0 size, we c
-     ret = rgwstore->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL, NULL);
 -    ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL);
++    ret = store->put_obj_meta(s->obj_ctx, obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MULTIMETA, true, NULL, NULL, NULL, NULL);
    } while (ret == -EEXIST);
  done:
    send_response();
@@@ -1838,8 -1594,8 +1837,8 @@@ void RGWCompleteMultipart::execute(
    attrs[RGW_ATTR_ETAG] = etag_bl;
  
    target_obj.init(s->bucket, s->object_str);
-   rgwstore->set_atomic(s->obj_ctx, target_obj);
-   ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
+   store->set_atomic(s->obj_ctx, target_obj);
 -  ret = store->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL);
++  ret = store->put_obj_meta(s->obj_ctx, target_obj, 0, NULL, attrs, RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, NULL, NULL);
    if (ret < 0)
      goto done;
    
  
    manifest.obj_size = ofs;
  
-   rgwstore->set_atomic(s->obj_ctx, target_obj);
+   store->set_atomic(s->obj_ctx, target_obj);
  
-   ret = rgwstore->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs,
-                                RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest, NULL);
+   ret = store->put_obj_meta(s->obj_ctx, target_obj, ofs, NULL, attrs,
 -                               RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest);
++                            RGW_OBJ_CATEGORY_MAIN, false, NULL, NULL, &manifest, NULL);
    if (ret < 0)
      goto done;
  
Simple merge
index 4d45dbfbb03f12aa10b1377be5b0c6bc0b701b16,9a0d06b632df36682b6cdbc15f00efd1e58d22bd..f7eb81d2b1d22328187f23e8706897d60e13ce29
@@@ -1167,124 -1226,6 +1229,124 @@@ int RGWRados::copy_obj(void *ctx
    if (ret < 0)
      return ret;
  
-   ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest, &tag);
 +  if (replace_attrs) {
 +    attrset = attrs;
 +  }
 +
 +  RGWObjManifest manifest;
 +  RGWObjState *astate = NULL;
 +  RGWRadosCtx *rctx = (RGWRadosCtx *)ctx;
 +  ret = get_obj_state(rctx, src_obj, &astate);
 +  if (ret < 0)
 +    return ret;
 +
 +  vector<rgw_obj> ref_objs;
 +
 +  bool copy_data = !astate->has_manifest;
 +  bool copy_first = false;
 +  if (astate->has_manifest) {
 +    if (astate->manifest.objs.size() < 2) {
 +      copy_data = true;
 +    } else {
 +      map<uint64_t, RGWObjManifestPart>::iterator iter = astate->manifest.objs.begin();
 +      RGWObjManifestPart part = iter->second;
 +      if (part.loc == src_obj) {
 +      if (part.size > RGW_MAX_CHUNK_SIZE)  // should never happen
 +        copy_data = true;
 +      else
 +          copy_first = true;
 +      }
 +    }
 +  }
 +
 +  if (copy_data) { /* refcounting tail wouldn't work here, just copy the data */
 +    return copy_obj_data(ctx, handle, end, dest_obj, src_obj, mtime, attrset, category, err);
 +  }
 +
 +  map<uint64_t, RGWObjManifestPart>::iterator miter = astate->manifest.objs.begin();
 +
 +  if (copy_first) // we need to copy first chunk, not increase refcount
 +    ++miter;
 +
 +  RGWObjManifestPart *first_part = &miter->second;
 +  string oid, key;
 +  rgw_bucket bucket;
 +  get_obj_bucket_and_oid_key(first_part->loc, bucket, oid, key);
 +  librados::IoCtx io_ctx;
 +
 +  ret = open_bucket_ctx(bucket, io_ctx);
 +  if (ret < 0)
 +    return ret;
 +
 +  bufferlist first_chunk;
 +
 +  string tag;
 +  append_rand_alpha(cct, tag, tag, 32);
 +
 +  for (; miter != astate->manifest.objs.end(); ++miter) {
 +    RGWObjManifestPart& part = miter->second;
 +    ObjectWriteOperation op;
 +    manifest.objs[miter->first] = part;
 +    cls_refcount_get(op, tag, true);
 +
 +    get_obj_bucket_and_oid_key(part.loc, bucket, oid, key);
 +    io_ctx.locator_set_key(key);
 +
 +    ret = io_ctx.operate(oid, &op);
 +    if (ret < 0)
 +      goto done_ret;
 +
 +    ref_objs.push_back(part.loc);
 +  }
 +
 +  if (copy_first) {
 +    ret = get_obj(ctx, &handle, src_obj, first_chunk, 0, RGW_MAX_CHUNK_SIZE);
 +    if (ret < 0)
 +      goto done_ret;
 +
 +    first_part = &manifest.objs[0];
 +    first_part->loc = dest_obj;
 +    first_part->loc_ofs = 0;
 +    first_part->size = first_chunk.length();
 +  }
 +
 +  manifest.obj_size = total_len;
 +
++  ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest, &tag);
 +  if (mtime)
 +    obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL);
 +
 +  return 0;
 +
 +done_ret:
 +  vector<rgw_obj>::iterator riter;
 +
 +  /* rollback reference */
 +  for (riter = ref_objs.begin(); riter != ref_objs.end(); ++riter) {
 +    ObjectWriteOperation op;
 +    cls_refcount_put(op, tag, true);
 +
 +    get_obj_bucket_and_oid_key(*riter, bucket, oid, key);
 +    io_ctx.locator_set_key(key);
 +
 +    int r = io_ctx.operate(oid, &op);
 +    if (r < 0) {
 +      ldout(cct, 0) << "ERROR: cleanup after error failed to drop reference on obj=" << *riter << dendl;
 +    }
 +  }
 +  return ret;
 +}
 +
 +
 +int RGWRados::copy_obj_data(void *ctx,
 +             void *handle, off_t end,
 +               rgw_obj& dest_obj,
 +               rgw_obj& src_obj,
 +             time_t *mtime,
 +               map<string, bufferlist>& attrs,
 +               RGWObjCategory category,
 +               struct rgw_err *err)
 +{
    bufferlist first_chunk;
    RGWObjManifest manifest;
    RGWObjManifestPart *first_part;
    }
    manifest.obj_size = ofs;
  
-   ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest, NULL);
 -  if (replace_attrs) {
 -    attrset = attrs;
 -  }
 -
 -  ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest);
++  ret = put_obj_meta(ctx, dest_obj, end + 1, NULL, attrs, category, false, NULL, &first_chunk, &manifest, NULL);
    if (mtime)
      obj_stat(ctx, dest_obj, NULL, mtime, NULL, NULL);
  
  
    return ret;
  done_err:
-   rgwstore->delete_obj(ctx, shadow_obj);
 -  delete_obj(ctx, shadow_obj, false);
++  delete_obj(ctx, shadow_obj);
    finish_get_obj(&handle);
    return r;
  }
@@@ -1386,8 -1322,8 +1448,8 @@@ int RGWRados::delete_bucket(rgw_bucket
      }
    } while (is_truncated);
  
-   rgw_obj obj(rgw_root_bucket, bucket.name);
+   rgw_obj obj(params.domain_root, bucket.name);
 -  r = delete_obj(NULL, obj, true);
 +  r = delete_obj(NULL, obj);
    if (r < 0)
      return r;
  
@@@ -3266,7 -3179,7 +3328,7 @@@ int RGWRados::process_intent_log(rgw_bu
          complete = false;
          break;
        }
-       r = rgwstore->delete_obj(NULL, entry.obj);
 -      r = delete_obj(NULL, entry.obj, false);
++      r = delete_obj(NULL, entry.obj);
        if (r < 0 && r != -ENOENT) {
          cerr << "failed to remove obj: " << entry.obj << std::endl;
          complete = false;
index 7afd1e6af9c5c1139c5affbf33ef52d996f8db08,c8796edb7313a7eea6c1780ab9c159c9a124391a..ff6cde341a85049b58622b3ae5776223ada3ad3c
@@@ -293,10 -323,16 +323,17 @@@ protected
    librados::Rados *rados;
    librados::IoCtx gc_pool_ctx;        // .rgw.gc
  
+   bool pools_initialized;
  public:
-   RGWRados() : lock("rados_timer_lock"), timer(NULL), num_watchers(0), watchers(NULL), watch_handles(NULL),
+   RGWRados() : lock("rados_timer_lock"), timer(NULL), gc(NULL), use_gc_thread(false),
+                num_watchers(0), watchers(NULL), watch_handles(NULL),
 -               bucket_id_lock("rados_bucket_id"), max_bucket_id(0), rados(NULL),
 +               bucket_id_lock("rados_bucket_id"), max_bucket_id(0),
-              cct(NULL), rados(NULL) {}
++               cct(NULL), rados(NULL),
+                pools_initialized(false) {}
+   RGWRadosParams params;
    virtual ~RGWRados() {}
  
    void tick();
Simple merge
index 8b85505d6b805923c2d1f7dde83d4257e16115b1,bf41e99df5fd74836cebe8abd67fb48c7d5d9015..369e521c7b9fc8d04cfbbf446f4aad9a8c4dab4a
@@@ -15,10 -15,10 +15,10 @@@ class RGWGetObj_REST : public RGWGetOb
  protected:
    bool sent_header;
  public:
 -  RGWGetObj_REST() {}
 +  RGWGetObj_REST() : sent_header(false) {}
  
-   virtual void init(struct req_state *s, RGWHandler *h) {
-     RGWGetObj::init(s, h);
+   virtual void init(RGWRados *store, struct req_state *s, RGWHandler *h) {
+     RGWGetObj::init(store, s, h);
      sent_header = false;
    }
  
Simple merge
index c17e5056713e0d8b6aa5c00147bbaa7079696580,fcc36090bc9a1a8bb6e6b9cb569923845bcab3a6..03286727dcf6ffc2248d7f13fa235ef1d1cd9d74
      bucket link                link bucket to specified user
      bucket unlink              unlink bucket from specified user
      bucket stats               returns bucket statistics
 -    bucket info                show bucket information
      bucket rm                  remove bucket
      object rm                  remove object
+     cluster info               show cluster params info
      pool add                   add an existing pool for data placement
      pool rm                    remove an existing pool from data placement set
      pools list                 list placement active set