From 992bb5feeb9e1994d4c31b4b13dbae594dd3c87a Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Tue, 24 Aug 2021 16:20:50 +0800 Subject: [PATCH 3/3] [thin_repair/thin_dump] Check consistency of thin_ids before running a regular dump (cherry picked from commit 73dda15b5977dfa45cbfa36edddf4c19d279767b) --- functional-tests/thin-functional-tests.scm | 56 ++++++++++++++++++++++++++++++ thin-provisioning/metadata_dumper.cc | 8 +++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/functional-tests/thin-functional-tests.scm b/functional-tests/thin-functional-tests.scm index d06a5a3..37d3df9 100644 --- a/functional-tests/thin-functional-tests.scm +++ b/functional-tests/thin-functional-tests.scm @@ -81,6 +81,15 @@ (let ((csum (checksum-block b (ftype-sizeof unsigned-32) superblock-salt))) (ftype-set! ThinSuperblock (csum) sb csum)))))) + (define (tamper-mapping-root md mapping-root) + (with-bcache (cache md 1) + (with-block (b cache 0 (get-flags dirty)) + (let ((sb (block->superblock b))) + (ftype-set! ThinSuperblock (data-mapping-root) sb mapping-root) + ;;;;;; Update the csum manually since the block validator for ft-lib is not ready + (let ((csum (checksum-block b (ftype-sizeof unsigned-32) superblock-salt))) + (ftype-set! ThinSuperblock (csum) sb csum)))))) + (define (get-superblock-flags md) (with-bcache (cache md 1) (with-block (b cache 0 (get-flags)) @@ -97,6 +106,26 @@ ;; to run. (define (register-thin-tests) #t) + ;; An deterministic simple XML for testing + (define simple-thin-xml + (fmt #f + (tag 'superblock `((uuid . "") + (time . 0) + (transaction . 1) + (flags . 0) + (version . 2) + (data-block-size . 128) + (nr-data-blocks . 1024)) + (tag 'device `((dev-id . 1) + (mapped-blocks . 16) + (transaction . 0) + (creation-time . 0) + (snap-time . 0)) + (tag 'range-mapping `((origin-begin . 0) + (data-begin . 0) + (length . 16) + (time . 0))))))) + ;; XML of metadata with empty thins (define xml-with-empty-thins (fmt #f @@ -414,6 +443,18 @@ (assert-eof stderr) (assert-equal expected-xml repaired-xml))))) + (define-scenario (thin-dump repair-superblock inconsistent-device-ids) + "metadata with inconsistent device ids should be repaired" + (with-temp-file-sized ((md "thin.bin" (meg 4))) + (with-temp-file-containing ((xml "thin.xml" simple-thin-xml)) + (run-ok (thin-restore "-i" xml "-o" md))) + (run-ok-rcv (expected-xml _) (thin-dump md) + ;;;;;; simulate multiple activation by replacing the mapping root with a bottom-level leaf + (tamper-mapping-root md 10) + (run-ok-rcv (repaired-xml stderr) (thin-dump "--repair" md) + (assert-eof stderr) + (assert-equal expected-xml repaired-xml))))) + ;;;----------------------------------------------------------- ;;; thin_rmap scenarios ;;;----------------------------------------------------------- @@ -624,6 +665,21 @@ (assert-eof stderr) (assert-equal expected-xml repaired-xml)))))) + (define-scenario (thin-repair superblock inconsistent-device-ids) + "metadata with inconsistent device ids should be repaired" + (with-temp-file-sized ((md1 "thin.bin" (meg 4))) + (with-temp-file-containing ((xml "thin.xml" simple-thin-xml)) + (run-ok (thin-restore "-i" xml "-o" md1))) + (run-ok-rcv (expected-xml _) (thin-dump md1) + ;;;;;; simulate multiple activation by replacing the mapping root with a bottom-level leaf + (tamper-mapping-root md1 10) + (with-empty-metadata (md2) + (run-ok-rcv (_ stderr) (thin-repair "-i" md1 "-o" md2) + (assert-eof stderr)) + (run-ok-rcv (repaired-xml stderr) (thin-dump md2) + (assert-eof stderr) + (assert-equal expected-xml repaired-xml)))))) + ;;;----------------------------------------------------------- ;;; thin_metadata_pack scenarios ;;;----------------------------------------------------------- diff --git a/thin-provisioning/metadata_dumper.cc b/thin-provisioning/metadata_dumper.cc index d169c27..0ca4afe 100644 --- a/thin-provisioning/metadata_dumper.cc +++ b/thin-provisioning/metadata_dumper.cc @@ -412,6 +412,9 @@ namespace { if (rhs == ms.end()) continue; + if (lhs->second != rhs->second) + continue; + filtered.push_back(make_pair(p.first.b, p.second.b)); } @@ -886,8 +889,9 @@ namespace { auto tm = open_tm(bm, superblock_detail::SUPERBLOCK_LOCATION); - if (!get_dev_ids(*tm, msb->device_details_root_) || - !get_map_ids(*tm, msb->data_mapping_root_)) + auto maybe_dev_ids = get_dev_ids(*tm, msb->device_details_root_); + auto maybe_map_ids = get_map_ids(*tm, msb->data_mapping_root_); + if (!maybe_dev_ids || !maybe_map_ids || (*maybe_dev_ids) != (*maybe_map_ids)) find_better_roots_(bm, *msb); emit_trees_(bm, *msb, e, opts); -- 1.8.3.1