]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: image create validates that pool supports overwrites 13986/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 15 Mar 2017 18:49:13 +0000 (14:49 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 15 Mar 2017 21:30:11 +0000 (17:30 -0400)
Fixes: http://tracker.ceph.com/issues/19081
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/image/CreateRequest.cc
src/librbd/image/CreateRequest.h

index 9f3bcc9d8e2cf3cdab0c089769d08aac215bb6bb..f9e43e79c6afd292b8887ee7a77b92b853f06455 100644 (file)
@@ -281,6 +281,7 @@ void CreateRequest<I>::validate_pool() {
   librados::ObjectReadOperation op;
   op.stat(NULL, NULL, NULL);
 
+  m_outbl.clear();
   int r = m_ioctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_outbl);
   assert(r == 0);
   comp->release();
@@ -291,7 +292,7 @@ void CreateRequest<I>::handle_validate_pool(int r) {
   ldout(m_cct, 20) << "r=" << r << dendl;
 
   if (r == 0) {
-    create_id_object();
+    validate_overwrite();
     return;
   } else if ((r < 0) && (r != -ENOENT)) {
     lderr(m_cct) << "failed to stat RBD directory: " << cpp_strerror(r)
@@ -328,6 +329,73 @@ void CreateRequest<I>::handle_validate_pool(int r) {
                      << ": " << cpp_strerror(r) << dendl;
   }
 
+  validate_overwrite();
+}
+
+template <typename I>
+void CreateRequest<I>::validate_overwrite() {
+  ldout(m_cct, 20) << dendl;
+
+  m_data_io_ctx = m_ioctx;
+  if (m_data_pool_id != -1) {
+    librados::Rados rados(m_ioctx);
+    int r = rados.ioctx_create2(m_data_pool_id, m_data_io_ctx);
+    if (r < 0) {
+      lderr(m_cct) << "data pool " << m_data_pool << " does not exist" << dendl;
+      complete(r);
+      return;
+    }
+  }
+
+  using klass = CreateRequest<I>;
+  librados::AioCompletion *comp =
+    create_rados_callback<klass, &klass::handle_validate_overwrite>(this);
+
+  librados::ObjectReadOperation op;
+  op.read(0, 0, nullptr, nullptr);
+
+  m_outbl.clear();
+  int r = m_data_io_ctx.aio_operate(RBD_INFO, comp, &op, &m_outbl);
+  assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void CreateRequest<I>::handle_validate_overwrite(int r) {
+  ldout(m_cct, 20) << "r=" << r << dendl;
+
+  bufferlist bl;
+  bl.append("overwrite validated");
+
+  if (r == 0 && m_outbl.contents_equal(bl)) {
+    create_id_object();
+    return;
+  } else if ((r < 0) && (r != -ENOENT)) {
+    lderr(m_cct) << "failed to read RBD info: " << cpp_strerror(r) << dendl;
+    complete(r);
+    return;
+  }
+
+  // validate the pool supports overwrites. We cannot use rbd_directory
+  // since the v1 images store the directory as tmap data within the object.
+  ldout(m_cct, 10) << "validating overwrite support" << dendl;
+  bufferlist initial_bl;
+  initial_bl.append("validate");
+  r = m_data_io_ctx.write(RBD_INFO, initial_bl, initial_bl.length(), 0);
+  if (r >= 0) {
+    r = m_data_io_ctx.write(RBD_INFO, bl, bl.length(), 0);
+  }
+  if (r == -EOPNOTSUPP) {
+    lderr(m_cct) << "pool missing required overwrite support" << dendl;
+    complete(-EINVAL);
+    return;
+  } else if (r < 0) {
+    lderr(m_cct) << "failed to validate overwrite support: " << cpp_strerror(r)
+                 << dendl;
+    complete(r);
+    return;
+  }
+
   create_id_object();
 }
 
@@ -406,6 +474,8 @@ void CreateRequest<I>::negotiate_features() {
   using klass = CreateRequest<I>;
   librados::AioCompletion *comp =
     create_rados_callback<klass, &klass::handle_negotiate_features>(this);
+
+  m_outbl.clear();
   int r = m_ioctx.aio_operate(RBD_DIRECTORY, comp, &op, &m_outbl);
   assert(r == 0);
   comp->release();
index 8a3464b5f3a3d3c2c721bb0da36d7170d583f71a..9d77838dd3180bd342cba10e5981f3a2db416809 100644 (file)
@@ -54,8 +54,11 @@ private:
    *                                  <start> . . . . > . . . . .
    *                                     |                      .
    *                                     v                      .
-   *                                VALIDATE POOL               v (pool validation
-   *                                     |                      . disabled)
+   *                               VALIDATE POOL                v (pool validation
+   *                                     |                      .  disabled)
+   *                                     v                      .
+   *                             VALIDATE OVERWRITE             .
+   *                                     |                      .
    *                                     v                      .
    * (error: bottom up)           CREATE ID OBJECT. . < . . . . .
    *  _______<_______                    |
@@ -99,6 +102,7 @@ private:
                 ContextWQ *op_work_queue, Context *on_finish);
 
   IoCtx &m_ioctx;
+  IoCtx m_data_io_ctx;
   std::string m_image_name;
   std::string m_image_id;
   uint64_t m_size;
@@ -132,6 +136,9 @@ private:
   void validate_pool();
   void handle_validate_pool(int r);
 
+  void validate_overwrite();
+  void handle_validate_overwrite(int r);
+
   void create_id_object();
   void handle_create_id_object(int r);