]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fixed assert when flattening clone with zero overlap 24045/head
authorJason Dillaman <dillaman@redhat.com>
Wed, 12 Sep 2018 01:52:05 +0000 (21:52 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 12 Sep 2018 01:52:05 +0000 (21:52 -0400)
Fixes: http://tracker.ceph.com/issues/35702
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/Operations.cc
src/librbd/operation/FlattenRequest.cc
src/test/librbd/test_librbd.cc

index 8a0b00b2ab531ef80839a3101ef0e8bd0bec181c..e670b8523fb4c3fb7696ecdc0b2f6050149c480d 100644 (file)
@@ -402,7 +402,6 @@ void Operations<I>::execute_flatten(ProgressContext &prog_ctx,
   }
 
   ::SnapContext snapc = m_image_ctx.snapc;
-  ceph_assert(m_image_ctx.parent != NULL);
 
   uint64_t overlap;
   int r = m_image_ctx.get_parent_overlap(CEPH_NOSNAP, &overlap);
index 0b861ebe59d01055b6fcb6e8e5612cd5dfdd9315..2f3225c64ae5c3b2d0d3bb51c3273af35d45246a 100644 (file)
@@ -169,7 +169,7 @@ bool FlattenRequest<I>::send_update_header() {
     RWLock::RLocker parent_locker(image_ctx.parent_lock);
     // stop early if the parent went away - it just means
     // another flatten finished first, so this one is useless.
-    if (!image_ctx.parent) {
+    if (image_ctx.parent_md.spec.pool_id == -1) {
       ldout(cct, 5) << "image already flattened" << dendl;
       return true;
     }
index 478fbd4c099c258a768bc2e340ecf414e0ae8bf5..9ab40bd8d5e0b9a50e85e1419110a86af73e366e 100644 (file)
@@ -7005,6 +7005,38 @@ TEST_F(TestLibRBD, TestGetModifyTimestamp)
   rados_ioctx_destroy(ioctx);
 }
 
+TEST_F(TestLibRBD, ZeroOverlapFlatten) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  librbd::Image parent_image;
+  std::string name = get_temp_image_name();
+
+  uint64_t size = 1;
+  int order = 0;
+
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order));
+  ASSERT_EQ(0, rbd.open(ioctx, parent_image, name.c_str(), NULL));
+
+  uint64_t features;
+  ASSERT_EQ(0, parent_image.features(&features));
+
+  ASSERT_EQ(0, parent_image.snap_create("snap"));
+  ASSERT_EQ(0, parent_image.snap_protect("snap"));
+
+  std::string clone_name = this->get_temp_image_name();
+  ASSERT_EQ(0, rbd.clone(ioctx, name.c_str(), "snap", ioctx, clone_name.c_str(),
+                         features, &order));
+
+  librbd::Image clone_image;
+  ASSERT_EQ(0, rbd.open(ioctx, clone_image, clone_name.c_str(), NULL));
+  ASSERT_EQ(0, clone_image.resize(0));
+  ASSERT_EQ(0, clone_image.flatten());
+}
+
 // poorman's ceph_assert()
 namespace ceph {
   void __ceph_assert_fail(const char *assertion, const char *file, int line,