RGWBucketInfo bucket_info;
time_t mtime;
RGWObjectCtx obj_ctx(store);
- int r = store->get_bucket_info(obj_ctx, bucket.name, bucket_info, &mtime);
+ int r = store->get_bucket_info(obj_ctx, bucket.tenant, bucket.name, bucket_info, &mtime);
if (r < 0)
return r;
}
};
-static int init_bucket(const string& bucket_name, const string& bucket_id,
+static int init_bucket(const string& tenant, const string& bucket_name, const string& bucket_id,
RGWBucketInfo& bucket_info, rgw_bucket& bucket)
{
if (!bucket_name.empty()) {
RGWObjectCtx obj_ctx(store);
int r;
if (bucket_id.empty()) {
- r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL);
+ r = store->get_bucket_info(obj_ctx, tenant, bucket_name, bucket_info, NULL);
} else {
string bucket_instance_id = bucket_name + ":" + bucket_id;
r = store->get_bucket_instance_info(obj_ctx, bucket_instance_id, bucket_info, NULL, NULL);
common_init_finish(g_ceph_context);
rgw_user user_id;
+ string tenant;
std::string access_key, secret_key, user_email, display_name;
std::string bucket_name, pool_name, object;
std::string date, subuser, access, format;
usage();
return 0;
} else if (ceph_argparse_witharg(args, i, &val, "-i", "--uid", (char*)NULL)) {
- user_id.from_str(val);
+ string s = val;
+ if (!tenant.empty()) {
+ s = tenant + ":" + val;
+ }
+ user_id.from_str(s);
+ tenant = user_id.tenant;
+ } else if (ceph_argparse_witharg(args, i, &val, "--tenant", (char*)NULL)) {
+ tenant = val;
} else if (ceph_argparse_witharg(args, i, &val, "--access-key", (char*)NULL)) {
access_key = val;
} else if (ceph_argparse_witharg(args, i, &val, "--subuser", (char*)NULL)) {
/* populate bucket operation */
bucket_op.set_bucket_name(bucket_name);
+ bucket_op.set_tenant(tenant);
bucket_op.set_object(object);
bucket_op.set_check_objects(check_objects);
bucket_op.set_delete_children(delete_child_objects);
return EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(bucket_name, tenant, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
if (opt_cmd == OPT_OBJECT_RM) {
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
if (opt_cmd == OPT_OBJECT_UNLINK) {
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
if (opt_cmd == OPT_OBJECT_STAT) {
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
return -EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
return -EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
return -EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
return -EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
return -EINVAL;
}
RGWBucketInfo bucket_info;
- int ret = init_bucket(bucket_name, bucket_id, bucket_info, bucket);
+ int ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket);
if (ret < 0) {
cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl;
return -ret;
RGWObjVersionTracker ot;
map<string, bufferlist> attrs;
RGWObjectCtx obj_ctx(store);
- ret = store->get_bucket_entrypoint_info(obj_ctx, bucket_name, ep, &ot, NULL, &attrs);
+ ret = store->get_bucket_entrypoint_info(obj_ctx, user_id.tenant, bucket_name, ep, &ot, NULL, &attrs);
if (ret == -ENOENT)
return 0;
if (ret < 0)
RGWBucketInfo bucket_info;
time_t mtime;
RGWObjectCtx obj_ctx(store);
- int r = store->get_bucket_info(obj_ctx, bucket.name, bucket_info, &mtime);
+ int r = store->get_bucket_info(obj_ctx, user_id.tenant, bucket.name, bucket_info, &mtime);
if (r < 0) {
ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket << dendl;
continue;
rgw_bucket& actual_bucket = bucket_info.bucket;
if (actual_bucket.name.compare(bucket.name) != 0 ||
+ actual_bucket.tenant.compare(bucket.tenant) != 0 ||
actual_bucket.data_pool.compare(bucket.data_pool) != 0 ||
actual_bucket.index_pool.compare(bucket.index_pool) != 0 ||
actual_bucket.marker.compare(bucket.marker) != 0 ||
rgw_user user_id = op_state.get_user_id();
bucket_name = op_state.get_bucket_name();
+ tenant = op_state.get_tenant();
RGWUserBuckets user_buckets;
RGWObjectCtx obj_ctx(store);
return -EINVAL;
if (!bucket_name.empty()) {
- int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL);
+ int r = store->get_bucket_info(obj_ctx, tenant, bucket_name, bucket_info, NULL);
if (r < 0) {
ldout(store->ctx(), 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
return r;
return bucket.remove_object(op_state);
}
-static int bucket_stats(RGWRados *store, std::string& bucket_name, Formatter *formatter)
+static int bucket_stats(RGWRados *store, std::string& tenant, std::string& bucket_name, Formatter *formatter)
{
RGWBucketInfo bucket_info;
rgw_bucket bucket;
time_t mtime;
RGWObjectCtx obj_ctx(store);
- int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, &mtime);
+ int r = store->get_bucket_info(obj_ctx, tenant, bucket_name, bucket_info, &mtime);
if (r < 0)
return r;
size_t max_entries = cct->_conf->rgw_list_buckets_max_chunk;
bool show_stats = op_state.will_fetch_stats();
+ string tenant = op_state.get_tenant();
if (op_state.is_user_op()) {
formatter->open_array_section("buckets");
for (iter = m.begin(); iter != m.end(); ++iter) {
std::string obj_name = iter->first;
if (show_stats)
- bucket_stats(store, obj_name, formatter);
+ bucket_stats(store, tenant, obj_name, formatter);
else
formatter->dump_string("bucket", obj_name);
formatter->close_section();
} else if (!bucket_name.empty()) {
- bucket_stats(store, bucket_name, formatter);
+ bucket_stats(store, tenant, bucket_name, formatter);
} else {
RGWAccessHandle handle;
while (store->list_buckets_next(obj, &handle) >= 0) {
formatter->dump_string("bucket", obj.key.name);
if (show_stats)
- bucket_stats(store, obj.key.name, formatter);
+ bucket_stats(store, tenant, obj.key.name, formatter);
}
}
struct RGWBucketAdminOpState {
rgw_user uid;
+ std::string tenant;
std::string display_name;
std::string bucket_name;
std::string bucket_id;
void set_user_id(rgw_user& user_id) {
if (!user_id.empty())
uid = user_id;
+ tenant = uid.tenant;
+ }
+ void set_tenant(string& t) {
+ tenant = t;
}
void set_bucket_name(std::string& bucket_str) {
bucket_name = bucket_str;
std::string& get_user_display_name() { return display_name; }
std::string& get_bucket_name() { return bucket_name; }
std::string& get_object_name() { return object_name; }
+ std::string& get_tenant() { return tenant; };
rgw_bucket& get_bucket() { return bucket; }
void set_bucket(rgw_bucket& _bucket) {
RGWAccessHandle handle;
RGWUserInfo user_info;
+ std::string tenant;
std::string bucket_name;
bool failure;
RGWBucketInfo bucket_info;
-private:
-
public:
RGWBucket() : store(NULL), handle(NULL), failure(false) {}
int init(RGWRados *storage, RGWBucketAdminOpState& op_state);
WRITE_CLASS_ENCODER(RGWUserInfo)
struct rgw_bucket {
+ std::string tenant;
std::string name;
std::string data_pool;
std::string data_extra_pool; /* if not set, then we should use data_pool instead */
b->bucket_id = bucket_id;
}
+ rgw_bucket(const char *t, const char *n, const char *p, const char *m, const char *id) :
+ tenant(t), name(n), pool(p), marker(m), bucket_id(id) {}
void encode(bufferlist& bl) const {
- ENCODE_START(7, 3, bl);
+ ENCODE_START(8, 3, bl);
::encode(name, bl);
::encode(data_pool, bl);
::encode(marker, bl);
::encode(bucket_id, bl);
::encode(index_pool, bl);
::encode(data_extra_pool, bl);
+ ::encode(tenant, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator& bl) {
- DECODE_START_LEGACY_COMPAT_LEN(7, 3, 3, bl);
+ DECODE_START_LEGACY_COMPAT_LEN(8, 3, 3, bl);
::decode(name, bl);
::decode(data_pool, bl);
if (struct_v >= 2) {
if (struct_v >= 7) {
::decode(data_extra_pool, bl);
}
+ if (struct_v >= 8) {
+ ::decode(tenant, bl);
+ }
DECODE_FINISH(bl);
}
bool has_bad_meta;
RGWUserInfo user;
+ string tenant;
RGWAccessControlPolicy *bucket_acl;
RGWAccessControlPolicy *object_acl;
o.push_back(new RGWObjManifestPart);
RGWObjManifestPart *p = new RGWObjManifestPart;
- rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12", "region");
+ rgw_bucket b("tenant", "bucket", ".pool", ".index_pool", "marker_", "12", "region");
p->loc = rgw_obj(b, "object");
p->loc_ofs = 512 * 1024;
p->size = 128 * 1024;
RGWObjManifest *m = new RGWObjManifest;
for (int i = 0; i<10; i++) {
RGWObjManifestPart p;
- rgw_bucket b("bucket", ".pool", ".index_pool", "marker_", "12", "region");
+ rgw_bucket b("tenant", "bucket", ".pool", ".index_pool", "marker_", "12", "region");
p.loc = rgw_obj(b, "object");
p.loc_ofs = 0;
p.size = 512 * 1024;
void rgw_bucket::generate_test_instances(list<rgw_bucket*>& o)
{
- rgw_bucket *b = new rgw_bucket("name", "pool", ".index_pool", "marker", "123", "region");
+ rgw_bucket *b = new rgw_bucket("tenant", "name", "pool", ".index_pool", "marker", "123", "region");
o.push_back(b);
o.push_back(new rgw_bucket);
}
void RGWBucketInfo::generate_test_instances(list<RGWBucketInfo*>& o)
{
RGWBucketInfo *i = new RGWBucketInfo;
- i->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
+ i->bucket = rgw_bucket("tenant", "bucket", "pool", ".index_pool", "marker", "10", "region");
i->owner = "owner";
i->flags = BUCKET_SUSPENDED;
o.push_back(i);
void RGWBucketEnt::generate_test_instances(list<RGWBucketEnt*>& o)
{
RGWBucketEnt *e = new RGWBucketEnt;
- e->bucket = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
+ e->bucket = rgw_bucket("tenant", "bucket", "pool", ".index_pool", "marker", "10", "region");
e->size = 1024;
e->size_rounded = 4096;
e->count = 1;
void rgw_obj::generate_test_instances(list<rgw_obj*>& o)
{
- rgw_bucket b = rgw_bucket("bucket", "pool", ".index_pool", "marker", "10", "region");
+ rgw_bucket b = rgw_bucket("tenant", "bucket", "pool", ".index_pool", "marker", "10", "region");
rgw_obj *obj = new rgw_obj(b, "object");
o.push_back(obj);
o.push_back(new rgw_obj);
RGWBucketInfo bucket_info;
map<string, bufferlist> bucket_attrs;
RGWObjectCtx obj_ctx(store);
- int r = store->get_bucket_info(obj_ctx, bucket_name, bucket_info, NULL, &bucket_attrs);
+ int r = store->get_bucket_info(obj_ctx, s->tenant, bucket_name, bucket_info, NULL, &bucket_attrs);
if (r < 0) {
ldout(s->cct, 0) << "could not get bucket info for bucket=" << bucket_name << dendl;
return r;
RGWObjectCtx& obj_ctx = *static_cast<RGWObjectCtx *>(s->obj_ctx);
- ret = store->get_bucket_info(obj_ctx, src_bucket_name, src_bucket_info, NULL, &src_attrs);
+ ret = store->get_bucket_info(obj_ctx, s->tenant, src_bucket_name, src_bucket_info, NULL, &src_attrs);
if (ret < 0)
return ret;
dest_bucket_info = src_bucket_info;
dest_attrs = src_attrs;
} else {
- ret = store->get_bucket_info(obj_ctx, dest_bucket_name, dest_bucket_info, NULL, &dest_attrs);
+ ret = store->get_bucket_info(obj_ctx, s->tenant, dest_bucket_name, dest_bucket_info, NULL, &dest_attrs);
if (ret < 0)
return ret;
}
notify_oid.append(buf);
}
-int RGWRados::open_bucket_pool_ctx(const string& bucket_name, const string& pool, librados::IoCtx& io_ctx)
+int RGWRados::open_bucket_pool_ctx(const string& tenant, const string& bucket_name, const string& pool, librados::IoCtx& io_ctx)
{
librados::Rados *rad = get_rados_handle();
int r = rad->ioctx_create(pool.c_str(), io_ctx);
void RGWRados::get_bucket_instance_entry(rgw_bucket& bucket, string& entry)
{
- entry = bucket.name + ":" + bucket.bucket_id;
+ if (bucket.tenant.empty()) {
+ entry = bucket.name + ":" + bucket.bucket_id;
+ } else {
+ entry = bucket.tenant + ":" + bucket.name + ":" + bucket.bucket_id;
+ }
}
void RGWRados::get_bucket_meta_oid(rgw_bucket& bucket, string& oid)
return 0;
}
-int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx, const string& bucket_name, RGWBucketInfo& info,
+struct bucket_info_entry {
+ RGWBucketInfo info;
+ time_t mtime;
+ map<string, bufferlist> attrs;
+};
+
+static RGWChainedCacheImpl<bucket_info_entry> binfo_cache;
+
+int RGWRados::get_bucket_info(RGWObjectCtx& obj_ctx, const string& tenant, const string& bucket_name, RGWBucketInfo& info,
time_t *pmtime, map<string, bufferlist> *pattrs)
{
bucket_info_entry e;
time_t ep_mtime;
RGWObjVersionTracker ot;
rgw_cache_entry_info entry_cache_info;
- int ret = get_bucket_entrypoint_info(obj_ctx, bucket_name, entry_point, &ot, &ep_mtime, pattrs, &entry_cache_info);
+ int ret = get_bucket_entrypoint_info(obj_ctx, tenant, bucket_name, entry_point, &ot, &ep_mtime, pattrs, &entry_cache_info);
if (ret < 0) {
info.bucket.name = bucket_name; /* only init this field */
return ret;
if (entry_point.has_bucket_info) {
info = entry_point.old_bucket_info;
info.bucket.oid = bucket_name;
+ info.bucket.tenant = tenant;
info.ep_objv = ot.read_version;
ldout(cct, 20) << "rgw_get_bucket_info: old bucket info, bucket=" << info.bucket << " owner " << info.owner << dendl;
return 0;
return 0;
}
-int RGWRados::put_bucket_entrypoint_info(const string& bucket_name, RGWBucketEntryPoint& entry_point,
+int RGWRados::put_bucket_entrypoint_info(const string& tenant, const string& bucket_name, RGWBucketEntryPoint& entry_point,
bool exclusive, RGWObjVersionTracker& objv_tracker, time_t mtime,
map<string, bufferlist> *pattrs)
{
int put_bucket_entrypoint_info(const string& bucket_name, RGWBucketEntryPoint& entry_point, bool exclusive, RGWObjVersionTracker& objv_tracker, time_t mtime,
map<string, bufferlist> *pattrs);
int put_bucket_instance_info(RGWBucketInfo& info, bool exclusive, time_t mtime, map<string, bufferlist> *pattrs);
- int get_bucket_entrypoint_info(RGWObjectCtx& obj_ctx, const string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime,
+ int get_bucket_entrypoint_info(RGWObjectCtx& obj_ctx, const string& tenant, const string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime,
map<string, bufferlist> *pattrs, rgw_cache_entry_info *cache_info = NULL);
int get_bucket_instance_info(RGWObjectCtx& obj_ctx, const string& meta_key, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
int get_bucket_instance_info(RGWObjectCtx& obj_ctx, rgw_bucket& bucket, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
} /* if keystone_result < 0 */
// populate the owner info
+ s->tenant = s->user.user_id.tenant;
s->owner.set_id(s->user.user_id);
s->owner.set_name(s->user.display_name);