diff --git a/Makefile.in b/Makefile.in index 1d37887..2822626 100644 --- a/Makefile.in +++ b/Makefile.in @@ -54,10 +54,9 @@ SOURCE=\ thin-provisioning/mapping_tree.cc \ thin-provisioning/metadata.cc \ thin-provisioning/metadata_checker.cc \ - thin-provisioning/metadata_disk_structures.cc \ thin-provisioning/metadata_dumper.cc \ thin-provisioning/restore_emitter.cc \ - thin-provisioning/superblock_checker.cc \ + thin-provisioning/superblock.cc \ thin-provisioning/superblock_validator.cc \ thin-provisioning/thin_pool.cc \ thin-provisioning/xml_format.cc @@ -139,8 +138,7 @@ THIN_CHECK_SOURCE=\ thin-provisioning/file_utils.cc \ thin-provisioning/metadata.cc \ thin-provisioning/metadata_checker.cc \ - thin-provisioning/metadata_disk_structures.cc \ - thin-provisioning/superblock_checker.cc \ + thin-provisioning/superblock.cc \ thin-provisioning/superblock_validator.cc THIN_DEBUG_OBJECTS=$(subst .cc,.o,$(THIN_DEBUG_SOURCE)) diff --git a/persistent-data/data-structures/ref_counter.h b/persistent-data/data-structures/ref_counter.h index f4ef791..88937e8 100644 --- a/persistent-data/data-structures/ref_counter.h +++ b/persistent-data/data-structures/ref_counter.h @@ -19,6 +19,8 @@ #ifndef REF_COUNTER_H #define REF_COUNTER_H +#include + //---------------------------------------------------------------- namespace persistent_data { diff --git a/thin-provisioning/metadata.cc b/thin-provisioning/metadata.cc index 326bd3c..0639cc1 100644 --- a/thin-provisioning/metadata.cc +++ b/thin-provisioning/metadata.cc @@ -37,6 +37,8 @@ using namespace thin_provisioning; //---------------------------------------------------------------- namespace { + using namespace superblock_detail; + unsigned const METADATA_CACHE_SIZE = 1024; block_manager<>::ptr open_bm(string const &dev_path, bool writeable) { diff --git a/thin-provisioning/metadata.h b/thin-provisioning/metadata.h index 27df10c..3861827 100644 --- a/thin-provisioning/metadata.h +++ b/thin-provisioning/metadata.h @@ -25,9 +25,9 @@ #include "persistent-data/space-maps/disk.h" #include "persistent-data/transaction_manager.h" -#include "thin-provisioning/metadata_disk_structures.h" #include "thin-provisioning/device_tree.h" #include "thin-provisioning/mapping_tree.h" +#include "thin-provisioning/superblock.h" //---------------------------------------------------------------- @@ -77,7 +77,7 @@ namespace thin_provisioning { tm_ptr tm_; - superblock sb_; + superblock_detail::superblock sb_; checked_space_map::ptr metadata_sm_; checked_space_map::ptr data_sm_; diff --git a/thin-provisioning/metadata_checker.cc b/thin-provisioning/metadata_checker.cc index 1d064a7..548ea2f 100644 --- a/thin-provisioning/metadata_checker.cc +++ b/thin-provisioning/metadata_checker.cc @@ -25,7 +25,7 @@ using namespace persistent_data; using namespace thin_provisioning; //---------------------------------------------------------------- - +#if 0 void metadata_damage::set_message(std::string const &message) { @@ -436,3 +436,4 @@ thin_provisioning::metadata_check(std::string const &dev_path) //---------------------------------------------------------------- #endif +#endif diff --git a/thin-provisioning/metadata_checker.h b/thin-provisioning/metadata_checker.h index 877f1b5..890b937 100644 --- a/thin-provisioning/metadata_checker.h +++ b/thin-provisioning/metadata_checker.h @@ -29,7 +29,18 @@ //---------------------------------------------------------------- namespace thin_provisioning { - class metadata_damage_visitor; + // FIXME: should take a block manager or transaction manager + void check_metadata(std::string const &path); + + + + + + + + + +#if 0 // Base class for all types of metadata damage. Used in reporting. class metadata_damage { @@ -143,22 +154,7 @@ namespace thin_provisioning { typedef std::deque damage_list; typedef boost::shared_ptr damage_list_ptr; - - //-------------------------------- - - class checker { - public: - typedef persistent_data::block_manager<> block_manager; - typedef boost::shared_ptr ptr; - - checker(block_manager::ptr bm); - - virtual ~checker() {}; - virtual damage_list_ptr check() = 0; - - protected: - block_manager::ptr bm_; - }; +#endif } //---------------------------------------------------------------- diff --git a/thin-provisioning/metadata_disk_structures.h b/thin-provisioning/metadata_disk_structures.h deleted file mode 100644 index 0b1d978..0000000 --- a/thin-provisioning/metadata_disk_structures.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2011 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#ifndef METADATA_DISK_STRUCTURES_H -#define METADATA_DISK_STRUCTURES_H - -#include "persistent-data/endian_utils.h" -#include "persistent-data/data-structures/btree.h" - -//---------------------------------------------------------------- - -namespace thin_provisioning { - using namespace base; // FIXME: don't use namespaces in headers. - - unsigned const SPACE_MAP_ROOT_SIZE = 128; - - typedef unsigned char __u8; - - struct superblock_disk { - le32 csum_; - le32 flags_; - le64 blocknr_; - - __u8 uuid_[16]; - le64 magic_; - le32 version_; - le32 time_; - - le64 trans_id_; - /* root for userspace's transaction (for migration and friends) */ - le64 metadata_snap_; - - __u8 data_space_map_root_[SPACE_MAP_ROOT_SIZE]; - __u8 metadata_space_map_root_[SPACE_MAP_ROOT_SIZE]; - - /* 2 level btree mapping (dev_id, (dev block, time)) -> data block */ - le64 data_mapping_root_; - - /* device detail root mapping dev_id -> device_details */ - le64 device_details_root_; - - le32 data_block_size_; /* in 512-byte sectors */ - - le32 metadata_block_size_; /* in 512-byte sectors */ - le64 metadata_nr_blocks_; - - le32 compat_flags_; - le32 compat_ro_flags_; - le32 incompat_flags_; - } __attribute__ ((packed)); - - struct superblock { - uint32_t csum_; - uint32_t flags_; - uint64_t blocknr_; - - unsigned char uuid_[16]; - uint64_t magic_; - uint32_t version_; - uint32_t time_; - - uint64_t trans_id_; - /* root for userspace's transaction (for migration and friends) */ - uint64_t metadata_snap_; - - unsigned char data_space_map_root_[SPACE_MAP_ROOT_SIZE]; - unsigned char metadata_space_map_root_[SPACE_MAP_ROOT_SIZE]; - - /* 2 level btree mapping (dev_id, (dev block, time)) -> data block */ - uint64_t data_mapping_root_; - - /* device detail root mapping dev_id -> device_details */ - uint64_t device_details_root_; - - uint32_t data_block_size_; /* in 512-byte sectors */ - - uint32_t metadata_block_size_; /* in 512-byte sectors */ - uint64_t metadata_nr_blocks_; - - uint32_t compat_flags_; - uint32_t compat_ro_flags_; - uint32_t incompat_flags_; - }; - - struct superblock_traits { - typedef superblock_disk disk_type; - typedef superblock value_type; - typedef no_op_ref_counter ref_counter; - - static void unpack(superblock_disk const &disk, superblock &core); - static void pack(superblock const &core, superblock_disk &disk); - }; - - block_address const SUPERBLOCK_LOCATION = 0; -} - -//---------------------------------------------------------------- - -#endif diff --git a/thin-provisioning/restore_emitter.cc b/thin-provisioning/restore_emitter.cc index 58b5c18..ecd2fe5 100644 --- a/thin-provisioning/restore_emitter.cc +++ b/thin-provisioning/restore_emitter.cc @@ -16,7 +16,8 @@ // with thin-provisioning-tools. If not, see // . -#include "restore_emitter.h" +#include "thin-provisioning/restore_emitter.h" +#include "thin-provisioning/superblock.h" using namespace boost; using namespace std; @@ -25,6 +26,8 @@ using namespace thin_provisioning; //---------------------------------------------------------------- namespace { + using namespace superblock_detail; + class restorer : public emitter { public: restorer(metadata::ptr md) diff --git a/thin-provisioning/metadata_disk_structures.cc b/thin-provisioning/superblock.cc similarity index 72% rename from thin-provisioning/metadata_disk_structures.cc rename to thin-provisioning/superblock.cc index f484763..c9c9751 100644 --- a/thin-provisioning/metadata_disk_structures.cc +++ b/thin-provisioning/superblock.cc @@ -1,26 +1,8 @@ -// Copyright (C) 2011 Red Hat, Inc. All rights reserved. -// -// This file is part of the thin-provisioning-tools source. -// -// thin-provisioning-tools is free software: you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// thin-provisioning-tools is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with thin-provisioning-tools. If not, see -// . - -#include "thin-provisioning/metadata_disk_structures.h" - -#include +#include "thin-provisioning/superblock.h" +#include "thin-provisioning/superblock_validator.h" using namespace thin_provisioning; +using namespace superblock_detail; //---------------------------------------------------------------- @@ -91,3 +73,40 @@ superblock_traits::pack(superblock const &value, superblock_disk &disk) } //---------------------------------------------------------------- + + +#if 0 +superblock_checker::superblock_checker(block_manager::ptr bm) + : checker(bm) +{ +} + +// FIXME: Other things to check: +// - magic +// - version +// - 3 * flags (should be zero) +// - in bounds: metadata_snap, data_mapping_root +// - metadata_nr_blocks_ matches what we've been given. +damage_list_ptr +superblock_checker::check() +{ + superblock sb; + + damage_list_ptr damage(new damage_list); + + try { + block_manager::read_ref r = bm_->read_lock(SUPERBLOCK_LOCATION, superblock_validator()); + superblock_disk const *sbd = reinterpret_cast(&r.data()); + superblock_traits::unpack(*sbd, sb); + + } catch (checksum_error const &e) { + metadata_damage::ptr err(new super_block_corruption); + err->set_message("checksum error"); + damage->push_back(err); + } + + return damage; +} + +//---------------------------------------------------------------- +#endif diff --git a/thin-provisioning/superblock.h b/thin-provisioning/superblock.h new file mode 100644 index 0000000..ce69ef6 --- /dev/null +++ b/thin-provisioning/superblock.h @@ -0,0 +1,108 @@ +#ifndef THIN_SUPERBLOCK_H +#define THIN_SUPERBLOCK_H + +#include "persistent-data/block.h" +#include "persistent-data/endian_utils.h" +#include "persistent-data/data-structures/ref_counter.h" + +//---------------------------------------------------------------- + +namespace thin_provisioning { + namespace superblock_detail { + using namespace base; + using namespace persistent_data; + + unsigned const SPACE_MAP_ROOT_SIZE = 128; + + typedef unsigned char __u8; + + struct superblock_disk { + le32 csum_; + le32 flags_; + le64 blocknr_; + + __u8 uuid_[16]; + le64 magic_; + le32 version_; + le32 time_; + + le64 trans_id_; + /* root for userspace's transaction (for migration and friends) */ + le64 metadata_snap_; + + __u8 data_space_map_root_[SPACE_MAP_ROOT_SIZE]; + __u8 metadata_space_map_root_[SPACE_MAP_ROOT_SIZE]; + + /* 2 level btree mapping (dev_id, (dev block, time)) -> data block */ + le64 data_mapping_root_; + + /* device detail root mapping dev_id -> device_details */ + le64 device_details_root_; + + le32 data_block_size_; /* in 512-byte sectors */ + + le32 metadata_block_size_; /* in 512-byte sectors */ + le64 metadata_nr_blocks_; + + le32 compat_flags_; + le32 compat_ro_flags_; + le32 incompat_flags_; + } __attribute__ ((packed)); + + struct superblock { + uint32_t csum_; + uint32_t flags_; + uint64_t blocknr_; + + unsigned char uuid_[16]; + uint64_t magic_; + uint32_t version_; + uint32_t time_; + + uint64_t trans_id_; + /* root for userspace's transaction (for migration and friends) */ + uint64_t metadata_snap_; + + unsigned char data_space_map_root_[SPACE_MAP_ROOT_SIZE]; + unsigned char metadata_space_map_root_[SPACE_MAP_ROOT_SIZE]; + + /* 2 level btree mapping (dev_id, (dev block, time)) -> data block */ + uint64_t data_mapping_root_; + + /* device detail root mapping dev_id -> device_details */ + uint64_t device_details_root_; + + uint32_t data_block_size_; /* in 512-byte sectors */ + + uint32_t metadata_block_size_; /* in 512-byte sectors */ + uint64_t metadata_nr_blocks_; + + uint32_t compat_flags_; + uint32_t compat_ro_flags_; + uint32_t incompat_flags_; + }; + + struct superblock_traits { + typedef superblock_disk disk_type; + typedef superblock value_type; + typedef no_op_ref_counter ref_counter; + + static void unpack(superblock_disk const &disk, superblock &core); + static void pack(superblock const &core, superblock_disk &disk); + }; + + block_address const SUPERBLOCK_LOCATION = 0; + } + +#if 0 + class superblock_checker : public checker { + public: + superblock_checker(block_manager::ptr bm); + damage_list_ptr check(); + }; +#endif +} + +//---------------------------------------------------------------- + +#endif diff --git a/thin-provisioning/superblock_checker.cc b/thin-provisioning/superblock_checker.cc deleted file mode 100644 index f2dd625..0000000 --- a/thin-provisioning/superblock_checker.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "thin-provisioning/superblock_checker.h" - -#include "thin-provisioning/metadata_disk_structures.h" -#include "thin-provisioning/superblock_validator.h" - - -using namespace thin_provisioning; - -//---------------------------------------------------------------- - -superblock_checker::superblock_checker(block_manager::ptr bm) - : checker(bm) -{ -} - -// FIXME: Other things to check: -// - magic -// - version -// - 3 * flags (should be zero) -// - in bounds: metadata_snap, data_mapping_root -// - metadata_nr_blocks_ matches what we've been given. -damage_list_ptr -superblock_checker::check() -{ - superblock sb; - - damage_list_ptr damage(new damage_list); - - try { - block_manager::read_ref r = bm_->read_lock(SUPERBLOCK_LOCATION, superblock_validator()); - superblock_disk const *sbd = reinterpret_cast(&r.data()); - superblock_traits::unpack(*sbd, sb); - - } catch (checksum_error const &e) { - metadata_damage::ptr err(new super_block_corruption); - err->set_message("checksum error"); - damage->push_back(err); - } - - return damage; -} - -//---------------------------------------------------------------- diff --git a/thin-provisioning/superblock_checker.h b/thin-provisioning/superblock_checker.h deleted file mode 100644 index fd50a5d..0000000 --- a/thin-provisioning/superblock_checker.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef THIN_SUPERBLOCK_CHECKER_H -#define THIN_SUPERBLOCK_CHECKER_H - -#include "thin-provisioning/metadata_checker.h" - -//---------------------------------------------------------------- - -namespace thin_provisioning { - class superblock_checker : public checker { - public: - superblock_checker(block_manager::ptr bm); - damage_list_ptr check(); - }; -} - -//---------------------------------------------------------------- - -#endif diff --git a/thin-provisioning/superblock_validator.cc b/thin-provisioning/superblock_validator.cc index 2d59d65..1f5b561 100644 --- a/thin-provisioning/superblock_validator.cc +++ b/thin-provisioning/superblock_validator.cc @@ -1,12 +1,17 @@ -#include "thin-provisioning/superblock_validator.h" +#include "persistent-data/checksum.h" +#include "persistent-data/errors.h" -#include "thin-provisioning/metadata_disk_structures.h" +#include "thin-provisioning/superblock_validator.h" +#include "thin-provisioning/superblock.h" using namespace thin_provisioning; //---------------------------------------------------------------- namespace { + using namespace persistent_data; + using namespace superblock_detail; + uint32_t const VERSION = 1; unsigned const SECTOR_TO_BLOCK_SHIFT = 3; uint32_t const SUPERBLOCK_CSUM_SEED = 160774; diff --git a/thin-provisioning/thin_check.cc b/thin-provisioning/thin_check.cc index b183ead..c768c0d 100644 --- a/thin-provisioning/thin_check.cc +++ b/thin-provisioning/thin_check.cc @@ -29,6 +29,12 @@ using namespace std; using namespace thin_provisioning; namespace { + enum error_state { + NO_ERRORS, + NON_FATAL, // eg, lost blocks + FATAL // needs fixing before pool can be activated + }; + int check(string const &path, bool quiet) { try { optional maybe_errors = metadata_check(path);