From 6907778d767ba08bb80c495785056ed122b023fe Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Tue, 16 Jun 2015 11:57:08 +0300 Subject: [PATCH] ceph-objectstore-tool: add mark-complete operation It is supposed to be used as a last resort to fix a cluster that has PGs in 'incomplete' state, using the following procedure: 1) stop the osd that is primary for the incomplete PG; 2) run: ceph-objectstore-tool --data-path ... --journal-path ... --pgid $PGID --op mark-complete 3) start the osd. Fixes: #10098 Signed-off-by: Mykola Golub --- src/test/ceph_objectstore_tool.py | 2 +- src/tools/ceph_objectstore_tool.cc | 37 ++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/test/ceph_objectstore_tool.py b/src/test/ceph_objectstore_tool.py index 7f616b7d94c..79230d22834 100755 --- a/src/test/ceph_objectstore_tool.py +++ b/src/test/ceph_objectstore_tool.py @@ -791,7 +791,7 @@ def main(argv): # Specify a bad --op command cmd = (CFSD_PREFIX + "--op oops").format(osd=ONEOSD) - ERRORS += test_failure(cmd, "Must provide --op (info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list, get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap)") + ERRORS += test_failure(cmd, "Must provide --op (info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list, get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap, mark-complete)") # Provide just the object param not a command cmd = (CFSD_PREFIX + "object").format(osd=ONEOSD) diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index a2dbccbc5fc..4f74501e802 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -1909,10 +1909,10 @@ int main(int argc, char **argv) ("journal-path", po::value(&jpath), "path to journal, mandatory for filestore type") ("pgid", po::value(&pgidstr), - "PG id, mandatory for info, log, remove, export, rm-past-intervals") + "PG id, mandatory for info, log, remove, export, rm-past-intervals, mark-complete") ("op", po::value(&op), "Arg is one of [info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list, " - "get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap]") + "get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap, mark-complete]") ("epoch", po::value(&epoch), "epoch# for get-osdmap and get-inc-osdmap, the current epoch in use if not specified") ("file", po::value(&file), @@ -2285,7 +2285,8 @@ int main(int argc, char **argv) // The ops which require --pgid option are checked here and // mentioned in the usage for --pgid. if ((op == "info" || op == "log" || op == "remove" || op == "export" - || op == "rm-past-intervals") && pgidstr.length() == 0) { + || op == "rm-past-intervals" || op == "mark-complete") && + pgidstr.length() == 0) { cerr << "Must provide pgid" << std::endl; usage(desc); ret = 1; @@ -2563,9 +2564,9 @@ int main(int argc, char **argv) // If not an object command nor any of the ops handled below, then output this usage // before complaining about a bad pgid - if (!vm.count("objcmd") && op != "export" && op != "info" && op != "log" && op != "rm-past-intervals") { + if (!vm.count("objcmd") && op != "export" && op != "info" && op != "log" && op != "rm-past-intervals" && op != "mark-complete") { cerr << "Must provide --op (info, log, remove, export, import, list, fix-lost, list-pgs, rm-past-intervals, set-allow-sharded-objects, dump-journal, dump-super, meta-list, " - "get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap)" + "get-osdmap, set-osdmap, get-inc-osdmap, set-inc-osdmap, mark-complete)" << std::endl; usage(desc); ret = 1; @@ -2822,6 +2823,32 @@ int main(int argc, char **argv) fs->apply_transaction(*t); cout << "Removal succeeded" << std::endl; } + } else if (op == "mark-complete") { + ObjectStore::Transaction tran; + ObjectStore::Transaction *t = &tran; + + if (struct_ver != PG::cur_struct_v) { + cerr << "Can't mark-complete, version mismatch " << (int)struct_ver + << " (pg) != " << (int)PG::cur_struct_v << " (tool)" + << std::endl; + ret = 1; + goto out; + } + + cout << "Marking complete " << std::endl; + + info.last_update = eversion_t(superblock.current_epoch, info.last_update.version + 1); + info.last_backfill = hobject_t::get_max(); + info.last_epoch_started = superblock.current_epoch; + info.history.last_epoch_started = superblock.current_epoch; + info.history.last_epoch_clean = superblock.current_epoch; + past_intervals.clear(); + + ret = write_info(*t, map_epoch, info, past_intervals); + if (ret == 0) { + fs->apply_transaction(*t); + cout << "Marking complete succeeded" << std::endl; + } } else { assert(!"Should have already checked for valid --op"); } -- 2.47.3