diff options
-rw-r--r-- | Android.mk | 8 | ||||
-rw-r--r-- | roots.cpp | 62 | ||||
-rw-r--r-- | tests/Android.mk | 4 | ||||
-rw-r--r-- | tests/component/update_verifier_test.cpp | 2 | ||||
-rw-r--r-- | tests/component/updater_test.cpp | 96 | ||||
-rw-r--r-- | update_verifier/Android.mk | 4 | ||||
-rw-r--r-- | update_verifier/update_verifier.cpp | 21 | ||||
-rw-r--r-- | updater/install.cpp | 27 |
8 files changed, 110 insertions, 114 deletions
diff --git a/Android.mk b/Android.mk index 5ce9d335c..bbb204660 100644 --- a/Android.mk +++ b/Android.mk @@ -84,9 +84,11 @@ LOCAL_MODULE := recovery LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_REQUIRED_MODULES := e2fsdroid_static mke2fs_static mke2fs.conf + ifeq ($(TARGET_USERIMAGES_USE_F2FS),true) ifeq ($(HOST_OS),linux) -LOCAL_REQUIRED_MODULES := mkfs.f2fs +LOCAL_REQUIRED_MODULES += mkfs.f2fs endif endif @@ -113,6 +115,7 @@ LOCAL_STATIC_LIBRARIES := \ libverifier \ libbatterymonitor \ libbootloader_message \ + libfs_mgr \ libext4_utils \ libsparse \ libziparchive \ @@ -123,7 +126,6 @@ LOCAL_STATIC_LIBRARIES := \ libfusesideload \ libminui \ libpng \ - libfs_mgr \ libcrypto_utils \ libcrypto \ libvintf_recovery \ @@ -152,7 +154,7 @@ else endif ifeq ($(BOARD_CACHEIMAGE_PARTITION_SIZE),) -LOCAL_REQUIRED_MODULES := recovery-persist recovery-refresh +LOCAL_REQUIRED_MODULES += recovery-persist recovery-refresh endif include $(BUILD_EXECUTABLE) @@ -27,7 +27,8 @@ #include <fcntl.h> #include <android-base/logging.h> -#include <ext4_utils/make_ext4fs.h> +#include <android-base/properties.h> +#include <android-base/stringprintf.h> #include <ext4_utils/wipe.h> #include <fs_mgr.h> @@ -215,11 +216,60 @@ int format_volume(const char* volume, const char* directory) { } int result; if (strcmp(v->fs_type, "ext4") == 0) { - if (v->erase_blk_size != 0 && v->logical_blk_size != 0) { - result = make_ext4fs_directory_align(v->blk_device, length, volume, sehandle, - directory, v->erase_blk_size, v->logical_blk_size); - } else { - result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory); + static constexpr int block_size = 4096; + int raid_stride = v->logical_blk_size / block_size; + int raid_stripe_width = v->erase_blk_size / block_size; + + // stride should be the max of 8kb and logical block size + if (v->logical_blk_size != 0 && v->logical_blk_size < 8192) { + raid_stride = 8192 / block_size; + } + + const char* mke2fs_argv[] = { "/sbin/mke2fs_static", + "-F", + "-t", + "ext4", + "-b", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr }; + + int i = 5; + std::string block_size_str = std::to_string(block_size); + mke2fs_argv[i++] = block_size_str.c_str(); + + std::string ext_args; + if (v->erase_blk_size != 0 && v->logical_blk_size != 0) { + ext_args = android::base::StringPrintf("stride=%d,stripe-width=%d", raid_stride, + raid_stripe_width); + mke2fs_argv[i++] = "-E"; + mke2fs_argv[i++] = ext_args.c_str(); + } + + mke2fs_argv[i++] = v->blk_device; + + std::string size_str = std::to_string(length / block_size); + if (length != 0) { + mke2fs_argv[i++] = size_str.c_str(); + } + + result = exec_cmd(mke2fs_argv[0], const_cast<char**>(mke2fs_argv)); + if (result == 0 && directory != nullptr) { + const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static", + "-e", + "-S", + "/file_contexts", + "-f", + directory, + "-a", + volume, + v->blk_device, + nullptr }; + + result = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv)); } } else { /* Has to be f2fs because we checked earlier. */ if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { diff --git a/tests/Android.mk b/tests/Android.mk index 262f4ffdd..346873dbe 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -92,6 +92,10 @@ ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true) LOCAL_CFLAGS += -DPRODUCT_SUPPORTS_VERITY=1 endif +ifeq ($(BOARD_AVB_ENABLE),true) +LOCAL_CFLAGS += -DBOARD_AVB_ENABLE=1 +endif + LOCAL_MODULE := recovery_component_test LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_C_INCLUDES := bootable/recovery diff --git a/tests/component/update_verifier_test.cpp b/tests/component/update_verifier_test.cpp index 73b4478aa..5fc7ef63f 100644 --- a/tests/component/update_verifier_test.cpp +++ b/tests/component/update_verifier_test.cpp @@ -24,7 +24,7 @@ class UpdateVerifierTest : public ::testing::Test { protected: void SetUp() override { -#ifdef PRODUCT_SUPPORTS_VERITY +#if defined(PRODUCT_SUPPORTS_VERITY) || defined(BOARD_AVB_ENABLE) verity_supported = true; #else verity_supported = false; diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp index 35e87fd56..0298a7645 100644 --- a/tests/component/updater_test.cpp +++ b/tests/component/updater_test.cpp @@ -224,102 +224,6 @@ TEST_F(UpdaterTest, file_getprop) { expect("", script6.c_str(), kNoCause); } -TEST_F(UpdaterTest, package_extract_dir) { - // package_extract_dir expects 2 arguments. - expect(nullptr, "package_extract_dir()", kArgsParsingFailure); - expect(nullptr, "package_extract_dir(\"arg1\")", kArgsParsingFailure); - expect(nullptr, "package_extract_dir(\"arg1\", \"arg2\", \"arg3\")", kArgsParsingFailure); - - std::string zip_path = from_testdata_base("ziptest_valid.zip"); - ZipArchiveHandle handle; - ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); - - // Need to set up the ziphandle. - UpdaterInfo updater_info; - updater_info.package_zip = handle; - - // Extract "b/c.txt" and "b/d.txt" with package_extract_dir("b", "<dir>"). - TemporaryDir td; - std::string temp_dir(td.path); - std::string script("package_extract_dir(\"b\", \"" + temp_dir + "\")"); - expect("t", script.c_str(), kNoCause, &updater_info); - - // Verify. - std::string data; - std::string file_c = temp_dir + "/c.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_c, &data)); - ASSERT_EQ(kCTxtContents, data); - - std::string file_d = temp_dir + "/d.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_d, &data)); - ASSERT_EQ(kDTxtContents, data); - - // Modify the contents in order to retry. It's expected to be overwritten. - ASSERT_TRUE(android::base::WriteStringToFile("random", file_c)); - ASSERT_TRUE(android::base::WriteStringToFile("random", file_d)); - - // Extract again and verify. - expect("t", script.c_str(), kNoCause, &updater_info); - - ASSERT_TRUE(android::base::ReadFileToString(file_c, &data)); - ASSERT_EQ(kCTxtContents, data); - ASSERT_TRUE(android::base::ReadFileToString(file_d, &data)); - ASSERT_EQ(kDTxtContents, data); - - // Clean up the temp files under td. - ASSERT_EQ(0, unlink(file_c.c_str())); - ASSERT_EQ(0, unlink(file_d.c_str())); - - // Extracting "b/" (with slash) should give the same result. - script = "package_extract_dir(\"b/\", \"" + temp_dir + "\")"; - expect("t", script.c_str(), kNoCause, &updater_info); - - ASSERT_TRUE(android::base::ReadFileToString(file_c, &data)); - ASSERT_EQ(kCTxtContents, data); - ASSERT_TRUE(android::base::ReadFileToString(file_d, &data)); - ASSERT_EQ(kDTxtContents, data); - - ASSERT_EQ(0, unlink(file_c.c_str())); - ASSERT_EQ(0, unlink(file_d.c_str())); - - // Extracting "" is allowed. The entries will carry the path name. - script = "package_extract_dir(\"\", \"" + temp_dir + "\")"; - expect("t", script.c_str(), kNoCause, &updater_info); - - std::string file_a = temp_dir + "/a.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_a, &data)); - ASSERT_EQ(kATxtContents, data); - std::string file_b = temp_dir + "/b.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_b, &data)); - ASSERT_EQ(kBTxtContents, data); - std::string file_b_c = temp_dir + "/b/c.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_b_c, &data)); - ASSERT_EQ(kCTxtContents, data); - std::string file_b_d = temp_dir + "/b/d.txt"; - ASSERT_TRUE(android::base::ReadFileToString(file_b_d, &data)); - ASSERT_EQ(kDTxtContents, data); - - ASSERT_EQ(0, unlink(file_a.c_str())); - ASSERT_EQ(0, unlink(file_b.c_str())); - ASSERT_EQ(0, unlink(file_b_c.c_str())); - ASSERT_EQ(0, unlink(file_b_d.c_str())); - ASSERT_EQ(0, rmdir((temp_dir + "/b").c_str())); - - // Extracting non-existent entry should still give "t". - script = "package_extract_dir(\"doesntexist\", \"" + temp_dir + "\")"; - expect("t", script.c_str(), kNoCause, &updater_info); - - // Only relative zip_path is allowed. - script = "package_extract_dir(\"/b\", \"" + temp_dir + "\")"; - expect("", script.c_str(), kNoCause, &updater_info); - - // Only absolute dest_path is allowed. - script = "package_extract_dir(\"b\", \"path\")"; - expect("", script.c_str(), kNoCause, &updater_info); - - CloseArchive(handle); -} - // TODO: Test extracting to block device. TEST_F(UpdaterTest, package_extract_file) { // package_extract_file expects 1 or 2 arguments. diff --git a/update_verifier/Android.mk b/update_verifier/Android.mk index 37d9bfed3..33c5fe9e7 100644 --- a/update_verifier/Android.mk +++ b/update_verifier/Android.mk @@ -39,6 +39,10 @@ ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true) LOCAL_CFLAGS += -DPRODUCT_SUPPORTS_VERITY=1 endif +ifeq ($(BOARD_AVB_ENABLE),true) +LOCAL_CFLAGS += -DBOARD_AVB_ENABLE=1 +endif + include $(BUILD_STATIC_LIBRARY) # update_verifier (executable) diff --git a/update_verifier/update_verifier.cpp b/update_verifier/update_verifier.cpp index fdbcfde56..d3a5185b8 100644 --- a/update_verifier/update_verifier.cpp +++ b/update_verifier/update_verifier.cpp @@ -99,12 +99,21 @@ static bool read_blocks(const std::string& partition, const std::string& range_s std::string content; if (!android::base::ReadFileToString(path, &content)) { PLOG(WARNING) << "Failed to read " << path; - } else if (android::base::Trim(content) == partition) { - dm_block_device = DEV_PATH + std::string(namelist[n]->d_name); - while (n--) { - free(namelist[n]); + } else { + std::string dm_block_name = android::base::Trim(content); +#ifdef BOARD_AVB_ENABLE + // AVB is using 'vroot' for the root block device but we're expecting 'system'. + if (dm_block_name == "vroot") { + dm_block_name = "system"; + } +#endif + if (dm_block_name == partition) { + dm_block_device = DEV_PATH + std::string(namelist[n]->d_name); + while (n--) { + free(namelist[n]); + } + break; } - break; } free(namelist[n]); } @@ -229,7 +238,7 @@ int update_verifier(int argc, char** argv) { if (is_successful == BoolResult::FALSE) { // The current slot has not booted successfully. -#ifdef PRODUCT_SUPPORTS_VERITY +#if defined(PRODUCT_SUPPORTS_VERITY) || defined(BOARD_AVB_ENABLE) std::string verity_mode = android::base::GetProperty("ro.boot.veritymode", ""); if (verity_mode.empty()) { LOG(ERROR) << "Failed to get dm-verity mode."; diff --git a/updater/install.cpp b/updater/install.cpp index ff79edce0..c9a3a0799 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -302,9 +302,32 @@ Value* FormatFn(const char* name, State* state, const std::vector<std::unique_pt } if (fs_type == "ext4") { - int status = make_ext4fs(location.c_str(), size, mount_point.c_str(), sehandle); + const char* mke2fs_argv[] = { "/sbin/mke2fs_static", "-t", "ext4", "-b", "4096", + location.c_str(), nullptr, nullptr }; + std::string size_str; + if (size != 0) { + size_str = std::to_string(size / 4096LL); + mke2fs_argv[6] = size_str.c_str(); + } + + int status = exec_cmd(mke2fs_argv[0], const_cast<char**>(mke2fs_argv)); + if (status != 0) { + LOG(WARNING) << name << ": mke2fs failed (" << status << ") on " << location + << ", falling back to make_ext4fs"; + status = make_ext4fs(location.c_str(), size, mount_point.c_str(), sehandle); + if (status != 0) { + LOG(ERROR) << name << ": make_ext4fs failed (" << status << ") on " << location; + return StringValue(""); + } + return StringValue(location); + } + + const char* e2fsdroid_argv[] = { "/sbin/e2fsdroid_static", "-e", "-S", + "/file_contexts", "-a", mount_point.c_str(), + location.c_str(), nullptr }; + status = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv)); if (status != 0) { - LOG(ERROR) << name << ": make_ext4fs failed (" << status << ") on " << location; + LOG(ERROR) << name << ": e2fsdroid failed (" << status << ") on " << location; return StringValue(""); } return StringValue(location); |