Make integrity migration interrupt-safe
This commit is contained in:
parent
a19b2281f7
commit
a3a9f25e02
@ -2,11 +2,13 @@
|
||||
#include "IntegrityBlockStore2.h"
|
||||
#include "KnownBlockVersions.h"
|
||||
#include <cpp-utils/data/SerializationHelper.h>
|
||||
#include <cpp-utils/process/SignalCatcher.h>
|
||||
|
||||
using cpputils::Data;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::serialize;
|
||||
using cpputils::deserialize;
|
||||
using cpputils::SignalCatcher;
|
||||
using std::string;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
@ -195,22 +197,31 @@ void IntegrityBlockStore2::forEachBlock(std::function<void (const BlockId &)> ca
|
||||
|
||||
#ifndef CRYFS_NO_COMPATIBILITY
|
||||
void IntegrityBlockStore2::migrateFromBlockstoreWithoutVersionNumbers(BlockStore2 *baseBlockStore, const boost::filesystem::path &integrityFilePath, uint32_t myClientId) {
|
||||
SignalCatcher signalCatcher;
|
||||
|
||||
std::cout << "Migrating file system for integrity features. Please don't interrupt this process. This can take a while..." << std::flush;
|
||||
KnownBlockVersions knownBlockVersions(integrityFilePath, myClientId);
|
||||
baseBlockStore->forEachBlock([&baseBlockStore, &knownBlockVersions] (const BlockId &blockId) {
|
||||
baseBlockStore->forEachBlock([&baseBlockStore, &knownBlockVersions, &signalCatcher] (const BlockId &blockId) {
|
||||
if (signalCatcher.signal_occurred()) {
|
||||
throw std::runtime_error("Caught signal");
|
||||
}
|
||||
migrateBlockFromBlockstoreWithoutVersionNumbers(baseBlockStore, blockId, &knownBlockVersions);
|
||||
});
|
||||
std::cout << "done" << std::endl;
|
||||
}
|
||||
|
||||
void IntegrityBlockStore2::migrateBlockFromBlockstoreWithoutVersionNumbers(blockstore::BlockStore2* baseBlockStore, const blockstore::BlockId& blockId, KnownBlockVersions *knownBlockVersions) {
|
||||
uint64_t version = knownBlockVersions->incrementVersion(blockId);
|
||||
|
||||
auto data_ = baseBlockStore->load(blockId);
|
||||
if (data_ == boost::none) {
|
||||
LOG(WARN, "Block not found, but was returned from forEachBlock before");
|
||||
return;
|
||||
}
|
||||
if (0 != _readFormatHeader(*data_)) {
|
||||
// already migrated
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t version = knownBlockVersions->incrementVersion(blockId);
|
||||
cpputils::Data data = std::move(*data_);
|
||||
cpputils::Data dataWithHeader = _prependHeaderToData(blockId, knownBlockVersions->myClientId(), version, data);
|
||||
baseBlockStore->store(blockId, dataWithHeader);
|
||||
|
Loading…
Reference in New Issue
Block a user