From abcff4c78e2ea64d7c02f5d446d8d5ea23d4c6aa Mon Sep 17 00:00:00 2001 From: Asias He Date: Wed, 2 Aug 2017 16:12:16 +0800 Subject: [PATCH] repair: Fix repair_tracker done If it throws after repair_tracker.start and before the when_all below, the repair_tracker.done will never be called for this repair id. Fixes #2660 --- repair/repair.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/repair/repair.cc b/repair/repair.cc index 5f38ba97ee..b8eaf4c247 100644 --- a/repair/repair.cc +++ b/repair/repair.cc @@ -38,6 +38,7 @@ #include #include +#include static logging::logger rlogger("repair"); @@ -1050,6 +1051,7 @@ static int do_repair_start(seastar::sharded& db, sstring keyspace, int id = repair_tracker.next_repair_command(); rlogger.info("starting user-requested repair for keyspace {}, repair id {}, options {}", keyspace, id, options_map); repair_tracker.start(id); + auto fail = defer([&repair_tracker, id] { repair_tracker.done(id, false); }); // If the "ranges" option is not explicitly specified, we repair all the // local ranges (the token ranges for which this node holds a replica of). @@ -1137,17 +1139,16 @@ static int do_repair_start(seastar::sharded& db, sstring keyspace, repair_results.push_back(std::move(f)); } - when_all(repair_results.begin(), repair_results.end()).then([id] (std::vector> results) { + when_all(repair_results.begin(), repair_results.end()).then([id, fail = std::move(fail)] (std::vector> results) mutable { if (std::any_of(results.begin(), results.end(), [] (auto&& f) { return f.failed(); })) { - repair_tracker.done(id, false); rlogger.info("repair {} failed", id); } else { + fail.cancel(); repair_tracker.done(id, true); rlogger.info("repair {} completed successfully", id); } return make_ready_future<>(); }).handle_exception([id] (std::exception_ptr eptr) { - repair_tracker.done(id, false); rlogger.info("repair {} failed: {}", id, eptr); });