Skip to content

Commit

Permalink
Copy disk database to backup upon upgrade
Browse files Browse the repository at this point in the history
This supports downgrading.
  • Loading branch information
halfgaar committed Nov 20, 2024
1 parent ac997ee commit 8116852
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 8 deletions.
5 changes: 3 additions & 2 deletions bridgeinfodb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ void BridgeInfoDb::openWrite()

void BridgeInfoDb::openRead()
{
PersistenceFile::openRead();
const std::string current_magic_string(MAGIC_STRING_BRIDGEINFO_FILE_V1);
PersistenceFile::openRead(current_magic_string);

if (detectedVersionString == MAGIC_STRING_BRIDGEINFO_FILE_V1)
if (detectedVersionString == current_magic_string)
readVersion = ReadVersion::v1;
else
throw std::runtime_error("Unknown file version.");
Expand Down
35 changes: 34 additions & 1 deletion persistencefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ See LICENSE for license details.
#include <stdio.h>
#include <cstring>
#include <libgen.h>
#include <fstream>

#include "utils.h"
#include "logger.h"
Expand Down Expand Up @@ -321,7 +322,7 @@ void PersistenceFile::openWrite(const std::string &versionString)
writeCheck(buf.data(), 1, HASH_SIZE, f);
}

void PersistenceFile::openRead()
void PersistenceFile::openRead(const std::string &expected_version_string)
{
if (openMode != FileMode::unknown)
throw std::runtime_error("File is already open.");
Expand All @@ -339,6 +340,38 @@ void PersistenceFile::openRead()
readCheck(buf.data(), 1, MAGIC_STRING_LENGH, f);
detectedVersionString = std::string(buf.data(), strlen(buf.data()));

// In case people want to downgrade, the old file is still there.
if (detectedVersionString != expected_version_string)
{
const std::string copy_file_path = filePath + "." + detectedVersionString;

try
{
const size_t file_size = getFileSize(filePath);
const size_t free_space = getFreeSpace(filePath);

if (free_space > file_size * 3)
{
logger->log(LOG_NOTICE) << "File version change detected. Copying '" << filePath << "' to '"
<< copy_file_path << "' to support downgrading FlashMQ.";
std::ifstream src(filePath, std::ios::binary);
std::ofstream dst(copy_file_path, std::ios::binary);
src.exceptions(std::ifstream::failbit | std::ifstream::badbit);
dst.exceptions(std::ifstream::failbit | std::ifstream::badbit);
dst << src.rdbuf();
}
else
{
logger->log(LOG_NOTICE) << "File version change detected, but not copying '" << filePath << "' to '"
<< copy_file_path << "' because disk space is running low.";
}
}
catch (std::exception &ex)
{
logger->log(LOG_ERROR) << "Backing up to '" << copy_file_path << "' failed.";
}
}

fseek(f, TOTAL_HEADER_SIZE, SEEK_SET);
}

Expand Down
2 changes: 1 addition & 1 deletion persistencefile.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class PersistenceFile
virtual ~PersistenceFile();

void openWrite(const std::string &versionString);
void openRead();
void openRead(const std::string &expected_version_string);
void closeFile();

const std::string &getFilePath() const;
Expand Down
6 changes: 4 additions & 2 deletions retainedmessagesdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,17 @@ void RetainedMessagesDB::openWrite()

void RetainedMessagesDB::openRead()
{
PersistenceFile::openRead();
const std::string current_magic_string(MAGIC_STRING_V4);

PersistenceFile::openRead(current_magic_string);

if (detectedVersionString == MAGIC_STRING_V1)
readVersion = ReadVersion::v1;
else if (detectedVersionString == MAGIC_STRING_V2)
readVersion = ReadVersion::v2;
else if (detectedVersionString == MAGIC_STRING_V3)
readVersion = ReadVersion::v3;
else if (detectedVersionString == MAGIC_STRING_V4)
else if (detectedVersionString == current_magic_string)
readVersion = ReadVersion::v4;
else
throw std::runtime_error("Unknown file version.");
Expand Down
6 changes: 4 additions & 2 deletions sessionsandsubscriptionsdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ void SessionsAndSubscriptionsDB::openWrite()

void SessionsAndSubscriptionsDB::openRead()
{
PersistenceFile::openRead();
const std::string current_magic_string(MAGIC_STRING_SESSION_FILE_V6);

PersistenceFile::openRead(current_magic_string);

if (detectedVersionString == MAGIC_STRING_SESSION_FILE_V1)
readVersion = ReadVersion::v1;
Expand All @@ -96,7 +98,7 @@ void SessionsAndSubscriptionsDB::openRead()
readVersion = ReadVersion::v4;
else if (detectedVersionString == MAGIC_STRING_SESSION_FILE_V5)
readVersion = ReadVersion::v5;
else if (detectedVersionString == MAGIC_STRING_SESSION_FILE_V6)
else if (detectedVersionString == current_magic_string)
readVersion = ReadVersion::v6;
else
throw std::runtime_error("Unknown file version.");
Expand Down

0 comments on commit 8116852

Please sign in to comment.