]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cls_log: store info in header, new op to retrieve it
authorYehuda Sadeh <yehuda@inktank.com>
Tue, 2 Jul 2013 22:38:49 +0000 (15:38 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Tue, 2 Jul 2013 22:38:49 +0000 (15:38 -0700)
Keep max_timestamp, max_marker. Add a new op to retrieve header.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/cls/log/cls_log.cc
src/cls/log/cls_log_client.cc
src/cls/log/cls_log_client.h
src/cls/log/cls_log_ops.h
src/cls/log/cls_log_types.h

index 8c62b5a9a688edbaca06ba73d85d80f373d49991..46ba357480c5dc73a65745044b108ac5d689f0bf 100644 (file)
@@ -23,6 +23,7 @@ cls_handle_t h_class;
 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_";
 
@@ -47,6 +48,41 @@ static void get_index_time_prefix(utime_t& ts, string& index)
   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);
@@ -70,23 +106,42 @@ static int cls_log_add(cls_method_context_t hctx, bufferlist *in, bufferlist *ou
     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;
 }
 
@@ -230,6 +285,29 @@ static int cls_log_trim(cls_method_context_t hctx, bufferlist *in, bufferlist *o
   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!");
@@ -240,6 +318,7 @@ void __cls_init()
   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;
 }
index 0e3aa85b827b220278173cbab28d85e9379ea596..ea8adf11145de52d293d2d3d9929df9a64b86ffb 100644 (file)
@@ -122,3 +122,32 @@ void cls_log_list(librados::ObjectReadOperation& op, utime_t& from, utime_t& to,
   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));
+}
+
index afda05597c2adf38dac04611b052b482659245aa..3b4c96d1d3a13701517fd04e6a861308a93ee302 100644 (file)
@@ -26,4 +26,6 @@ void cls_log_trim(librados::ObjectWriteOperation& op, const utime_t& from_time,
 int cls_log_trim(librados::IoCtx& io_ctx, const string& oid, const utime_t& from_time, const utime_t& to_time,
                  const string& from_marker, const string& to_marker);
 
+void cls_log_info(librados::ObjectReadOperation& op, cls_log_header *header);
+
 #endif
index dac232d76d2ca452168bc6ab194cbe16d6696e4b..6bcb69d1334f705bbeb283c977e6d2cd8ae03700 100644 (file)
@@ -115,4 +115,38 @@ struct cls_log_trim_op {
 };
 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
index 13dd7a34a9590ffcfcae82acbe7b53da11e27bf9..7d9679488ddcd398a453e6e934583679de72912a 100644 (file)
@@ -41,6 +41,26 @@ struct cls_log_entry {
 };
 WRITE_CLASS_ENCODER(cls_log_entry)
 
+struct cls_log_header {
+  string max_marker;
+  utime_t max_time;
+
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    ::encode(max_marker, bl);
+    ::encode(max_time, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::iterator& bl) {
+    DECODE_START(1, bl);
+    ::decode(max_marker, bl);
+    ::decode(max_time, bl);
+    DECODE_FINISH(bl);
+  }
+};
+WRITE_CLASS_ENCODER(cls_log_header)
+
 
 #endif