]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: default features should be negotiated with the OSD 11808/head
authorMykola Golub <mgolub@mirantis.com>
Mon, 7 Nov 2016 13:56:22 +0000 (15:56 +0200)
committerMykola Golub <mgolub@mirantis.com>
Mon, 7 Nov 2016 18:13:00 +0000 (20:13 +0200)
Fixes: http://tracker.ceph.com/issues/17010
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
src/librbd/Utils.cc
src/librbd/image/CreateRequest.cc
src/librbd/image/CreateRequest.h
src/librbd/internal.cc

index 81495623a262d056a4a708d932994c8fb5cfd581..a7a225939a61247c9e8cb390619a86fb379c2bef 100644 (file)
@@ -64,7 +64,7 @@ std::string generate_image_id(librados::IoCtx &ioctx) {
   return id;
 }
 
-uint64_t parse_rbd_default_features(CephContext* cct) 
+uint64_t parse_rbd_default_features(CephContext* cct)
 {
   int ret = 0;
   uint64_t value = 0;
@@ -72,7 +72,7 @@ uint64_t parse_rbd_default_features(CephContext* cct)
   try {
       value = boost::lexical_cast<decltype(value)>(str_val);
   } catch (const boost::bad_lexical_cast& ) {
-    map<std::string, int> conf_vals = {{RBD_FEATURE_NAME_LAYERING, RBD_FEATURE_LAYERING}, 
+    map<std::string, int> conf_vals = {{RBD_FEATURE_NAME_LAYERING, RBD_FEATURE_LAYERING},
                                        {RBD_FEATURE_NAME_STRIPINGV2, RBD_FEATURE_STRIPINGV2},
                                        {RBD_FEATURE_NAME_EXCLUSIVE_LOCK, RBD_FEATURE_EXCLUSIVE_LOCK},
                                        {RBD_FEATURE_NAME_OBJECT_MAP, RBD_FEATURE_OBJECT_MAP},
@@ -89,7 +89,7 @@ uint64_t parse_rbd_default_features(CephContext* cct)
         value += conf_vals[feature];
       } else {
         ret = -EINVAL;
-        ldout(cct, 1) << "Warning: unknown rbd feature " << feature << dendl;
+        lderr(cct) << "ignoring unknown feature " << feature << dendl;
       }
     }
     if (value == 0 && ret == -EINVAL)
index e9ac3592b6d26bccca312ab0e98661100d4e080d..ff64dc7806d15da0e520a19bdfd699e09afc8801 100644 (file)
@@ -136,6 +136,7 @@ CreateRequest<I>::CreateRequest(IoCtx &ioctx, const std::string &image_name,
 
   if (image_options.get(RBD_IMAGE_OPTION_FEATURES, &m_features) != 0) {
     m_features = util::parse_rbd_default_features(m_cct);
+    m_negotiate_features = true;
   }
 
   uint64_t features_clear = 0;
@@ -381,6 +382,48 @@ Context *CreateRequest<I>::handle_add_image_to_directory(int *result) {
     return nullptr;
   }
 
+  negotiate_features();
+  return nullptr;
+}
+
+template<typename I>
+void CreateRequest<I>::negotiate_features() {
+  if (!m_negotiate_features) {
+    create_image();
+    return;
+  }
+
+  ldout(m_cct, 20) << this << " " << __func__ << dendl;
+
+  librados::ObjectReadOperation op;
+  cls_client::get_all_features_start(&op);
+
+  using klass = CreateRequest<I>;
+  librados::AioCompletion *comp =
+    create_rados_ack_callback<klass, &klass::handle_negotiate_features>(this);
+  int r = m_ioctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_outbl);
+  assert(r == 0);
+  comp->release();
+}
+
+template<typename I>
+Context *CreateRequest<I>::handle_negotiate_features(int *result) {
+  ldout(m_cct, 20) << __func__ << ": r=" << *result << dendl;
+
+  uint64_t all_features;
+  if (*result == 0) {
+    bufferlist::iterator it = m_outbl.begin();
+    *result = cls_client::get_all_features_finish(&it, &all_features);
+  }
+  if (*result < 0) {
+    ldout(m_cct, 10) << "error retrieving server supported features set: "
+                     << cpp_strerror(*result) << dendl;
+  } else if ((m_features & all_features) != m_features) {
+    m_features &= all_features;
+    ldout(m_cct, 10) << "limiting default features set to server supported: "
+                    << m_features << dendl;
+  }
+
   create_image();
   return nullptr;
 }
index aa30615c1437528d4830058db74269e304bc09cb..9841af941d9a1c23bba1e0f3ec0653ba12b1d59f 100644 (file)
@@ -60,7 +60,10 @@ private:
    * |               |                   v
    * |               |          ADD IMAGE TO DIRECTORY
    * |               |               /   |
-   * |      REMOVE ID OBJECT<-------/    v         (stripingv2 disabled)
+   * |      REMOVE ID OBJECT<-------/    v
+   * |               |           NEGOTIATE FEATURES (when using default features)
+   * |               |                   |
+   * |               |                   v         (stripingv2 disabled)
    * |               |              CREATE IMAGE. . . . > . . . .
    * v               |               /   |                      .
    * |      REMOVE FROM DIR<--------/    v                      .
@@ -112,6 +115,7 @@ private:
   int64_t m_data_pool_id = -1;
   const std::string m_non_primary_global_image_id;
   const std::string m_primary_mirror_uuid;
+  bool m_negotiate_features = false;
 
   ContextWQ *m_op_work_queue;
   Context *m_on_finish;
@@ -135,6 +139,9 @@ private:
   void add_image_to_directory();
   Context *handle_add_image_to_directory(int *result);
 
+  void negotiate_features();
+  Context *handle_negotiate_features(int *result);
+
   void create_image();
   Context *handle_create_image(int *result);
 
index 21188895c2770964debe0a017f5e2e3fdfc6837d..f2b304aa044dc55aa6b6d6f0ccba7f23eb25a11f 100644 (file)
@@ -900,10 +900,19 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
   int create(librados::IoCtx& io_ctx, const char *imgname, uint64_t size,
             int *order)
   {
-    CephContext *cct = (CephContext *)io_ctx.cct();
-    bool old_format = cct->_conf->rbd_default_format == 1;
-    uint64_t features = old_format ? 0 : librbd::util::parse_rbd_default_features(cct);
-    return create(io_ctx, imgname, size, old_format, features, order, 0, 0);
+    uint64_t order_ = *order;
+    ImageOptions opts;
+
+    int r = opts.set(RBD_IMAGE_OPTION_ORDER, order_);
+    assert(r == 0);
+
+    r = create(io_ctx, imgname, size, opts, "", "");
+
+    int r1 = opts.get(RBD_IMAGE_OPTION_ORDER, &order_);
+    assert(r1 == 0);
+    *order = order_;
+
+    return r;
   }
 
   int create(IoCtx& io_ctx, const char *imgname, uint64_t size,