From: David Zafman Date: Wed, 4 Apr 2018 23:09:39 +0000 (-0700) Subject: osd rados command: Show snapset in list-inconsistent-snapset X-Git-Tag: v13.1.0~334^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=60ae2b8eb3ef73e9eb175340340681f48beae48d;p=ceph.git 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 --- diff --git a/doc/rados/command/list-inconsistent-snap.json b/doc/rados/command/list-inconsistent-snap.json index c1e7119d88a6e..55f1d53e95567 100644 --- a/doc/rados/command/list-inconsistent-snap.json +++ b/doc/rados/command/list-inconsistent-snap.json @@ -51,7 +51,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 fa8a8e8412d03..aaaca4c547c29 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": [ @@ -330,7 +389,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": [ @@ -342,7 +430,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": [ @@ -359,7 +477,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": [ @@ -371,7 +538,16 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj6" + "name": "obj6", + "snapset": { + "snap_context": { + "seq": 1, + "snaps": [ + 1 + ] + }, + "clones": [] + } }, { "extra clones": [ @@ -383,7 +559,14 @@ function TEST_scrub_snaps() { "snap": "head", "locator": "", "nspace": "", - "name": "obj7" + "name": "obj7", + "snapset": { + "snap_context": { + "seq": 0, + "snaps": [] + }, + "clones": [] + } }, { "errors": [ @@ -392,7 +575,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 2ba3bcf992c2c..f86a8de75b4fe 100644 --- a/src/common/scrub_types.cc +++ b/src/common/scrub_types.cc @@ -229,21 +229,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 21bd65f34f7c6..bcbdb43200cb6 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 346af0ab7bfee..a82fb1075449e 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -14375,6 +14375,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; for (map::reverse_iterator p = scrubmap.objects.rbegin(); p != scrubmap.objects.rend(); ++p) { @@ -14496,6 +14497,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; @@ -14510,12 +14512,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; @@ -14532,6 +14535,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 @@ -14613,8 +14617,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); @@ -14634,7 +14640,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 (auto p = missing_digest.begin(); p != missing_digest.end(); ++p) { diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index dbee5eaf2dd9a..78feb4c38d650 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -1537,6 +1537,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");