diff options
-rw-r--r-- | adb/daemon/remount_service.cpp | 16 | ||||
-rw-r--r-- | fs_mgr/fs_mgr.cpp | 24 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_overlayfs.cpp | 64 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr_overlayfs.h | 2 | ||||
-rw-r--r-- | fs_mgr/liblp/builder.cpp | 8 | ||||
-rw-r--r-- | fs_mgr/liblp/builder_test.cpp | 24 | ||||
-rw-r--r-- | fs_mgr/liblp/include/liblp/builder.h | 1 | ||||
-rw-r--r-- | init/first_stage_mount.cpp | 2 | ||||
-rw-r--r-- | libgrallocusage/OWNERS | 3 | ||||
-rw-r--r-- | mkbootimg/include/bootimg/bootimg.h | 35 | ||||
-rwxr-xr-x | mkbootimg/mkbootimg | 5 |
11 files changed, 109 insertions, 75 deletions
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp index cf4d2944a..380dfa653 100644 --- a/adb/daemon/remount_service.cpp +++ b/adb/daemon/remount_service.cpp @@ -146,6 +146,10 @@ static bool remount_partition(int fd, const char* dir) { return true; } bool is_root = strcmp(dir, "/") == 0; + if (is_root && !find_mount("/system", false).empty()) { + dir = "/system"; + is_root = false; + } std::string dev = find_mount(dir, is_root); // Even if the device for the root is not found, we still try to remount it // as rw. This typically only happens when running Android in a container: @@ -216,13 +220,19 @@ void remount_service(unique_fd fd, const std::string& cmd) { // If we can use overlayfs, lets get it in place first // before we struggle with determining deduplication operations. - if (!verity_enabled && fs_mgr_overlayfs_setup() && fs_mgr_overlayfs_mount_all()) { - WriteFdExactly(fd.get(), "overlayfs mounted\n"); + if (!verity_enabled && fs_mgr_overlayfs_setup()) { + std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), + fs_mgr_free_fstab); + if (fs_mgr_overlayfs_mount_all(fstab.get())) { + WriteFdExactly(fd.get(), "overlayfs mounted\n"); + } } // Find partitions that are deduplicated, and can be un-deduplicated. std::set<std::string> dedup; - for (const auto& partition : partitions) { + for (const auto& part : partitions) { + auto partition = part; + if ((part == "/") && !find_mount("/system", false).empty()) partition = "/system"; std::string dev = find_mount(partition.c_str(), partition == "/"); if (dev.empty() || !fs_mgr_has_shared_blocks(partition, dev)) { continue; diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 10cd9e7f0..d29ccf438 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -569,8 +569,7 @@ static int fs_match(const char *in1, const char *in2) * -1 on failure with errno set to match the 1st mount failure. * 0 on success. */ -static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx) -{ +static int mount_with_alternatives(fstab* fstab, int start_idx, int* end_idx, int* attempted_idx) { int i; int mount_errno = 0; int mounted = 0; @@ -863,8 +862,7 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) { * first successful mount. * Returns -1 on error, and FS_MGR_MNTALL_* otherwise. */ -int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) -{ +int fs_mgr_mount_all(fstab* fstab, int mount_mode) { int i = 0; int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; int error_count = 0; @@ -1093,7 +1091,7 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode) } #if ALLOW_ADBD_DISABLE_VERITY == 1 // "userdebug" build - fs_mgr_overlayfs_mount_all(); + fs_mgr_overlayfs_mount_all(fstab); #endif if (error_count) { @@ -1129,7 +1127,7 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec) * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one * in turn, and stop on 1st success, or no more match. */ -static int fs_mgr_do_mount_helper(struct fstab* fstab, const char* n_name, char* n_blk_device, +static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, int need_checkpoint) { int i = 0; int mount_errors = 0; @@ -1244,13 +1242,12 @@ static int fs_mgr_do_mount_helper(struct fstab* fstab, const char* n_name, char* return FS_MGR_DOMNT_FAILED; } -int fs_mgr_do_mount(struct fstab* fstab, const char* n_name, char* n_blk_device, - char* tmp_mount_point) { +int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, -1); } -int fs_mgr_do_mount(struct fstab* fstab, const char* n_name, char* n_blk_device, - char* tmp_mount_point, bool needs_cp) { +int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, + bool needs_cp) { return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_cp); } @@ -1276,8 +1273,7 @@ int fs_mgr_do_tmpfs_mount(const char *n_name) /* This must be called after mount_all, because the mkswap command needs to be * available. */ -int fs_mgr_swapon_all(struct fstab *fstab) -{ +int fs_mgr_swapon_all(fstab* fstab) { int i = 0; int flags = 0; int err = 0; @@ -1367,7 +1363,7 @@ int fs_mgr_swapon_all(struct fstab *fstab) return ret; } -struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab) { +struct fstab_rec const* fs_mgr_get_crypt_entry(fstab const* fstab) { int i; if (!fstab) { @@ -1391,7 +1387,7 @@ struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab) { * * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long */ -void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size) { +void fs_mgr_get_crypt_info(fstab* fstab, char* key_loc, char* real_blk_device, size_t size) { struct fstab_rec const* rec = fs_mgr_get_crypt_entry(fstab); if (key_loc) { if (rec) { diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index b39a418f7..c0bef2c7e 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -49,7 +49,7 @@ using namespace std::literals; #if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs -bool fs_mgr_overlayfs_mount_all() { +bool fs_mgr_overlayfs_mount_all(const fstab*) { return false; } @@ -194,6 +194,31 @@ bool fs_mgr_wants_overlayfs() { return overlayfs_in_kernel; } +bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point) { + std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab("/proc/mounts"), + fs_mgr_free_fstab); + if (!fstab) return false; + const auto lowerdir = kLowerdirOption + mount_point; + for (auto i = 0; i < fstab->num_entries; ++i) { + const auto fsrec = &fstab->recs[i]; + const auto fs_type = fsrec->fs_type; + if (!fs_type) continue; + if (("overlay"s != fs_type) && ("overlayfs"s != fs_type)) continue; + auto fsrec_mount_point = fsrec->mount_point; + if (!fsrec_mount_point) continue; + if (mount_point != fsrec_mount_point) continue; + const auto fs_options = fsrec->fs_options; + if (!fs_options) continue; + const auto options = android::base::Split(fs_options, ","); + for (const auto& opt : options) { + if (opt == lowerdir) { + return true; + } + } + } + return false; +} + bool fs_mgr_wants_overlayfs(const fstab_rec* fsrec) { if (!fsrec) return false; @@ -345,31 +370,6 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) { } } -bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point) { - std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab( - fs_mgr_read_fstab("/proc/mounts"), fs_mgr_free_fstab); - if (!fstab) return false; - const auto lowerdir = kLowerdirOption + mount_point; - for (auto i = 0; i < fstab->num_entries; ++i) { - const auto fsrec = &fstab->recs[i]; - const auto fs_type = fsrec->fs_type; - if (!fs_type) continue; - if (("overlay"s != fs_type) && ("overlayfs"s != fs_type)) continue; - auto fsrec_mount_point = fsrec->mount_point; - if (!fsrec_mount_point) continue; - if (mount_point != fsrec_mount_point) continue; - const auto fs_options = fsrec->fs_options; - if (!fs_options) continue; - const auto options = android::base::Split(fs_options, ","); - for (const auto opt : options) { - if (opt == lowerdir) { - return true; - } - } - } - return false; -} - std::vector<std::string> fs_mgr_candidate_list(const fstab* fstab, const char* mount_point = nullptr) { std::vector<std::string> mounts; @@ -400,16 +400,14 @@ std::vector<std::string> fs_mgr_candidate_list(const fstab* fstab, } // namespace -bool fs_mgr_overlayfs_mount_all() { +bool fs_mgr_overlayfs_mount_all(const fstab* fstab) { auto ret = false; if (!fs_mgr_wants_overlayfs()) return ret; - std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); if (!fstab) return ret; - for (const auto& mount_point : fs_mgr_candidate_list(fstab.get())) { + for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { if (fs_mgr_overlayfs_already_mounted(mount_point)) continue; if (fs_mgr_overlayfs_mount(mount_point)) ret = true; } @@ -432,8 +430,8 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } - std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); + std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), + fs_mgr_free_fstab); if (fstab && !fs_mgr_get_entry_for_mount_point(fstab.get(), kOverlayMountPoint)) return ret; auto mounts = fs_mgr_candidate_list(fstab.get(), fs_mgr_mount_point(fstab.get(), mount_point)); if (fstab && mounts.empty()) return ret; @@ -464,7 +462,7 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* // If something is altered, set *change. bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if (change) *change = false; - mount_point = fs_mgr_mount_point(std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)>( + mount_point = fs_mgr_mount_point(std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)>( fs_mgr_read_fstab_default(), fs_mgr_free_fstab) .get(), mount_point); diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h index ceb45de3e..251dd9b91 100644 --- a/fs_mgr/include/fs_mgr_overlayfs.h +++ b/fs_mgr/include/fs_mgr_overlayfs.h @@ -20,7 +20,7 @@ #include <string> -bool fs_mgr_overlayfs_mount_all(); +bool fs_mgr_overlayfs_mount_all(const fstab* fstab); bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr, bool* change = nullptr); bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr); diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 018c2802c..352647b8e 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -482,6 +482,14 @@ uint64_t MetadataBuilder::AllocatableSpace() const { return (geometry_.last_logical_sector - geometry_.first_logical_sector + 1) * LP_SECTOR_SIZE; } +uint64_t MetadataBuilder::UsedSpace() const { + uint64_t size = 0; + for (const auto& partition : partitions_) { + size += partition->size(); + } + return size; +} + uint64_t MetadataBuilder::AlignSector(uint64_t sector) { // Note: when reading alignment info from the Kernel, we don't assume it // is aligned to the sector size, so we round up to the nearest sector. diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp index da9c8f37e..0c7e43d24 100644 --- a/fs_mgr/liblp/builder_test.cpp +++ b/fs_mgr/liblp/builder_test.cpp @@ -202,14 +202,28 @@ TEST(liblp, InternalPartitionAlignment) { } TEST(liblp, UseAllDiskSpace) { - unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(1024 * 1024, 1024, 2); - EXPECT_EQ(builder->AllocatableSpace(), 1036288); + static constexpr uint64_t total = 1024 * 1024; + static constexpr uint64_t metadata = 1024; + static constexpr uint64_t slots = 2; + unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(total, metadata, slots); + // We reserve a geometry block (4KB) plus space for each copy of the + // maximum size of a metadata blob. Then, we double that space since + // we store a backup copy of everything. + static constexpr uint64_t geometry = 4 * 1024; + static constexpr uint64_t allocatable = total - (metadata * slots + geometry) * 2; + EXPECT_EQ(builder->AllocatableSpace(), allocatable); + EXPECT_EQ(builder->UsedSpace(), 0); Partition* system = builder->AddPartition("system", TEST_GUID, LP_PARTITION_ATTR_READONLY); ASSERT_NE(system, nullptr); - EXPECT_EQ(builder->ResizePartition(system, 1036288), true); - EXPECT_EQ(system->size(), 1036288); - EXPECT_EQ(builder->ResizePartition(system, 1036289), false); + EXPECT_EQ(builder->ResizePartition(system, allocatable), true); + EXPECT_EQ(system->size(), allocatable); + EXPECT_EQ(builder->UsedSpace(), allocatable); + EXPECT_EQ(builder->AllocatableSpace(), allocatable); + EXPECT_EQ(builder->ResizePartition(system, allocatable + 1), false); + EXPECT_EQ(system->size(), allocatable); + EXPECT_EQ(builder->UsedSpace(), allocatable); + EXPECT_EQ(builder->AllocatableSpace(), allocatable); } TEST(liblp, BuildComplex) { diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h index 38842a4e6..27808256f 100644 --- a/fs_mgr/liblp/include/liblp/builder.h +++ b/fs_mgr/liblp/include/liblp/builder.h @@ -184,6 +184,7 @@ class MetadataBuilder { // Amount of space that can be allocated to logical partitions. uint64_t AllocatableSpace() const; + uint64_t UsedSpace() const; // Merge new block device information into previous values. Alignment values // are only overwritten if the new values are non-zero. diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 79cfbcb4e..1f4bec1bd 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -388,7 +388,7 @@ bool FirstStageMount::MountPartitions() { } } - fs_mgr_overlayfs_mount_all(); + fs_mgr_overlayfs_mount_all(device_tree_fstab_.get()); return true; } diff --git a/libgrallocusage/OWNERS b/libgrallocusage/OWNERS new file mode 100644 index 000000000..154dc6d1b --- /dev/null +++ b/libgrallocusage/OWNERS @@ -0,0 +1,3 @@ +jessehall@google.com +olv@google.com +stoza@google.com diff --git a/mkbootimg/include/bootimg/bootimg.h b/mkbootimg/include/bootimg/bootimg.h index bce308b02..4432f9ec9 100644 --- a/mkbootimg/include/bootimg/bootimg.h +++ b/mkbootimg/include/bootimg/bootimg.h @@ -110,25 +110,25 @@ typedef struct boot_img_hdr_v0 boot_img_hdr; */ struct boot_img_hdr_v1 : public boot_img_hdr_v0 { - uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO image */ - uint64_t recovery_dtbo_offset; /* offset to recovery dtbo in boot image */ + uint32_t recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */ + uint64_t recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */ uint32_t header_size; } __attribute__((packed)); /* When the boot image header has a version of 1, the structure of the boot * image is as follows: * - * +-----------------+ - * | boot header | 1 page - * +-----------------+ - * | kernel | n pages - * +-----------------+ - * | ramdisk | m pages - * +-----------------+ - * | second stage | o pages - * +-----------------+ - * | recovery dtbo | p pages - * +-----------------+ + * +---------------------+ + * | boot header | 1 page + * +---------------------+ + * | kernel | n pages + * +---------------------+ + * | ramdisk | m pages + * +---------------------+ + * | second stage | o pages + * +---------------------+ + * | recovery dtbo/acpio | p pages + * +---------------------+ * n = (kernel_size + page_size - 1) / page_size * m = (ramdisk_size + page_size - 1) / page_size * o = (second_size + page_size - 1) / page_size @@ -136,13 +136,14 @@ struct boot_img_hdr_v1 : public boot_img_hdr_v0 { * * 0. all entities are page_size aligned in flash * 1. kernel and ramdisk are required (size != 0) - * 2. recovery_dtbo is required for recovery.img in non-A/B devices(recovery_dtbo_size != 0) + * 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B + * devices(recovery_dtbo_size != 0) * 3. second is optional (second_size == 0 -> no second) * 4. load each element (kernel, ramdisk, second) at * the specified physical address (kernel_addr, etc) - * 5. If booting to recovery mode in a non-A/B device, extract recovery dtbo and - * apply the correct set of overlays on the base device tree depending on the - * hardware/product revision. + * 5. If booting to recovery mode in a non-A/B device, extract recovery + * dtbo/acpio and apply the correct set of overlays on the base device tree + * depending on the hardware/product revision. * 6. prepare tags at tag_addr. kernel_args[] is * appended to the kernel commandline in the tags. * 7. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr diff --git a/mkbootimg/mkbootimg b/mkbootimg/mkbootimg index fda9af0d2..2eb2bab56 100755 --- a/mkbootimg/mkbootimg +++ b/mkbootimg/mkbootimg @@ -161,7 +161,10 @@ def parse_cmdline(): required=True) parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb')) parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb')) - parser.add_argument('--recovery_dtbo', help='path to the recovery DTBO', type=FileType('rb')) + recovery_dtbo_group = parser.add_mutually_exclusive_group() + recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO', type=FileType('rb')) + recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO', + type=FileType('rb'), metavar='RECOVERY_ACPIO', dest='recovery_dtbo') parser.add_argument('--cmdline', help='extra arguments to be passed on the ' 'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536) parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000) |