rgw: fix bucket suspension

This commit is contained in:
Yehuda Sadeh 2011-10-26 14:30:26 -07:00
parent f197e84517
commit 6752babdfd
9 changed files with 77 additions and 70 deletions

View File

@ -128,8 +128,7 @@ public:
virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool) = 0;
virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets) { return -ENOTSUP; }
virtual int disable_buckets(std::vector<rgw_bucket>& buckets) { return -ENOTSUP; }
virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid) { return -ENOTSUP; }
virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled) { return -ENOTSUP; }
virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended) {
*suspended = false;
return 0;
@ -271,6 +270,7 @@ public:
/* The bucket here can either be the bucket name identifier, or the ID
* in period format: ".123" */
virtual int get_bucket_info(void *ctx, string& bucket, RGWBucketInfo& info) = 0;
virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info) = 0;
virtual int remove_temp_objects(string date, string time) {

View File

@ -1218,10 +1218,7 @@ int main(int argc, char **argv)
RGWBucketEnt obj = iter->second;
bucket_names.push_back(obj.bucket);
}
if (disable)
ret = rgwstore->disable_buckets(bucket_names);
else
ret = rgwstore->enable_buckets(bucket_names, info.auid);
ret = rgwstore->set_buckets_enabled(bucket_names, !disable);
if (ret < 0) {
cerr << "ERROR: failed to change pool" << std::endl;
return 1;

View File

@ -430,24 +430,34 @@ inline ostream& operator<<(ostream& out, const rgw_bucket b) {
extern rgw_bucket rgw_root_bucket;
enum RGWBucketFlags {
BUCKET_SUSPENDED = 0x1,
};
struct RGWBucketInfo
{
rgw_bucket bucket;
string owner;
uint32_t flags;
void encode(bufferlist& bl) const {
__u32 ver = 2;
__u32 ver = 3;
::encode(ver, bl);
::encode(bucket, bl);
::encode(owner, bl);
::encode(flags, bl);
}
void decode(bufferlist::iterator& bl) {
__u32 ver;
::decode(ver, bl);
::decode(bucket, bl);
if (ver > 1)
if (ver >= 2)
::decode(owner, bl);
if (ver >= 3)
::decode(flags, bl);
}
RGWBucketInfo() : flags(0) {}
};
WRITE_CLASS_ENCODER(RGWBucketInfo)
@ -545,12 +555,11 @@ struct RGWObjEnt {
}
};
/** Store basic data on an object */
/** Store basic data on bucket */
struct RGWBucketEnt {
rgw_bucket bucket;
size_t size;
time_t mtime;
string etag;
uint64_t count;
void encode(bufferlist& bl) const {
@ -583,7 +592,6 @@ struct RGWBucketEnt {
bucket.clear();
size = 0;
mtime = 0;
etag = "";
count = 0;
}
};

View File

@ -667,3 +667,8 @@ int RGWFS::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info)
{
return -ENOTSUP;
}
int RGWFS::put_bucket_info(string& bucket_name, RGWBucketInfo& info)
{
return -ENOTSUP;
}

View File

@ -63,6 +63,7 @@ public:
int obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, map<string, bufferlist> *attrs);
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info);
virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info);
};
#endif

View File

@ -172,21 +172,16 @@ static int get_obj_attrs(struct req_state *s, rgw_obj& obj, map<string, bufferli
return ret;
}
int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
static int read_acls(struct req_state *s, RGWBucketInfo& bucket_info, RGWAccessControlPolicy *policy, rgw_bucket& bucket, string& object)
{
string upload_id;
url_decode(s->args.get("uploadId"), upload_id);
string oid = object;
rgw_obj obj;
if (!oid.empty()) {
bool suspended;
int ret = rgwstore->bucket_suspended(bucket, &suspended);
if (ret < 0)
return ret;
if (suspended)
return -ERR_USER_SUSPENDED;
if (bucket_info.flags & BUCKET_SUSPENDED) {
dout(0) << "bucket " << bucket_info.bucket.name << " is suspended" << dendl;
return -ERR_USER_SUSPENDED;
}
if (!oid.empty() && !upload_id.empty()) {
@ -224,7 +219,7 @@ int read_acls(struct req_state *s, RGWAccessControlPolicy *policy, rgw_bucket& b
* only_bucket: If true, reads the bucket ACL rather than the object ACL.
* Returns: 0 on success, -ERR# otherwise.
*/
int read_acls(struct req_state *s, bool only_bucket)
static int read_acls(struct req_state *s, bool only_bucket)
{
int ret = 0;
string obj_str;
@ -242,8 +237,8 @@ int read_acls(struct req_state *s, bool only_bucket)
rgwstore->set_atomic(s->obj_ctx, obj);
}
RGWBucketInfo bucket_info;
if (s->bucket_name_str.size()) {
RGWBucketInfo bucket_info;
ret = rgwstore->get_bucket_info(s->obj_ctx, s->bucket_name_str, bucket_info);
if (ret < 0) {
dout(0) << "couldn't get bucket from bucket_name (name=" << s->bucket_name_str << ")" << dendl;
@ -253,7 +248,7 @@ int read_acls(struct req_state *s, bool only_bucket)
s->bucket_owner = bucket_info.owner;
}
ret = read_acls(s, s->acl, s->bucket, obj_str);
ret = read_acls(s, bucket_info, s->acl, s->bucket, obj_str);
return ret;
}
@ -926,7 +921,7 @@ int RGWCopyObj::verify_permission()
src_bucket = bucket_info.bucket;
/* just checking the bucket's permission */
ret = read_acls(s, &src_policy, src_bucket, empty_str);
ret = read_acls(s, bucket_info, &src_policy, src_bucket, empty_str);
if (ret < 0)
return ret;
@ -1008,7 +1003,7 @@ int RGWGetACLs::verify_permission()
void RGWGetACLs::execute()
{
ret = read_acls(s);
ret = read_acls(s, false);
if (ret < 0) {
send_response();

View File

@ -22,13 +22,6 @@ struct req_state;
/** Get the HTTP request metadata */
extern void get_request_metadata(struct req_state *s, map<string, bufferlist>& attrs);
/**
* Get the ACL for an object off of disk. If you hold the req_state, use next
* method.
*/
extern int read_acls(RGWAccessControlPolicy *policy, rgw_obj& bucket, string& object);
/** Get the ACL needed for a request off of disk.*/
extern int read_acls(struct req_state *s, bool only_bucket = false);
/**
* Provide the base class for all ops.

View File

@ -939,56 +939,51 @@ int RGWRados::purge_buckets(std::string& id, vector<rgw_bucket>& buckets)
return ret;
}
int RGWRados::set_buckets_auid(vector<rgw_bucket>& buckets, uint64_t auid)
int RGWRados::set_buckets_enabled(vector<rgw_bucket>& buckets, bool enabled)
{
librados::IoCtx ctx;
vector<librados::PoolAsyncCompletion *> completions;
int ret = 0;
vector<rgw_bucket>::iterator iter;
for (iter = buckets.begin(); iter != buckets.end(); ++iter) {
rgw_bucket& bucket = *iter;
int r = open_bucket_ctx(bucket, ctx);
if (r < 0)
return r;
if (enabled)
dout(20) << "enabling bucket name=" << bucket.name << dendl;
else
dout(20) << "disabling bucket name=" << bucket.name << dendl;
librados::PoolAsyncCompletion *c = librados::Rados::pool_async_create_completion();
completions.push_back(c);
ctx.set_auid_async(auid, c);
RGWBucketInfo info;
int r = get_bucket_info(NULL, bucket.name, info);
if (r < 0) {
dout(0) << "get_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
ret = r;
continue;
}
if (enabled) {
info.flags &= ~BUCKET_SUSPENDED;
} else {
info.flags |= BUCKET_SUSPENDED;
}
r = put_bucket_info(bucket.name, info);
if (r < 0) {
dout(0) << "put_bucket_info on bucket=" << bucket.name << " returned err=" << r << ", skipping bucket" << dendl;
ret = r;
continue;
}
}
vector<librados::PoolAsyncCompletion *>::iterator citer;
for (citer = completions.begin(); citer != completions.end(); ++citer) {
PoolAsyncCompletion *c = *citer;
c->wait();
c->release();
}
return 0;
}
int RGWRados::disable_buckets(vector<rgw_bucket>& buckets)
{
return set_buckets_auid(buckets, RGW_SUSPENDED_USER_AUID);
}
int RGWRados::enable_buckets(vector<rgw_bucket>& buckets, uint64_t auid)
{
return set_buckets_auid(buckets, auid);
}
int RGWRados::bucket_suspended(rgw_bucket& bucket, bool *suspended)
{
librados::IoCtx ctx;
int r = open_bucket_ctx(bucket, ctx);
if (r < 0)
return r;
uint64_t auid;
int ret = ctx.get_auid(&auid);
if (ret < 0)
RGWBucketInfo bucket_info;
int ret = rgwstore->get_bucket_info(NULL, bucket.name, bucket_info);
if (ret < 0) {
return ret;
}
*suspended = (auid == RGW_SUSPENDED_USER_AUID);
*suspended = ((bucket_info.flags & BUCKET_SUSPENDED) != 0);
return 0;
}
@ -1789,6 +1784,7 @@ int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime,
mtime = ut.sec();
} catch (buffer::error& err) {
dout(0) << "ERROR: failed decoding object (obj=" << obj << ") info (either size or mtime), aborting" << dendl;
return -EIO;
}
if (psize)
*psize = size;
@ -1848,6 +1844,18 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
return 0;
}
int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info)
{
bufferlist bl;
::encode(info, bl);
string unused;
int ret = rgw_put_obj(unused, pi_buckets_rados, bucket_name, bl.c_str(), bl.length());
return ret;
}
int RGWRados::tmap_get(rgw_obj& obj, bufferlist& header, std::map<string, bufferlist>& m)
{

View File

@ -239,8 +239,7 @@ public:
virtual int delete_bucket(std::string& id, rgw_bucket& bucket, bool remove_pool);
virtual int purge_buckets(std::string& id, vector<rgw_bucket>& buckets);
virtual int disable_buckets(std::vector<rgw_bucket>& buckets);
virtual int enable_buckets(std::vector<rgw_bucket>& buckets, uint64_t auid);
virtual int set_buckets_enabled(std::vector<rgw_bucket>& buckets, bool enabled);
virtual int bucket_suspended(rgw_bucket& bucket, bool *suspended);
/** Delete an object.*/
@ -309,6 +308,7 @@ public:
int decode_policy(bufferlist& bl, ACLOwner *owner);
int get_bucket_stats(rgw_bucket& bucket, map<RGWObjCategory, RGWBucketStats>& stats);
virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info);
virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info);
int cls_rgw_init_index(rgw_bucket& bucket, string& oid);
int cls_obj_prepare_op(rgw_bucket& bucket, uint8_t op, string& tag,