From 222b86bfbd5c48c26aee41a70b5adb2104ec65b6 Mon Sep 17 00:00:00 2001 From: zhuruigan Date: Mon, 5 Feb 2024 16:18:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6=E5=88=86?= =?UTF-8?q?=E6=9E=90=E8=BF=94=E5=9B=9E=E7=B1=BB=E5=9E=8B=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=AE=80=E6=8A=A5=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhuruigan Change-Id: If595a481d7bc32fbc8dbd2853232bd79d696a494 --- .../native/backup_ext/include/untar_file.h | 4 +- .../native/backup_ext/src/ext_extension.cpp | 68 ++--- frameworks/native/backup_ext/src/tar_file.cpp | 2 + .../native/backup_ext/src/untar_file.cpp | 2 +- .../b_json/b_json_entity_ext_manage_test.cpp | 250 ------------------ .../b_json/b_report_entity_test.cpp | 2 +- .../include/b_json/b_json_entity_ext_manage.h | 18 -- utils/include/b_json/b_report_entity.h | 3 +- utils/src/b_json/b_json_entity_ext_manage.cpp | 133 ++-------- utils/src/b_json/b_report_entity.cpp | 6 +- 10 files changed, 61 insertions(+), 427 deletions(-) diff --git a/frameworks/native/backup_ext/include/untar_file.h b/frameworks/native/backup_ext/include/untar_file.h index 6bd0e4200..c2a28dc2d 100644 --- a/frameworks/native/backup_ext/include/untar_file.h +++ b/frameworks/native/backup_ext/include/untar_file.h @@ -34,7 +34,7 @@ public: static UntarFile &GetInstance(); int UnPacket(const std::string &tarFile, const std::string &rootPath); int IncrementalUnPacket(const std::string &tarFile, const std::string &rootPath, - const std::map &includes); + const std::unordered_map &includes); private: UntarFile() = default; @@ -147,7 +147,7 @@ private: off_t tarFileBlockCnt_ {0}; off_t pos_ {0}; size_t readCnt_ {0}; - std::map includes_; + std::unordered_map includes_; }; } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index 3c29b896c..8f81a35c1 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -23,8 +23,10 @@ #include #include #include +#include #include +#include #include #include @@ -47,8 +49,8 @@ #include "b_resources/b_constants.h" #include "b_tarball/b_tarball_factory.h" #include "filemgmt_libhilog.h" -#include "service_proxy.h" #include "hitrace_meter.h" +#include "service_proxy.h" #include "tar_file.h" #include "untar_file.h" @@ -84,7 +86,7 @@ void BackupExtExtension::VerifyCaller() } } -static bool CheckAndCreateDirectory(const string& filePath) +static bool CheckAndCreateDirectory(const string &filePath) { size_t pos = filePath.rfind('/'); if (pos == string::npos) { @@ -184,7 +186,7 @@ ErrCode BackupExtExtension::GetIncrementalFileHandle(const string &fileName) if (access(tarName.c_str(), F_OK) == 0) { throw BError(BError::Codes::EXT_INVAL_ARG, string("The file already exists")); } - UniqueFd fd (open(tarName.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); + UniqueFd fd(open(tarName.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); if (fd < 0) { HILOGE("Failed to open tar file = %{private}s, err = %{public}d", tarName.c_str(), errno); throw BError(BError::Codes::EXT_INVAL_ARG, string("open tar file failed")); @@ -195,7 +197,7 @@ ErrCode BackupExtExtension::GetIncrementalFileHandle(const string &fileName) if (access(reportName.c_str(), F_OK) == 0) { throw BError(BError::Codes::EXT_INVAL_ARG, string("The report file already exists")); } - UniqueFd reportFd (open(reportName.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); + UniqueFd reportFd(open(reportName.data(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)); if (reportFd < 0) { HILOGE("Failed to open report file = %{private}s, err = %{public}d", reportName.c_str(), errno); throw BError(BError::Codes::EXT_INVAL_ARG, string("open report file failed")); @@ -431,8 +433,7 @@ static bool IsUserTar(const string &tarFile, const string &indexFile) BJsonCachedEntity cachedEntity(UniqueFd(open(filePath.data(), O_RDONLY))); auto cache = cachedEntity.Structuralize(); auto info = cache.GetExtManageInfo(); - auto iter = find_if(info.begin(), info.end(), - [&tarFile](const auto& item) { return item.hashName == tarFile; }); + auto iter = find_if(info.begin(), info.end(), [&tarFile](const auto &item) { return item.hashName == tarFile; }); if (iter != info.end()) { HILOGI("tarFile:%{public}s isUserTar:%{public}d", tarFile.data(), iter->isUserTar); return iter->isUserTar; @@ -543,7 +544,7 @@ int BackupExtExtension::DoRestore(const string &fileName) return ERR_OK; } -static map GetTarIncludes(const string &tarName) +static unordered_map GetTarIncludes(const string &tarName) { // 获取简报文件内容 string reportName = GetReportFileName(tarName); @@ -617,7 +618,7 @@ void BackupExtExtension::AsyncTaskBackup(const string config) static void RestoreBigFilesForSpecialCloneCloud(ExtManageInfo item) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - struct stat& sta = item.sta; + struct stat &sta = item.sta; string fileName = item.hashName; if (chmod(fileName.c_str(), sta.st_mode) != 0) { HILOGE("Failed to chmod filePath, err = %{public}d", errno); @@ -681,8 +682,7 @@ static ErrCode RestoreFilesForSpecialCloneCloud() return ERR_OK; } -static bool RestoreBigFilePrecheck(string& fileName, const string& path, - const string& hashName, const string& filePath) +static bool RestoreBigFilePrecheck(string &fileName, const string &path, const string &hashName, const string &filePath) { if (filePath.empty()) { HILOGE("file path is empty. %{public}s", filePath.c_str()); @@ -703,8 +703,9 @@ static bool RestoreBigFilePrecheck(string& fileName, const string& path, return true; } -static void RestoreBigFileAfter(const string& fileName, const string& filePath, const struct stat& sta, - const set& lks) +static void RestoreBigFileAfter(const string &fileName, + const string &filePath, + const struct stat &sta) { if (chmod(filePath.c_str(), sta.st_mode) != 0) { HILOGE("Failed to chmod filePath, err = %{public}d", errno); @@ -729,12 +730,6 @@ static void RestoreBigFileAfter(const string& fileName, const string& filePath, } } - for (const auto &lksPath : lks) { - if (link(filePath.data(), lksPath.data())) { - HILOGE("failed to create hard link file, errno : %{public}d", errno); - } - } - struct timespec tv[2] = {sta.st_atim, sta.st_mtim}; UniqueFd fd(open(filePath.data(), O_RDONLY)); if (futimens(fd.Get(), tv) != 0) { @@ -768,7 +763,7 @@ static void RestoreBigFiles(bool appendTargetPath) continue; } - RestoreBigFileAfter(fileName, filePath, item.sta, cache.GetHardLinkInfo(item.hashName)); + RestoreBigFileAfter(fileName, filePath, item.sta); } } @@ -849,8 +844,8 @@ void BackupExtExtension::AsyncTaskRestore() } // 恢复用户tar包以及大文件 // 目的地址是否需要拼接path(临时目录),FullBackupOnly为true并且非特殊场景 - bool appendTargetPath = ptr->extension_->UseFullBackupOnly() && - !ptr->extension_->SpeicalVersionForCloneAndCloud(); + bool appendTargetPath = + ptr->extension_->UseFullBackupOnly() && !ptr->extension_->SpeicalVersionForCloneAndCloud(); RestoreBigFiles(appendTargetPath); // delete 1.tar/manage.json @@ -904,8 +899,8 @@ void BackupExtExtension::AsyncTaskIncrementalRestore() } // 恢复用户tar包以及大文件 // 目的地址是否需要拼接path(临时目录),FullBackupOnly为true并且非特殊场景 - bool appendTargetPath = ptr->extension_->UseFullBackupOnly() && - !ptr->extension_->SpeicalVersionForCloneAndCloud(); + bool appendTargetPath = + ptr->extension_->UseFullBackupOnly() && !ptr->extension_->SpeicalVersionForCloneAndCloud(); RestoreBigFiles(appendTargetPath); // delete 1.tar/manage.json @@ -1137,6 +1132,11 @@ ErrCode BackupExtExtension::HandleRestore() return 0; } +static bool CheckTar(const string &fileName) +{ + return ExtractFileExt(fileName) == "tar"; +} + using CompareFilesResult = tuple, map, map, @@ -1145,9 +1145,9 @@ using CompareFilesResult = tuple, static CompareFilesResult CompareFiles(const UniqueFd &cloudFd, const UniqueFd &storageFd) { BReportEntity cloudRp(UniqueFd(cloudFd.Get())); - map cloudFiles = cloudRp.GetReportInfos(); + unordered_map cloudFiles = cloudRp.GetReportInfos(); BReportEntity storageRp(UniqueFd(storageFd.Get())); - map storageFiles = storageRp.GetReportInfos(); + unordered_map storageFiles = storageRp.GetReportInfos(); map allFiles; map smallFiles; map bigFiles; @@ -1155,7 +1155,8 @@ static CompareFilesResult CompareFiles(const UniqueFd &cloudFd, const UniqueFd & for (auto &item : storageFiles) { // 进行文件对比 string path = item.first; - if (item.second.isIncremental == true && item.second.isDir == true) { + bool isExist = cloudFiles.find(path) != cloudFiles.end() ? true : false; + if (item.second.isIncremental == true && item.second.isDir == true && !isExist) { smallFiles.try_emplace(path, item.second); } if (item.second.isIncremental == true && item.second.isDir == false) { @@ -1165,13 +1166,14 @@ static CompareFilesResult CompareFiles(const UniqueFd &cloudFd, const UniqueFd & } item.second.hash = fileHash; item.second.isIncremental = true; - } else { - item.second.hash = (cloudFiles.find(path) == cloudFiles.end()) ? cloudFiles[path].hash : ""; + } + + if (item.second.isDir == false && CheckTar(path)) { + item.second.userTar = 1; } allFiles.try_emplace(path, item.second); - if (cloudFiles.find(path) == cloudFiles.end() || - (item.second.isDir == false && item.second.isIncremental == true && + if (!isExist || (item.second.isDir == false && item.second.isIncremental == true && cloudFiles.find(path)->second.hash != item.second.hash)) { // 在云空间简报里不存在或者hash不一致 if (item.second.size < BConstants::BIG_FILE_BOUNDARY) { @@ -1216,12 +1218,12 @@ static void WriteFile(const string &filename, const map= DEFAULT_SLICE_SIZE) { + HILOGI("Current tar file size is over %{public}d, start to slice", + static_cast(DEFAULT_SLICE_SIZE / MB_TO_BYTE)); fileCount_ = 0; FillSplitTailBlocks(); CreateSplitTarFile(); diff --git a/frameworks/native/backup_ext/src/untar_file.cpp b/frameworks/native/backup_ext/src/untar_file.cpp index ebff9a541..1beb90bb9 100644 --- a/frameworks/native/backup_ext/src/untar_file.cpp +++ b/frameworks/native/backup_ext/src/untar_file.cpp @@ -95,7 +95,7 @@ int UntarFile::UnPacket(const string &tarFile, const string &rootPath) } int UntarFile::IncrementalUnPacket(const string &tarFile, const string &rootPath, - const map &includes) + const unordered_map &includes) { includes_ = includes; tarFilePtr_ = fopen(tarFile.c_str(), "rb"); diff --git a/tests/unittests/backup_utils/b_json/b_json_entity_ext_manage_test.cpp b/tests/unittests/backup_utils/b_json/b_json_entity_ext_manage_test.cpp index eae013cf3..e6be909ad 100644 --- a/tests/unittests/backup_utils/b_json/b_json_entity_ext_manage_test.cpp +++ b/tests/unittests/backup_utils/b_json/b_json_entity_ext_manage_test.cpp @@ -279,7 +279,6 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0300, testing::ext:: * 0:通过向索引文件写入3条有效数据模拟覆盖对索引文件的(无穷)内容的测试覆盖 * 0:通过向索引文件的记录一写入0条、记录二写入1条、记录三写入2条有效硬链接数据模拟对索引文件含 * 有硬链接(空、有、无穷)个的测试覆盖 - * 0:通过调用接口SetHardLinkInfo向索引文件中对应记录添加硬链接 * 1:调用接口SetExtManage,向索引文件写入数据 * 2:调用接口GetExtManage,从索引文件读出文件名数据 * 3:调用接口GetExtManageInfo,从索引文件读出文件详细数据(含文件名和对应文件的stat数据) @@ -319,15 +318,6 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0400, testing::ext:: info.emplace(testFile3HexName, make_tuple(pathTestFile3, GetFileStat(pathTestFile3), true)); cache.SetExtManage(info); - // 向索引文件中的三条记录分别追加0、1、2条硬链接信息 - set hardLinks1, hardLinks2, hardLinks3; - cache.SetHardLinkInfo(testFile1HexName, hardLinks1); - hardLinks2.emplace(root + "testFile2hardlink1"); - cache.SetHardLinkInfo(testFile2HexName, hardLinks2); - hardLinks3.emplace(root + "testFile3hardlink1"); - hardLinks3.emplace(root + "testFile3hardlink2"); - cache.SetHardLinkInfo(testFile3HexName, hardLinks3); - // 预置结果集,用以在读取索引文件后做结果判断 set resultFileName {testFile1HexName, testFile2HexName, testFile3HexName}; @@ -338,15 +328,6 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0400, testing::ext:: auto fileInfo = cache.GetExtManageInfo(); EXPECT_EQ(fileInfo.size(), info.size()); EXPECT_TRUE(IsEqual(fileInfo, info)); - // 传入无效文件名"00000000",测试读取文件硬链接接口是否正确返回 - auto testFile0HardLinks = cache.GetHardLinkInfo("00000000"); - EXPECT_TRUE(testFile0HardLinks.empty()); - auto testFile1HardLinks = cache.GetHardLinkInfo(testFile1HexName); - EXPECT_TRUE(testFile1HardLinks.empty()); - auto testFile2HardLinks = cache.GetHardLinkInfo(testFile2HexName); - EXPECT_EQ(testFile2HardLinks, hardLinks2); - auto testFile3HardLinks = cache.GetHardLinkInfo(testFile3HexName); - EXPECT_EQ(testFile3HardLinks, hardLinks3); } catch (...) { EXPECT_TRUE(false); GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; @@ -394,24 +375,14 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0500, testing::ext:: auto cache = cachedEntity.Structuralize(); // 生成三条有用数据并写入索引文件 - // 通过重用原始文件的stat向该记录追加(0/1/2)条硬链接文件信息 map> info; struct stat sta = {}; info.emplace(testFile1HexName, make_tuple(pathTestFile1, GetFileStat(pathTestFile1), true)); info.emplace(testFile2HexName, make_tuple(pathTestFile2, sta = GetFileStat(pathTestFile2), true)); - info.emplace("testFile2hardlink1", make_tuple(root + "testFile2hardlink1", sta, true)); info.emplace(testFile3HexName, make_tuple(pathTestFile3, sta = GetFileStat(pathTestFile3), true)); - info.emplace("testFile3hardlink1", make_tuple(root + "testFile3hardlink1", sta, true)); - info.emplace("testFile3hardlink2", make_tuple(root + "testFile3hardlink2", sta, true)); cache.SetExtManage(info); // 预置结果集,用以在读取索引文件后做结果判断 - // 将info中的硬链接信息删除,保留原始文件信息,作为后续结果值判断的比较对象 - info.erase("testFile2hardlink1"); - info.erase("testFile3hardlink1"); - info.erase("testFile3hardlink2"); - set hardLinks2 {root + "testFile2hardlink1"}; - set hardLinks3 {root + "testFile3hardlink1", root + "testFile3hardlink2"}; set resultFileName {testFile1HexName, testFile2HexName, testFile3HexName}; // 读取索引文件内容并做结果判断 @@ -421,12 +392,6 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0500, testing::ext:: auto fileInfo = cache.GetExtManageInfo(); EXPECT_EQ(fileInfo.size(), info.size()); EXPECT_TRUE(IsEqual(fileInfo, info)); - auto testFile1HardLinks = cache.GetHardLinkInfo(testFile1HexName); - EXPECT_TRUE(testFile1HardLinks.empty()); - auto testFile2HardLinks = cache.GetHardLinkInfo(testFile2HexName); - EXPECT_EQ(testFile2HardLinks, hardLinks2); - auto testFile3HardLinks = cache.GetHardLinkInfo(testFile3HexName); - EXPECT_EQ(testFile3HardLinks, hardLinks3); } catch (...) { EXPECT_TRUE(false); GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; @@ -434,38 +399,6 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0500, testing::ext:: GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0500"; } -/** - * @tc.number: SUB_backup_b_json_entity_ext_manage_0600 - * @tc.name: b_json_entity_ext_manage_0600 - * @tc.desc: 测试SetExtManage接口中的FindLinks在设备号或INode数目为0时能否成功通过GetExtManage获取相关信息 - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0600, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0600"; - try { - map> mp = {{"key", {"first", {}, true}}}; - Json::Value jv; - BJsonEntityExtManage extMg(jv); - - extMg.SetExtManage(mp); - set ss = extMg.GetExtManage(); - EXPECT_EQ(ss.size(), 1); - - std::get(mp.at("key")).st_dev = 1; - extMg.SetExtManage(mp); - ss = extMg.GetExtManage(); - EXPECT_EQ(ss.size(), 1); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0600"; -} - /** * @tc.number: SUB_backup_b_json_entity_ext_manage_0700 * @tc.name: b_json_entity_ext_manage_0700 @@ -590,187 +523,4 @@ HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0803, testing::ext:: } GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0803"; } - -/** - * @tc.number: SUB_backup_bb_json_entity_ext_manage_0900 - * @tc.name: b_json_entity_ext_manage_0900 - * @tc.desc: 测试SetHardLinkInfo接口和GetHardLinkInfo接口在不符合相关条件时能否成功返回false和空set - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0900, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0900"; - try { - string_view sv = R"({"key":1})"; - BJsonCachedEntity cachedEntity(sv); - auto cache = cachedEntity.Structuralize(); - EXPECT_FALSE(cache.SetHardLinkInfo("", {})); - - Json::Value jv; - BJsonEntityExtManage extMg(jv); - EXPECT_FALSE(extMg.SetHardLinkInfo("1", {})); - - EXPECT_FALSE(cache.SetHardLinkInfo("1", {})); - - EXPECT_EQ(cache.GetHardLinkInfo(""), set()); - - EXPECT_EQ(extMg.GetHardLinkInfo("1"), set()); - - EXPECT_EQ(cache.GetHardLinkInfo("1"), set()); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0900"; -} - -/** - * @tc.number: SUB_backup_b_json_entity_ext_manage_0901 - * @tc.name: b_json_entity_ext_manage_0901 - * @tc.desc: 测试SetHardLinkInfo接口和GetHardLinkInfo接口在不符合相关条件时能否成功返回false和空set - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0901, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0901"; - try { - string_view sv = R"({"key":1})"; - BJsonCachedEntity cachedEntity(sv); - auto cache = cachedEntity.Structuralize(); - EXPECT_FALSE(cache.SetHardLinkInfo("#4$5%", {})); - - Json::Value jv; - BJsonEntityExtManage extMg(jv); - EXPECT_FALSE(extMg.SetHardLinkInfo("1", {})); - - EXPECT_FALSE(cache.SetHardLinkInfo("1", {})); - - EXPECT_EQ(cache.GetHardLinkInfo("#4$5%"), set()); - - EXPECT_EQ(extMg.GetHardLinkInfo("1"), set()); - - EXPECT_EQ(cache.GetHardLinkInfo("1"), set()); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0901"; -} - -/** - * @tc.number: SUB_backup_b_json_entity_ext_manage_0902 - * @tc.name: b_json_entity_ext_manage_0902 - * @tc.desc: 测试SetHardLinkInfo接口和GetHardLinkInfo接口在不符合相关条件时能否成功返回false和空set - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0902, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0902"; - try { - string_view sv = R"({"key":1})"; - BJsonCachedEntity cachedEntity(sv); - auto cache = cachedEntity.Structuralize(); - EXPECT_FALSE(cache.SetHardLinkInfo("测试代码", {})); - - Json::Value jv; - BJsonEntityExtManage extMg(jv); - EXPECT_FALSE(extMg.SetHardLinkInfo("1", {})); - - EXPECT_FALSE(cache.SetHardLinkInfo("1", {})); - - EXPECT_EQ(cache.GetHardLinkInfo("测试代码"), set()); - - EXPECT_EQ(extMg.GetHardLinkInfo("1"), set()); - - EXPECT_EQ(cache.GetHardLinkInfo("1"), set()); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0902"; -} - -/** - * @tc.number: SUB_backup_b_json_entity_ext_manage_0903 - * @tc.name: b_json_entity_ext_manage_0903 - * @tc.desc: 测试SetHardLinkInfo接口和GetHardLinkInfo接口在不符合相关条件时能否成功返回false和空set - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0903, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0903"; - try { - string_view sv = R"({"key":1})"; - BJsonCachedEntity cachedEntity(sv); - auto cache = cachedEntity.Structuralize(); - EXPECT_FALSE(cache.SetHardLinkInfo("ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA\ - BCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD", {})); - - Json::Value jv; - BJsonEntityExtManage extMg(jv); - EXPECT_FALSE(extMg.SetHardLinkInfo("1", {})); - - EXPECT_FALSE(cache.SetHardLinkInfo("1", {})); - - EXPECT_EQ(cache.GetHardLinkInfo("ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDA\ - BCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD"), set()); - - EXPECT_EQ(extMg.GetHardLinkInfo("1"), set()); - - EXPECT_EQ(cache.GetHardLinkInfo("1"), set()); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0903"; -} - -/** - * @tc.number: SUB_backup_b_json_entity_ext_manage_0904 - * @tc.name: b_json_entity_ext_manage_0904 - * @tc.desc: 测试SetHardLinkInfo接口和GetHardLinkInfo接口在不符合相关条件时能否成功返回false和空set - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 0 - * @tc.require: I6F3GV - */ -HWTEST_F(BJsonEntityExtManageTest, b_json_entity_ext_manage_0904, testing::ext::TestSize.Level0) -{ - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-begin b_json_entity_ext_manage_0904"; - try { - string_view sv = R"({"key":1})"; - BJsonCachedEntity cachedEntity(sv); - auto cache = cachedEntity.Structuralize(); - EXPECT_FALSE(cache.SetHardLinkInfo("", {""""""""""""""""""""""""""""""""""""""""""""""""""})); - - Json::Value jv; - BJsonEntityExtManage extMg(jv); - EXPECT_FALSE(extMg.SetHardLinkInfo("测试代码", {})); - - EXPECT_FALSE(cache.SetHardLinkInfo("#4$5%", {})); - - EXPECT_EQ(cache.GetHardLinkInfo(""), set()); - - EXPECT_EQ(extMg.GetHardLinkInfo("测试代码"), set()); - - EXPECT_EQ(cache.GetHardLinkInfo("#4$5%"), set()); - } catch (...) { - EXPECT_TRUE(false); - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-an exception occurred."; - } - GTEST_LOG_(INFO) << "BJsonEntityExtManageTest-end b_json_entity_ext_manage_0904"; -} - } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/tests/unittests/backup_utils/b_json/b_report_entity_test.cpp b/tests/unittests/backup_utils/b_json/b_report_entity_test.cpp index a94a6ca95..40a952afc 100644 --- a/tests/unittests/backup_utils/b_json/b_report_entity_test.cpp +++ b/tests/unittests/backup_utils/b_json/b_report_entity_test.cpp @@ -78,7 +78,7 @@ HWTEST_F(BReportEntityTest, b_report_entity_GetReportInfos_0100, testing::ext::T const auto [filePath, res] = GetTestFile(tm, content); BReportEntity cloudRp(UniqueFd(open(filePath.data(), O_RDONLY, 0))); - map cloudFiles = cloudRp.GetReportInfos(); + unordered_map cloudFiles = cloudRp.GetReportInfos(); bool flag = false; diff --git a/utils/include/b_json/b_json_entity_ext_manage.h b/utils/include/b_json/b_json_entity_ext_manage.h index 0d78e442d..ccd2b7afd 100644 --- a/utils/include/b_json/b_json_entity_ext_manage.h +++ b/utils/include/b_json/b_json_entity_ext_manage.h @@ -55,24 +55,6 @@ public: */ std::vector GetExtManageInfo() const; - /** - * @brief Set the hard link Information - * - * @param origin 原始文件名 - * @param hardLinks 硬链接文件名 - * @return true 设置成功 - * @return false 设置失败 - */ - bool SetHardLinkInfo(const std::string origin, const std::set hardLinks); - - /** - * @brief Get the hard link Information - * - * @param origin 原始文件名 - * @return const 硬链接集合 - */ - const std::set GetHardLinkInfo(const string origin); - public: /** * @brief 构造方法,具备T(Json::Value&, std::any)能力的构造函数 diff --git a/utils/include/b_json/b_report_entity.h b/utils/include/b_json/b_report_entity.h index 9bdc59df9..7756f3e9e 100644 --- a/utils/include/b_json/b_report_entity.h +++ b/utils/include/b_json/b_report_entity.h @@ -32,6 +32,7 @@ struct ReportFileInfo { off_t mtime {0}; std::string hash; bool isIncremental {false}; + off_t userTar {0}; }; class BReportEntity { @@ -41,7 +42,7 @@ public: * * @return std::map */ - std::map GetReportInfos(); + std::unordered_map GetReportInfos(); public: /** diff --git a/utils/src/b_json/b_json_entity_ext_manage.cpp b/utils/src/b_json/b_json_entity_ext_manage.cpp index 41658735d..db63c22b7 100644 --- a/utils/src/b_json/b_json_entity_ext_manage.cpp +++ b/utils/src/b_json/b_json_entity_ext_manage.cpp @@ -32,15 +32,8 @@ namespace { const int32_t DEFAULT_MODE = 0100660; // 0660 } -static bool CheckBigFile(const string &tarFile) +static bool CheckBigFile(struct stat sta) { - HILOGI("CheckBigFile tarFile:%{public}s", tarFile.data()); - struct stat sta; - int ret = stat(tarFile.c_str(), &sta); - if (ret != 0) { - HILOGE("stat file failed, file:%{public}s", tarFile.c_str()); - return false; - } if (sta.st_size > BConstants::BIG_FILE_BOUNDARY) { return true; } @@ -54,8 +47,7 @@ static bool CheckBigFile(const string &tarFile) */ static bool CheckOwnPackTar(const string &fileName) { - if (access(fileName.c_str(), F_OK) != 0) { - HILOGE("file does not exists"); + if (ExtractFileExt(fileName) != "tar") { return false; } // 如果不是在默认路径下的文件包,不属于自身打包的tar文件 @@ -66,6 +58,8 @@ static bool CheckOwnPackTar(const string &fileName) } catch (const BError &e) { HILOGE("file is not backup path"); return false; + } catch (...) { + return false; } string::size_type pathPos = absPath.find(defaultBackupPath); @@ -80,17 +74,22 @@ static bool CheckOwnPackTar(const string &fileName) } string firstName = string(tarFile).substr(0, pos); + // 判断文件名是否包含part (兼容增量) + string::size_type partPos = firstName.find("_part"); + if (partPos == string::npos) { + return false; + } - return (firstName == "part") && (ExtractFileExt(tarFile) == "tar"); + return true; } -static bool CheckUserTar(const string &fileName) +static bool CheckUserTar(const string &fileName, struct stat sta) { if (access(fileName.c_str(), F_OK) != 0) { HILOGI("file does not exists"); return false; } - return (ExtractFileExt(fileName) == "tar") && CheckBigFile(fileName); + return (ExtractFileExt(fileName) == "tar") && CheckBigFile(sta); } Json::Value Stat2JsonValue(struct stat sta) @@ -139,49 +138,14 @@ void BJsonEntityExtManage::SetExtManage(const map vec(info.size(), false); - - auto FindLinks = [&vec](map>::const_iterator it, - unsigned long index) -> set { - if (std::get<1>(it->second).st_dev == 0 || std::get<1>(it->second).st_ino == 0) { - return {}; - } - - set lks; - auto item = it; - item++; - - for (auto i = index + 1; i < vec.size(); ++i, ++item) { - if (std::get<1>(it->second).st_dev == std::get<1>(item->second).st_dev && - std::get<1>(it->second).st_ino == std::get<1>(item->second).st_ino) { - vec[i] = true; - lks.insert(std::get<0>(item->second)); - HILOGI("lks insert %{public}s", std::get<0>(item->second).c_str()); - } - HILOGI("lks doesn't insert %{public}s", std::get<0>(item->second).c_str()); - } - return lks; - }; - - unsigned long index = 0; - for (auto item = info.begin(); item != info.end(); ++item, ++index) { - if (vec[index]) { - HILOGI("skipped file is %{public}s", item->first.c_str()); - continue; - } - HILOGI("file name is %{public}s", item->first.c_str()); - + for (auto item = info.begin(); item != info.end(); ++item) { Json::Value value; value["fileName"] = item->first; auto [path, sta, isBeforeTar] = item->second; value["information"]["path"] = path; value["information"]["stat"] = Stat2JsonValue(sta); - value["isUserTar"] = isBeforeTar && CheckUserTar(path); - value["isBigFile"] = !CheckOwnPackTar(path) && CheckBigFile(path); - set lks = FindLinks(item, index); - for (const auto &lk : lks) { - value["hardlinks"].append(lk); - } + value["isUserTar"] = isBeforeTar && CheckUserTar(path, sta); + value["isBigFile"] = !CheckOwnPackTar(path) && CheckBigFile(sta); obj_.append(value); } @@ -250,71 +214,4 @@ std::vector BJsonEntityExtManage::GetExtManageInfo() const return infos; } - -bool BJsonEntityExtManage::SetHardLinkInfo(const string origin, const set hardLinks) -{ - if (origin.empty()) { - HILOGE("origin file name can not empty"); - return false; - } - if (!obj_) { - HILOGE("Uninitialized JSon Object reference"); - return false; - } - if (!obj_.isArray()) { - HILOGE("json object isn't an array"); - return false; - } - - for (Json::Value &item : obj_) { - string fileName = item.isObject() && item.isMember("fileName") && item["fileName"].isString() - ? item["fileName"].asString() - : ""; - if (origin == fileName) { - for (const auto &lk : hardLinks) { - item["hardlinks"].append(lk); - } - return true; - } - } - - return false; -} - -const set BJsonEntityExtManage::GetHardLinkInfo(const string origin) -{ - if (origin.empty()) { - HILOGE("origin file name can not empty"); - return {}; - } - if (!obj_) { - HILOGE("Uninitialized JSon Object reference"); - return {}; - } - if (!obj_.isArray()) { - HILOGE("json object isn't an array"); - return {}; - } - - set hardlinks; - for (const Json::Value &item : obj_) { - if (!item.isObject()) { - continue; - } - string fileName = item.isMember("fileName") && item["fileName"].isString() ? item["fileName"].asString() : ""; - if (origin != fileName) { - continue; - } - if (!(item.isMember("hardlinks") && item["hardlinks"].isArray())) { - break; - } - for (const auto &lk : item["hardlinks"]) { - if (lk.isString()) { - hardlinks.emplace(lk.asString()); - } - } - } - - return hardlinks; -} } // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/utils/src/b_json/b_report_entity.cpp b/utils/src/b_json/b_report_entity.cpp index 816441b6e..5d4ac0826 100644 --- a/utils/src/b_json/b_report_entity.cpp +++ b/utils/src/b_json/b_report_entity.cpp @@ -111,7 +111,7 @@ static ErrCode ParseReportInfo(struct ReportFileInfo &fileStat, static void DealLine(unordered_map &keys, int &num, const string &line, - map &infos) + unordered_map &infos) { string currentLine = line; if (currentLine[currentLine.length() - 1] == LINE_WRAP) { @@ -137,9 +137,9 @@ static void DealLine(unordered_map &keys, } } -map BReportEntity::GetReportInfos() +unordered_map BReportEntity::GetReportInfos() { - map infos {}; + unordered_map infos {}; char buffer[HASH_BUFFER_SIZE]; ssize_t bytesRead; -- Gitee