diff --git a/caching/cache_repair.cc b/caching/cache_repair.cc index 5d1aafa..4a8cd9c 100644 --- a/caching/cache_repair.cc +++ b/caching/cache_repair.cc @@ -23,7 +23,7 @@ namespace { emitter::ptr output_emitter(string const &path) { block_manager<>::ptr bm = open_bm(path, block_io<>::READ_WRITE); metadata::ptr md(new metadata(bm, metadata::CREATE)); - return create_restore_emitter(md); + return create_restore_emitter(md, true); } int repair(string const &old_path, string const &new_path) { diff --git a/caching/cache_restore.cc b/caching/cache_restore.cc index b672932..536ef82 100644 --- a/caching/cache_restore.cc +++ b/caching/cache_restore.cc @@ -23,20 +23,23 @@ namespace { struct flags { flags() : metadata_version(1), - override_metadata_version(false) { + override_metadata_version(false), + clean_shutdown(true) { } optional input; optional output; + uint32_t metadata_version; bool override_metadata_version; + bool clean_shutdown; }; int restore(flags const &fs) { try { block_manager<>::ptr bm = open_bm(*fs.output, block_io<>::READ_WRITE); metadata::ptr md(new metadata(bm, metadata::CREATE)); - emitter::ptr restorer = create_restore_emitter(md); + emitter::ptr restorer = create_restore_emitter(md, fs.clean_shutdown); if (fs.override_metadata_version) { cerr << "overriding" << endl; @@ -63,7 +66,8 @@ namespace { << " {-o|--output} " << endl << " {-V|--version}" << endl << endl - << " {--debug-override-metadata-version} " << endl; + << " {--debug-override-metadata-version} " << endl + << " {--omit-clean-shutdown}" << endl; } } @@ -76,6 +80,7 @@ int main(int argc, char **argv) char const *short_opts = "hi:o:V"; option const long_opts[] = { { "debug-override-metadata-version", required_argument, NULL, 0 }, + { "omit-clean-shutdown", no_argument, NULL, 1 }, { "help", no_argument, NULL, 'h'}, { "input", required_argument, NULL, 'i' }, { "output", required_argument, NULL, 'o'}, @@ -90,6 +95,10 @@ int main(int argc, char **argv) fs.override_metadata_version = true; break; + case 1: + fs.clean_shutdown = false; + break; + case 'h': usage(cout, prog_name); return 0; diff --git a/caching/metadata.cc b/caching/metadata.cc index 2d8ef83..0633306 100644 --- a/caching/metadata.cc +++ b/caching/metadata.cc @@ -47,13 +47,13 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot) } void -metadata::commit() +metadata::commit(bool clean_shutdown) { commit_space_map(); commit_mappings(); commit_hints(); commit_discard_bits(); - commit_superblock(); + commit_superblock(clean_shutdown); } void @@ -130,10 +130,13 @@ metadata::commit_discard_bits() } void -metadata::commit_superblock() +metadata::commit_superblock(bool clean_shutdown) { - sb_.flags.set_flag(superblock_flags::CLEAN_SHUTDOWN); + if (clean_shutdown) + sb_.flags.set_flag(superblock_flags::CLEAN_SHUTDOWN); + write_superblock(tm_->get_bm(), sb_); + sb_.flags.clear_flag(superblock_flags::CLEAN_SHUTDOWN); } diff --git a/caching/metadata.h b/caching/metadata.h index 611b424..2e5eccf 100644 --- a/caching/metadata.h +++ b/caching/metadata.h @@ -28,7 +28,7 @@ namespace caching { metadata(block_manager<>::ptr bm, open_type ot); - void commit(); + void commit(bool clean_shutdown = true); void setup_hint_array(size_t width); @@ -50,7 +50,7 @@ namespace caching { void commit_mappings(); void commit_hints(); void commit_discard_bits(); - void commit_superblock(); + void commit_superblock(bool clean_shutdown); }; }; diff --git a/caching/restore_emitter.cc b/caching/restore_emitter.cc index 6c862bf..55be343 100644 --- a/caching/restore_emitter.cc +++ b/caching/restore_emitter.cc @@ -11,9 +11,10 @@ using namespace superblock_damage; namespace { class restorer : public emitter { public: - restorer(metadata::ptr md) + restorer(metadata::ptr md, bool clean_shutdown) : in_superblock_(false), - md_(md) { + md_(md), + clean_shutdown_(clean_shutdown) { } virtual ~restorer() { @@ -44,7 +45,7 @@ namespace { } virtual void end_superblock() { - md_->commit(); + md_->commit(clean_shutdown_); } virtual void begin_mappings() { @@ -99,15 +100,16 @@ namespace { private: bool in_superblock_; metadata::ptr md_; + bool clean_shutdown_; }; } //---------------------------------------------------------------- emitter::ptr -caching::create_restore_emitter(metadata::ptr md) +caching::create_restore_emitter(metadata::ptr md, bool clean_shutdown) { - return emitter::ptr(new restorer(md)); + return emitter::ptr(new restorer(md, clean_shutdown)); } //---------------------------------------------------------------- diff --git a/caching/restore_emitter.h b/caching/restore_emitter.h index 658dc68..9282895 100644 --- a/caching/restore_emitter.h +++ b/caching/restore_emitter.h @@ -7,7 +7,7 @@ //---------------------------------------------------------------- namespace caching { - emitter::ptr create_restore_emitter(metadata::ptr md); + emitter::ptr create_restore_emitter(metadata::ptr md, bool clean_shutdown = true); } //---------------------------------------------------------------- diff --git a/features/cache_restore.feature b/features/cache_restore.feature index b9eef7d..1052089 100644 --- a/features/cache_restore.feature +++ b/features/cache_restore.feature @@ -21,6 +21,7 @@ Feature: thin_restore {-V|--version} {--debug-override-metadata-version} + {--omit-clean-shutdown} """ @@ -38,6 +39,7 @@ Feature: thin_restore {-V|--version} {--debug-override-metadata-version} + {--omit-clean-shutdown} """ @@ -72,3 +74,9 @@ Feature: thin_restore And an empty dev file When I run cache_restore with -i metadata.xml -o metadata.bin --debug-override-metadata-version 10298 Then it should pass + + Scenario: accepts --omit-clean-shutdown + Given a small xml file + And an empty dev file + When I run cache_restore with -i metadata.xml -o metadata.bin --omit-clean-shutdown + Then it should pass