diff --git a/Makefile.in b/Makefile.in index e4e35f7..bcdba26 100644 --- a/Makefile.in +++ b/Makefile.in @@ -25,7 +25,8 @@ PROGRAMS=\ thin_debug \ thin_check \ thin_dump \ - thin_restore + thin_restore \ + thin_rmap all: $(PROGRAMS) @@ -67,7 +68,8 @@ PROGRAM_SOURCE=\ \ thin-provisioning/thin_check.cc \ thin-provisioning/thin_dump.cc \ - thin-provisioning/thin_restore.cc + thin-provisioning/thin_restore.cc \ + thin-provisioning/thin_rmap.cc CXX:=@CXX@ OBJECTS:=$(subst .cc,.o,$(SOURCE)) @@ -141,10 +143,29 @@ THIN_CHECK_SOURCE=\ thin-provisioning/metadata_checker.cc \ thin-provisioning/superblock.cc +THIN_RMAP_SOURCE=\ + persistent-data/checksum.cc \ + persistent-data/endian_utils.cc \ + persistent-data/error_set.cc \ + persistent-data/hex_dump.cc \ + persistent-data/lock_tracker.cc \ + persistent-data/space_map.cc \ + persistent-data/space-maps/disk.cc \ + persistent-data/space-maps/recursive.cc \ + persistent-data/space-maps/careful_alloc.cc \ + persistent-data/transaction_manager.cc \ + thin-provisioning/file_utils.cc \ + thin-provisioning/device_tree.cc \ + thin-provisioning/mapping_tree.cc \ + thin-provisioning/metadata.cc \ + thin-provisioning/metadata_checker.cc \ + thin-provisioning/superblock.cc + THIN_DEBUG_OBJECTS=$(subst .cc,.o,$(THIN_DEBUG_SOURCE)) THIN_DUMP_OBJECTS=$(subst .cc,.o,$(THIN_DUMP_SOURCE)) THIN_RESTORE_OBJECTS=$(subst .cc,.o,$(THIN_RESTORE_SOURCE)) THIN_CHECK_OBJECTS=$(subst .cc,.o,$(THIN_CHECK_SOURCE)) +THIN_RMAP_OBJECTS=$(subst .cc,.o,$(THIN_RMAP_SOURCE)) thin_debug: $(THIN_DEBUG_OBJECTS) thin-provisioning/thin_debug.o @echo " [LD] $@" @@ -158,7 +179,7 @@ thin_restore: $(THIN_RESTORE_OBJECTS) thin-provisioning/thin_restore.o @echo " [LD] $@" $(V) $(CXX) $(CXXFLAGS) -o $@ $+ $(LIBS) $(LIBEXPAT) -thin_check: $(THIN_CHECK_OBJECTS) thin-provisioning/thin_check.o +thin_rmap: $(THIN_RMAP_OBJECTS) thin-provisioning/thin_rmap.o @echo " [LD] $@" $(V) $(CXX) $(CXXFLAGS) -o $@ $+ $(LIBS) diff --git a/features/thin_rmap.feature b/features/thin_rmap.feature new file mode 100644 index 0000000..46b2f48 --- /dev/null +++ b/features/thin_rmap.feature @@ -0,0 +1,49 @@ +Feature: thin_rmap + Scenario: print version (-V flag) + When I run `thin_rmap -V` + Then it should pass with: + + """ + 0.1.5 + """ + + Scenario: print version (--version flag) + When I run `thin_rmap --version` + Then it should pass with: + + """ + 0.1.5 + """ + + Scenario: print help + When I run `thin_rmap --help` + Then it should pass with: + + """ + Usage: thin_rmap [options] {device|file} + Options: + {-h|--help} + {-V|--version} + {--region }* + Where: + is of the form .. + for example 5..45 denotes blocks 5 to 44 inclusive, but not block 45 + """ + + Scenario: print help + When I run `thin_rmap -h` + Then it should pass with: + """ + Usage: thin_rmap [options] {device|file} + Options: + {-h|--help} + {-V|--version} + {--region }* + Where: + is of the form .. + for example 5..45 denotes blocks 5 to 44 inclusive, but not block 45 + """ + + Scenario: Unrecognised option should cause failure + When I run `thin_rmap --unleash-the-hedeghogs` + Then it should fail diff --git a/thin-provisioning/thin_rmap.cc b/thin-provisioning/thin_rmap.cc new file mode 100644 index 0000000..6a59411 --- /dev/null +++ b/thin-provisioning/thin_rmap.cc @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +#include "version.h" + +#include "persistent-data/range.h" +#include "thin-provisioning/superblock.h" +#include "thin-provisioning/mapping_tree.h" + +using namespace std; +using namespace thin_provisioning; + +//---------------------------------------------------------------- + +namespace { + typedef range region; + + int rmap(string const &path, vector const ®ions) { + cerr << "Not implemented" << endl; + return 1; + } + + void usage(ostream &out, string const &cmd) { + out << "Usage: " << cmd << " [options] {device|file}" << endl + << "Options:" << endl + << " {-h|--help}" << endl + << " {-V|--version}" << endl + << " {--region }*" << endl + << "Where:" << endl + << " is of the form .." << endl + << " for example 5..45 denotes blocks 5 to 44 inclusive, but not block 45" << endl; + } +} + +//---------------------------------------------------------------- + +int main(int argc, char **argv) +{ + int c; + vector regions; + char const shortopts[] = "hV"; + option const longopts[] = { + { "help", no_argument, NULL, 'h'}, + { "version", no_argument, NULL, 'V'}, + { "region", required_argument, NULL, 1}, + { NULL, no_argument, NULL, 0 } + }; + + while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { + switch (c) { + case 'h': + usage(cout, basename(argv[0])); + return 0; + + case 'V': + cout << THIN_PROVISIONING_TOOLS_VERSION << endl; + return 0; + + case 1: + // region + break; + + default: + usage(cerr, basename(argv[0])); + return 1; + } + } + + if (argc == optind) { + cerr << "No input file provided." << endl; + usage(cerr, basename(argv[0])); + exit(1); + } + + return rmap(argv[optind], regions); +} + +//----------------------------------------------------------------