PublishFile rebuild

issue: https://gitee.com/openharmony/filemanagement_app_file_service/issues/I9EIIW
Signed-off-by: hunili <lihucheng2@huawei.com>
This commit is contained in:
hunili 2024-04-16 13:04:09 +08:00
parent 78224ccbb3
commit cfd68acc03
13 changed files with 265 additions and 146 deletions

View File

@ -24,6 +24,7 @@
#include <sys/stat.h>
#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"
@ -83,9 +84,8 @@ private:
/**
* @brief incremental restore
*
* @param fileName name of the file that to be untar
*/
int DoIncrementalRestore(const string &fileName);
int DoIncrementalRestore();
/** @brief clear backup restore data */
void DoClear();
@ -117,7 +117,7 @@ private:
* @brief Executing Restoration Tasks Asynchronously
*
*/
void AsyncTaskRestore();
void AsyncTaskRestore(std::set<std::string> fileSet, const std::vector<ExtManageInfo> extManageInfo);
/**
* @brief Executing Incremental Restoration Tasks Asynchronously
@ -178,7 +178,6 @@ private:
private:
std::shared_mutex lock_;
std::shared_ptr<ExtBackup> extension_;
std::vector<std::string> tars_;
std::string backupInfo_;
OHOS::ThreadPool threadPool_;
};

View File

@ -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::set<std::string> GetIdxFileData()
{
UniqueFd idxFd(open(INDEX_FILE_RESTORE.data(), O_RDONLY));
if (idxFd < 0) {
HILOGE("Failed to open idxFile = %{private}s, err = %{public}d", INDEX_FILE_RESTORE.c_str(), errno);
return std::set<std::string>();
}
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(std::move(idxFd));
auto cache = cachedEntity.Structuralize();
return cache.GetExtManage();
}
static std::vector<ExtManageInfo> 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 {};
}
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(std::move(idxFd));
auto cache = cachedEntity.Structuralize();
return cache.GetExtManageInfo();
}
void BackupExtExtension::VerifyCaller()
{
uint32_t tokenCaller = IPCSkeleton::GetCallingTokenID();
@ -326,45 +349,7 @@ static ErrCode BigFileReady(sptr<IService> proxy)
return ret;
}
static bool IsAllFileReceived(vector<string> tars, bool isSpeicalVersion)
{
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
// 是否已收到索引文件
HILOGI("Start check All file is received");
if (isSpeicalVersion) {
HILOGI("Check if manage.json is received for SpeicalVersion.");
string manageFileName = INDEX_FILE_RESTORE;
if (manageFileName.front() == BConstants::FILE_SEPARATOR_CHAR) {
manageFileName = manageFileName.substr(1);
}
if (find(tars.begin(), tars.end(), manageFileName) == tars.end()) {
return false;
}
} else {
HILOGI("Check if manage.json is received.");
if (find(tars.begin(), tars.end(), string(BConstants::EXT_BACKUP_MANAGE)) == tars.end()) {
return false;
}
}
// 获取索引文件内容
HILOGI("Start Parse manage.json file");
BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(UniqueFd(open(INDEX_FILE_RESTORE.data(), O_RDONLY)));
auto cache = cachedEntity.Structuralize();
set<string> info = cache.GetExtManage();
// 从数量上判断是否已经全部收到
if (tars.size() <= info.size()) {
HILOGE("tars count is not equals info count");
return false;
}
HILOGI("compare tars and info, tars size:%zu, info size:%zu", tars.size(), info.size());
// 逐个判断是否收到
sort(tars.begin(), tars.end());
return includes(tars.begin(), tars.end(), info.begin(), info.end());
}
ErrCode BackupExtExtension::PublishFile(const string &fileName)
ErrCode BackupExtExtension::PublishFile(const std::string &fileName)
{
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
HILOGI("Begin publish file. fileName is %{public}s", fileName.data());
@ -373,26 +358,9 @@ ErrCode BackupExtExtension::PublishFile(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<shared_mutex> 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)) {
HILOGE("Check all file is received failed");
return ERR_OK;
}
}
// 异步执行解压操作
if (extension_->AllowToBackupRestore()) {
AsyncTaskRestore();
AsyncTaskRestore(GetIdxFileData(), GetExtManageInfo());
}
HILOGE("End publish file");
return ERR_OK;
@ -419,27 +387,9 @@ 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<shared_mutex> 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)) {
HILOGE("Check all files received failed");
return ERR_OK;
}
}
// 异步执行解压操作
if (extension_->AllowToBackupRestore()) {
if (isSpeicalVersion) {
if (extension_->SpeicalVersionForCloneAndCloud()) {
HILOGI("Create task for Incremental SpecialVersion");
AsyncTaskIncreRestoreSpecialVersion();
} else {
@ -478,18 +428,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> &extManageInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
if (tarFile.empty()) {
return false;
}
string filePath = BExcepUltils::Canonicalize(indexFile);
BJsonCachedEntity<BJsonEntityExtManage> 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;
}
@ -611,25 +558,30 @@ static unordered_map<string, struct ReportFileInfo> GetTarIncludes(const string
return rp.GetReportInfos();
}
int BackupExtExtension::DoIncrementalRestore(const string &fileName)
int BackupExtExtension::DoIncrementalRestore()
{
HILOGI("Do incremental restore");
if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) {
return EPERM;
}
// REM: 给定version
// REM: 解压启动Extension时即挂载好的备份目录中的数据
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
string tarName = path + fileName;
auto fileSet = GetIdxFileData();
auto extManageInfo = GetExtManageInfo();
for (auto item : fileSet) { // 处理要解压的tar文件
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, extManageInfo)) {
if (extension_->GetExtensionAction() != BConstants::ExtensionAction::RESTORE) {
return EPERM;
}
// REM: 给定version
// REM: 解压启动Extension时即挂载好的备份目录中的数据
string path = string(BConstants::PATH_BUNDLE_BACKUP_HOME).append(BConstants::SA_BUNDLE_BACKUP_RESTORE);
string tarName = path + item;
// 当用户指定fullBackupOnly字段或指定版本的恢复解压目录当前在/backup/restore
if (extension_->SpeicalVersionForCloneAndCloud() || extension_->UseFullBackupOnly()) {
UntarFile::GetInstance().IncrementalUnPacket(tarName, path, GetTarIncludes(tarName));
} else {
UntarFile::GetInstance().IncrementalUnPacket(tarName, "/", GetTarIncludes(tarName));
// 当用户指定fullBackupOnly字段或指定版本的恢复解压目录当前在/backup/restore
if (extension_->SpeicalVersionForCloneAndCloud() || extension_->UseFullBackupOnly()) {
UntarFile::GetInstance().IncrementalUnPacket(tarName, path, GetTarIncludes(tarName));
} else {
UntarFile::GetInstance().IncrementalUnPacket(tarName, "/", GetTarIncludes(tarName));
}
HILOGI("Application recovered successfully, package path is %{public}s", tarName.c_str());
}
}
HILOGI("Application recovered successfully, package path is %{public}s", tarName.c_str());
return ERR_OK;
}
@ -833,8 +785,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 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;
@ -855,8 +808,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 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;
@ -878,9 +832,10 @@ static void DeleteBackupIncrementalTars()
}
}
void BackupExtExtension::AsyncTaskRestore()
void BackupExtExtension::AsyncTaskRestore(std::set<std::string> fileSet,
const std::vector<ExtManageInfo> extManageInfo)
{
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
auto task = [obj {wptr<BackupExtExtension>(this)}, fileSet {fileSet}, extManageInfo {extManageInfo}]() {
auto ptr = obj.promote();
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK, "Ext extension handle have already released");
try {
@ -895,8 +850,9 @@ 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);
}
}
@ -937,7 +893,7 @@ void BackupExtExtension::AsyncTaskRestore()
void BackupExtExtension::AsyncTaskIncrementalRestore()
{
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
auto task = [obj {wptr<BackupExtExtension>(this)}]() {
auto ptr = obj.promote();
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK,
"Ext extension handle have been already released");
@ -945,12 +901,7 @@ void BackupExtExtension::AsyncTaskIncrementalRestore()
"extension handle have been already released");
try {
// 解压
int ret = ERR_OK;
for (auto item : tars) { // 处理要解压的tar文件
if (ExtractFileExt(item) == "tar" && !IsUserTar(item, INDEX_FILE_RESTORE)) {
ret = ptr->DoIncrementalRestore(item);
}
}
int ret = ptr->DoIncrementalRestore();
// 恢复用户tar包以及大文件
// 目的地址是否需要拼接path(临时目录)FullBackupOnly为true并且非特殊场景
bool appendTargetPath =
@ -992,7 +943,7 @@ void BackupExtExtension::AsyncTaskIncrementalRestore()
void BackupExtExtension::AsyncTaskIncreRestoreSpecialVersion()
{
auto task = [obj {wptr<BackupExtExtension>(this)}, tars {tars_}]() {
auto task = [obj {wptr<BackupExtExtension>(this)}]() {
auto ptr = obj.promote();
BExcepUltils::BAssert(ptr, BError::Codes::EXT_BROKEN_FRAMEWORK,
"Ext extension handle have been already released");
@ -1147,7 +1098,6 @@ void BackupExtExtension::DoClear()
ForceRemoveDirectory(
string(BConstants::PATH_BUNDLE_BACKUP_HOME_EL1).append(BConstants::SA_BUNDLE_BACKUP_RESTORE));
unique_lock<shared_mutex> lock(lock_);
tars_.clear();
} catch (...) {
HILOGI("Failed to clear");
}

View File

@ -482,7 +482,10 @@ ErrCode Service::PublishFile(const BFileInfo &fileInfo)
HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__);
try {
VerifyCaller(IServiceReverse::Scenario::RESTORE);
if (!fileInfo.fileName.empty()) {
HILOGE("Forbit to use publishFile with fileName for App");
return EPERM;
}
auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
auto proxy = backUpConnection->GetBackupExtProxy();

View File

@ -181,6 +181,10 @@ ErrCode Service::PublishIncrementalFile(const BFileInfo &fileInfo)
try {
VerifyCaller(IServiceReverse::Scenario::RESTORE);
HILOGI("Start get ExtConnection, bundleName:%{public}s", fileInfo.owner.c_str());
if (!fileInfo.fileName.empty()) {
HILOGE("Forbit to use PublishIncrementalFile with fileName for App");
return EPERM;
}
auto backUpConnection = session_->GetExtConnection(fileInfo.owner);
auto proxy = backUpConnection->GetBackupExtProxy();
if (!proxy) {

View File

@ -494,11 +494,11 @@ HWTEST_F(ServiceProxyTest, SUB_Service_proxy_PublishIncrementalFile_0100, testin
.WillOnce(Return(EPERM));
string bundleName = "com.example.app2backup";
string fileName = "1.tar";
string fileName = "";
BFileInfo fileInfo(bundleName, fileName, -1);
int32_t result = proxy_->PublishIncrementalFile(fileInfo);
EXPECT_EQ(result, BError(BError::Codes::OK));
fileName = "test";
result = proxy_->PublishIncrementalFile(fileInfo);
EXPECT_NE(result, BError(BError::Codes::OK));
GTEST_LOG_(INFO) << "ServiceProxyTest-end SUB_Service_proxy_PublishIncrementalFile_0100";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Copyright (c) 2022-2024 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
@ -189,7 +189,7 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0100, testing::ext::TestSize.Level
try {
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
EXPECT_EQ(ret, BError(BError::Codes::OK));
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
ret = servicePtr_->PublishFile(fileInfo);
EXPECT_EQ(ret, BError(BError::Codes::OK));
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
@ -218,13 +218,13 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0101, testing::ext::TestSize.Level
try {
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
EXPECT_EQ(ret, BError(BError::Codes::OK));
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
ret = servicePtr_->PublishFile(fileInfo);
EXPECT_EQ(ret, BError(BError::Codes::OK));
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
fileInfo.fileName = "/data/storage/el2/restore/bundle.hap";
ret = servicePtr_->PublishFile(fileInfo);
EXPECT_EQ(ret, BError(BError::Codes::OK));
EXPECT_NE(ret, BError(BError::Codes::OK));
} catch (...) {
EXPECT_TRUE(false);
GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by PublishFile.";
@ -247,13 +247,12 @@ HWTEST_F(ServiceTest, SUB_Service_PublishFile_0102, testing::ext::TestSize.Level
try {
ErrCode ret = Init(IServiceReverse::Scenario::RESTORE);
EXPECT_EQ(ret, BError(BError::Codes::OK));
BFileInfo fileInfo {BUNDLE_NAME, FILE_NAME, 0};
BFileInfo fileInfo {BUNDLE_NAME, "", 0};
ret = servicePtr_->PublishFile(fileInfo);
EXPECT_EQ(ret, BError(BError::Codes::OK));
GTEST_LOG_(INFO) << "ServiceTest-PublishFile Branches";
string bundleName = "";
ret = servicePtr_->PublishFile(fileInfo);
EXPECT_EQ(ret, BError(BError::Codes::OK));
EXPECT_NE(ret, BError(BError::Codes::OK));
} catch (...) {
EXPECT_TRUE(false);
GTEST_LOG_(INFO) << "ServiceTest-an exception occurred by PublishFile.";

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Copyright (c) 2022-2024 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
@ -19,6 +19,8 @@
#include <gtest/gtest.h>
#include "b_resources/b_constants.h"
#include "directory_ex.h"
#include "tools_op.h"
namespace OHOS::FileManagement::Backup {
@ -149,4 +151,55 @@ HWTEST_F(ToolsOpTest, SUB_backup_tools_op_0400, testing::ext::TestSize.Level1)
}
GTEST_LOG_(INFO) << "ToolsOpTest-end SUB_backup_tools_op_0400";
}
/**
* @tc.number: SUB_backup_tools_op_0500
* @tc.name: SUB_backup_tools_op_0500
* @tc.desc: Execute分支
* @tc.size: MEDIUM
* @tc.type: FUNC
* @tc.level Level 1
* @tc.require: I6F3GV
*/
HWTEST_F(ToolsOpTest, SUB_backup_tools_op_0500, testing::ext::TestSize.Level1)
{
GTEST_LOG_(INFO) << "ToolsOpTest-begin SUB_backup_tools_op_0500";
try {
std::string bundleName = "test";
std::string wholePath = string(BConstants::BACKUP_TOOL_RECEIVE_DIR) + bundleName;
std::string incrementalpath = string(BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR) + bundleName;
if (access(incrementalpath.c_str(), F_OK) == 0) {
ForceRemoveDirectory(incrementalpath.data());
}
int result = ToolsOp::GetFIleNums(bundleName, false);
EXPECT_TRUE(result == DEFAULT_ERR_NUMBER);
if (access(wholePath.c_str(), F_OK) == 0) {
ForceRemoveDirectory(wholePath.data());
}
result = ToolsOp::GetFIleNums(bundleName, true);
EXPECT_TRUE(result == DEFAULT_ERR_NUMBER);
if (access(incrementalpath.c_str(), F_OK) != 0) {
ForceCreateDirectory(incrementalpath.data());
}
result = ToolsOp::GetFIleNums(bundleName, false);
EXPECT_TRUE(result == 0);
if (access(wholePath.c_str(), F_OK) != 0) {
ForceCreateDirectory(wholePath.data());
}
result = ToolsOp::GetFIleNums(bundleName, true);
EXPECT_TRUE(result == 0);
if (access(incrementalpath.c_str(), F_OK) == 0) {
ForceRemoveDirectory(incrementalpath.data());
}
if (access(wholePath.c_str(), F_OK) != 0) {
ForceCreateDirectory(wholePath.data());
}
} catch (...) {
EXPECT_TRUE(false);
GTEST_LOG_(INFO) << "ToolsOpTest-an exception occurred by construction.";
}
GTEST_LOG_(INFO) << "ToolsOpTest-end SUB_backup_tools_op_0500";
}
} // namespace OHOS::FileManagement::Backup

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Copyright (c) 2022-2024 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
@ -16,6 +16,7 @@
#ifndef OHOS_FILEMGMT_BACKUP_TOOLS_OP_H
#define OHOS_FILEMGMT_BACKUP_TOOLS_OP_H
#include <dirent.h>
#include <functional>
#include <map>
#include <string>
@ -23,6 +24,7 @@
#include <vector>
namespace OHOS::FileManagement::Backup {
const int DEFAULT_ERR_NUMBER = -1;
class ToolsOp {
public:
using CRefVStrView = const std::vector<std::string_view> &;
@ -112,6 +114,12 @@ public:
*/
int Execute(std::map<std::string, std::vector<std::string>> mapArg) const;
/**
* @brief dir下文件个数publishfile触发时机
*
* @return int 0
*/
static int GetFIleNums(const std::string &bundleName, bool isWholeRestore = true);
private:
Descriptor desc_;
static inline std::vector<ToolsOp> opsAvailable_;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Copyright (c) 2022-2024 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
@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "b_resources/b_constants.h"
#include "tools_op.h"
#include <regex>
@ -84,4 +85,31 @@ int ToolsOp::Execute(map<string, vector<string>> args) const
}
return desc_.funcExec(args);
}
int ToolsOp::GetFIleNums(const std::string &bundleName, bool isWholeRestore)
{
std::string path = "";
path = string(isWholeRestore? BConstants::BACKUP_TOOL_RECEIVE_DIR :
BConstants::BACKUP_TOOL_INCREMENTAL_RECEIVE_DIR) + bundleName;
struct dirent *entry;
printf("bundle path = %s\n", path.c_str());
DIR *dir = opendir(path.c_str());
if (dir == nullptr) {
fprintf(stderr, "Open path error %s\n", path.c_str());
return DEFAULT_ERR_NUMBER;
}
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!\n");
}
closedir(dir);
return num;
}
} // namespace OHOS::FileManagement::Backup

View File

@ -105,7 +105,10 @@ private:
public:
std::atomic<bool> isAllBundelsFinished {false};
mutex fileCountLock_;
vector<BIncrementalData> lastIncrementalData {};
map<string, int> fileCount_;
map<string, int> fileNums_;
};
static string GenHelpMsg()
@ -150,10 +153,21 @@ static void OnFileReady(shared_ptr<SessionRestore> 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");
std::string bundleName = fileInfo.owner;
{
unique_lock<mutex> fileLock(ctx->fileCountLock_);
++ctx->fileCount_[bundleName];
// 文件准备完成
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
printf("PublishFile start.\n");
BFileInfo fileInfoTemp = fileInfo;
fileInfoTemp.fileName = "";
int ret = ctx->session_->PublishFile(fileInfoTemp);
if (ret != 0) {
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
}
}
}
ctx->TryNotify();
}
@ -287,6 +301,10 @@ static int32_t Init(const string &pathCapFile, vector<string> bundleNames, bool
UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU));
auto ctx = make_shared<SessionRestore>();
int len = bundleNames.size();
for (int i = 0; i < len; ++i) {
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i], false);
}
int32_t ret = InitRestoreSession(ctx, bundleNames, times);
if (ret != 0) {
printf("Failed to init restore session error:%d\n", ret);

View File

@ -75,6 +75,9 @@ public:
}
shared_ptr<BIncrementalSessionRestoreAsync> session_ = {};
map<string, int> fileCount_;
map<string, int> fileNums_;
mutex fileCountLock_;
private:
mutable condition_variable cv_;
@ -120,9 +123,21 @@ static void OnFileReady(shared_ptr<InrementalSessionAsync> 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");
std::string bundleName = fileInfo.owner;
{
unique_lock<mutex> fileLock(ctx->fileCountLock_);
++ctx->fileCount_[bundleName];
// 文件准备完成
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
printf("PublishFile start.\n");
BFileInfo fileInfoTemp = fileInfo;
fileInfoTemp.fileName = "";
int ret = ctx->session_->PublishFile(fileInfoTemp);
if (ret != 0) {
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
}
}
}
}
@ -355,6 +370,10 @@ static int32_t InitArg(const string &pathCapFile,
}
auto ctx = make_shared<InrementalSessionAsync>();
int len = bundleNames.size();
for (int i = 0; i < len; ++i) {
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i], 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),

View File

@ -104,6 +104,9 @@ private:
public:
std::atomic<bool> isAllBundelsFinished {false};
map<string, int> fileCount_;
map<string, int> fileNums_;
mutex fileCountLock_;
};
static string GenHelpMsg()
@ -129,9 +132,21 @@ static void OnFileReady(shared_ptr<Session> 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");
std::string bundleName = fileInfo.owner;
{
unique_lock<mutex> fileLock(ctx->fileCountLock_);
++ctx->fileCount_[bundleName];
// 文件准备完成
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
printf("PublishFile start.\n");
BFileInfo fileInfoTemp = fileInfo;
fileInfoTemp.fileName = "";
int ret = ctx->session_->PublishFile(fileInfoTemp);
if (ret != 0) {
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
}
}
}
ctx->TryNotify();
}
@ -263,6 +278,10 @@ static int32_t InitPathCapFile(const string &pathCapFile, vector<string> bundleN
UniqueFd fd(open(realPath.data(), O_RDWR, S_IRWXU));
auto ctx = make_shared<Session>();
int len = bundleNames.size();
for (int i = 0; i < len; ++i) {
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i]);
}
int32_t ret = InitRestoreSession(ctx);
if (ret != 0) {
printf("Failed to init restore session error:%d\n", ret);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -75,6 +75,9 @@ public:
}
shared_ptr<BSessionRestoreAsync> session_ = {};
map<string, int> fileCount_;
map<string, int> fileNums_;
mutex fileCountLock_;
private:
mutable condition_variable cv_;
@ -114,9 +117,21 @@ static void OnFileReady(shared_ptr<SessionAsync> 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");
std::string bundleName = fileInfo.owner;
{
unique_lock<mutex> fileLock(ctx->fileCountLock_);
++ctx->fileCount_[bundleName];
// 文件准备完成
printf("FileReady count/num = %d/%d\n", ctx->fileCount_[bundleName], ctx->fileNums_[bundleName]);
if (ctx->fileCount_[bundleName] == ctx->fileNums_[bundleName]) {
printf("PublishFile start.\n");
BFileInfo fileInfoTemp = fileInfo;
fileInfoTemp.fileName = "";
int ret = ctx->session_->PublishFile(fileInfoTemp);
if (ret != 0) {
throw BError(BError::Codes::TOOL_INVAL_ARG, "PublishFile error");
}
}
}
}
@ -339,6 +354,10 @@ static int32_t InitArg(const string &pathCapFile,
}
auto ctx = make_shared<SessionAsync>();
int len = bundleNames.size();
for (int i = 0; i < len; ++i) {
ctx->fileNums_[bundleNames[i]] = ToolsOp::GetFIleNums(bundleNames[i]);
}
ctx->session_ = BSessionRestoreAsync::Init(BSessionRestoreAsync::Callbacks {
.onFileReady = bind(OnFileReady, ctx, placeholders::_1, placeholders::_2),
.onBundleStarted = bind(OnBundleStarted, ctx, placeholders::_1, placeholders::_2),