[*_restore] if things go wrong wipe the superblock.
So we don't leave the metadata device with partially restored metadata.
This commit is contained in:
parent
8035e10b2a
commit
5b92f410ec
@ -9,6 +9,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
@ -140,4 +141,16 @@ file_utils::get_file_length(string const &file) {
|
|||||||
return nr_bytes;
|
return nr_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
file_utils::zero_superblock(std::string const &path)
|
||||||
|
{
|
||||||
|
unsigned const SUPERBLOCK_SIZE = 4096;
|
||||||
|
char buffer[SUPERBLOCK_SIZE];
|
||||||
|
int fd = open_block_file(path, SUPERBLOCK_SIZE, true, true);
|
||||||
|
|
||||||
|
memset(buffer, 0, SUPERBLOCK_SIZE);
|
||||||
|
if (::write(fd, buffer, SUPERBLOCK_SIZE) != SUPERBLOCK_SIZE)
|
||||||
|
throw runtime_error("couldn't zero superblock");
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
@ -14,6 +14,7 @@ namespace file_utils {
|
|||||||
int create_block_file(std::string const &path, off_t file_size);
|
int create_block_file(std::string const &path, off_t file_size);
|
||||||
int open_block_file(std::string const &path, off_t min_size, bool writeable, bool excl = true);
|
int open_block_file(std::string const &path, off_t min_size, bool writeable, bool excl = true);
|
||||||
uint64_t get_file_length(std::string const &file);
|
uint64_t get_file_length(std::string const &file);
|
||||||
|
void zero_superblock(std::string const &path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
@ -57,16 +57,20 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int restore(flags const &fs) {
|
int restore(flags const &fs) {
|
||||||
|
bool metadata_touched = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
|
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
|
||||||
|
|
||||||
|
check_file_exists(*fs.input);
|
||||||
|
ifstream in(fs.input->c_str(), ifstream::in);
|
||||||
|
|
||||||
|
metadata_touched = true;
|
||||||
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
||||||
emitter::ptr restorer = create_restore_emitter(md,
|
emitter::ptr restorer = create_restore_emitter(md,
|
||||||
fs.metadata_version,
|
fs.metadata_version,
|
||||||
fs.clean_shutdown ? CLEAN_SHUTDOWN : NO_CLEAN_SHUTDOWN);
|
fs.clean_shutdown ? CLEAN_SHUTDOWN : NO_CLEAN_SHUTDOWN);
|
||||||
|
|
||||||
check_file_exists(*fs.input);
|
|
||||||
ifstream in(fs.input->c_str(), ifstream::in);
|
|
||||||
|
|
||||||
unique_ptr<progress_monitor> monitor = create_monitor(fs.quiet);
|
unique_ptr<progress_monitor> monitor = create_monitor(fs.quiet);
|
||||||
parse_xml(in, restorer, get_file_length(*fs.input), *monitor);
|
parse_xml(in, restorer, get_file_length(*fs.input), *monitor);
|
||||||
|
|
||||||
@ -74,6 +78,8 @@ namespace {
|
|||||||
override_version(md, fs);
|
override_version(md, fs);
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
|
if (metadata_touched)
|
||||||
|
zero_superblock(*fs.output);
|
||||||
cerr << e.what() << endl;
|
cerr << e.what() << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#include "base/file_utils.h"
|
||||||
#include "base/output_file_requirements.h"
|
#include "base/output_file_requirements.h"
|
||||||
#include "era/commands.h"
|
#include "era/commands.h"
|
||||||
#include "era/metadata.h"
|
#include "era/metadata.h"
|
||||||
@ -33,14 +34,19 @@ namespace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int restore(flags const &fs, bool quiet) {
|
int restore(flags const &fs, bool quiet) {
|
||||||
|
bool metadata_touched = false;
|
||||||
try {
|
try {
|
||||||
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
|
block_manager<>::ptr bm = open_bm(*fs.output, block_manager<>::READ_WRITE);
|
||||||
|
file_utils::check_file_exists(*fs.output);
|
||||||
|
metadata_touched = true;
|
||||||
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
metadata::ptr md(new metadata(bm, metadata::CREATE));
|
||||||
emitter::ptr restorer = create_restore_emitter(*md);
|
emitter::ptr restorer = create_restore_emitter(*md);
|
||||||
|
|
||||||
parse_xml(*fs.input, restorer, fs.quiet);
|
parse_xml(*fs.input, restorer, fs.quiet);
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
|
if (metadata_touched)
|
||||||
|
file_utils::zero_superblock(*fs.output);
|
||||||
cerr << e.what() << endl;
|
cerr << e.what() << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
// with thin-provisioning-tools. If not, see
|
// with thin-provisioning-tools. If not, see
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "base/file_utils.h"
|
||||||
#include "base/output_file_requirements.h"
|
#include "base/output_file_requirements.h"
|
||||||
#include "persistent-data/file_utils.h"
|
#include "persistent-data/file_utils.h"
|
||||||
#include "thin-provisioning/commands.h"
|
#include "thin-provisioning/commands.h"
|
||||||
@ -44,15 +45,20 @@ using namespace thin_provisioning;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int restore(string const &backup_file, string const &dev, bool quiet) {
|
int restore(string const &backup_file, string const &dev, bool quiet) {
|
||||||
|
bool metadata_touched = false;
|
||||||
try {
|
try {
|
||||||
// The block size gets updated by the restorer.
|
// The block size gets updated by the restorer.
|
||||||
block_manager<>::ptr bm(open_bm(dev, block_manager<>::READ_WRITE));
|
block_manager<>::ptr bm(open_bm(dev, block_manager<>::READ_WRITE));
|
||||||
|
file_utils::check_file_exists(backup_file);
|
||||||
|
metadata_touched = true;
|
||||||
metadata::ptr md(new metadata(bm, metadata::CREATE, 128, 0));
|
metadata::ptr md(new metadata(bm, metadata::CREATE, 128, 0));
|
||||||
emitter::ptr restorer = create_restore_emitter(md);
|
emitter::ptr restorer = create_restore_emitter(md);
|
||||||
|
|
||||||
parse_xml(backup_file, restorer, quiet);
|
parse_xml(backup_file, restorer, quiet);
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
|
if (metadata_touched)
|
||||||
|
file_utils::zero_superblock(dev);
|
||||||
cerr << e.what() << endl;
|
cerr << e.what() << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user