cls_method_handle_t h_log_add;
cls_method_handle_t h_log_list;
cls_method_handle_t h_log_trim;
+cls_method_handle_t h_log_info;
static string log_index_prefix = "1_";
index = log_index_prefix + buf;
}
+static int read_header(cls_method_context_t hctx, cls_log_header& header)
+{
+ bufferlist header_bl;
+
+ int ret = cls_cxx_map_read_header(hctx, &header_bl);
+ if (ret < 0)
+ return ret;
+
+ if (header_bl.length() == 0) {
+ header = cls_log_header();
+ return 0;
+ }
+
+ bufferlist::iterator iter = header_bl.begin();
+ try {
+ ::decode(header, iter);
+ } catch (buffer::error& err) {
+ CLS_LOG(0, "ERROR: read_header(): failed to decode header");
+ }
+
+ return 0;
+}
+
+static int write_header(cls_method_context_t hctx, cls_log_header& header)
+{
+ bufferlist header_bl;
+ ::encode(header, header_bl);
+
+ int ret = cls_cxx_map_write_header(hctx, &header_bl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static void get_index(cls_method_context_t hctx, utime_t& ts, string& index)
{
get_index_time_prefix(ts, index);
return -EINVAL;
}
+ cls_log_header header;
+
+ int ret = read_header(hctx, header);
+ if (ret < 0)
+ return ret;
+
for (list<cls_log_entry>::iterator iter = op.entries.begin();
iter != op.entries.end(); ++iter) {
cls_log_entry& entry = *iter;
string index;
- get_index(hctx, entry.timestamp, index);
+ utime_t timestamp = entry.timestamp;
+ if (timestamp < header.max_time)
+ timestamp = header.max_time;
+ else if (timestamp > header.max_time)
+ header.max_time = timestamp;
+
+ get_index(hctx, timestamp, index);
CLS_LOG(0, "storing entry at %s", index.c_str());
entry.id = index;
- int ret = write_log_entry(hctx, index, entry);
+ if (index > header.max_marker)
+ header.max_marker = index;
+
+ ret = write_log_entry(hctx, index, entry);
if (ret < 0)
return ret;
}
-
+
+ ret = write_header(hctx, header);
+ if (ret < 0)
+ return ret;
+
return 0;
}
return 0;
}
+static int cls_log_info(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+ bufferlist::iterator in_iter = in->begin();
+
+ cls_log_info_op op;
+ try {
+ ::decode(op, in_iter);
+ } catch (buffer::error& err) {
+ CLS_LOG(1, "ERROR: cls_log_add_op(): failed to decode op");
+ return -EINVAL;
+ }
+
+ cls_log_info_ret ret;
+
+ int rc = read_header(hctx, ret.header);
+ if (rc < 0)
+ return rc;
+
+ ::encode(ret, *out);
+
+ return 0;
+}
+
void __cls_init()
{
CLS_LOG(1, "Loaded log class!");
cls_register_cxx_method(h_class, "add", CLS_METHOD_RD | CLS_METHOD_WR, cls_log_add, &h_log_add);
cls_register_cxx_method(h_class, "list", CLS_METHOD_RD, cls_log_list, &h_log_list);
cls_register_cxx_method(h_class, "trim", CLS_METHOD_RD | CLS_METHOD_WR, cls_log_trim, &h_log_trim);
+ cls_register_cxx_method(h_class, "info", CLS_METHOD_RD, cls_log_info, &h_log_info);
return;
}
op.exec("log", "list", inbl, new LogListCtx(&entries, out_marker, truncated));
}
+class LogInfoCtx : public ObjectOperationCompletion {
+ cls_log_header *header;
+public:
+ LogInfoCtx(cls_log_header *_header) : header(_header) {}
+ void handle_completion(int r, bufferlist& outbl) {
+ if (r >= 0) {
+ cls_log_info_ret ret;
+ try {
+ bufferlist::iterator iter = outbl.begin();
+ ::decode(ret, iter);
+ if (header)
+ *header = ret.header;
+ } catch (buffer::error& err) {
+ // nothing we can do about it atm
+ }
+ }
+ }
+};
+
+void cls_log_info(librados::ObjectReadOperation& op, cls_log_header *header)
+{
+ bufferlist inbl;
+ cls_log_info_op call;
+
+ ::encode(call, inbl);
+
+ op.exec("log", "info", inbl, new LogInfoCtx(header));
+}
+
};
WRITE_CLASS_ENCODER(cls_log_trim_op)
+struct cls_log_info_op {
+ cls_log_info_op() {}
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ // currently empty request
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::iterator& bl) {
+ DECODE_START(1, bl);
+ // currently empty request
+ DECODE_FINISH(bl);
+ }
+};
+WRITE_CLASS_ENCODER(cls_log_info_op)
+
+struct cls_log_info_ret {
+ cls_log_header header;
+
+ void encode(bufferlist& bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(header, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(bufferlist::iterator& bl) {
+ DECODE_START(1, bl);
+ ::decode(header, bl);
+ DECODE_FINISH(bl);
+ }
+};
+WRITE_CLASS_ENCODER(cls_log_info_ret)
+
#endif