diff --git a/interfaces/kits/slot_info/BUILD.gn b/interfaces/kits/slot_info/BUILD.gn index f79e5b1d29359be77d0cacf256ac0d72dd9bc7b1..e513ffb5d2f6d478a628844c41d68d540e7e022d 100644 --- a/interfaces/kits/slot_info/BUILD.gn +++ b/interfaces/kits/slot_info/BUILD.gn @@ -27,8 +27,12 @@ ohos_static_library("libslotinfo") { deps = [ "${updater_path}/services/log:libupdaterlog" ] if (init_feature_ab_partition) { defines = [ "UPDATER_AB_SUPPORT" ] - external_deps = - [ "drivers_peripheral_partitionslot:libpartition_slot_manager" ] + external_deps = [ + "c_utils:utilsbase", + "drivers_peripheral_partitionslot:libpartition_slot_manager", + "hilog:libhilog_base", + "init:libbegetutil_static", + ] } subsystem_name = "updater" diff --git a/services/include/updater/updater.h b/services/include/updater/updater.h index 798afa60396769eb310ada38e787634d311c1fcb..0851fb0db518e04365701b9c91f806947c68e9c0 100644 --- a/services/include/updater/updater.h +++ b/services/include/updater/updater.h @@ -62,6 +62,7 @@ struct UpdaterParams { std::string shrinkInfo = ""; std::string virtualShrinkInfo = ""; std::string miscCmd {"boot_updater"}; + std::vector updateBin {}; std::vector updatePackage {}; std::vector> installTime {}; std::function callbackProgress {}; @@ -90,6 +91,9 @@ void ProgressSmoothHandler(int beginProgress, int endProgress); UpdaterStatus DoInstallUpdaterPackage(Hpackage::PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams, PackageUpdateMode updateMode); +UpdaterStatus DoInstallUpdaterBinfile(Hpackage::PkgManager::PkgManagerPtr pkgManager, + UpdaterParams &upParams, PackageUpdateMode updateMode); + UpdaterStatus StartUpdaterProc(Hpackage::PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams); diff --git a/services/include/updater/updater_const.h b/services/include/updater/updater_const.h index 7378ab572db7ec48f3b5c087c66716fae1715574..8d0e0ed3b0bd51d074897bfe1b2b229c32471d6b 100644 --- a/services/include/updater/updater_const.h +++ b/services/include/updater/updater_const.h @@ -38,6 +38,7 @@ constexpr const char *MODULE_UPDATE_RESULT_FILE = "module_update_result"; constexpr const char *MISC_FILE = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc"; constexpr const char *MISC_PATH = "/misc"; constexpr const char *UPDATER_BINARY = "updater_binary"; +constexpr const char *STREAM_ZIP_PATH = "/data/updater/update_stream.zip"; constexpr const char *SDCARD_PATH = "/sdcard"; constexpr const char *INTERNAL_DATA_PATH = "/internaldata"; constexpr const char *UPDATER_HDC_LOG = "/data/updater/log/flashd_hdc.log"; @@ -90,7 +91,7 @@ constexpr int MINIMAL_ARGC_LIMIT = 2; constexpr int MAXIMAL_ARGC_LIMIT = 4; constexpr int MAX_LOG_BUF_SIZE = 4096; constexpr int MAX_LOG_NAME_SIZE = 100; -constexpr long MAX_LOG_SIZE = 2 * 1024 * 1024; +constexpr long MAX_LOG_SIZE = 10 * 1024 * 1024; constexpr long MAX_LOG_DIR_SIZE = 10 * 1024 * 1024; constexpr int MAX_RESULT_SIZE = 20; constexpr int MAX_RESULT_BUFF_SIZE = 1000; diff --git a/services/package/pkg_manager/pkg_managerImpl.cpp b/services/package/pkg_manager/pkg_managerImpl.cpp index ccd8722e3395f81c234ac7db06f33a82c27c180c..702c288f89ebfdae6e1efc1dd35e033833ba4d60 100644 --- a/services/package/pkg_manager/pkg_managerImpl.cpp +++ b/services/package/pkg_manager/pkg_managerImpl.cpp @@ -358,7 +358,7 @@ int32_t PkgManagerImpl::ExtraAndLoadPackage(const std::string &path, const std:: (void)mkdir(tempPath.c_str(), 0775); // 0775 : rwxrwxr-x #endif } - + // Extract package to file or memory if (unzipToFile_ || type == PkgFile::PKG_TYPE_UPGRADE) { ret = CreatePkgStream(stream, tempPath + name + ".tmp", info->unpackedSize, PkgStream::PkgStreamType_Write); diff --git a/services/package/pkg_manager/pkg_manager_impl.h b/services/package/pkg_manager/pkg_manager_impl.h index ba6a6604e979f2a0a4021251a96a844b69c82bc0..0be739db83eafd28e4992a085507b92e8364536e 100644 --- a/services/package/pkg_manager/pkg_manager_impl.h +++ b/services/package/pkg_manager/pkg_manager_impl.h @@ -101,6 +101,7 @@ public: int32_t LoadPackage(const std::string &packagePath, std::vector &fileIds, PkgFile::PkgType type) override; + private: PkgFilePtr CreatePackage(PkgStreamPtr stream, PkgFile::PkgType type, PkgInfoPtr header = nullptr); diff --git a/services/stream_update/bin_chunk_update.cpp b/services/stream_update/bin_chunk_update.cpp index 5a7736e9ca50d9fc3834b6ddafd1a0f03feeb606..a9140fd93e0e05da3c3a37b68efc246c1f1e09d2 100755 --- a/services/stream_update/bin_chunk_update.cpp +++ b/services/stream_update/bin_chunk_update.cpp @@ -800,10 +800,10 @@ std::string BinChunkUpdate::ComputeFileHash(const std::string &partitionName, bool BinChunkUpdate::VerifyPartitionHash(const std::string &partitionName, const std::string &expectedHash, const std::map &dataLenInfos) { - LOG(DEBUG) << "BinChunkUpdate::VerifyPartitionHash enter"; + LOG(INFO) << "BinChunkUpdate::VerifyPartitionHash enter"; std::string actualHash = ComputeFileHash(partitionName, dataLenInfos); - LOG(DEBUG) << "actualHash:" << actualHash << " expectedHash:" << expectedHash; + LOG(INFO) << "actualHash:" << actualHash << " expectedHash:" << expectedHash; if (actualHash != expectedHash) { LOG(ERROR) << "Error verifying hash for partition " << partitionName; diff --git a/services/stream_update/bin_chunk_update.h b/services/stream_update/bin_chunk_update.h index c9710b5449f015d06226d241a0c36b17bba6780e..306326d693df3a368f5fb1411c0cd478c2a3a4ef 100755 --- a/services/stream_update/bin_chunk_update.h +++ b/services/stream_update/bin_chunk_update.h @@ -47,6 +47,7 @@ using UpdateResultCode = enum { }; using BinUpdateTip = enum { + BIN_UPDATE_ZIP_TIP = 0xaa, BIN_UPDATE_HEAD_TIP = 0x01, BIN_UPDATE_DATA_TIP = 0x12, BIN_UPDATE_HASH_TIP = 0x16 diff --git a/services/updater.cpp b/services/updater.cpp index 9e8e4a9542161a96460bae2507df788589202a53..a5b2429e8eaa9c5a5bfe7274722cb735e9b282ea 100644 --- a/services/updater.cpp +++ b/services/updater.cpp @@ -265,6 +265,63 @@ __attribute__((weak)) bool PreStartBinaryEntry([[maybe_unused]] const std::strin return true; } +UpdaterStatus DoInstallUpdaterBinfile(PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams, + PackageUpdateMode updateMode) +{ + UPDATER_INIT_RECORD; + UPDATER_UI_INSTANCE.ShowProgressPage(); + if (upParams.callbackProgress == nullptr) { + LOG(ERROR) << "CallbackProgress is nullptr"; + UPDATER_LAST_WORD(UPDATE_CORRUPT, "CallbackProgress is nullptr"); + return UPDATE_CORRUPT; + } + upParams.callbackProgress(upParams.initialProgress * FULL_PERCENT_PROGRESS); + if (pkgManager == nullptr) { + LOG(ERROR) << "pkgManager is nullptr"; + UPDATER_LAST_WORD(UPDATE_CORRUPT, "pkgManager is nullptr"); + return UPDATE_CORRUPT; + } + + if (SetupPartitions(updateMode != SDCARD_UPDATE || upParams.sdExtMode == SDCARD_UPDATE_FROM_DEV || + upParams.sdExtMode == SDCARD_UPDATE_FROM_DATA || Utils::CheckUpdateMode(Updater::SDCARD_INTRAL_MODE) || + Utils::CheckUpdateMode(Updater::FACTORY_INTERNAL_MODE)) != 0) { + UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_SETPART_FAIL), true); + UPDATER_LAST_WORD(UPDATE_ERROR, "SetupPartitions failed"); + return UPDATE_ERROR; + } + + if (upParams.retryCount > 0) { + LOG(INFO) << "Retry for " << upParams.retryCount << " time(s)"; + } + + // 获取zip信息 + int ret = GetUpdatePackageInfo(pkgManager, STREAM_ZIP_PATH); + if (ret != 0) { + LOG(ERROR) << "get update package info fail"; + UPDATER_LAST_WORD(UPDATE_CORRUPT, "GetUpdatePackageInfo failed"); + return UPDATE_CORRUPT; + } + if (!PreStartBinaryEntry(upParams.updateBin[upParams.pkgLocation])) { + LOG(ERROR) << "pre binary process failed"; + UPDATER_LAST_WORD(UPDATE_ERROR, "PreStartBinaryEntry failed"); + return UPDATE_ERROR; + } + + g_tmpProgressValue = 0; + // 从bin文件开启进程 + UpdaterStatus updateRet = StartUpdaterProc(pkgManager, upParams); + if (updateRet != UPDATE_SUCCESS) { + UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_INSTALL_FAIL)); + UPDATER_LAST_WORD(updateRet, "StartUpdaterProc failed"); + LOG(ERROR) << "Install package failed."; + } + if (WriteResult(upParams.updateBin[upParams.pkgLocation], + updateRet == UPDATE_SUCCESS ? "verify_success" : "verify_fail") != UPDATE_SUCCESS) { + LOG(ERROR) << "write update state fail"; + } + return updateRet; +} + UpdaterStatus DoInstallUpdaterPackage(PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams, PackageUpdateMode updateMode) { @@ -418,8 +475,15 @@ void ExcuteSubProc(const UpdaterParams &upParams, const std::string &fullPath, i } } const std::string retryPara = upParams.retryCount > 0 ? "retry=1" : "retry=0"; - execl(fullPath.c_str(), fullPath.c_str(), upParams.updatePackage[upParams.pkgLocation].c_str(), + if (upParams.updateBin.size() > 0) { + LOG(INFO) << "Binary Path:" << upParams.updateBin[upParams.pkgLocation].c_str(); + execl(fullPath.c_str(), fullPath.c_str(), upParams.updateBin[upParams.pkgLocation].c_str(), std::to_string(pipeWrite).c_str(), retryPara.c_str(), nullptr); + } else if (upParams.updatePackage.size() > 0) { + LOG(INFO) << "Binary Path:" << upParams.updatePackage[upParams.pkgLocation].c_str(); + execl(fullPath.c_str(), fullPath.c_str(), upParams.updatePackage[upParams.pkgLocation].c_str(), + std::to_string(pipeWrite).c_str(), retryPara.c_str(), nullptr); + } LOG(ERROR) << "Execute updater binary failed"; UPDATER_LAST_WORD(UPDATE_ERROR, "Execute updater binary failed"); exit(-1); @@ -476,11 +540,26 @@ UpdaterStatus CheckProcStatus(pid_t pid, bool retryUpdate) return UPDATE_SUCCESS; } -static std::string GetBinaryPath(PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams) +static std::string GetBinaryPathFromBin(PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams) { std::string fullPath = GetWorkPath() + std::string(UPDATER_BINARY); (void)Utils::DeleteFile(fullPath); + std::string toolPath = "/data/updater/update_stream.zip"; + if (ExtractUpdaterBinary(pkgManager, toolPath, UPDATER_BINARY) != 0) { + LOG(INFO) << "There is no valid updater_binary in package, use updater_binary in device"; + fullPath = "/bin/updater_binary"; + } +#ifdef UPDATER_UT + fullPath = "/data/updater/updater_binary"; +#endif + return fullPath; +} + +static std::string GetBinaryPath(PkgManager::PkgManagerPtr pkgManager, UpdaterParams &upParams) +{ + std::string fullPath = GetWorkPath() + std::string(UPDATER_BINARY); + (void)Utils::DeleteFile(fullPath); if (ExtractUpdaterBinary(pkgManager, upParams.updatePackage[upParams.pkgLocation], UPDATER_BINARY) != 0) { LOG(INFO) << "There is no valid updater_binary in package, use updater_binary in device"; fullPath = "/bin/updater_binary"; @@ -509,7 +588,12 @@ UpdaterStatus StartUpdaterProc(PkgManager::PkgManagerPtr pkgManager, UpdaterPara int pipeRead = pfd[0]; int pipeWrite = pfd[1]; - std::string fullPath = GetBinaryPath(pkgManager, upParams); + std::string fullPath = ""; + if (upParams.updateBin.size() > 0) { + fullPath = GetBinaryPathFromBin(pkgManager, upParams); + } else if (upParams.updatePackage.size() > 0) { + fullPath = GetBinaryPath(pkgManager, upParams); + } if (chmod(fullPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { LOG(ERROR) << "Failed to change mode"; } diff --git a/services/updater_binary/BUILD.gn b/services/updater_binary/BUILD.gn index 754e1e2ff6aa90ea1f4b6cd994728ccff85a4b2d..3f79682c84790f2295e8ab5454f75049032eb3f0 100644 --- a/services/updater_binary/BUILD.gn +++ b/services/updater_binary/BUILD.gn @@ -50,6 +50,7 @@ ohos_static_library("libupdater_binary") { "${updater_path}/services/updater_binary/update_image_patch.cpp", "${updater_path}/services/updater_binary/update_partitions.cpp", "${updater_path}/services/updater_binary/update_processor.cpp", + "${updater_path}/services/updater_binary/update_processor_stream.cpp", ] configs = [ ":updater_config" ] @@ -65,6 +66,7 @@ ohos_static_library("libupdater_binary") { "${updater_path}/services/log:libupdaterlog", "${updater_path}/services/package:libupdaterpackage", "${updater_path}/services/script:libupdaterscript", + "${updater_path}/services/stream_update:libbinchunkupdate", "${updater_path}/utils:libutils", ] diff --git a/services/updater_binary/main.cpp b/services/updater_binary/main.cpp index a581259e3c324582c73bf861e4ce3c7ddbeedb14..133ecac49fc993d06a246534a3554a45e35145ee 100644 --- a/services/updater_binary/main.cpp +++ b/services/updater_binary/main.cpp @@ -21,6 +21,7 @@ #include "log.h" #include "updater/updater_const.h" #include "update_processor.h" +#include "update_processor_stream.h" #include "utils.h" using namespace Updater; @@ -52,6 +53,23 @@ int main(int argc, char **argv) // Re-load fstab to child process. LoadFstab(); - return ProcessUpdater(retry, pipeFd, packagePath, Utils::GetCertName()); + + // 根据 packagePath 的后缀选择执行不同的函数 + std::string fileExtension; + size_t dotPosition = packagePath.find_last_of("."); + if (dotPosition == std::string::npos) { + LOG(ERROR) << "Invalid packagePath: No extension found in " << packagePath; + return EXIT_INVALID_ARGS; + } + fileExtension = packagePath.substr(dotPosition + 1); + std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower); + if (fileExtension == "zip") { + return ProcessUpdater(retry, pipeFd, packagePath, Utils::GetCertName()); + } else if (fileExtension == "bin") { + return ProcessUpdaterStream(retry, pipeFd, packagePath, Utils::GetCertName()); + } else { + LOG(ERROR) << "Invalid packagePath:" << packagePath; + return EXIT_INVALID_ARGS; + } } #endif diff --git a/services/updater_binary/update_processor_stream.cpp b/services/updater_binary/update_processor_stream.cpp new file mode 100755 index 0000000000000000000000000000000000000000..a6476729fa265647d74ef35bf4b5577bef0bb3a5 --- /dev/null +++ b/services/updater_binary/update_processor_stream.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2021 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 "update_processor.h" +#include +#include +#include +#include +#include +#include "securec.h" +#include "applypatch/data_writer.h" +#include "applypatch/partition_record.h" +#include "applypatch/update_progress.h" +#include "dump.h" +#include "log.h" +#include "package/hash_data_verifier.h" +#include "pkg_manager.h" +#ifdef UPDATER_USE_PTABLE +#include "ptable_manager.h" +#endif +#include "script_instruction.h" +#include "script_manager.h" +#include "slot_info/slot_info.h" +#include "updater_main.h" +#include "updater/updater_const.h" +#include "update_bin/bin_process.h" +#include "scope_guard.h" +#include "bin_chunk_update.h" + +#define TYPE_ZIP_HEADER 0xaa + +using namespace Uscript; +using namespace Hpackage; +using namespace Updater; + +namespace Updater { +constexpr uint32_t BUFFER_SIZE = 50 * 1024; +constexpr uint32_t MAX_UPDATER_BUFFER_SIZE = 2 * BUFFER_SIZE; +constexpr uint32_t BYTE_SHIFT_8 = 8; +constexpr uint32_t BYTE_SHIFT_16 = 16; +constexpr uint32_t BYTE_SHIFT_24 = 24; +constexpr uint32_t SECOND_BUFFER = 2; +constexpr uint32_t THIRD_BUFFER = 3; + +enum UpdateStatus { + UPDATE_STATE_INIT = 0, + UPDATE_STATE_ONGOING, + UPDATE_STATE_FAILED, + UPDATE_STATE_SUCCESSFUL, + UPDATE_STATE_MAX +}; + +bool ReadLE16(std::istream& is, uint16_t& value) +{ + char buf[2] = {0}; + if (!is.read(buf, sizeof(buf))) { + return false; + } + value = static_cast(static_cast(buf[0])) | + (static_cast(static_cast(buf[1])) << BYTE_SHIFT_8); + return true; +} + +bool ReadLE32(std::istream& is, uint32_t& value) +{ + char buf[4] = {0}; + if (!is.read(buf, sizeof(buf))) { + return false; + } + value = static_cast(static_cast(buf[0])) | + (static_cast(static_cast(buf[1])) << BYTE_SHIFT_8) | + (static_cast(static_cast(buf[SECOND_BUFFER])) << BYTE_SHIFT_16) | + (static_cast(static_cast(buf[THIRD_BUFFER])) << BYTE_SHIFT_24); + return true; +} +static int ProcessUpdateFile(const std::string &packagePath, FILE* pipeWrite) +{ + std::shared_ptr binChunkUpdate_ {}; + // 打开输入文件 + std::ifstream in_file(packagePath, std::ios::binary); + if (!in_file) { + LOG(ERROR) << "Error: Failed to open " << packagePath; + return UPDATE_ERROR; + } + + uint16_t type = 0; + if (!ReadLE16(in_file, type)) { + LOG(ERROR) << "Failed to read type"; + return UPDATE_ERROR; + } + + if (type != TYPE_ZIP_HEADER) { + LOG(ERROR) << "Unsupported header type: 0x" << std::hex << type; + in_file.close(); + return UPDATE_ERROR; + } + uint32_t length = 0; + if (!ReadLE32(in_file, length)) { + LOG(ERROR) << "Failed to read length"; + return UPDATE_ERROR; + } + + if (!in_file.seekg(length, std::ios::cur)) { + in_file.close(); + LOG(ERROR) << "Failed to seekg length"; + return UPDATE_ERROR; + } + + // 读取剩余数据 + std::vector buffer_stream(BUFFER_SIZE); + binChunkUpdate_ = std::make_unique(MAX_UPDATER_BUFFER_SIZE); + while (!in_file.eof()) { + in_file.read(reinterpret_cast(buffer_stream.data()), buffer_stream.size()); + size_t readBytes = in_file.gcount(); + uint32_t dealLen = 0; + if (readBytes > 0) { + UpdateResultCode ret = binChunkUpdate_->StartBinChunkUpdate( + buffer_stream.data(), static_cast(readBytes), dealLen); + if (STREAM_UPDATE_SUCCESS == ret) { + LOG(INFO) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_SUCCESS"; + } else if (STREAM_UPDATE_FAILURE == ret) { + LOG(ERROR) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_FAILURE"; + return UPDATE_ERROR; + } else if (STREAM_UPDATE_COMPLETE == ret) { + LOG(INFO) << "StreamInstallProcesser ThreadExecuteFunc STREM_UPDATE_COMPLETE"; + break; + } + } + } + in_file.close(); + return UPDATE_SUCCESS; +} + +int ProcessUpdaterStream(bool retry, int pipeFd, const std::string &packagePath, const std::string &keyPath) +{ + UPDATER_INIT_RECORD; + UpdaterInit::GetInstance().InvokeEvent(UPDATER_BINARY_INIT_EVENT); + Dump::GetInstance().RegisterDump("DumpHelperLog", std::make_unique()); + + // 初始化管道 + std::unique_ptr pipeWrite(fdopen(pipeFd, "w"), fclose); + if (pipeWrite == nullptr) { + LOG(ERROR) << "Fail to fdopen, err: " << strerror(errno); + UPDATER_LAST_WORD(strerror(errno), "Fail to fdopen"); + return EXIT_INVALID_ARGS; + } + + int ret = -1; + Detail::ScopeGuard guard([&] { + (void)fprintf(pipeWrite.get(), "subProcessResult:%d\n", ret); + (void)fflush(pipeWrite.get()); + }); + setlinebuf(pipeWrite.get()); + + // 初始化包管理器 + PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance(); + if (pkgManager == nullptr) { + LOG(ERROR) << "pkgManager is nullptr"; + UPDATER_LAST_WORD(EXIT_INVALID_ARGS, "pkgManager is nullptr"); + return EXIT_INVALID_ARGS; + } + + // 加载包 + std::vector components; + int loadRet = pkgManager->LoadPackage(packagePath, keyPath, components); + if (loadRet != PKG_SUCCESS) { + LOG(ERROR) << "Fail to load package"; + PkgManager::ReleasePackageInstance(pkgManager); + UPDATER_LAST_WORD("Fail to load package", packagePath, keyPath); + return EXIT_INVALID_ARGS; + } + +#ifdef UPDATER_USE_PTABLE + // 分区表操作 + if (!PackagePtable::GetInstance().WritePtableWithFile()) { + LOG(ERROR) << "write ptable with file fail"; + PkgManager::ReleasePackageInstance(pkgManager); + UPDATER_LAST_WORD("Error to write ptable with file"); + return EXIT_EXEC_SCRIPT_ERROR; + } + if (!DevicePtable::GetInstance().LoadPartitionInfo()) { + PkgManager::ReleasePackageInstance(pkgManager); + return EXIT_EXEC_SCRIPT_ERROR; + } +#endif + + // 调用核心函数并传递管道 + ret = ProcessUpdateFile(packagePath, pipeWrite.get()); + if (ret != UPDATE_SUCCESS) { + LOG(ERROR) << "ProcessUpdaterStream failed with code: " << ret; + } + + // 释放资源 + PkgManager::ReleasePackageInstance(pkgManager); + return ret; +} +} // Updater \ No newline at end of file diff --git a/services/updater_binary/update_processor_stream.h b/services/updater_binary/update_processor_stream.h new file mode 100755 index 0000000000000000000000000000000000000000..5eed42c114d89f4d9ce6612f7860ca06e75734f9 --- /dev/null +++ b/services/updater_binary/update_processor_stream.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 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 UPDATE_PROCESSOR_STREAM_H +#define UPDATE_PROCESSOR_STREAM_H + +#include +#include +#include +#include +#include "applypatch/data_writer.h" +#include "pkg_manager.h" +#include "script_instruction.h" +#include "script_manager.h" +#include "bin_chunk_update.h" + +using Uscript::UScriptEnv; +using Uscript::UScriptInstructionFactory; +using Uscript::UScriptInstructionFactoryPtr; +using Uscript::UScriptInstructionPtr; + +namespace Updater { +int ProcessUpdaterStream(bool retry, int pipeFd, const std::string &packagePath, const std::string &keyPath); +} // Updater +#endif /* UPDATE_PROCESSOR_H */ diff --git a/services/updater_main.cpp b/services/updater_main.cpp index 01f324b599c864b6f2d69ce2972461a63d82c59a..efbdbfd65dd38011c2449914849af3e0a32a2e6d 100644 --- a/services/updater_main.cpp +++ b/services/updater_main.cpp @@ -59,6 +59,7 @@ using namespace std::literals::chrono_literals; [[maybe_unused]] constexpr int DISPLAY_TIME = 1000 * 1000; constexpr struct option OPTIONS[] = { + { "update_bin", required_argument, nullptr, 0 }, { "update_package", required_argument, nullptr, 0 }, { "retry_count", required_argument, nullptr, 0 }, { "factory_wipe_data", no_argument, nullptr, 0 }, @@ -83,6 +84,36 @@ constexpr struct option OPTIONS[] = { }; constexpr float VERIFY_PERCENT = 0.05; constexpr double FULL_PERCENT = 100.00; +constexpr uint32_t BYTE_SHIFT_8 = 8; +constexpr uint32_t BYTE_SHIFT_16 = 16; +constexpr uint32_t BYTE_SHIFT_24 = 24; +constexpr uint32_t SECOND_BUFFER = 2; +constexpr uint32_t THIRD_BUFFER = 3; +constexpr uint8_t TYPE_ZIP_HEADER = 0xaa; + +bool ReadLE16(std::istream& is, uint16_t& value) +{ + char buf[2] = {0}; + if (!is.read(buf, sizeof(buf))) { + return false; + } + value = static_cast(static_cast(buf[0])) | + (static_cast(static_cast(buf[1])) << BYTE_SHIFT_8); + return true; +} + +bool ReadLE32(std::istream& is, uint32_t& value) +{ + char buf[4] = {0}; + if (!is.read(buf, sizeof(buf))) { + return false; + } + value = static_cast(static_cast(buf[0])) | + (static_cast(static_cast(buf[1])) << BYTE_SHIFT_8) | + (static_cast(static_cast(buf[SECOND_BUFFER])) << BYTE_SHIFT_16) | + (static_cast(static_cast(buf[THIRD_BUFFER])) << BYTE_SHIFT_24); + return true; +} int FactoryReset(FactoryResetMode mode, const std::string &path) { @@ -95,6 +126,86 @@ int FactoryReset(FactoryResetMode mode, const std::string &path) return ret; } +static UpdaterStatus ReadUpdateStreamzip(const std::string &packagePath) +{ + std::filesystem::path packageFsPath(packagePath); + std::filesystem::path outputPath = packageFsPath.parent_path() / "update_stream.zip"; + std::string outputPathStr = outputPath.string(); + LOG(INFO) << "outputPathStr:" << outputPathStr; + + std::ifstream in_file(packagePath, std::ios::binary); + if (!in_file) { + LOG(ERROR) << "Error: Failed to open " << packagePath; + return UPDATE_ERROR; + } + uint16_t type; + if (!ReadLE16(in_file, type)) { + LOG(ERROR) << "Failed to read type"; + return UPDATE_ERROR; + } + if (type != TYPE_ZIP_HEADER) { + LOG(ERROR) << "Invalid type, expected 0xaa but got " << type; + return UPDATE_ERROR; + } + + uint32_t length; + if (!ReadLE32(in_file, length)) { + LOG(ERROR) << "Failed to read length"; + return UPDATE_ERROR; + } + LOG(INFO) << "header.length = " << length; + + std::vector valueData(length); + if (!in_file.read(valueData.data(), length)) { + LOG(ERROR) << "Incomplete value data"; + return UPDATE_ERROR; + } + + std::ofstream outFile(outputPathStr, std::ios::binary); + if (!outFile.write(valueData.data(), length)) { + LOG(ERROR) << "Write failed"; + return UPDATE_ERROR; + } + LOG(INFO) << "Successfully restored build_tools.zip to " << outputPathStr; + return UPDATE_SUCCESS; +} + +const char* GetFileType(const char* path, struct stat* st) +{ + if (lstat(path, st) != 0) { + return "Unknown"; + } + + switch (st->st_mode & S_IFMT) { + case S_IFREG: return "File"; + case S_IFDIR: return "Directory"; + case S_IFLNK: return "Symlink"; + case S_IFIFO: return "FIFO"; + case S_IFSOCK: return "Socket"; + case S_IFCHR: return "CharDevice"; + case S_IFBLK: return "BlockDevice"; + default: return "Unknown"; + } +} + +static UpdaterStatus GetReadUpdateStreamzipFromBinfile(PkgManager::PkgManagerPtr pkgManager, + const std::string &packagePath) +{ + UPDATER_INIT_RECORD; + if (pkgManager == nullptr) { + LOG(ERROR) << "pkgManager is nullptr"; + UPDATER_LAST_WORD(PKG_INVALID_FILE, "pkgManager is nullptr"); + return UPDATE_CORRUPT; + } + // 获取zip内容 + int32_t status = ReadUpdateStreamzip(packagePath); + if (status != UPDATE_SUCCESS) { + LOG(ERROR) << "ReadUpdateStreamzip failed"; + return UPDATE_ERROR; + } + return UPDATE_SUCCESS; +} + static int OtaUpdatePreCheck(PkgManager::PkgManagerPtr pkgManager, const std::string &packagePath) { UPDATER_INIT_RECORD; @@ -157,6 +268,12 @@ static UpdaterStatus UpdatePreCheck(UpdaterParams &upParams, const std::string p return UPDATE_SUCCESS; } +__attribute__((weak)) int32_t VerifySpecialBin([[maybe_unused]]UpdaterParams &upParams) +{ + return PKG_SUCCESS; +} + + __attribute__((weak)) int32_t VerifySpecialPkgs([[maybe_unused]]UpdaterParams &upParams) { return PKG_SUCCESS; @@ -180,6 +297,60 @@ __attribute__((weak)) void NotifyReboot(const std::string& rebootTarget, Updater::Utils::UpdaterDoReboot(rebootTarget, rebootReason, extData); } +static UpdaterStatus VerifyBinfiles(UpdaterParams &upParams) +{ + UPDATER_INIT_RECORD; + LOG(INFO) << "Verify binfiles start..."; + UPDATER_UI_INSTANCE.ShowProgressPage(); + UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKG)); + + if (upParams.callbackProgress == nullptr) { + UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKGFAIL), true); + UPDATER_LAST_WORD(UPDATE_CORRUPT, "upParams.callbackProgress is null"); + return UPDATE_CORRUPT; + } + upParams.callbackProgress(0.0); + upParams.installTime.resize(upParams.updateBin.size(), std::chrono::duration(0)); + ReadInstallTime(upParams); + for (unsigned int i = upParams.pkgLocation; i < upParams.updateBin.size(); i++) { + LOG(INFO) << "Verify package:" << upParams.updateBin[i]; + auto startTime = std::chrono::system_clock::now(); + PkgManager::PkgManagerPtr manager = PkgManager::CreatePackageInstance(); + if (manager == nullptr) { + LOG(ERROR) << "CreatePackageInstance fail"; + return UPDATE_ERROR; + } + // 从update_bin中获取zip + int32_t status = GetReadUpdateStreamzipFromBinfile(manager, upParams.updateBin[i]); + if (status != UPDATE_SUCCESS) { + LOG(ERROR) << "GetReadUpdateStreamzipFromBinfile fail"; + return UPDATE_ERROR; + } + // 验证update_stream.zip包 + int32_t verifyret = OtaUpdatePreCheck(manager, STREAM_ZIP_PATH); + PkgManager::ReleasePackageInstance(manager); + if (verifyret != UPDATE_SUCCESS) { + UpdaterVerifyFailEntry((verifyret == PKG_INVALID_DIGEST) && (upParams.updateMode == HOTA_UPDATE)); + upParams.pkgLocation = i; + UPDATER_UI_INSTANCE.ShowUpdInfo(TR(UPD_VERIFYPKGFAIL), true); + auto endTime = std::chrono::system_clock::now(); + upParams.installTime[i] = endTime - startTime; + return UPDATE_CORRUPT; + } + auto endTime = std::chrono::system_clock::now(); + upParams.installTime[i] = endTime - startTime; + } + + if (VerifySpecialBin(upParams) != PKG_SUCCESS) { + UPDATER_LAST_WORD(UPDATE_CORRUPT, "VerifySpecialBin failed"); + return UPDATE_CORRUPT; + } + ProgressSmoothHandler(UPDATER_UI_INSTANCE.GetCurrentPercent(), + UPDATER_UI_INSTANCE.GetCurrentPercent() + static_cast(VERIFY_PERCENT * FULL_PERCENT_PROGRESS)); + LOG(INFO) << "Verify binfiles successfull..."; + return UPDATE_SUCCESS; +} + static UpdaterStatus VerifyPackages(UpdaterParams &upParams) { UPDATER_INIT_RECORD; @@ -297,6 +468,27 @@ bool IsBatteryCapacitySufficient() return capacity >= lowLevel; } +UpdaterStatus InstallUpdaterBinfile(UpdaterParams &upParams, PkgManager::PkgManagerPtr manager) +{ + UPDATER_INIT_RECORD; + UpdaterStatus status = UPDATE_UNKNOWN; + STAGE(UPDATE_STAGE_BEGIN) << "Install Binfile"; + status = DoInstallUpdaterBinfile(manager, upParams, HOTA_UPDATE); + if (status != UPDATE_SUCCESS) { + UPDATER_UI_INSTANCE.Sleep(UI_SHOW_DURATION); + UPDATER_UI_INSTANCE.ShowLog(TR(LOG_UPDFAIL)); + STAGE(UPDATE_STAGE_FAIL) << "Install failed"; + if (status == UPDATE_RETRY) { + HwFaultRetry::GetInstance().DoRetryAction(); + UPDATER_UI_INSTANCE.ShowFailedPage(); + } + } else { + LOG(INFO) << "Install binfile success."; + STAGE(UPDATE_STAGE_SUCCESS) << "Install binfile"; + } + return status; +} + UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, PkgManager::PkgManagerPtr manager) { UPDATER_INIT_RECORD; @@ -331,18 +523,45 @@ UpdaterStatus InstallUpdaterPackage(UpdaterParams &upParams, PkgManager::PkgMana return status; } +static UpdaterStatus UpdateUpdateFile(const UpdaterParams &upParams, + std::vector &pkgStartPosition, double &updateStartPosition, + std::vector &updateFile) +{ + updateFile.clear(); + if (upParams.updateBin.size() > 0) { + if (upParams.pkgLocation == upParams.updateBin.size()) { + updateStartPosition = VERIFY_PERCENT; + return UPDATE_SUCCESS; + } + for (const auto& file : upParams.updateBin) { + updateFile.push_back(file); + } + } else if (upParams.updatePackage.size() > 0) { + if (upParams.pkgLocation == upParams.updatePackage.size()) { + updateStartPosition = VERIFY_PERCENT; + return UPDATE_SUCCESS; + } + for (const auto& file : upParams.updatePackage) { + updateFile.push_back(file); + } + } + return UPDATE_SKIP; +} + static UpdaterStatus CalcProgress(const UpdaterParams &upParams, std::vector &pkgStartPosition, double &updateStartPosition) { UPDATER_INIT_RECORD; int64_t allPkgSize = 0; std::vector everyPkgSize; - if (upParams.pkgLocation == upParams.updatePackage.size()) { - updateStartPosition = VERIFY_PERCENT; + std::vector updateFile; + + UpdaterStatus status = UpdateUpdateFile(upParams, pkgStartPosition, updateStartPosition, updateFile); + if (status == UPDATE_SUCCESS) { return UPDATE_SUCCESS; } - for (const auto &path : upParams.updatePackage) { - char realPath[PATH_MAX + 1] = {0}; + for (const auto &path : updateFile) { + char realPath[PATH_MAX] = {0}; if (realpath(path.c_str(), realPath) == nullptr) { LOG(WARNING) << "Can not find updatePackage : " << path; everyPkgSize.push_back(0); @@ -401,6 +620,32 @@ static UpdaterStatus CheckVerifyPackages(UpdaterParams &upParams) return status; } +static UpdaterStatus VerifyCommonFiles(UpdaterParams &upParams) +{ + if (upParams.updateBin.size() > 0) { + if (upParams.pkgLocation == upParams.updateBin.size()) { + LOG(WARNING) << "all package has been upgraded, skip pre process"; + return UPDATE_SUCCESS; + } + // 从bin文件中提取zip文件 + if (VerifyBinfiles(upParams) != UPDATE_SUCCESS) { + LOG(ERROR) << "VerifyBinfiles failed"; + return UPDATE_CORRUPT; // verify binfiles failed must return UPDATE_CORRUPT, ux need it !!! + } + } else if (upParams.updatePackage.size() > 0) { + if (upParams.pkgLocation == upParams.updatePackage.size()) { + LOG(WARNING) << "all package has been upgraded, skip pre process"; + return UPDATE_SUCCESS; + } + // verify package first + if (VerifyPackages(upParams) != UPDATE_SUCCESS) { + LOG(ERROR) << "VerifyPackages failed"; + return UPDATE_CORRUPT; // verify package failed must return UPDATE_CORRUPT, ux need it !!! + } + } + return UPDATE_SUCCESS; +} + static UpdaterStatus PreUpdatePackages(UpdaterParams &upParams) { UPDATER_INIT_RECORD; @@ -408,30 +653,32 @@ static UpdaterStatus PreUpdatePackages(UpdaterParams &upParams) UpdaterStatus status = UPDATE_UNKNOWN; - upParams.installTime.resize(upParams.updatePackage.size(), std::chrono::duration(0)); - if (CheckMountData() != 0) { - return UPDATE_ERROR; + if (upParams.updateBin.size() > 0) { + upParams.installTime.resize(upParams.updateBin.size(), std::chrono::duration(0)); + if (CheckMountData() != 0) { + return UPDATE_ERROR; + } + } else if (upParams.updatePackage.size() > 0) { + upParams.installTime.resize(upParams.updatePackage.size(), std::chrono::duration(0)); + if (CheckMountData() != 0) { + return UPDATE_ERROR; + } } const std::string resultPath = std::string(UPDATER_PATH) + "/" + std::string(UPDATER_RESULT_FILE); if (access(resultPath.c_str(), F_OK) != -1) { (void)DeleteFile(resultPath); LOG(INFO) << "delete last upgrade file"; } - - if (upParams.pkgLocation == upParams.updatePackage.size()) { - LOG(WARNING) << "all package has been upgraded, skip pre process"; - return UPDATE_SUCCESS; - } - - // verify package first - if (VerifyPackages(upParams) != UPDATE_SUCCESS) { - return UPDATE_CORRUPT; // verify package failed must return UPDATE_CORRUPT, ux need it !!! + if (VerifyCommonFiles(upParams) == UPDATE_CORRUPT) { + return UPDATE_CORRUPT; } // Only handle UPATE_ERROR and UPDATE_SUCCESS here.Let package verify handle others. - if (IsSpaceCapacitySufficient(upParams) == UPDATE_ERROR) { - UPDATER_LAST_WORD(status, "space nott enough"); - return status; + if (upParams.updatePackage.size() > 0) { + if (IsSpaceCapacitySufficient(upParams) == UPDATE_ERROR) { + UPDATER_LAST_WORD(status, "space nott enough"); + return status; + } } if (upParams.retryCount == 0 && !IsBatteryCapacitySufficient()) { UPDATER_UI_INSTANCE.ShowUpdInfo(TR(LOG_LOWPOWER)); @@ -455,6 +702,49 @@ static UpdaterStatus PreUpdatePackages(UpdaterParams &upParams) return UPDATE_SUCCESS; } +static UpdaterStatus DoInstallBinfiles(UpdaterParams &upParams, std::vector &pkgStartPosition) +{ + UPDATER_INIT_RECORD; + UpdaterStatus status = UPDATE_UNKNOWN; + if (upParams.pkgLocation == upParams.updateBin.size()) { + LOG(WARNING) << "all Binfiles has been installed, directly return success"; + upParams.callbackProgress(FULL_PERCENT_PROGRESS); + return UPDATE_SUCCESS; + } + PkgManager::PkgManagerPtr manager = PkgManager::CreatePackageInstance(); + if (manager == nullptr) { + LOG(ERROR) << "CreatePackageInstance fail"; + return UPDATE_ERROR; + } + auto startTime = std::chrono::system_clock::now(); + upParams.initialProgress = ((UPDATER_UI_INSTANCE.GetCurrentPercent() / FULL_PERCENT) > + pkgStartPosition[upParams.pkgLocation]) ? + (UPDATER_UI_INSTANCE.GetCurrentPercent() / FULL_PERCENT) : pkgStartPosition[upParams.pkgLocation]; + upParams.currentPercentage = pkgStartPosition[upParams.pkgLocation + 1] - upParams.initialProgress; + LOG(INFO) << "InstallUpdaterBin pkg is " << upParams.updateBin[upParams.pkgLocation] << + " percent:" << upParams.initialProgress << "~" << pkgStartPosition[upParams.pkgLocation + 1]; + // 安装bin文件 + status = InstallUpdaterBinfile(upParams, manager); + auto endTime = std::chrono::system_clock::now(); + upParams.installTime[upParams.pkgLocation] = upParams.installTime[upParams.pkgLocation] + endTime - startTime; + WriteInstallTime(upParams); + if (status != UPDATE_SUCCESS) { + LOG(ERROR) << "InstallUpdaterBin failed! Pkg is " << upParams.updateBin[upParams.pkgLocation]; + if (!CheckResultFail()) { + UPDATER_LAST_WORD(status, "InstallUpdaterBin failed"); + } + PkgManager::ReleasePackageInstance(manager); + return status; + } + ProgressSmoothHandler( + static_cast(upParams.initialProgress * FULL_PERCENT_PROGRESS + + upParams.currentPercentage * GetTmpProgressValue()), + static_cast(pkgStartPosition[upParams.pkgLocation + 1] * FULL_PERCENT_PROGRESS)); + SetMessageToMisc(upParams.miscCmd, upParams.pkgLocation + 1, "upgraded_pkg_num"); + PkgManager::ReleasePackageInstance(manager); + return status; +} + static UpdaterStatus DoInstallPackages(UpdaterParams &upParams, std::vector &pkgStartPosition) { UPDATER_INIT_RECORD; @@ -499,6 +789,48 @@ static UpdaterStatus DoInstallPackages(UpdaterParams &upParams, std::vector pkgStartPosition {}; + double updateStartPosition = 0.0; + status = CalcProgress(upParams, pkgStartPosition, updateStartPosition); + if (status != UPDATE_SUCCESS) { + UPDATER_LAST_WORD(status, "CalcProgress failed"); + return status; + } + for (unsigned int i = 0; i < upParams.updateBin.size(); i++) { + LOG(INFO) << "package " << i << ":" << upParams.updateBin[i] << + " percent:" << upParams.currentPercentage; + } + if (upParams.callbackProgress == nullptr) { + LOG(ERROR) << "CallbackProgress is nullptr"; + return UPDATE_CORRUPT; + } + float value = (UPDATER_UI_INSTANCE.GetCurrentPercent() > (updateStartPosition * FULL_PERCENT_PROGRESS)) ? + UPDATER_UI_INSTANCE.GetCurrentPercent() : (updateStartPosition * FULL_PERCENT_PROGRESS); + upParams.callbackProgress(value); + // 执行安装 + status = DoInstallBinfiles(upParams, pkgStartPosition); + if (NotifyActionResult(upParams, status, {GET_UPDATE_STATUS}) != UPDATE_SUCCESS) { + LOG(ERROR) << "get status fail"; + return UPDATE_CORRUPT; + } + if (status != UPDATE_SUCCESS) { + UPDATER_LAST_WORD(status, "DoInstallBinfiles failed"); + return status; + } + if (upParams.forceUpdate) { + UPDATER_UI_INSTANCE.ShowLogRes(TR(LABEL_UPD_OK_SHUTDOWN)); + } + if (NotifyActionResult(upParams, status, {GET_UPDATE_STATUS}) != UPDATE_SUCCESS) { + LOG(ERROR) << "get status fail"; + return UPDATE_CORRUPT; + } + UPDATER_UI_INSTANCE.ShowSuccessPage(); + return status; +} UpdaterStatus DoUpdatePackages(UpdaterParams &upParams) { @@ -542,7 +874,8 @@ UpdaterStatus DoUpdatePackages(UpdaterParams &upParams) return status; } -static void PostUpdatePackages(UpdaterParams &upParams, bool updateResult) +static void PostUpdate(UpdaterParams &upParams, bool updateResult, + const std::vector& updateList, const std::string& type) { std::string writeBuffer; std::string buf; @@ -561,18 +894,17 @@ static void PostUpdatePackages(UpdaterParams &upParams, bool updateResult) for (unsigned int i = 0; i < upParams.pkgLocation; i++) { time = DurationToString(upParams.installTime, i); - writeBuffer += upParams.updatePackage.size() < i + 1 ? "" : upParams.updatePackage[i]; + writeBuffer += (i < updateList.size() ? updateList[i] : ""); writeBuffer += "|pass||install_time=" + time + "|\n"; } time = DurationToString(upParams.installTime, upParams.pkgLocation); - writeBuffer += upParams.updatePackage.size() < upParams.pkgLocation + 1 ? "" : - upParams.updatePackage[upParams.pkgLocation]; + writeBuffer += (upParams.pkgLocation < updateList.size() ? updateList[upParams.pkgLocation] : ""); writeBuffer += "|" + buf + "|install_time=" + time + "|\n"; - for (unsigned int i = upParams.pkgLocation + 1; i < upParams.updatePackage.size(); i++) { - writeBuffer += upParams.updatePackage[i] + "\n"; + for (unsigned int i = upParams.pkgLocation + 1; i < updateList.size(); i++) { + writeBuffer += updateList[i] + "\n"; } - if (writeBuffer != "") { + if (!writeBuffer.empty()) { writeBuffer.pop_back(); } LOG(INFO) << "post over, writeBuffer = " << writeBuffer; @@ -580,6 +912,16 @@ static void PostUpdatePackages(UpdaterParams &upParams, bool updateResult) DeleteInstallTimeFile(); } +static void PostUpdateBinfiles(UpdaterParams &upParams, bool updateResult) +{ + PostUpdate(upParams, updateResult, upParams.updateBin, "Binfiles"); +} + +static void PostUpdatePackages(UpdaterParams &upParams, bool updateResult) +{ + PostUpdate(upParams, updateResult, upParams.updatePackage, "Packages"); +} + static UpdaterStatus PreSdcardUpdatePackages(UpdaterParams &upParams) { upParams.installTime.resize(upParams.updatePackage.size(), std::chrono::duration(0)); @@ -641,6 +983,18 @@ UpdaterStatus UpdaterFromSdcard(UpdaterParams &upParams) return status; } +UpdaterStatus InstallUpdaterBinfiles(UpdaterParams &upParams) +{ + UpdaterInit::GetInstance().InvokeEvent(UPDATER_PRE_UPDATE_PACKAGE_EVENT); + UpdaterStatus status = PreUpdatePackages(upParams); + if (status == UPDATE_SUCCESS) { + status = DoUpdateBinfiles(upParams); + } + PostUpdateBinfiles(upParams, status == UPDATE_SUCCESS); + UpdaterInit::GetInstance().InvokeEvent(UPDATER_POST_UPDATE_PACKAGE_EVENT); + return status; +} + UpdaterStatus InstallUpdaterPackages(UpdaterParams &upParams) { UpdaterInit::GetInstance().InvokeEvent(UPDATER_PRE_UPDATE_PACKAGE_EVENT); @@ -661,12 +1015,10 @@ UpdaterStatus StartUpdaterEntry(UpdaterParams &upParams) LOG(ERROR) << "PreStartUpdaterEntry failed"; return status; } - status = DoUpdaterEntry(upParams); if (status != UPDATE_SUCCESS) { LOG(WARNING) << "DoUpdaterEntry failed"; } - status = PostStartUpdaterEntry(upParams, status); if (status != UPDATE_SUCCESS) { LOG(ERROR) << "PostStartUpdaterEntry failed"; @@ -677,7 +1029,11 @@ UpdaterStatus StartUpdaterEntry(UpdaterParams &upParams) UpdaterStatus DoUpdaterEntry(UpdaterParams &upParams) { UpdaterStatus status = UPDATE_UNKNOWN; - if (upParams.updateMode == SDCARD_UPDATE) { + if (upParams.updateBin.size() > 0) { + LOG(INFO) << "start bin update"; + UPDATER_UI_INSTANCE.ShowProgressPage(); + status = InstallUpdaterBinfiles(upParams); + } else if (upParams.updateMode == SDCARD_UPDATE) { LOG(INFO) << "start sdcard update"; UPDATER_UI_INSTANCE.ShowProgressPage(); status = UpdaterFromSdcard(upParams); @@ -726,6 +1082,12 @@ std::unordered_map> InitOptionsFuncTab(char* PackageUpdateMode &mode, UpdaterParams &upParams) { std::unordered_map> optionsFuncTab { + {"update_bin", [&]() -> void + { + upParams.updateBin.push_back(optarg); + (void)UPDATER_UI_INSTANCE.SetMode(UPDATERMODE_OTA); + mode = HOTA_UPDATE; + }}, {"update_package", [&]() -> void { upParams.updatePackage.push_back(optarg); diff --git a/updater_default_cfg.gni b/updater_default_cfg.gni index e2036f204ba0e0f2f69774d693df1f297926b271..796286a3362b12408a1c9cf58b66df6af96a9cf6 100644 --- a/updater_default_cfg.gni +++ b/updater_default_cfg.gni @@ -45,7 +45,7 @@ template("updater_gen") { } else { ohos_executable(target_name) { if (!is_asan && !is_emulator && target_name == "updater_binary") { - static_link = false + static_link = true } forward_variables_from(invoker, "*") diff --git a/utils/utils.cpp b/utils/utils.cpp index 854e135cf1671e66e9cf9df74e783c1cbda47c17..96341e9159b3d6635262b897e0c10d6a468f3656 100644 --- a/utils/utils.cpp +++ b/utils/utils.cpp @@ -109,6 +109,7 @@ void SaveLogs() std::string stageLogPath = std::string(UPDATER_STAGE_LOG); // save logs + STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdaterLog"; bool ret = CopyUpdaterLogs(TMP_LOG, updaterLogPath); if (!ret) { LOG(ERROR) << "Copy updater log failed!"; @@ -587,6 +588,8 @@ bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog) } while (Utils::GetFileSize(sLog) + GetDirSizeForFile(dLog) > MAX_LOG_DIR_SIZE) { + LOG(ERROR) << "Size bigger for" << sLog; + STAGE(UPDATE_STAGE_FAIL) << "sLog and dLog file error, unable to copy"; if (DeleteOldFile(destPath) != true) { break; } diff --git a/utils/write_updater.cpp b/utils/write_updater.cpp index e8c9d9e6824249d9cda6a4e8a554c57da90dd345..4ca55a98f8a5c422d7708cf7136c29b6b9ce2d7d 100644 --- a/utils/write_updater.cpp +++ b/utils/write_updater.cpp @@ -32,6 +32,7 @@ constexpr const char *HANDLE_MISC_LIB_PATH = "/system/lib64/libupdater_handle_mi static void PrintPrompts() { cout << "Please input correct command, examples :" << endl; + cout << "bin : write_updater bin /data/updater/update.bin" <