From 45c71dfeec7c7716555706b56bb7fd0d2b412bae Mon Sep 17 00:00:00 2001 From: hunili Date: Wed, 3 Apr 2024 11:24:21 +0800 Subject: [PATCH] Rebuild Publishfile interface Signed-off-by: hunili --- .../native/backup_ext/include/ext_extension.h | 22 ++- .../native/backup_ext/src/ext_extension.cpp | 157 ++++++++++++------ .../backup_ext/src/ext_extension_stub.cpp | 14 +- .../backup_kit_inner/impl/i_extension.h | 4 +- .../backup_sa/include/module_ipc/service.h | 1 + .../include/module_ipc/svc_extension_proxy.h | 4 +- services/backup_sa/src/module_ipc/service.cpp | 30 +++- .../src/module_ipc/service_incremental.cpp | 14 +- .../svc_extension_incremental_proxy.cpp | 7 +- .../src/module_ipc/svc_extension_proxy.cpp | 7 +- tools/backup_tool/include/tools_op.h | 12 ++ tools/backup_tool/src/tools_op.cpp | 42 +++++ .../src/tools_op_incremental_restore.cpp | 37 ++++- .../tools_op_incremental_restore_async.cpp | 36 +++- tools/backup_tool/src/tools_op_restore.cpp | 37 ++++- .../src/tools_op_restore_async.cpp | 39 ++++- utils/include/b_error/b_error.h | 2 + 17 files changed, 370 insertions(+), 95 deletions(-) diff --git a/frameworks/native/backup_ext/include/ext_extension.h b/frameworks/native/backup_ext/include/ext_extension.h index fc6b406cd..9a21d33d7 100644 --- a/frameworks/native/backup_ext/include/ext_extension.h +++ b/frameworks/native/backup_ext/include/ext_extension.h @@ -24,6 +24,7 @@ #include #include "b_json/b_json_entity_extension_config.h" +#include "b_json/b_json_entity_ext_manage.h" #include "b_json/b_report_entity.h" #include "ext_backup_js.h" #include "ext_extension_stub.h" @@ -32,15 +33,19 @@ #include "unique_fd.h" namespace OHOS::FileManagement::Backup { +struct PublishModeRecoder { + bool isCalled_ = false; + bool isNewMode_ = true; +}; class BackupExtExtension : public ExtExtensionStub { public: UniqueFd GetFileHandle(const std::string &fileName) override; ErrCode HandleClear() override; - ErrCode PublishFile(const std::string &fileName) override; + ErrCode PublishFile(const std::string &fileName, bool isSaCalled) override; ErrCode HandleBackup() override; ErrCode HandleRestore() override; ErrCode GetIncrementalFileHandle(const std::string &fileName) override; - ErrCode PublishIncrementalFile(const std::string &fileName) override; + ErrCode PublishIncrementalFile(const std::string &fileName, bool isSaCalled) override; ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override; std::tuple GetIncrementalBackupFileHandle() override; ErrCode GetBackupInfo(std::string &result) override; @@ -117,7 +122,7 @@ private: * @brief Executing Restoration Tasks Asynchronously * */ - void AsyncTaskRestore(); + void AsyncTaskRestore(std::set fileSet, const std::vector extManageInfo); /** * @brief Executing Incremental Restoration Tasks Asynchronously @@ -175,12 +180,23 @@ private: * @brief get callbackEx for execute appDone */ std::function AppDoneCallbackEx(wptr obj); + + /** + * @brief get callbackEx for execute appDone + */ + bool DealBundleExtProcess(const string &fileName); + + /** + * @brief verify publishfile mode + */ + bool VerifyPublishFileMode(bool isNewMode); private: std::shared_mutex lock_; std::shared_ptr extension_; std::vector tars_; std::string backupInfo_; OHOS::ThreadPool threadPool_; + PublishModeRecoder recoder_; }; } // 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 1cc2b5ccb..49f4a3b12 100644 --- a/frameworks/native/backup_ext/src/ext_extension.cpp +++ b/frameworks/native/backup_ext/src/ext_extension.cpp @@ -44,8 +44,6 @@ #include "b_filesystem/b_file.h" #include "b_filesystem/b_file_hash.h" #include "b_json/b_json_cached_entity.h" -#include "b_json/b_json_entity_ext_manage.h" -#include "b_json/b_report_entity.h" #include "b_tarball/b_tarball_factory.h" #include "filemgmt_libhilog.h" #include "hitrace_meter.h" @@ -71,6 +69,31 @@ const int64_t DEFAULT_SLICE_SIZE = 100 * 1024 * 1024; // 分片文件大小为10 const uint32_t MAX_FILE_COUNT = 6000; // 单个tar包最多包含6000个文件 } // namespace +static std::tuple> GetIdxFileData() +{ + UniqueFd idxFd(open(INDEX_FILE_RESTORE.data(), O_RDONLY)); + if (idxFd < 0) { + return {false, std::set()}; + HILOGE("Failed to open idxFile = %{private}s, err = %{public}d", INDEX_FILE_RESTORE.c_str(), errno); + } + BJsonCachedEntity cachedEntity(std::move(idxFd)); + auto cache = cachedEntity.Structuralize(); + return {true, cache.GetExtManage()}; +} + +static std::tuple> GetExtManageInfo() +{ + string filePath = BExcepUltils::Canonicalize(INDEX_FILE_RESTORE); + UniqueFd idxFd(open(filePath.data(), O_RDONLY)); + if (idxFd < 0) { + HILOGE("Failed to open cano_idxFile = %{private}s, err = %{public}d", filePath.c_str(), errno); + return {false, {}}; + } + BJsonCachedEntity cachedEntity(std::move(idxFd)); + auto cache = cachedEntity.Structuralize(); + return {true, cache.GetExtManageInfo()}; +} + void BackupExtExtension::VerifyCaller() { HILOGD("begin"); @@ -84,6 +107,10 @@ void BackupExtExtension::VerifyCaller() throw BError(BError::Codes::EXT_BROKEN_IPC, string("Calling uid is invalid, calling uid is ").append(to_string(IPCSkeleton::GetCallingUid()))); } + if (!VerifyPublishFileMode(true)) { + throw BError(BError::Codes::EXT_PUSHLISHFI_USE_ERROR, + string("Calling uid is invalid, calling uid is ").append(to_string(IPCSkeleton::GetCallingUid()))); + } } static bool CheckAndCreateDirectory(const string &filePath) @@ -360,36 +387,29 @@ static bool IsAllFileReceived(vector tars, bool isSpeicalVersion) return includes(tars.begin(), tars.end(), info.begin(), info.end()); } -ErrCode BackupExtExtension::PublishFile(const string &fileName) +ErrCode BackupExtExtension::PublishFile(const string &fileName, bool isSaCalled) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); - HILOGE("begin publish file. fileName is %{public}s", fileName.data()); + HILOGI("begin publish file. fileName is %{public}s", fileName.data()); try { if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) { throw BError(BError::Codes::EXT_INVAL_ARG, "Action is invalid"); } VerifyCaller(); - // 是否指定克隆模式 - bool isSpeicalVersion = extension_->SpeicalVersionForCloneAndCloud(); - string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); - string tarName = isSpeicalVersion ? fileName : path + fileName; - { - BExcepUltils::VerifyPath(tarName, !isSpeicalVersion); - unique_lock lock(lock_); - if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) { - throw BError(BError::Codes::EXT_INVAL_ARG, "The file does not exist"); - } - tars_.push_back(fileName); - if (!IsAllFileReceived(tars_, isSpeicalVersion)) { - return ERR_OK; - } + if (!isSaCalled && !DealBundleExtProcess(fileName)) { + return ERR_OK; } // 异步执行解压操作 if (extension_->AllowToBackupRestore()) { - AsyncTaskRestore(); + auto [resIdx, fileSet] = GetIdxFileData(); + auto [resExt, extManageInfo] = GetExtManageInfo(); + if (!resIdx || !resExt) { + DoClear(); + return BError(BError::Codes::EXT_FD_OPEN_FAILED).GetCode(); + } + AsyncTaskRestore(fileSet, extManageInfo); } - return ERR_OK; } catch (const BError &e) { DoClear(); @@ -405,7 +425,7 @@ ErrCode BackupExtExtension::PublishFile(const string &fileName) } } -ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) +ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName, bool isSaCalled) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); HILOGI("begin publish incremental file. fileName is %{private}s", fileName.data()); @@ -414,23 +434,11 @@ ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) throw BError(BError::Codes::EXT_INVAL_ARG, "Action is invalid"); } VerifyCaller(); - bool isSpeicalVersion = extension_->SpeicalVersionForCloneAndCloud(); - string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); - string tarName = isSpeicalVersion ? fileName : path + fileName; - { - BExcepUltils::VerifyPath(tarName, !isSpeicalVersion); - unique_lock lock(lock_); - if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) { - throw BError(BError::Codes::EXT_INVAL_ARG, "The file does not exist"); - } - tars_.push_back(fileName); - if (!IsAllFileReceived(tars_, isSpeicalVersion)) { - return ERR_OK; - } + if (!isSaCalled && !DealBundleExtProcess(fileName)) { + return ERR_OK; } - // 异步执行解压操作 if (extension_->AllowToBackupRestore()) { if (isSpeicalVersion) { @@ -439,7 +447,6 @@ ErrCode BackupExtExtension::PublishIncrementalFile(const string &fileName) AsyncTaskIncrementalRestore(); } } - return ERR_OK; } catch (const BError &e) { DoClear(); @@ -470,18 +477,15 @@ ErrCode BackupExtExtension::HandleBackup() return 0; } -static bool IsUserTar(const string &tarFile, const string &indexFile) +static bool IsUserTar(const string &tarFile, const std::vector &extManageInfo) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); if (tarFile.empty()) { return false; } - string filePath = BExcepUltils::Canonicalize(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; }); - if (iter != info.end()) { + auto iter = find_if(extManageInfo.begin(), extManageInfo.end(), + [&tarFile](const auto &item) { return item.hashName == tarFile; }); + if (iter != extManageInfo.end()) { HILOGI("tarFile:%{public}s isUserTar:%{public}d", tarFile.data(), iter->isUserTar); return iter->isUserTar; } @@ -822,8 +826,9 @@ static void DeleteBackupTars() auto cache = cachedEntity.Structuralize(); auto info = cache.GetExtManage(); auto path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); + auto [resExt, extManageInfo] = GetExtManageInfo(); for (auto &item : info) { - if (ExtractFileExt(item) != "tar" || IsUserTar(item, INDEX_FILE_RESTORE)) { + if (ExtractFileExt(item) != "tar" || IsUserTar(item, extManageInfo)) { continue; } string tarPath = path + item; @@ -843,8 +848,9 @@ static void DeleteBackupIncrementalTars() auto cache = cachedEntity.Structuralize(); auto info = cache.GetExtManage(); auto path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); + auto [resExt, extManageInfo] = GetExtManageInfo(); for (auto &item : info) { - if (ExtractFileExt(item) != "tar" || IsUserTar(item, INDEX_FILE_RESTORE)) { + if (ExtractFileExt(item) != "tar" || IsUserTar(item, extManageInfo)) { continue; } string tarPath = path + item; @@ -866,9 +872,10 @@ static void DeleteBackupIncrementalTars() } } -void BackupExtExtension::AsyncTaskRestore() +void BackupExtExtension::AsyncTaskRestore(std::set fileSet, + const std::vector extManageInfo) { - auto task = [obj {wptr(this)}, tars {tars_}]() { + auto task = [obj {wptr(this)}, fileSet {fileSet}, extManageInfo {extManageInfo}]() { auto ptr = obj.promote(); BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have already released"); try { @@ -884,8 +891,8 @@ void BackupExtExtension::AsyncTaskRestore() return; } // 解压 - for (auto item : tars) { // 处理要解压的tar文件 - if (ExtractFileExt(item) == "tar" && !IsUserTar(item, INDEX_FILE_RESTORE)) { + for (auto item : fileSet) { // 处理要解压的tar文件 + if (ExtractFileExt(item) == "tar" && !IsUserTar(item, extManageInfo)) { ret = ptr->DoRestore(item); } } @@ -930,7 +937,7 @@ void BackupExtExtension::AsyncTaskRestore() void BackupExtExtension::AsyncTaskIncrementalRestore() { - auto task = [obj {wptr(this)}, tars {tars_}]() { + auto task = [obj {wptr(this)}]() { auto ptr = obj.promote(); BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been already released"); @@ -939,8 +946,14 @@ void BackupExtExtension::AsyncTaskIncrementalRestore() try { // 解压 int ret = ERR_OK; - for (auto item : tars) { // 处理要解压的tar文件 - if (ExtractFileExt(item) == "tar" && !IsUserTar(item, INDEX_FILE_RESTORE)) { + auto [resIdx, fileSet] = GetIdxFileData(); + auto [resExt, extManageInfo] = GetExtManageInfo(); + if (!resIdx || !resExt) { + ptr->AppIncrementalDone(static_cast(BError::Codes::EXT_FD_OPEN_FAILED)); + ptr->DoClear(); + } + for (auto item : fileSet) { // 处理要解压的tar文件 + if (ExtractFileExt(item) == "tar" && !IsUserTar(item, extManageInfo)) { ret = ptr->DoIncrementalRestore(item); } } @@ -985,7 +998,7 @@ void BackupExtExtension::AsyncTaskIncrementalRestore() void BackupExtExtension::AsyncTaskIncreRestoreSpecialVersion() { - auto task = [obj {wptr(this)}, tars {tars_}]() { + auto task = [obj {wptr(this)}]() { auto ptr = obj.promote(); BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have been already released"); @@ -1668,4 +1681,42 @@ std::function BackupExtExtension::IncrementalAppDoneCallbackEx(wptrDoClear(); }; } + +bool BackupExtExtension::DealBundleExtProcess(const string &fileName) +{ + if (fileName.empty()) { + HILOGI("New mode restore."); + return true; + } + // 是否指定克隆模式 + bool isSpeicalVersion = extension_->SpeicalVersionForCloneAndCloud(); + + string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE); + string tarName = isSpeicalVersion ? fileName : path + fileName; + { + BExcepUltils::VerifyPath(tarName, !isSpeicalVersion); + unique_lock lock(lock_); + if (find(tars_.begin(), tars_.end(), fileName) != tars_.end() || access(tarName.data(), F_OK) != 0) { + throw BError(BError::Codes::EXT_INVAL_ARG, "The file does not exist"); + } + tars_.push_back(fileName); + if (!IsAllFileReceived(tars_, isSpeicalVersion)) { + return false; + } + } + return true; +} + +bool BackupExtExtension::VerifyPublishFileMode(bool isNewMode) +{ + if (!recoder_.isCalled_) { + recoder_.isCalled_ = true; + recoder_.isNewMode_ = isNewMode; + } else { + if (recoder_.isNewMode_ != isNewMode) { + HILOGE("Incorrect use of %{pulic}s mode.", recoder_.isNewMode_? "new" : "old"); + } + } + return true; +} } // namespace OHOS::FileManagement::Backup diff --git a/frameworks/native/backup_ext/src/ext_extension_stub.cpp b/frameworks/native/backup_ext/src/ext_extension_stub.cpp index 804013fe9..3e38ebbd5 100644 --- a/frameworks/native/backup_ext/src/ext_extension_stub.cpp +++ b/frameworks/native/backup_ext/src/ext_extension_stub.cpp @@ -117,8 +117,11 @@ ErrCode ExtExtensionStub::CmdPublishFile(MessageParcel &data, MessageParcel &rep if (!data.ReadString(fileName)) { return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive fileName"); } - - ErrCode res = PublishFile(fileName); + bool isSaCalled = false; + if (!data.ReadBool(isSaCalled)) { + return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive isSaCalled"); + } + ErrCode res = PublishFile(fileName, isSaCalled); if (!reply.WriteInt32(res)) { stringstream ss; ss << "Failed to send the result " << res; @@ -161,8 +164,11 @@ ErrCode ExtExtensionStub::CmdPublishIncrementalFile(MessageParcel &data, Message if (!data.ReadString(fileName)) { return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive fileName"); } - - ErrCode res = PublishIncrementalFile(fileName); + bool isSaCalled = false; + if (!data.ReadBool(isSaCalled)) { + return BError(BError::Codes::EXT_INVAL_ARG, "Failed to receive isSaCalled"); + } + ErrCode res = PublishIncrementalFile(fileName, isSaCalled); if (!reply.WriteInt32(res)) { stringstream ss; ss << "Failed to send the result " << res; diff --git a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h index 3641d6a4a..2dd5ee04c 100644 --- a/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h +++ b/interfaces/inner_api/native/backup_kit_inner/impl/i_extension.h @@ -30,10 +30,10 @@ public: virtual UniqueFd GetFileHandle(const std::string &fileName) = 0; virtual ErrCode HandleClear() = 0; virtual ErrCode HandleBackup() = 0; - virtual ErrCode PublishFile(const std::string &fileName) = 0; + virtual ErrCode PublishFile(const std::string &fileName, bool isSaCalled) = 0; virtual ErrCode HandleRestore() = 0; virtual ErrCode GetIncrementalFileHandle(const std::string &fileName) = 0; - virtual ErrCode PublishIncrementalFile(const std::string &fileName) = 0; + virtual ErrCode PublishIncrementalFile(const std::string &fileName, bool isSaCalled) = 0; virtual ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) = 0; virtual std::tuple GetIncrementalBackupFileHandle() = 0; virtual ErrCode GetBackupInfo(std::string &result) = 0; diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index e36e9d27e..b90835117 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -232,6 +232,7 @@ private: */ void NotifyBundleInfos(std::map &bundleNameDetailMap, BJsonEntityCaps::BundleInfo restoreInfo, RestoreTypeEnum restoreType); + bool IsSaExtAbility(const BFileInfo &fileInfo); private: static sptr instance_; diff --git a/services/backup_sa/include/module_ipc/svc_extension_proxy.h b/services/backup_sa/include/module_ipc/svc_extension_proxy.h index a63a781aa..9f8cf2443 100644 --- a/services/backup_sa/include/module_ipc/svc_extension_proxy.h +++ b/services/backup_sa/include/module_ipc/svc_extension_proxy.h @@ -26,10 +26,10 @@ public: UniqueFd GetFileHandle(const std::string &fileName) override; ErrCode HandleClear() override; ErrCode HandleBackup() override; - ErrCode PublishFile(const std::string &fileName) override; + ErrCode PublishFile(const std::string &fileName, bool isSaCalled) override; ErrCode HandleRestore() override; ErrCode GetIncrementalFileHandle(const std::string &fileName) override; - ErrCode PublishIncrementalFile(const std::string &fileName) override; + ErrCode PublishIncrementalFile(const std::string &fileName, bool isSaCalled) override; ErrCode HandleIncrementalBackup(UniqueFd incrementalFd, UniqueFd manifestFd) override; std::tuple GetIncrementalBackupFileHandle() override; ErrCode GetBackupInfo(std::string &result) override; diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index 9769fe377..e6853c353 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -489,14 +489,22 @@ ErrCode Service::PublishFile(const BFileInfo &fileInfo) try { HILOGI("Begin"); VerifyCaller(IServiceReverse::Scenario::RESTORE); - - auto backUpConnection = session_->GetExtConnection(fileInfo.owner); - + wptr backUpConnection; + bool isSaCalled = true; + if (IsSaExtAbility(fileInfo)) { + // todo Get SA connectionInfo + // int saId = -1; + // saId = std::stoi(fileInfo.owner); + // backUpConnection = session_->GetExtConnection(fileInfo.owner); // saId + } else { + backUpConnection = session_->GetExtConnection(fileInfo.owner); + isSaCalled = false; + } auto proxy = backUpConnection->GetBackupExtProxy(); if (!proxy) { throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); } - ErrCode res = proxy->PublishFile(fileInfo.fileName); + ErrCode res = proxy->PublishFile(fileInfo.fileName, isSaCalled); if (res) { HILOGE("Failed to publish file for backup extension"); } @@ -1091,4 +1099,18 @@ AAFwk::Want Service::CreateConnectWant (BundleName &bundleName) want.SetParam(BConstants::EXTENSION_ACTION_PARA, static_cast(action)); return want; } + +bool Service::IsSaExtAbility(const BFileInfo &fileInfo) +{ + int len = static_cast(fileInfo.owner.size()); + if (len == 0) { + return false; + } + for (int i = 0; i < len; ++i) { + if (!isdigit(fileInfo.owner[i])) { + return false; + } + } + return true; +} } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index 2a536f8c6..ccbfe4f23 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -185,12 +185,22 @@ ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo) HILOGI("Begin"); VerifyCaller(IServiceReverse::Scenario::RESTORE); HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str()); - auto backUpConnection = session_->GetExtConnection(fileInfo.owner); + wptr backUpConnection; + bool isSaCalled = true; + if (IsSaExtAbility(fileInfo)) { + // todo Get SA connectionInfo + // int saId = -1; + // saId = std::stoi(fileInfo.owner); + // backUpConnection = session_->GetExtConnection(fileInfo.owner); // saId + } else { + backUpConnection = session_->GetExtConnection(fileInfo.owner); + isSaCalled = false; + } auto proxy = backUpConnection->GetBackupExtProxy(); if (!proxy) { throw BError(BError::Codes::SA_INVAL_ARG, "Extension backup Proxy is empty"); } - ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName); + ErrCode res = proxy->PublishIncrementalFile(fileInfo.fileName, isSaCalled); if (res) { HILOGE("Failed to publish file for backup extension"); } diff --git a/services/backup_sa/src/module_ipc/svc_extension_incremental_proxy.cpp b/services/backup_sa/src/module_ipc/svc_extension_incremental_proxy.cpp index f674f510c..d44fad1c6 100644 --- a/services/backup_sa/src/module_ipc/svc_extension_incremental_proxy.cpp +++ b/services/backup_sa/src/module_ipc/svc_extension_incremental_proxy.cpp @@ -51,7 +51,7 @@ ErrCode SvcExtensionProxy::GetIncrementalFileHandle(const string &fileName) return reply.ReadInt32(); } -ErrCode SvcExtensionProxy::PublishIncrementalFile(const string &fileName) +ErrCode SvcExtensionProxy::PublishIncrementalFile(const string &fileName, bool isSaCalled) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); HILOGI("Start"); @@ -63,7 +63,10 @@ ErrCode SvcExtensionProxy::PublishIncrementalFile(const string &fileName) BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the fileName"); return ErrCode(EPERM); } - + if (!data.WriteBool(isSaCalled)) { + BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the isSaCalled"); + return ErrCode(EPERM); + } MessageParcel reply; MessageOption option; int32_t ret = Remote()->SendRequest(static_cast(IExtensionInterfaceCode::CMD_PUBLISH_INCREMENTAL_FILE), diff --git a/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp b/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp index c753481c4..36b5e8031 100644 --- a/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp +++ b/services/backup_sa/src/module_ipc/svc_extension_proxy.cpp @@ -94,7 +94,7 @@ ErrCode SvcExtensionProxy::HandleBackup() return reply.ReadInt32(); } -ErrCode SvcExtensionProxy::PublishFile(const string &fileName) +ErrCode SvcExtensionProxy::PublishFile(const string &fileName, bool isSaCalled) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); HILOGD("Start"); @@ -107,6 +107,11 @@ ErrCode SvcExtensionProxy::PublishFile(const string &fileName) return ErrCode(EPERM); } + if (!data.WriteBool(isSaCalled)) { + BError(BError::Codes::SDK_INVAL_ARG, "Failed to send the isSaCalled"); + return ErrCode(EPERM); + } + MessageParcel reply; MessageOption option; int32_t ret = diff --git a/tools/backup_tool/include/tools_op.h b/tools/backup_tool/include/tools_op.h index 79b063c1e..ed93a026d 100644 --- a/tools/backup_tool/include/tools_op.h +++ b/tools/backup_tool/include/tools_op.h @@ -16,6 +16,7 @@ #ifndef OHOS_FILEMGMT_BACKUP_TOOLS_OP_H #define OHOS_FILEMGMT_BACKUP_TOOLS_OP_H +#include #include #include #include @@ -31,6 +32,11 @@ public: bool repeatable = false; }; + enum class PublishFileMode { + OLD, + NEW + }; + struct Descriptor { // 命令名,必填 std::vector opName; @@ -112,6 +118,12 @@ public: */ int Execute(std::map> mapArg) const; + /** + * @brief 获取dir下文件个数,用于publishfile触发时机 + * + * @return int 错误码(0 表示成功,非零表示失败) + */ + static int GetFIleNums(bool isWholeRestore = true); private: Descriptor desc_; static inline std::vector opsAvailable_; diff --git a/tools/backup_tool/src/tools_op.cpp b/tools/backup_tool/src/tools_op.cpp index 782de8c2a..b823cd308 100644 --- a/tools/backup_tool/src/tools_op.cpp +++ b/tools/backup_tool/src/tools_op.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "b_resources/b_constants.h" #include "tools_op.h" #include @@ -84,4 +85,45 @@ int ToolsOp::Execute(map> args) const } return desc_.funcExec(args); } + +int ToolsOp::GetFIleNums(bool isWholeRestore) +{ + std::string path = ""; + path = string(isWholeRestore? BConstants::BACKUP_TOOL_RECEIVE_DIR : + BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR); + DIR *dir = opendir(path.c_str()); + if (dir == nullptr) { + fprintf(stderr, "Open path error %s\n", path.c_str()); + return false; + } + struct dirent *entry; + vector bundles; + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_type == DT_DIR && (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)) { + printf("Test bundlename = %s\n", entry->d_name); + bundles.push_back(entry->d_name); + } + } + closedir(dir); + if (bundles.size() == 0) { + fprintf(stderr, "path:%s has no data\n", path.c_str()); + return false; + } + path += bundles[0]; + printf("bundle path = %s\n", path.c_str()); + dir = opendir(path.c_str()); + int num = 0; + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_type != DT_DIR || (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)) { + ++num; + } else { + continue; + } + } + if (num == 0) { + fprintf(stderr, "The path dir is empty!"); + } + closedir(dir); + return num; +} } // namespace OHOS::FileManagement::Backup diff --git a/tools/backup_tool/src/tools_op_incremental_restore.cpp b/tools/backup_tool/src/tools_op_incremental_restore.cpp index fa143196c..59d9ca775 100644 --- a/tools/backup_tool/src/tools_op_incremental_restore.cpp +++ b/tools/backup_tool/src/tools_op_incremental_restore.cpp @@ -106,6 +106,9 @@ private: public: std::atomic isAllBundelsFinished {false}; vector lastIncrementalData {}; + std::atomic fileCount_ {0}; + std::atomic fileNums_ {0}; + ToolsOp::PublishFileMode publishMode_ {ToolsOp::PublishFileMode::OLD}; }; static string GenHelpMsg() @@ -151,9 +154,18 @@ static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInf BFile::SendFile(manifestFd, fdManifest); } // 文件准备完成 - int ret = ctx->session_->PublishFile(fileInfo); - if (ret != 0) { - throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + ctx->fileCount_++; + printf("FileReady count/num = %d/%d\n", ctx->fileCount_.load(), ctx->fileNums_.load()); + if (ctx->publishMode_ == ToolsOp::PublishFileMode::OLD || ctx->fileCount_ == ctx->fileNums_) { + printf("PublishFile start."); + BFileInfo fileInfoTemp = fileInfo; + if (ctx->publishMode_ == ToolsOp::PublishFileMode::NEW) { + fileInfoTemp.fileName = ""; + } + int ret = ctx->session_->PublishFile(fileInfoTemp); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } } ctx->TryNotify(); } @@ -276,7 +288,8 @@ static int32_t InitRestoreSession(shared_ptr ctx, return 0; } -static int32_t Init(const string &pathCapFile, vector bundleNames, bool depMode, vector times) +static int32_t Init(const string &pathCapFile, + vector bundleNames, bool depMode, vector times, const ToolsOp::PublishFileMode publishMode) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); string realPath = pathCapFile; @@ -287,6 +300,8 @@ static int32_t Init(const string &pathCapFile, vector bundleNames, bool UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU)); auto ctx = make_shared(); + ctx->fileNums_ = ToolsOp::GetFIleNums(false); + ctx->publishMode_ = publishMode; int32_t ret = InitRestoreSession(ctx, bundleNames, times); if (ret != 0) { printf("Failed to init restore session error:%d\n", ret); @@ -333,7 +348,15 @@ static int g_exec(map> &mapArgToVal) mapArgToVal.find("incrementalTime") == mapArgToVal.end()) { return -EPERM; } - return Init(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], depMode, mapArgToVal["incrementalTime"]); + ToolsOp::PublishFileMode publishFileMode = ToolsOp::PublishFileMode::OLD; + if (mapArgToVal.find("publishFileMode") != mapArgToVal.end()) { + string strFlag = *(mapArgToVal["publishFileMode"].begin()); + if (strFlag == "new") { + publishFileMode = ToolsOp::PublishFileMode::NEW; + } + } + return Init(*(mapArgToVal["pathCapFile"].begin()), + mapArgToVal["bundles"], depMode, mapArgToVal["incrementalTime"], publishFileMode); } bool IncrementalRestoreRegister() @@ -355,6 +378,10 @@ bool IncrementalRestoreRegister() { .paramName = "incrementalTime", .repeatable = true, + }, + { + .paramName = "publishFileMode", + .repeatable = true, }}, .funcGenHelpMsg = GenHelpMsg, .funcExec = g_exec, diff --git a/tools/backup_tool/src/tools_op_incremental_restore_async.cpp b/tools/backup_tool/src/tools_op_incremental_restore_async.cpp index 29bfab073..9c39a4fd5 100644 --- a/tools/backup_tool/src/tools_op_incremental_restore_async.cpp +++ b/tools/backup_tool/src/tools_op_incremental_restore_async.cpp @@ -75,6 +75,9 @@ public: } shared_ptr session_ = {}; + std::atomic fileCount_ {0}; + std::atomic fileNums_ {0}; + ToolsOp::PublishFileMode publishMode_ {ToolsOp::PublishFileMode::OLD}; private: mutable condition_variable cv_; @@ -120,9 +123,18 @@ static void OnFileReady(shared_ptr ctx, const BFileInfo throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); } BFile::SendFile(fd, fdLocal); - int ret = ctx->session_->PublishFile(fileInfo); - if (ret != 0) { - throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + ctx->fileCount_++; + printf("FileReady count/num = %d/%d\n", ctx->fileCount_.load(), ctx->fileNums_.load()); + if (ctx->publishMode_ == ToolsOp::PublishFileMode::OLD || ctx->fileCount_ == ctx->fileNums_) { + printf("PublishFile start."); + BFileInfo fileInfoTemp = fileInfo; + if (ctx->publishMode_ == ToolsOp::PublishFileMode::NEW) { + fileInfoTemp.fileName = ""; + } + int ret = ctx->session_->PublishFile(fileInfoTemp); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } } } @@ -344,7 +356,8 @@ static int32_t AppendBundles(shared_ptr restore, static int32_t InitArg(const string &pathCapFile, const vector &bundleNames, const string &type, - const string &userId) + const string &userId, + const ToolsOp::PublishFileMode publishMode) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); BExcepUltils::VerifyPath(pathCapFile, false); @@ -355,6 +368,8 @@ static int32_t InitArg(const string &pathCapFile, } auto ctx = make_shared(); + ctx->publishMode_ = publishMode; + ctx->fileNums_ = ToolsOp::GetFIleNums(false); ctx->session_ = BIncrementalSessionRestoreAsync::Init(BIncrementalSessionRestoreAsync::Callbacks { .onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2, placeholders::_3), .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), @@ -377,8 +392,15 @@ static int g_exec(map> &mapArgToVal) mapArgToVal.find("restoreType") == mapArgToVal.end() || mapArgToVal.find("userId") == mapArgToVal.end()) { return -EPERM; } + ToolsOp::PublishFileMode publishFileMode = ToolsOp::PublishFileMode::OLD; + if (mapArgToVal.find("publishFileMode") != mapArgToVal.end()) { + string strFlag = *(mapArgToVal["publishFileMode"].begin()); + if (strFlag == "new") { + publishFileMode = ToolsOp::PublishFileMode::NEW; + } + } return InitArg(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], *(mapArgToVal["restoreType"].begin()), - *(mapArgToVal["userId"].begin())); + *(mapArgToVal["userId"].begin()), publishFileMode); } bool IncrementalRestoreAsyncRegister() @@ -400,6 +422,10 @@ bool IncrementalRestoreAsyncRegister() { .paramName = "userId", .repeatable = true, + }, + { + .paramName = "publishFileMode", + .repeatable = true, }}, .funcGenHelpMsg = GenHelpMsg, .funcExec = g_exec, diff --git a/tools/backup_tool/src/tools_op_restore.cpp b/tools/backup_tool/src/tools_op_restore.cpp index dbf3e3725..040115bc0 100644 --- a/tools/backup_tool/src/tools_op_restore.cpp +++ b/tools/backup_tool/src/tools_op_restore.cpp @@ -104,6 +104,9 @@ private: public: std::atomic isAllBundelsFinished {false}; + std::atomic fileCount_ {0}; + std::atomic fileNums_ {0}; + ToolsOp::PublishFileMode publishMode_ {ToolsOp::PublishFileMode::OLD}; }; static string GenHelpMsg() @@ -129,9 +132,18 @@ static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, Uniq throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); } BFile::SendFile(fd, fdLocal); - int ret = ctx->session_->PublishFile(fileInfo); - if (ret != 0) { - throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + ctx->fileCount_++; + printf("FileReady count/num = %d/%d\n", ctx->fileCount_.load(), ctx->fileNums_.load()); + if (ctx->publishMode_ == ToolsOp::PublishFileMode::OLD || ctx->fileCount_ == ctx->fileNums_) { + printf("PublishFile start."); + BFileInfo fileInfoTemp = fileInfo; + if (ctx->publishMode_ == ToolsOp::PublishFileMode::NEW) { + fileInfoTemp.fileName = ""; + } + int ret = ctx->session_->PublishFile(fileInfoTemp); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } } ctx->TryNotify(); } @@ -252,7 +264,8 @@ static int32_t InitRestoreSession(shared_ptr ctx) return 0; } -static int32_t InitPathCapFile(const string &pathCapFile, vector bundleNames, bool depMode) +static int32_t InitPathCapFile(const string &pathCapFile, + vector bundleNames, bool depMode, const ToolsOp::PublishFileMode publishMode) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); string realPath = pathCapFile; @@ -263,6 +276,8 @@ static int32_t InitPathCapFile(const string &pathCapFile, vector bundleN UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU)); auto ctx = make_shared(); + ctx->fileNums_ = ToolsOp::GetFIleNums(); + ctx->publishMode_ = publishMode; int32_t ret = InitRestoreSession(ctx); if (ret != 0) { printf("Failed to init restore session error:%d\n", ret); @@ -304,11 +319,17 @@ static int Exec(map> &mapArgToVal) string strFlag = *(mapArgToVal["depMode"].begin()); depMode = (strFlag == "true"); } - + ToolsOp::PublishFileMode publishFileMode = ToolsOp::PublishFileMode::OLD; + if (mapArgToVal.find("publishFileMode") != mapArgToVal.end()) { + string strFlag = *(mapArgToVal["publishFileMode"].begin()); + if (strFlag == "new") { + publishFileMode = ToolsOp::PublishFileMode::NEW; + } + } if (mapArgToVal.find("pathCapFile") == mapArgToVal.end() || mapArgToVal.find("bundles") == mapArgToVal.end()) { return -EPERM; } - return InitPathCapFile(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], depMode); + return InitPathCapFile(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], depMode, publishFileMode); } bool RestoreRegister() @@ -326,6 +347,10 @@ bool RestoreRegister() { .paramName = "depMode", .repeatable = false, + }, + { + .paramName = "publishFileMode", + .repeatable = true, }}, .funcGenHelpMsg = GenHelpMsg, .funcExec = Exec, diff --git a/tools/backup_tool/src/tools_op_restore_async.cpp b/tools/backup_tool/src/tools_op_restore_async.cpp index 1ced7f9a3..3ed10eef8 100644 --- a/tools/backup_tool/src/tools_op_restore_async.cpp +++ b/tools/backup_tool/src/tools_op_restore_async.cpp @@ -75,6 +75,9 @@ public: } shared_ptr session_ = {}; + std::atomic fileCount_ {0}; + std::atomic fileNums_ {0}; + ToolsOp::PublishFileMode publishMode_ {ToolsOp::PublishFileMode::OLD}; private: mutable condition_variable cv_; @@ -114,9 +117,18 @@ static void OnFileReady(shared_ptr ctx, const BFileInfo &fileInfo, throw BError(BError::Codes::TOOL_INVAL_ARG, generic_category().message(errno)); } BFile::SendFile(fd, fdLocal); - int ret = ctx->session_->PublishFile(fileInfo); - if (ret != 0) { - throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + ctx->fileCount_++; + printf("FileReady count/num = %d/%d\n", ctx->fileCount_.load(), ctx->fileNums_.load()); + if (ctx->publishMode_ == ToolsOp::PublishFileMode::OLD || ctx->fileCount_ == ctx->fileNums_) { + printf("PublishFile start."); + BFileInfo fileInfoTemp = fileInfo; + if (ctx->publishMode_ == ToolsOp::PublishFileMode::NEW) { + fileInfoTemp.fileName = ""; + } + int ret = ctx->session_->PublishFile(fileInfoTemp); + if (ret != 0) { + throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error"); + } } } @@ -328,7 +340,8 @@ static int32_t AppendBundles(shared_ptr restore, static int32_t InitArg(const string &pathCapFile, const vector &bundleNames, const string &type, - const string &userId) + const string &userId, + const ToolsOp::PublishFileMode publishMode) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Init"); BExcepUltils::VerifyPath(pathCapFile, false); @@ -339,6 +352,8 @@ static int32_t InitArg(const string &pathCapFile, } auto ctx = make_shared(); + ctx->fileNums_ = ToolsOp::GetFIleNums(); + ctx->publishMode_ = publishMode; ctx->session_ = BSessionRestoreAsync::Init(BSessionRestoreAsync::Callbacks { .onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2), .onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2), @@ -361,8 +376,15 @@ static int Exec(map> &mapArgToVal) mapArgToVal.find("restoreType") == mapArgToVal.end() || mapArgToVal.find("userId") == mapArgToVal.end()) { return -EPERM; } + ToolsOp::PublishFileMode publishFileMode = ToolsOp::PublishFileMode::OLD; + if (mapArgToVal.find("publishFileMode") != mapArgToVal.end()) { + string strFlag = *(mapArgToVal["publishFileMode"].begin()); + if (strFlag == "new") { + publishFileMode = ToolsOp::PublishFileMode::NEW; + } + } return InitArg(*(mapArgToVal["pathCapFile"].begin()), mapArgToVal["bundles"], *(mapArgToVal["restoreType"].begin()), - *(mapArgToVal["userId"].begin())); + *(mapArgToVal["userId"].begin()), publishFileMode); } bool RestoreAsyncRegister() @@ -384,7 +406,12 @@ bool RestoreAsyncRegister() { .paramName = "userId", .repeatable = true, - }}, + }, + { + .paramName = "publishFileMode", + .repeatable = true, + } + }, .funcGenHelpMsg = GenHelpMsg, .funcExec = Exec, }}); diff --git a/utils/include/b_error/b_error.h b/utils/include/b_error/b_error.h index 6b6f0a222..0e6873cc3 100644 --- a/utils/include/b_error/b_error.h +++ b/utils/include/b_error/b_error.h @@ -87,6 +87,8 @@ public: EXT_FORBID_BACKUP_RESTORE = 0x5006, EXT_BACKUP_PACKET_ERROR = 0x5007, EXT_METHOD_NOT_EXIST = 0x5008, + EXT_FD_OPEN_FAILED = 0x5009, + EXT_PUSHLISHFI_USE_ERROR = 0x500a }; enum BackupErrorCode { -- Gitee