]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-objectstore-tool: don't destroy SnapMapper until the txn is completed
authorKefu Chai <kchai@redhat.com>
Mon, 26 Feb 2018 14:20:43 +0000 (22:20 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 26 Feb 2018 17:08:22 +0000 (01:08 +0800)
ch->flush() only ensure that the op is dequeued from osr/collection's
queue. but the ops could be still in the flight and they could still be
holding a *weak* reference of SnapMapper. we should make sure that the
mapper is still available when they reference it,

Fixes: http://tracker.ceph.com/issues/23121
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/tools/ceph_objectstore_tool.cc

index e10613ba98e14d39a3cb6392a26070d03d3328d3..2137240bc4f669ca52b0d4bef5beb5428dfdb01c 100644 (file)
@@ -415,6 +415,22 @@ int mark_pg_for_removal(ObjectStore *fs, spg_t pgid, ObjectStore::Transaction *t
 #pragma GCC diagnostic pop
 #pragma GCC diagnostic warning "-Wpragmas"
 
+template<typename Func>
+void wait_until_done(ObjectStore::Transaction* txn, Func&& func)
+{
+  bool finished = false;
+  std::condition_variable cond;
+  std::mutex m;
+  txn->register_on_complete(make_lambda_context([&]() {
+    std::unique_lock lock{m};
+    finished = true;
+    cond.notify_one();
+  }));
+  std::move(func)();
+  std::unique_lock lock{m};
+  cond.wait(lock, [&] {return finished;});
+}
+
 int initiate_new_remove_pg(ObjectStore *store, spg_t r_pgid)
 {
   if (!dry_run)
@@ -1164,8 +1180,12 @@ int ObjectStoreTool::get_object(ObjectStore *store,
       return -EFAULT;
     }
   }
-  if (!dry_run)
-    store->queue_transaction(ch, std::move(*t));
+  if (!dry_run) {
+    wait_until_done(t, [&] {
+      store->queue_transaction(ch, std::move(*t));
+      ch->flush();
+    });
+  }
   return 0;
 }
 
@@ -1830,11 +1850,12 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb,
     set<string> remove;
     remove.insert("_remove");
     t.omap_rmkeys(coll, pgid.make_pgmeta_oid(), remove);
-    store->queue_transaction(ch, std::move(t));
+    wait_until_done(&t, [&] {
+      store->queue_transaction(ch, std::move(t));
+      // make sure we flush onreadable items before mapper/driver are destroyed.
+      ch->flush();
+    });
   }
-
-  // make sure we flush onreadable items before mapper/driver are destroyed.
-  ch->flush();
   return 0;
 }
 
@@ -1947,9 +1968,12 @@ int do_remove_object(ObjectStore *store, coll_t coll,
     }
   }
 
-  if (!dry_run)
-    store->queue_transaction(ch, std::move(t));
-
+  if (!dry_run) {
+    wait_until_done(&t, [&] {
+      store->queue_transaction(ch, std::move(t));
+      ch->flush();
+    });
+  }
   return 0;
 }