From b8c4fafd3a7fe11986862390c230d3797ec2de8a Mon Sep 17 00:00:00 2001 From: Robin Davies Date: Sun, 1 Sep 2024 09:53:32 -0400 Subject: [PATCH] sync() after write to avoid losing file data on power off. --- CMakeLists.txt | 4 +-- NetworkManagerP2P/src/DBusLog.cpp | 3 ++- NetworkManagerP2P/src/NMP2pSettings.cpp | 5 ++-- PiPedalCommon/src/CMakeLists.txt | 1 + PiPedalCommon/src/ServiceConfiguration.cpp | 3 ++- PiPedalCommon/src/WriteTemplateFile.cpp | 3 ++- .../src/include/ConfigSerializer.hpp | 3 ++- PiPedalCommon/src/include/ofstream_synced.hpp | 26 ++++++++++++++++++ PiPedalCommon/src/ofstream_synced.cpp | 19 +++++++++++++ README.md | 4 +-- docs/Installing.md | 6 ++--- docs/download.md | 6 ++--- docs/index.md | 4 +-- src/ConfigMain.cpp | 4 +++ src/FileBrowserFilesFeature.cpp | 3 ++- src/SetWifiConfig.cpp | 6 +++++ src/Storage.cpp | 27 ++++++++++--------- src/UpdateResults.cpp | 3 ++- src/Updater.cpp | 3 ++- src/WebServer.cpp | 1 + src/WebServerConfig.cpp | 2 ++ 21 files changed, 102 insertions(+), 34 deletions(-) create mode 100644 PiPedalCommon/src/include/ofstream_synced.hpp create mode 100644 PiPedalCommon/src/ofstream_synced.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a429cc..0d9f957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.16.0) project(pipedal - VERSION 1.2.45 + VERSION 1.2.46 DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi" HOMEPAGE_URL "https://rerdavies.github.io/pipedal" ) -set (DISPLAY_VERSION "PiPedal v1.2.45-Release") +set (DISPLAY_VERSION "PiPedal v1.2.46-Development") set (PACKAGE_ARCHITECTURE "arm64") set (CMAKE_INSTALL_PREFIX "/usr/") diff --git a/NetworkManagerP2P/src/DBusLog.cpp b/NetworkManagerP2P/src/DBusLog.cpp index d3a4668..9c01c28 100644 --- a/NetworkManagerP2P/src/DBusLog.cpp +++ b/NetworkManagerP2P/src/DBusLog.cpp @@ -6,6 +6,7 @@ #include #include "ss.hpp" #include +#include "ofstream_synced.hpp" namespace impl { @@ -72,7 +73,7 @@ public: f << "trace: " << message << std::endl; } private: - std::ofstream f; + pipedal::ofstream_synced f; }; class SystemdDBusLogger : public IDBusLogger { diff --git a/NetworkManagerP2P/src/NMP2pSettings.cpp b/NetworkManagerP2P/src/NMP2pSettings.cpp index 21b9917..9caf9a6 100644 --- a/NetworkManagerP2P/src/NMP2pSettings.cpp +++ b/NetworkManagerP2P/src/NMP2pSettings.cpp @@ -10,6 +10,7 @@ #include "ChannelInfo.hpp" #include "DBusLog.hpp" #include +#include "ofstream_synced.hpp" using namespace pipedal; P2pSettings::P2pSettings(const std::filesystem::path&configDirectoryPath, const std::filesystem::path&varDirectoryPath) @@ -193,7 +194,7 @@ void P2pSettings::Load() } static void openWithPerms( - std::ofstream &f, + pipedal::ofstream_synced &f, const std::filesystem::path &path, std::filesystem::perms perms = std::filesystem::perms::owner_read | std::filesystem::perms::owner_write | @@ -221,7 +222,7 @@ void P2pSettings::Save() { auto filename = config_filename(); try { - std::ofstream f; + pipedal::ofstream_synced f; openWithPerms(f,filename); if (!f.is_open()) diff --git a/PiPedalCommon/src/CMakeLists.txt b/PiPedalCommon/src/CMakeLists.txt index b6d34e6..295a63e 100644 --- a/PiPedalCommon/src/CMakeLists.txt +++ b/PiPedalCommon/src/CMakeLists.txt @@ -41,6 +41,7 @@ message(STATUS "NMPIPEDAL CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") # Use the sdbus-c++ target in SDBusCpp namespace add_library(PiPedalCommon STATIC + ofstream_synced.cpp include/ofstream_synced.hpp ConfigSerializer.cpp include/ConfigSerializer.hpp WifiRegs.cpp include/WifiRegs.hpp WifiRegulations.cpp include/WifiRegulations.hpp diff --git a/PiPedalCommon/src/ServiceConfiguration.cpp b/PiPedalCommon/src/ServiceConfiguration.cpp index 7afb2ce..eab9617 100644 --- a/PiPedalCommon/src/ServiceConfiguration.cpp +++ b/PiPedalCommon/src/ServiceConfiguration.cpp @@ -30,6 +30,7 @@ #include #include #include +#include "ofstream_synced.hpp" using namespace pipedal; @@ -65,7 +66,7 @@ void ServiceConfiguration::Save() std::filesystem::create_directories(directory); // make sure the file has correct permissions. - std::ofstream t; + pipedal::ofstream_synced t; t.open(filename); t.close(); diff --git a/PiPedalCommon/src/WriteTemplateFile.cpp b/PiPedalCommon/src/WriteTemplateFile.cpp index 84720e0..102e675 100644 --- a/PiPedalCommon/src/WriteTemplateFile.cpp +++ b/PiPedalCommon/src/WriteTemplateFile.cpp @@ -21,6 +21,7 @@ #include "WriteTemplateFile.hpp" #include #include +#include "ofstream_synced.hpp" using namespace pipedal; @@ -37,7 +38,7 @@ void pipedal::WriteTemplateFile( const std::filesystem::path &inputFile, const std::filesystem::path &outputFile) { - std::ofstream out(outputFile); + pipedal::ofstream_synced out(outputFile); std::ifstream in(inputFile); if (!in.is_open()) diff --git a/PiPedalCommon/src/include/ConfigSerializer.hpp b/PiPedalCommon/src/include/ConfigSerializer.hpp index 0cd5dfa..1bd2f6e 100644 --- a/PiPedalCommon/src/include/ConfigSerializer.hpp +++ b/PiPedalCommon/src/include/ConfigSerializer.hpp @@ -30,6 +30,7 @@ #include "autoptr_vector.h" #include #include +#include "ofstream_synced.hpp" namespace config_serializer { @@ -256,7 +257,7 @@ namespace config_serializer } void Save(const std::string &path) { - std::ofstream f; + pipedal::ofstream_synced f; f.open(path); if (!f.is_open()) { diff --git a/PiPedalCommon/src/include/ofstream_synced.hpp b/PiPedalCommon/src/include/ofstream_synced.hpp new file mode 100644 index 0000000..b04af94 --- /dev/null +++ b/PiPedalCommon/src/include/ofstream_synced.hpp @@ -0,0 +1,26 @@ + +#pragma once + +#include + +namespace pipedal +{ + void FileSystemSync(); + + class ofstream_synced : public std::ofstream + { + public: + ofstream_synced() {} + + explicit ofstream_synced(const std::string &filename, ios_base::openmode mode = ios_base::out) + : std::ofstream(filename, mode) + { + } + explicit ofstream_synced(const char *filename, ios_base::openmode mode = ios_base::out) + : std::ofstream(filename, mode) + { + } + ~ofstream_synced(); + }; + +} \ No newline at end of file diff --git a/PiPedalCommon/src/ofstream_synced.cpp b/PiPedalCommon/src/ofstream_synced.cpp new file mode 100644 index 0000000..8d305d2 --- /dev/null +++ b/PiPedalCommon/src/ofstream_synced.cpp @@ -0,0 +1,19 @@ +#include "ofstream_synced.hpp" +#include "unistd.h" + +using namespace pipedal; + + +void pipedal::FileSystemSync() +{ + ::sync(); +} + +ofstream_synced::~ofstream_synced() +{ + if (is_open()) + { + close(); + ::sync(); + } +} \ No newline at end of file diff --git a/README.md b/README.md index 1639f4d..33d311c 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ -Download: v1.2.45 +Download: v1.2.46 Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal). Documentation: [https://rerdavies.github.io/pipedal/Documentation.html](https://rerdavies.github.io/pipedal/Documentation.html).   -#### NEW version 1.2.45 Release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. +#### NEW version 1.2.46 Release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.   diff --git a/docs/Installing.md b/docs/Installing.md index 32a2bde..5343212 100644 --- a/docs/Installing.md +++ b/docs/Installing.md @@ -13,17 +13,17 @@ page_icon: img/Install4.jpg Download the most recent Debian (.deb) package for your platform: -- [Raspberry Pi OS bookworm (64-bit) v1.2.45](https://github.com/rerdavies/pipedal/releases/download/) +- [Raspberry Pi OS bookworm (64-bit) v1.2.46](https://github.com/rerdavies/pipedal/releases/download/) - [Ubuntu/Raspberry Pi OS bullseyeye (64-bit) v1.2.31](https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb) -Version 1.2.45 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31. +Version 1.2.46 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31. Install the package by running ``` sudo apt update cd ~/Downloads - sudo apt-get install pipedal_1.2.45_arm64.deb + sudo apt-get install pipedal_1.2.46_arm64.deb ``` Adjust accordingly if you have downloaded v1.1.31. diff --git a/docs/download.md b/docs/download.md index 16ce4ed..b4f3d22 100644 --- a/docs/download.md +++ b/docs/download.md @@ -4,17 +4,17 @@ Download the most recent Debian (.deb) package for your platform: -- Raspberry Pi OS Bookworm (64-bit) v1.2.45 +- Raspberry Pi OS Bookworm (64-bit) v1.2.46 - Ubuntu 21.04 or Raspberry Pi OS bullseyeyeye (64-bit) v1.1.31 -v1.2.45 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS. +v1.2.46 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS. Install the package by running ``` sudo apt update cd ~/Downloads - sudo apt-get install ./pipedal_1.2.45_arm64.deb + sudo apt-get install ./pipedal_1.2.46_arm64.deb ``` Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation. diff --git a/docs/index.md b/docs/index.md index 7660af7..5949ead 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ -v1.2.45 +v1.2.46   @@ -9,7 +9,7 @@ To download PiPedal, click [here](download.md). To view PiPedal documentation, click [here](Documentation.md). -#### NEW version 1.2.45 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details. +#### NEW version 1.2.46 Release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.   diff --git a/src/ConfigMain.cpp b/src/ConfigMain.cpp index 6789ed3..d330149 100644 --- a/src/ConfigMain.cpp +++ b/src/ConfigMain.cpp @@ -40,6 +40,8 @@ #include "WifiChannelSelectors.hpp" #include "PiPedalConfiguration.hpp" #include +#include "ofstream_synced.hpp" + #if JACK_HOST #define INSTALL_JACK_SERVICE 1 @@ -1346,10 +1348,12 @@ int main(int argc, char **argv) portOption = "0.0.0.0:" + portOption; } Install(prefix, portOption); + FileSystemSync(); } else if (uninstall) { Uninstall(); + FileSystemSync(); } else if (stop) { diff --git a/src/FileBrowserFilesFeature.cpp b/src/FileBrowserFilesFeature.cpp index 9894c5a..3207688 100644 --- a/src/FileBrowserFilesFeature.cpp +++ b/src/FileBrowserFilesFeature.cpp @@ -29,6 +29,7 @@ #include #include #include "util.hpp" +#include "ofstream_synced.hpp" using namespace pipedal; using namespace pipedal::implementation; @@ -101,7 +102,7 @@ FileBrowserFilesFeature::FileBrowserFilesFeature() } void BrowserFilesVersionInfo::Save(std::filesystem::path &path) { - std::ofstream f{path}; + pipedal::ofstream_synced f{path}; if (!f.is_open()) return; f << version << std::endl; diff --git a/src/SetWifiConfig.cpp b/src/SetWifiConfig.cpp index 13b0f0a..04f1d62 100644 --- a/src/SetWifiConfig.cpp +++ b/src/SetWifiConfig.cpp @@ -26,6 +26,7 @@ #include "SystemConfigFile.hpp" #include "SysExec.hpp" #include "WriteTemplateFile.hpp" +#include using namespace pipedal; using namespace std; @@ -473,6 +474,7 @@ void pipedal::SetWifiConfig(const WifiConfigSettings &settings) sysExec(SYSTEMCTL_BIN " restart dnsmasq"); sysExec(SYSTEMCTL_BIN " enable dnsmasq"); } + ::sync(); } /********************************************************************************* @@ -563,6 +565,7 @@ void UninstallP2p() SetWifiDirectConfig(wifiDirectConfigSettings); } + ::sync(); } static void RemoveDhcpcdConfig() @@ -679,6 +682,7 @@ void pipedal::SetWifiDirectConfig(const WifiDirectConfigSettings &settings) { cout << e.what() << endl; } + ::sync(); } void pipedal::OnWifiReinstall() { WifiDirectConfigSettings settings; @@ -686,6 +690,7 @@ void pipedal::OnWifiReinstall() { if (settings.enable_) { SetWifiDirectConfig(settings); + ::sync(); } } void pipedal::OnWifiUninstall(bool preserveState) @@ -707,6 +712,7 @@ void pipedal::OnWifiUninstall(bool preserveState) settings.Save(); } } + ::sync(); } void pipedal::OnWifiInstallComplete() { diff --git a/src/Storage.cpp b/src/Storage.cpp index d593afb..9f47749 100644 --- a/src/Storage.cpp +++ b/src/Storage.cpp @@ -31,6 +31,7 @@ #include "PiPedalUI.hpp" #include "PluginHost.hpp" #include "ss.hpp" +#include "ofstream_synced.hpp" using namespace pipedal; @@ -344,7 +345,7 @@ void Storage::SavePluginPresetIndex() if (pluginPresetIndexChanged) { pluginPresetIndexChanged = false; - std::ofstream os; + pipedal::ofstream_synced os; auto path = GetPluginPresetsDirectory() / "index.json"; os.open(path, std::ios_base::trunc); if (os.fail()) @@ -359,7 +360,7 @@ void Storage::SavePluginPresetIndex() void Storage::SaveBankIndex() { - std::ofstream os; + pipedal::ofstream_synced os; os.open(GetIndexFileName(), std::ios_base::trunc); json_writer writer(os, false); writer.write(this->bankIndex); @@ -434,7 +435,7 @@ void Storage::SaveBankFile(const std::string &name, const BankFile &bankFile) } try { - std::ofstream s; + pipedal::ofstream_synced s; s.open(fileName, std::ios_base::trunc); json_writer writer(s, false); writer.write(bankFile); @@ -721,7 +722,7 @@ void Storage::SaveChannelSelection() auto fileName = this->GetChannelSelectionFileName(); try { - std::ofstream s(fileName); + pipedal::ofstream_synced s(fileName); json_writer writer(s, false); writer.write(this->jackChannelSelection); } @@ -906,7 +907,7 @@ int64_t Storage::UploadBank(BankFile &bankFile, int64_t uploadAfter) bankFile.name(s.str()); } std::filesystem::path path = this->GetBankFileName(bankFile.name()); - std::ofstream f(path); + pipedal::ofstream_synced f(path); if (!f.is_open()) { throw PiPedalException("Can't write to bank file."); @@ -928,7 +929,7 @@ void Storage::SaveUserSettings() { std::filesystem::path path = this->dataRoot / USER_SETTINGS_FILENAME; { - std::ofstream f(path); + pipedal::ofstream_synced f(path); if (!f.is_open()) { throw PiPedalException("Unable to write to " + ((std::string)path)); @@ -964,7 +965,7 @@ void Storage::SetWifiConfigSettings(const WifiConfigSettings &wifiConfigSettings std::filesystem::path path = this->dataRoot / WIFI_CONFIG_SETTINGS_FILENAME; { - std::ofstream f(path); + pipedal::ofstream_synced f(path); if (!f.is_open()) { throw PiPedalException("Unable to write to " + ((std::string)path)); @@ -1077,7 +1078,7 @@ void Storage::SaveCurrentPreset(const CurrentPreset ¤tPreset) { std::filesystem::path path = GetCurrentPresetPath(); - std::ofstream f(path); + pipedal::ofstream_synced f(path); json_writer writer(f, false); writer.write(currentPreset); } @@ -1152,7 +1153,7 @@ void Storage::SavePluginPresets(const std::string &pluginUri, const PluginPreset } auto tempPath = path.string() + ".$$$"; { - std::ofstream os; + pipedal::ofstream_synced os; os.open(tempPath, std::ios_base::trunc); if (os.fail()) { @@ -1396,7 +1397,7 @@ std::map Storage::GetFavorites() const void Storage::SetFavorites(const std::map &favorites) { std::filesystem::path fileName = this->dataRoot / "favorites.json"; - std::ofstream f; + pipedal::ofstream_synced f; f.open(fileName); if (f.is_open()) { @@ -1425,7 +1426,7 @@ pipedal::JackServerSettings Storage::GetJackServerSettings() void Storage::SetJackServerSettings(const pipedal::JackServerSettings &jackConfiguration) { std::filesystem::path fileName = this->dataRoot / "AudioConfig.json"; - std::ofstream f; + pipedal::ofstream_synced f; f.open(fileName); if (f.is_open()) { @@ -1440,7 +1441,7 @@ void Storage::SetJackServerSettings(const pipedal::JackServerSettings &jackConfi void Storage::SetSystemMidiBindings(const std::vector &bindings) { std::filesystem::path fileName = this->dataRoot / "SystemMidiBindings.json"; - std::ofstream f; + pipedal::ofstream_synced f; f.open(fileName); if (f.is_open()) { @@ -1714,7 +1715,7 @@ std::string Storage::UploadUserFile(const std::string &directory, const std::str try { std::filesystem::create_directories(path.parent_path()); - std::ofstream f(path, std::ios_base::trunc | std::ios_base::binary); + pipedal::ofstream_synced f(path, std::ios_base::trunc | std::ios_base::binary); if (!f.is_open()) { throw std::logic_error(SS("Can't create file " << path << ".")); diff --git a/src/UpdateResults.cpp b/src/UpdateResults.cpp index 1bc8b6a..e5ed66d 100644 --- a/src/UpdateResults.cpp +++ b/src/UpdateResults.cpp @@ -22,6 +22,7 @@ #include #include "Lv2Log.hpp" #include "ss.hpp" +#include "ofstream_synced.hpp" @@ -40,7 +41,7 @@ void UpdateResults::Load() } void UpdateResults::Save() { - std::ofstream f {UPDATE_RESULT_PATH}; + pipedal::ofstream_synced f {UPDATE_RESULT_PATH}; if (f.is_open()) { json_writer writer(f); diff --git a/src/Updater.cpp b/src/Updater.cpp index e5b35a0..8c612cc 100644 --- a/src/Updater.cpp +++ b/src/Updater.cpp @@ -34,6 +34,7 @@ #include #include "UpdaterSecurity.hpp" #include "SysExec.hpp" +#include "ofstream_synced.hpp" using namespace pipedal; namespace fs = std::filesystem; @@ -88,7 +89,7 @@ static void SetCachedUpdateStatus(UpdateStatus &updateStatus) updateStatus.LastUpdateTime(std::chrono::system_clock::now()); try { - std::ofstream f{UPDATE_STATUS_CACHE_FILE}; + pipedal::ofstream_synced f{UPDATE_STATUS_CACHE_FILE}; json_writer writer{f}; writer.write(updateStatus); } diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 781d726..551d39d 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -36,6 +36,7 @@ #include #include "Ipv6Helpers.hpp" #include "util.hpp" +#include "ofstream_synced.hpp" #include "WebServer.hpp" diff --git a/src/WebServerConfig.cpp b/src/WebServerConfig.cpp index ed08964..f88a4e1 100644 --- a/src/WebServerConfig.cpp +++ b/src/WebServerConfig.cpp @@ -28,6 +28,7 @@ #include #include "ZipFile.hpp" #include "PiPedalUI.hpp" +#include "ofstream_synced.hpp" #define PRESET_EXTENSION ".piPreset" @@ -439,6 +440,7 @@ public: Lv2Log::error(SS("Unzip failed. " << e.what())); throw; } + FileSystemSync(); } else { outputFileName = this->model->UploadUserFile(directory,patchProperty,filename,req.get_body_input_stream(), req.content_length());