diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 80def732c..dd8bad9aa 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -40,6 +40,7 @@ LOCAL_MODULE := fastboot LOCAL_MODULE_TAGS := debug LOCAL_MODULE_HOST_OS := darwin linux windows LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code +LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid LOCAL_SRC_FILES_linux := usb_linux.cpp LOCAL_STATIC_LIBRARIES_linux := libselinux @@ -85,6 +86,8 @@ LOCAL_SHARED_LIBRARIES := include $(BUILD_HOST_EXECUTABLE) my_dist_files := $(LOCAL_BUILT_MODULE) +my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) +my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX) ifeq ($(HOST_OS),linux) my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX) endif diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp index 99ca7dd81..f3c000eb7 100644 --- a/fastboot/fs.cpp +++ b/fastboot/fs.cpp @@ -10,14 +10,22 @@ #include #include #include +#ifndef WIN32 +#include +#endif #include +#include +#include +#include #include #include #include +using android::base::StringPrintf; using android::base::unique_fd; +#ifdef WIN32 static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { @@ -34,6 +42,84 @@ static int generate_ext4_image(const char* fileName, long long partSize, const s } return 0; } +#else +static int exec_e2fs_cmd(const char* path, char* const argv[]) { + int status; + pid_t child; + if ((child = fork()) == 0) { + setenv("MKE2FS_CONFIG", "", 1); + execvp(path, argv); + _exit(EXIT_FAILURE); + } + if (child < 0) { + fprintf(stderr, "%s failed with fork %s\n", path, strerror(errno)); + return -1; + } + if (TEMP_FAILURE_RETRY(waitpid(child, &status, 0)) == -1) { + fprintf(stderr, "%s failed with waitpid %s\n", path, strerror(errno)); + return -1; + } + int ret = -1; + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + if (ret != 0) { + fprintf(stderr, "%s failed with status %d\n", path, ret); + } + } + return ret; +} + +static int generate_ext4_image(const char* fileName, long long partSize, + const std::string& initial_dir, unsigned eraseBlkSize, + unsigned logicalBlkSize) { + static constexpr int block_size = 4096; + const std::string exec_dir = android::base::GetExecutableDirectory(); + + const std::string mke2fs_path = exec_dir + "/mke2fs"; + std::vector mke2fs_args = {mke2fs_path.c_str(), "-t", "ext4", "-b"}; + + std::string block_size_str = std::to_string(block_size); + mke2fs_args.push_back(block_size_str.c_str()); + + std::string ext_attr = "android_sparse"; + if (eraseBlkSize != 0 && logicalBlkSize != 0) { + int raid_stride = logicalBlkSize / block_size; + int raid_stripe_width = eraseBlkSize / block_size; + // stride should be the max of 8kb and logical block size + if (logicalBlkSize != 0 && logicalBlkSize < 8192) raid_stride = 8192 / block_size; + ext_attr += StringPrintf(",stride=%d,stripe-width=%d", raid_stride, raid_stripe_width); + } + mke2fs_args.push_back("-E"); + mke2fs_args.push_back(ext_attr.c_str()); + mke2fs_args.push_back(fileName); + + std::string size_str = std::to_string(partSize / block_size); + mke2fs_args.push_back(size_str.c_str()); + mke2fs_args.push_back(nullptr); + + int ret = exec_e2fs_cmd(mke2fs_args[0], const_cast(mke2fs_args.data())); + if (ret != 0) { + fprintf(stderr, "mke2fs failed: %d\n", ret); + return -1; + } + + if (initial_dir.empty()) { + return 0; + } + + const std::string e2fsdroid_path = exec_dir + "/e2fsdroid"; + std::vector e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(), + fileName, nullptr}; + + ret = exec_e2fs_cmd(e2fsdroid_args[0], const_cast(e2fsdroid_args.data())); + if (ret != 0) { + fprintf(stderr, "e2fsdroid failed: %d\n", ret); + return -1; + } + + return 0; +} +#endif #ifdef USE_F2FS static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp index 5705f937f..a03d92c6b 100644 --- a/fs_mgr/fs_mgr_format.cpp +++ b/fs_mgr/fs_mgr_format.cpp @@ -86,13 +86,15 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) static int format_f2fs(char *fs_blkdev) { - char * args[3]; + char * args[5]; int pid; int rc = 0; - args[0] = (char *)"/sbin/mkfs.f2fs"; - args[1] = fs_blkdev; - args[2] = (char *)0; + args[0] = (char *)"/system/bin/make_f2fs"; + args[1] = (char *)"-f"; + args[2] = (char *)"-O encrypt"; + args[3] = fs_blkdev; + args[4] = (char *)0; pid = fork(); if (pid < 0) { @@ -100,7 +102,7 @@ static int format_f2fs(char *fs_blkdev) } if (!pid) { /* This doesn't return */ - execv("/sbin/mkfs.f2fs", args); + execv(args[0], args); exit(1); } for(;;) { diff --git a/init/Android.bp b/init/Android.bp index 47578ead0..82945981e 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -94,6 +94,10 @@ cc_binary { name: "init", defaults: ["init_defaults"], + required: [ + "e2fsdroid", + "mke2fs", + ], static_executable: true, srcs: [ "bootchart.cpp", diff --git a/init/Android.mk b/init/Android.mk index 325614e3a..670edc049 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -89,6 +89,10 @@ LOCAL_STATIC_LIBRARIES := \ libavb \ libkeyutils \ +LOCAL_REQUIRED_MODULES := \ + e2fsdroid \ + mke2fs \ + # Create symlinks. LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \ diff --git a/init/init.cpp b/init/init.cpp index 0dfaf9e59..57d19552a 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -930,8 +930,8 @@ static void selinux_restore_context() { selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); selinux_android_restorecon("/dev/device-mapper", 0); - selinux_android_restorecon("/sbin/mke2fs", 0); - selinux_android_restorecon("/sbin/e2fsdroid", 0); + selinux_android_restorecon("/sbin/mke2fs_static", 0); + selinux_android_restorecon("/sbin/e2fsdroid_static", 0); } // Set the UDC controller for the ConfigFS USB Gadgets.