diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index 236d595a698355f237c9d5b8d5663473f5c716ac..4496d29769b12496e40f852aa3304b7069c274c9 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -35,7 +35,6 @@ namespace OHOS::FileManagement::Backup { using CompareFilesResult = tuple, map, - map, map>; class BackupExtExtension : public ExtExtensionStub { public: @@ -140,14 +139,15 @@ private: int DoIncrementalBackup(const std::map &allFiles, const std::map &smallFiles, - const std::map &bigFiles, - const std::map &bigInfos); + const std::map &bigFiles); - CompareFilesResult CompareFiles(const std::unordered_map &cloudFiles, - const unordered_map &storageFiles); + void CompareFiles(UniqueFd incrementalFd, + UniqueFd manifestFd, + map &allFiles, + map &smallFiles, + map &bigFiles); - void AsyncTaskDoIncrementalBackup(const std::unordered_map &cloudFiles, - const unordered_map &storageFiles); + void AsyncTaskDoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd); void AsyncTaskOnIncrementalBackup(); /** diff --git a/frameworks/native/backup_ext/src/ext_extension.cpp b/frameworks/native/backup_ext/src/ext_extension.cpp index d9f7294874be06694a6b8b8e026c1caa3711205d..efb68d0e08a897fe7e68ac9e9f770a2610b70bb7 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -1262,57 +1262,59 @@ static bool CheckTar(const string &fileName) return ExtractFileExt(fileName) == "tar"; } -CompareFilesResult BackupExtExtension::CompareFiles(const std::unordered_map &cloudFiles, - const unordered_map &storageFiles) +void BackupExtExtension::CompareFiles(UniqueFd incrementalFd, + UniqueFd manifestFd, + map &allFiles, + map &smallFiles, + map &bigFiles) { - HILOGD("Begin"); - map allFiles; - map smallFiles; - map bigFiles; - map bigInfos; - std::unordered_map cloud(cloudFiles.begin(), cloudFiles.end()); - std::unordered_map storage(storageFiles.begin(), storageFiles.end()); - for (auto &item : storage) { + HILOGI("Begin Compare"); + struct ReportFileInfo storageFiles; + + BReportEntity cloudRp(move(manifestFd)); + unordered_map cloudFiles = cloudRp.GetReportInfos(); + BReportEntity storageRp(move(incrementalFd)); + + while (storageRp.GetStorageReportInfos(storageFiles)) { // 进行文件对比 - string path = item.first; - bool isExist = cloud.find(path) != cloud.end() ? true : false; - if (item.second.isIncremental == true && item.second.isDir == true && !isExist) { - smallFiles.try_emplace(path, item.second); + string path = storageFiles.filePath; + if (path.empty()) { + continue; + } + bool isExist = cloudFiles.find(path) != cloudFiles.end() ? true : false; + if (storageFiles.isIncremental == true && storageFiles.isDir == true && !isExist) { + smallFiles.try_emplace(path, storageFiles); } - if (item.second.isIncremental == true && item.second.isDir == false) { + if (storageFiles.isIncremental == true && storageFiles.isDir == false) { auto [res, fileHash] = BFileHash::HashWithSHA256(path); if (fileHash.empty()) { continue; } - item.second.hash = fileHash; - item.second.isIncremental = true; + storageFiles.hash = fileHash; + storageFiles.isIncremental = true; } - if (item.second.isDir == false && CheckTar(path)) { - item.second.userTar = 1; + if (storageFiles.isDir == false && CheckTar(path)) { + storageFiles.userTar = 1; } - allFiles.try_emplace(path, item.second); - if (item.second.isDir == false && item.second.isIncremental == true && (!isExist || - cloud.find(path)->second.hash != item.second.hash)) { + allFiles.try_emplace(path, storageFiles); + if (storageFiles.isDir == false && storageFiles.isIncremental == true && (!isExist || + cloudFiles.find(path)->second.hash != storageFiles.hash)) { // 在云空间简报里不存在或者hash不一致 - if (item.second.size <= BConstants::BIG_FILE_BOUNDARY) { - smallFiles.try_emplace(path, item.second); + if (storageFiles.size <= BConstants::BIG_FILE_BOUNDARY) { + smallFiles.try_emplace(path, storageFiles); continue; } - struct stat sta = {}; - if (stat(path.c_str(), &sta) == -1) { - continue; - } - bigFiles.try_emplace(path, sta); - bigInfos.try_emplace(path, item.second); + bigFiles.try_emplace(path, storageFiles); } } - return {allFiles, smallFiles, bigFiles, bigInfos}; + HILOGI("End Compare"); } ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) { + HILOGI("Start HandleIncrementalBackup"); HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); string usrConfig = extension_->GetUsrConfig(); BJsonCachedEntity cachedEntity(usrConfig); @@ -1322,11 +1324,7 @@ ErrCode BackupExtExtension::HandleIncrementalBackup(UniqueFd incrementalFd, Uniq return BError(BError::Codes::EXT_FORBID_BACKUP_RESTORE, "Application does not allow backup or restore") .GetCode(); } - BReportEntity cloudRp(move(manifestFd)); - unordered_map cloudFiles = cloudRp.GetReportInfos(); - BReportEntity storageRp(move(incrementalFd)); - unordered_map storageFiles = storageRp.GetReportInfos(); - AsyncTaskDoIncrementalBackup(cloudFiles, storageFiles); + AsyncTaskDoIncrementalBackup(move(incrementalFd), move(manifestFd)); return 0; } @@ -1381,7 +1379,7 @@ static void WriteFile(const string &filename, const map &files) +static TarMap GetIncrmentBigInfos(const map &files) { auto getStringHash = [](const TarMap &m, const string &str) -> string { ostringstream strHex; @@ -1402,9 +1400,11 @@ static TarMap GetIncrmentBigInfos(const map &files) TarMap bigFiles; for (const auto &item : files) { + struct stat sta = {}; + stat(item.first.c_str(), &sta); string md5Name = getStringHash(bigFiles, item.first); if (!md5Name.empty()) { - bigFiles.emplace(md5Name, make_tuple(item.first, item.second, true)); + bigFiles.emplace(md5Name, make_tuple(item.first, sta, true)); } } @@ -1477,19 +1477,28 @@ static ErrCode IncrementalBigFileReady(const TarMap &pkgInfo, return ret; } -void BackupExtExtension::AsyncTaskDoIncrementalBackup( - const std::unordered_map &cloudFiles, - const unordered_map &storageFiles) -{ - auto task = [obj {wptr(this)}, cloudFiles, storageFiles]() { +void BackupExtExtension::AsyncTaskDoIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) +{ + HILOGI("Start AsyncTaskDoIncrementalBackup"); + int incrementalFdDup = dup(incrementalFd); + int manifestFdDup = dup(manifestFd); + + auto task = [obj {wptr(this)}, manifestFdDup, incrementalFdDup]() { auto ptr = obj.promote(); try { BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been already released"); BExcepUltils::BAssert(ptr->extension_, BError::Codes::EXT_INVAL_ARG, "extension handle have been already released"); - auto [allFiles, smallFiles, bigFiles, bigInfos] = ptr->CompareFiles(cloudFiles, storageFiles); - auto ret = ptr->DoIncrementalBackup(allFiles, smallFiles, bigFiles, bigInfos); + map allFiles; + map smallFiles; + map bigFiles; + UniqueFd incrementalDupFd(dup(incrementalFdDup)); + UniqueFd manifestDupFd(dup(manifestFdDup)); + close(incrementalFdDup); + close(manifestFdDup); + auto [allFiles, smallFiles, bigFiles] = ptr->CompareFiles(move(incrementalDupFd), move(manifestDupFd), allFiles, smallFiles, bigFiles); + auto ret = ptr->DoIncrementalBackup(allFiles, smallFiles, bigFiles); ptr->AppIncrementalDone(ret); HILOGE("Incremental backup app done %{public}d", ret); } catch (const BError &e) { @@ -1522,6 +1531,7 @@ void BackupExtExtension::AsyncTaskOnIncrementalBackup() if (proxy == nullptr) { throw BError(BError::Codes::EXT_BROKEN_BACKUP_SA, std::generic_category().message(errno)); } + HILOGI("Start GetAppLocalListAndDoIncrementalBackup"); proxy->GetAppLocalListAndDoIncrementalBackup(); }; try { @@ -1631,8 +1641,7 @@ static ErrCode IncrementalAllFileReady(const TarMap &pkgInfo, int BackupExtExtension::DoIncrementalBackup(const map &allFiles, const map &smallFiles, - const map &bigFiles, - const map &bigInfos) + const map &bigFiles) { HILOGI("Do increment backup"); if (extension_->GetExtensionAction() != BConstants::ExtensionAction::BACKUP) { @@ -1664,7 +1673,7 @@ int BackupExtExtension::DoIncrementalBackup(const mapIncreaseSessionCnt(); session_->SetSessionUserId(GetUserIdDefault()); std::string bundleName = VerifyCallerAndGetCallerName(); - auto backUpConnection = session_->GetExtConnection(bundleName); - auto proxy = backUpConnection->GetBackupExtProxy(); - if (!proxy) { - throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); - } - int64_t lastTime = session_->GetLastIncrementalTime(bundleName); - std::vector bundleNames; - bundleNames.emplace_back(BIncrementalData {bundleName, lastTime}); - BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session_->GetSessionUserId()); - string path = BConstants::GetSaBundleBackupRootDir(session_->GetSessionUserId()). - append(bundleName). - append("/"). - append(BConstants::BACKUP_STAT_SYMBOL). - append(to_string(lastTime)); - HILOGD("path = %{public}s", path.c_str()); - UniqueFd fdLocal(open(path.data(), O_RDWR, S_IRGRP | S_IWGRP)); - if (fdLocal < 0) { - HILOGD("fdLocal open fail, error = %{public}d", errno); - throw BError(BError::Codes::SA_INVAL_ARG, "open local Manifest file failed"); - } - UniqueFd lastManifestFd(session_->GetIncrementalManifestFd(bundleName)); - auto ret = proxy->HandleIncrementalBackup(move(fdLocal), move(lastManifestFd)); - if (ret) { - ClearSessionAndSchedInfo(bundleName); - NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED)); - } + auto task = [ptr {wptr(this)}, BundleName] { + auto thisPtr = prt.promote(); + if (!thisPtr) { + HILOGW("this pointer is null"); + return; + } + auto session = thisPtr->session_; + auto backUpConnection = session_->GetExtConnection(bundleName); + auto proxy = backUpConnection->GetBackupExtProxy(); + if (!proxy) { + throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); + } + int64_t lastTime = session_->GetLastIncrementalTime(bundleName); + std::vector bundleNames; + bundleNames.emplace_back(BIncrementalData {bundleName, lastTime}); + BundleMgrAdapter::GetBundleInfosForIncremental(bundleNames, session_->GetSessionUserId()); + string path = BConstants::GetSaBundleBackupRootDir(session_->GetSessionUserId()). + append(bundleName). + append("/"). + append(BConstants::BACKUP_STAT_SYMBOL). + append(to_string(lastTime)); + HILOGD("path = %{public}s", path.c_str()); + UniqueFd fdLocal(open(path.data(), O_RDWR, S_IRGRP | S_IWGRP)); + if (fdLocal < 0) { + HILOGD("fdLocal open fail, error = %{public}d", errno); + throw BError(BError::Codes::SA_INVAL_ARG, "open local Manifest file failed"); + } + UniqueFd lastManifestFd(session_->GetIncrementalManifestFd(bundleName)); + auto ret = proxy->HandleIncrementalBackup(move(fdLocal), move(lastManifestFd)); + if (ret) { + thisPtr->ClearSessionAndSchedInfo(bundleName); + thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_DIED)); + } + }; + threadPool_.AddTask([task]() { + try { + task(); + } catch (...) { + HILOGE("Failed to add task to thread pool"); + } + }); session_->DecreaseSessionCnt(); return BError(BError::Codes::OK); } catch (const BError &e) { diff --git a/utils/include/b_json/b_report_entity.h b/utils/include/b_json/b_report_entity.h index 9dec68dcd6ae080af5b7a1015e17700d7a2cf1aa..c7a2476c108b706060197e3df9b76da9f43de0aa 100644 --- a/utils/include/b_json/b_report_entity.h +++ b/utils/include/b_json/b_report_entity.h @@ -45,6 +45,13 @@ public: */ std::unordered_map GetReportInfos(); + /** + * @brief 获取本地Report信息 + * + * @return bool + */ + bool GetStorageReportInfos(struct ReportFileInfo &fileStat); + /** * @brief Check if line is encode * diff --git a/utils/src/b_json/b_report_entity.cpp b/utils/src/b_json/b_report_entity.cpp index 6bc7152b0759d2a8d095ece347495cbce57e6044..6734e6c02135be42d5db77de18e9ae4ebd0ad313 100644 --- a/utils/src/b_json/b_report_entity.cpp +++ b/utils/src/b_json/b_report_entity.cpp @@ -162,6 +162,37 @@ static void DealLine(unordered_map &keys, } } +static struct ReportFileInfo StorageDealLine(unordered_map &keys, int &num, const string &line) +{ + if (line.empty()) { + return {}; + } + + string currentLine = line; + if (currentLine[currentLine.length() - 1] == LINE_WRAP) { + currentLine.pop_back(); + } + + vector splits = SplitStringByChar(currentLine, ATTR_SEP); + if (num < INFO_ALIGN_NUM) { + if (num == 1) { + for (int j = 0; j < (int)splits.size(); j++) { + keys.emplace(splits[j], j - 1); + } + } + num++; + } else { + struct ReportFileInfo fileState; + auto code = ParseReportInfo(fileState, splits, keys); + if (code != ERR_OK) { + HILOGE("ParseReportInfo err:%{public}d, %{public}s", code, currentLine.c_str()); + } else { + return fileState; + } + } + return {}; +} + unordered_map BReportEntity::GetReportInfos() { unordered_map infos {}; @@ -191,6 +222,33 @@ unordered_map BReportEntity::GetReportInfos() return infos; } +bool BReportEntity::GetStorageReportInfos(struct ReportFileInfo &fileStat) +{ + char buffer[2]; + ssize_t bytesRead; + string currentLine; + static unordered_map keys; + static int num = 0; + + if ((bytesRead = read(srcFile_, buffer, 1)) <= 0) { + keys = {}; + num = 0; + return false; + } + do { + if (buffer[0] != LINE_SEP && buffer[0] != '\0') { + currentLine += buffer[0]; + } else { + currentLine += LINE_SEP; + fileStat = StorageDealLine(keys, num, currentLine); + return true; + } + } while ((bytesRead = read(srcFile_, buffer, 1)) > 0); + currentLine += LINE_SEP; + fileStat = StorageDealLine(keys, num, currentLine); + return true; +} + void BReportEntity::CheckAndUpdateIfReportLineEncoded(std::string &path) { if (path.empty()) {