op.exec(RGW_CLASS, RGW_GC_REMOVE, in);
}
-int cls_rgw_lc_get_head(IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head)
+int cls_rgw_lc_get_head(IoCtx& io_ctx, const string& oid, cls_rgw_lc_obj_head& head)
{
bufferlist in, out;
int r = io_ctx.exec(oid, RGW_CLASS, RGW_LC_GET_HEAD, in, out);
return r;
}
-int cls_rgw_lc_put_head(IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head)
+int cls_rgw_lc_put_head(IoCtx& io_ctx, const string& oid, cls_rgw_lc_obj_head& head)
{
bufferlist in, out;
cls_rgw_lc_put_head_op call;
return r;
}
-int cls_rgw_lc_get_next_entry(IoCtx& io_ctx, string& oid, string& marker, pair<string, int>& entry)
+int cls_rgw_lc_get_next_entry(IoCtx& io_ctx, const string& oid, string& marker, pair<string, int>& entry)
{
bufferlist in, out;
cls_rgw_lc_get_next_entry_op call;
return r;
}
-int cls_rgw_lc_rm_entry(IoCtx& io_ctx, string& oid, pair<string, int>& entry)
+int cls_rgw_lc_rm_entry(IoCtx& io_ctx, const string& oid, const pair<string, int>& entry)
{
bufferlist in, out;
cls_rgw_lc_rm_entry_op call;
return r;
}
-int cls_rgw_lc_set_entry(IoCtx& io_ctx, string& oid, pair<string, int>& entry)
+int cls_rgw_lc_set_entry(IoCtx& io_ctx, const string& oid, const pair<string, int>& entry)
{
bufferlist in, out;
cls_rgw_lc_set_entry_op call;
return r;
}
-int cls_rgw_lc_list(IoCtx& io_ctx, string& oid,
+int cls_rgw_lc_list(IoCtx& io_ctx, const string& oid,
const string& marker,
uint32_t max_entries,
map<string, int>& entries)
void cls_rgw_gc_remove(librados::ObjectWriteOperation& op, const vector<string>& tags);
/* lifecycle */
-int cls_rgw_lc_get_head(librados::IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head);
-int cls_rgw_lc_put_head(librados::IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head);
-int cls_rgw_lc_get_next_entry(librados::IoCtx& io_ctx, string& oid, string& marker, pair<string, int>& entry);
-int cls_rgw_lc_rm_entry(librados::IoCtx& io_ctx, string& oid, pair<string, int>& entry);
-int cls_rgw_lc_set_entry(librados::IoCtx& io_ctx, string& oid, pair<string, int>& entry);
-int cls_rgw_lc_list(librados::IoCtx& io_ctx, string& oid,
+int cls_rgw_lc_get_head(librados::IoCtx& io_ctx, const string& oid, cls_rgw_lc_obj_head& head);
+int cls_rgw_lc_put_head(librados::IoCtx& io_ctx, const string& oid, cls_rgw_lc_obj_head& head);
+int cls_rgw_lc_get_next_entry(librados::IoCtx& io_ctx, const string& oid, string& marker, pair<string, int>& entry);
+int cls_rgw_lc_rm_entry(librados::IoCtx& io_ctx, const string& oid, const pair<string, int>& entry);
+int cls_rgw_lc_set_entry(librados::IoCtx& io_ctx, const string& oid, const pair<string, int>& entry);
+int cls_rgw_lc_list(librados::IoCtx& io_ctx, const string& oid,
const string& marker,
uint32_t max_entries,
map<string, int>& entries);
o.push_back(new RGWLifecycleConfiguration);
}
+static void get_lc_oid(CephContext *cct, const string& shard_id, string *oid)
+{
+ int max_objs = (cct->_conf->rgw_lc_max_objs > HASH_PRIME ? HASH_PRIME : cct->_conf->rgw_lc_max_objs);
+ int index = ceph_str_hash_linux(shard_id.c_str(), shard_id.size()) % HASH_PRIME % max_objs;
+ *oid = lc_oid_prefix;
+ char buf[32];
+ snprintf(buf, 32, ".%d", index);
+ oid->append(buf);
+ return;
+}
+
+template<typename F>
+static int guard_lc_modify(RGWRados* store, const rgw_bucket& bucket, const string& cookie, const F& f) {
+ CephContext *cct = store->ctx();
+
+ string shard_id = bucket.tenant + ':' + bucket.name + ':' + bucket.bucket_id;
+
+ string oid;
+ get_lc_oid(cct, shard_id, &oid);
+
+ pair<string, int> entry(shard_id, lc_uninitial);
+ int max_lock_secs = cct->_conf->rgw_lc_lock_max_time;
+
+ rados::cls::lock::Lock l(lc_index_lock_name);
+ utime_t time(max_lock_secs, 0);
+ l.set_duration(time);
+ l.set_cookie(cookie);
+
+ librados::IoCtx *ctx = store->get_lc_pool_ctx();
+ int ret;
+
+ do {
+ ret = l.lock_exclusive(ctx, oid);
+ if (ret == -EBUSY) {
+ ldout(cct, 0) << "RGWLC::RGWPutLC() failed to acquire lock on "
+ << oid << ", sleep 5, try again" << dendl;
+ sleep(5); // XXX: return retryable error
+ continue;
+ }
+ if (ret < 0) {
+ ldout(cct, 0) << "RGWLC::RGWPutLC() failed to acquire lock on "
+ << oid << ", ret=" << ret << dendl;
+ break;
+ }
+ ret = f(ctx, oid, entry);
+ if (ret < 0) {
+ ldout(cct, 0) << "RGWLC::RGWPutLC() failed to set entry on "
+ << oid << ", ret=" << ret << dendl;
+ }
+ break;
+ } while(true);
+ l.unlock(ctx, oid);
+ return ret;
+}
+
+int RGWLC::set_bucket_config(RGWBucketInfo& bucket_info,
+ const map<string, bufferlist>& bucket_attrs,
+ RGWLifecycleConfiguration *config)
+{
+ map<string, bufferlist> attrs = bucket_attrs;
+ config->encode(attrs[RGW_ATTR_LC]);
+ int ret = rgw_bucket_set_attrs(store, bucket_info, attrs, &bucket_info.objv_tracker);
+ if (ret < 0)
+ return ret;
+
+ rgw_bucket& bucket = bucket_info.bucket;
+
+
+ ret = guard_lc_modify(store, bucket, cookie, [&](librados::IoCtx *ctx, const string& oid,
+ const pair<string, int>& entry) {
+ return cls_rgw_lc_set_entry(*ctx, oid, entry);
+ });
+
+ return ret;
+}
+
+int RGWLC::remove_bucket_config(RGWBucketInfo& bucket_info,
+ const map<string, bufferlist>& bucket_attrs)
+{
+ map<string, bufferlist> attrs = bucket_attrs;
+ attrs.erase(RGW_ATTR_LC);
+ int ret = rgw_bucket_set_attrs(store, bucket_info, attrs,
+ &bucket_info.objv_tracker);
+
+ rgw_bucket& bucket = bucket_info.bucket;
+
+ if (ret < 0) {
+ ldout(cct, 0) << "RGWLC::RGWDeleteLC() failed to set attrs on bucket="
+ << bucket.name << " returned err=" << ret << dendl;
+ return ret;
+ }
+
+
+ ret = guard_lc_modify(store, bucket, cookie, [&](librados::IoCtx *ctx, const string& oid,
+ const pair<string, int>& entry) {
+ return cls_rgw_lc_rm_entry(*ctx, oid, entry);
+ });
+
+ return ret;
+}
+
bool going_down();
void start_processor();
void stop_processor();
+ int set_bucket_config(RGWBucketInfo& bucket_info,
+ const map<string, bufferlist>& bucket_attrs,
+ RGWLifecycleConfiguration *config);
+ int remove_bucket_config(RGWBucketInfo& bucket_info,
+ const map<string, bufferlist>& bucket_attrs);
CephContext *get_cct() const override { return store->ctx(); }
unsigned get_subsys() const;
}
}
-static void get_lc_oid(struct req_state *s, string& oid)
-{
- string shard_id = s->bucket.name + ':' +s->bucket.bucket_id;
- int max_objs = (s->cct->_conf->rgw_lc_max_objs > HASH_PRIME)?HASH_PRIME:s->cct->_conf->rgw_lc_max_objs;
- int index = ceph_str_hash_linux(shard_id.c_str(), shard_id.size()) % HASH_PRIME % max_objs;
- oid = lc_oid_prefix;
- char buf[32];
- snprintf(buf, 32, ".%d", index);
- oid.append(buf);
- return;
-}
-
void RGWPutLC::execute()
{
bufferlist bl;
new_config.to_xml(*_dout);
*_dout << dendl;
}
-
- new_config.encode(bl);
- map<string, bufferlist> attrs;
- attrs = s->bucket_attrs;
- attrs[RGW_ATTR_LC] = bl;
- op_ret = rgw_bucket_set_attrs(store, s->bucket_info, attrs, &s->bucket_info.objv_tracker);
- if (op_ret < 0)
+
+ op_ret = store->get_lc()->set_bucket_config(s->bucket_info, s->bucket_attrs, &new_config);
+ if (op_ret < 0) {
return;
- string shard_id = s->bucket.tenant + ':' + s->bucket.name + ':' + s->bucket.bucket_id;
- string oid;
- get_lc_oid(s, oid);
- pair<string, int> entry(shard_id, lc_uninitial);
- int max_lock_secs = s->cct->_conf->rgw_lc_lock_max_time;
- rados::cls::lock::Lock l(lc_index_lock_name);
- utime_t time(max_lock_secs, 0);
- l.set_duration(time);
- l.set_cookie(cookie);
- librados::IoCtx *ctx = store->get_lc_pool_ctx();
- do {
- op_ret = l.lock_exclusive(ctx, oid);
- if (op_ret == -EBUSY) {
- ldpp_dout(this, 0) << "RGWLC::RGWPutLC() failed to acquire lock on "
- << oid << ", sleep 5, try again" << dendl;
- sleep(5); // XXX: return retryable error
- continue;
- }
- if (op_ret < 0) {
- ldpp_dout(this, 0) << "RGWLC::RGWPutLC() failed to acquire lock on "
- << oid << ", ret=" << op_ret << dendl;
- break;
- }
- op_ret = cls_rgw_lc_set_entry(*ctx, oid, entry);
- if (op_ret < 0) {
- ldpp_dout(this, 0) << "RGWLC::RGWPutLC() failed to set entry on "
- << oid << ", ret=" << op_ret << dendl;
- }
- break;
- }while(1);
- l.unlock(ctx, oid);
+ }
return;
}
<< s->bucket.name << " returned err=" << op_ret << dendl;
return;
}
- string shard_id = s->bucket.tenant + ':' + s->bucket.name + ':' + s->bucket.bucket_id;
- pair<string, int> entry(shard_id, lc_uninitial);
- string oid;
- get_lc_oid(s, oid);
- int max_lock_secs = s->cct->_conf->rgw_lc_lock_max_time;
- librados::IoCtx *ctx = store->get_lc_pool_ctx();
- rados::cls::lock::Lock l(lc_index_lock_name);
- utime_t time(max_lock_secs, 0);
- l.set_duration(time);
- do {
- op_ret = l.lock_exclusive(ctx, oid);
- if (op_ret == -EBUSY) {
- ldpp_dout(this, 0) << "RGWLC::RGWDeleteLC() failed to acquire lock on "
- << oid << ", sleep 5, try again" << dendl;
- sleep(5); // XXX: return retryable error
- continue;
- }
- if (op_ret < 0) {
- ldpp_dout(this, 0) << "RGWLC::RGWDeleteLC() failed to acquire lock on "
- << oid << ", ret=" << op_ret << dendl;
- break;
- }
- op_ret = cls_rgw_lc_rm_entry(*ctx, oid, entry);
- if (op_ret < 0) {
- ldpp_dout(this, 0) << "RGWLC::RGWDeleteLC() failed to rm entry on "
- << oid << ", ret=" << op_ret << dendl;
- }
- break;
- }while(1);
- l.unlock(ctx, oid);
+
+ op_ret = store->get_lc()->remove_bucket_config(s->bucket_info, s->bucket_attrs);
+ if (op_ret < 0) {
+ return;
+ }
return;
}
return *this;
}
+ RGWLC *get_lc() {
+ return lc;
+ }
+
RGWRados& set_run_gc_thread(bool _use_gc_thread) {
use_gc_thread = _use_gc_thread;
return *this;