~aleteoryx/muditaos

dc2059fd8b3f5c13984a33ee80e432eebe07c3de — Wiktor S. Ovalle Correa 5 years ago c4fc4e8
[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.
M board/linux/libiosyscalls/src/syscalls_posix.cpp => board/linux/libiosyscalls/src/syscalls_posix.cpp +8 -2
@@ 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);

M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +32 -5
@@ 22,13 22,32 @@
#include <cinttypes>
#include <filesystem>

#include <purefs/filesystem_paths.hpp>
#include <sys/mount.h>
#include <sys/statvfs.h>

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<UpdateMuditaOS>(this);
    settings = std::make_unique<settings::Settings>(this);

}

ServiceDesktop::~ServiceDesktop()


@@ 38,7 57,7 @@ ServiceDesktop::~ServiceDesktop()

sys::ReturnCodes ServiceDesktop::InitHandler()
{
    desktopWorker = std::make_unique<WorkerDesktop>(this);
    desktopWorker  = std::make_unique<WorkerDesktop>(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<sdesktop::BackupMessage *>(msg);
        if (backupMessage != nullptr) {

            RemountFS();
            BackupRestore::BackupUserFiles(this);
            RemountFS(true);
        }
        return std::make_shared<sys::ResponseMessage>();
    });


@@ 71,7 91,7 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
    connect(sdesktop::RestoreMessage(), [&](sys::Message *msg) {
        sdesktop::RestoreMessage *restoreMessage = dynamic_cast<sdesktop::RestoreMessage *>(msg);
        if (restoreMessage != nullptr) {

            RemountFS();
            BackupRestore::RestoreUserFiles(this);
        }
        return std::make_shared<sys::ResponseMessage>();


@@ 81,6 101,10 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
        auto *factoryMessage = dynamic_cast<sdesktop::FactoryMessage *>(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<sys::ResponseMessage>();


@@ 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<sys::ResponseMessage>();
    });

M module-vfs/src/purefs/vfs_subsystem.cpp => module-vfs/src/purefs/vfs_subsystem.cpp +1 -1
@@ 109,7 109,7 @@ namespace purefs::subsystem
        }
        err = fs_core->register_filesystem("littlefs", std::make_shared<fs::drivers::filesystem_littlefs>());
        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 {};
        }