[thin] Introduce thin_patch_superblock to override superblock fields
This commit is contained in:
parent
c42b623e39
commit
b42408ef41
@ -134,6 +134,7 @@ DEVTOOLS_SOURCE=\
|
||||
thin-provisioning/thin_generate_metadata.cc \
|
||||
thin-provisioning/thin_generate_mappings.cc \
|
||||
thin-provisioning/variable_chunk_stream.cc \
|
||||
thin-provisioning/thin_patch_superblock.cc \
|
||||
thin-provisioning/thin_show_metadata.cc \
|
||||
thin-provisioning/thin_scan.cc \
|
||||
ui/ui.cc
|
||||
|
@ -25,6 +25,7 @@ thin_provisioning::register_thin_commands(base::application &app)
|
||||
app.add_cmd(command::ptr(new thin_generate_damage_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_generate_metadata_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_generate_mappings_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_patch_superblock_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_show_duplicates_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_show_metadata_cmd()));
|
||||
app.add_cmd(command::ptr(new thin_journal_cmd()));
|
||||
|
@ -124,6 +124,13 @@ namespace thin_provisioning {
|
||||
virtual int run(int argc, char **argv);
|
||||
};
|
||||
|
||||
class thin_patch_superblock_cmd : public base::command {
|
||||
public:
|
||||
thin_patch_superblock_cmd();
|
||||
virtual void usage(std::ostream &out) const;
|
||||
virtual int run(int argc, char **argv);
|
||||
};
|
||||
|
||||
class thin_show_metadata_cmd : public base::command {
|
||||
public:
|
||||
thin_show_metadata_cmd();
|
||||
|
193
thin-provisioning/thin_patch_superblock.cc
Normal file
193
thin-provisioning/thin_patch_superblock.cc
Normal file
@ -0,0 +1,193 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include "persistent-data/file_utils.h"
|
||||
#include "persistent-data/space-maps/disk_structures.h"
|
||||
#include "thin-provisioning/commands.h"
|
||||
#include "thin-provisioning/metadata.h"
|
||||
#include "thin-provisioning/superblock.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace persistent_data;
|
||||
using namespace sm_disk_detail;
|
||||
using namespace thin_provisioning;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
struct flags {
|
||||
flags();
|
||||
bool check_conformance();
|
||||
|
||||
string output;
|
||||
|
||||
boost::optional<uint64_t> transaction_id;
|
||||
block_address data_mapping_root;
|
||||
block_address device_details_root;
|
||||
|
||||
block_address metadata_bitmap_root;
|
||||
block_address metadata_ref_count_root;
|
||||
|
||||
block_address data_bitmap_root;
|
||||
block_address data_ref_count_root;
|
||||
};
|
||||
|
||||
flags::flags()
|
||||
: data_mapping_root(0), device_details_root(0),
|
||||
metadata_bitmap_root(0), metadata_ref_count_root(0),
|
||||
data_bitmap_root(0), data_ref_count_root(0) {
|
||||
}
|
||||
|
||||
bool flags::check_conformance() {
|
||||
if (!output.size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void patch_space_map_root(void *root,
|
||||
block_address bitmap_root,
|
||||
block_address ref_count_root) {
|
||||
sm_disk_detail::sm_root v;
|
||||
sm_disk_detail::sm_root_disk d;
|
||||
|
||||
memcpy(&d, root, sizeof(d));
|
||||
sm_root_traits::unpack(d, v);
|
||||
|
||||
if (bitmap_root)
|
||||
v.bitmap_root_ = bitmap_root;
|
||||
if (ref_count_root)
|
||||
v.ref_count_root_ = ref_count_root;
|
||||
|
||||
sm_root_traits::pack(v, d);
|
||||
memcpy(root, &d, sizeof(d));
|
||||
}
|
||||
|
||||
int patch_superblock(flags const &fs) {
|
||||
block_manager::ptr bm = open_bm(fs.output, block_manager::READ_WRITE);
|
||||
superblock_detail::superblock sb = read_superblock(bm, superblock_detail::SUPERBLOCK_LOCATION);
|
||||
|
||||
if (fs.transaction_id)
|
||||
sb.trans_id_ = *fs.transaction_id;
|
||||
|
||||
if (fs.data_mapping_root)
|
||||
sb.data_mapping_root_ = fs.data_mapping_root;
|
||||
|
||||
if (fs.device_details_root)
|
||||
sb.device_details_root_ = fs.device_details_root;
|
||||
|
||||
patch_space_map_root(sb.metadata_space_map_root_,
|
||||
fs.metadata_bitmap_root,
|
||||
fs.metadata_ref_count_root);
|
||||
|
||||
patch_space_map_root(sb.data_space_map_root_,
|
||||
fs.data_bitmap_root,
|
||||
fs.data_ref_count_root);
|
||||
|
||||
write_superblock(bm, sb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
thin_patch_superblock_cmd::thin_patch_superblock_cmd()
|
||||
: command("thin_patch_superblock")
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
thin_patch_superblock_cmd::usage(std::ostream &out) const
|
||||
{
|
||||
out << "Usage: " << get_name() << " [options]\n"
|
||||
<< "Options:\n"
|
||||
<< " {-h|--help}\n"
|
||||
<< " {-o|--output} <output device or file>\n"
|
||||
<< " {--transaction-id} <tid>\n"
|
||||
<< " {--data-mapping-root} <blocknr>\n"
|
||||
<< " {--device-details-root} <blocknr>\n"
|
||||
<< " {--metadata-bitmap-root} <blocknr>\n"
|
||||
<< " {--metadata-ref-count-root} <blocknr>\n"
|
||||
<< " {--data-bitmap-root} <blocknr>\n"
|
||||
<< " {--data-ref-count-root} <blocknr>\n"
|
||||
<< " {-V|--version}" << endl;
|
||||
}
|
||||
|
||||
int
|
||||
thin_patch_superblock_cmd::run(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
flags fs;
|
||||
const char shortopts[] = "ho:V";
|
||||
|
||||
const struct option longopts[] = {
|
||||
{ "help", no_argument, NULL, 'h'},
|
||||
{ "output", required_argument, NULL, 'o'},
|
||||
{ "transaction-id", required_argument, NULL, 1 },
|
||||
{ "data-mapping-root", required_argument, NULL, 2 },
|
||||
{ "device-details-root", required_argument, NULL, 3 },
|
||||
{ "metadata-bitmap-root", required_argument, NULL, 4 },
|
||||
{ "metadata-ref-count-root", required_argument, NULL, 5 },
|
||||
{ "data-bitmap-root", required_argument, NULL, 6 },
|
||||
{ "data-ref-count-root", required_argument, NULL, 7 },
|
||||
{ "version", no_argument, NULL, 'V'},
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
usage(cout);
|
||||
return 0;
|
||||
|
||||
case 'o':
|
||||
fs.output = optarg;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fs.transaction_id = parse_uint64(optarg, "transaction_id");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fs.data_mapping_root = parse_uint64(optarg, "data_mapping_root");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fs.device_details_root = parse_uint64(optarg, "device_details_root");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fs.metadata_bitmap_root = parse_uint64(optarg, "metadata_bitmap_root");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
fs.metadata_ref_count_root = parse_uint64(optarg, "metadata_ref_count_root");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
fs.data_bitmap_root = parse_uint64(optarg, "data_bitmap_root");
|
||||
break;
|
||||
|
||||
case 7:
|
||||
fs.data_ref_count_root = parse_uint64(optarg, "data_ref_count_root");
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
cout << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage(cerr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.check_conformance()) {
|
||||
usage(cerr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return patch_superblock(fs);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user