~aleteoryx/muditaos

8545fa3bb32d0b1f364702dd604a1d840212f34e — Lucjan Bryndza 5 years ago c13eb5a
[EGD-4498] Add unit test for remount RO

Add unit test for remount filesystem in ro mode
Some minor fixes
M module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp => module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp +3 -3
@@ 341,7 341,7 @@ namespace purefs::fs::drivers
        const auto err  = invoke_lfs(zfile->mntpoint(), ::lfs_stat, path.c_str(), &linfo);
        if (!err) {
            auto vmnt = std::static_pointer_cast<mount_point_littlefs>(vfile->mntpoint());
            translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), vmnt->flags() & mount_flags::read_only, st);
            translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), vmnt->is_ro(), st);
        }
        return err;
    }


@@ 352,7 352,7 @@ namespace purefs::fs::drivers
        const auto err = invoke_lfs(mnt, file, ::lfs_stat, &linfo);
        if (!err) {
            auto mntp = std::static_pointer_cast<mount_point_littlefs>(mnt);
            translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, st);
            translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->is_ro(), st);
        }
        return err;
    }


@@ 421,7 421,7 @@ namespace purefs::fs::drivers
        int err = invoke_lfs(dirstate, ::lfs_dir_read, &linfo);
        if (err == 1) {
            auto mntp = std::static_pointer_cast<mount_point_littlefs>(dirstate->mntpoint());
            translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, filestat);
            translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->is_ro(), filestat);
            filename = linfo.name;
            err      = 0;
        }

M module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp => module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp +3 -3
@@ 342,7 342,7 @@ namespace purefs::fs::drivers
        if (fres == FR_OK) {
            const auto vmnt = vfile->mntpoint();
            if (vmnt) {
                translate_filinfo_to_stat(finfo, vfile->ff_filp(), vmnt->flags() & mount_flags::read_only, st);
                translate_filinfo_to_stat(finfo, vfile->ff_filp(), vmnt->is_ro(), st);
            }
            else {
                return -EIO;


@@ 362,7 362,7 @@ namespace purefs::fs::drivers
        const auto fspath = vmnt->native_path(file);
        const int fres    = f_stat(fspath.c_str(), &finfo);
        if (fres == FR_OK) {
            translate_filinfo_to_stat(finfo, nullptr, vmnt->flags() & mount_flags::read_only, st);
            translate_filinfo_to_stat(finfo, nullptr, vmnt->is_ro(), st);
        }
        return translate_error(fres);
    }


@@ 445,7 445,7 @@ namespace purefs::fs::drivers
            else {
                const auto vmnt = dirp->mntpoint();
                if (vmnt) {
                    translate_filinfo_to_stat(ffinfo, nullptr, vmnt->flags() & mount_flags::read_only, filestat);
                    translate_filinfo_to_stat(ffinfo, nullptr, vmnt->is_ro(), filestat);
                    filename = ffinfo.fname;
                }
                else {

M module-vfs/include/internal/purefs/fs/file_handle.hpp => module-vfs/include/internal/purefs/fs/file_handle.hpp +1 -0
@@ 13,6 13,7 @@ namespace purefs::fs::internal
    {
      public:
        file_handle(const file_handle &) = delete;
        auto operator=(const file_handle &) = delete;
        virtual ~file_handle()           = default;
        file_handle(std::shared_ptr<mount_point> mp, unsigned flags) : m_mount_point(mp), m_flags(flags)
        {}

M module-vfs/include/internal/purefs/fs/mount_point.hpp => module-vfs/include/internal/purefs/fs/mount_point.hpp +9 -2
@@ 5,6 5,7 @@
#include <memory>
#include <string>
#include <iostream>
#include <purefs/fs/mount_flags.hpp>

namespace purefs::blkdev::internal
{


@@ 28,6 29,8 @@ namespace purefs::fs::internal
                    std::shared_ptr<filesystem_operations> fs)
            : m_diskh(diskh), m_path(path), m_fs(fs), m_flags(flags)
        {}
        mount_point(const mount_point &) = delete;
        auto operator=(const mount_point &) = delete;
        virtual ~mount_point() = default;
        auto disk() const noexcept
        {


@@ 41,10 44,14 @@ namespace purefs::fs::internal
        {
            return m_fs.lock();
        }
        auto flags() const noexcept
        auto flags() const noexcept -> unsigned
        {
            return m_flags;
        }
        auto is_ro() const noexcept -> bool
        {
            return (m_flags & mount_flags::read_only) == mount_flags::read_only;
        }
        void modify_flags(unsigned flags) noexcept
        {
            m_flags = flags;


@@ 70,6 77,6 @@ namespace purefs::fs::internal
        const std::weak_ptr<blkdev::internal::disk_handle> m_diskh;
        const std::string m_path;                        //! Mounted path
        const std::weak_ptr<filesystem_operations> m_fs; //! Filesystem operation
        unsigned m_flags;
        volatile unsigned m_flags;
    };
} // namespace purefs::fs::internal

M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +2 -2
@@ 202,7 202,7 @@ namespace purefs::fs
            if (!mountp) {
                return -ENOENT;
            }
            if (acc == iaccess::rw && (mountp->flags() & mount_flags::read_only)) {
            if (acc == iaccess::rw && mountp->is_ro()) {
                return -EACCES;
            }
            auto fsops = mountp->fs_ops();


@@ 225,7 225,7 @@ namespace purefs::fs
            if (!mountp) {
                return -ENOENT;
            }
            if (mountp->flags() & mount_flags::read_only) {
            if (mountp->is_ro()) {
                return -EACCES;
            }
            if (path.compare(0, pathpos, path2, 0, pathpos) != 0) {

M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +1 -1
@@ 75,7 75,7 @@ namespace purefs::fs
            if (mpi != std::end(m_mounts)) {
                if (flags & mount_flags::remount) {
                    // NOTE: Currently only RO is supported
                    mpi->second->modify_flags(flags);
                    mpi->second->modify_flags(flags & ~mount_flags::remount);
                    return {};
                }
                else {

M module-vfs/tests/unittest_filesystem_core.cpp => module-vfs/tests/unittest_filesystem_core.cpp +73 -0
@@ 272,6 272,79 @@ TEST_CASE("Corefs: Directory operations")
    }
}

TEST_CASE("Read only filesystem")
{
    using namespace purefs;
    auto dm   = std::make_shared<blkdev::disk_manager>();
    auto disk = std::make_shared<blkdev::disk_image>(disk_image);
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);
    SECTION("Open file in O_RDWR")
    {
        int hwnd = fscore.open("/sys/rotest.txt", O_RDWR | O_CREAT, 0660);
        REQUIRE(hwnd == -EACCES);
        const std::string text = "test";
        fscore.write(hwnd, text.c_str(), text.size());
    }
    SECTION("Check function which not modify fs")
    {
        struct statvfs ssv;
        ret = fscore.stat_vfs("/sys/", ssv);
        REQUIRE(ret == 0);
    }
    SECTION("Check stat to not set S_IW...")
    {
        struct stat st;
        ret = fscore.stat("/sys/current", st);
        REQUIRE(ret == 0);
        REQUIRE(st.st_mode & S_IFDIR);
        REQUIRE((st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH)) == 0);
    }
    REQUIRE(fscore.umount("/sys") == 0);
}

TEST_CASE("Remount filesystem from RO to RW and to RO")
{
    using namespace purefs;
    auto dm   = std::make_shared<blkdev::disk_manager>();
    auto disk = std::make_shared<blkdev::disk_image>(disk_image);
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    auto fscore         = std::make_shared<purefs::fs::filesystem>(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore->register_filesystem("vfat", vfs_vfat);
    REQUIRE(ret == 0);
    REQUIRE(fscore->mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);

    {
        const int hwnd = fscore->open("/sys/remount_test.txt", O_RDWR | O_CREAT, 0660);
        REQUIRE(hwnd == -EACCES);
    }
    REQUIRE(fscore->mount("", "/sys", "", fs::mount_flags::remount) == 0);
    {
        int hwnd = fscore->open("/sys/remount_test4.txt", O_RDWR | O_CREAT, 0660);
        REQUIRE(hwnd > 2);
        const std::string text = "test";
        fscore->write(hwnd, text.c_str(), text.size());
        REQUIRE(fscore->close(hwnd) == 0);
    }
    {
        struct stat st;
        ret = fscore->stat("/sys/current", st);
        REQUIRE(ret == 0);
        REQUIRE(st.st_mode & S_IFDIR);
        REQUIRE(st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH));
    }
    REQUIRE(fscore->umount("/sys") == 0);
}

TEST_CASE("Unititest integrated subsystem")
{
    auto [disk, vfs] = purefs::subsystem::initialize();