From dc2059fd8b3f5c13984a33ee80e432eebe07c3de Mon Sep 17 00:00:00 2001 From: "Wiktor S. Ovalle Correa" Date: Fri, 29 Jan 2021 17:35:19 +0100 Subject: [PATCH] [EGD-5522] Remount fs R/W for backup or update After setting vFAT to be read only by default backup, update and factory reset procedures need to remount R/W first. --- .../libiosyscalls/src/syscalls_posix.cpp | 10 ++++- .../service-desktop/ServiceDesktop.cpp | 37 ++++++++++++++++--- module-vfs/src/purefs/vfs_subsystem.cpp | 2 +- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/board/linux/libiosyscalls/src/syscalls_posix.cpp b/board/linux/libiosyscalls/src/syscalls_posix.cpp index 893ccbf0b47cbfe74a16c5fc5f51e0f6fa6e6e0e..525b47fbe636ce84d3e13d8115f3421ae5ada968 100644 --- a/board/linux/libiosyscalls/src/syscalls_posix.cpp +++ b/board/linux/libiosyscalls/src/syscalls_posix.cpp @@ -625,8 +625,14 @@ extern "C" const char *special_file, const char *dir, const char *fstype, unsigned long int rwflag, const void *data) { if (vfs::redirect_to_image(dir)) { - TRACE_SYSCALLN("(%s, %s, %s, %08lx, %p) -> VFS", special_file, dir, fstype, rwflag, data); - return vfs::invoke_fs(&fs::mount, special_file, dir, fstype, rwflag, data); + TRACE_SYSCALLN("(%s, %s, %s, %08lx, %p) -> VFS", + special_file ? special_file : "(null)", + dir ? dir : "(null)", + fstype ? fstype : "(null)", + rwflag, + data); + return vfs::invoke_fs( + &fs::mount, special_file ? special_file : "", dir ? dir : "", fstype ? fstype : "", rwflag, data); } else { TRACE_SYSCALLN("(%s, %s, %s, %08lx,%p) -> linux fs", special_file, dir, fstype, rwflag, data); diff --git a/module-services/service-desktop/ServiceDesktop.cpp b/module-services/service-desktop/ServiceDesktop.cpp index 2baa6939e793cd2d2597a777475e7c99ec2a26ad..3e14fb3bc421131d2d312a6cb20b1a2e77907eea 100644 --- a/module-services/service-desktop/ServiceDesktop.cpp +++ b/module-services/service-desktop/ServiceDesktop.cpp @@ -22,13 +22,32 @@ #include #include +#include +#include +#include + +namespace +{ + auto RemountFS(bool readOnly = false, std::string path = std::string(purefs::dir::getRootDiskPath())) + { + struct statvfs stat; + if (auto ret = statvfs(path.c_str(), &stat)) + return ret; + auto flags = stat.f_flag; + if (readOnly) + flags |= MS_RDONLY; + else + flags &= ~MS_RDONLY; + return mount(NULL, path.c_str(), NULL, flags | MS_REMOUNT, NULL); + } +} // namespace + ServiceDesktop::ServiceDesktop() : sys::Service(service::name::service_desktop, "", sdesktop::service_stack) { LOG_INFO("[ServiceDesktop] Initializing"); updateOS = std::make_unique(this); settings = std::make_unique(this); - } ServiceDesktop::~ServiceDesktop() @@ -38,7 +57,7 @@ ServiceDesktop::~ServiceDesktop() sys::ReturnCodes ServiceDesktop::InitHandler() { - desktopWorker = std::make_unique(this); + desktopWorker = std::make_unique(this); const bool ret = desktopWorker->init( {{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_len}, {sdesktop::SEND_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_object_size}}); @@ -62,8 +81,9 @@ sys::ReturnCodes ServiceDesktop::InitHandler() connect(sdesktop::BackupMessage(), [&](sys::Message *msg) { sdesktop::BackupMessage *backupMessage = dynamic_cast(msg); if (backupMessage != nullptr) { - + RemountFS(); BackupRestore::BackupUserFiles(this); + RemountFS(true); } return std::make_shared(); }); @@ -71,7 +91,7 @@ sys::ReturnCodes ServiceDesktop::InitHandler() connect(sdesktop::RestoreMessage(), [&](sys::Message *msg) { sdesktop::RestoreMessage *restoreMessage = dynamic_cast(msg); if (restoreMessage != nullptr) { - + RemountFS(); BackupRestore::RestoreUserFiles(this); } return std::make_shared(); @@ -81,6 +101,10 @@ sys::ReturnCodes ServiceDesktop::InitHandler() auto *factoryMessage = dynamic_cast(msg); if (factoryMessage != nullptr) { LOG_DEBUG("ServiceDesktop: FactoryMessage received"); + RemountFS(); + // Factory reset calls SystemManager::Reboot(), but + // there is no umount() in SystemManager::CloseSystemHandler() - + // this might theoretically cause filesystem corruption FactoryReset::Run(this); } return std::make_shared(); @@ -108,8 +132,11 @@ sys::ReturnCodes ServiceDesktop::InitHandler() updateOsMsg->updateStats.uuid); if (updateOS->setUpdateFile(purefs::dir::getUpdatesOSPath(), updateOsMsg->updateStats.updateFile) == - updateos::UpdateError::NoError) + updateos::UpdateError::NoError) { + RemountFS(); + // Same possible issue as with FactoryReset::Run() updateOS->runUpdate(); + } } return std::make_shared(); }); diff --git a/module-vfs/src/purefs/vfs_subsystem.cpp b/module-vfs/src/purefs/vfs_subsystem.cpp index d8eef58898906e40a7b6c8ed8ec5c5fdbc5828d6..967435fb758644081b234dcef2b5c852e6b9385b 100644 --- a/module-vfs/src/purefs/vfs_subsystem.cpp +++ b/module-vfs/src/purefs/vfs_subsystem.cpp @@ -109,7 +109,7 @@ namespace purefs::subsystem } err = fs_core->register_filesystem("littlefs", std::make_shared()); if (err) { - LOG_FATAL("Unable to register vfat filesystem with error %i", err); + LOG_FATAL("Unable to register lfs filesystem with error %i", err); return {}; }