From 02895914030f53f762ca5ecd9d397c75cf370c87 Mon Sep 17 00:00:00 2001 From: David Zafman Date: Wed, 4 Apr 2018 16:09:39 -0700 Subject: [PATCH] osd rados command: Show snapset in list-inconsistent-snapset Add SnapSet bufferlist to inconsistent_snapset_t Partial fix for http://tracker.ceph.com/issues/23428 Signed-off-by: David Zafman (cherry picked from commit 60ae2b8eb3ef73e9eb175340340681f48beae48d) Conflicts: src/common/scrub_types.cc (uses ::decode and ::encode) src/osd/PrimaryLogPG.cc (trivial) --- doc/rados/command/list-inconsistent-snap.json | 2 +- qa/standalone/scrub/osd-scrub-snaps.sh | 240 +++++++++++++++++- src/common/scrub_types.cc | 8 +- src/include/rados/rados_types.hpp | 1 + src/osd/PrimaryLogPG.cc | 12 +- src/tools/rados/rados.cc | 9 + 6 files changed, 259 insertions(+), 13 deletions(-) diff --git a/doc/rados/command/list-inconsistent-snap.json b/doc/rados/command/list-inconsistent-snap.json index 22044719f0bba..9a463e8ecfcca 100644 --- a/doc/rados/command/list-inconsistent-snap.json +++ b/doc/rados/command/list-inconsistent-snap.json @@ -52,7 +52,7 @@ "clone_missing" ] }, - "minItems": 1, + "minItems": 0, "uniqueItems": true }, "missing": { diff --git a/qa/standalone/scrub/osd-scrub-snaps.sh b/qa/standalone/scrub/osd-scrub-snaps.sh index b7a58b531849b..c701110f27b31 100755 --- a/qa/standalone/scrub/osd-scrub-snaps.sh +++ b/qa/standalone/scrub/osd-scrub-snaps.sh @@ -288,6 +288,31 @@ function TEST_scrub_snaps() { "nspace": "", "name": "obj5" }, + { + "name": "obj10", + "nspace": "", + "locator": "", + "snap": "head", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": 1032, + "overlap": "????", + "snaps": [ + 1 + ] + } + ] + }, + "errors": [] + }, { "extra clones": [ 1 @@ -298,7 +323,41 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj11" + "name": "obj11", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [] + } + }, + { + "name": "obj14", + "nspace": "", + "locator": "", + "snap": "head", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": 1033, + "overlap": "[]", + "snaps": [ + 1 + ] + } + ] + }, + "errors": [] }, { "errors": [ @@ -339,7 +398,36 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj3" + "name": "obj3", + "snapset": { + "snap_context": { + "seq": 3, + "snaps": [ + 3, + 2, + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": 1032, + "overlap": "[]", + "snaps": [ + 1 + ] + }, + { + "snap": 3, + "size": 256, + "overlap": "[]", + "snaps": [ + 3, + 2 + ] + } + ] + } }, { "missing": [ @@ -351,7 +439,37 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj4" + "name": "obj4", + "snapset": { + "snap_context": { + "seq": 7, + "snaps": [ + 7, + 6, + 5, + 4, + 3, + 2, + 1 + ] + }, + "clones": [ + { + "snap": 7, + "size": 1032, + "overlap": "[]", + "snaps": [ + 7, + 6, + 5, + 4, + 3, + 2, + 1 + ] + } + ] + } }, { "missing": [ @@ -368,7 +486,56 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj5" + "name": "obj5", + "snapset": { + "snap_context": { + "seq": 6, + "snaps": [ + 6, + 5, + 4, + 3, + 2, + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": 1032, + "overlap": "[]", + "snaps": [ + 1 + ] + }, + { + "snap": 2, + "size": 256, + "overlap": "[]", + "snaps": [ + 2 + ] + }, + { + "snap": 4, + "size": 512, + "overlap": "[]", + "snaps": [ + 4, + 3 + ] + }, + { + "snap": 6, + "size": 1024, + "overlap": "[]", + "snaps": [ + 6, + 5 + ] + } + ] + } }, { "extra clones": [ @@ -380,7 +547,16 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj6" + "name": "obj6", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [] + } }, { "extra clones": [ @@ -393,7 +569,14 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj7" + "name": "obj7", + "snapset": { + "snap_context": { + "seq": 0, + "snaps": [] + }, + "clones": [] + } }, { "errors": [ @@ -402,7 +585,50 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj8" + "name": "obj8", + "snapset": { + "snap_context": { + "seq": 0, + "snaps": [ + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": 1032, + "overlap": "[]", + "snaps": [ + 1 + ] + } + ] + } + }, + { + "name": "obj9", + "nspace": "", + "locator": "", + "snap": "head", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [ + { + "snap": 1, + "size": "????", + "overlap": "[]", + "snaps": [ + 1 + ] + } + ] + }, + "errors": [] } ], "epoch": 20 diff --git a/src/common/scrub_types.cc b/src/common/scrub_types.cc index 149078518b3ff..dd8e801aa8ba0 100644 --- a/src/common/scrub_types.cc +++ b/src/common/scrub_types.cc @@ -233,21 +233,25 @@ void inconsistent_snapset_wrapper::set_size_mismatch() void inconsistent_snapset_wrapper::encode(bufferlist& bl) const { - ENCODE_START(1, 1, bl); + ENCODE_START(2, 1, bl); ::encode(errors, bl); ::encode(object, bl); ::encode(clones, bl); ::encode(missing, bl); + ::encode(ss_bl, bl); ENCODE_FINISH(bl); } void inconsistent_snapset_wrapper::decode(bufferlist::iterator& bp) { - DECODE_START(1, bp); + DECODE_START(2, bp); ::decode(errors, bp); ::decode(object, bp); ::decode(clones, bp); ::decode(missing, bp); + if (struct_v >= 2) { + ::decode(ss_bl, bp); + } DECODE_FINISH(bp); } diff --git a/src/include/rados/rados_types.hpp b/src/include/rados/rados_types.hpp index 7cd1cd33f942d..3c6b18a3cc570 100644 --- a/src/include/rados/rados_types.hpp +++ b/src/include/rados/rados_types.hpp @@ -265,6 +265,7 @@ struct inconsistent_snapset_t { // Extra clones std::vector clones; std::vector missing; + ceph::bufferlist ss_bl; bool ss_attr_missing() const { // Compatibility return errors & SNAPSET_MISSING; diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index dc393c4631005..1358eefa69a9d 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -13822,6 +13822,7 @@ void PrimaryLogPG::scrub_snapshot_metadata( vector::reverse_iterator curclone; // Defined only if snapset initialized unsigned missing = 0; inconsistent_snapset_wrapper soid_error, head_error; + unsigned soid_error_count = 0; bufferlist last_data; @@ -13949,6 +13950,7 @@ void PrimaryLogPG::scrub_snapshot_metadata( ++scrubber.shallow_errors; soid_error.set_headless(); scrubber.store->add_snap_error(pool.id, soid_error); + ++soid_error_count; if (head && soid.get_head() == head->get_head()) head_error.set_clone(soid.snap); continue; @@ -13963,12 +13965,13 @@ void PrimaryLogPG::scrub_snapshot_metadata( } // Save previous head error information - if (head && head_error.errors) + if (head && (head_error.errors || soid_error_count)) scrubber.store->add_snap_error(pool.id, head_error); // Set this as a new head object head = soid; missing = 0; head_error = soid_error; + soid_error_count = 0; dout(20) << __func__ << " " << mode << " new head " << head << dendl; @@ -13985,6 +13988,7 @@ void PrimaryLogPG::scrub_snapshot_metadata( try { snapset = SnapSet(); // Initialize optional<> before decoding into it ::decode(snapset.get(), blp); + head_error.ss_bl.push_back(p->second.attrs[SS_ATTR]); } catch (buffer::error& e) { snapset = boost::none; osd->clog->error() << mode << " " << info.pgid << " " << soid @@ -14115,8 +14119,10 @@ void PrimaryLogPG::scrub_snapshot_metadata( // what's next? ++curclone; - if (soid_error.errors) + if (soid_error.errors) { scrubber.store->add_snap_error(pool.id, soid_error); + ++soid_error_count; + } } scrub_cstat.add(stat); @@ -14136,7 +14142,7 @@ void PrimaryLogPG::scrub_snapshot_metadata( log_missing(missing, head, osd->clog, info.pgid, __func__, mode, pool.info.allow_incomplete_clones()); } - if (head && head_error.errors) + if (head && (head_error.errors || soid_error_count)) scrubber.store->add_snap_error(pool.id, head_error); for (map>::const_iterator p = diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index 4a0a3d73a02a8..7017a4479436e 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -1533,6 +1533,15 @@ static void dump_inconsistent(const inconsistent_snapset_t& inc, { dump_object_id(inc.object, f); + if (inc.ss_bl.length()) { + SnapSet ss; + bufferlist bl = inc.ss_bl; + bufferlist::iterator bliter = bl.begin(); + decode(ss, bliter); // Can't be corrupted + f.open_object_section("snapset"); + ss.dump(&f); + f.close_section(); + } f.open_array_section("errors"); if (inc.snapset_missing()) f.dump_string("error", "snapset_missing"); -- 2.39.5