From: Mykola Golub Date: Tue, 16 Jun 2015 08:57:08 +0000 (+0300) Subject: ceph-objectstore-tool: add mark-complete operation X-Git-Tag: v0.94.7~28^2~2^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=0fe3dfe8768b27743189add73cde9a44095f2a62;p=ceph.git 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 (cherry picked from commit 6907778d767ba08bb80c495785056ed122b023fe) Conflicts: src/test/ceph_objectstore_tool.py (trivial) src/tools/ceph_objectstore_tool.cc (trivial) --- diff --git a/src/test/ceph_objectstore_tool.py b/src/test/ceph_objectstore_tool.py index c875c0bcfdc30..b18d5f94d865e 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)") + 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, 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 f98dfd80d31fd..e4ce3a19b041c 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -2737,10 +2737,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, " - "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), @@ -3144,7 +3144,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; @@ -3414,9 +3415,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, " - "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; @@ -3677,6 +3678,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"); }