From: Kefu Chai Date: Mon, 26 Feb 2018 14:20:43 +0000 (+0800) Subject: ceph-objectstore-tool: don't destroy SnapMapper until the txn is completed X-Git-Tag: v13.0.2~145^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=42f310f253a658ec8c600a8406084ec91ecd49ba;p=ceph.git ceph-objectstore-tool: don't destroy SnapMapper until the txn is completed 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 --- diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index e10613ba98e..2137240bc4f 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -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 +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 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; }