]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add create timestamp metadata for image
authorrunsisi <runsisi@zte.com.cn>
Fri, 21 Apr 2017 08:32:33 +0000 (16:32 +0800)
committerrunsisi <runsisi@zte.com.cn>
Tue, 20 Jun 2017 05:52:06 +0000 (13:52 +0800)
Signed-off-by: runsisi <runsisi@zte.com.cn>
src/cls/rbd/cls_rbd.cc
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/image/OpenRequest.cc
src/librbd/image/OpenRequest.h
src/librbd/librbd.cc
src/tracing/librbd.tp

index cb0d1fdcddacfea1e8d21638082c5d9427b517a2..3eb64a45a5c88bd0b96be5fc7e65dd95c46e57de 100644 (file)
@@ -223,12 +223,15 @@ int create(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
   bufferlist featuresbl;
   bufferlist object_prefixbl;
   bufferlist snap_seqbl;
+  bufferlist create_timestampbl;
   uint64_t snap_seq = 0;
+  utime_t create_timestamp = ceph_clock_now();
   ::encode(size, sizebl);
   ::encode(order, orderbl);
   ::encode(features, featuresbl);
   ::encode(object_prefix, object_prefixbl);
   ::encode(snap_seq, snap_seqbl);
+  ::encode(create_timestamp, create_timestampbl);
 
   map<string, bufferlist> omap_vals;
   omap_vals["size"] = sizebl;
@@ -236,6 +239,7 @@ int create(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
   omap_vals["features"] = featuresbl;
   omap_vals["object_prefix"] = object_prefixbl;
   omap_vals["snap_seq"] = snap_seqbl;
+  omap_vals["create_timestamp"] = create_timestampbl;
 
   if (features & RBD_FEATURE_DATA_POOL) {
     if (data_pool_id == -1) {
@@ -769,6 +773,32 @@ int set_stripe_unit_count(cls_method_context_t hctx, bufferlist *in, bufferlist
   return 0;
 }
 
+int get_create_timestamp(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  CLS_LOG(20, "get_create_timestamp");
+
+  utime_t timestamp;
+  bufferlist bl;
+  int r = cls_cxx_map_get_val(hctx, "create_timestamp", &bl);
+  if (r < 0) {
+    if (r != -ENOENT) {
+      CLS_ERR("error reading create_timestamp: %s", cpp_strerror(r).c_str());
+      return r;
+    }
+  } else {
+    try {
+      bufferlist::iterator it = bl.begin();
+      ::decode(timestamp, it);
+    } catch (const buffer::error &err) {
+      CLS_ERR("could not decode create_timestamp");
+      return -EIO;
+    }
+  }
+
+  ::encode(timestamp, *out);
+  return 0;
+}
+
 /**
  * get the image flags
  *
@@ -5079,6 +5109,7 @@ CLS_INIT(rbd)
   cls_method_handle_t h_set_protection_status;
   cls_method_handle_t h_get_stripe_unit_count;
   cls_method_handle_t h_set_stripe_unit_count;
+  cls_method_handle_t h_get_create_timestamp;
   cls_method_handle_t h_get_flags;
   cls_method_handle_t h_set_flags;
   cls_method_handle_t h_remove_parent;
@@ -5227,6 +5258,9 @@ CLS_INIT(rbd)
   cls_register_cxx_method(h_class, "set_stripe_unit_count",
                          CLS_METHOD_RD | CLS_METHOD_WR,
                          set_stripe_unit_count, &h_set_stripe_unit_count);
+  cls_register_cxx_method(h_class, "get_create_timestamp",
+                          CLS_METHOD_RD,
+                          get_create_timestamp, &h_get_create_timestamp);
   cls_register_cxx_method(h_class, "get_flags",
                           CLS_METHOD_RD,
                           get_flags, &h_get_flags);
index c1fd48a0d0493b04ae62ff81b1b800a5980be57f..88b5b3d0340e8aa7a90b0c5631ee6047d4e5d32b 100644 (file)
@@ -915,6 +915,39 @@ namespace librbd {
       return ioctx->operate(oid, &op);
     }
 
+    void get_create_timestamp_start(librados::ObjectReadOperation *op) {
+      bufferlist empty_bl;
+      op->exec("rbd", "get_create_timestamp", empty_bl);
+    }
+
+    int get_create_timestamp_finish(bufferlist::iterator *it,
+                                    utime_t *timestamp) {
+      assert(timestamp);
+
+      try {
+        ::decode(*timestamp, *it);
+      } catch (const buffer::error &err) {
+        return -EBADMSG;
+      }
+      return 0;
+    }
+
+    int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
+                             utime_t *timestamp)
+    {
+      librados::ObjectReadOperation op;
+      get_create_timestamp_start(&op);
+
+      bufferlist out_bl;
+      int r = ioctx->operate(oid, &op, &out_bl);
+      if (r < 0) {
+        return r;
+      }
+
+      bufferlist::iterator it = out_bl.begin();
+      return get_create_timestamp_finish(&it, timestamp);
+    }
+
     /************************ rbd_id object methods ************************/
 
     void get_id_start(librados::ObjectReadOperation *op) {
index f43e16e381fd1f1ab1a483e4fee45d4e9281f62d..754017f2deaf856091c4d9719875b6999c1525e9 100644 (file)
@@ -179,6 +179,11 @@ namespace librbd {
                               uint64_t stripe_unit, uint64_t stripe_count);
     int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
                              uint64_t stripe_unit, uint64_t stripe_count);
+    void get_create_timestamp_start(librados::ObjectReadOperation *op);
+    int get_create_timestamp_finish(bufferlist::iterator *it,
+                                    utime_t *timestamp);
+    int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
+                             utime_t *timestamp);
     int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
                       const std::string &start, uint64_t max_return,
                       map<string, bufferlist> *pairs);
index 87d04eb44706badce71dab6c8683437b46e58e2e..dca8f42370413a6c0b56f5afcea611a1e85d1a21 100644 (file)
@@ -364,6 +364,10 @@ CEPH_RBD_API int rbd_update_features(rbd_image_t image, uint64_t features,
 CEPH_RBD_API int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit);
 CEPH_RBD_API int rbd_get_stripe_count(rbd_image_t image,
                                       uint64_t *stripe_count);
+
+CEPH_RBD_API int rbd_get_create_timestamp(rbd_image_t image,
+                                          struct timespec *timestamp);
+
 CEPH_RBD_API int rbd_get_overlap(rbd_image_t image, uint64_t *overlap);
 CEPH_RBD_API int rbd_get_id(rbd_image_t image, char *id, size_t id_len);
 CEPH_RBD_API int rbd_get_block_name_prefix(rbd_image_t image,
index f03ca9f362209e42549e002249ebd89799aa3928..b8e74569205318816553eeb00b53c22e68f3a638 100644 (file)
@@ -297,6 +297,8 @@ public:
   uint64_t get_stripe_unit() const;
   uint64_t get_stripe_count() const;
 
+  int get_create_timestamp(struct timespec *timestamp);
+
   int flatten();
   int flatten_with_progress(ProgressContext &prog_ctx);
   /**
index e03259ee35c191837530428da620f35404f232fa..fd2333ee105e68d22bbe5ca9f1008db6d14dbd65 100644 (file)
@@ -527,6 +527,11 @@ struct C_InvalidateCache : public Context {
     return stripe_count * (1ull << order);
   }
 
+  utime_t ImageCtx::get_create_timestamp() const
+  {
+    return create_timestamp;
+  }
+
   int ImageCtx::is_snap_protected(snap_t in_snap_id,
                                  bool *is_protected) const
   {
index 23b577ab6e66c167d832b8dd28abe2548cde8bc4..99a02748ef665010eb5db260c2420a23b390e761 100644 (file)
@@ -128,6 +128,7 @@ namespace librbd {
     cls::rbd::GroupSpec group_spec;
     uint64_t stripe_unit, stripe_count;
     uint64_t flags;
+    utime_t create_timestamp;
 
     file_layout_t layout;
 
@@ -254,6 +255,7 @@ namespace librbd {
     uint64_t get_stripe_unit() const;
     uint64_t get_stripe_count() const;
     uint64_t get_stripe_period() const;
+    utime_t get_create_timestamp() const;
 
     void add_snap(cls::rbd::SnapshotNamespace in_snap_namespace,
                  std::string in_snap_name,
index 579088b3cf03ff316de0ebdad23ce85a949ffca5..5b13f519602b19e52ce981c768a02265020d9daf 100644 (file)
@@ -322,6 +322,45 @@ Context *OpenRequest<I>::handle_v2_get_stripe_unit_count(int *result) {
     return nullptr;
   }
 
+  send_v2_get_create_timestamp();
+  return nullptr;
+}
+
+template <typename I>
+void OpenRequest<I>::send_v2_get_create_timestamp() {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  librados::ObjectReadOperation op;
+  cls_client::get_create_timestamp_start(&op);
+
+  using klass = OpenRequest<I>;
+  librados::AioCompletion *comp = create_rados_callback<
+    klass, &klass::handle_v2_get_create_timestamp>(this);
+  m_out_bl.clear();
+  m_image_ctx->md_ctx.aio_operate(m_image_ctx->header_oid, comp, &op,
+                                  &m_out_bl);
+  comp->release();
+}
+
+template <typename I>
+Context *OpenRequest<I>::handle_v2_get_create_timestamp(int *result) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;
+
+  if (*result == 0) {
+    bufferlist::iterator it = m_out_bl.begin();
+    *result = cls_client::get_create_timestamp_finish(&it,
+        &m_image_ctx->create_timestamp);
+  }
+  if (*result < 0 && *result != -EOPNOTSUPP) {
+    lderr(cct) << "failed to retrieve create_timestamp: "
+               << cpp_strerror(*result)
+               << dendl;
+    send_close_image(*result);
+    return nullptr;
+  }
+
   send_v2_get_data_pool();
   return nullptr;
 }
index 3ae8602fb4bc9695f837f2748d9ca5eb384a6ce3..5dd088770b710ea3bf5b7f4bd4b05887e07aeacd 100644 (file)
@@ -52,6 +52,9 @@ private:
    *            V2_GET_STRIPE_UNIT_COUNT            |
    *                |                               |
    *                v                               |
+   *            V2_GET_CREATE_TIMESTAMP             |
+   *                |                               |
+   *                v                               |
    *            V2_GET_DATA_POOL                    |
    *                |                               |
    *                v                               |
@@ -105,6 +108,9 @@ private:
   void send_v2_get_stripe_unit_count();
   Context *handle_v2_get_stripe_unit_count(int *result);
 
+  void send_v2_get_create_timestamp();
+  Context *handle_v2_get_create_timestamp(int *result);
+
   void send_v2_get_data_pool();
   Context *handle_v2_get_data_pool(int *result);
 
index 86ddd0a857354f6a247d912ee17d5fe1cd44ce0b..1d5920fccb3087ee81f6472c48effb0c000472db 100644 (file)
@@ -1011,6 +1011,17 @@ namespace librbd {
     return stripe_count;
   }
 
+  int Image::get_create_timestamp(struct timespec *timestamp)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, get_create_timestamp_enter, ictx, ictx->name.c_str(),
+               ictx->read_only);
+    utime_t time = ictx->get_create_timestamp();
+    time.to_timespec(timestamp);
+    tracepoint(librbd, get_create_timestamp_exit, 0, timestamp);
+    return 0;
+  }
+
   int Image::overlap(uint64_t *overlap)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -2817,6 +2828,18 @@ extern "C" int rbd_get_stripe_count(rbd_image_t image, uint64_t *stripe_count)
   return 0;
 }
 
+extern "C"  int rbd_get_create_timestamp(rbd_image_t image,
+                                           struct timespec *timestamp)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, get_create_timestamp_enter, ictx, ictx->name.c_str(),
+             ictx->read_only);
+  utime_t time = ictx->get_create_timestamp();
+  time.to_timespec(timestamp);
+  tracepoint(librbd, get_create_timestamp_exit, 0, timestamp);
+  return 0;
+}
+
 extern "C" int rbd_get_overlap(rbd_image_t image, uint64_t *overlap)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
index 7078390daed9cf4079b6f9346a6d1b4c757c04b6..f8c77142a784254f59686992bc3a013ac7709623 100644 (file)
@@ -1934,6 +1934,28 @@ TRACEPOINT_EVENT(librbd, get_stripe_count_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, get_create_timestamp_enter,
+    TP_ARGS(
+        void*, imagectx,
+        const char*, name,
+        char, read_only),
+    TP_FIELDS(
+        ctf_integer_hex(void*, imagectx, imagectx)
+        ctf_string(name, name)
+        ctf_integer(char, read_only, read_only)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, get_create_timestamp_exit,
+    TP_ARGS(
+        int, retval,
+        struct timespec*, timestamp),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+        ctf_integer(uint64_t, timestamp, timestamp->tv_sec)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, get_features_enter,
     TP_ARGS(
         void*, imagectx,