Consumers of this api need to know their position in the log. It's
readily available when fetching the log, so return it. Without the
marker in this call, a client could not easily or efficiently figure
out its position in the log, since it would require getting the global
last marker in the log, and then reading all the log entries.
This would be slow for large logs, and would be subject to races that
would cause potentially very expensive duplicate work.
Returning this atomically while fetching the log entries simplifies
all of this.
Fixes: #6615
Backport: dumpling
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
(cherry picked from commit
c275912509255f8bb4c854e181318b45ab0f8564)
};
void cls_log_list(librados::ObjectReadOperation& op, utime_t& from, utime_t& to,
- string& in_marker, int max_entries, list<cls_log_entry>& entries,
+ const string& in_marker, int max_entries,
+ list<cls_log_entry>& entries,
string *out_marker, bool *truncated)
{
bufferlist inbl;
const string& section, const string& name, bufferlist& bl);
void cls_log_list(librados::ObjectReadOperation& op, utime_t& from, utime_t& to,
- string& in_marker, int max_entries, list<cls_log_entry>& entries,
+ const string& in_marker, int max_entries,
+ list<cls_log_entry>& entries,
string *out_marker, bool *truncated);
void cls_log_trim(librados::ObjectWriteOperation& op, const utime_t& from_time, const utime_t& to_time,
}
int RGWDataChangesLog::list_entries(int shard, utime_t& start_time, utime_t& end_time, int max_entries,
- list<rgw_data_change>& entries, string& marker, bool *truncated) {
+ list<rgw_data_change>& entries,
+ const string& marker,
+ string *out_marker,
+ bool *truncated) {
list<cls_log_entry> log_entries;
int ret = store->time_log_list(oids[shard], start_time, end_time,
- max_entries, log_entries, marker, truncated);
+ max_entries, log_entries, marker,
+ out_marker, truncated);
if (ret < 0)
return ret;
for (; marker.shard < num_shards && (int)entries.size() < max_entries;
marker.shard++, marker.marker.clear()) {
int ret = list_entries(marker.shard, start_time, end_time, max_entries - entries.size(), entries,
- marker.marker, &truncated);
+ marker.marker, NULL, &truncated);
if (ret == -ENOENT) {
continue;
}
int add_entry(rgw_bucket& bucket);
int renew_entries();
int list_entries(int shard, utime_t& start_time, utime_t& end_time, int max_entries,
- list<rgw_data_change>& entries, string& marker, bool *truncated);
+ list<rgw_data_change>& entries,
+ const string& marker,
+ string *out_marker,
+ bool *truncated);
int trim_entries(int shard_id, const utime_t& start_time, const utime_t& end_time,
const string& start_marker, const string& end_marker);
int trim_entries(const utime_t& start_time, const utime_t& end_time,
}
int RGWRados::time_log_list(const string& oid, utime_t& start_time, utime_t& end_time,
- int max_entries, list<cls_log_entry>& entries, string& marker, bool *truncated)
+ int max_entries, list<cls_log_entry>& entries,
+ const string& marker,
+ string *out_marker,
+ bool *truncated)
{
librados::IoCtx io_ctx;
return r;
librados::ObjectReadOperation op;
- cls_log_list(op, start_time, end_time, marker, max_entries, entries, &marker, truncated);
+ cls_log_list(op, start_time, end_time, marker, max_entries, entries,
+ out_marker, truncated);
bufferlist obl;
int time_log_add(const string& oid, list<cls_log_entry>& entries);
int time_log_add(const string& oid, const utime_t& ut, const string& section, const string& key, bufferlist& bl);
int time_log_list(const string& oid, utime_t& start_time, utime_t& end_time,
- int max_entries, list<cls_log_entry>& entries, string& marker, bool *truncated);
+ int max_entries, list<cls_log_entry>& entries,
+ const string& marker, string *out_marker, bool *truncated);
int time_log_info(const string& oid, cls_log_header *header);
int time_log_trim(const string& oid, const utime_t& start_time, const utime_t& end_time,
const string& from_marker, const string& to_marker);
}
}
- bool truncated;
do {
+ // Note that last_marker is updated to be the marker of the last
+ // entry listed
http_ret = store->data_log->list_entries(shard_id, ut_st, ut_et,
- max_entries, entries, marker, &truncated);
+ max_entries, entries, marker,
+ &last_marker, &truncated);
if (http_ret < 0)
break;
if (http_ret < 0)
return;
- s->formatter->open_array_section("entries");
- for (list<rgw_data_change>::iterator iter = entries.begin();
- iter != entries.end(); ++iter) {
- rgw_data_change& entry = *iter;
- encode_json("entry", entry, s->formatter);
- flusher.flush();
+ s->formatter->open_object_section("log_entries");
+ s->formatter->dump_string("marker", last_marker);
+ s->formatter->dump_bool("truncated", truncated);
+ {
+ s->formatter->open_array_section("entries");
+ for (list<rgw_data_change>::iterator iter = entries.begin();
+ iter != entries.end(); ++iter) {
+ rgw_data_change& entry = *iter;
+ encode_json("entry", entry, s->formatter);
+ flusher.flush();
+ }
+ s->formatter->close_section();
}
s->formatter->close_section();
flusher.flush();
class RGWOp_DATALog_List : public RGWRESTOp {
list<rgw_data_change> entries;
+ string last_marker;
+ bool truncated;
int http_ret;
public:
- RGWOp_DATALog_List() : http_ret(0) {}
+ RGWOp_DATALog_List() : truncated(false), http_ret(0) {}
~RGWOp_DATALog_List() {}
int check_caps(RGWUserCaps& caps) {