diff options
author | Ji Chen <insomnia@139.com> | 2016-06-13 04:32:34 +0200 |
---|---|---|
committer | Ji Chen <insomnia@139.com> | 2016-07-22 06:22:12 +0200 |
commit | abe4b1378cc0e23e0da9c76c034c6d592b81b105 (patch) | |
tree | 545e3b31f4cb613aa5035eb01ffd0132e5309d29 /src/cls/rgw | |
parent | Merge pull request #9089 from SirishaGuduru/bugfix15603 (diff) | |
download | ceph-abe4b1378cc0e23e0da9c76c034c6d592b81b105.tar.xz ceph-abe4b1378cc0e23e0da9c76c034c6d592b81b105.zip |
RGW:lifecycle feature[rebase]
As same as amazon S3 interface,"PUT Bucket lifecycle" and
"DELETE Bucket lifecycle" have been implemented,
"GET Bucket lifecycle" not realized yet as S3cmd has not
realize it also.
The feature`s main point is to remove expire file per day.
Files transfer from hot layer to cold layer is not supported.
ToDo:Maybe to transfer from replicate pool to EC pool or
from ssd to sata pool will be valuable.
Now put all buckets which should do lifecycle into shard
objects in .rgw.lc pool.
lifecycle config file format:
<LifecycleConfiguration>
<Rule>
<ID>sample-rule</ID>
<Prefix></Prefix>
<Status>enable</Status>
<Expiration>
<Days>1</Days>
</Expiration>
</Rule>
</LifecycleConfiguration>
Signed-off-by: Ji Chen <insomnia@139.com>
Diffstat (limited to 'src/cls/rgw')
-rw-r--r-- | src/cls/rgw/cls_rgw.cc | 166 | ||||
-rw-r--r-- | src/cls/rgw/cls_rgw_client.cc | 102 | ||||
-rw-r--r-- | src/cls/rgw/cls_rgw_client.h | 16 | ||||
-rw-r--r-- | src/cls/rgw/cls_rgw_ops.h | 158 | ||||
-rw-r--r-- | src/cls/rgw/cls_rgw_types.h | 28 |
5 files changed, 466 insertions, 4 deletions
diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 46c2a3f9b49..161c78c9712 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -50,6 +50,12 @@ cls_method_handle_t h_rgw_user_usage_log_trim; cls_method_handle_t h_rgw_gc_set_entry; cls_method_handle_t h_rgw_gc_list; cls_method_handle_t h_rgw_gc_remove; +cls_method_handle_t h_rgw_lc_set_entry; +cls_method_handle_t h_rgw_lc_rm_entry; +cls_method_handle_t h_rgw_lc_get_next_entry; +cls_method_handle_t h_rgw_lc_put_head; +cls_method_handle_t h_rgw_lc_get_head; +cls_method_handle_t h_rgw_lc_list_entries; #define ROUND_BLOCK_SIZE 4096 @@ -2818,7 +2824,7 @@ static int usage_log_read_cb(cls_method_context_t hctx, const string& key, rgw_u rgw_user_bucket ub(puser->to_str(), entry.bucket); rgw_usage_log_entry& le = (*usage)[ub]; le.aggregate(entry); - + return 0; } @@ -2962,7 +2968,7 @@ static int gc_omap_remove(cls_method_context_t hctx, int type, const string& key static bool key_in_index(const string& key, int index_type) { - const string& prefix = gc_index_prefixes[index_type]; + const string& prefix = gc_index_prefixes[index_type]; return (key.compare(0, prefix.size(), prefix) == 0); } @@ -3221,6 +3227,154 @@ static int rgw_cls_gc_remove(cls_method_context_t hctx, bufferlist *in, bufferli return gc_remove(hctx, op.tags); } +static int rgw_cls_lc_set_entry(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + bufferlist::iterator in_iter = in->begin(); + + cls_rgw_lc_set_entry_op op; + try { + ::decode(op, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_set_entry(): failed to decode entry\n"); + return -EINVAL; + } + + bufferlist bl; + ::encode(op.entry, bl); + + int ret = cls_cxx_map_set_val(hctx, op.entry.first, &bl); + return ret; +} + +static int rgw_cls_lc_rm_entry(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + bufferlist::iterator in_iter = in->begin(); + + cls_rgw_lc_rm_entry_op op; + try { + ::decode(op, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_rm_entry(): failed to decode entry\n"); + return -EINVAL; + } + + bufferlist bl; + ::encode(op.entry, bl); + + int ret = cls_cxx_map_remove_key(hctx, op.entry.first); + return ret; +} + +static int rgw_cls_lc_get_next_entry(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + bufferlist::iterator in_iter = in->begin(); + cls_rgw_lc_get_next_entry_ret op_ret; + cls_rgw_lc_get_next_entry_op op; + try { + ::decode(op, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_rm_entry(): failed to decode entry\n"); + return -EINVAL; + } + + map<string, bufferlist> vals; + string filter_prefix; + int ret = cls_cxx_map_get_vals(hctx, op.marker, filter_prefix, 1, &vals); + if (ret < 0) + return ret; + map<string, bufferlist>::iterator it; + pair<string, int> entry; + if (!vals.empty()) { + it=vals.begin(); + in_iter = it->second.begin(); + try { + ::decode(entry, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_get_next_entry(): failed to decode entry\n"); + return -EIO; + } + } + op_ret.entry = entry; + ::encode(op_ret, *out); + return 0; +} + +static int rgw_cls_lc_list_entries(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + cls_rgw_lc_list_entries_op op; + bufferlist::iterator in_iter = in->begin(); + try { + ::decode(op, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_rm_entry(): failed to decode entry\n"); + return -EINVAL; + } + cls_rgw_lc_list_entries_ret op_ret; + bufferlist::iterator iter; + map<string, bufferlist> vals; + string filter_prefix; + int ret = cls_cxx_map_get_vals(hctx, op.marker, filter_prefix, op.max_entries, &vals); + if (ret < 0) + return ret; + map<string, bufferlist>::iterator it; + pair<string, int> entry; + for (it = vals.begin(); it != vals.end(); it++) { + iter = it->second.begin(); + try { + ::decode(entry, iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_list_entries(): failed to decode entry\n"); + return -EIO; + } + op_ret.entries.insert(entry); + } + ::encode(op_ret, *out); + return 0; +} + +static int rgw_cls_lc_put_head(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + bufferlist::iterator in_iter = in->begin(); + + cls_rgw_lc_put_head_op op; + try { + ::decode(op, in_iter); + } catch (buffer::error& err) { + CLS_LOG(1, "ERROR: rgw_cls_lc_set_entry(): failed to decode entry\n"); + return -EINVAL; + } + + bufferlist bl; + ::encode(op.head, bl); + int ret = cls_cxx_map_write_header(hctx,&bl); + return ret; +} + +static int rgw_cls_lc_get_head(cls_method_context_t hctx, bufferlist *in, bufferlist *out) +{ + bufferlist bl; + int ret = cls_cxx_map_read_header(hctx, &bl); + if (ret < 0) + return ret; + cls_rgw_lc_obj_head head; + if (bl.length() != 0) { + bufferlist::iterator iter = bl.begin(); + try { + ::decode(head, iter); + } catch (buffer::error& err) { + CLS_LOG(0, "ERROR: rgw_cls_lc_get_head(): failed to decode entry %s\n",err.what()); + return -EINVAL; + } + } else { + head.start_date = 0; + head.marker.clear(); + } + cls_rgw_lc_get_head_ret op_ret; + op_ret.head = head; + ::encode(op_ret, *out); + return 0; +} + void __cls_init() { CLS_LOG(1, "Loaded rgw class!"); @@ -3265,6 +3419,14 @@ void __cls_init() cls_register_cxx_method(h_class, "gc_list", CLS_METHOD_RD, rgw_cls_gc_list, &h_rgw_gc_list); cls_register_cxx_method(h_class, "gc_remove", CLS_METHOD_RD | CLS_METHOD_WR, rgw_cls_gc_remove, &h_rgw_gc_remove); + /* lifecycle bucket list */ + cls_register_cxx_method(h_class, "lc_set_entry", CLS_METHOD_RD | CLS_METHOD_WR, rgw_cls_lc_set_entry, &h_rgw_lc_set_entry); + cls_register_cxx_method(h_class, "lc_rm_entry", CLS_METHOD_RD | CLS_METHOD_WR, rgw_cls_lc_rm_entry, &h_rgw_lc_rm_entry); + cls_register_cxx_method(h_class, "lc_get_next_entry", CLS_METHOD_RD, rgw_cls_lc_get_next_entry, &h_rgw_lc_get_next_entry); + cls_register_cxx_method(h_class, "lc_put_head", CLS_METHOD_RD| CLS_METHOD_WR, rgw_cls_lc_put_head, &h_rgw_lc_put_head); + cls_register_cxx_method(h_class, "lc_get_head", CLS_METHOD_RD, rgw_cls_lc_get_head, &h_rgw_lc_get_head); + cls_register_cxx_method(h_class, "lc_list_entries", CLS_METHOD_RD, rgw_cls_lc_list_entries, &h_rgw_lc_list_entries); + return; } diff --git a/src/cls/rgw/cls_rgw_client.cc b/src/cls/rgw/cls_rgw_client.cc index 1cf1156385b..41647845691 100644 --- a/src/cls/rgw/cls_rgw_client.cc +++ b/src/cls/rgw/cls_rgw_client.cc @@ -650,3 +650,105 @@ void cls_rgw_gc_remove(librados::ObjectWriteOperation& op, const list<string>& t ::encode(call, in); op.exec("rgw", "gc_remove", in); } + +int cls_rgw_lc_get_head(IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head) +{ + bufferlist in, out; + int r = io_ctx.exec(oid, "rgw", "lc_get_head", in, out); + if (r < 0) + return r; + + cls_rgw_lc_get_head_ret ret; + try { + bufferlist::iterator iter = out.begin(); + ::decode(ret, iter); + } catch (buffer::error& err) { + return -EIO; + } + head = ret.head; + + return r; +} + +int cls_rgw_lc_put_head(IoCtx& io_ctx, string& oid, cls_rgw_lc_obj_head& head) +{ + bufferlist in, out; + cls_rgw_lc_put_head_op call; + call.head = head; + ::encode(call, in); + int r = io_ctx.exec(oid, "rgw", "lc_put_head", in, out); + return r; +} + +int cls_rgw_lc_get_next_entry(IoCtx& io_ctx, string& oid, string& marker, pair<string, int>& entry) +{ + bufferlist in, out; + cls_rgw_lc_get_next_entry_op call; + call.marker = marker; + ::encode(call, in); + int r = io_ctx.exec(oid, "rgw", "lc_get_next_entry", in, out); + if (r < 0) + return r; + + cls_rgw_lc_get_next_entry_ret ret; + try { + bufferlist::iterator iter = out.begin(); + ::decode(ret, iter); + } catch (buffer::error& err) { + return -EIO; + } + entry = ret.entry; + + return r; +} + +int cls_rgw_lc_rm_entry(IoCtx& io_ctx, string& oid, pair<string, int>& entry) +{ + bufferlist in, out; + cls_rgw_lc_rm_entry_op call; + call.entry = entry; + ::encode(call, in); + int r = io_ctx.exec(oid, "rgw", "lc_rm_entry", in, out); + return r; +} + +int cls_rgw_lc_set_entry(IoCtx& io_ctx, string& oid, pair<string, int>& entry) +{ + bufferlist in, out; + cls_rgw_lc_rm_entry_op call; + call.entry = entry; + ::encode(call, in); + int r = io_ctx.exec(oid, "rgw", "lc_set_entry", in, out); + return r; +} + +int cls_rgw_lc_list(IoCtx& io_ctx, string& oid, + const string& marker, + uint32_t max_entries, + map<string, int>& entries) +{ + bufferlist in, out; + cls_rgw_lc_list_entries_op op; + + entries.clear(); + + op.marker = marker; + op.max_entries = max_entries; + + ::encode(op, in); + + int r = io_ctx.exec(oid, "rgw", "lc_list_entries", in, out); + if (r < 0) + return r; + + cls_rgw_lc_list_entries_ret ret; + try { + bufferlist::iterator iter = out.begin(); + ::decode(ret, iter); + } catch (buffer::error& err) { + return -EIO; + } + entries.insert(ret.entries.begin(),ret.entries.end()); + + return r; +} diff --git a/src/cls/rgw/cls_rgw_client.h b/src/cls/rgw/cls_rgw_client.h index 1b02a5eabf4..4c68385f5a8 100644 --- a/src/cls/rgw/cls_rgw_client.h +++ b/src/cls/rgw/cls_rgw_client.h @@ -474,4 +474,20 @@ int cls_rgw_gc_list(librados::IoCtx& io_ctx, string& oid, string& marker, uint32 void cls_rgw_gc_remove(librados::ObjectWriteOperation& op, const list<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, + const string& marker, + uint32_t max_entries, + map<string, int>& entries); + + + + + + #endif diff --git a/src/cls/rgw/cls_rgw_ops.h b/src/cls/rgw/cls_rgw_ops.h index 15a638a3923..4aed26b4f5e 100644 --- a/src/cls/rgw/cls_rgw_ops.h +++ b/src/cls/rgw/cls_rgw_ops.h @@ -937,4 +937,162 @@ struct cls_rgw_bi_log_list_ret { }; WRITE_CLASS_ENCODER(cls_rgw_bi_log_list_ret) +struct cls_rgw_lc_get_next_entry_op { + string marker; + cls_rgw_lc_get_next_entry_op() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(marker, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(marker, bl); + DECODE_FINISH(bl); + } +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_get_next_entry_op) + +struct cls_rgw_lc_get_next_entry_ret { + pair<string, int> entry; + + cls_rgw_lc_get_next_entry_ret() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(entry, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(entry, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_get_next_entry_ret) + +struct cls_rgw_lc_rm_entry_op { + pair<string, int> entry; + cls_rgw_lc_rm_entry_op() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(entry, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(entry, bl); + DECODE_FINISH(bl); + } +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_rm_entry_op) + +struct cls_rgw_lc_set_entry_op { + pair<string, int> entry; + cls_rgw_lc_set_entry_op() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(entry, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(entry, bl); + DECODE_FINISH(bl); + } +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_set_entry_op) + +struct cls_rgw_lc_put_head_op { + cls_rgw_lc_obj_head head; + + + cls_rgw_lc_put_head_op() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(head, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(head, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_put_head_op) + +struct cls_rgw_lc_get_head_ret { + cls_rgw_lc_obj_head head; + + cls_rgw_lc_get_head_ret() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(head, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(head, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_get_head_ret) + +struct cls_rgw_lc_list_entries_op { + string marker; + uint32_t max_entries; + + cls_rgw_lc_list_entries_op() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(marker, bl); + ::encode(max_entries, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(marker, bl); + ::decode(max_entries, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_list_entries_op) + +struct cls_rgw_lc_list_entries_ret { + map<string, int> entries; + + cls_rgw_lc_list_entries_ret() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(entries, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(entries, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_list_entries_ret) + #endif /* CEPH_CLS_RGW_OPS_H */ diff --git a/src/cls/rgw/cls_rgw_types.h b/src/cls/rgw/cls_rgw_types.h index cf143ce92cc..7527db7c727 100644 --- a/src/cls/rgw/cls_rgw_types.h +++ b/src/cls/rgw/cls_rgw_types.h @@ -532,7 +532,7 @@ struct rgw_bi_log_entry { void dump(Formatter *f) const; void decode_json(JSONObj *obj); static void generate_test_instances(list<rgw_bi_log_entry*>& o); - + bool is_versioned() { return ((bilog_flags & RGW_BILOG_FLAG_VERSIONED_OP) != 0); } @@ -794,7 +794,7 @@ struct rgw_user_bucket { return true; else if (!comp) return bucket.compare(ub2.bucket) < 0; - + return false; } }; @@ -930,4 +930,28 @@ struct cls_rgw_gc_obj_info }; WRITE_CLASS_ENCODER(cls_rgw_gc_obj_info) +struct cls_rgw_lc_obj_head +{ + time_t start_date; + string marker; + + cls_rgw_lc_obj_head() {} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(start_date, bl); + ::encode(marker, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(start_date, bl); + ::decode(marker, bl); + DECODE_FINISH(bl); + } + +}; +WRITE_CLASS_ENCODER(cls_rgw_lc_obj_head) + #endif |