]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: normalize image group C/C++ API
authorJason Dillaman <dillaman@redhat.com>
Tue, 16 Jan 2018 20:08:34 +0000 (15:08 -0500)
committerJason Dillaman <dillaman@redhat.com>
Fri, 26 Jan 2018 15:32:40 +0000 (10:32 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
12 files changed:
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/api/Group.cc
src/librbd/api/Group.h
src/librbd/api/Image.cc
src/librbd/api/Image.h
src/librbd/librbd.cc
src/test/librbd/test_Groups.cc
src/tools/rbd/action/Group.cc
src/tools/rbd/action/Info.cc
src/tools/rbd/action/Remove.cc
src/tools/rbd/action/Snap.cc

index 1a9c41d5bbbd73d80b28a04f8cf3fb86d68bc907..50949add5c1140113a935ad163f76e6776482830 100644 (file)
@@ -1,4 +1,4 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 /*
  * Ceph - scalable distributed file system
@@ -157,17 +157,13 @@ typedef enum {
 typedef struct {
   char *name;
   int64_t pool;
-} rbd_group_image_spec_t;
-
-typedef struct {
-  rbd_group_image_spec_t spec;
   rbd_group_image_state_t state;
-} rbd_group_image_status_t;
+} rbd_group_image_info_t;
 
 typedef struct {
   char *name;
   int64_t pool;
-} rbd_group_spec_t;
+} rbd_group_info_t;
 
 typedef enum {
   RBD_GROUP_SNAP_STATE_INCOMPLETE,
@@ -177,7 +173,7 @@ typedef enum {
 typedef struct {
   char *name;
   rbd_group_snap_state_t state;
-} rbd_group_snap_spec_t;
+} rbd_group_snap_info_t;
 
 typedef enum {
   RBD_SNAP_NAMESPACE_TYPE_USER = 0,
@@ -396,6 +392,7 @@ CEPH_RBD_API int rbd_get_size(rbd_image_t image, uint64_t *size);
 CEPH_RBD_API int rbd_get_features(rbd_image_t image, uint64_t *features);
 CEPH_RBD_API int rbd_update_features(rbd_image_t image, uint64_t features,
                                      uint8_t enabled);
+CEPH_RBD_API int rbd_get_op_features(rbd_image_t image, uint64_t *op_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);
@@ -421,6 +418,8 @@ CEPH_RBD_API int rbd_get_parent_info2(rbd_image_t image,
                                       char *parent_snapname,
                                       size_t psnapnamelen);
 CEPH_RBD_API int rbd_get_flags(rbd_image_t image, uint64_t *flags);
+CEPH_RBD_API int rbd_get_group(rbd_image_t image, rbd_group_info_t *group_info,
+                               size_t group_info_size);
 CEPH_RBD_API int rbd_set_image_notification(rbd_image_t image, int fd, int type);
 
 /* exclusive lock feature */
@@ -552,8 +551,10 @@ CEPH_RBD_API int rbd_snap_get_namespace_type(rbd_image_t image,
                                             rbd_snap_namespace_type_t *namespace_type);
 CEPH_RBD_API int rbd_snap_get_group_namespace(rbd_image_t image,
                                               uint64_t snap_id,
-                                              rbd_snap_group_namespace_t *group_snap);
-CEPH_RBD_API void rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_snap);
+                                              rbd_snap_group_namespace_t *group_snap,
+                                              size_t group_snap_size);
+CEPH_RBD_API int rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_snap,
+                                                  size_t group_snap_size);
 
 CEPH_RBD_API int rbd_flatten(rbd_image_t image);
 
@@ -886,6 +887,8 @@ CEPH_RBD_API int rbd_aio_mirror_image_get_status(rbd_image_t image,
 CEPH_RBD_API int rbd_group_create(rados_ioctx_t p, const char *name);
 CEPH_RBD_API int rbd_group_remove(rados_ioctx_t p, const char *name);
 CEPH_RBD_API int rbd_group_list(rados_ioctx_t p, char *names, size_t *size);
+CEPH_RBD_API int rbd_group_info_cleanup(rbd_group_info_t *group_info,
+                                        size_t group_info_size);
 
 /**
  * Register an image metadata change watcher.
@@ -932,26 +935,27 @@ CEPH_RBD_API int rbd_watchers_list(rbd_image_t image,
 CEPH_RBD_API void rbd_watchers_list_cleanup(rbd_image_watcher_t *watchers,
                                            size_t num_watchers);
 
-CEPH_RBD_API int rbd_group_image_add(
-                               rados_ioctx_t group_p, const char *group_name,
-                               rados_ioctx_t image_p, const char *image_name);
-CEPH_RBD_API int rbd_group_image_remove(
-                               rados_ioctx_t group_p, const char *group_name,
-                               rados_ioctx_t image_p, const char *image_name);
-CEPH_RBD_API int rbd_group_image_remove_by_id(
-                               rados_ioctx_t group_p, const char *group_name,
-                               rados_ioctx_t image_p, const char *image_id);
-CEPH_RBD_API int rbd_group_image_list(
-                                 rados_ioctx_t group_p, const char *group_name,
-                                 rbd_group_image_status_t *images,
-                                 size_t *image_size);
-CEPH_RBD_API int rbd_image_get_group(rados_ioctx_t image_p,
-                                    const char *image_name,
-                                    rbd_group_spec_t *group_spec);
-CEPH_RBD_API void rbd_group_spec_cleanup(rbd_group_spec_t *group_spec);
-CEPH_RBD_API void rbd_group_image_status_cleanup(rbd_group_image_status_t *image);
-CEPH_RBD_API void rbd_group_image_status_list_cleanup(rbd_group_image_status_t *images,
-                                                      size_t len);
+CEPH_RBD_API int rbd_group_image_add(rados_ioctx_t group_p,
+                                     const char *group_name,
+                                     rados_ioctx_t image_p,
+                                     const char *image_name);
+CEPH_RBD_API int rbd_group_image_remove(rados_ioctx_t group_p,
+                                        const char *group_name,
+                                        rados_ioctx_t image_p,
+                                        const char *image_name);
+CEPH_RBD_API int rbd_group_image_remove_by_id(rados_ioctx_t group_p,
+                                              const char *group_name,
+                                              rados_ioctx_t image_p,
+                                              const char *image_id);
+CEPH_RBD_API int rbd_group_image_list(rados_ioctx_t group_p,
+                                      const char *group_name,
+                                      rbd_group_image_info_t *images,
+                                      size_t group_image_info_size,
+                                      size_t *num_entries);
+CEPH_RBD_API int rbd_group_image_list_cleanup(rbd_group_image_info_t *images,
+                                              size_t group_image_info_size,
+                                              size_t num_entries);
+
 CEPH_RBD_API int rbd_group_snap_create(rados_ioctx_t group_p,
                                        const char *group_name,
                                        const char *snap_name);
@@ -964,10 +968,12 @@ CEPH_RBD_API int rbd_group_snap_rename(rados_ioctx_t group_p,
                                        const char *new_snap_name);
 CEPH_RBD_API int rbd_group_snap_list(rados_ioctx_t group_p,
                                      const char *group_name,
-                                     rbd_group_snap_spec_t *snaps,
-                                     size_t *snaps_size);
-CEPH_RBD_API void rbd_group_snap_list_cleanup(rbd_group_snap_spec_t *snaps,
-                                              size_t len);
+                                     rbd_group_snap_info_t *snaps,
+                                     size_t group_snap_info_size,
+                                     size_t *num_entries);
+CEPH_RBD_API int rbd_group_snap_list_cleanup(rbd_group_snap_info_t *snaps,
+                                             size_t group_snap_info_size,
+                                             size_t num_entries);
 
 #ifdef __cplusplus
 }
index b77c02efe507d352c831413c88fc8aa6328b26f7..7ea80162af151264493d5b60205a3e8bc0d234ee 100644 (file)
@@ -1,4 +1,4 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 /*
  * Ceph - scalable distributed file system
@@ -84,19 +84,19 @@ namespace librbd {
     std::string name;
     int64_t pool;
     group_image_state_t state;
-  } group_image_status_t;
+  } group_image_info_t;
 
   typedef struct {
     std::string name;
     int64_t pool;
-  } group_spec_t;
+  } group_info_t;
 
   typedef rbd_group_snap_state_t group_snap_state_t;
 
   typedef struct {
     std::string name;
     group_snap_state_t state;
-  } group_snap_spec_t;
+  } group_snap_info_t;
 
   typedef rbd_image_info_t image_info_t;
 
@@ -224,7 +224,8 @@ public:
   int group_image_remove_by_id(IoCtx& io_ctx, const char *group_name,
                                IoCtx& image_io_ctx, const char *image_id);
   int group_image_list(IoCtx& io_ctx, const char *group_name,
-                      std::vector<group_image_status_t> *images);
+                       std::vector<group_image_info_t> *images,
+                       size_t group_image_info_size);
 
   int group_snap_create(IoCtx& io_ctx, const char *group_name,
                        const char *snap_name);
@@ -233,7 +234,8 @@ public:
   int group_snap_rename(IoCtx& group_ioctx, const char *group_name,
                         const char *old_snap_name, const char *new_snap_name);
   int group_snap_list(IoCtx& group_ioctx, const char *group_name,
-                     std::vector<group_snap_spec_t> *snaps);
+                      std::vector<group_snap_info_t> *snaps,
+                      size_t group_snap_info_size);
 
 private:
   /* We don't allow assignment or copying */
@@ -295,9 +297,10 @@ public:
                    std::string *parent_id, std::string *parent_snapname);
   int old_format(uint8_t *old);
   int size(uint64_t *size);
-  int get_group(group_spec_t *group_spec);
+  int get_group(group_info_t *group_info, size_t group_info_size);
   int features(uint64_t *features);
   int update_features(uint64_t features, bool enabled);
+  int get_op_features(uint64_t *op_features);
   int overlap(uint64_t *overlap);
   int get_flags(uint64_t *flags);
   int set_image_notification(int fd, int type);
@@ -382,7 +385,8 @@ public:
   int snap_get_namespace_type(uint64_t snap_id,
                               snap_namespace_type_t *namespace_type);
   int snap_get_group_namespace(uint64_t snap_id,
-                               snap_group_namespace_t *group_namespace);
+                               snap_group_namespace_t *group_namespace,
+                               size_t snap_group_namespace_size);
 
   /* I/O */
   ssize_t read(uint64_t ofs, size_t len, ceph::bufferlist& bl);
index f8d7fa7cb36e27a7372b553646cbc58d3e3796b4..f5f90bfd5729ffc98b0a32bfee35216de63d3a5d 100644 (file)
@@ -597,7 +597,7 @@ int Group<I>::image_remove(librados::IoCtx& group_ioctx, const char *group_name,
 template <typename I>
 int Group<I>::image_list(librados::IoCtx& group_ioctx,
                         const char *group_name,
-                        std::vector<group_image_status_t>* images)
+                        std::vector<group_image_info_t>* images)
 {
   CephContext *cct = (CephContext *)group_ioctx.cct();
   ldout(cct, 20) << "io_ctx=" << &group_ioctx
@@ -622,7 +622,7 @@ int Group<I>::image_list(librados::IoCtx& group_ioctx,
     }
 
     images->push_back(
-       group_image_status_t {
+       group_image_info_t {
           image_name,
           ioctx.get_id(),
           static_cast<group_image_state_t>(image_id.state)});
@@ -632,7 +632,7 @@ int Group<I>::image_list(librados::IoCtx& group_ioctx,
 }
 
 template <typename I>
-int Group<I>::image_get_group(I *ictx, group_spec_t *group_spec)
+int Group<I>::image_get_group(I *ictx, group_info_t *group_info)
 {
   int r = ictx->state->refresh_if_required();
   if (r < 0)
@@ -650,11 +650,11 @@ int Group<I>::image_get_group(I *ictx, group_spec_t *group_spec)
                                 ictx->group_spec.group_id, &group_name);
     if (r < 0)
       return r;
-    group_spec->pool = ioctx.get_id();
-    group_spec->name = group_name;
+    group_info->pool = ioctx.get_id();
+    group_info->name = group_name;
   } else {
-    group_spec->pool = RBD_GROUP_INVALID_POOL;
-    group_spec->name = "";
+    group_info->pool = RBD_GROUP_INVALID_POOL;
+    group_info->name = "";
   }
 
   return 0;
@@ -979,7 +979,7 @@ int Group<I>::snap_rename(librados::IoCtx& group_ioctx, const char *group_name,
 
 template <typename I>
 int Group<I>::snap_list(librados::IoCtx& group_ioctx, const char *group_name,
-                       std::vector<group_snap_spec_t> *snaps)
+                       std::vector<group_snap_info_t> *snaps)
 {
   std::vector<cls::rbd::GroupSnapshot> cls_snaps;
 
@@ -990,7 +990,7 @@ int Group<I>::snap_list(librados::IoCtx& group_ioctx, const char *group_name,
 
   for (auto snap : cls_snaps) {
     snaps->push_back(
-       group_snap_spec_t {
+       group_snap_info_t {
           snap.name,
           static_cast<group_snap_state_t>(snap.state)});
 
index bfcfedab8e798f4e4e1c9f7318354267cadf3f24..7f7e973c90f5cfc6e37eb2c04d7557669bed2f41 100644 (file)
@@ -32,9 +32,9 @@ struct Group {
                                 librados::IoCtx& image_ioctx,
                                 const char *image_id);
   static int image_list(librados::IoCtx& group_ioctx, const char *group_name,
-                       std::vector<group_image_status_t> *images);
+                       std::vector<group_image_info_t> *images);
 
-  static int image_get_group(ImageCtxT *ictx, group_spec_t *group_spec);
+  static int image_get_group(ImageCtxT *ictx, group_info_t *group_info);
 
   static int snap_create(librados::IoCtx& group_ioctx,
                          const char *group_name, const char *snap_name);
@@ -43,7 +43,7 @@ struct Group {
   static int snap_rename(librados::IoCtx& group_ioctx, const char *group_name,
                          const char *old_snap_name, const char *new_snap_name);
   static int snap_list(librados::IoCtx& group_ioctx, const char *group_name,
-                       std::vector<group_snap_spec_t> *snaps);
+                       std::vector<group_snap_info_t> *snaps);
 
 };
 
index d4983d5f299901b1342aef0a046ab6caadda1709..a4afdb2bb5ae9d1da071601394caffbc450b4f12 100644 (file)
 namespace librbd {
 namespace api {
 
+template <typename I>
+int Image<I>::get_op_features(I *ictx, uint64_t *op_features) {
+  CephContext *cct = ictx->cct;
+  ldout(cct, 20) << "image_ctx=" << ictx << dendl;
+
+  int r = ictx->state->refresh_if_required();
+  if (r < 0) {
+    return r;
+  }
+
+  RWLock::RLocker snap_locker(ictx->snap_lock);
+  *op_features = ictx->op_features;
+  return 0;
+}
+
 template <typename I>
 int Image<I>::list_images(librados::IoCtx& io_ctx, ImageNameToIds *images) {
   CephContext *cct = (CephContext *)io_ctx.cct();
index d690d44cc270948f3e34f673ceade94cc85f7ae3..1339994a67d1578f000e8000cafe4481bac5774d 100644 (file)
@@ -27,6 +27,8 @@ struct Image {
   typedef std::map<PoolSpec, ImageIds> PoolImageIds;
   typedef std::map<std::string, std::string> ImageNameToIds;
 
+  static int get_op_features(ImageCtxT *ictx, uint64_t *op_features);
+
   static int list_images(librados::IoCtx& io_ctx,
                          ImageNameToIds *images);
 
index 42def5efd4e5c6eac9b7f7ed1b85d00160fee5b2..e684ace54c54c36577b9a643e20a6b9e6fa3fb8c 100644 (file)
@@ -155,23 +155,23 @@ struct C_UpdateWatchCB : public librbd::UpdateWatchCtx {
   }
 };
 
-void group_image_status_cpp_to_c(const librbd::group_image_status_t &cpp_status,
-                                rbd_group_image_status_t *c_status) {
-  c_status->spec.name = strdup(cpp_status.name.c_str());
-  c_status->spec.pool = cpp_status.pool;
-  c_status->state = cpp_status.state;
+void group_image_status_cpp_to_c(const librbd::group_image_info_t &cpp_info,
+                                rbd_group_image_info_t *c_info) {
+  c_info->name = strdup(cpp_info.name.c_str());
+  c_info->pool = cpp_info.pool;
+  c_info->state = cpp_info.state;
 }
 
-void group_spec_cpp_to_c(const librbd::group_spec_t &cpp_spec,
-                        rbd_group_spec_t *c_spec) {
-  c_spec->name = strdup(cpp_spec.name.c_str());
-  c_spec->pool = cpp_spec.pool;
+void group_info_cpp_to_c(const librbd::group_info_t &cpp_info,
+                        rbd_group_info_t *c_info) {
+  c_info->name = strdup(cpp_info.name.c_str());
+  c_info->pool = cpp_info.pool;
 }
 
-void group_snap_spec_cpp_to_c(const librbd::group_snap_spec_t &cpp_spec,
-                             rbd_group_snap_spec_t *c_spec) {
-  c_spec->name = strdup(cpp_spec.name.c_str());
-  c_spec->state = cpp_spec.state;
+void group_snap_info_cpp_to_c(const librbd::group_snap_info_t &cpp_info,
+                             rbd_group_snap_info_t *c_info) {
+  c_info->name = strdup(cpp_info.name.c_str());
+  c_info->state = cpp_info.state;
 }
 
 void mirror_image_info_cpp_to_c(const librbd::mirror_image_info_t &cpp_info,
@@ -723,9 +723,11 @@ namespace librbd {
                            IoCtx& image_ioctx, const char *image_name)
   {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_image_add_enter, group_ioctx.get_pool_name().c_str(),
-              group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
-              image_ioctx.get_id(), image_name);
+    tracepoint(librbd, group_image_add_enter,
+               group_ioctx.get_pool_name().c_str(),
+               group_ioctx.get_id(), group_name,
+               image_ioctx.get_pool_name().c_str(),
+               image_ioctx.get_id(), image_name);
     int r = librbd::api::Group<>::image_add(group_ioctx, group_name,
                                             image_ioctx, image_name);
     tracepoint(librbd, group_image_add_exit, r);
@@ -736,9 +738,11 @@ namespace librbd {
                               IoCtx& image_ioctx, const char *image_name)
   {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_image_remove_enter, group_ioctx.get_pool_name().c_str(),
-              group_ioctx.get_id(), group_name, image_ioctx.get_pool_name().c_str(),
-              image_ioctx.get_id(), image_name);
+    tracepoint(librbd, group_image_remove_enter,
+               group_ioctx.get_pool_name().c_str(),
+               group_ioctx.get_id(), group_name,
+               image_ioctx.get_pool_name().c_str(),
+               image_ioctx.get_id(), image_name);
     int r = librbd::api::Group<>::image_remove(group_ioctx, group_name,
                                                image_ioctx, image_name);
     tracepoint(librbd, group_image_remove_exit, r);
@@ -761,11 +765,19 @@ namespace librbd {
   }
 
   int RBD::group_image_list(IoCtx& group_ioctx, const char *group_name,
-                            std::vector<group_image_status_t> *images)
+                            std::vector<group_image_info_t> *images,
+                            size_t group_image_info_size)
   {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_image_list_enter, group_ioctx.get_pool_name().c_str(),
+    tracepoint(librbd, group_image_list_enter,
+               group_ioctx.get_pool_name().c_str(),
               group_ioctx.get_id(), group_name);
+
+    if (group_image_info_size != sizeof(group_image_info_t)) {
+      tracepoint(librbd, group_image_list_exit, -ERANGE);
+      return -ERANGE;
+    }
+
     int r = librbd::api::Group<>::image_list(group_ioctx, group_name, images);
     tracepoint(librbd, group_image_list_exit, r);
     return r;
@@ -774,9 +786,11 @@ namespace librbd {
   int RBD::group_snap_create(IoCtx& group_ioctx, const char *group_name,
                             const char *snap_name) {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_snap_create_enter, group_ioctx.get_pool_name().c_str(),
+    tracepoint(librbd, group_snap_create_enter,
+               group_ioctx.get_pool_name().c_str(),
               group_ioctx.get_id(), group_name, snap_name);
-    int r = librbd::api::Group<>::snap_create(group_ioctx, group_name, snap_name);
+    int r = librbd::api::Group<>::snap_create(group_ioctx, group_name,
+                                              snap_name);
     tracepoint(librbd, group_snap_create_exit, r);
     return r;
   }
@@ -784,19 +798,29 @@ namespace librbd {
   int RBD::group_snap_remove(IoCtx& group_ioctx, const char *group_name,
                             const char *snap_name) {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_snap_remove_enter, group_ioctx.get_pool_name().c_str(),
+    tracepoint(librbd, group_snap_remove_enter,
+               group_ioctx.get_pool_name().c_str(),
               group_ioctx.get_id(), group_name, snap_name);
-    int r = librbd::api::Group<>::snap_remove(group_ioctx, group_name, snap_name);
+    int r = librbd::api::Group<>::snap_remove(group_ioctx, group_name,
+                                              snap_name);
     tracepoint(librbd, group_snap_remove_exit, r);
     return r;
   }
 
   int RBD::group_snap_list(IoCtx& group_ioctx, const char *group_name,
-                          std::vector<group_snap_spec_t> *snaps)
+                          std::vector<group_snap_info_t> *snaps,
+                           size_t group_snap_info_size)
   {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-    tracepoint(librbd, group_snap_list_enter, group_ioctx.get_pool_name().c_str(),
+    tracepoint(librbd, group_snap_list_enter,
+               group_ioctx.get_pool_name().c_str(),
               group_ioctx.get_id(), group_name);
+
+    if (group_snap_info_size != sizeof(group_snap_info_t)) {
+      tracepoint(librbd, group_snap_list_exit, -ERANGE);
+      return -ERANGE;
+    }
+
     int r = librbd::api::Group<>::snap_list(group_ioctx, group_name, snaps);
     tracepoint(librbd, group_snap_list_exit, r);
     return r;
@@ -1018,11 +1042,17 @@ namespace librbd {
     return r;
   }
 
-  int Image::get_group(group_spec_t *group_spec)
+  int Image::get_group(group_info_t *group_info, size_t group_info_size)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
     tracepoint(librbd, image_get_group_enter, ictx->name.c_str());
-    int r = librbd::api::Group<>::image_get_group(ictx, group_spec);
+
+    if (group_info_size != sizeof(group_info_t)) {
+      tracepoint(librbd, image_get_group_exit, -ERANGE);
+      return -ERANGE;
+    }
+
+    int r = librbd::api::Group<>::image_get_group(ictx, group_info);
     tracepoint(librbd, image_get_group_exit, r);
     return r;
   }
@@ -1045,6 +1075,12 @@ namespace librbd {
     return r;
   }
 
+  int Image::get_op_features(uint64_t *op_features)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::api::Image<>::get_op_features(ictx, op_features);
+  }
+
   uint64_t Image::get_stripe_unit() const
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1585,10 +1621,17 @@ namespace librbd {
   }
 
   int Image::snap_get_group_namespace(uint64_t snap_id,
-                                     snap_group_namespace_t *group_snap) {
+                                     snap_group_namespace_t *group_snap,
+                                      size_t group_snap_size) {
     ImageCtx *ictx = (ImageCtx *)ctx;
     tracepoint(librbd, snap_get_group_namespace_enter, ictx,
                ictx->name.c_str());
+
+    if (group_snap_size != sizeof(snap_group_namespace_t)) {
+      tracepoint(librbd, snap_get_group_namespace_exit, -ERANGE);
+      return -ERANGE;
+    }
+
     int r = librbd::api::Snapshot<>::get_group_namespace(ictx, snap_id,
                                                          group_snap);
     tracepoint(librbd, snap_get_group_namespace_exit, r);
@@ -3030,6 +3073,12 @@ extern "C" int rbd_update_features(rbd_image_t image, uint64_t features,
   return r;
 }
 
+extern "C" int rbd_get_op_features(rbd_image_t image, uint64_t *op_features)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::api::Image<>::get_op_features(ictx, op_features);
+}
+
 extern "C" int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
@@ -3180,6 +3229,29 @@ extern "C" int rbd_get_flags(rbd_image_t image, uint64_t *flags)
   return r;
 }
 
+extern "C" int rbd_get_group(rbd_image_t image, rbd_group_info_t *group_info,
+                             size_t group_info_size)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, image_get_group_enter, ictx->name.c_str());
+
+  if (group_info_size != sizeof(rbd_group_info_t)) {
+    tracepoint(librbd, image_get_group_exit, -ERANGE);
+    return -ERANGE;
+  }
+
+  librbd::group_info_t cpp_group_info;
+  int r = librbd::api::Group<>::image_get_group(ictx, &cpp_group_info);
+  if (r >= 0) {
+    group_info_cpp_to_c(cpp_group_info, group_info);
+  } else {
+    group_info->name = NULL;
+  }
+
+  tracepoint(librbd, image_get_group_exit, r);
+  return r;
+}
+
 extern "C" int rbd_set_image_notification(rbd_image_t image, int fd, int type)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
@@ -4435,9 +4507,10 @@ extern "C" int rbd_group_list(rados_ioctx_t p, char *names, size_t *size)
   return (int)expected_size;
 }
 
-extern "C" int rbd_group_image_add(
-                                 rados_ioctx_t group_p, const char *group_name,
-                                 rados_ioctx_t image_p, const char *image_name)
+extern "C" int rbd_group_image_add(rados_ioctx_t group_p,
+                                   const char *group_name,
+                                   rados_ioctx_t image_p,
+                                   const char *image_name)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx image_ioctx;
@@ -4457,9 +4530,10 @@ extern "C" int rbd_group_image_add(
   return r;
 }
 
-extern "C" int rbd_group_image_remove(
-                                rados_ioctx_t group_p, const char *group_name,
-                                rados_ioctx_t image_p, const char *image_name)
+extern "C" int rbd_group_image_remove(rados_ioctx_t group_p,
+                                      const char *group_name,
+                                      rados_ioctx_t image_p,
+                                      const char *image_name)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx image_ioctx;
@@ -4506,17 +4580,25 @@ extern "C" int rbd_group_image_remove_by_id(rados_ioctx_t group_p,
 
 extern "C" int rbd_group_image_list(rados_ioctx_t group_p,
                                    const char *group_name,
-                                   rbd_group_image_status_t *images,
+                                   rbd_group_image_info_t *images,
+                                    size_t group_image_info_size,
                                    size_t *image_size)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
 
   TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-  tracepoint(librbd, group_image_list_enter, group_ioctx.get_pool_name().c_str(),
+  tracepoint(librbd, group_image_list_enter,
+             group_ioctx.get_pool_name().c_str(),
             group_ioctx.get_id(), group_name);
 
-  std::vector<librbd::group_image_status_t> cpp_images;
+  if (group_image_info_size != sizeof(rbd_group_image_info_t)) {
+    *image_size = 0;
+    tracepoint(librbd, group_image_list_exit, -ERANGE);
+    return -ERANGE;
+  }
+
+  std::vector<librbd::group_image_info_t> cpp_images;
   int r = librbd::api::Group<>::image_list(group_ioctx, group_name,
                                            &cpp_images);
 
@@ -4545,54 +4627,39 @@ extern "C" int rbd_group_image_list(rados_ioctx_t group_p,
   return r;
 }
 
-extern "C" int rbd_image_get_group(rados_ioctx_t image_p,
-                                  const char *image_name,
-                                  rbd_group_spec_t *c_group_spec)
-{
-  librados::IoCtx io_ctx;
-  librados::IoCtx::from_rados_ioctx_t(image_p, io_ctx);
-
-  librbd::ImageCtx *ictx = new librbd::ImageCtx(image_name, "", "", io_ctx, false);
-  int r = ictx->state->open(false);
-  if (r < 0) {
-    tracepoint(librbd, open_image_exit, r);
-    return r;
+extern "C" int rbd_group_info_cleanup(rbd_group_info_t *group_info,
+                                      size_t group_info_size) {
+  if (group_info_size != sizeof(rbd_group_info_t)) {
+    return -ERANGE;
   }
 
-  tracepoint(librbd, image_get_group_enter, ictx->name.c_str());
-  librbd::group_spec_t group_spec;
-  r = librbd::api::Group<>::image_get_group(ictx, &group_spec);
-  group_spec_cpp_to_c(group_spec, c_group_spec);
-  tracepoint(librbd, image_get_group_exit, r);
-  ictx->state->close();
-  return r;
-}
-
-extern "C" void rbd_group_spec_cleanup(rbd_group_spec_t *group_spec) {
-  free(group_spec->name);
+  free(group_info->name);
+  return 0;
 }
 
-extern "C" void rbd_group_image_status_cleanup(
-                                             rbd_group_image_status_t *image) {
-    free(image->spec.name);
-}
+extern "C" int rbd_group_image_list_cleanup(rbd_group_image_info_t *images,
+                                            size_t group_image_info_size,
+                                            size_t len) {
+  if (group_image_info_size != sizeof(rbd_group_image_info_t)) {
+    return -ERANGE;
+  }
 
-extern "C" void rbd_group_image_status_list_cleanup(
-                                             rbd_group_image_status_t *images,
-                                             size_t len) {
   for (size_t i = 0; i < len; ++i) {
-    rbd_group_image_status_cleanup(&images[i]);
+    free(images[i].name);
   }
+  return 0;
 }
 
-extern "C" int rbd_group_snap_create(rados_ioctx_t group_p, const char *group_name,
-                                     const char *snap_name)
+extern "C" int rbd_group_snap_create(rados_ioctx_t group_p,
+                                     const char *group_name,
+                                     const char *snap_name)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
 
   TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-  tracepoint(librbd, group_snap_create_enter, group_ioctx.get_pool_name().c_str(),
+  tracepoint(librbd, group_snap_create_enter,
+             group_ioctx.get_pool_name().c_str(),
             group_ioctx.get_id(), group_name, snap_name);
 
   int r = librbd::api::Group<>::snap_create(group_ioctx, group_name, snap_name);
@@ -4602,14 +4669,16 @@ extern "C" int rbd_group_snap_create(rados_ioctx_t group_p, const char *group_na
   return r;
 }
 
-extern "C" int rbd_group_snap_remove(rados_ioctx_t group_p, const char *group_name,
-                                     const char *snap_name)
+extern "C" int rbd_group_snap_remove(rados_ioctx_t group_p,
+                                     const char *group_name,
+                                     const char *snap_name)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
 
   TracepointProvider::initialize<tracepoint_traits>(get_cct(group_ioctx));
-  tracepoint(librbd, group_snap_remove_enter, group_ioctx.get_pool_name().c_str(),
+  tracepoint(librbd, group_snap_remove_enter,
+             group_ioctx.get_pool_name().c_str(),
             group_ioctx.get_id(), group_name, snap_name);
 
   int r = librbd::api::Group<>::snap_remove(group_ioctx, group_name, snap_name);
@@ -4639,8 +4708,11 @@ extern "C" int rbd_group_snap_rename(rados_ioctx_t group_p,
   return r;
 }
 
-extern "C" int rbd_group_snap_list(rados_ioctx_t group_p, const char *group_name,
-                                  rbd_group_snap_spec_t *snaps, size_t *snaps_size)
+extern "C" int rbd_group_snap_list(rados_ioctx_t group_p,
+                                   const char *group_name,
+                                   rbd_group_snap_info_t *snaps,
+                                   size_t group_snap_info_size,
+                                   size_t *snaps_size)
 {
   librados::IoCtx group_ioctx;
   librados::IoCtx::from_rados_ioctx_t(group_p, group_ioctx);
@@ -4649,7 +4721,13 @@ extern "C" int rbd_group_snap_list(rados_ioctx_t group_p, const char *group_name
   tracepoint(librbd, group_snap_list_enter, group_ioctx.get_pool_name().c_str(),
             group_ioctx.get_id(), group_name);
 
-  std::vector<librbd::group_snap_spec_t> cpp_snaps;
+  if (group_snap_info_size != sizeof(rbd_group_snap_info_t)) {
+    *snaps_size = 0;
+    tracepoint(librbd, group_snap_list_exit, -ERANGE);
+    return -ERANGE;
+  }
+
+  std::vector<librbd::group_snap_info_t> cpp_snaps;
   int r = librbd::api::Group<>::snap_list(group_ioctx, group_name, &cpp_snaps);
 
   if (r == -ENOENT) {
@@ -4670,7 +4748,7 @@ extern "C" int rbd_group_snap_list(rados_ioctx_t group_p, const char *group_name
   }
 
   for (size_t i = 0; i < cpp_snaps.size(); ++i) {
-    group_snap_spec_cpp_to_c(cpp_snaps[i], &snaps[i]);
+    group_snap_info_cpp_to_c(cpp_snaps[i], &snaps[i]);
   }
 
   *snaps_size = cpp_snaps.size();
@@ -4678,11 +4756,17 @@ extern "C" int rbd_group_snap_list(rados_ioctx_t group_p, const char *group_name
   return 0;
 }
 
-extern "C" void rbd_group_snap_list_cleanup(rbd_group_snap_spec_t *snaps,
-                                            size_t len) {
+extern "C" int rbd_group_snap_list_cleanup(rbd_group_snap_info_t *snaps,
+                                           size_t group_snap_info_size,
+                                           size_t len) {
+  if (group_snap_info_size != sizeof(rbd_group_snap_info_t)) {
+    return -ERANGE;
+  }
+
   for (size_t i = 0; i < len; ++i) {
     free(snaps[i].name);
   }
+  return 0;
 }
 
 extern "C" int rbd_snap_get_namespace_type(rbd_image_t image,
@@ -4697,11 +4781,17 @@ extern "C" int rbd_snap_get_namespace_type(rbd_image_t image,
 }
 
 extern "C" int rbd_snap_get_group_namespace(rbd_image_t image, uint64_t snap_id,
-                                            rbd_snap_group_namespace_t *group_snap) {
+                                            rbd_snap_group_namespace_t *group_snap,
+                                            size_t snap_group_namespace_size) {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
   tracepoint(librbd, snap_get_group_namespace_enter, ictx,
              ictx->name.c_str());
 
+  if (snap_group_namespace_size != sizeof(rbd_snap_group_namespace_t)) {
+    tracepoint(librbd, snap_get_group_namespace_exit, -ERANGE);
+    return -ERANGE;
+  }
+
   librbd::snap_group_namespace_t group_namespace;
   int r = librbd::api::Snapshot<>::get_group_namespace(ictx, snap_id,
                                                        &group_namespace);
@@ -4716,9 +4806,16 @@ extern "C" int rbd_snap_get_group_namespace(rbd_image_t image, uint64_t snap_id,
   return r;
 }
 
-extern "C" void rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_snap) {
+extern "C" int rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_snap,
+                                                size_t snap_group_namespace_size) {
+  if (snap_group_namespace_size != sizeof(rbd_snap_group_namespace_t)) {
+    tracepoint(librbd, snap_get_group_namespace_exit, -ERANGE);
+    return -ERANGE;
+  }
+
   free(group_snap->group_name);
   free(group_snap->group_snap_name);
+  return 0;
 }
 
 extern "C" int rbd_watchers_list(rbd_image_t image,
index 4cc201831b1305bf6a4d4f73ac50235bb2a98501..03ab01dc5a1d88cc411d4deea27bab7405c3fdbd 100644 (file)
@@ -64,54 +64,78 @@ TEST_F(TestGroup, group_create)
 
 TEST_F(TestGroup, add_image)
 {
+  REQUIRE_FORMAT_V2();
+
   librados::IoCtx ioctx;
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
 
   const char *group_name = "mycg";
-  const char *image_name = "myimage";
   librbd::RBD rbd;
   ASSERT_EQ(0, rbd.group_create(ioctx, group_name));
-  int order = 14;
-  ASSERT_EQ(0, rbd.create2(ioctx, image_name, 65535,
-                          RBD_FEATURE_LAYERING, &order)); // Specified features make image of new format.
 
-  ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx, image_name));
+  librbd::Image image;
+  ASSERT_EQ(0, rbd.open(ioctx, image, m_image_name.c_str(), NULL));
+
+  uint64_t features;
+  ASSERT_EQ(0, image.features(&features));
+  ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
+
+  uint64_t op_features;
+  ASSERT_EQ(0, image.get_op_features(&op_features));
+  ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
+
+  ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx,
+                                   m_image_name.c_str()));
 
-  vector<librbd::group_image_status_t> images;
-  ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images));
+  ASSERT_EQ(0, image.features(&features));
+  ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) ==
+                RBD_FEATURE_OPERATIONS);
+  ASSERT_EQ(0, image.get_op_features(&op_features));
+  ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) ==
+                RBD_OPERATION_FEATURE_GROUP);
+
+  vector<librbd::group_image_info_t> images;
+  ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images,
+                                    sizeof(librbd::group_image_info_t)));
   ASSERT_EQ(1U, images.size());
-  ASSERT_EQ("myimage", images[0].name);
+  ASSERT_EQ(m_image_name, images[0].name);
   ASSERT_EQ(ioctx.get_id(), images[0].pool);
 
-  ASSERT_EQ(0, rbd.group_image_remove(ioctx, group_name, ioctx, image_name));
+  ASSERT_EQ(0, rbd.group_image_remove(ioctx, group_name, ioctx,
+                                      m_image_name.c_str()));
+
+  ASSERT_EQ(0, image.features(&features));
+  ASSERT_TRUE((features & RBD_FEATURE_OPERATIONS) == 0ULL);
+  ASSERT_EQ(0, image.get_op_features(&op_features));
+  ASSERT_TRUE((op_features & RBD_OPERATION_FEATURE_GROUP) == 0ULL);
 
   images.clear();
-  ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images));
+  ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images,
+                                    sizeof(librbd::group_image_info_t)));
   ASSERT_EQ(0U, images.size());
 }
 
 TEST_F(TestGroup, add_snapshot)
 {
+  REQUIRE_FORMAT_V2();
+
   librados::IoCtx ioctx;
   ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
 
   const char *group_name = "snap_group";
-  const char *image_name = "snap_image";
   const char *snap_name = "snap_snapshot";
 
   librbd::RBD rbd;
   ASSERT_EQ(0, rbd.group_create(ioctx, group_name));
 
-  int order = 14;
-  ASSERT_EQ(0, rbd.create2(ioctx, image_name, 65535,
-                          RBD_FEATURE_LAYERING, &order)); // Specified features make image of new format.
-
-  ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx, image_name));
+  ASSERT_EQ(0, rbd.group_image_add(ioctx, group_name, ioctx,
+                                   m_image_name.c_str()));
 
   ASSERT_EQ(0, rbd.group_snap_create(ioctx, group_name, snap_name));
 
-  std::vector<librbd::group_snap_spec_t> snaps;
-  ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps));
+  std::vector<librbd::group_snap_info_t> snaps;
+  ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
+                                   sizeof(librbd::group_snap_info_t)));
   ASSERT_EQ(1U, snaps.size());
 
   ASSERT_EQ(snap_name, snaps[0].name);
@@ -119,6 +143,7 @@ TEST_F(TestGroup, add_snapshot)
   ASSERT_EQ(0, rbd.group_snap_remove(ioctx, group_name, snap_name));
 
   snaps.clear();
-  ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps));
+  ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
+                                   sizeof(librbd::group_snap_info_t)));
   ASSERT_EQ(0U, snaps.size());
 }
index 73d704c3946d09c138067c84216a97827d265939..1e07e069087d7b6ad7de9a8fdf82257c5b334083 100644 (file)
@@ -284,9 +284,10 @@ int execute_list_images(const po::variables_map &vm,
   }
 
   librbd::RBD rbd;
-  std::vector<librbd::group_image_status_t> images;
+  std::vector<librbd::group_image_info_t> images;
 
-  r = rbd.group_image_list(io_ctx, group_name.c_str(), &images);
+  r = rbd.group_image_list(io_ctx, group_name.c_str(), &images,
+                           sizeof(librbd::group_image_info_t));
 
   if (r == -ENOENT)
     r = 0;
@@ -476,9 +477,10 @@ int execute_group_snap_list(const po::variables_map &vm,
   }
 
   librbd::RBD rbd;
-  std::vector<librbd::group_snap_spec_t> snaps;
+  std::vector<librbd::group_snap_info_t> snaps;
 
-  r = rbd.group_snap_list(io_ctx, group_name.c_str(), &snaps);
+  r = rbd.group_snap_list(io_ctx, group_name.c_str(), &snaps,
+                          sizeof(librbd::group_snap_info_t));
 
   if (r == -ENOENT) {
     r = 0;
index 3efc2257837704ccf8ace1c93e0a8c8f6ca0a983..5ed9c70eab224815b9a1444370854f1457435a48 100644 (file)
@@ -130,25 +130,25 @@ static int do_show_info(librados::IoCtx &io_ctx, librbd::Image& image,
 
   std::string prefix = image.get_block_name_prefix();
 
-  librbd::group_spec_t group_spec;
-  r = image.get_group(&group_spec);
+  librbd::group_info_t group_info;
+  r = image.get_group(&group_info, sizeof(group_info));
   if (r < 0) {
     return r;
   }
 
   std::string group_string = "";
-  if (RBD_GROUP_INVALID_POOL != group_spec.pool) {
+  if (RBD_GROUP_INVALID_POOL != group_info.pool) {
     std::string group_pool;
     librados::Rados rados(io_ctx);
     librados::IoCtx group_io_ctx;
-    r = rados.ioctx_create2(group_spec.pool, group_io_ctx);
+    r = rados.ioctx_create2(group_info.pool, group_io_ctx);
     if (r < 0) {
-      group_pool = "<missing group pool " + stringify(group_spec.pool) + ">";
+      group_pool = "<missing group pool " + stringify(group_info.pool) + ">";
     } else {
       group_pool = group_io_ctx.get_pool_name();
     }
 
-    group_string = group_pool + "/" + group_spec.name;
+    group_string = group_pool + "/" + group_info.name;
   }
 
   struct timespec create_timestamp;
index d6eb2d01ef91ea24541755da763d01359657f4d6..67dbae87b31ffe28a5ad06e65e12a7bb1183aec2 100644 (file)
@@ -74,13 +74,13 @@ int execute(const po::variables_map &vm,
     } else if (r == -EMLINK) {
       librbd::Image image;
       int image_r = utils::open_image(io_ctx, image_name, true, &image);
-      librbd::group_spec_t group_spec;
+      librbd::group_info_t group_info;
       if (image_r == 0) {
-       image_r = image.get_group(&group_spec);
+       image_r = image.get_group(&group_info, sizeof(group_info));
       }
       if (image_r == 0)
        std::cerr << "rbd: error: image belongs to a group "
-                 << group_spec.pool << "." << group_spec.name;
+                 << group_info.pool << "." << group_info.name;
       else
        std::cerr << "rbd: error: image belongs to a group";
 
index 668ad2e1ea67dc3f1ac3674c2834e8e0150db8f1..47a6dbd295fc0a813bb046ba57b919bff7fdf264 100644 (file)
@@ -77,7 +77,8 @@ int do_list_snaps(librbd::Image& image, Formatter *f, bool all_snaps, librados::
       tt_str = tt_str.substr(0, tt_str.length() - 1);
     }
     librbd::snap_group_namespace_t group_snap;
-    int get_group_res = image.snap_get_group_namespace(s->id, &group_snap);
+    int get_group_res = image.snap_get_group_namespace(s->id, &group_snap,
+                                                       sizeof(group_snap));
 
     if (f) {
       f->open_object_section("snapshot");