Loading fastboot/fastboot.cpp +31 −18 Original line number Diff line number Diff line Loading @@ -673,7 +673,7 @@ static unique_fd unzip_to_file(ZipArchiveHandle zip, const char* entry_name) { return fd; } static void CheckRequirement(const std::string& cur_product, const std::string& var, static bool CheckRequirement(const std::string& cur_product, const std::string& var, const std::string& product, bool invert, const std::vector<std::string>& options) { Status("Checking '" + var + "'"); Loading @@ -685,7 +685,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& double split = now(); fprintf(stderr, "IGNORE, product is %s required only for %s [%7.3fs]\n", cur_product.c_str(), product.c_str(), (split - start)); return; return true; } } Loading @@ -694,7 +694,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& fprintf(stderr, "FAILED\n\n"); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb->Error().c_str()); die("requirements not met!"); return false; } bool match = false; Loading @@ -714,7 +714,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& if (match) { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); return; return true; } fprintf(stderr, "FAILED\n\n"); Loading @@ -724,7 +724,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& fprintf(stderr, " or '%s'", it->c_str()); } fprintf(stderr, ".\n\n"); die("requirements not met!"); return false; } bool ParseRequirementLine(const std::string& line, std::string* name, std::string* product, Loading Loading @@ -788,7 +788,7 @@ static void HandlePartitionExists(const std::vector<std::string>& options) { } } static void CheckRequirements(const std::string& data) { static void CheckRequirements(const std::string& data, bool force_flash) { std::string cur_product; if (fb->GetVar("product", &cur_product) != fastboot::SUCCESS) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb->Error().c_str()); Loading @@ -812,7 +812,14 @@ static void CheckRequirements(const std::string& data) { if (name == "partition-exists") { HandlePartitionExists(options); } else { CheckRequirement(cur_product, name, product, invert, options); bool met = CheckRequirement(cur_product, name, product, invert, options); if (!met) { if (!force_flash) { die("requirements not met!"); } else { fprintf(stderr, "requirements not met! but proceeding due to --force\n"); } } } } } Loading Loading @@ -1405,7 +1412,8 @@ class ImageSource { class FlashAllTool { public: FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe); FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash); void Flash(); Loading @@ -1421,16 +1429,19 @@ class FlashAllTool { std::string slot_override_; bool skip_secondary_; bool wipe_; bool force_flash_; std::string secondary_slot_; std::vector<std::pair<const Image*, std::string>> boot_images_; std::vector<std::pair<const Image*, std::string>> os_images_; }; FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe) FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash) : source_(source), slot_override_(slot_override), skip_secondary_(skip_secondary), wipe_(wipe) wipe_(wipe), force_flash_(force_flash) { } Loading Loading @@ -1478,7 +1489,7 @@ void FlashAllTool::CheckRequirements() { if (!source_.ReadFile("android-info.txt", &contents)) { die("could not read android-info.txt"); } ::CheckRequirements({contents.data(), contents.size()}); ::CheckRequirements({contents.data(), contents.size()}, force_flash_); } void FlashAllTool::DetermineSecondarySlot() { Loading Loading @@ -1598,14 +1609,15 @@ unique_fd ZipImageSource::OpenFile(const std::string& name) const { return unzip_to_file(zip_, name.c_str()); } static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) { static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary, bool force_flash) { ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); if (error != 0) { die("failed to open zip file '%s': %s", filename, ErrorCodeString(error)); } FlashAllTool tool(ZipImageSource(zip), slot_override, skip_secondary, false); FlashAllTool tool(ZipImageSource(zip), slot_override, skip_secondary, false, force_flash); tool.Flash(); CloseArchive(zip); Loading @@ -1630,8 +1642,9 @@ unique_fd LocalImageSource::OpenFile(const std::string& name) const { return unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_BINARY))); } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe); static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash) { FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe, force_flash); tool.Flash(); } Loading Loading @@ -2179,9 +2192,9 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "flashall") { if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); do_flashall(slot_override, true, wants_wipe); do_flashall(slot_override, true, wants_wipe, force_flash); } else { do_flashall(slot_override, skip_secondary, wants_wipe); do_flashall(slot_override, skip_secondary, wants_wipe, force_flash); } wants_reboot = true; } else if (command == "update") { Loading @@ -2193,7 +2206,7 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!args.empty()) { filename = next_arg(&args); } do_update(filename.c_str(), slot_override, skip_secondary || slot_all); do_update(filename.c_str(), slot_override, skip_secondary || slot_all, force_flash); wants_reboot = true; } else if (command == FB_CMD_SET_ACTIVE) { std::string slot = verify_slot(next_arg(&args), false); Loading fs_mgr/fs_mgr.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,46 @@ bool fs_mgr_is_f2fs(const std::string& blk_device) { return sb == cpu_to_le32(F2FS_SUPER_MAGIC); } static void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb) { std::string block_device; if (!Realpath(entry_block_device, &block_device)) { PERROR << "Failed to realpath " << entry_block_device; return; } static constexpr std::string_view kDevBlockPrefix("/dev/block/"); if (!android::base::StartsWith(block_device, kDevBlockPrefix)) { LWARNING << block_device << " is not a block device"; return; } DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string block_name = block_device; if (android::base::StartsWith(block_device, kDevBlockPrefix)) { block_name = block_device.substr(kDevBlockPrefix.length()); } std::string sys_partition = android::base::StringPrintf("/sys/class/block/%s/partition", block_name.c_str()); struct stat info; if (lstat(sys_partition.c_str(), &info) == 0) { // it has a partition like "sda12". block_name += "/.."; } std::string sys_ra = android::base::StringPrintf("/sys/class/block/%s/queue/read_ahead_kb", block_name.c_str()); std::string size = android::base::StringPrintf("%llu", (long long)size_kb); android::base::WriteStringToFile(size, sys_ra.c_str()); LINFO << "Set readahead_kb: " << size << " on " << sys_ra; auto parent = dm.GetParentBlockDeviceByPath(block_device); if (!parent) { return; } block_device = *parent; } } // // Prepare the filesystem on the given block device to be mounted. // Loading @@ -667,6 +707,11 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& } mkdir(mount_point.c_str(), 0755); // Don't need to return error, since it's a salt if (entry.readahead_size_kb != -1) { SetReadAheadSize(blk_device, entry.readahead_size_kb); } int fs_stat = 0; if (is_extfs(entry.fs_type)) { Loading fs_mgr/fs_mgr_fstab.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,13 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { entry->reserved_size = static_cast<off64_t>(size); } } else if (StartsWith(flag, "readahead_size_kb=")) { int val; if (ParseInt(arg, &val, 0, 16 * 1024)) { entry->readahead_size_kb = val; } else { LWARNING << "Warning: readahead_size_kb= flag malformed (0 ~ 16MB): " << arg; } } else if (StartsWith(flag, "eraseblk=")) { // The erase block size flag is followed by an = and the flash erase block size. Get it, // check that it is a power of 2 and at least 4096, and return it. Loading fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct FstabEntry { int max_comp_streams = 0; off64_t zram_size = 0; off64_t reserved_size = 0; off64_t readahead_size_kb = -1; std::string encryption_options; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; Loading fs_mgr/tests/fs_mgr_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1097,3 +1097,59 @@ TEST(fs_mgr, UserdataMountedFromDefaultFstab) { ASSERT_NE(nullptr, fs_mgr_get_mounted_entry_for_userdata(&fstab, block_device)) << "/data wasn't mounted from default fstab"; } TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_Readahead_Size_KB) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); std::string fstab_contents = R"fs( source none0 swap defaults readahead_size_kb=blah source none1 swap defaults readahead_size_kb=128 source none2 swap defaults readahead_size_kb=5% source none3 swap defaults readahead_size_kb=5kb source none4 swap defaults readahead_size_kb=16385 source none5 swap defaults readahead_size_kb=-128 source none6 swap defaults readahead_size_kb=0 )fs"; ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path)); Fstab fstab; EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab)); ASSERT_EQ(7U, fstab.size()); FstabEntry::FsMgrFlags flags = {}; auto entry = fstab.begin(); EXPECT_EQ("none0", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none1", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(128, entry->readahead_size_kb); entry++; EXPECT_EQ("none2", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none3", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none4", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none5", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none6", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(0, entry->readahead_size_kb); } Loading
fastboot/fastboot.cpp +31 −18 Original line number Diff line number Diff line Loading @@ -673,7 +673,7 @@ static unique_fd unzip_to_file(ZipArchiveHandle zip, const char* entry_name) { return fd; } static void CheckRequirement(const std::string& cur_product, const std::string& var, static bool CheckRequirement(const std::string& cur_product, const std::string& var, const std::string& product, bool invert, const std::vector<std::string>& options) { Status("Checking '" + var + "'"); Loading @@ -685,7 +685,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& double split = now(); fprintf(stderr, "IGNORE, product is %s required only for %s [%7.3fs]\n", cur_product.c_str(), product.c_str(), (split - start)); return; return true; } } Loading @@ -694,7 +694,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& fprintf(stderr, "FAILED\n\n"); fprintf(stderr, "Could not getvar for '%s' (%s)\n\n", var.c_str(), fb->Error().c_str()); die("requirements not met!"); return false; } bool match = false; Loading @@ -714,7 +714,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& if (match) { double split = now(); fprintf(stderr, "OKAY [%7.3fs]\n", (split - start)); return; return true; } fprintf(stderr, "FAILED\n\n"); Loading @@ -724,7 +724,7 @@ static void CheckRequirement(const std::string& cur_product, const std::string& fprintf(stderr, " or '%s'", it->c_str()); } fprintf(stderr, ".\n\n"); die("requirements not met!"); return false; } bool ParseRequirementLine(const std::string& line, std::string* name, std::string* product, Loading Loading @@ -788,7 +788,7 @@ static void HandlePartitionExists(const std::vector<std::string>& options) { } } static void CheckRequirements(const std::string& data) { static void CheckRequirements(const std::string& data, bool force_flash) { std::string cur_product; if (fb->GetVar("product", &cur_product) != fastboot::SUCCESS) { fprintf(stderr, "getvar:product FAILED (%s)\n", fb->Error().c_str()); Loading @@ -812,7 +812,14 @@ static void CheckRequirements(const std::string& data) { if (name == "partition-exists") { HandlePartitionExists(options); } else { CheckRequirement(cur_product, name, product, invert, options); bool met = CheckRequirement(cur_product, name, product, invert, options); if (!met) { if (!force_flash) { die("requirements not met!"); } else { fprintf(stderr, "requirements not met! but proceeding due to --force\n"); } } } } } Loading Loading @@ -1405,7 +1412,8 @@ class ImageSource { class FlashAllTool { public: FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe); FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash); void Flash(); Loading @@ -1421,16 +1429,19 @@ class FlashAllTool { std::string slot_override_; bool skip_secondary_; bool wipe_; bool force_flash_; std::string secondary_slot_; std::vector<std::pair<const Image*, std::string>> boot_images_; std::vector<std::pair<const Image*, std::string>> os_images_; }; FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe) FlashAllTool::FlashAllTool(const ImageSource& source, const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash) : source_(source), slot_override_(slot_override), skip_secondary_(skip_secondary), wipe_(wipe) wipe_(wipe), force_flash_(force_flash) { } Loading Loading @@ -1478,7 +1489,7 @@ void FlashAllTool::CheckRequirements() { if (!source_.ReadFile("android-info.txt", &contents)) { die("could not read android-info.txt"); } ::CheckRequirements({contents.data(), contents.size()}); ::CheckRequirements({contents.data(), contents.size()}, force_flash_); } void FlashAllTool::DetermineSecondarySlot() { Loading Loading @@ -1598,14 +1609,15 @@ unique_fd ZipImageSource::OpenFile(const std::string& name) const { return unzip_to_file(zip_, name.c_str()); } static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary) { static void do_update(const char* filename, const std::string& slot_override, bool skip_secondary, bool force_flash) { ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); if (error != 0) { die("failed to open zip file '%s': %s", filename, ErrorCodeString(error)); } FlashAllTool tool(ZipImageSource(zip), slot_override, skip_secondary, false); FlashAllTool tool(ZipImageSource(zip), slot_override, skip_secondary, false, force_flash); tool.Flash(); CloseArchive(zip); Loading @@ -1630,8 +1642,9 @@ unique_fd LocalImageSource::OpenFile(const std::string& name) const { return unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_BINARY))); } static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe) { FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe); static void do_flashall(const std::string& slot_override, bool skip_secondary, bool wipe, bool force_flash) { FlashAllTool tool(LocalImageSource(), slot_override, skip_secondary, wipe, force_flash); tool.Flash(); } Loading Loading @@ -2179,9 +2192,9 @@ int FastBootTool::Main(int argc, char* argv[]) { } else if (command == "flashall") { if (slot_override == "all") { fprintf(stderr, "Warning: slot set to 'all'. Secondary slots will not be flashed.\n"); do_flashall(slot_override, true, wants_wipe); do_flashall(slot_override, true, wants_wipe, force_flash); } else { do_flashall(slot_override, skip_secondary, wants_wipe); do_flashall(slot_override, skip_secondary, wants_wipe, force_flash); } wants_reboot = true; } else if (command == "update") { Loading @@ -2193,7 +2206,7 @@ int FastBootTool::Main(int argc, char* argv[]) { if (!args.empty()) { filename = next_arg(&args); } do_update(filename.c_str(), slot_override, skip_secondary || slot_all); do_update(filename.c_str(), slot_override, skip_secondary || slot_all, force_flash); wants_reboot = true; } else if (command == FB_CMD_SET_ACTIVE) { std::string slot = verify_slot(next_arg(&args), false); Loading
fs_mgr/fs_mgr.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,46 @@ bool fs_mgr_is_f2fs(const std::string& blk_device) { return sb == cpu_to_le32(F2FS_SUPER_MAGIC); } static void SetReadAheadSize(const std::string& entry_block_device, off64_t size_kb) { std::string block_device; if (!Realpath(entry_block_device, &block_device)) { PERROR << "Failed to realpath " << entry_block_device; return; } static constexpr std::string_view kDevBlockPrefix("/dev/block/"); if (!android::base::StartsWith(block_device, kDevBlockPrefix)) { LWARNING << block_device << " is not a block device"; return; } DeviceMapper& dm = DeviceMapper::Instance(); while (true) { std::string block_name = block_device; if (android::base::StartsWith(block_device, kDevBlockPrefix)) { block_name = block_device.substr(kDevBlockPrefix.length()); } std::string sys_partition = android::base::StringPrintf("/sys/class/block/%s/partition", block_name.c_str()); struct stat info; if (lstat(sys_partition.c_str(), &info) == 0) { // it has a partition like "sda12". block_name += "/.."; } std::string sys_ra = android::base::StringPrintf("/sys/class/block/%s/queue/read_ahead_kb", block_name.c_str()); std::string size = android::base::StringPrintf("%llu", (long long)size_kb); android::base::WriteStringToFile(size, sys_ra.c_str()); LINFO << "Set readahead_kb: " << size << " on " << sys_ra; auto parent = dm.GetParentBlockDeviceByPath(block_device); if (!parent) { return; } block_device = *parent; } } // // Prepare the filesystem on the given block device to be mounted. // Loading @@ -667,6 +707,11 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& } mkdir(mount_point.c_str(), 0755); // Don't need to return error, since it's a salt if (entry.readahead_size_kb != -1) { SetReadAheadSize(blk_device, entry.readahead_size_kb); } int fs_stat = 0; if (is_extfs(entry.fs_type)) { Loading
fs_mgr/fs_mgr_fstab.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,13 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { } else { entry->reserved_size = static_cast<off64_t>(size); } } else if (StartsWith(flag, "readahead_size_kb=")) { int val; if (ParseInt(arg, &val, 0, 16 * 1024)) { entry->readahead_size_kb = val; } else { LWARNING << "Warning: readahead_size_kb= flag malformed (0 ~ 16MB): " << arg; } } else if (StartsWith(flag, "eraseblk=")) { // The erase block size flag is followed by an = and the flash erase block size. Get it, // check that it is a power of 2 and at least 4096, and return it. Loading
fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ struct FstabEntry { int max_comp_streams = 0; off64_t zram_size = 0; off64_t reserved_size = 0; off64_t readahead_size_kb = -1; std::string encryption_options; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; Loading
fs_mgr/tests/fs_mgr_test.cpp +56 −0 Original line number Diff line number Diff line Loading @@ -1097,3 +1097,59 @@ TEST(fs_mgr, UserdataMountedFromDefaultFstab) { ASSERT_NE(nullptr, fs_mgr_get_mounted_entry_for_userdata(&fstab, block_device)) << "/data wasn't mounted from default fstab"; } TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_Readahead_Size_KB) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); std::string fstab_contents = R"fs( source none0 swap defaults readahead_size_kb=blah source none1 swap defaults readahead_size_kb=128 source none2 swap defaults readahead_size_kb=5% source none3 swap defaults readahead_size_kb=5kb source none4 swap defaults readahead_size_kb=16385 source none5 swap defaults readahead_size_kb=-128 source none6 swap defaults readahead_size_kb=0 )fs"; ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path)); Fstab fstab; EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab)); ASSERT_EQ(7U, fstab.size()); FstabEntry::FsMgrFlags flags = {}; auto entry = fstab.begin(); EXPECT_EQ("none0", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none1", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(128, entry->readahead_size_kb); entry++; EXPECT_EQ("none2", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none3", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none4", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none5", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(-1, entry->readahead_size_kb); entry++; EXPECT_EQ("none6", entry->mount_point); EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); EXPECT_EQ(0, entry->readahead_size_kb); }