aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2022-05-09 17:38:52 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-05-09 17:38:52 +0000
commit6d7ac5c74caf0e4cbcc139375c24beadb6c236a4 (patch)
tree951983e17d88809cfa69710dbc040e0112985667
parent310bd8257d70f91ba82b589cc2eb0473da7394a3 (diff)
parentc2f616c150a9f5c2976d0ff5849577790d2bc5b5 (diff)
downloadrecovery-android11-dev.tar.gz
Merge "Add checking FS utilities for updater" into android11-devandroid11-dev
-rw-r--r--edify/include/edify/updater_runtime_interface.h4
-rw-r--r--updater/include/updater/simulator_runtime.h1
-rw-r--r--updater/include/updater/updater_runtime.h1
-rw-r--r--updater/install.cpp119
-rw-r--r--updater/simulator_runtime.cpp6
-rw-r--r--updater/updater_runtime.cpp51
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.