From 3107ce08ccb8b927ad82874c4ae0025bf0502375 Mon Sep 17 00:00:00 2001 From: huhui Date: Wed, 28 May 2025 16:32:57 +0800 Subject: [PATCH 1/3] test pr Signed-off-by: huhui --- .../module_external/storage_manager_service.h | 181 ++++ .../storage_manager_service.cpp | 836 ++++++++++++++++++ 2 files changed, 1017 insertions(+) create mode 100644 services/backup_sa/include/module_external/storage_manager_service.h create mode 100644 services/backup_sa/src/module_external/storage_manager_service.cpp diff --git a/services/backup_sa/include/module_external/storage_manager_service.h b/services/backup_sa/include/module_external/storage_manager_service.h new file mode 100644 index 000000000..3fda6fa47 --- /dev/null +++ b/services/backup_sa/include/module_external/storage_manager_service.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H +#define OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H + +#include +#include +#include + +#include "istorage_manager.h" +#include "datashare_abs_result_set.h" +#include "datashare_helper.h" +#include "datashare_predicates.h" + +namespace OHOS::FileManagement::Backup { +const uint64_t PATH_MAX_LEN = 4096; +const std::string PHY_APP = "/data/app/"; +const std::string WILDCARD_DEFAULT_INCLUDE = "*"; +constexpr char FILE_SEPARATOR_CHAR = '/'; +const std::string BASE_EL1 = "/data/storage/el1/base/"; +const std::string BASE_EL2 = "/data/storage/el2/base/"; +const std::string EL1 = "el1"; +const std::string EL2 = "el2"; +const std::string BASE = "/base/"; +const std::string Backup_INCLUDE = "INCLUDES"; +const std::string Backup_EXCLUDE = "EXCLUDES"; +const std::string BACKUP_PATH_PREFIX = "/data/service/el2"; +const std::string BACKUP_PATH_SURFFIX = "/backup/backup_sa/"; +const std::string BACKUP_INCEXC_SYMBOL = "incExc_"; +const std::string BACKUP_STAT_SYMBOL = "stat_"; +const std::string DEFAULT_INCLUDE_PATH_IN_HAP_FILES = "files"; +const std::string DEFAULT_INCLUDE_PATH_IN_HAP_DATABASE = "database"; +const std::string DEFAULT_INCLUDE_PATH_IN_HAP_PREFERENCE = "preferences"; +const std::string MEDIA_CLOUD_SAND_PREFIX = "/storage/cloud"; +const std::string MEDIA_SAND_PREFIX = "/storage/media"; +const std::string URI_PREFIX = "file://"; +const std::string NORMAL_SAND_PREFIX = "/data/storage/"; +const std::string FILE_SAND_PREFIX = "/storage/Users"; +const std::string FILE_AUTHORITY = "docs"; +const std::string DEFAULT_PATH_WITH_WILDCARD = "/haps/*"; +const std::string FILE_CONTENT_SEPARATOR = ";"; +const char LINE_SEP = '\n'; +const std::string VER_10_LINE1 = "version=1.0&attrNum=8"; +const std::string VER_10_LINE2 = "path;mode;dir;size;mtime;hash;inIncremental;encodeFlag"; +const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; +const std::string MEDIA_QUERYOPRN_QUERYVOLUME = "query_media_volume"; +const std::string MEDIA_TYPE = "media"; +const std::string FILE_TYPE = "file"; +const std::int32_t E_OK = 0; +constexpr int32_t E_ERR = -1; +constexpr int32_t STORAGE_SERVICE_SYS_CAP_TAG = 13600000; +constexpr const char *QUOTA_DEVICE_DATA_PATH = "/data"; +constexpr const char *PROC_MOUNTS_PATH = "/proc/mounts"; +constexpr const char *DEV_BLOCK_PATH = "/dev/block"; +const std::int32_t E_SA_IS_NULLPTR = STORAGE_SERVICE_SYS_CAP_TAG + 12; +const std::int32_t E_REMOTE_IS_NULLPTR = STORAGE_SERVICE_SYS_CAP_TAG + 13; +const std::int32_t E_MEDIALIBRARY_ERROR = STORAGE_SERVICE_SYS_CAP_TAG + 1202; +const std::int32_t E_QUERY = STORAGE_SERVICE_SYS_CAP_TAG + 1206; +const std::int32_t E_GETROWCOUNT = STORAGE_SERVICE_SYS_CAP_TAG + 1207; +const std::int32_t E_SYS_KERNEL_ERR = STORAGE_SERVICE_SYS_CAP_TAG + 8; +const int32_t E_SYS_ERR = -1; +const int MEDIA_TYPE_IMAGE = 1; +const int MEDIA_TYPE_VIDEO = 2; +const int MEDIA_TYPE_AUDIO = 3; +const int32_t GET_DATA_SHARE_HELPER_TIMES = 5; +const int UID_FILE_MANAGER = 1006; +const int32_t USER_ID_BASE = 200000; +static std::map mQuotaReverseMounts; + + +struct FileStat { + std::string filePath; + int64_t fileSize; + int64_t lastUpdateTime; + int32_t mode; + bool isDir; + bool isIncre; +}; +struct BundleStatsParas { + uint32_t userId; + std::string &bundleName; + int64_t lastBackupTime; + int64_t fileSizeSum; + int64_t incFileSizeSum; +}; + +class StorageManagerServie { +public: + StorageManagerServie(); + ~StorageManagerServie(); + static StorageManagerServie &GetInstance(); + /** + * @brief Get the bundle stats object + * + * @param bundleName bundle name + */ + StorageManager::BundleStats GetBundleStats(const std::string &bundleName); + + /** + * @brief Get the user storage stats object + * + * @param bundleName bundle name + * @param userId user id + */ + int32_t GetUserStorageStatsByType(int32_t userId, StorageManager::StorageStats &storageStats, std::string type); + + /** + * @brief update memory para + * + * @param size para data + */ + int32_t UpdateMemoryPara(int32_t size, int32_t oldSize); + + /** + * @brief Get the user storage stats object + * + * @param userId user id + * @param bundleNames + * @param incrementalBackTimes + * @param pkgFileSizes bundle backup file size + * @param incPkgFileSizes Incremental bundle backup file size + */ + int32_t GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, + const std::vector &incrementalBackTimes, std::vector &pkgFileSizes, + std::vector &incPkgFileSizes); +private: + void GetBundleStatsForIncreaseEach(uint32_t userId, std::string &bundleName, int64_t lastBackupTime, + std::vector &pkgFileSizes, std::vector &incPkgFileSizes); + std::tuple, std::vector> ReadIncludesExcludesPath( + const std::string &bundleName, const int64_t lastBackupTime, const uint32_t userId); + void DealWithIncludeFiles(const BundleStatsParas ¶s, const std::vector &includes, + std::vector &phyIncludes, std::map& pathMap); + void ConvertSandboxRealPath(const uint32_t userId, const std::string &bundleName, + const std::string &sandboxPathStr, std::vector &realPaths, + std::map& pathMap); + void DeduplicationPath(std::vector &configPaths); + void ScanExtensionPath(BundleStatsParas ¶s, + const std::vector &includes, const std::vector &excludes, + std::map &pathMap, std::ofstream &statFile); + void RecognizeSandboxWildCard(const uint32_t userId, const std::string &bundleName, + const std::string &sandboxPathStr, std::vector &phyIncludes, + std::map& pathMap); + void SetExcludePathMap(std::string &excludePath, std::map &excludesMap); + std::tuple CheckIfDirForIncludes(const std::string &path, BundleStatsParas ¶s, + std::map &pathMap, std::ofstream &statFile, std::map &excludesMap); + bool GetIncludesFileStats(const std::string &dir, BundleStatsParas ¶s, + std::map &pathMap, + std::ofstream &statFile, std::map &excludesMap); + bool GetPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &includeWildCard, + std::vector &includePathList, std::map &pathMap); + bool ExcludeFilter(std::map &excludesMap, const std::string &path); + void WriteFileList(std::ofstream &statFile, struct FileStat fileStat, BundleStatsParas ¶s); + bool AddOuterDirIntoFileStat(const std::string &dir, BundleStatsParas ¶s, const std::string &sandboxDir, + std::ofstream &statFile, std::map &excludesMap); + std::string PhysicalToSandboxPath(const std::string &dir, const std::string &sandboxDir, const std::string &path); + void InsertStatFile(const std::string &path, struct FileStat fileStat, + std::ofstream &statFile, std::map &excludesMap, BundleStatsParas ¶s); + bool AddPathMapForPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &phyPath, + std::map &pathMap); + uint32_t CheckOverLongPath(const std::string &path); + int32_t GetMediaStorageStats(StorageManager::StorageStats &storageStats); + void GetMediaTypeAndSize(const std::shared_ptr &resultSet, + StorageManager::StorageStats &storageStats); + int32_t GetFileStorageStats(int32_t userId, StorageManager::StorageStats &storageStats); + bool InitialiseQuotaMounts(); +} +} // namespace OHOS::FileManagement::Backup +#endif // OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H \ No newline at end of file diff --git a/services/backup_sa/src/module_external/storage_manager_service.cpp b/services/backup_sa/src/module_external/storage_manager_service.cpp new file mode 100644 index 000000000..3ead3522e --- /dev/null +++ b/services/backup_sa/src/module_external/storage_manager_service.cpp @@ -0,0 +1,836 @@ +/* + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "module_external/storage_manager_service.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "b_error/b_error.h" +#include "b_resources/b_constants.h" +#include "filemgmt_helper.h" +#include "sandbox_helper.h" +#include "file_uri.h" + +#include +#include + +namespace OHOS::FileManagement::Backup { +using namespace std; +std:: recursive_mutex mMountsLock; +// +// +// +// +// +// + +static bool PathSortFunc(const std::string &path1, const std::string &path2) +{ + return path1 < path2; +} + +static std::string GetQuotaSrcMountPath(const std::string &target) +{ + std::lock_guard lock(mMountsLock); + if (mQuotaReverseMounts.find(target) != mQuotaReverseMounts.end()) { + return mQuotaReverseMounts[target]; + } else { + return ""; + } +} + +StorageManagerServie::StorageManagerServie() +{ +} +StorageManagerServie::~StorageManagerServie() +{ +} + +StorageManagerServie &StorageManagerServie::GetInstance() +{ + static StorageManagerServie instance{}; + return instance; +} + +StorageManager::BundleStats StorageManagerServie::GetBundleStats(const string &bundleName) +{ + StorageManager::BundleStats bundleStats; + return bundleStats; +} + +int32_t StorageStatusService::GetUserStorageStatsByType(int32_t userId, StorageStats &storageStats, std::string type) +{ + // + storageStats.video_ = 0; + storageStats.image_ = 0; + storageStats.file_ = 0; + int32_t err = E_OK; + if (type == MEDIA_TYPE) { + LOGI("GetUserStorageStatsByType media"); + err = GetMediaStorageStats(storageStats); + } else if (type == FILE_TYPE) { + LOGI("GetUserStorageStatsByType file"); + err = GetFileStorageStats(userId, storageStats); + } else { + LOGI("GetUserStorageStatsByType type: %{public}s", type.c_str()); + } + return err; +} + +int32_t StorageManagerServie::GetMediaStorageStats(StorageStats &storageStats) +{ + LOGE("GetMediaStorageStats start"); + auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (sam == nullptr) { + LOGE("StorageStatusService::GetMediaStorageStats samgr == nullptr"); + return E_SA_IS_NULLPTR; + } + auto remoteObj = sam->GetSystemAbility(FILEMANAGEMENT_BACKUP_SERVICE_SA_ID); + if (remoteObj == nullptr) { + LOGE("StorageStatusService::GetMediaStorageStats remoteObj == nullptr"); + return E_REMOTE_IS_NULLPTR; + } + int32_t tryCount = 1; + LOGE("GetMediaStorageStats start Creator"); + auto dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI); + while (dataShareHelper == nullptr && tryCount < GET_DATA_SHARE_HELPER_TIMES) { + LOGW("dataShareHelper is retrying, attempt %{public}d", tryCount); + dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI); + tryCount++; + } + if (dataShareHelper == nullptr) { + LOGE("dataShareHelper is null!"); + return E_MEDIALIBRARY_ERROR; + } + vector columns; + Uri uri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_QUERYOPRN_QUERYVOLUME + "/" + MEDIA_QUERYOPRN_QUERYVOLUME); + DataShare::DataSharePredicates predicates; + LOGE("GetMediaStorageStats start Query"); + auto queryResultSet = dataShareHelper->Query(uri, predicates, columns); + if (queryResultSet == nullptr) { + LOGE("queryResultSet is null!"); + return E_QUERY; + } + auto count = 0; + auto ret = queryResultSet->GetRowCount(count); + if ((ret != E_OK) || (count < 0)) { + LOGE("get row count from rdb failed"); + return E_GETROWCOUNT; + } + GetMediaTypeAndSize(queryResultSet, storageStats); + dataShareHelper->Release(); + LOGE("GetMediaStorageStats end"); + return E_OK; +} + +void StorageManagerServie::GetMediaTypeAndSize(const std::shared_ptr &resultSet, StorageStats &storageStats) +{ + if (resultSet == nullptr) { + LOGE("StorageStatusService::GetMediaTypeAndSize, input resultSet is nullptr."); + return; + } + int thumbnailType = -1; + while (resultSet->GoToNextRow() == E_OK) { + int32_t index = 0; + int mediatype = 0; + int64_t size = 0; + if (resultSet->GetColumnIndex("media_type", index) || resultSet->GetInt(index, mediatype)) { + LOGE("get media_type column index or int value err."); + continue; + } + if (resultSet->GetColumnIndex("size", index) || resultSet->GetLong(index, size)) { + LOGE("get size column index or long value err."); + continue; + } + LOGI("media type: %{public}d, size: %{public}lld", mediatype, static_cast(size)); + if (mediatype == MEDIA_TYPE_IMAGE || mediatype == thumbnailType) { + storageStats.image_ += size; + } else if (mediatype == MEDIA_TYPE_AUDIO) { + storageStats.audio_ = size; + } else if (mediatype == MEDIA_TYPE_VIDEO) { + storageStats.video_ = size; + } else { + LOGD("unsupprted media_type: %{public}d", mediatype); + } + } +} + +int32_t StorageManagerServie::GetFileStorageStats(int32_t userId, StorageStats &storageStats) +{ + int32_t uid = userId * USER_ID_BASE + UID_FILE_MANAGER; + HILOGE("GetOccupiedSpaceForUid uid:%{public}d", uid); + if (InitialiseQuotaMounts() != true) { + HILOGE("Failed to initialise quota mounts"); + reutrn E_SYS_KERNEL_ERR; + } + + std::string device = ""; + for (auto it = mQuotaReverseMounts.begin(); it != mQuotaReverseMounts.end(); ++it) { + // + } + // + device = GetQuotaSrcMountPath(QUOTA_DEVICE_DATA_PATH); + if (device.empty()) { + HILOGE("skip when device no quotas present"); + return E_OK; + } + + struct dqblk dq; + // + if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid, reinterpret_cast(&dq)) != 0) { + HILOGE("Failed to get quotactl, errno : %{public}d", errno); + return E_SYS_KERNEL_ERR + } + // + storageStats.file_ = static_cast(dq.dqb_curspace); + HILOGE("GetOccupiedSpaceForUid size:%{public}s", std::tostring(storageStats.file_).c_str()); + return E_OK; + + +} + +bool StorageManagerServie::InitialiseQuotaMounts() +{ + std::lock_guard lock(mMountsLock); + mQuotaReverseMounts.clear(); + std::ifstream in(PROC_MOUNTS_PATH); + + if (!in.is_open()) { + LOGE("Failed to open mounts file"); + return false; + } + std::string source; + std::string target; + std::string ignored; + + while (in.peek() != EOF) { + std::getline(in, source, ' '); + std::getline(in, target, ' '); + std::getline(in, ignored); + // + // + // + if (source.compare(0, strlen(DEV_BLOCK_PATH), DEV_BLOCK_PATH) == 0) { + struct dqblk dq; + // + if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0, reinterpret_cast(&dq)) == 0) { + // + mQuotaReverseMounts[target] = source; + } + // + // + } + } + + return true; +} + +int32_t StorageManagerServie::UpdateMemoryPara(int32_t size, int32_t oldSize) +{ + return 0; +} + +int32_t StorageManagerServie::GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, + const std::vector &incrementalBackTimes, std::vector &pkgFileSizes, + std::vector &incPkgFileSizes) +{ + LOGI("GetBundleStatsForIncrease start"); + // + if (bundleNames.size() != incrementalBackTimes.size()) { + LOGE("Invalid paramters, size of bundleNames should match incrementalBackTimes."); + return E_PARAMS_INVALID; + } + + for (size_t i = 0; i < bundleNames.size(); i++) { + std::string bundleName = bundleNames[i]; + int64_t lastBackupTime = incrementalBackTimes[i]; + // + GetBundleStatsForIncreaseEach(userId, bundleName, lastBackupTime, pkgFileSizes, incPkgFileSizes); + } + return E_OK; +} + +void StorageManagerServie::GetBundleStatsForIncreaseEach(uint32_t userId, std::string &bundleName, int64_t lastBackupTime, + std::vector &pkgFileSizes, std::vector &incPkgFileSizes) +{ + // + // input parameters + BundleStatsParas paras = {.userId = userId, .bundleName = bundleName, + .lastBackupTime = lastBackupTime, .fileSizeSum = 0, .incFileSizeSum = 0}; + + // obtain includes, excludes in backup extension config + auto [includes, excludes] = ReadIncludesExcludesPath(bundleName, lastBackupTime, userId); + if (includes.empty()) { + pkgFileSizes.emplace_back(0); + incPkgFileSizes.emplace_back(0); + return; + } + // physical paths + std::vector phyIncludes; + // map about sandbox path to physical path + std::map pathMap; + + // recognize physical path for include directory + DealWithIncludeFiles(paras, includes, phyIncludes, pathMap); + if (phyIncludes.empty()) { + LOGE("Incorrect convert for include sandbox path for %{private}s", bundleName.c_str()); + pkgFileSizes.emplace_back(0); + incPkgFileSizes.emplace_back(0); + return; + } + + // recognize physical path for exclude directory + std::vector phyExcludes; + for (const auto &exclude : excludes) { + std::string excludeStr = exclude; + if (excludeStr.front() != FILE_SEPARATOR_CHAR) { + excludeStr = FILE_SEPARATOR_CHAR + excludeStr; + } + // convert sandbox to physical path + ConvertSandboxRealPath(userId, bundleName, excludeStr, phyExcludes, pathMap); + } + + std::string filePath = BACKUP_PATH_PREFIX + std::to_string(userId) + BACKUP_PATH_SURFFIX + + bundleName + FILE_SEPARATOR_CHAR + BACKUP_STAT_SYMBOL + std::to_string(lastBackupTime); + // + std::ofstream statFile; + statFile.open(filePath.data(), std::ios::out | std::ios::trunc); + if (!statFile.is_open()) { + LOGE("creat file fail, errno:%{public}d.", errno); + pkgFileSizes.emplace_back(0); + incPkgFileSizes.emplace_back(0); + return; + } + statFile << VER_10_LINE1 << std::endl; + statFile << VER_10_LINE2 << std::endl; + + DeduplicationPath(phyIncludes); + ScanExtensionPath(paras, phyIncludes, phyExcludes, pathMap, statFile); + // calculate summary file sizes + pkgFileSizes.emplace_back(paras.fileSizeSum); + incPkgFileSizes.emplace_back(paras.incFileSizeSum); + LOGI("bundleName: %{public}s, size: %{public}lld", bundleName.c_str(), static_cast(paras.fileSizeSum)); + statFile.close(); +} + +std::tuple, std::vector> StorageManagerServie::ReadIncludesExcludesPath( + const std::string &bundleName, const int64_t lastBackupTime, const uint32_t userId) +{ + // + if (bundleName.empty()) { + LOGE("bundleName is empty"); + return { {}, {} }; + } + // 保存includeExclude的path + std::string filePath = BACKUP_PATH_PREFIX + std::to_string(userId) + BACKUP_PATH_SURFFIX + + bundleName + FILE_SEPARATOR_CHAR + BACKUP_INCEXC_SYMBOL + std::to_string(lastBackupTime); + // + std::ifstream incExcFile; + incExcFile.open(filePath.data()); + if (!incExcFile.is_open()) { + LOGE("Cannot open include/exclude file, fail errno:%{public}d", errno); + return { {}, {} }; + } + + std::vector includes; + std::vector excludes; + bool incOrExt = true; + while (incExcFile) { + std::string line; + std::getline(incExcFile, line); + if (line.empty()) { + LOGI("Read Complete"); + break; + } + if (line == BACKUP_INCLUDE) { + incOrExt = true; + } else if (line == BACKUP_EXCLUDE) { + incOrExt = false; + } + if (incOrExt && line != BACKUP_INCLUDE) { + includes.emplace_back(line); + } else if (!incOrExt && line != BACKUP_EXCLUDE) { + excludes.emplace_back(line); + } + } + // + // + // + // + // + // + incExcFile.close(); + return {includes, excludes}; +} + +void StorageManagerServie::DealWithIncludeFiles(const BundleStatsParas ¶s, const std::vector &includes, + std::vector &phyIncludes, std::map& pathMap) +{ + uint32_t userId = paras.userId; + std::string bundleName = paras.bundleName; + for (const auto &include : includes) { + // + std::string includeStr = include; + // + if (includeStr.front() != FILE_SEPARATOR_CHAR) { + includeStr = FILE_SEPARATOR_CHAR + includeStr; + } + if (includeStr.find(BASE_EL1 + DEFAULT_PATH_WITH_WILDCARD) == 0 || + includeStr.find(BASE_EL2 + DEFAULT_PATH_WITH_WILDCARD) == 0) { + // recognize sandbox path to physical path with wild card + RecognizeSandboxWildCard(userId, bundleName, includeStr, phyIncludes, pathMap); + if (phyIncludes.empty()) { + LOGE("DealWithIncludeFiles failed to recognize path with wildcard %{private}s", bundleName.c_str()); + continue; + } + } else { + // convert sandbox to physical path + ConvertSandboxRealPath(userId, bundleName, includeStr, phyIncludes, pathMap); + } + } +} + +void StorageManagerServie::ConvertSandboxRealPath(const uint32_t userId, const std::string &bundleName, + const std::string &sandboxPathStr, std::vector &realPaths, + std::map& pathMap) +{ + std::string uriString; + if (sandboxPathStr.find(NORMAL_SAND_PREFIX) == 0) { + // for normal hap, start with file://bundleName + uriString = URI_PREFIX + bundleName; + } else if (sandboxPathStr.find(FILE_SAND_PREFIX) == 0) { + // for public files, start with file://docs + uriString = URI_PREFIX + FILE_AUTHORITY; + } else if (sandboxPathStr.find(MEDIA_SAND_PREFIX) == 0) { + std::string physicalPath = sandboxPathStr; + physicalPath.insert(MEDIA_SAND_PREFIX.length(), FILE_SEPARATOR_CHAR + std::to_string(userId)); + realPaths.emplace_back(physicalPath); + pathMap.insert({physicalPath, sandboxPathStr}); + return; + } else if (sandboxPathStr.find(MEDIA_CLOUD_SAND_PREFIX) == 0) { + std::string physicalPath = sandboxPathStr; + physicalPath.insert(MEDIA_CLOUD_SAND_PREFIX.length(), FILE_SEPARATOR_CHAR + std::to_string(userId)); + realPaths.emplace_back(physicalPath); + pathMap.insert({physicalPath, sandboxPathStr}); + return; + } + + if (!uriString.empty()) { + std::string sandboxPathUriStr = AppFileService::SandboxHelper::Encode(sandboxPathStr); + // + uriString += sandboxPathUriStr; + // + AppFileService::ModuleFileUri::FileUri uri(uriString); + // files + std::string physicalPath; + int ret = AppFileService::SandboxHelper::GetBackupPhysicalPath(uri.ToString(), std::to_string(userId), + physicalPath); + if (ret != 0) { + LOGE("Get physical path failed with %{public}d", ret); + return; + } + // + realPaths.emplace_back(physicalPath); + pathMap.insert({physicalPath, sandboxPathStr}); + } +} + +void StorageManagerServie::DeduplicationPath(std::vector &configPaths) +{ + sort(configPaths.begin(), configPaths.end(), PathSortFunc); + auto it = unique(configPaths.begin(), configPaths.end(), [](const std::string &path1, const std::string &path2) { + return path1 == path2; + }); + configPaths.erase(it, configPaths.end()); +} + +void StorageManagerServie::ScanExtensionPath(BundleStatsParas ¶s, + const std::vector &includes, const std::vector &excludes, + std::map &pathMap, std::ofstream &statFile) +{ + std::map excludesMap; + for (auto exclude : excludes) { + SetExcludePathMap(exclude, excludesMap); + } + // all file with stats in include directory + for (const auto &includeDir : includes) { + // Check if includeDir is a file path + auto [isSucc, isDir] = CheckIfDirForIncludes(includeDir, paras, pathMap, statFile, excludesMap); + if (!isSucc) { + continue; + } + // recognize all file in include directory + if (isDir && !GetIncludesFileStats(includeDir, paras, pathMap, statFile, excludesMap)) { + LOGE("Faied to get include files for includeDir"); + } + } +} + +void StorageManagerServie::RecognizeSandboxWildCard(const uint32_t userId, const std::string &bundleName, + const std::string &sandboxPathStr, std::vector &phyIncludes, + std::map& pathMap) +{ + if (sandboxPathStr.find(BASE_EL1 + DEFAULT_PATH_WITH_WILDCARD) == 0) { + std::string physicalPrefix = PHY_APP + EL1 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + + bundleName + FILE_SEPARATOR_CHAR; + std::string relatePath = sandboxPathStr.substr(BASE_EL1.size()); + if (!GetPathWildCard(userId, bundleName, physicalPrefix + relatePath, phyIncludes, pathMap)) { + LOGE("el1 GetPathWildCard dir path invaild"); + } + } else if (sandboxPathStr.find(BASE_EL2 + DEFAULT_PATH_WITH_WILDCARD) == 0) { + std::string physicalPrefix = PHY_APP + EL2 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + + bundleName + FILE_SEPARATOR_CHAR; + std::string relatePath = sandboxPathStr.substr(BASE_EL2.size()); + if (!GetPathWildCard(userId, bundleName, physicalPrefix + relatePath, phyIncludes, pathMap)) { + LOGE("el2 GetPathWildCard dir path invaild"); + } + } +} + +void StorageManagerServie::SetExcludePathMap(std::string &excludePath, std::map &excludesMap) +{ + if (excludePath.empty()) { + LOGE("SetExcludePathMap Param failed"); + return; + } + struct stat fileStatInfo = {0}; + if (stat(excludePath.c_str(), &fileStatInfo) != 0) { + LOGE("SetExcludePathMap call stat error %{private}s, errno:%{public}d", excludePath.c_str(), errno); + return; + } + if (S_ISDIR(fileStatInfo.st_mode)) { + if (excludePath.back() != FILE_SEPARATOR_CHAR) { + excludePath.push_back(FILE_SEPARATOR_CHAR); + } + excludesMap.insert({excludePath, true}); + } else { + excludesMap.insert({excludePath, false}); + } +} + +std::tuple StorageManagerServie::CheckIfDirForIncludes(const std::string &path, BundleStatsParas ¶s, + std::map &pathMap, std::ofstream &statFile, std::map &excludesMap) +{ + if (!statFile.is_open() || path.empty()) { + LOGE("CheckIfDirForIncludes Param failed"); + return {false, false}; + } + // check whether the path exists + struct stat fileStatInfo = {0}; + // + if (stat(path.c_str(), &fileStatInfo) != 0) { + LOGE("CheckIfDirForIncludes call stat error %{private}s, fail errno:%{public}d", path.c_str(), errno); + // + return {false, false}; + } + if (S_ISDIR(fileStatInfo.st_mode)) { + LOGI("%{private}s exists and is a directory", path.c_str()); + // + return {true, true}; + } else { + std::string sandboxPath = path; + auto it = pathMap.find(path); + if (it != pathMap.end()) { + sandboxPath = it->second; + } + + struct FileStat fileStat; + fileStat.filePath = sandboxPath; + fileStat.fileSize = fileStatInfo.st_size; + // mode + fileStat.mode = static_cast(fileStatInfo.st_mode); + fileStat.isDir = false; + int64_t lastUpdateTime = static_cast(fileStatInfo.st_mtime); + fileStat.lastUpdateTime = lastUpdateTime; + if (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) { + fileStat.isIncre = true; + } + if (ExcludeFilter(excludesMap, path) == false) { + WriteFileList(statFile, fileStat, paras); + } + return {true, false}; + } +} + +bool StorageManagerServie::GetIncludesFileStats(const std::string &dir, BundleStatsParas ¶s, + std::map &pathMap, + std::ofstream &statFile, std::map &excludesMap) +{ + std::string sandboxDir = dir; + auto it = pathMap.find(dir); + if (it != pathMap.end()) { + sandboxDir = it->second; + } + // stat current directory info + AddOuterDirIntoFileStat(dir, paras, sandboxDir, statFile, excludesMap); + + std::stack folderStack; + std::string filePath; + folderStack.push(dir); + // stat files and sub-directory in current directory info + while (!folderStack.empty()) { + filePath = folderStack.top(); + folderStack.pop(); + DIR *dirPtr = opendir(filePath.c_str()); + if (dirPtr == nullptr) { + LOGE("GetIncludesFileStats open file dir:%{private}s fail, errno:%{public}d", filePath.c_str(), errno); + continue; + } + if (filePath.back() != FILE_SEPARATOR_CHAR) { + filePath.push_back(FILE_SEPARATOR_CHAR); + } + + struct dirent *entry = nullptr; + while ((entry = readdir(dirPtr)) != nullptr) { + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { + continue; + } + std::string path = filePath + entry->d_name; + struct stat fileInfo = {0}; + if (stat(path.c_str(), &fileInfo) != 0) { + LOGE("GetIncludesFileStats call stat error %{private}s, errno:%{public}d", path.c_str(), errno); + fileInfo.st_size = 0; + } + struct FileStat fileStat = {}; + fileStat.filePath = PhysicalToSandboxPath(dir, sandboxDir, path); + fileStat.fileSize = fileInfo.st_size; + CheckOverLongPath(fileStat.filePath); + // mode + fileStat.mode = static_cast(fileInfo.st_mode); + int64_t lastUpdateTime = static_cast(fileInfo.st_mtime); + fileStat.lastUpdateTime = lastUpdateTime; + fileStat.isIncre = (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) ? true : false; + if (entry->d_type == DT_DIR) { + fileStat.isDir = true; + folderStack.push(path); + } + InsertStatFile(path, fileStat, statFile, excludesMap, paras); + } + closedir(dirPtr); + } + return true; +} + +bool StorageManagerServie::GetPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &includeWildCard, + std::vector &includePathList, std::map &pathMap) +{ + size_t pos = includeWildCard.rfind(WILDCARD_DEFAULT_INCLUDE); + if (pos == std::string::npos) { + LOGE("GetPathWildCard: path should include *"); + return false; + } + std::string pathBeforeWildCard = includeWildCard.substr(0, pos); + DIR *dirPtr = opendir(pathBeforeWildCard.c_str()); + if (dirPtr == nullptr) { + // + LOGE("GetPathWildCard open file dir:%{private}s fail, errno:%{public}d", pathBeforeWildCard.c_str(), errno); + return false; + } + struct dirent *entry = nullptr; + std::vector subDirs; + while ((entry = readdir(dirPtr)) != nullptr) { + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { + continue; + } + std::string path = pathBeforeWildCard + entry->d_name; + if (entry->d_type == DT_DIR) { + subDirs.emplace_back(path); + } + } + closedir(dirPtr); + for (auto &subDir : subDirs) { + DIR *subDirPtr = opendir(subDir.c_str()); + if (subDirPtr == nullptr) { + LOGE("GetPathWildCard open file dir:%{private}s fail, errno:%{public}d", subDir.c_str(), errno); + return false; + } + while ((entry = readdir(subDirPtr)) != nullptr) { + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { + continue; + } + std::string dirName = std::string(entry->d_name); + + std::string path = subDir + FILE_SEPARATOR_CHAR + entry->d_name; + if (entry->d_type == DT_DIR && (dirName == DEFAULT_INCLUDE_PATH_IN_HAP_FILES || + dirName == DEFAULT_INCLUDE_PATH_IN_HAP_DATABASE || + dirName == DEFAULT_INCLUDE_PATH_IN_HAP_PREFERENCE)) { + includePathList.emplace_back(path); + AddPathMapForPathWildCard(userId, bundleName, path, pathMap); + } + } + closedir(subDirPtr); + } + return true; +} + +bool StorageManagerServie::ExcludeFilter(std::map &excludesMap, const std::string &path) +{ + if (path.empty()) { + LOGE("ExcludeFilter Param failed"); + return true; + } + std::string formatPath = path; + for (auto exclude = excludesMap.begin(); exclude != excludesMap.end(); exclude++) { + if (exclude->second != true) { + if (formatPath.compare(exclude->first) == 0) { + return true; + } + } else { + if (formatPath.compare(0, exclude->first.size(), exclude->first) == 0) { + return true; + } + } + } + return false; +} + +void StorageManagerServie::WriteFileList(std::ofstream &statFile, struct FileStat fileStat, BundleStatsParas ¶s) +{ + if (!statFile.is_open() || fileStat.filePath.empty()) { + LOGE("WriteFileList Param failed"); + return; + } + std::string fileLine = ""; + bool encodeFlag = false; + if (fileStat.filePath.find(LINE_SEP) != std::string::npos) { + fileLine += AppFileService::SandboxHelper::Encode(fileStat.filePath) + FILE_CONTENT_SEPARATOR; + encodeFlag = true; + } else { + fileLine += fileStat.filePath + FILE_CONTENT_SEPARATOR; + } + fileLine += std::to_string(fileStat.mode) + FILE_CONTENT_SEPARATOR; + if (fileStat.isDir) { + fileLine += std::to_string(1) + FILE_CONTENT_SEPARATOR; + } else { + fileLine += std::to_string(0) + FILE_CONTENT_SEPARATOR; + } + fileLine += std::to_string(fileStat.fileSize) + FILE_CONTENT_SEPARATOR; + fileLine += std::to_string(fileStat.lastUpdateTime) + FILE_CONTENT_SEPARATOR; + fileLine += FILE_CONTENT_SEPARATOR; + if (fileStat.isIncre) { + fileLine += std::to_string(1); + } else { + fileLine += std::to_string(0); + } + fileLine += FILE_CONTENT_SEPARATOR; + if (encodeFlag) { + fileLine += std::to_string(1); + } else { + fileLine += std::to_string(0); + } + // te file line + statFile << fileLine << std::endl; + if (fileStat.isIncre) { + paras.incFileSizeSum += fileStat.fileSize; + } + paras.fileSizeSum += fileStat.fileSize; +} + +bool StorageManagerServie::AddOuterDirIntoFileStat(const std::string &dir, BundleStatsParas ¶s, const std::string &sandboxDir, + std::ofstream &statFile, std::map &excludesMap) +{ + if (!statFile.is_open() || dir.empty()) { + LOGE("AddOuterDirIntoFileStat Param failed"); + return false; + } + struct stat fileInfo = {0}; + if (stat(dir.c_str(), &fileInfo) != 0) { + LOGE("AddOuterDirIntoFileStat call stat error %{private}s, fail errno:%{public}d", dir.c_str(), errno); + return false; + } + struct FileStat fileStat = {}; + fileStat.filePath = PhysicalToSandboxPath(dir, sandboxDir, dir); + fileStat.fileSize = fileInfo.st_size; + // + // mode + fileStat.mode = static_cast(fileInfo.st_mode); + int64_t lastUpdateTime = static_cast(fileInfo.st_mtime); + fileStat.lastUpdateTime = lastUpdateTime; + fileStat.isIncre = (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) ? true : false; + fileStat.isDir = true; + std::string formatPath = dir; + if (formatPath.back() != FILE_SEPARATOR_CHAR) { + formatPath.push_back(FILE_SEPARATOR_CHAR); + } + if (ExcludeFilter(excludesMap, formatPath) == false) { + WriteFileList(statFile, fileStat, paras); + } + return true; +} + +std::string StorageManagerServie::PhysicalToSandboxPath(const std::string &dir, const std::string &sandboxDir, + const std::string &path) +{ + std::size_t dirPos = dir.size(); + std::string pathSurffix = path.substr(dirPos); + return sandboxDir + pathSurffix; +} + +void StorageManagerServie::InsertStatFile(const std::string &path, struct FileStat fileStat, + std::ofstream &statFile, std::map &excludesMap, BundleStatsParas ¶s) +{ + if (!statFile.is_open() || path.empty()) { + LOGE("InsertStatFile Param failed"); + return; + } + std::string formatPath = path; + if (fileStat.isDir == true && formatPath.back() != FILE_SEPARATOR_CHAR) { + formatPath.push_back(FILE_SEPARATOR_CHAR); + } + if (!ExcludeFilter(excludesMap, formatPath)) { + WriteFileList(statFile, fileStat, paras); + } +} + +bool StorageManagerServie::AddPathMapForPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &phyPath, + std::map &pathMap) +{ + std::string physicalPrefixEl1 = PHY_APP + EL1 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + + bundleName + FILE_SEPARATOR_CHAR; + std::string physicalPrefixEl2 = PHY_APP + EL2 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + + bundleName + FILE_SEPARATOR_CHAR; + if (phyPath.find(physicalPrefixEl1) == 0) { + std::string relatePath = phyPath.substr(physicalPrefixEl1.size()); + pathMap.insert({phyPath, BASE_EL1 + relatePath}); + } else if (phyPath.find(physicalPrefixEl2) == 0) { + std::string relatePath = phyPath.substr(physicalPrefixEl2.size()); + pathMap.insert({phyPath, BASE_EL2 + relatePath}); + } else { + LOGE("Invalid phyiscal path"); + return false; + } + return true; +} + +uint32_t CheckOverLongPath(const std::string &path) +{ + uint32_t len = path.length(); + if (len >= PATH_MAX_LEN) { + size_t found = path.find_last_of('/'); + std::string sub = path.substr(found + 1); + LOGE("Path over long, length:%{public}d, fileName:%{public}s.", len, sub.c_str()); + } + return len; +} + +} // namespace OHOS::FileManagement::Backup \ No newline at end of file -- Gitee From 0eb6a91b321ee8e08dd702c2c4f03b07ab865619 Mon Sep 17 00:00:00 2001 From: huhui Date: Fri, 30 May 2025 15:57:11 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=B4=E6=B5=8B?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huhui --- .../backup_sa/src/module_ipc/svc_session_manager.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/services/backup_sa/src/module_ipc/svc_session_manager.cpp b/services/backup_sa/src/module_ipc/svc_session_manager.cpp index 8a79ef982..a575474a1 100644 --- a/services/backup_sa/src/module_ipc/svc_session_manager.cpp +++ b/services/backup_sa/src/module_ipc/svc_session_manager.cpp @@ -1197,7 +1197,11 @@ bool SvcSessionManager::CleanAndCheckIfNeedWait(ErrCode &ret, std::vector lock(lock_); for (auto it = impl_.backupExtNameMap.begin(); it != impl_.backupExtNameMap.end();) { + HILOGI("ExtensionAbility bundleName: %{public}s, schedAction: %{public}d, isInPublishFile: %{public}d", + it->first.c_str(), it->second.schedAction, it->second.isInPublishFile); if (it->second.schedAction == BConstants::ServiceSchedAction::WAIT) { + HILOGI("Clear extensionAbility bundleName: %{public}s, schedAction: %{public}d", + it->first.c_str(), it->second.schedAction); it = impl_.backupExtNameMap.erase(it); } else if (it->second.schedAction == BConstants::ServiceSchedAction::START || (it->second.schedAction == BConstants::ServiceSchedAction::RUNNING && !it->second.isInPublishFile)) { @@ -1208,14 +1212,14 @@ bool SvcSessionManager::CleanAndCheckIfNeedWait(ErrCode &ret, std::vectorsecond.backUpConnection; if (backUpConnection == nullptr) { - HILOGE("Clear session error, backUpConnection is empty"); + HILOGE("Clear session error, backUpConnection is empty, bundleName: %{public}s", it->first.c_str()); it = impl_.backupExtNameMap.erase(it); continue; } auto proxy = backUpConnection->GetBackupExtProxy(); // start action if (proxy == nullptr) { - HILOGE("Clear session error, backUpConnection is empty"); + HILOGE("Clear session error, BackupExtProxy is empty, bundleName: %{public}s", it->first.c_str()); backUpConnection->DisconnectBackupExtAbility(); it = impl_.backupExtNameMap.erase(it); continue; @@ -1231,6 +1235,7 @@ bool SvcSessionManager::CleanAndCheckIfNeedWait(ErrCode &ret, std::vectorDisconnectBackupExtAbility(); + HILOGI("Disconnect, extensionAbility, bundleName: %{public}s", it->first.c_str()); it = impl_.backupExtNameMap.erase(it); } else { ++it; -- Gitee From 05c540c4c2933ecb14c1176e2b2d165138800fb1 Mon Sep 17 00:00:00 2001 From: huhui Date: Fri, 30 May 2025 09:27:40 +0000 Subject: [PATCH 3/3] Revert "test pr" This reverts commit 3107ce08ccb8b927ad82874c4ae0025bf0502375. --- .../module_external/storage_manager_service.h | 181 ---- .../storage_manager_service.cpp | 836 ------------------ 2 files changed, 1017 deletions(-) delete mode 100644 services/backup_sa/include/module_external/storage_manager_service.h delete mode 100644 services/backup_sa/src/module_external/storage_manager_service.cpp diff --git a/services/backup_sa/include/module_external/storage_manager_service.h b/services/backup_sa/include/module_external/storage_manager_service.h deleted file mode 100644 index 3fda6fa47..000000000 --- a/services/backup_sa/include/module_external/storage_manager_service.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H -#define OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H - -#include -#include -#include - -#include "istorage_manager.h" -#include "datashare_abs_result_set.h" -#include "datashare_helper.h" -#include "datashare_predicates.h" - -namespace OHOS::FileManagement::Backup { -const uint64_t PATH_MAX_LEN = 4096; -const std::string PHY_APP = "/data/app/"; -const std::string WILDCARD_DEFAULT_INCLUDE = "*"; -constexpr char FILE_SEPARATOR_CHAR = '/'; -const std::string BASE_EL1 = "/data/storage/el1/base/"; -const std::string BASE_EL2 = "/data/storage/el2/base/"; -const std::string EL1 = "el1"; -const std::string EL2 = "el2"; -const std::string BASE = "/base/"; -const std::string Backup_INCLUDE = "INCLUDES"; -const std::string Backup_EXCLUDE = "EXCLUDES"; -const std::string BACKUP_PATH_PREFIX = "/data/service/el2"; -const std::string BACKUP_PATH_SURFFIX = "/backup/backup_sa/"; -const std::string BACKUP_INCEXC_SYMBOL = "incExc_"; -const std::string BACKUP_STAT_SYMBOL = "stat_"; -const std::string DEFAULT_INCLUDE_PATH_IN_HAP_FILES = "files"; -const std::string DEFAULT_INCLUDE_PATH_IN_HAP_DATABASE = "database"; -const std::string DEFAULT_INCLUDE_PATH_IN_HAP_PREFERENCE = "preferences"; -const std::string MEDIA_CLOUD_SAND_PREFIX = "/storage/cloud"; -const std::string MEDIA_SAND_PREFIX = "/storage/media"; -const std::string URI_PREFIX = "file://"; -const std::string NORMAL_SAND_PREFIX = "/data/storage/"; -const std::string FILE_SAND_PREFIX = "/storage/Users"; -const std::string FILE_AUTHORITY = "docs"; -const std::string DEFAULT_PATH_WITH_WILDCARD = "/haps/*"; -const std::string FILE_CONTENT_SEPARATOR = ";"; -const char LINE_SEP = '\n'; -const std::string VER_10_LINE1 = "version=1.0&attrNum=8"; -const std::string VER_10_LINE2 = "path;mode;dir;size;mtime;hash;inIncremental;encodeFlag"; -const std::string MEDIALIBRARY_DATA_URI = "datashare:///media"; -const std::string MEDIA_QUERYOPRN_QUERYVOLUME = "query_media_volume"; -const std::string MEDIA_TYPE = "media"; -const std::string FILE_TYPE = "file"; -const std::int32_t E_OK = 0; -constexpr int32_t E_ERR = -1; -constexpr int32_t STORAGE_SERVICE_SYS_CAP_TAG = 13600000; -constexpr const char *QUOTA_DEVICE_DATA_PATH = "/data"; -constexpr const char *PROC_MOUNTS_PATH = "/proc/mounts"; -constexpr const char *DEV_BLOCK_PATH = "/dev/block"; -const std::int32_t E_SA_IS_NULLPTR = STORAGE_SERVICE_SYS_CAP_TAG + 12; -const std::int32_t E_REMOTE_IS_NULLPTR = STORAGE_SERVICE_SYS_CAP_TAG + 13; -const std::int32_t E_MEDIALIBRARY_ERROR = STORAGE_SERVICE_SYS_CAP_TAG + 1202; -const std::int32_t E_QUERY = STORAGE_SERVICE_SYS_CAP_TAG + 1206; -const std::int32_t E_GETROWCOUNT = STORAGE_SERVICE_SYS_CAP_TAG + 1207; -const std::int32_t E_SYS_KERNEL_ERR = STORAGE_SERVICE_SYS_CAP_TAG + 8; -const int32_t E_SYS_ERR = -1; -const int MEDIA_TYPE_IMAGE = 1; -const int MEDIA_TYPE_VIDEO = 2; -const int MEDIA_TYPE_AUDIO = 3; -const int32_t GET_DATA_SHARE_HELPER_TIMES = 5; -const int UID_FILE_MANAGER = 1006; -const int32_t USER_ID_BASE = 200000; -static std::map mQuotaReverseMounts; - - -struct FileStat { - std::string filePath; - int64_t fileSize; - int64_t lastUpdateTime; - int32_t mode; - bool isDir; - bool isIncre; -}; -struct BundleStatsParas { - uint32_t userId; - std::string &bundleName; - int64_t lastBackupTime; - int64_t fileSizeSum; - int64_t incFileSizeSum; -}; - -class StorageManagerServie { -public: - StorageManagerServie(); - ~StorageManagerServie(); - static StorageManagerServie &GetInstance(); - /** - * @brief Get the bundle stats object - * - * @param bundleName bundle name - */ - StorageManager::BundleStats GetBundleStats(const std::string &bundleName); - - /** - * @brief Get the user storage stats object - * - * @param bundleName bundle name - * @param userId user id - */ - int32_t GetUserStorageStatsByType(int32_t userId, StorageManager::StorageStats &storageStats, std::string type); - - /** - * @brief update memory para - * - * @param size para data - */ - int32_t UpdateMemoryPara(int32_t size, int32_t oldSize); - - /** - * @brief Get the user storage stats object - * - * @param userId user id - * @param bundleNames - * @param incrementalBackTimes - * @param pkgFileSizes bundle backup file size - * @param incPkgFileSizes Incremental bundle backup file size - */ - int32_t GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, - const std::vector &incrementalBackTimes, std::vector &pkgFileSizes, - std::vector &incPkgFileSizes); -private: - void GetBundleStatsForIncreaseEach(uint32_t userId, std::string &bundleName, int64_t lastBackupTime, - std::vector &pkgFileSizes, std::vector &incPkgFileSizes); - std::tuple, std::vector> ReadIncludesExcludesPath( - const std::string &bundleName, const int64_t lastBackupTime, const uint32_t userId); - void DealWithIncludeFiles(const BundleStatsParas ¶s, const std::vector &includes, - std::vector &phyIncludes, std::map& pathMap); - void ConvertSandboxRealPath(const uint32_t userId, const std::string &bundleName, - const std::string &sandboxPathStr, std::vector &realPaths, - std::map& pathMap); - void DeduplicationPath(std::vector &configPaths); - void ScanExtensionPath(BundleStatsParas ¶s, - const std::vector &includes, const std::vector &excludes, - std::map &pathMap, std::ofstream &statFile); - void RecognizeSandboxWildCard(const uint32_t userId, const std::string &bundleName, - const std::string &sandboxPathStr, std::vector &phyIncludes, - std::map& pathMap); - void SetExcludePathMap(std::string &excludePath, std::map &excludesMap); - std::tuple CheckIfDirForIncludes(const std::string &path, BundleStatsParas ¶s, - std::map &pathMap, std::ofstream &statFile, std::map &excludesMap); - bool GetIncludesFileStats(const std::string &dir, BundleStatsParas ¶s, - std::map &pathMap, - std::ofstream &statFile, std::map &excludesMap); - bool GetPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &includeWildCard, - std::vector &includePathList, std::map &pathMap); - bool ExcludeFilter(std::map &excludesMap, const std::string &path); - void WriteFileList(std::ofstream &statFile, struct FileStat fileStat, BundleStatsParas ¶s); - bool AddOuterDirIntoFileStat(const std::string &dir, BundleStatsParas ¶s, const std::string &sandboxDir, - std::ofstream &statFile, std::map &excludesMap); - std::string PhysicalToSandboxPath(const std::string &dir, const std::string &sandboxDir, const std::string &path); - void InsertStatFile(const std::string &path, struct FileStat fileStat, - std::ofstream &statFile, std::map &excludesMap, BundleStatsParas ¶s); - bool AddPathMapForPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &phyPath, - std::map &pathMap); - uint32_t CheckOverLongPath(const std::string &path); - int32_t GetMediaStorageStats(StorageManager::StorageStats &storageStats); - void GetMediaTypeAndSize(const std::shared_ptr &resultSet, - StorageManager::StorageStats &storageStats); - int32_t GetFileStorageStats(int32_t userId, StorageManager::StorageStats &storageStats); - bool InitialiseQuotaMounts(); -} -} // namespace OHOS::FileManagement::Backup -#endif // OHOS_FILEMGMT_BACKUP_STORAGE_MGR_SERVICE_H \ No newline at end of file diff --git a/services/backup_sa/src/module_external/storage_manager_service.cpp b/services/backup_sa/src/module_external/storage_manager_service.cpp deleted file mode 100644 index 3ead3522e..000000000 --- a/services/backup_sa/src/module_external/storage_manager_service.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - #include "module_external/storage_manager_service.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "b_error/b_error.h" -#include "b_resources/b_constants.h" -#include "filemgmt_helper.h" -#include "sandbox_helper.h" -#include "file_uri.h" - -#include -#include - -namespace OHOS::FileManagement::Backup { -using namespace std; -std:: recursive_mutex mMountsLock; -// -// -// -// -// -// - -static bool PathSortFunc(const std::string &path1, const std::string &path2) -{ - return path1 < path2; -} - -static std::string GetQuotaSrcMountPath(const std::string &target) -{ - std::lock_guard lock(mMountsLock); - if (mQuotaReverseMounts.find(target) != mQuotaReverseMounts.end()) { - return mQuotaReverseMounts[target]; - } else { - return ""; - } -} - -StorageManagerServie::StorageManagerServie() -{ -} -StorageManagerServie::~StorageManagerServie() -{ -} - -StorageManagerServie &StorageManagerServie::GetInstance() -{ - static StorageManagerServie instance{}; - return instance; -} - -StorageManager::BundleStats StorageManagerServie::GetBundleStats(const string &bundleName) -{ - StorageManager::BundleStats bundleStats; - return bundleStats; -} - -int32_t StorageStatusService::GetUserStorageStatsByType(int32_t userId, StorageStats &storageStats, std::string type) -{ - // - storageStats.video_ = 0; - storageStats.image_ = 0; - storageStats.file_ = 0; - int32_t err = E_OK; - if (type == MEDIA_TYPE) { - LOGI("GetUserStorageStatsByType media"); - err = GetMediaStorageStats(storageStats); - } else if (type == FILE_TYPE) { - LOGI("GetUserStorageStatsByType file"); - err = GetFileStorageStats(userId, storageStats); - } else { - LOGI("GetUserStorageStatsByType type: %{public}s", type.c_str()); - } - return err; -} - -int32_t StorageManagerServie::GetMediaStorageStats(StorageStats &storageStats) -{ - LOGE("GetMediaStorageStats start"); - auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (sam == nullptr) { - LOGE("StorageStatusService::GetMediaStorageStats samgr == nullptr"); - return E_SA_IS_NULLPTR; - } - auto remoteObj = sam->GetSystemAbility(FILEMANAGEMENT_BACKUP_SERVICE_SA_ID); - if (remoteObj == nullptr) { - LOGE("StorageStatusService::GetMediaStorageStats remoteObj == nullptr"); - return E_REMOTE_IS_NULLPTR; - } - int32_t tryCount = 1; - LOGE("GetMediaStorageStats start Creator"); - auto dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI); - while (dataShareHelper == nullptr && tryCount < GET_DATA_SHARE_HELPER_TIMES) { - LOGW("dataShareHelper is retrying, attempt %{public}d", tryCount); - dataShareHelper = DataShare::DataShareHelper::Creator(remoteObj, MEDIALIBRARY_DATA_URI); - tryCount++; - } - if (dataShareHelper == nullptr) { - LOGE("dataShareHelper is null!"); - return E_MEDIALIBRARY_ERROR; - } - vector columns; - Uri uri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_QUERYOPRN_QUERYVOLUME + "/" + MEDIA_QUERYOPRN_QUERYVOLUME); - DataShare::DataSharePredicates predicates; - LOGE("GetMediaStorageStats start Query"); - auto queryResultSet = dataShareHelper->Query(uri, predicates, columns); - if (queryResultSet == nullptr) { - LOGE("queryResultSet is null!"); - return E_QUERY; - } - auto count = 0; - auto ret = queryResultSet->GetRowCount(count); - if ((ret != E_OK) || (count < 0)) { - LOGE("get row count from rdb failed"); - return E_GETROWCOUNT; - } - GetMediaTypeAndSize(queryResultSet, storageStats); - dataShareHelper->Release(); - LOGE("GetMediaStorageStats end"); - return E_OK; -} - -void StorageManagerServie::GetMediaTypeAndSize(const std::shared_ptr &resultSet, StorageStats &storageStats) -{ - if (resultSet == nullptr) { - LOGE("StorageStatusService::GetMediaTypeAndSize, input resultSet is nullptr."); - return; - } - int thumbnailType = -1; - while (resultSet->GoToNextRow() == E_OK) { - int32_t index = 0; - int mediatype = 0; - int64_t size = 0; - if (resultSet->GetColumnIndex("media_type", index) || resultSet->GetInt(index, mediatype)) { - LOGE("get media_type column index or int value err."); - continue; - } - if (resultSet->GetColumnIndex("size", index) || resultSet->GetLong(index, size)) { - LOGE("get size column index or long value err."); - continue; - } - LOGI("media type: %{public}d, size: %{public}lld", mediatype, static_cast(size)); - if (mediatype == MEDIA_TYPE_IMAGE || mediatype == thumbnailType) { - storageStats.image_ += size; - } else if (mediatype == MEDIA_TYPE_AUDIO) { - storageStats.audio_ = size; - } else if (mediatype == MEDIA_TYPE_VIDEO) { - storageStats.video_ = size; - } else { - LOGD("unsupprted media_type: %{public}d", mediatype); - } - } -} - -int32_t StorageManagerServie::GetFileStorageStats(int32_t userId, StorageStats &storageStats) -{ - int32_t uid = userId * USER_ID_BASE + UID_FILE_MANAGER; - HILOGE("GetOccupiedSpaceForUid uid:%{public}d", uid); - if (InitialiseQuotaMounts() != true) { - HILOGE("Failed to initialise quota mounts"); - reutrn E_SYS_KERNEL_ERR; - } - - std::string device = ""; - for (auto it = mQuotaReverseMounts.begin(); it != mQuotaReverseMounts.end(); ++it) { - // - } - // - device = GetQuotaSrcMountPath(QUOTA_DEVICE_DATA_PATH); - if (device.empty()) { - HILOGE("skip when device no quotas present"); - return E_OK; - } - - struct dqblk dq; - // - if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid, reinterpret_cast(&dq)) != 0) { - HILOGE("Failed to get quotactl, errno : %{public}d", errno); - return E_SYS_KERNEL_ERR - } - // - storageStats.file_ = static_cast(dq.dqb_curspace); - HILOGE("GetOccupiedSpaceForUid size:%{public}s", std::tostring(storageStats.file_).c_str()); - return E_OK; - - -} - -bool StorageManagerServie::InitialiseQuotaMounts() -{ - std::lock_guard lock(mMountsLock); - mQuotaReverseMounts.clear(); - std::ifstream in(PROC_MOUNTS_PATH); - - if (!in.is_open()) { - LOGE("Failed to open mounts file"); - return false; - } - std::string source; - std::string target; - std::string ignored; - - while (in.peek() != EOF) { - std::getline(in, source, ' '); - std::getline(in, target, ' '); - std::getline(in, ignored); - // - // - // - if (source.compare(0, strlen(DEV_BLOCK_PATH), DEV_BLOCK_PATH) == 0) { - struct dqblk dq; - // - if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0, reinterpret_cast(&dq)) == 0) { - // - mQuotaReverseMounts[target] = source; - } - // - // - } - } - - return true; -} - -int32_t StorageManagerServie::UpdateMemoryPara(int32_t size, int32_t oldSize) -{ - return 0; -} - -int32_t StorageManagerServie::GetBundleStatsForIncrease(uint32_t userId, const std::vector &bundleNames, - const std::vector &incrementalBackTimes, std::vector &pkgFileSizes, - std::vector &incPkgFileSizes) -{ - LOGI("GetBundleStatsForIncrease start"); - // - if (bundleNames.size() != incrementalBackTimes.size()) { - LOGE("Invalid paramters, size of bundleNames should match incrementalBackTimes."); - return E_PARAMS_INVALID; - } - - for (size_t i = 0; i < bundleNames.size(); i++) { - std::string bundleName = bundleNames[i]; - int64_t lastBackupTime = incrementalBackTimes[i]; - // - GetBundleStatsForIncreaseEach(userId, bundleName, lastBackupTime, pkgFileSizes, incPkgFileSizes); - } - return E_OK; -} - -void StorageManagerServie::GetBundleStatsForIncreaseEach(uint32_t userId, std::string &bundleName, int64_t lastBackupTime, - std::vector &pkgFileSizes, std::vector &incPkgFileSizes) -{ - // - // input parameters - BundleStatsParas paras = {.userId = userId, .bundleName = bundleName, - .lastBackupTime = lastBackupTime, .fileSizeSum = 0, .incFileSizeSum = 0}; - - // obtain includes, excludes in backup extension config - auto [includes, excludes] = ReadIncludesExcludesPath(bundleName, lastBackupTime, userId); - if (includes.empty()) { - pkgFileSizes.emplace_back(0); - incPkgFileSizes.emplace_back(0); - return; - } - // physical paths - std::vector phyIncludes; - // map about sandbox path to physical path - std::map pathMap; - - // recognize physical path for include directory - DealWithIncludeFiles(paras, includes, phyIncludes, pathMap); - if (phyIncludes.empty()) { - LOGE("Incorrect convert for include sandbox path for %{private}s", bundleName.c_str()); - pkgFileSizes.emplace_back(0); - incPkgFileSizes.emplace_back(0); - return; - } - - // recognize physical path for exclude directory - std::vector phyExcludes; - for (const auto &exclude : excludes) { - std::string excludeStr = exclude; - if (excludeStr.front() != FILE_SEPARATOR_CHAR) { - excludeStr = FILE_SEPARATOR_CHAR + excludeStr; - } - // convert sandbox to physical path - ConvertSandboxRealPath(userId, bundleName, excludeStr, phyExcludes, pathMap); - } - - std::string filePath = BACKUP_PATH_PREFIX + std::to_string(userId) + BACKUP_PATH_SURFFIX + - bundleName + FILE_SEPARATOR_CHAR + BACKUP_STAT_SYMBOL + std::to_string(lastBackupTime); - // - std::ofstream statFile; - statFile.open(filePath.data(), std::ios::out | std::ios::trunc); - if (!statFile.is_open()) { - LOGE("creat file fail, errno:%{public}d.", errno); - pkgFileSizes.emplace_back(0); - incPkgFileSizes.emplace_back(0); - return; - } - statFile << VER_10_LINE1 << std::endl; - statFile << VER_10_LINE2 << std::endl; - - DeduplicationPath(phyIncludes); - ScanExtensionPath(paras, phyIncludes, phyExcludes, pathMap, statFile); - // calculate summary file sizes - pkgFileSizes.emplace_back(paras.fileSizeSum); - incPkgFileSizes.emplace_back(paras.incFileSizeSum); - LOGI("bundleName: %{public}s, size: %{public}lld", bundleName.c_str(), static_cast(paras.fileSizeSum)); - statFile.close(); -} - -std::tuple, std::vector> StorageManagerServie::ReadIncludesExcludesPath( - const std::string &bundleName, const int64_t lastBackupTime, const uint32_t userId) -{ - // - if (bundleName.empty()) { - LOGE("bundleName is empty"); - return { {}, {} }; - } - // 保存includeExclude的path - std::string filePath = BACKUP_PATH_PREFIX + std::to_string(userId) + BACKUP_PATH_SURFFIX + - bundleName + FILE_SEPARATOR_CHAR + BACKUP_INCEXC_SYMBOL + std::to_string(lastBackupTime); - // - std::ifstream incExcFile; - incExcFile.open(filePath.data()); - if (!incExcFile.is_open()) { - LOGE("Cannot open include/exclude file, fail errno:%{public}d", errno); - return { {}, {} }; - } - - std::vector includes; - std::vector excludes; - bool incOrExt = true; - while (incExcFile) { - std::string line; - std::getline(incExcFile, line); - if (line.empty()) { - LOGI("Read Complete"); - break; - } - if (line == BACKUP_INCLUDE) { - incOrExt = true; - } else if (line == BACKUP_EXCLUDE) { - incOrExt = false; - } - if (incOrExt && line != BACKUP_INCLUDE) { - includes.emplace_back(line); - } else if (!incOrExt && line != BACKUP_EXCLUDE) { - excludes.emplace_back(line); - } - } - // - // - // - // - // - // - incExcFile.close(); - return {includes, excludes}; -} - -void StorageManagerServie::DealWithIncludeFiles(const BundleStatsParas ¶s, const std::vector &includes, - std::vector &phyIncludes, std::map& pathMap) -{ - uint32_t userId = paras.userId; - std::string bundleName = paras.bundleName; - for (const auto &include : includes) { - // - std::string includeStr = include; - // - if (includeStr.front() != FILE_SEPARATOR_CHAR) { - includeStr = FILE_SEPARATOR_CHAR + includeStr; - } - if (includeStr.find(BASE_EL1 + DEFAULT_PATH_WITH_WILDCARD) == 0 || - includeStr.find(BASE_EL2 + DEFAULT_PATH_WITH_WILDCARD) == 0) { - // recognize sandbox path to physical path with wild card - RecognizeSandboxWildCard(userId, bundleName, includeStr, phyIncludes, pathMap); - if (phyIncludes.empty()) { - LOGE("DealWithIncludeFiles failed to recognize path with wildcard %{private}s", bundleName.c_str()); - continue; - } - } else { - // convert sandbox to physical path - ConvertSandboxRealPath(userId, bundleName, includeStr, phyIncludes, pathMap); - } - } -} - -void StorageManagerServie::ConvertSandboxRealPath(const uint32_t userId, const std::string &bundleName, - const std::string &sandboxPathStr, std::vector &realPaths, - std::map& pathMap) -{ - std::string uriString; - if (sandboxPathStr.find(NORMAL_SAND_PREFIX) == 0) { - // for normal hap, start with file://bundleName - uriString = URI_PREFIX + bundleName; - } else if (sandboxPathStr.find(FILE_SAND_PREFIX) == 0) { - // for public files, start with file://docs - uriString = URI_PREFIX + FILE_AUTHORITY; - } else if (sandboxPathStr.find(MEDIA_SAND_PREFIX) == 0) { - std::string physicalPath = sandboxPathStr; - physicalPath.insert(MEDIA_SAND_PREFIX.length(), FILE_SEPARATOR_CHAR + std::to_string(userId)); - realPaths.emplace_back(physicalPath); - pathMap.insert({physicalPath, sandboxPathStr}); - return; - } else if (sandboxPathStr.find(MEDIA_CLOUD_SAND_PREFIX) == 0) { - std::string physicalPath = sandboxPathStr; - physicalPath.insert(MEDIA_CLOUD_SAND_PREFIX.length(), FILE_SEPARATOR_CHAR + std::to_string(userId)); - realPaths.emplace_back(physicalPath); - pathMap.insert({physicalPath, sandboxPathStr}); - return; - } - - if (!uriString.empty()) { - std::string sandboxPathUriStr = AppFileService::SandboxHelper::Encode(sandboxPathStr); - // - uriString += sandboxPathUriStr; - // - AppFileService::ModuleFileUri::FileUri uri(uriString); - // files - std::string physicalPath; - int ret = AppFileService::SandboxHelper::GetBackupPhysicalPath(uri.ToString(), std::to_string(userId), - physicalPath); - if (ret != 0) { - LOGE("Get physical path failed with %{public}d", ret); - return; - } - // - realPaths.emplace_back(physicalPath); - pathMap.insert({physicalPath, sandboxPathStr}); - } -} - -void StorageManagerServie::DeduplicationPath(std::vector &configPaths) -{ - sort(configPaths.begin(), configPaths.end(), PathSortFunc); - auto it = unique(configPaths.begin(), configPaths.end(), [](const std::string &path1, const std::string &path2) { - return path1 == path2; - }); - configPaths.erase(it, configPaths.end()); -} - -void StorageManagerServie::ScanExtensionPath(BundleStatsParas ¶s, - const std::vector &includes, const std::vector &excludes, - std::map &pathMap, std::ofstream &statFile) -{ - std::map excludesMap; - for (auto exclude : excludes) { - SetExcludePathMap(exclude, excludesMap); - } - // all file with stats in include directory - for (const auto &includeDir : includes) { - // Check if includeDir is a file path - auto [isSucc, isDir] = CheckIfDirForIncludes(includeDir, paras, pathMap, statFile, excludesMap); - if (!isSucc) { - continue; - } - // recognize all file in include directory - if (isDir && !GetIncludesFileStats(includeDir, paras, pathMap, statFile, excludesMap)) { - LOGE("Faied to get include files for includeDir"); - } - } -} - -void StorageManagerServie::RecognizeSandboxWildCard(const uint32_t userId, const std::string &bundleName, - const std::string &sandboxPathStr, std::vector &phyIncludes, - std::map& pathMap) -{ - if (sandboxPathStr.find(BASE_EL1 + DEFAULT_PATH_WITH_WILDCARD) == 0) { - std::string physicalPrefix = PHY_APP + EL1 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + - bundleName + FILE_SEPARATOR_CHAR; - std::string relatePath = sandboxPathStr.substr(BASE_EL1.size()); - if (!GetPathWildCard(userId, bundleName, physicalPrefix + relatePath, phyIncludes, pathMap)) { - LOGE("el1 GetPathWildCard dir path invaild"); - } - } else if (sandboxPathStr.find(BASE_EL2 + DEFAULT_PATH_WITH_WILDCARD) == 0) { - std::string physicalPrefix = PHY_APP + EL2 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + - bundleName + FILE_SEPARATOR_CHAR; - std::string relatePath = sandboxPathStr.substr(BASE_EL2.size()); - if (!GetPathWildCard(userId, bundleName, physicalPrefix + relatePath, phyIncludes, pathMap)) { - LOGE("el2 GetPathWildCard dir path invaild"); - } - } -} - -void StorageManagerServie::SetExcludePathMap(std::string &excludePath, std::map &excludesMap) -{ - if (excludePath.empty()) { - LOGE("SetExcludePathMap Param failed"); - return; - } - struct stat fileStatInfo = {0}; - if (stat(excludePath.c_str(), &fileStatInfo) != 0) { - LOGE("SetExcludePathMap call stat error %{private}s, errno:%{public}d", excludePath.c_str(), errno); - return; - } - if (S_ISDIR(fileStatInfo.st_mode)) { - if (excludePath.back() != FILE_SEPARATOR_CHAR) { - excludePath.push_back(FILE_SEPARATOR_CHAR); - } - excludesMap.insert({excludePath, true}); - } else { - excludesMap.insert({excludePath, false}); - } -} - -std::tuple StorageManagerServie::CheckIfDirForIncludes(const std::string &path, BundleStatsParas ¶s, - std::map &pathMap, std::ofstream &statFile, std::map &excludesMap) -{ - if (!statFile.is_open() || path.empty()) { - LOGE("CheckIfDirForIncludes Param failed"); - return {false, false}; - } - // check whether the path exists - struct stat fileStatInfo = {0}; - // - if (stat(path.c_str(), &fileStatInfo) != 0) { - LOGE("CheckIfDirForIncludes call stat error %{private}s, fail errno:%{public}d", path.c_str(), errno); - // - return {false, false}; - } - if (S_ISDIR(fileStatInfo.st_mode)) { - LOGI("%{private}s exists and is a directory", path.c_str()); - // - return {true, true}; - } else { - std::string sandboxPath = path; - auto it = pathMap.find(path); - if (it != pathMap.end()) { - sandboxPath = it->second; - } - - struct FileStat fileStat; - fileStat.filePath = sandboxPath; - fileStat.fileSize = fileStatInfo.st_size; - // mode - fileStat.mode = static_cast(fileStatInfo.st_mode); - fileStat.isDir = false; - int64_t lastUpdateTime = static_cast(fileStatInfo.st_mtime); - fileStat.lastUpdateTime = lastUpdateTime; - if (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) { - fileStat.isIncre = true; - } - if (ExcludeFilter(excludesMap, path) == false) { - WriteFileList(statFile, fileStat, paras); - } - return {true, false}; - } -} - -bool StorageManagerServie::GetIncludesFileStats(const std::string &dir, BundleStatsParas ¶s, - std::map &pathMap, - std::ofstream &statFile, std::map &excludesMap) -{ - std::string sandboxDir = dir; - auto it = pathMap.find(dir); - if (it != pathMap.end()) { - sandboxDir = it->second; - } - // stat current directory info - AddOuterDirIntoFileStat(dir, paras, sandboxDir, statFile, excludesMap); - - std::stack folderStack; - std::string filePath; - folderStack.push(dir); - // stat files and sub-directory in current directory info - while (!folderStack.empty()) { - filePath = folderStack.top(); - folderStack.pop(); - DIR *dirPtr = opendir(filePath.c_str()); - if (dirPtr == nullptr) { - LOGE("GetIncludesFileStats open file dir:%{private}s fail, errno:%{public}d", filePath.c_str(), errno); - continue; - } - if (filePath.back() != FILE_SEPARATOR_CHAR) { - filePath.push_back(FILE_SEPARATOR_CHAR); - } - - struct dirent *entry = nullptr; - while ((entry = readdir(dirPtr)) != nullptr) { - if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { - continue; - } - std::string path = filePath + entry->d_name; - struct stat fileInfo = {0}; - if (stat(path.c_str(), &fileInfo) != 0) { - LOGE("GetIncludesFileStats call stat error %{private}s, errno:%{public}d", path.c_str(), errno); - fileInfo.st_size = 0; - } - struct FileStat fileStat = {}; - fileStat.filePath = PhysicalToSandboxPath(dir, sandboxDir, path); - fileStat.fileSize = fileInfo.st_size; - CheckOverLongPath(fileStat.filePath); - // mode - fileStat.mode = static_cast(fileInfo.st_mode); - int64_t lastUpdateTime = static_cast(fileInfo.st_mtime); - fileStat.lastUpdateTime = lastUpdateTime; - fileStat.isIncre = (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) ? true : false; - if (entry->d_type == DT_DIR) { - fileStat.isDir = true; - folderStack.push(path); - } - InsertStatFile(path, fileStat, statFile, excludesMap, paras); - } - closedir(dirPtr); - } - return true; -} - -bool StorageManagerServie::GetPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &includeWildCard, - std::vector &includePathList, std::map &pathMap) -{ - size_t pos = includeWildCard.rfind(WILDCARD_DEFAULT_INCLUDE); - if (pos == std::string::npos) { - LOGE("GetPathWildCard: path should include *"); - return false; - } - std::string pathBeforeWildCard = includeWildCard.substr(0, pos); - DIR *dirPtr = opendir(pathBeforeWildCard.c_str()); - if (dirPtr == nullptr) { - // - LOGE("GetPathWildCard open file dir:%{private}s fail, errno:%{public}d", pathBeforeWildCard.c_str(), errno); - return false; - } - struct dirent *entry = nullptr; - std::vector subDirs; - while ((entry = readdir(dirPtr)) != nullptr) { - if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { - continue; - } - std::string path = pathBeforeWildCard + entry->d_name; - if (entry->d_type == DT_DIR) { - subDirs.emplace_back(path); - } - } - closedir(dirPtr); - for (auto &subDir : subDirs) { - DIR *subDirPtr = opendir(subDir.c_str()); - if (subDirPtr == nullptr) { - LOGE("GetPathWildCard open file dir:%{private}s fail, errno:%{public}d", subDir.c_str(), errno); - return false; - } - while ((entry = readdir(subDirPtr)) != nullptr) { - if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { - continue; - } - std::string dirName = std::string(entry->d_name); - - std::string path = subDir + FILE_SEPARATOR_CHAR + entry->d_name; - if (entry->d_type == DT_DIR && (dirName == DEFAULT_INCLUDE_PATH_IN_HAP_FILES || - dirName == DEFAULT_INCLUDE_PATH_IN_HAP_DATABASE || - dirName == DEFAULT_INCLUDE_PATH_IN_HAP_PREFERENCE)) { - includePathList.emplace_back(path); - AddPathMapForPathWildCard(userId, bundleName, path, pathMap); - } - } - closedir(subDirPtr); - } - return true; -} - -bool StorageManagerServie::ExcludeFilter(std::map &excludesMap, const std::string &path) -{ - if (path.empty()) { - LOGE("ExcludeFilter Param failed"); - return true; - } - std::string formatPath = path; - for (auto exclude = excludesMap.begin(); exclude != excludesMap.end(); exclude++) { - if (exclude->second != true) { - if (formatPath.compare(exclude->first) == 0) { - return true; - } - } else { - if (formatPath.compare(0, exclude->first.size(), exclude->first) == 0) { - return true; - } - } - } - return false; -} - -void StorageManagerServie::WriteFileList(std::ofstream &statFile, struct FileStat fileStat, BundleStatsParas ¶s) -{ - if (!statFile.is_open() || fileStat.filePath.empty()) { - LOGE("WriteFileList Param failed"); - return; - } - std::string fileLine = ""; - bool encodeFlag = false; - if (fileStat.filePath.find(LINE_SEP) != std::string::npos) { - fileLine += AppFileService::SandboxHelper::Encode(fileStat.filePath) + FILE_CONTENT_SEPARATOR; - encodeFlag = true; - } else { - fileLine += fileStat.filePath + FILE_CONTENT_SEPARATOR; - } - fileLine += std::to_string(fileStat.mode) + FILE_CONTENT_SEPARATOR; - if (fileStat.isDir) { - fileLine += std::to_string(1) + FILE_CONTENT_SEPARATOR; - } else { - fileLine += std::to_string(0) + FILE_CONTENT_SEPARATOR; - } - fileLine += std::to_string(fileStat.fileSize) + FILE_CONTENT_SEPARATOR; - fileLine += std::to_string(fileStat.lastUpdateTime) + FILE_CONTENT_SEPARATOR; - fileLine += FILE_CONTENT_SEPARATOR; - if (fileStat.isIncre) { - fileLine += std::to_string(1); - } else { - fileLine += std::to_string(0); - } - fileLine += FILE_CONTENT_SEPARATOR; - if (encodeFlag) { - fileLine += std::to_string(1); - } else { - fileLine += std::to_string(0); - } - // te file line - statFile << fileLine << std::endl; - if (fileStat.isIncre) { - paras.incFileSizeSum += fileStat.fileSize; - } - paras.fileSizeSum += fileStat.fileSize; -} - -bool StorageManagerServie::AddOuterDirIntoFileStat(const std::string &dir, BundleStatsParas ¶s, const std::string &sandboxDir, - std::ofstream &statFile, std::map &excludesMap) -{ - if (!statFile.is_open() || dir.empty()) { - LOGE("AddOuterDirIntoFileStat Param failed"); - return false; - } - struct stat fileInfo = {0}; - if (stat(dir.c_str(), &fileInfo) != 0) { - LOGE("AddOuterDirIntoFileStat call stat error %{private}s, fail errno:%{public}d", dir.c_str(), errno); - return false; - } - struct FileStat fileStat = {}; - fileStat.filePath = PhysicalToSandboxPath(dir, sandboxDir, dir); - fileStat.fileSize = fileInfo.st_size; - // - // mode - fileStat.mode = static_cast(fileInfo.st_mode); - int64_t lastUpdateTime = static_cast(fileInfo.st_mtime); - fileStat.lastUpdateTime = lastUpdateTime; - fileStat.isIncre = (paras.lastBackupTime == 0 || lastUpdateTime > paras.lastBackupTime) ? true : false; - fileStat.isDir = true; - std::string formatPath = dir; - if (formatPath.back() != FILE_SEPARATOR_CHAR) { - formatPath.push_back(FILE_SEPARATOR_CHAR); - } - if (ExcludeFilter(excludesMap, formatPath) == false) { - WriteFileList(statFile, fileStat, paras); - } - return true; -} - -std::string StorageManagerServie::PhysicalToSandboxPath(const std::string &dir, const std::string &sandboxDir, - const std::string &path) -{ - std::size_t dirPos = dir.size(); - std::string pathSurffix = path.substr(dirPos); - return sandboxDir + pathSurffix; -} - -void StorageManagerServie::InsertStatFile(const std::string &path, struct FileStat fileStat, - std::ofstream &statFile, std::map &excludesMap, BundleStatsParas ¶s) -{ - if (!statFile.is_open() || path.empty()) { - LOGE("InsertStatFile Param failed"); - return; - } - std::string formatPath = path; - if (fileStat.isDir == true && formatPath.back() != FILE_SEPARATOR_CHAR) { - formatPath.push_back(FILE_SEPARATOR_CHAR); - } - if (!ExcludeFilter(excludesMap, formatPath)) { - WriteFileList(statFile, fileStat, paras); - } -} - -bool StorageManagerServie::AddPathMapForPathWildCard(uint32_t userId, const std::string &bundleName, const std::string &phyPath, - std::map &pathMap) -{ - std::string physicalPrefixEl1 = PHY_APP + EL1 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + - bundleName + FILE_SEPARATOR_CHAR; - std::string physicalPrefixEl2 = PHY_APP + EL2 + FILE_SEPARATOR_CHAR + std::to_string(userId) + BASE + - bundleName + FILE_SEPARATOR_CHAR; - if (phyPath.find(physicalPrefixEl1) == 0) { - std::string relatePath = phyPath.substr(physicalPrefixEl1.size()); - pathMap.insert({phyPath, BASE_EL1 + relatePath}); - } else if (phyPath.find(physicalPrefixEl2) == 0) { - std::string relatePath = phyPath.substr(physicalPrefixEl2.size()); - pathMap.insert({phyPath, BASE_EL2 + relatePath}); - } else { - LOGE("Invalid phyiscal path"); - return false; - } - return true; -} - -uint32_t CheckOverLongPath(const std::string &path) -{ - uint32_t len = path.length(); - if (len >= PATH_MAX_LEN) { - size_t found = path.find_last_of('/'); - std::string sub = path.substr(found + 1); - LOGE("Path over long, length:%{public}d, fileName:%{public}s.", len, sub.c_str()); - } - return len; -} - -} // namespace OHOS::FileManagement::Backup \ No newline at end of file -- Gitee