]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: Add metadata_get method to support single metadata key retrieve
authorHaomai Wang <haomaiwang@gmail.com>
Mon, 9 Mar 2015 07:19:04 +0000 (15:19 +0800)
committerHaomai Wang <haomaiwang@gmail.com>
Fri, 13 Mar 2015 14:52:42 +0000 (22:52 +0800)
Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
man/rbd.8
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/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/rbd.cc
src/tracing/librbd.tp

index 693403c5bbaa4575a4f6f3af52c3a2015aa5f4a3..1605785dce43daad9af738dd0c150cdc1465d0c2 100644 (file)
--- a/man/rbd.8
+++ b/man/rbd.8
@@ -301,14 +301,17 @@ dest\-image will have the same size, order, and image format as src\-image.
 .B \fBmv\fP [\fIsrc\-image\fP] [\fIdest\-image\fP]
 Renames an image.  Note: rename across pools is not supported.
 .TP
-.B \fBmetadata-list\fP [\fIimage\-name\fP]
+.B \fBimage-meta list\fP [\fIimage\-name\fP]
 Show metadata held on the image. The first column is the key
 and the second column is the value.
 .TP
-.B \fBmetadata-set\fP [\fIimage\-name\fP] [\fIkey\fP] [\fIvalue\fP]
+.B \fBimage-meta get\fP [\fIimage\-name\fP] [\fIkey\fP]
+Get metadata value with the key.
+.TP
+.B \fBimage-meta set\fP [\fIimage\-name\fP] [\fIkey\fP] [\fIvalue\fP]
 Set metadata key with the value. They will displayed in \fImetadata-list\fP
 .TP
-.B \fBmetadata-remove\fP [\fIimage\-name\fP] [\fIkey\fP]
+.B \fBimage-meta remove\fP [\fIimage\-name\fP] [\fIkey\fP]
 Remove metadata key with the value.
 .TP
 .B \fBsnap\fP ls [\fIimage\-name\fP]
index 0cd85d0a27306220443d0b77e6b1dd06a91329a3..4ae07aea7a8919105713f8322e76154781a580ec 100644 (file)
@@ -99,6 +99,7 @@ cls_method_handle_t h_object_map_update;
 cls_method_handle_t h_metadata_set;
 cls_method_handle_t h_metadata_remove;
 cls_method_handle_t h_metadata_list;
+cls_method_handle_t h_metadata_get;
 cls_method_handle_t h_old_snapshots_list;
 cls_method_handle_t h_old_snapshot_add;
 cls_method_handle_t h_old_snapshot_remove;
@@ -2227,6 +2228,37 @@ int metadata_remove(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
   return 0;
 }
 
+/**
+ * Input:
+ * @param key
+ *
+ * Output:
+ * @param metadata value associated with the key
+ * @returns 0 on success, negative error code on failure
+ */
+int metadata_get(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
+{
+  string key, value;
+
+  bufferlist::iterator iter = in->begin();
+  try {
+    ::decode(key, iter);
+  } catch (const buffer::error &err) {
+    return -EINVAL;
+  }
+
+  CLS_LOG(20, "metdata_get key=%s", key.c_str());
+
+  int r = read_key(hctx, metadata_key_for_name(key), &value);
+  if (r < 0) {
+    CLS_ERR("error get metadata: %d", r);
+    return r;
+  }
+
+  ::encode(value, *out);
+  return 0;
+}
+
 
 /****************************** Old format *******************************/
 
@@ -2498,6 +2530,9 @@ void __cls_init()
   cls_register_cxx_method(h_class, "metadata_remove",
                           CLS_METHOD_RD | CLS_METHOD_WR,
                          metadata_remove, &h_metadata_remove);
+  cls_register_cxx_method(h_class, "metadata_get",
+                          CLS_METHOD_RD,
+                         metadata_get, &h_metadata_get);
 
   /* methods for the rbd_children object */
   cls_register_cxx_method(h_class, "add_child",
index bd6f78921c949e70beae5edd300a84f9bb632336..77864e777bbae26a9999c252978bb5bffab0058e 100644 (file)
@@ -786,5 +786,26 @@ namespace librbd {
 
       return 0;
     }
+
+    int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
+                     const std::string &key, string *s)
+    {
+      assert(s);
+      bufferlist in, out;
+      ::encode(key, in);
+      int r = ioctx->exec(oid, "rbd", "metadata_get", in, out);
+      if (r < 0)
+        return r;
+
+      bufferlist::iterator iter = out.begin();
+      try {
+        ::decode(*s, iter);
+      } catch (const buffer::error &err) {
+        return -EBADMSG;
+      }
+
+      return 0;
+    }
+
   } // namespace cls_client
 } // namespace librbd
index c3a44bfc2cdde1314636893b9eaec6cbd98cbf0d..174a2aa5b07c8285f8f5e531296c7e98f1b27b94 100644 (file)
@@ -87,6 +87,14 @@ 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);
+    int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
+                      map<string, string> *pairs);
+    int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
+                     const std::string &key, const std::string &data);
+    int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
+                        const std::string &key);
+    int metadata_get(librados::IoCtx *ioctx, const std::string &oid,
+                     const std::string &key, string *v);
 
     // operations on rbd_id objects
     int get_id(librados::IoCtx *ioctx, const std::string &oid, std::string *id);
@@ -119,14 +127,6 @@ namespace librbd {
                           uint8_t new_object_state,
                           const boost::optional<uint8_t> &current_object_state);
 
-    // operations on the rbd_object_map.$image_id object
-    int metadata_set(librados::IoCtx *ioctx, const std::string &oid,
-                     const std::string &key, const std::string &data);
-    int metadata_remove(librados::IoCtx *ioctx, const std::string &oid,
-                        const std::string &key);
-    int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
-                      map<string, string> *pairs);
-
     // class operations on the old format, kept for
     // backwards compatability
     int old_snapshot_add(librados::IoCtx *ioctx, const std::string &oid,
index 016fd0cc5c392173c239d5e178db82e82ae2aae0..c578840553b519872cb791d4a54b849abd897ae8 100644 (file)
@@ -443,6 +443,7 @@ CEPH_RBD_API int rbd_aio_flush(rbd_image_t image, rbd_completion_t c);
  */
 CEPH_RBD_API int rbd_invalidate_cache(rbd_image_t image);
 
+CEPH_RBD_API int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *val_len);
 CEPH_RBD_API int rbd_metadata_set(rbd_image_t image, const char *key, const char *value);
 CEPH_RBD_API int rbd_metadata_remove(rbd_image_t image, const char *key);
 /**
index 136e20d08cacd8ab86e8947bdf3de7c790366cfc..8beeb9659e300881988597f3b1584594f25aa2bc 100644 (file)
@@ -241,6 +241,7 @@ public:
    */
   int invalidate_cache();
 
+  int metadata_get(const std::string &key, std::string *value);
   int metadata_set(const std::string &key, const std::string &value);
   int metadata_remove(const std::string &key);
   /**
index 8ccc02598e9d09b604b53f4fc01bac503e15f0f9..36699b27bd2dc5a4238958d1b5c6013a2e8258a9 100644 (file)
@@ -3371,6 +3371,19 @@ reprotect_and_return_err:
     return r;
   }
 
+  int metadata_get(ImageCtx *ictx, const string &key, string *value)
+  {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << "metadata_get " << ictx << " key=" << key << dendl;
+
+    int r = ictx_check(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    return cls_client::metadata_get(&ictx->md_ctx, ictx->header_oid, key, value);
+  }
+
   int metadata_set(ImageCtx *ictx, const string &key, const string &value)
   {
     CephContext *cct = ictx->cct;
index 13a48a6964d804922190fd4dff30f3f9b2c0e7b2..3cb63cf94e2d36ac0cf128e4a3f30e4653f514fc 100644 (file)
@@ -208,6 +208,7 @@ namespace librbd {
   int _flush(ImageCtx *ictx);
   int invalidate_cache(ImageCtx *ictx);
   int metadata_list(ImageCtx *ictx, map<string, string> *pairs);
+  int metadata_get(ImageCtx *ictx, const std::string &key, std::string *value);
   int metadata_set(ImageCtx *ictx, const std::string &key, const std::string &value);
   int metadata_remove(ImageCtx *ictx, const std::string &key);
 
index 1369ddb2bb657dd4b4fc3750f4b3e7b9d1a7ad7a..772027790f7582adcbd5e3ff29d2c8be0035b598 100644 (file)
@@ -793,6 +793,18 @@ namespace librbd {
     return r;
   }
 
+  int Image::metadata_get(const std::string &key, std::string *value)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, metadata_get_enter, ictx, key.c_str());
+    int r = librbd::metadata_get(ictx, key, value);
+    if (r < 0)
+      tracepoint(librbd, metadata_get_exit, r, key.c_str(), NULL);
+    else
+      tracepoint(librbd, metadata_get_exit, r, key.c_str(), value->c_str());
+    return r;
+  }
+
   int Image::metadata_set(const std::string &key, const std::string &value)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1731,6 +1743,27 @@ extern "C" int rbd_invalidate_cache(rbd_image_t image)
   return r;
 }
 
+extern "C" int rbd_metadata_get(rbd_image_t image, const char *key, char *value, size_t *vallen)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  string val_s;
+  tracepoint(librbd, metadata_get_enter, ictx, key);
+  int r = librbd::metadata_get(ictx, key, &val_s);
+  if (r < 0) {
+    tracepoint(librbd, metadata_get_exit, r, key, NULL);
+    return r;
+  }
+  if (*vallen < val_s.size()) {
+    r = -ERANGE;
+    *vallen = val_s.size();
+    tracepoint(librbd, metadata_get_exit, r, key, NULL);
+  } else {
+    strncpy(value, val_s.c_str(), val_s.size());
+    tracepoint(librbd, metadata_get_exit, r, key, value);
+  }
+  return r;
+}
+
 extern "C" int rbd_metadata_set(rbd_image_t image, const char *key, const char *value)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
index 647a864b6a3bd4e33f03cfc4b168645056b1f645..695a977e15469ef1c02d98d38b370712beb19ebf 100644 (file)
@@ -114,9 +114,10 @@ void usage()
 "                                              path or \"-\" for stdin\n"
 "  (cp | copy) <src> <dest>                    copy src image to dest\n"
 "  (mv | rename) <src> <dest>                  rename src image to dest\n"
-"  metadata-set <key> <value>                  metadata set key with value\n"
-"  metadata-remove <key>                       metadata remove key\n"
-"  metadata-list                               metadata list keys with values\n"
+"  image-meta list <image-name>                image metadata list keys with values\n"
+"  image-meta get <image-name> <key>           image metadata get the value associated with the key\n"
+"  image-meta set <image-name> <key> <value>   image metadata set key with value\n"
+"  image-meta remove <image-name> <key>        image metadata remove the key and value associated\n"
 "  snap ls <image-name>                        dump list of image snapshots\n"
 "  snap create <snap-name>                     create a snapshot\n"
 "  snap rollback <snap-name>                   rollback image to snapshot\n"
@@ -2156,6 +2157,16 @@ static int do_metadata_remove(librbd::Image& image, const char *key)
   return image.metadata_remove(key);
 }
 
+static int do_metadata_get(librbd::Image& image, const char *key)
+{
+  string s;
+  int r = image.metadata_get(key, &s);
+  if (r < 0)
+    return r;
+  cout << s;
+  return 0;
+}
+
 static int do_copy(librbd::Image &src, librados::IoCtx& dest_pp,
                   const char *destname)
 {
@@ -2517,12 +2528,13 @@ enum {
   OPT_LOCK_REMOVE,
   OPT_BENCH_WRITE,
   OPT_MERGE_DIFF,
+  OPT_METADATA_LIST,
   OPT_METADATA_SET,
+  OPT_METADATA_GET,
   OPT_METADATA_REMOVE,
-  OPT_METADATA_LIST,
 };
 
-static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd)
+static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd, bool metacmd)
 {
   if (!snapcmd && !lockcmd) {
     if (strcmp(cmd, "ls") == 0 ||
@@ -2572,12 +2584,6 @@ static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd)
       return OPT_UNMAP;
     if (strcmp(cmd, "bench-write") == 0)
       return OPT_BENCH_WRITE;
-    if (strcmp(cmd, "metadata-set") == 0)
-      return OPT_METADATA_SET;
-    if (strcmp(cmd, "metadata-remove") == 0)
-      return OPT_METADATA_REMOVE;
-    if (strcmp(cmd, "metadata-list") == 0)
-      return OPT_METADATA_LIST;
   } else if (snapcmd) {
     if (strcmp(cmd, "create") == 0 ||
         strcmp(cmd, "add") == 0)
@@ -2597,6 +2603,15 @@ static int get_cmd(const char *cmd, bool snapcmd, bool lockcmd)
       return OPT_SNAP_PROTECT;
     if (strcmp(cmd, "unprotect") == 0)
       return OPT_SNAP_UNPROTECT;
+  } else if (metacmd) {
+    if (strcmp(cmd, "list") == 0)
+      return OPT_METADATA_LIST;
+    if (strcmp(cmd, "set") == 0)
+      return OPT_METADATA_SET;
+    if (strcmp(cmd, "get") == 0)
+      return OPT_METADATA_GET;
+    if (strcmp(cmd, "remove") == 0)
+      return OPT_METADATA_REMOVE;
   } else {
     if (strcmp(cmd, "ls") == 0 ||
         strcmp(cmd, "list") == 0)
@@ -2807,16 +2822,23 @@ int main(int argc, const char **argv)
       cerr << "rbd: which snap command do you want?" << std::endl;
       return EXIT_FAILURE;
     }
-    opt_cmd = get_cmd(*i, true, false);
+    opt_cmd = get_cmd(*i, true, false, false);
   } else if (strcmp(*i, "lock") == 0) {
     i = args.erase(i);
     if (i == args.end()) {
       cerr << "rbd: which lock command do you want?" << std::endl;
       return EXIT_FAILURE;
     }
-    opt_cmd = get_cmd(*i, false, true);
+    opt_cmd = get_cmd(*i, false, true, false);
+  } else if (strcmp(*i, "image-meta") == 0) {
+    i = args.erase(i);
+    if (i == args.end()) {
+      cerr << "rbd: which image-meta command do you want?" << std::endl;
+      return EXIT_FAILURE;
+    }
+    opt_cmd = get_cmd(*i, false, false, true);
   } else {
-    opt_cmd = get_cmd(*i, false, false);
+    opt_cmd = get_cmd(*i, false, false, false);
   }
   if (opt_cmd == OPT_NO_CMD) {
     cerr << "rbd: error parsing command '" << *i << "'; -h or --help for usage" << std::endl;
@@ -2895,6 +2917,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \
       case OPT_METADATA_SET:
        SET_CONF_PARAM(v, &imgname, &key, &value);
        break;
+      case OPT_METADATA_GET:
       case OPT_METADATA_REMOVE:
        SET_CONF_PARAM(v, &imgname, &key, NULL);
        break;
@@ -3128,7 +3151,8 @@ if (!set_conf_param(v, p1, p2, p3)) { \
        opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT_DIFF || opt_cmd == OPT_COPY ||
        opt_cmd == OPT_DIFF ||
        opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST ||
-       opt_cmd == OPT_METADATA_SET || opt_cmd == OPT_METADATA_LIST || opt_cmd == OPT_METADATA_REMOVE ||
+       opt_cmd == OPT_METADATA_SET || opt_cmd == OPT_METADATA_LIST ||
+       opt_cmd == OPT_METADATA_REMOVE || opt_cmd == OPT_METADATA_GET ||
        opt_cmd == OPT_STATUS)) {
 
     if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
@@ -3566,6 +3590,14 @@ if (!set_conf_param(v, p1, p2, p3)) { \
       return -r;
     }
     break;
+
+  case OPT_METADATA_GET:
+    r = do_metadata_get(image, key);
+    if (r < 0) {
+      cerr << "rbd: getting metadata failed: " << cpp_strerror(r) << std::endl;
+      return -r;
+    }
+    break;
   }
 
   return 0;
index fd74475f9f600aee94cf6de593883e22f4caf448..bf2c6f4f0dbd8b9724df65746e44a8fa54635a7a 100644 (file)
@@ -479,6 +479,28 @@ TRACEPOINT_EVENT(librbd, invalidate_cache_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, metadata_get_enter,
+    TP_ARGS(
+        void*, imagectx,
+        const char*, key),
+    TP_FIELDS(
+        ctf_integer_hex(void*, imagectx, imagectx)
+        ctf_string(key, key)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, metadata_get_exit,
+    TP_ARGS(
+        int, retval,
+        const char*, key,
+        const char*, value),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+        ctf_string(key, key)
+        ctf_string(value, value)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, metadata_set_enter,
     TP_ARGS(
         void*, imagectx,