diff --git a/src/overlaybd/tar/erofs/test/erofs_stress.cpp b/src/overlaybd/tar/erofs/test/erofs_stress.cpp index 57a6456c..114b2107 100644 --- a/src/overlaybd/tar/erofs/test/erofs_stress.cpp +++ b/src/overlaybd/tar/erofs/test/erofs_stress.cpp @@ -141,7 +141,8 @@ class StressInterImpl: public StressGenInter { mode_t mode; for (int i = 0; i < 3; i ++) { - str_mode += std::to_string(get_randomint(0, 7)); + /* ensure that the tester can read/write the file */ + str_mode += std::to_string(get_randomint(0, 7) | (i == 0 ? 6 : 0)); } mode = std::stoi(str_mode, nullptr, 8); if (file->file->fchmod(mode)) @@ -150,12 +151,12 @@ class StressInterImpl: public StressGenInter { } /* own in build phase */ - bool build_gen_own(StressNode *node, StressHostFile *file) override { + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { uid_t uid = get_randomint(own_id_min, own_id_max); gid_t gid = get_randomint(own_id_min, own_id_max); - if (file->file->fchown(uid, gid)) - LOG_ERROR_RETURN(-1,false, "failt to chown of file `", file->path); + meta->uid = uid; + meta->gid = gid; return true; } @@ -188,12 +189,12 @@ class StressInterImpl: public StressGenInter { return true; } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { uid_t uid = get_randomint(own_id_min, own_id_max); gid_t gid = get_randomint(own_id_min, own_id_max); - if (host_fs->chown(path, uid, gid)) - LOG_ERROR_RETURN(-1,false, "failt to chown of dir `", path); + meta->uid = uid; + meta->gid = gid; return true; } @@ -213,15 +214,20 @@ class StressInterImpl: public StressGenInter { return true; } - bool build_stat_file(StressNode *node, StressHostFile *file_info) override { + bool build_stat_file(StressNode *node, StressHostFile *file_info, struct in_mem_meta *meta) override { if (file_info->file->fstat(&node->node_stat)) LOG_ERRNO_RETURN(-1, false, "fail to stat file `", file_info->path); + node->node_stat.st_uid = meta->uid; + node->node_stat.st_gid = meta->gid; + return true; } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { if (host_fs->stat(path, &node->node_stat)) LOG_ERROR_RETURN(-1, false, "fail to stat dir `", path); + node->node_stat.st_uid = meta->uid; + node->node_stat.st_gid = meta->gid; return true; } @@ -246,24 +252,26 @@ class StressCase001: public StressBase, public StressInterImpl { /* create empty files in build phase*/ EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_mod(StressNode *node, StressHostFile *file), true) - EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_own(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_xattrs(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_content(StressNode *node, StressHostFile *file), true) - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); + } + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -308,26 +316,28 @@ class StressCase002: public StressBase, public StressInterImpl { /* leave mod/own/xattr empty */ EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_mod(StressNode *node, StressHostFile *file), true) - EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_own(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_xattrs(StressNode *node, StressHostFile *file), true) + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); + } bool build_gen_content(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_content(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -358,6 +368,7 @@ class StressCase002: public StressBase, public StressInterImpl { return ret; } }; + /* * TC003 * @@ -370,28 +381,31 @@ class StressCase003: public StressBase, public StressInterImpl { public: StressCase003(std::string path, int layers): StressBase(path, layers) {} + /* leave mod/own/content empty */ EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_mod(StressNode *node, StressHostFile *file), true) - EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_own(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_content(StressNode *node, StressHostFile *file), true) + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); + } bool build_gen_xattrs(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_xattrs(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -430,27 +444,29 @@ class StressCase004: public StressBase, public StressInterImpl { public: StressCase004(std::string path, int layers): StressBase(path, layers) {} - EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_own(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_xattrs(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_content(StressNode *node, StressHostFile *file), true) + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); + } bool build_gen_mod(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_mod(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file), true) @@ -491,24 +507,24 @@ class StressCase005: public StressBase, public StressInterImpl { EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_mod(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_xattrs(StressNode *node, StressHostFile *file), true) EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_content(StressNode *node, StressHostFile *file), true) - bool build_gen_own(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_gen_own(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -549,8 +565,8 @@ class StressCase006: public StressBase, public StressInterImpl { bool build_gen_mod(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_mod(node, file); } - bool build_gen_own(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_gen_own(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); } bool build_gen_xattrs(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_xattrs(node, file); @@ -558,21 +574,21 @@ class StressCase006: public StressBase, public StressInterImpl { bool build_gen_content(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_content(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -617,8 +633,8 @@ class StressCase007: public StressBase, public StressInterImpl { bool build_gen_mod(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_mod(node, file); } - bool build_gen_own(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_gen_own(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); } bool build_gen_xattrs(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_xattrs(node, file); @@ -626,21 +642,21 @@ class StressCase007: public StressBase, public StressInterImpl { bool build_gen_content(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_content(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -705,8 +721,8 @@ class StressCase008: public StressBase, public StressInterImpl { bool build_gen_mod(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_mod(node, file); } - bool build_gen_own(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_gen_own(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); } bool build_gen_xattrs(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_xattrs(node, file); @@ -714,21 +730,21 @@ class StressCase008: public StressBase, public StressInterImpl { bool build_gen_content(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_content(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -802,8 +818,8 @@ class StressCase009: public StressBase, public StressInterImpl { bool build_gen_mod(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_mod(node, file); } - bool build_gen_own(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_gen_own(node, file); + bool build_gen_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_gen_own(node, meta); } bool build_gen_xattrs(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_xattrs(node, file); @@ -811,21 +827,21 @@ class StressCase009: public StressBase, public StressInterImpl { bool build_gen_content(StressNode *node, StressHostFile *file) override { return StressInterImpl::build_gen_content(node, file); } - bool build_stat_file(StressNode *node, StressHostFile *file) override { - return StressInterImpl::build_stat_file(node, file); + bool build_stat_file(StressNode *node, StressHostFile *file, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_file(node, file, meta); } bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_mod(node, path, host_fs); } - bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_dir_own(node, path, host_fs); + bool build_dir_own(StressNode *node, struct in_mem_meta *meta) override { + return StressInterImpl::build_dir_own(node, meta); } bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { return StressInterImpl::build_dir_xattrs(node, path, host_fs); } - bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override { - return StressInterImpl::build_stat_dir(node, path, host_fs); + bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) override { + return StressInterImpl::build_stat_dir(node, path, host_fs, meta); } bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override { @@ -931,6 +947,7 @@ TEST(ErofsStressTest, TC003) { ASSERT_EQ(tc003->run(), true); delete tc003; } + TEST(ErofsStressTest, TC004) { std::srand(static_cast(std::time(0))); StressCase004 *tc004 = new StressCase004("./erofs_stress_004", 10); @@ -967,8 +984,8 @@ TEST(ErofsStressTest, TC007) { TEST(ErofsStressTest, TC008) { std::srand(static_cast(std::time(0))); - /* 100 layers */ - StressCase008 *tc008 = new StressCase008("./erofs_stress_008", 100); + /* 30 layers */ + StressCase008 *tc008 = new StressCase008("./erofs_stress_008", 30); ASSERT_EQ(tc008->run(), true); delete tc008; diff --git a/src/overlaybd/tar/erofs/test/erofs_stress_base.cpp b/src/overlaybd/tar/erofs/test/erofs_stress_base.cpp index 81fc4a86..3a7c7d52 100644 --- a/src/overlaybd/tar/erofs/test/erofs_stress_base.cpp +++ b/src/overlaybd/tar/erofs/test/erofs_stress_base.cpp @@ -153,6 +153,23 @@ static LayerNode *build_layer_tree(std::vector &dirs) { return nodes[0]; } +static bool append_tar(bool first, std::string tar_name, std::string tmp_tar, std::string prefix, std::string file_name, struct in_mem_meta *meta) +{ + std::string cmd = std::string("tar --create --file=") + (first ? tar_name : tmp_tar) + " --xattrs --xattrs-include='*'"; + if (meta) + cmd = cmd + " --owner=" + std::to_string(meta->uid) + " --group=" + std::to_string(meta->gid); + cmd = cmd + " -C " + prefix + " " + file_name; + + if (system(cmd.c_str())) + LOG_ERROR_RETURN(-1, false, "fail to create tar file for `, cmd: `", prefix + "/" + file_name, cmd); + if (!first) { + cmd = std::string("tar --concatenate --file=") + tar_name + " " + tmp_tar; + if (system(cmd.c_str())) + LOG_ERROR_RETURN(-1, false, "fail to concatenate ` to `, cmd: `", tmp_tar, tar_name, cmd); + } + return true; +} + bool StressBase::create_layer(int idx) { #define MAX_TRY_TIME 10 @@ -170,6 +187,7 @@ bool StressBase::create_layer(int idx) { std::string root_path = prefix + "/" + root_dirname; std::string clean_cmd = "rm -rf " + root_path; bool res; + std::map meta_maps; if (system(clean_cmd.c_str())) LOG_ERROR_RETURN(-1, false, "fail to prepare clean dir for `", root_path); @@ -177,19 +195,26 @@ bool StressBase::create_layer(int idx) { layer_tree->pwd = root_path; q.emplace_back(layer_tree); + std::string layer_name = origin_prefix + "/layer" + std::to_string(idx) + ".tar"; + std::string tmp_tar = origin_prefix + "/layer" + std::to_string(idx) + "_tmp.tar"; + StressNode *node = new StressNode(layer_tree->pwd.substr(prefix.length()), NODE_DIR); if (host_fs->mkdir(layer_tree->pwd.c_str(), 0755) != 0) LOG_ERROR_RETURN(-1, false, "fail to mkdir `", layer_tree->pwd); + meta_maps[layer_tree->pwd] = new struct in_mem_meta(); res = build_dir_mod(node, layer_tree->pwd.c_str(), host_fs) && - build_dir_own(node, layer_tree->pwd.c_str(), host_fs) && + build_dir_own(node, meta_maps[layer_tree->pwd]) && build_dir_xattrs(node, layer_tree->pwd.c_str(), host_fs) && - build_stat_dir(node, layer_tree->pwd.c_str(), host_fs); + build_stat_dir(node, layer_tree->pwd.c_str(), host_fs, meta_maps[layer_tree->pwd]); if (!res) LOG_ERROR_RETURN(-1, false, "fail to generate fields for dir `",layer_tree->pwd); if (!tree->add_node(node)) LOG_ERROR_RETURN(-1, false, "fail to add node `",layer_tree->pwd); + if (!append_tar(true, layer_name, tmp_tar, prefix, root_dirname, meta_maps[layer_tree->pwd])) + LOG_ERROR_RETURN(-1, false, "fail to crate tar for `", layer_tree->pwd); + // traverse the layer tree while (q.size()) { LayerNode *cur = q.front(); @@ -215,22 +240,27 @@ bool StressBase::create_layer(int idx) { LOG_ERROR_RETURN(-1, false, "fail to add WHITEOUT file `", filename); file_info->file->fsync(); delete file_info; + if (!append_tar(false, layer_name, tmp_tar, prefix, host_filename.substr(1), nullptr)) + LOG_ERROR_RETURN(-1, false, "fail to create tar for whiteout file: `", (prefix + host_filename)); } else { filename = name_prefix + "/" + filename; StressNode *node = new StressNode(filename, NODE_REGULAR); StressHostFile *file_info = new StressHostFile(prefix + filename, host_fs); + meta_maps[prefix + filename] = new struct in_mem_meta(); res = build_gen_mod(node, file_info) && - build_gen_own(node, file_info) && + build_gen_own(node, meta_maps[prefix + filename]) && build_gen_xattrs(node, file_info) && build_gen_content(node, file_info) && - build_stat_file(node, file_info); + build_stat_file(node, file_info, meta_maps[prefix + filename]); if (!res) LOG_ERROR_RETURN(-1, false, "fail to generate file contents"); if (!tree->add_node(node)) LOG_ERROR_RETURN(-1, false, "failt to add node `", filename); file_info->file->fsync(); delete file_info; + if (!append_tar(false, layer_name, tmp_tar, prefix, filename.substr(1), meta_maps[prefix + filename])) + LOG_ERROR_RETURN(-1, false, "fail to create tar for file `", (prefix + filename)); } } @@ -256,21 +286,26 @@ bool StressBase::create_layer(int idx) { LOG_ERROR_RETURN(-1, false, "fail to crate whiout dir in host fs: `", host_filename); file_info->file->fsync(); delete file_info; + if (!append_tar(false, layer_name, tmp_tar, prefix, host_filename.substr(prefix.length() + 1), nullptr)) + LOG_ERROR_RETURN(-1, false, "fail to create whitout dir for `", host_filename); break; } else { next->pwd = cur->pwd + "/" + dir_name; if (host_fs->mkdir(next->pwd.c_str(), 0755) == 0) { StressNode *dir_node = new StressNode(next->pwd.substr(prefix.length()), NODE_DIR); + meta_maps[next->pwd] = new struct in_mem_meta(); res = build_dir_mod(dir_node, next->pwd.c_str(), host_fs) && - build_dir_own(dir_node, next->pwd.c_str(), host_fs) && + build_dir_own(dir_node, meta_maps[next->pwd]) && build_dir_xattrs(dir_node, next->pwd.c_str(), host_fs) && - build_stat_dir(dir_node, next->pwd.c_str(), host_fs); + build_stat_dir(dir_node, next->pwd.c_str(), host_fs, meta_maps[next->pwd]); if (!res) LOG_ERROR_RETURN(-1, false, "fail to generate fields for dir `", next->pwd); if (!tree->add_node(dir_node)) LOG_ERROR_RETURN(-1, false, "fail to add node `", next->pwd); q.emplace_back(next); + if (!append_tar(false, layer_name, tmp_tar, prefix, next->pwd.substr(prefix.length() + 1), meta_maps[next->pwd])) + LOG_ERROR_RETURN(-1, false, "fail to create tar for dir `", next->pwd); break; } } @@ -281,10 +316,11 @@ bool StressBase::create_layer(int idx) { #undef MAX_TRY_TIME - std::string layer_name = origin_prefix + "/layer" + std::to_string(idx); - std::string cmd = std::string(" sudo tar --xattrs --xattrs-include='*' -cf ") + layer_name + ".tar -C " + prefix + " " + root_dirname; - if (system(cmd.c_str())) - LOG_ERROR_RETURN(-1, false, "fail to prepare tar file, cmd: `", cmd); + for (auto it = meta_maps.begin(); it != meta_maps.end(); ) { + delete it->second; + it = meta_maps.erase(it); + } + prefix = origin_prefix; return true; } diff --git a/src/overlaybd/tar/erofs/test/erofs_stress_base.h b/src/overlaybd/tar/erofs/test/erofs_stress_base.h index 6fb5d724..ffe1d2a7 100644 --- a/src/overlaybd/tar/erofs/test/erofs_stress_base.h +++ b/src/overlaybd/tar/erofs/test/erofs_stress_base.h @@ -136,22 +136,27 @@ class StressHostFile { } }; +struct in_mem_meta{ + uid_t uid; + gid_t gid; +}; + /* interface to generate corresponding values for in-mem nodes and host-fs files */ class StressGenInter { public: /* for a single file (node) */ /* generate content for in-memory inodes and host files (prepare layers phase) */ virtual bool build_gen_mod(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0; - virtual bool build_gen_own(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0; + virtual bool build_gen_own(StressNode *node /* out */, struct in_mem_meta *meta /* out */) = 0; virtual bool build_gen_xattrs(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0; virtual bool build_gen_content(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0; - virtual bool build_stat_file(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0; + virtual bool build_stat_file(StressNode *node /* out */, StressHostFile *file_info /* out */, struct in_mem_meta *meta) = 0; /* for a single dir (node) */ virtual bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0; - virtual bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0; + virtual bool build_dir_own(StressNode *node, struct in_mem_meta *meta) = 0; virtual bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0; - virtual bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0; + virtual bool build_stat_dir(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs, struct in_mem_meta *meta) = 0; /* generate in-mem inode according to erofs-fs file (for both files and dirs) */ virtual bool verify_gen_xattrs(StressNode *node /* out */, photon::fs::IFile *erofs_file /* in */) = 0;