From eac05c1b5d8d698ef9945c018eb9cb89ee236c29 Mon Sep 17 00:00:00 2001 From: Thanos Makatos Date: Fri, 4 Mar 2016 18:18:29 +0300 Subject: [PATCH 1/9] document how to extract thin pool metadata --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index d23dae5..ce83bd7 100644 --- a/README.md +++ b/README.md @@ -130,3 +130,35 @@ Once you've done this you can run the tests with a simple: Or specific tests with: cucumber features/thin_restore -n 'print help' + + +Dump Metadata +============= + +To dump the metadata of a live thin pool, you must first create a snapshot of +the metadata: + + $ dmsetup message vg001-mythinpool-tpool 0 reserve_metadata_snap + +Then, extract the held root from the device mapper's status of the thin pool +(7th field). This value must be passed to ```thin_dump```. + + $ sudo dmsetup status vg001-mythinpool-tpool + 0 8192 thin-pool 2 11/1024 1/64 10 rw discard_passdown + ^ + +Extract the metadata: + + $ sudo bin/thin_dump -m10 /dev/mapper/vg001-mythinpool_tmeta + + + + + + + + + +Finally, release the root: + + $ dmsetup message vg001-mythinpool-tpool 0 release_metadata_snap From f162d59bf6da9a3e930f8498e6b41c6029be1920 Mon Sep 17 00:00:00 2001 From: Thanos Makatos Date: Fri, 4 Mar 2016 18:30:02 +0300 Subject: [PATCH 2/9] no need to supply held root, thin_dump -m will look it up --- README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.md b/README.md index ce83bd7..005ae50 100644 --- a/README.md +++ b/README.md @@ -140,16 +140,9 @@ the metadata: $ dmsetup message vg001-mythinpool-tpool 0 reserve_metadata_snap -Then, extract the held root from the device mapper's status of the thin pool -(7th field). This value must be passed to ```thin_dump```. - - $ sudo dmsetup status vg001-mythinpool-tpool - 0 8192 thin-pool 2 11/1024 1/64 10 rw discard_passdown - ^ - Extract the metadata: - $ sudo bin/thin_dump -m10 /dev/mapper/vg001-mythinpool_tmeta + $ sudo bin/thin_dump -m /dev/mapper/vg001-mythinpool_tmeta From 38f67676e47ac9a88ebfdb1da7d349e4e6fb2d49 Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 7 Mar 2016 15:42:24 -0600 Subject: [PATCH 3/9] get stats in bytes --- thin-provisioning/thin_ls.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/thin-provisioning/thin_ls.cc b/thin-provisioning/thin_ls.cc index 869c7cf..4e0b97d 100644 --- a/thin-provisioning/thin_ls.cc +++ b/thin-provisioning/thin_ls.cc @@ -109,6 +109,10 @@ namespace { EXCLUSIVE_SECTORS, SHARED_SECTORS, + MAPPED_BYTES, + EXCLUSIVE_BYTES, + SHARED_BYTES, + MAPPED, EXCLUSIVE, SHARED, @@ -128,6 +132,10 @@ namespace { "EXCLUSIVE_SECTORS", "SHARED_SECTORS", + "MAPPED_BYTES", + "EXCLUSIVE_BYTES", + "SHARED_BYTES", + "MAPPED", "EXCLUSIVE", "SHARED", @@ -298,6 +306,8 @@ namespace { *it == SHARED_BLOCKS || *it == EXCLUSIVE_SECTORS || *it == SHARED_SECTORS || + *it == EXCLUSIVE_BYTES || + *it == SHARED_BYTES || *it == EXCLUSIVE || *it == SHARED) return true; @@ -375,6 +385,20 @@ namespace { grid.field((it->second.mapped_blocks_ - exclusive) * block_size); break; + case MAPPED_BYTES: + grid.field(it->second.mapped_blocks_ * block_size * + disk_unit_multiplier(UNIT_SECTOR)); + break; + + case EXCLUSIVE_BYTES: + grid.field(exclusive * block_size * + disk_unit_multiplier(UNIT_SECTOR)); + break; + + case SHARED_BYTES: + grid.field((it->second.mapped_blocks_ - exclusive) * block_size * + disk_unit_multiplier(UNIT_SECTOR)); + break; case MAPPED: grid.field( From c406db158acc3f6c3003992c34097e18f3e8023a Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Mon, 7 Mar 2016 16:21:39 -0600 Subject: [PATCH 4/9] update this_ls man page with new fields --- man8/thin_ls.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/man8/thin_ls.8 b/man8/thin_ls.8 index 7d5081b..47607c6 100644 --- a/man8/thin_ls.8 +++ b/man8/thin_ls.8 @@ -19,8 +19,8 @@ This tool cannot be run on live metadata unless the \fB\-\-metadata\-snap\fP opt .IP "\fB\-o, \-\-format\fP" Give a comma separated list of the fields to be output. Valid fields are: DEV, MAPPED_BLOCKS, EXCLUSIVE_BLOCKS, SHARED_BLOCKS, MAPPED_SECTORS, -EXCLUSIVE_SECTORS, SHARED_SECTORS, MAPPED, EXCLUSIVE, SHARED, TRANSACTION -CREATE_TIME, SNAP_TIME +EXCLUSIVE_SECTORS, SHARED_SECTORS, MAPPED_BYTES, EXCLUSIVE_BYTES, +SHARED_BYTES, MAPPED, EXCLUSIVE, SHARED, TRANSACTION CREATE_TIME, SNAP_TIME .IP "\fB\-\-no\-headers\fP" Don't output headers. From afb71d8b5eea4ce533856da233652098c68ec121 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 8 Mar 2016 16:14:37 +0000 Subject: [PATCH 5/9] bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5070360..280dcd2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.2-rc5 +0.6.2-rc6 From 2cf0c84ce385a7a13aba69baa47993be28c45b23 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 21 Mar 2016 15:36:49 +0000 Subject: [PATCH 6/9] [thin_repair] we need to read the space maps after all to get the data volume size. --- thin-provisioning/thin_repair.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/thin-provisioning/thin_repair.cc b/thin-provisioning/thin_repair.cc index 194f431..d146ccd 100644 --- a/thin-provisioning/thin_repair.cc +++ b/thin-provisioning/thin_repair.cc @@ -23,7 +23,12 @@ namespace { emitter::ptr e = create_restore_emitter(new_md); block_manager<>::ptr old_bm = open_bm(old_path, block_manager<>::READ_ONLY); - metadata::ptr old_md(new metadata(old_bm, false)); // we don't need to read the space maps + + // we need to read the space maps to get the size + // of the data device. This is a shame, since any + // corruption in the sms will cause the repair to + // fail. + metadata::ptr old_md(new metadata(old_bm, true)); metadata_dump(old_md, e, true); } catch (std::exception &e) { From a21f97e4050513b13bdf11d20a95ccdd89474af4 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 21 Mar 2016 17:16:41 +0000 Subject: [PATCH 7/9] [space map disk] Add get_nr_blocks_in_data_sm() which just uses the root --- persistent-data/space-maps/disk.cc | 11 +++++++++++ persistent-data/space-maps/disk.h | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/persistent-data/space-maps/disk.cc b/persistent-data/space-maps/disk.cc index e915eb4..9b1f9cc 100644 --- a/persistent-data/space-maps/disk.cc +++ b/persistent-data/space-maps/disk.cc @@ -773,4 +773,15 @@ persistent_data::open_metadata_sm(transaction_manager &tm, void *root) checked_space_map::ptr(new sm_disk(store, tm, v)))); } +block_address +persistent_data::get_nr_blocks_in_data_sm(transaction_manager &tm, void *root) +{ + sm_root_disk d; + sm_root v; + + ::memcpy(&d, root, sizeof(d)); + sm_root_traits::unpack(d, v); + return v.nr_blocks_; +} + //---------------------------------------------------------------- diff --git a/persistent-data/space-maps/disk.h b/persistent-data/space-maps/disk.h index 0a69f04..cb747e8 100644 --- a/persistent-data/space-maps/disk.h +++ b/persistent-data/space-maps/disk.h @@ -36,6 +36,11 @@ namespace persistent_data { checked_space_map::ptr open_metadata_sm(transaction_manager &tm, void *root); + + // Get the number of data blocks with minimal IO. Used when + // repairing to avoid the bulk of the space maps. + block_address + get_nr_blocks_in_data_sm(transaction_manager &tm, void *root); } //---------------------------------------------------------------- From b0e2d0e6a054c1925695b02693863234745528a8 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 21 Mar 2016 17:17:57 +0000 Subject: [PATCH 8/9] [thin_repair, metadata] Try harder to get the number of data blocks when opening the metadata. --- thin-provisioning/metadata_dumper.cc | 28 +++++++++++++++++++++------- thin-provisioning/thin_repair.cc | 6 +----- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/thin-provisioning/metadata_dumper.cc b/thin-provisioning/metadata_dumper.cc index 0c0fbe4..7bb9361 100644 --- a/thin-provisioning/metadata_dumper.cc +++ b/thin-provisioning/metadata_dumper.cc @@ -185,8 +185,13 @@ namespace { d.creation_time_, d.snapshotted_time_); - emit_mappings(tree_root); - + try { + emit_mappings(tree_root); + } catch (exception &e) { + cerr << e.what(); + e_->end_device(); + throw; + } e_->end_device(); } else if (!repair_) { @@ -211,6 +216,19 @@ namespace { bool repair_; mapping_tree_detail::damage_visitor::ptr damage_policy_; }; + + block_address get_nr_blocks(metadata::ptr md) { + if (md->data_sm_) + return md->data_sm_->get_nr_blocks(); + + else if (md->sb_.blocknr_ == superblock_detail::SUPERBLOCK_LOCATION) + // grab from the root structure of the space map + return get_nr_blocks_in_data_sm(*md->tm_, &md->sb_.data_space_map_root_); + + else + // metadata snap, we really don't know + return 0ull; + } } //---------------------------------------------------------------- @@ -222,14 +240,10 @@ thin_provisioning::metadata_dump(metadata::ptr md, emitter::ptr e, bool repair) device_tree_detail::damage_visitor::ptr dd_policy(details_damage_policy(repair)); walk_device_tree(*md->details_, de, *dd_policy); - // metadata snap doesn't have the space maps so we don't know how - // many data blocks there are. - block_address nr_data_blocks = md->data_sm_ ? md->data_sm_->get_nr_blocks() : 0; - e->begin_superblock("", md->sb_.time_, md->sb_.trans_id_, md->sb_.data_block_size_, - nr_data_blocks, + get_nr_blocks(md), boost::optional()); { diff --git a/thin-provisioning/thin_repair.cc b/thin-provisioning/thin_repair.cc index d146ccd..2741b78 100644 --- a/thin-provisioning/thin_repair.cc +++ b/thin-provisioning/thin_repair.cc @@ -24,11 +24,7 @@ namespace { block_manager<>::ptr old_bm = open_bm(old_path, block_manager<>::READ_ONLY); - // we need to read the space maps to get the size - // of the data device. This is a shame, since any - // corruption in the sms will cause the repair to - // fail. - metadata::ptr old_md(new metadata(old_bm, true)); + metadata::ptr old_md(new metadata(old_bm, false)); metadata_dump(old_md, e, true); } catch (std::exception &e) { From 72025c398e9e5079b7a605255eb39d458d6dc717 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 21 Mar 2016 17:27:26 +0000 Subject: [PATCH 9/9] bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 280dcd2..1f969e9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.2-rc6 +0.6.2-rc7