diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2022-05-09 17:38:52 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-05-09 17:38:52 +0000 |
commit | 6d7ac5c74caf0e4cbcc139375c24beadb6c236a4 (patch) | |
tree | 951983e17d88809cfa69710dbc040e0112985667 | |
parent | 310bd8257d70f91ba82b589cc2eb0473da7394a3 (diff) | |
parent | c2f616c150a9f5c2976d0ff5849577790d2bc5b5 (diff) | |
download | recovery-android11-dev.tar.gz |
Merge "Add checking FS utilities for updater" into android11-devandroid11-dev
-rw-r--r-- | edify/include/edify/updater_runtime_interface.h | 4 | ||||
-rw-r--r-- | updater/include/updater/simulator_runtime.h | 1 | ||||
-rw-r--r-- | updater/include/updater/updater_runtime.h | 1 | ||||
-rw-r--r-- | updater/install.cpp | 119 | ||||
-rw-r--r-- | updater/simulator_runtime.cpp | 6 | ||||
-rw-r--r-- | updater/updater_runtime.cpp | 51 |
6 files changed, 175 insertions, 7 deletions
diff --git a/edify/include/edify/updater_runtime_interface.h b/edify/include/edify/updater_runtime_interface.h index bdd6aecc..34b0a2f8 100644 --- a/edify/include/edify/updater_runtime_interface.h +++ b/edify/include/edify/updater_runtime_interface.h @@ -64,6 +64,10 @@ class UpdaterRuntimeInterface { // Starts a child process and runs the program with |args|. Uses vfork(2) if |is_vfork| is true. virtual int RunProgram(const std::vector<std::string>& args, bool is_vfork) const = 0; + // Starts a child process and runs the program with |args|. + // |stdout| and |stderr| will be stored in |result|. + virtual int RunProgram(const std::vector<std::string>& args, std::string* result) const = 0; + // Runs tune2fs with arguments |args|. virtual int Tune2Fs(const std::vector<std::string>& args) const = 0; diff --git a/updater/include/updater/simulator_runtime.h b/updater/include/updater/simulator_runtime.h index fa878db3..2bdc4cd5 100644 --- a/updater/include/updater/simulator_runtime.h +++ b/updater/include/updater/simulator_runtime.h @@ -48,6 +48,7 @@ class SimulatorRuntime : public UpdaterRuntimeInterface { int WipeBlockDevice(const std::string_view filename, size_t len) const override; int RunProgram(const std::vector<std::string>& args, bool is_vfork) const override; + int RunProgram(const std::vector<std::string>& args, std::string* result) const override; int Tune2Fs(const std::vector<std::string>& args) const override; bool MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) override; diff --git a/updater/include/updater/updater_runtime.h b/updater/include/updater/updater_runtime.h index b943dfcf..d4b59942 100644 --- a/updater/include/updater/updater_runtime.h +++ b/updater/include/updater/updater_runtime.h @@ -51,6 +51,7 @@ class UpdaterRuntime : public UpdaterRuntimeInterface { int WipeBlockDevice(const std::string_view filename, size_t len) const override; int RunProgram(const std::vector<std::string>& args, bool is_vfork) const override; + int RunProgram(const std::vector<std::string>& args, std::string* result) const override; int Tune2Fs(const std::vector<std::string>& args) const override; bool MapPartitionOnDeviceMapper(const std::string& partition_name, std::string* path) override; diff --git a/updater/install.cpp b/updater/install.cpp index afa5195d..088d0d3c 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -376,6 +376,49 @@ Value* UnmountFn(const char* name, State* state, const std::vector<std::unique_p return StringValue(mount_point); } +enum class FSTools { + FS_TOOL_MK_F2FS = 0, + FS_TOOL_SLOAD_F2FS, + FS_TOOL_MKE2FS, + FS_TOOL_E2FSDROID, +}; + +/* +* Helper function to check file system tools in recovery rootfs +* for various android versions +*/ +static const char* GetFsToolPath(FSTools e_fs_tool) { + static const std::vector<const char*> fs_tool_data[] = { + // FS_TOOL_MK_F2FS + { + "/system/bin/make_f2fs", + "/sbin/mkfs.f2fs", + }, + // FS_TOOL_SLOAD_F2FS + { + "/system/bin/sload_f2fs", + "/sbin/sload.f2fs", + }, + // FS_TOOL_MKE2FS + { + "/system/bin/mke2fs", + "/sbin/mke2fs_static", + }, + // FS_TOOL_E2FSDROID + { + "/system/bin/e2fsdroid", + "/sbin/e2fsdroid_static", + } + }; + + for (auto const& tool : fs_tool_data[static_cast<int>(e_fs_tool)]) { + if (access(tool, X_OK) == 0) { + return tool; + } + } + return nullptr; +} + // format(fs_type, partition_type, location, fs_size, mount_point) // // fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location> @@ -422,8 +465,13 @@ Value* FormatFn(const char* name, State* state, const std::vector<std::unique_pt auto updater_runtime = state->updater->GetRuntime(); if (fs_type == "ext4") { + const char* mke2fs_path = GetFsToolPath(FSTools::FS_TOOL_MKE2FS); + if (mke2fs_path == nullptr){ + LOG(ERROR) << name << ": could not locate mke2fs tool"; + return StringValue(""); + } std::vector<std::string> mke2fs_args = { - "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", location + mke2fs_path, "-t", "ext4", "-b", "4096", location }; if (size != 0) { mke2fs_args.push_back(std::to_string(size / 4096LL)); @@ -434,8 +482,13 @@ Value* FormatFn(const char* name, State* state, const std::vector<std::unique_pt return StringValue(""); } + const char* e2fsdroid_path = GetFsToolPath(FSTools::FS_TOOL_E2FSDROID); + if (e2fsdroid_path == nullptr) { + LOG(ERROR) << name << ": could not locate e2fsdroid tool"; + return StringValue(""); + } if (auto status = updater_runtime->RunProgram( - { "/system/bin/e2fsdroid", "-e", "-a", mount_point, location }, true); + { e2fsdroid_path, "-e", "-a", mount_point, location }, true); status != 0) { LOG(ERROR) << name << ": e2fsdroid failed (" << status << ") on " << location; return StringValue(""); @@ -448,19 +501,71 @@ Value* FormatFn(const char* name, State* state, const std::vector<std::unique_pt LOG(ERROR) << name << ": fs_size can't be negative for f2fs: " << fs_size; return StringValue(""); } - std::vector<std::string> f2fs_args = { - "/system/bin/make_f2fs", "-g", "android", "-w", "512", location - }; + const char* make_f2fs_path = GetFsToolPath(FSTools::FS_TOOL_MK_F2FS); + if (make_f2fs_path == nullptr) { + LOG(ERROR) << name << ": could not locate make_f2fs tool"; + return StringValue(""); + } + std::vector<std::string> f2fs_args; + + /* + * check if old version of mkfs.f2fs is used + * version string format : mkfs.f2fs %d.%d.%d (yyyy-mm-dd) + */ + + std::string mk_f2fs_version; + f2fs_args = {make_f2fs_path, "-V"}; + int exit_code = updater_runtime->RunProgram(f2fs_args, &mk_f2fs_version); + if (exit_code == 0) { + int v[3]; + char c[2]; + if (mk_f2fs_version.size() > strlen("mkfs.f2fs ") && + sscanf (mk_f2fs_version.c_str() + strlen("mkfs.f2fs "), "%d%c%d%c%d", + &v[0], &c[0], &v[1], &c[1], &v[2]) == 5) { + LOG(INFO) << name << ": found mkfs.f2fs ver: " << std::to_string(v[0]) + <<"." << std::to_string(v[1]) + <<"." << std::to_string(v[2]); + } else { + exit_code = -1; + LOG(WARNING) << name << ": invalid mkfs.f2fs version: " << mk_f2fs_version + << "\nOlder version (mkfs.f2fs Ver: 1.10.0) might be used"; + } + } else { + LOG(WARNING) << name << ": old version of mkfs.f2fs is used "; + } + + if (exit_code != 0) { + f2fs_args = { + make_f2fs_path, + "-d1", + "-f", + "-O", "encrypt", + "-O", "quota", + "-O", "verity", + "-w", "512", + location + }; + } else { + f2fs_args = { + make_f2fs_path, "-g", "android", "-w", "512", location + }; + } + if (size >= 512) { f2fs_args.push_back(std::to_string(size / 512)); } + if (auto status = updater_runtime->RunProgram(f2fs_args, true); status != 0) { LOG(ERROR) << name << ": make_f2fs failed (" << status << ") on " << location; return StringValue(""); } - + const char* sload_f2fs_path = GetFsToolPath(FSTools::FS_TOOL_SLOAD_F2FS); + if (sload_f2fs_path == nullptr) { + LOG(ERROR) << name << ": could not locate sload_f2fs tool"; + return StringValue(""); + } if (auto status = updater_runtime->RunProgram( - { "/system/bin/sload_f2fs", "-t", mount_point, location }, true); + { sload_f2fs_path, "-t", mount_point, location }, true); status != 0) { LOG(ERROR) << name << ": sload_f2fs failed (" << status << ") on " << location; return StringValue(""); diff --git a/updater/simulator_runtime.cpp b/updater/simulator_runtime.cpp index 57dfb32d..231a8585 100644 --- a/updater/simulator_runtime.cpp +++ b/updater/simulator_runtime.cpp @@ -76,6 +76,12 @@ int SimulatorRuntime::RunProgram(const std::vector<std::string>& args, bool /* i return 0; } +int SimulatorRuntime::RunProgram(const std::vector<std::string>& args, + std::string* /* result */) const { + LOG(INFO) << "Running program with args " << android::base::Join(args, " "); + return 0; +} + int SimulatorRuntime::Tune2Fs(const std::vector<std::string>& args) const { LOG(INFO) << "Running Tune2Fs with args " << android::base::Join(args, " "); return 0; diff --git a/updater/updater_runtime.cpp b/updater/updater_runtime.cpp index e9383050..6532ed6d 100644 --- a/updater/updater_runtime.cpp +++ b/updater/updater_runtime.cpp @@ -182,6 +182,57 @@ int UpdaterRuntime::RunProgram(const std::vector<std::string>& args, bool is_vfo return status; } +int UpdaterRuntime::RunProgram(const std::vector<std::string>& args, std::string* result) const { + CHECK(!args.empty()); + CHECK(result != nullptr); + int fd[2]; + auto argv = StringVectorToNullTerminatedArray(args); + + LOG(INFO) << "run_program: [" << args[0] << "] with " << argv.size() << " args"; + + *result = ""; + + if (pipe(fd) == -1) { + LOG(INFO) << "run_program: pipe() failed"; + exit(EXIT_FAILURE); + } + + pid_t child = fork(); + if (child == 0) { + // Redirect stdout/stderr to the parent process + dup2(fd[1], STDOUT_FILENO); + dup2(fd[1], STDERR_FILENO); + close(fd[0]); // close unused read end + execv(argv[0], argv.data()); + PLOG(ERROR) << "run_program: execv() failed"; + _exit(EXIT_FAILURE); + } + + close(fd[1]); // close unused write end + static constexpr int MAX_BUF = 64; + char buf[MAX_BUF]; + + while (true) { + size_t count = read(fd[0], buf, MAX_BUF); + if (count <= 0) + break; + result->append(buf, count); + } + close(fd[0]); // close read end + + int status; + waitpid(child, &status, 0); + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) { + LOG(ERROR) << "run_program: child exited with status " << WEXITSTATUS(status); + } + } else if (WIFSIGNALED(status)) { + LOG(ERROR) << "run_program: child terminated by signal " << WTERMSIG(status); + } + + return status; +} + int UpdaterRuntime::Tune2Fs(const std::vector<std::string>& args) const { auto tune2fs_args = StringVectorToNullTerminatedArray(args); // tune2fs changes the filesystem parameters on an ext2 filesystem; it returns 0 on success. |