From 23319ebebf6bda3b7aa085656ac5784534a4a574 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 30 Nov 2018 16:16:05 -0800 Subject: [PATCH] Start using new C++ Fstab class widely Bug: 62292478 Test: boot Test: adb-remount-test.sh Change-Id: Id4715af4c1f03e2cfc67de92d3ea58e933685e51 --- adb/daemon/remount_service.cpp | 5 +- fs_mgr/fs_mgr.cpp | 606 ++++++++++----------- fs_mgr/fs_mgr_format.cpp | 27 +- fs_mgr/fs_mgr_overlayfs.cpp | 181 +++--- fs_mgr/fs_mgr_priv.h | 2 +- fs_mgr/fs_mgr_verity.cpp | 103 ++-- fs_mgr/include/fs_mgr.h | 10 +- fs_mgr/include/fs_mgr_overlayfs.h | 6 +- fs_mgr/include_fstab/fstab/fstab.h | 1 + fs_mgr/libfs_avb/fs_avb.cpp | 16 +- fs_mgr/libfs_avb/include/fs_avb/fs_avb.h | 2 +- init/builtins.cpp | 7 +- init/first_stage_mount.cpp | 134 ++--- libcutils/include/cutils/partition_utils.h | 2 +- libcutils/partition_utils.cpp | 4 +- 15 files changed, 509 insertions(+), 597 deletions(-) diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp index b72ed1634..1a923173d 100644 --- a/adb/daemon/remount_service.cpp +++ b/adb/daemon/remount_service.cpp @@ -245,9 +245,8 @@ 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()) { - std::unique_ptr fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); - if (fs_mgr_overlayfs_mount_all(fstab.get())) { + Fstab fstab; + if (ReadDefaultFstab(&fstab) && fs_mgr_overlayfs_mount_all(&fstab)) { WriteFdExactly(fd.get(), "overlayfs mounted\n"); } } diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index d1eabab75..8757689d5 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -336,10 +336,10 @@ static bool run_tune2fs(const char* argv[], int argc) { } // Enable/disable quota support on the filesystem if needed. -static void tune_quota(const std::string& blk_device, const struct fstab_rec* rec, +static void tune_quota(const std::string& blk_device, const FstabEntry& entry, const struct ext4_super_block* sb, int* fs_stat) { bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0; - bool want_quota = fs_mgr_is_quota(rec) != 0; + bool want_quota = entry.fs_mgr_flags.quota; if (has_quota == want_quota) { return; @@ -372,16 +372,16 @@ static void tune_quota(const std::string& blk_device, const struct fstab_rec* re } // Set the number of reserved filesystem blocks if needed. -static void tune_reserved_size(const std::string& blk_device, const struct fstab_rec* rec, +static void tune_reserved_size(const std::string& blk_device, const FstabEntry& entry, const struct ext4_super_block* sb, int* fs_stat) { - if (!(rec->fs_mgr_flags & MF_RESERVEDSIZE)) { + if (!entry.fs_mgr_flags.reserved_size) { return; } // The size to reserve is given in the fstab, but we won't reserve more // than 2% of the filesystem. const uint64_t max_reserved_blocks = ext4_blocks_count(sb) * 0.02; - uint64_t reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(sb); + uint64_t reserved_blocks = entry.reserved_size / EXT4_BLOCK_SIZE(sb); if (reserved_blocks > max_reserved_blocks) { LWARNING << "Reserved blocks " << reserved_blocks << " is too large; " @@ -414,10 +414,10 @@ static void tune_reserved_size(const std::string& blk_device, const struct fstab } // Enable file-based encryption if needed. -static void tune_encrypt(const std::string& blk_device, const struct fstab_rec* rec, +static void tune_encrypt(const std::string& blk_device, const FstabEntry& entry, const struct ext4_super_block* sb, int* fs_stat) { bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0; - bool want_encrypt = fs_mgr_is_file_encrypted(rec) != 0; + bool want_encrypt = entry.fs_mgr_flags.file_encryption; if (has_encrypt || !want_encrypt) { return; @@ -478,10 +478,10 @@ static bool read_f2fs_superblock(const std::string& blk_device, int* fs_stat) { // If needed, we'll also enable (or disable) filesystem features as specified by // the fstab record. // -static int prepare_fs_for_mount(const std::string& blk_device, const struct fstab_rec* rec) { +static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry& entry) { int fs_stat = 0; - if (is_extfs(rec->fs_type)) { + if (is_extfs(entry.fs_type)) { struct ext4_super_block sb; if (read_ext4_superblock(blk_device, &sb, &fs_stat)) { @@ -494,27 +494,28 @@ static int prepare_fs_for_mount(const std::string& blk_device, const struct fsta } // Note: quotas should be enabled before running fsck. - tune_quota(blk_device, rec, &sb, &fs_stat); + tune_quota(blk_device, entry, &sb, &fs_stat); } else { return fs_stat; } - } else if (is_f2fs(rec->fs_type)) { + } else if (is_f2fs(entry.fs_type)) { if (!read_f2fs_superblock(blk_device, &fs_stat)) { return fs_stat; } } - if ((rec->fs_mgr_flags & MF_CHECK) || + if (entry.fs_mgr_flags.check || (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) { - check_fs(blk_device, rec->fs_type, rec->mount_point, &fs_stat); + check_fs(blk_device, entry.fs_type, entry.mount_point, &fs_stat); } - if (is_extfs(rec->fs_type) && (rec->fs_mgr_flags & (MF_RESERVEDSIZE | MF_FILEENCRYPTION))) { + if (is_extfs(entry.fs_type) && + (entry.fs_mgr_flags.reserved_size || entry.fs_mgr_flags.file_encryption)) { struct ext4_super_block sb; if (read_ext4_superblock(blk_device, &sb, &fs_stat)) { - tune_reserved_size(blk_device, rec, &sb, &fs_stat); - tune_encrypt(blk_device, rec, &sb, &fs_stat); + tune_reserved_size(blk_device, entry, &sb, &fs_stat); + tune_encrypt(blk_device, entry, &sb, &fs_stat); } } @@ -545,8 +546,7 @@ bool fs_mgr_is_device_unlocked() { // __mount(): wrapper around the mount() system call which also // sets the underlying block device to read-only if the mount is read-only. // See "man 2 mount" for return values. -static int __mount(const std::string& source, const std::string& target, - const struct fstab_rec* rec) { +static int __mount(const std::string& source, const std::string& target, const FstabEntry& entry) { // We need this because sometimes we have legacy symlinks that are // lingering around and need cleaning up. struct stat info; @@ -555,8 +555,9 @@ static int __mount(const std::string& source, const std::string& target, } mkdir(target.c_str(), 0755); errno = 0; - unsigned long mountflags = rec->flags; - int ret = mount(source.c_str(), target.c_str(), rec->fs_type, mountflags, rec->fs_options); + unsigned long mountflags = entry.flags; + int ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags, + entry.fs_options.c_str()); int save_errno = errno; const char* target_missing = ""; const char* source_missing = ""; @@ -569,7 +570,7 @@ static int __mount(const std::string& source, const std::string& target, errno = save_errno; } PINFO << __FUNCTION__ << "(source=" << source << source_missing << ",target=" << target - << target_missing << ",type=" << rec->fs_type << ")=" << ret; + << target_missing << ",type=" << entry.fs_type << ")=" << ret; if ((ret == 0) && (mountflags & MS_RDONLY) != 0) { fs_mgr_set_blk_ro(source); } @@ -605,106 +606,88 @@ static bool fs_match(const std::string& in1, const std::string& in2) { return true; } -/* - * Tries to mount any of the consecutive fstab entries that match - * the mountpoint of the one given by fstab->recs[start_idx]. - * - * end_idx: On return, will be the last rec that was looked at. - * attempted_idx: On return, will indicate which fstab rec - * succeeded. In case of failure, it will be the start_idx. - * Returns - * -1 on failure with errno set to match the 1st mount failure. - * 0 on success. - */ -static int mount_with_alternatives(fstab* fstab, int start_idx, int* end_idx, int* attempted_idx) { +// Tries to mount any of the consecutive fstab entries that match +// the mountpoint of the one given by fstab[start_idx]. +// +// end_idx: On return, will be the last entry that was looked at. +// attempted_idx: On return, will indicate which fstab entry +// succeeded. In case of failure, it will be the start_idx. +// Sets errno to match the 1st mount failure on failure. +static bool mount_with_alternatives(const Fstab& fstab, int start_idx, int* end_idx, + int* attempted_idx) { int i; int mount_errno = 0; - int mounted = 0; + bool mounted = false; - if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { - errno = EINVAL; - if (end_idx) *end_idx = start_idx; - if (attempted_idx) *attempted_idx = start_idx; - return -1; - } - - /* Hunt down an fstab entry for the same mount point that might succeed */ + // Hunt down an fstab entry for the same mount point that might succeed. for (i = start_idx; - /* We required that fstab entries for the same mountpoint be consecutive */ - i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point); - i++) { - /* - * Don't try to mount/encrypt the same mount point again. - * Deal with alternate entries for the same point which are required to be all following - * each other. - */ - if (mounted) { - LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint=" - << fstab->recs[i].mount_point << " rec[" << i - << "].fs_type=" << fstab->recs[i].fs_type - << " already mounted as " - << fstab->recs[*attempted_idx].fs_type; - continue; - } + // We required that fstab entries for the same mountpoint be consecutive. + i < fstab.size() && fstab[start_idx].mount_point == fstab[i].mount_point; i++) { + // Don't try to mount/encrypt the same mount point again. + // Deal with alternate entries for the same point which are required to be all following + // each other. + if (mounted) { + LERROR << __FUNCTION__ << "(): skipping fstab dup mountpoint=" << fstab[i].mount_point + << " rec[" << i << "].fs_type=" << fstab[i].fs_type << " already mounted as " + << fstab[*attempted_idx].fs_type; + continue; + } - int fs_stat = prepare_fs_for_mount(fstab->recs[i].blk_device, &fstab->recs[i]); - if (fs_stat & FS_STAT_INVALID_MAGIC) { - LERROR << __FUNCTION__ << "(): skipping mount due to invalid magic, mountpoint=" - << fstab->recs[i].mount_point - << " blk_dev=" << realpath(fstab->recs[i].blk_device) << " rec[" << i - << "].fs_type=" << fstab->recs[i].fs_type; - mount_errno = EINVAL; // continue bootup for FDE - continue; - } + int fs_stat = prepare_fs_for_mount(fstab[i].blk_device, fstab[i]); + if (fs_stat & FS_STAT_INVALID_MAGIC) { + LERROR << __FUNCTION__ + << "(): skipping mount due to invalid magic, mountpoint=" << fstab[i].mount_point + << " blk_dev=" << realpath(fstab[i].blk_device) << " rec[" << i + << "].fs_type=" << fstab[i].fs_type; + mount_errno = EINVAL; // continue bootup for FDE + continue; + } - int retry_count = 2; - while (retry_count-- > 0) { - if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, - &fstab->recs[i])) { - *attempted_idx = i; - mounted = 1; - if (i != start_idx) { - LERROR << __FUNCTION__ << "(): Mounted " << fstab->recs[i].blk_device - << " on " << fstab->recs[i].mount_point - << " with fs_type=" << fstab->recs[i].fs_type << " instead of " - << fstab->recs[start_idx].fs_type; - } - fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED; - mount_errno = 0; - break; - } else { - if (retry_count <= 0) break; // run check_fs only once - fs_stat |= FS_STAT_FULL_MOUNT_FAILED; - /* back up the first errno for crypto decisions */ - if (mount_errno == 0) { - mount_errno = errno; - } - // retry after fsck - check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, - fstab->recs[i].mount_point, &fs_stat); + int retry_count = 2; + while (retry_count-- > 0) { + if (!__mount(fstab[i].blk_device, fstab[i].mount_point, fstab[i])) { + *attempted_idx = i; + mounted = true; + if (i != start_idx) { + LERROR << __FUNCTION__ << "(): Mounted " << fstab[i].blk_device << " on " + << fstab[i].mount_point << " with fs_type=" << fstab[i].fs_type + << " instead of " << fstab[start_idx].fs_type; } + fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED; + mount_errno = 0; + break; + } else { + if (retry_count <= 0) break; // run check_fs only once + fs_stat |= FS_STAT_FULL_MOUNT_FAILED; + // back up the first errno for crypto decisions. + if (mount_errno == 0) { + mount_errno = errno; + } + // retry after fsck + check_fs(fstab[i].blk_device, fstab[i].fs_type, fstab[i].mount_point, &fs_stat); } - log_fs_stat(fstab->recs[i].blk_device, fs_stat); + } + log_fs_stat(fstab[i].blk_device, fs_stat); } /* Adjust i for the case where it was still withing the recs[] */ - if (i < fstab->num_entries) --i; + if (i < fstab.size()) --i; *end_idx = i; if (!mounted) { *attempted_idx = start_idx; errno = mount_errno; - return -1; + return false; } - return 0; + return true; } -static bool TranslateExtLabels(fstab_rec* rec) { - if (!StartsWith(rec->blk_device, "LABEL=")) { +static bool TranslateExtLabels(FstabEntry* entry) { + if (!StartsWith(entry->blk_device, "LABEL=")) { return true; } - std::string label = rec->blk_device + 6; + std::string label = entry->blk_device.substr(6); if (label.size() > 16) { LERROR << "FS label is longer than allowed by filesystem"; return false; @@ -744,10 +727,9 @@ static bool TranslateExtLabels(fstab_rec* rec) { if (label == super_block.s_volume_name) { std::string new_blk_device = "/dev/block/"s + ent->d_name; - LINFO << "resolved label " << rec->blk_device << " to " << new_blk_device; + LINFO << "resolved label " << entry->blk_device << " to " << new_blk_device; - free(rec->blk_device); - rec->blk_device = strdup(new_blk_device.c_str()); + entry->blk_device = new_blk_device; return true; } } @@ -755,54 +737,49 @@ static bool TranslateExtLabels(fstab_rec* rec) { return false; } -static bool needs_block_encryption(const struct fstab_rec* rec) -{ - if (android::base::GetBoolProperty("ro.vold.forceencryption", false) && - fs_mgr_is_encryptable(rec)) +static bool needs_block_encryption(const FstabEntry& entry) { + if (android::base::GetBoolProperty("ro.vold.forceencryption", false) && entry.is_encryptable()) return true; - if (rec->fs_mgr_flags & MF_FORCECRYPT) return true; - if (rec->fs_mgr_flags & MF_CRYPT) { + if (entry.fs_mgr_flags.force_crypt) return true; + if (entry.fs_mgr_flags.crypt) { // Check for existence of convert_fde breadcrumb file. - auto convert_fde_name = rec->mount_point + "/misc/vold/convert_fde"s; + auto convert_fde_name = entry.mount_point + "/misc/vold/convert_fde"; if (access(convert_fde_name.c_str(), F_OK) == 0) return true; } - if (rec->fs_mgr_flags & MF_FORCEFDEORFBE) { + if (entry.fs_mgr_flags.force_fde_or_fbe) { // Check for absence of convert_fbe breadcrumb file. - auto convert_fbe_name = rec->mount_point + "/convert_fbe"s; + auto convert_fbe_name = entry.mount_point + "/convert_fbe"; if (access(convert_fbe_name.c_str(), F_OK) != 0) return true; } return false; } -static bool should_use_metadata_encryption(const struct fstab_rec* rec) { - if (!(rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE))) return false; - if (!(rec->fs_mgr_flags & MF_KEYDIRECTORY)) return false; - return true; +static bool should_use_metadata_encryption(const FstabEntry& entry) { + return entry.fs_mgr_flags.key_directory && + (entry.fs_mgr_flags.file_encryption || entry.fs_mgr_flags.force_fde_or_fbe); } // Check to see if a mountable volume has encryption requirements -static int handle_encryptable(const struct fstab_rec* rec) -{ - /* If this is block encryptable, need to trigger encryption */ - if (needs_block_encryption(rec)) { - if (umount(rec->mount_point) == 0) { +static int handle_encryptable(const FstabEntry& entry) { + // If this is block encryptable, need to trigger encryption. + if (needs_block_encryption(entry)) { + if (umount(entry.mount_point.c_str()) == 0) { return FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION; } else { - PWARNING << "Could not umount " << rec->mount_point - << " - allow continue unencrypted"; + PWARNING << "Could not umount " << entry.mount_point << " - allow continue unencrypted"; return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; } - } else if (should_use_metadata_encryption(rec)) { - if (umount(rec->mount_point) == 0) { + } else if (should_use_metadata_encryption(entry)) { + if (umount(entry.mount_point.c_str()) == 0) { return FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION; } else { - PERROR << "Could not umount " << rec->mount_point << " - fail since can't encrypt"; + PERROR << "Could not umount " << entry.mount_point << " - fail since can't encrypt"; return FS_MGR_MNTALL_FAIL; } - } else if (rec->fs_mgr_flags & (MF_FILEENCRYPTION | MF_FORCEFDEORFBE)) { - LINFO << rec->mount_point << " is file encrypted"; + } else if (entry.fs_mgr_flags.file_encryption || entry.fs_mgr_flags.force_fde_or_fbe) { + LINFO << entry.mount_point << " is file encrypted"; return FS_MGR_MNTALL_DEV_FILE_ENCRYPTED; - } else if (fs_mgr_is_encryptable(rec)) { + } else if (entry.is_encryptable()) { return FS_MGR_MNTALL_DEV_NOT_ENCRYPTED; } else { return FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; @@ -843,21 +820,34 @@ static bool call_vdc_ret(const std::vector& args, int* ret) { return true; } -bool fs_mgr_update_logical_partition(struct fstab_rec* rec) { +bool fs_mgr_update_logical_partition(FstabEntry* entry) { // Logical partitions are specified with a named partition rather than a // block device, so if the block device is a path, then it has already // been updated. - if (rec->blk_device[0] == '/') { + if (entry->blk_device[0] == '/') { return true; } DeviceMapper& dm = DeviceMapper::Instance(); std::string device_name; - if (!dm.GetDmDevicePathByName(rec->blk_device, &device_name)) { + if (!dm.GetDmDevicePathByName(entry->blk_device, &device_name)) { return false; } + + entry->blk_device = device_name; + return true; +} + +bool fs_mgr_update_logical_partition(struct fstab_rec* rec) { + auto entry = FstabRecToFstabEntry(rec); + + if (!fs_mgr_update_logical_partition(&entry)) { + return false; + } + free(rec->blk_device); - rec->blk_device = strdup(device_name.c_str()); + rec->blk_device = strdup(entry.blk_device.c_str()); + return true; } @@ -865,13 +855,13 @@ class CheckpointManager { public: CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {} - bool Update(struct fstab_rec* rec) { - if (!fs_mgr_is_checkpoint(rec)) { + bool Update(FstabEntry* entry) { + if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; } - if (fs_mgr_is_checkpoint_blk(rec)) { - call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device}); + if (entry->fs_mgr_flags.checkpoint_blk) { + call_vdc({"checkpoint", "restoreCheckpoint", entry->blk_device}); } if (needs_checkpoint_ == UNKNOWN && @@ -884,7 +874,7 @@ class CheckpointManager { return true; } - if (!UpdateCheckpointPartition(rec)) { + if (!UpdateCheckpointPartition(entry)) { LERROR << "Could not set up checkpoint partition, skipping!"; return false; } @@ -892,18 +882,17 @@ class CheckpointManager { return true; } - bool Revert(struct fstab_rec* rec) { - if (!fs_mgr_is_checkpoint(rec)) { + bool Revert(FstabEntry* entry) { + if (!entry->fs_mgr_flags.checkpoint_blk && !entry->fs_mgr_flags.checkpoint_fs) { return true; } - if (device_map_.find(rec->blk_device) == device_map_.end()) { + if (device_map_.find(entry->blk_device) == device_map_.end()) { return true; } - std::string bow_device = rec->blk_device; - free(rec->blk_device); - rec->blk_device = strdup(device_map_[bow_device].c_str()); + std::string bow_device = entry->blk_device; + entry->blk_device = device_map_[bow_device]; device_map_.erase(bow_device); DeviceMapper& dm = DeviceMapper::Instance(); @@ -915,21 +904,17 @@ class CheckpointManager { } private: - bool UpdateCheckpointPartition(struct fstab_rec* rec) { - if (fs_mgr_is_checkpoint_fs(rec)) { - if (is_f2fs(rec->fs_type)) { - std::string opts(rec->fs_options); - - opts += ",checkpoint=disable"; - free(rec->fs_options); - rec->fs_options = strdup(opts.c_str()); + bool UpdateCheckpointPartition(FstabEntry* entry) { + if (entry->fs_mgr_flags.checkpoint_fs) { + if (is_f2fs(entry->fs_type)) { + entry->fs_options += ",checkpoint=disable"; } else { - LERROR << rec->fs_type << " does not implement checkpoints."; + LERROR << entry->fs_type << " does not implement checkpoints."; } - } else if (fs_mgr_is_checkpoint_blk(rec)) { - unique_fd fd(TEMP_FAILURE_RETRY(open(rec->blk_device, O_RDONLY | O_CLOEXEC))); + } else if (entry->fs_mgr_flags.checkpoint_blk) { + unique_fd fd(TEMP_FAILURE_RETRY(open(entry->blk_device.c_str(), O_RDONLY | O_CLOEXEC))); if (fd < 0) { - PERROR << "Cannot open device " << rec->blk_device; + PERROR << "Cannot open device " << entry->blk_device; return false; } @@ -941,7 +926,7 @@ class CheckpointManager { android::dm::DmTable table; if (!table.AddTarget( - std::make_unique(0, size, rec->blk_device))) { + std::make_unique(0, size, entry->blk_device))) { LERROR << "Failed to add bow target"; return false; } @@ -958,9 +943,8 @@ class CheckpointManager { return false; } - device_map_[name] = rec->blk_device; - free(rec->blk_device); - rec->blk_device = strdup(name.c_str()); + device_map_[name] = entry->blk_device; + entry->blk_device = name; } return true; } @@ -970,76 +954,70 @@ class CheckpointManager { std::map device_map_; }; -/* When multiple fstab records share the same mount_point, it will - * try to mount each one in turn, and ignore any duplicates after a - * first successful mount. - * Returns -1 on error, and FS_MGR_MNTALL_* otherwise. - */ -int fs_mgr_mount_all(fstab* fstab, int mount_mode) { - int i = 0; +// When multiple fstab records share the same mount_point, it will try to mount each +// one in turn, and ignore any duplicates after a first successful mount. +// Returns -1 on error, and FS_MGR_MNTALL_* otherwise. +int fs_mgr_mount_all(Fstab* fstab, int mount_mode) { int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE; int error_count = 0; - int mret = -1; - int mount_errno = 0; - int attempted_idx = -1; CheckpointManager checkpoint_manager; AvbUniquePtr avb_handle(nullptr); - if (!fstab) { + if (fstab->empty()) { return FS_MGR_MNTALL_FAIL; } - for (i = 0; i < fstab->num_entries; i++) { - /* Don't mount entries that are managed by vold or not for the mount mode*/ - if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) || - ((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) || - ((mount_mode == MOUNT_MODE_EARLY) && fs_mgr_is_latemount(&fstab->recs[i])) || - fs_mgr_is_first_stage_mount(&fstab->recs[i])) { + for (size_t i = 0; i < fstab->size(); i++) { + auto& current_entry = (*fstab)[i]; + + // Don't mount entries that are managed by vold or not for the mount mode. + if (current_entry.fs_mgr_flags.vold_managed || current_entry.fs_mgr_flags.recovery_only || + current_entry.fs_mgr_flags.first_stage_mount || + ((mount_mode == MOUNT_MODE_LATE) && !current_entry.fs_mgr_flags.late_mount) || + ((mount_mode == MOUNT_MODE_EARLY) && current_entry.fs_mgr_flags.late_mount)) { continue; } - /* Skip swap and raw partition entries such as boot, recovery, etc */ - if (!strcmp(fstab->recs[i].fs_type, "swap") || - !strcmp(fstab->recs[i].fs_type, "emmc") || - !strcmp(fstab->recs[i].fs_type, "mtd")) { + // Skip swap and raw partition entries such as boot, recovery, etc. + if (current_entry.fs_type == "swap" || current_entry.fs_type == "emmc" || + current_entry.fs_type == "mtd") { continue; } - /* Skip mounting the root partition, as it will already have been mounted */ - if (!strcmp(fstab->recs[i].mount_point, "/") || - !strcmp(fstab->recs[i].mount_point, "/system")) { - if ((fstab->recs[i].flags & MS_RDONLY) != 0) { - fs_mgr_set_blk_ro(fstab->recs[i].blk_device); + // Skip mounting the root partition, as it will already have been mounted. + if (current_entry.mount_point == "/" || current_entry.mount_point == "/system") { + if ((current_entry.flags & MS_RDONLY) != 0) { + fs_mgr_set_blk_ro(current_entry.blk_device); } continue; } - /* Translate LABEL= file system labels into block devices */ - if (is_extfs(fstab->recs[i].fs_type)) { - if (!TranslateExtLabels(&fstab->recs[i])) { + // Translate LABEL= file system labels into block devices. + if (is_extfs(current_entry.fs_type)) { + if (!TranslateExtLabels(¤t_entry)) { LERROR << "Could not translate label to block device"; continue; } } - if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) { - if (!fs_mgr_update_logical_partition(&fstab->recs[i])) { + if (current_entry.fs_mgr_flags.logical) { + if (!fs_mgr_update_logical_partition(¤t_entry)) { LERROR << "Could not set up logical partition, skipping!"; continue; } } - if (!checkpoint_manager.Update(&fstab->recs[i])) { + if (!checkpoint_manager.Update(¤t_entry)) { continue; } - if (fstab->recs[i].fs_mgr_flags & MF_WAIT && - !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) { - LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all"; + if (current_entry.fs_mgr_flags.wait && + !fs_mgr_wait_for_file(current_entry.blk_device, 20s)) { + LERROR << "Skipping '" << current_entry.blk_device << "' during mount_all"; continue; } - if (fstab->recs[i].fs_mgr_flags & MF_AVB) { + if (current_entry.fs_mgr_flags.avb) { if (!avb_handle) { avb_handle = AvbHandle::Open(); if (!avb_handle) { @@ -1047,15 +1025,15 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { return FS_MGR_MNTALL_FAIL; } } - if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == + if (avb_handle->SetUpAvbHashtree(¤t_entry, true /* wait_for_verity_dev */) == AvbHashtreeResult::kFail) { - LERROR << "Failed to set up AVB on partition: " - << fstab->recs[i].mount_point << ", skipping!"; - /* Skips mounting the device. */ + LERROR << "Failed to set up AVB on partition: " << current_entry.mount_point + << ", skipping!"; + // Skips mounting the device. continue; } - } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY)) { - int rc = fs_mgr_setup_verity(&fstab->recs[i], true); + } else if ((current_entry.fs_mgr_flags.verify)) { + int rc = fs_mgr_setup_verity(¤t_entry, true); if (__android_log_is_debuggable() && (rc == FS_MGR_SETUP_VERITY_DISABLED || rc == FS_MGR_SETUP_VERITY_SKIPPED)) { @@ -1068,17 +1046,19 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { int last_idx_inspected; int top_idx = i; + int attempted_idx = -1; - mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx); + bool mret = mount_with_alternatives(*fstab, i, &last_idx_inspected, &attempted_idx); + auto& attempted_entry = (*fstab)[attempted_idx]; i = last_idx_inspected; - mount_errno = errno; + int mount_errno = errno; - /* Deal with encryptability. */ - if (!mret) { - int status = handle_encryptable(&fstab->recs[attempted_idx]); + // Handle success and deal with encryptability. + if (mret) { + int status = handle_encryptable(attempted_entry); if (status == FS_MGR_MNTALL_FAIL) { - /* Fatal error - no point continuing */ + // Fatal error - no point continuing. return status; } @@ -1089,50 +1069,45 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } encryptable = status; if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) { - if (!call_vdc( - {"cryptfs", "encryptFstab", fstab->recs[attempted_idx].mount_point})) { + if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.mount_point})) { LERROR << "Encryption failed"; return FS_MGR_MNTALL_FAIL; } } } - /* Success! Go get the next one */ + // Success! Go get the next one. continue; } - bool wiped = partition_wiped(fstab->recs[top_idx].blk_device); + // Mounting failed, understand why and retry. + bool wiped = partition_wiped(current_entry.blk_device.c_str()); bool crypt_footer = false; - if (mret && mount_errno != EBUSY && mount_errno != EACCES && - fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) { - /* top_idx and attempted_idx point at the same partition, but sometimes - * at two different lines in the fstab. Use the top one for formatting - * as that is the preferred one. - */ - LERROR << __FUNCTION__ << "(): " << realpath(fstab->recs[top_idx].blk_device) - << " is wiped and " << fstab->recs[top_idx].mount_point << " " - << fstab->recs[top_idx].fs_type << " is formattable. Format it."; + if (mount_errno != EBUSY && mount_errno != EACCES && + current_entry.fs_mgr_flags.formattable && wiped) { + // current_entry and attempted_entry point at the same partition, but sometimes + // at two different lines in the fstab. Use current_entry for formatting + // as that is the preferred one. + LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device) + << " is wiped and " << current_entry.mount_point << " " << current_entry.fs_type + << " is formattable. Format it."; - checkpoint_manager.Revert(&fstab->recs[top_idx]); + checkpoint_manager.Revert(¤t_entry); - if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && - strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { + if (current_entry.is_encryptable() && current_entry.key_loc != KEY_IN_FOOTER) { unique_fd fd(TEMP_FAILURE_RETRY( - open(fstab->recs[top_idx].key_loc, O_WRONLY | O_CLOEXEC))); + open(current_entry.key_loc.c_str(), O_WRONLY | O_CLOEXEC))); if (fd >= 0) { - LINFO << __FUNCTION__ << "(): also wipe " - << fstab->recs[top_idx].key_loc; + LINFO << __FUNCTION__ << "(): also wipe " << current_entry.key_loc; wipe_block_device(fd, get_file_size(fd)); } else { - PERROR << __FUNCTION__ << "(): " - << fstab->recs[top_idx].key_loc << " wouldn't open"; + PERROR << __FUNCTION__ << "(): " << current_entry.key_loc << " wouldn't open"; } - } else if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) && - !strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) { + } else if (current_entry.is_encryptable() && current_entry.key_loc == KEY_IN_FOOTER) { crypt_footer = true; } - if (fs_mgr_do_format(&fstab->recs[top_idx], crypt_footer) == 0) { - /* Let's replay the mount actions. */ + if (fs_mgr_do_format(current_entry, crypt_footer) == 0) { + // Let's replay the mount actions. i = top_idx - 1; continue; } else { @@ -1143,35 +1118,29 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } } - /* mount(2) returned an error, handle the encryptable/formattable case */ - if (mret && mount_errno != EBUSY && mount_errno != EACCES && - fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) { + // mount(2) returned an error, handle the encryptable/formattable case. + if (mount_errno != EBUSY && mount_errno != EACCES && attempted_entry.is_encryptable()) { if (wiped) { - LERROR << __FUNCTION__ << "(): " - << fstab->recs[attempted_idx].blk_device - << " is wiped and " - << fstab->recs[attempted_idx].mount_point << " " - << fstab->recs[attempted_idx].fs_type + LERROR << __FUNCTION__ << "(): " << attempted_entry.blk_device << " is wiped and " + << attempted_entry.mount_point << " " << attempted_entry.fs_type << " is encryptable. Suggest recovery..."; encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY; continue; } else { - /* Need to mount a tmpfs at this mountpoint for now, and set - * properties that vold will query later for decrypting - */ + // Need to mount a tmpfs at this mountpoint for now, and set + // properties that vold will query later for decrypting LERROR << __FUNCTION__ << "(): possibly an encryptable blkdev " - << fstab->recs[attempted_idx].blk_device - << " for mount " << fstab->recs[attempted_idx].mount_point - << " type " << fstab->recs[attempted_idx].fs_type; - if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) { + << attempted_entry.blk_device << " for mount " << attempted_entry.mount_point + << " type " << attempted_entry.fs_type; + if (fs_mgr_do_tmpfs_mount(attempted_entry.mount_point.c_str()) < 0) { ++error_count; continue; } } encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED; - } else if (mret && mount_errno != EBUSY && mount_errno != EACCES && - should_use_metadata_encryption(&fstab->recs[attempted_idx])) { - if (!call_vdc({"cryptfs", "mountFstab", fstab->recs[attempted_idx].mount_point})) { + } else if (mount_errno != EBUSY && mount_errno != EACCES && + should_use_metadata_encryption(attempted_entry)) { + if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.mount_point})) { ++error_count; } encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED; @@ -1179,18 +1148,18 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } else { // fs_options might be null so we cannot use PERROR << directly. // Use StringPrintf to output "(null)" instead. - if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) { + if (attempted_entry.fs_mgr_flags.no_fail) { PERROR << android::base::StringPrintf( - "Ignoring failure to mount an un-encryptable or wiped " - "partition on %s at %s options: %s", - fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_options); + "Ignoring failure to mount an un-encryptable or wiped " + "partition on %s at %s options: %s", + attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(), + attempted_entry.fs_options.c_str()); } else { PERROR << android::base::StringPrintf( - "Failed to mount an un-encryptable or wiped partition " - "on %s at %s options: %s", - fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point, - fstab->recs[attempted_idx].fs_options); + "Failed to mount an un-encryptable or wiped partition " + "on %s at %s options: %s", + attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(), + attempted_entry.fs_options.c_str()); ++error_count; } continue; @@ -1208,20 +1177,13 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) { } } -/* wrapper to __mount() and expects a fully prepared fstab_rec, - * unlike fs_mgr_do_mount which does more things with avb / verity - * etc. - */ -int fs_mgr_do_mount_one(struct fstab_rec *rec) -{ - if (!rec) { - return FS_MGR_DOMNT_FAILED; - } - +// wrapper to __mount() and expects a fully prepared fstab_rec, +// unlike fs_mgr_do_mount which does more things with avb / verity etc. +int fs_mgr_do_mount_one(const FstabEntry& entry) { // Run fsck if needed - prepare_fs_for_mount(rec->blk_device, rec); + prepare_fs_for_mount(entry.blk_device, entry); - int ret = __mount(rec->blk_device, rec->mount_point, rec); + int ret = __mount(entry.blk_device, entry.mount_point, entry); if (ret) { ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED; } @@ -1229,17 +1191,26 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec) return ret; } -/* If tmp_mount_point is non-null, mount the filesystem there. This is for the - * tmp mount we do to check the user password - * 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(fstab* fstab, const char* n_name, char* n_blk_device, - char* tmp_mount_point, int needs_checkpoint) { - int i = 0; +int fs_mgr_do_mount_one(struct fstab_rec* rec) { + if (!rec) { + return FS_MGR_DOMNT_FAILED; + } + + auto entry = FstabRecToFstabEntry(rec); + + return fs_mgr_do_mount_one(entry); +} + +// If tmp_mount_point is non-null, mount the filesystem there. This is for the +// tmp mount we do to check the user password +// 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(Fstab* fstab, const std::string& n_name, + const std::string& n_blk_device, const char* tmp_mount_point, + int needs_checkpoint) { int mount_errors = 0; int first_mount_errno = 0; - char* mount_point; + std::string mount_point; CheckpointManager checkpoint_manager(needs_checkpoint); AvbUniquePtr avb_handle(nullptr); @@ -1247,42 +1218,41 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ return FS_MGR_DOMNT_FAILED; } - for (i = 0; i < fstab->num_entries; i++) { - if (!fs_match(fstab->recs[i].mount_point, n_name)) { + for (auto& fstab_entry : *fstab) { + if (!fs_match(fstab_entry.mount_point, n_name)) { continue; } - /* We found our match */ - /* If this swap or a raw partition, report an error */ - if (!strcmp(fstab->recs[i].fs_type, "swap") || - !strcmp(fstab->recs[i].fs_type, "emmc") || - !strcmp(fstab->recs[i].fs_type, "mtd")) { - LERROR << "Cannot mount filesystem of type " - << fstab->recs[i].fs_type << " on " << n_blk_device; + // We found our match. + // If this swap or a raw partition, report an error. + if (fstab_entry.fs_type == "swap" || fstab_entry.fs_type == "emmc" || + fstab_entry.fs_type == "mtd") { + LERROR << "Cannot mount filesystem of type " << fstab_entry.fs_type << " on " + << n_blk_device; return FS_MGR_DOMNT_FAILED; } - if ((fstab->recs[i].fs_mgr_flags & MF_LOGICAL)) { - if (!fs_mgr_update_logical_partition(&fstab->recs[i])) { + if (fstab_entry.fs_mgr_flags.logical) { + if (!fs_mgr_update_logical_partition(&fstab_entry)) { LERROR << "Could not set up logical partition, skipping!"; continue; } } - if (!checkpoint_manager.Update(&fstab->recs[i])) { + if (!checkpoint_manager.Update(&fstab_entry)) { LERROR << "Could not set up checkpoint partition, skipping!"; continue; } - /* First check the filesystem if requested */ - if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) { + // First check the filesystem if requested. + if (fstab_entry.fs_mgr_flags.wait && !fs_mgr_wait_for_file(n_blk_device, 20s)) { LERROR << "Skipping mounting '" << n_blk_device << "'"; continue; } - int fs_stat = prepare_fs_for_mount(n_blk_device, &fstab->recs[i]); + int fs_stat = prepare_fs_for_mount(n_blk_device, fstab_entry); - if (fstab->recs[i].fs_mgr_flags & MF_AVB) { + if (fstab_entry.fs_mgr_flags.avb) { if (!avb_handle) { avb_handle = AvbHandle::Open(); if (!avb_handle) { @@ -1290,15 +1260,15 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ return FS_MGR_DOMNT_FAILED; } } - if (avb_handle->SetUpAvbHashtree(&fstab->recs[i], true /* wait_for_verity_dev */) == + if (avb_handle->SetUpAvbHashtree(&fstab_entry, true /* wait_for_verity_dev */) == AvbHashtreeResult::kFail) { - LERROR << "Failed to set up AVB on partition: " - << fstab->recs[i].mount_point << ", skipping!"; - /* Skips mounting the device. */ + LERROR << "Failed to set up AVB on partition: " << fstab_entry.mount_point + << ", skipping!"; + // Skips mounting the device. continue; } - } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY)) { - int rc = fs_mgr_setup_verity(&fstab->recs[i], true); + } else if (fstab_entry.fs_mgr_flags.verify) { + int rc = fs_mgr_setup_verity(&fstab_entry, true); if (__android_log_is_debuggable() && (rc == FS_MGR_SETUP_VERITY_DISABLED || rc == FS_MGR_SETUP_VERITY_SKIPPED)) { @@ -1309,15 +1279,15 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ } } - /* Now mount it where requested */ + // Now mount it where requested */ if (tmp_mount_point) { mount_point = tmp_mount_point; } else { - mount_point = fstab->recs[i].mount_point; + mount_point = fstab_entry.mount_point; } int retry_count = 2; while (retry_count-- > 0) { - if (!__mount(n_blk_device, mount_point, &fstab->recs[i])) { + if (!__mount(n_blk_device, mount_point, fstab_entry)) { fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED; return FS_MGR_DOMNT_SUCCESS; } else { @@ -1326,10 +1296,10 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ mount_errors++; fs_stat |= FS_STAT_FULL_MOUNT_FAILED; // try again after fsck - check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point, &fs_stat); + check_fs(n_blk_device, fstab_entry.fs_type, fstab_entry.mount_point, &fs_stat); } } - log_fs_stat(fstab->recs[i].blk_device, fs_stat); + log_fs_stat(fstab_entry.blk_device, fs_stat); } // Reach here means the mount attempt fails. @@ -1337,19 +1307,22 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_ PERROR << "Cannot mount filesystem on " << n_blk_device << " at " << mount_point; if (first_mount_errno == EBUSY) return FS_MGR_DOMNT_BUSY; } else { - /* We didn't find a match, say so and return an error */ + // We didn't find a match, say so and return an error. LERROR << "Cannot find mount point " << n_name << " in fstab"; } return FS_MGR_DOMNT_FAILED; } 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); + auto new_fstab = LegacyFstabToFstab(fstab); + return fs_mgr_do_mount_helper(&new_fstab, n_name, n_blk_device, tmp_mount_point, -1); } int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point, bool needs_checkpoint) { - return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint); + auto new_fstab = LegacyFstabToFstab(fstab); + return fs_mgr_do_mount_helper(&new_fstab, n_name, n_blk_device, tmp_mount_point, + needs_checkpoint); } /* @@ -1492,23 +1465,22 @@ bool fs_mgr_load_verity_state(int* mode) { * logging mode, in which case return that */ *mode = VERITY_MODE_DEFAULT; - std::unique_ptr fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); - if (!fstab) { + Fstab fstab; + if (!ReadDefaultFstab(&fstab)) { LERROR << "Failed to read default fstab"; return false; } - for (int i = 0; i < fstab->num_entries; i++) { - if (fs_mgr_is_avb(&fstab->recs[i])) { + for (const auto& entry : fstab) { + if (entry.fs_mgr_flags.avb) { *mode = VERITY_MODE_RESTART; // avb only supports restart mode. break; - } else if (!fs_mgr_is_verified(&fstab->recs[i])) { + } else if (!entry.fs_mgr_flags.verify) { continue; } int current; - if (load_verity_state(&fstab->recs[i], ¤t) < 0) { + if (load_verity_state(entry, ¤t) < 0) { continue; } if (current != VERITY_MODE_DEFAULT) { diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp index 737deca3b..1a0e7ab16 100644 --- a/fs_mgr/fs_mgr_format.cpp +++ b/fs_mgr/fs_mgr_format.cpp @@ -120,20 +120,21 @@ static int format_f2fs(const std::string& fs_blkdev, uint64_t dev_sz, bool crypt LOG_KLOG, true, nullptr, nullptr, 0); } -int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer) -{ - int rc = -EINVAL; +int fs_mgr_do_format(const FstabEntry& entry, bool crypt_footer) { + LERROR << __FUNCTION__ << ": Format " << entry.blk_device << " as '" << entry.fs_type << "'"; - LERROR << __FUNCTION__ << ": Format " << fstab->blk_device - << " as '" << fstab->fs_type << "'"; - - if (!strncmp(fstab->fs_type, "f2fs", 4)) { - rc = format_f2fs(fstab->blk_device, fstab->length, crypt_footer); - } else if (!strncmp(fstab->fs_type, "ext4", 4)) { - rc = format_ext4(fstab->blk_device, fstab->mount_point, crypt_footer); + if (entry.fs_type == "f2fs") { + return format_f2fs(entry.blk_device, entry.length, crypt_footer); + } else if (entry.fs_type == "ext4") { + return format_ext4(entry.blk_device, entry.mount_point, crypt_footer); } else { - LERROR << "File system type '" << fstab->fs_type << "' is not supported"; + LERROR << "File system type '" << entry.fs_type << "' is not supported"; + return -EINVAL; } - - return rc; +} + +int fs_mgr_do_format(struct fstab_rec* rec, bool crypt_footer) { + auto entry = FstabRecToFstabEntry(rec); + + return fs_mgr_do_format(entry, crypt_footer); } diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp index d2d8dc1fa..50e765310 100644 --- a/fs_mgr/fs_mgr_overlayfs.cpp +++ b/fs_mgr/fs_mgr_overlayfs.cpp @@ -70,19 +70,11 @@ bool fs_mgr_access(const std::string& path) { #if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs -bool fs_mgr_overlayfs_mount_all(fstab*) { +bool fs_mgr_overlayfs_mount_all(Fstab*) { return false; } -bool fs_mgr_overlayfs_mount_all(const std::vector&) { - return false; -} - -std::vector fs_mgr_overlayfs_required_devices(fstab*) { - return {}; -} - -std::vector fs_mgr_overlayfs_required_devices(const std::vector&) { +std::vector fs_mgr_overlayfs_required_devices(Fstab*) { return {}; } @@ -131,28 +123,28 @@ bool fs_mgr_dir_is_writable(const std::string& path) { // At less than 1% free space return value of false, // means we will try to wrap with overlayfs. -bool fs_mgr_filesystem_has_space(const char* mount_point) { +bool fs_mgr_filesystem_has_space(const std::string& mount_point) { // If we have access issues to find out space remaining, return true // to prevent us trying to override with overlayfs. struct statvfs vst; - if (statvfs(mount_point, &vst)) return true; + if (statvfs(mount_point.c_str(), &vst)) return true; static constexpr int kPercentThreshold = 1; // 1% return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100)); } -bool fs_mgr_overlayfs_enabled(struct fstab_rec* fsrec) { +bool fs_mgr_overlayfs_enabled(FstabEntry* entry) { // readonly filesystem, can not be mount -o remount,rw // if squashfs or if free space is (near) zero making such a remount // virtually useless, or if there are shared blocks that prevent remount,rw - if (("squashfs"s == fsrec->fs_type) || !fs_mgr_filesystem_has_space(fsrec->mount_point)) { + if ("squashfs" == entry->fs_type || !fs_mgr_filesystem_has_space(entry->mount_point)) { return true; } - if (fs_mgr_is_logical(fsrec)) { - fs_mgr_update_logical_partition(fsrec); + if (entry->fs_mgr_flags.logical) { + fs_mgr_update_logical_partition(entry); } - return fs_mgr_has_shared_blocks(fsrec->mount_point, fsrec->blk_device); + return fs_mgr_has_shared_blocks(entry->mount_point, entry->blk_device); } bool fs_mgr_rm_all(const std::string& path, bool* change = nullptr, int level = 0) { @@ -250,22 +242,16 @@ bool fs_mgr_rw_access(const std::string& path) { } bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true) { - std::unique_ptr fstab(fs_mgr_read_fstab("/proc/mounts"), - fs_mgr_free_fstab); - if (!fstab) return false; + Fstab fstab; + if (!ReadFstabFromFile("/proc/mounts", &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_only && ("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; + for (const auto& entry : fstab) { + if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue; + if (mount_point != entry.mount_point) continue; if (!overlay_only) return true; - const auto fs_options = fsrec->fs_options; - if (!fs_options) continue; - const auto options = android::base::Split(fs_options, ","); + const auto options = android::base::Split(entry.fs_options, ","); for (const auto& opt : options) { if (opt == lowerdir) { return true; @@ -282,28 +268,20 @@ std::vector fs_mgr_overlayfs_verity_enabled_list() { return ret; } -bool fs_mgr_wants_overlayfs(fstab_rec* fsrec) { - if (!fsrec) return false; - - auto fsrec_mount_point = fsrec->mount_point; - if (!fsrec_mount_point || !fsrec_mount_point[0]) return false; - if (!fsrec->blk_device) return false; - - if (!fsrec->fs_type) return false; - +bool fs_mgr_wants_overlayfs(FstabEntry* entry) { // Don't check entries that are managed by vold. - if (fsrec->fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) return false; + if (entry->fs_mgr_flags.vold_managed || entry->fs_mgr_flags.recovery_only) return false; // Only concerned with readonly partitions. - if (!(fsrec->flags & MS_RDONLY)) return false; + if (!(entry->flags & MS_RDONLY)) return false; // If unbindable, do not allow overlayfs as this could expose us to // security issues. On Android, this could also be used to turn off // the ability to overlay an otherwise acceptable filesystem since // /system and /vendor are never bound(sic) to. - if (fsrec->flags & MS_UNBINDABLE) return false; + if (entry->flags & MS_UNBINDABLE) return false; - if (!fs_mgr_overlayfs_enabled(fsrec)) return false; + if (!fs_mgr_overlayfs_enabled(entry)) return false; return true; } @@ -391,11 +369,11 @@ std::string fs_mgr_overlayfs_super_device(uint32_t slot_number) { return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number); } -bool fs_mgr_overlayfs_has_logical(const fstab* fstab) { - if (!fstab) return false; - for (auto i = 0; i < fstab->num_entries; i++) { - const auto fsrec = &fstab->recs[i]; - if (fs_mgr_is_logical(fsrec)) return true; +bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) { + for (const auto& entry : fstab) { + if (entry.fs_mgr_flags.logical) { + return true; + } } return false; } @@ -540,15 +518,12 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) { } } -std::vector fs_mgr_candidate_list(fstab* fstab, const char* mount_point = nullptr) { +std::vector fs_mgr_candidate_list(Fstab* fstab, const char* mount_point = nullptr) { std::vector mounts; - if (!fstab) return mounts; - auto verity = fs_mgr_overlayfs_verity_enabled_list(); - for (auto i = 0; i < fstab->num_entries; i++) { - const auto fsrec = &fstab->recs[i]; - if (!fs_mgr_wants_overlayfs(fsrec)) continue; - std::string new_mount_point(fs_mgr_mount_point(fsrec->mount_point)); + for (auto& entry : *fstab) { + if (!fs_mgr_wants_overlayfs(&entry)) continue; + std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str())); if (mount_point && (new_mount_point != mount_point)) continue; if (std::find(verity.begin(), verity.end(), android::base::Basename(new_mount_point)) != verity.end()) { @@ -580,10 +555,9 @@ std::vector fs_mgr_candidate_list(fstab* fstab, const char* mount_p if (std::find(verity.begin(), verity.end(), "system") != verity.end()) return mounts; // confirm that fstab is missing system - if (fs_mgr_get_entry_for_mount_point(const_cast(fstab), "/")) { - return mounts; - } - if (fs_mgr_get_entry_for_mount_point(const_cast(fstab), "/system")) { + if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) { + return entry.mount_point == "/" || entry.mount_point == "/system "; + }) != fstab->end()) { return mounts; } @@ -605,26 +579,20 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s PERROR << "create " << kScratchMountPoint; } - std::unique_ptr local_fstab( - static_cast(calloc(1, sizeof(fstab))), fs_mgr_free_fstab); - auto fsrec = static_cast(calloc(1, sizeof(fstab_rec))); - local_fstab->num_entries = 1; - local_fstab->recs = fsrec; - fsrec->blk_device = strdup(device_path.c_str()); - fsrec->mount_point = strdup(kScratchMountPoint.c_str()); - fsrec->fs_type = strdup(mnt_type.c_str()); - fsrec->flags = MS_RELATIME; - fsrec->fs_options = strdup(""); + FstabEntry entry; + entry.blk_device = device_path; + entry.mount_point = kScratchMountPoint; + entry.fs_type = mnt_type; + entry.flags = MS_RELATIME; auto save_errno = errno; - auto mounted = fs_mgr_do_mount_one(fsrec) == 0; + auto mounted = fs_mgr_do_mount_one(entry) == 0; if (!mounted) { - free(fsrec->fs_type); if (mnt_type == "f2fs") { - fsrec->fs_type = strdup("ext4"); + entry.fs_type = "ext4"; } else { - fsrec->fs_type = strdup("f2fs"); + entry.fs_type = "f2fs"; } - mounted = fs_mgr_do_mount_one(fsrec) == 0; + mounted = fs_mgr_do_mount_one(entry) == 0; if (!mounted) save_errno = errno; } setfscreatecon(nullptr); @@ -681,7 +649,7 @@ bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std: return true; } -bool fs_mgr_overlayfs_create_scratch(const fstab* fstab, std::string* scratch_device, +bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_device, bool* partition_exists, bool* change) { *scratch_device = fs_mgr_overlayfs_scratch_device(); *partition_exists = fs_mgr_rw_access(*scratch_device); @@ -765,7 +733,7 @@ bool fs_mgr_overlayfs_create_scratch(const fstab* fstab, std::string* scratch_de } // Create and mount kScratchMountPoint storage if we have logical partitions -bool fs_mgr_overlayfs_setup_scratch(const fstab* fstab, bool* change) { +bool fs_mgr_overlayfs_setup_scratch(const Fstab& fstab, bool* change) { if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true; std::string scratch_device; @@ -805,20 +773,20 @@ bool fs_mgr_overlayfs_scratch_can_be_mounted(const std::string& scratch_device) return builder->FindPartition(android::base::Basename(kScratchMountPoint)) != nullptr; } -bool fs_mgr_overlayfs_invalid(const fstab* fstab) { +bool fs_mgr_overlayfs_invalid() { if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true; // in recovery or fastbootd mode, not allowed! if (fs_mgr_access("/system/bin/recovery")) return true; - return !fstab; + return false; } } // namespace -bool fs_mgr_overlayfs_mount_all(fstab* fstab) { +bool fs_mgr_overlayfs_mount_all(Fstab* fstab) { auto ret = false; - if (fs_mgr_overlayfs_invalid(fstab)) return ret; + if (fs_mgr_overlayfs_invalid()) return ret; auto scratch_can_be_mounted = true; for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { @@ -839,17 +807,12 @@ bool fs_mgr_overlayfs_mount_all(fstab* fstab) { return ret; } -bool fs_mgr_overlayfs_mount_all(const std::vector& fsrecs) { - std::vector recs; - for (const auto& rec : fsrecs) recs.push_back(*rec); - fstab fstab = {static_cast(fsrecs.size()), &recs[0]}; - return fs_mgr_overlayfs_mount_all(&fstab); -} +std::vector fs_mgr_overlayfs_required_devices(Fstab* fstab) { + if (fs_mgr_overlayfs_invalid()) return {}; -std::vector fs_mgr_overlayfs_required_devices(fstab* fstab) { - if (fs_mgr_overlayfs_invalid(fstab)) return {}; - - if (fs_mgr_get_entry_for_mount_point(fstab, kScratchMountPoint)) { + if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) { + return entry.mount_point == kScratchMountPoint; + }) != fstab->end()) { return {}; } @@ -862,13 +825,6 @@ std::vector fs_mgr_overlayfs_required_devices(fstab* fstab) { return {}; } -std::vector fs_mgr_overlayfs_required_devices(const std::vector& fsrecs) { - std::vector recs; - for (const auto& rec : fsrecs) recs.push_back(*rec); - fstab fstab = {static_cast(fsrecs.size()), &recs[0]}; - return fs_mgr_overlayfs_required_devices(&fstab); -} - // Returns false if setup not permitted, errno set to last error. // If something is altered, set *change. bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change) { @@ -881,10 +837,11 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* return ret; } - std::unique_ptr fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); - if (!fstab) return ret; - auto mounts = fs_mgr_candidate_list(fstab.get(), fs_mgr_mount_point(mount_point)); + Fstab fstab; + if (!ReadDefaultFstab(&fstab)) { + return false; + } + auto mounts = fs_mgr_candidate_list(&fstab, fs_mgr_mount_point(mount_point)); if (mounts.empty()) return ret; std::string dir; @@ -892,12 +849,16 @@ bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* if (backing && backing[0] && (overlay_mount_point != backing)) continue; if (overlay_mount_point == kScratchMountPoint) { if (!fs_mgr_rw_access(fs_mgr_overlayfs_super_device(fs_mgr_overlayfs_slot_number())) || - !fs_mgr_overlayfs_has_logical(fstab.get())) { + !fs_mgr_overlayfs_has_logical(fstab)) { continue; } - if (!fs_mgr_overlayfs_setup_scratch(fstab.get(), change)) continue; + if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue; } else { - if (!fs_mgr_get_entry_for_mount_point(fstab.get(), overlay_mount_point)) continue; + if (std::find_if(fstab.begin(), fstab.end(), [&overlay_mount_point](const auto& entry) { + return entry.mount_point == overlay_mount_point; + }) == fstab.end()) { + continue; + } } dir = overlay_mount_point; break; @@ -959,10 +920,12 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { bool fs_mgr_overlayfs_is_setup() { if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true; - std::unique_ptr fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); - if (fs_mgr_overlayfs_invalid(fstab.get())) return false; - for (const auto& mount_point : fs_mgr_candidate_list(fstab.get())) { + Fstab fstab; + if (!ReadDefaultFstab(&fstab)) { + return false; + } + if (fs_mgr_overlayfs_invalid()) return false; + for (const auto& mount_point : fs_mgr_candidate_list(&fstab)) { if (fs_mgr_overlayfs_already_mounted(mount_point)) return true; } return false; diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index faef34bee..072da97c8 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -137,6 +137,6 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab); bool fs_mgr_is_device_unlocked(); const std::string& get_android_dt_dir(); bool is_dt_compatible(); -int load_verity_state(fstab_rec* fstab, int* mode); +int load_verity_state(const FstabEntry& entry, int* mode); #endif /* __CORE_FS_MGR_PRIV_H */ diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index 2727a6d32..9adf8cc25 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp @@ -536,8 +536,7 @@ static int read_partition(const char *path, uint64_t size) return 0; } -static int compare_last_signature(struct fstab_rec *fstab, int *match) -{ +static int compare_last_signature(const FstabEntry& entry, int* match) { char tag[METADATA_TAG_MAX_LENGTH + 1]; int fd = -1; int rc = -1; @@ -549,42 +548,40 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match) *match = 1; - if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, - FEC_DEFAULT_ROOTS) == -1) { - PERROR << "Failed to open '" << fstab->blk_device << "'"; + if (fec_open(&f, entry.blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) == + -1) { + PERROR << "Failed to open '" << entry.blk_device << "'"; return rc; } // read verity metadata if (fec_verity_get_metadata(f, &verity) == -1) { - PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'"; + PERROR << "Failed to get verity metadata '" << entry.blk_device << "'"; goto out; } SHA256(verity.signature, sizeof(verity.signature), curr); - if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", - basename(fstab->mount_point)) >= (int)sizeof(tag)) { - LERROR << "Metadata tag name too long for " << fstab->mount_point; + if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", basename(entry.mount_point.c_str())) >= + (int)sizeof(tag)) { + LERROR << "Metadata tag name too long for " << entry.mount_point; goto out; } - if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_LENGTH, - &offset) < 0) { + if (metadata_find(entry.verity_loc.c_str(), tag, SHA256_DIGEST_LENGTH, &offset) < 0) { goto out; } - fd = TEMP_FAILURE_RETRY(open(fstab->verity_loc, O_RDWR | O_SYNC | O_CLOEXEC)); + fd = TEMP_FAILURE_RETRY(open(entry.verity_loc.c_str(), O_RDWR | O_SYNC | O_CLOEXEC)); if (fd == -1) { - PERROR << "Failed to open " << fstab->verity_loc; + PERROR << "Failed to open " << entry.verity_loc; goto out; } - if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), - offset)) != sizeof(prev)) { - PERROR << "Failed to read " << sizeof(prev) << " bytes from " - << fstab->verity_loc << " offset " << offset; + if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), offset)) != sizeof(prev)) { + PERROR << "Failed to read " << sizeof(prev) << " bytes from " << entry.verity_loc + << " offset " << offset; goto out; } @@ -594,8 +591,8 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match) /* update current signature hash */ if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr), offset)) != sizeof(curr)) { - PERROR << "Failed to write " << sizeof(curr) << " bytes to " - << fstab->verity_loc << " offset " << offset; + PERROR << "Failed to write " << sizeof(curr) << " bytes to " << entry.verity_loc + << " offset " << offset; goto out; } } @@ -607,28 +604,23 @@ out: return rc; } -static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset) -{ +static int get_verity_state_offset(const FstabEntry& entry, off64_t* offset) { char tag[METADATA_TAG_MAX_LENGTH + 1]; - if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", - basename(fstab->mount_point)) >= (int)sizeof(tag)) { - LERROR << "Metadata tag name too long for " << fstab->mount_point; + if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", basename(entry.mount_point.c_str())) >= + (int)sizeof(tag)) { + LERROR << "Metadata tag name too long for " << entry.mount_point; return -1; } - return metadata_find(fstab->verity_loc, tag, sizeof(struct verity_state), - offset); + return metadata_find(entry.verity_loc.c_str(), tag, sizeof(struct verity_state), offset); } -int load_verity_state(struct fstab_rec* fstab, int* mode) { - int match = 0; - off64_t offset = 0; - - /* unless otherwise specified, use EIO mode */ +int load_verity_state(const FstabEntry& entry, int* mode) { + // unless otherwise specified, use EIO mode. *mode = VERITY_MODE_EIO; - /* use the kernel parameter if set */ + // use the kernel parameter if set. std::string veritymode; if (fs_mgr_get_boot_config("veritymode", &veritymode)) { if (veritymode == "enforcing") { @@ -637,7 +629,8 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) { return 0; } - if (get_verity_state_offset(fstab, &offset) < 0) { + off64_t offset = 0; + if (get_verity_state_offset(entry, &offset) < 0) { /* fall back to stateless behavior */ return 0; } @@ -645,16 +638,17 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) { if (was_verity_restart()) { /* device was restarted after dm-verity detected a corrupted * block, so use EIO mode */ - return write_verity_state(fstab->verity_loc, offset, *mode); + return write_verity_state(entry.verity_loc.c_str(), offset, *mode); } - if (!compare_last_signature(fstab, &match) && !match) { + int match = 0; + if (!compare_last_signature(entry, &match) && !match) { /* partition has been reflashed, reset dm-verity state */ *mode = VERITY_MODE_DEFAULT; - return write_verity_state(fstab->verity_loc, offset, *mode); + return write_verity_state(entry.verity_loc.c_str(), offset, *mode); } - return read_verity_state(fstab->verity_loc, offset, mode); + return read_verity_state(entry.verity_loc.c_str(), offset, mode); } // Update the verity table using the actual block device path. @@ -716,8 +710,7 @@ static void update_verity_table_blk_device(const std::string& blk_device, char** // prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for // mount. The 'wait_for_verity_dev' parameter makes this function wait for the // verity device to get created before return -int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev) -{ +int fs_mgr_setup_verity(FstabEntry* entry, bool wait_for_verity_dev) { int retval = FS_MGR_SETUP_VERITY_FAIL; int fd = -1; std::string verity_blk_name; @@ -725,20 +718,20 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev) struct fec_verity_metadata verity; struct verity_table_params params = { .table = NULL }; - const std::string mount_point(basename(fstab->mount_point)); + const std::string mount_point(basename(entry->mount_point.c_str())); bool verified_at_boot = false; android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance(); - if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, - FEC_DEFAULT_ROOTS) < 0) { - PERROR << "Failed to open '" << fstab->blk_device << "'"; + if (fec_open(&f, entry->blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) < + 0) { + PERROR << "Failed to open '" << entry->blk_device << "'"; return retval; } // read verity metadata if (fec_verity_get_metadata(f, &verity) < 0) { - PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'"; + PERROR << "Failed to get verity metadata '" << entry->blk_device << "'"; // Allow verity disabled when the device is unlocked without metadata if (fs_mgr_is_device_unlocked()) { retval = FS_MGR_SETUP_VERITY_SKIPPED; @@ -760,9 +753,9 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev) params.ecc.valid = false; } - params.ecc_dev = fstab->blk_device; + params.ecc_dev = entry->blk_device.c_str(); - if (load_verity_state(fstab, ¶ms.mode) < 0) { + if (load_verity_state(*entry, ¶ms.mode) < 0) { /* if accessing or updating the state failed, switch to the default * safe mode. This makes sure the device won't end up in an endless * restart loop, and no corrupted data will be exposed to userspace @@ -803,8 +796,8 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev) << " (mode " << params.mode << ")"; // Update the verity params using the actual block device path - update_verity_table_blk_device(fstab->blk_device, ¶ms.table, - fstab->fs_mgr_flags & MF_SLOTSELECT); + update_verity_table_blk_device(entry->blk_device, ¶ms.table, + entry->fs_mgr_flags.slot_select); // load the verity mapping table if (load_verity_table(dm, mount_point, verity.data_size, ¶ms, format_verity_table) == 0) { @@ -848,31 +841,29 @@ loaded: } // mark the underlying block device as read-only - fs_mgr_set_blk_ro(fstab->blk_device); + fs_mgr_set_blk_ro(entry->blk_device); // Verify the entire partition in one go // If there is an error, allow it to mount as a normal verity partition. - if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) { - LINFO << "Verifying partition " << fstab->blk_device << " at boot"; + if (entry->fs_mgr_flags.verify_at_boot) { + LINFO << "Verifying partition " << entry->blk_device << " at boot"; int err = read_partition(verity_blk_name.c_str(), verity.data_size); if (!err) { - LINFO << "Verified verity partition " - << fstab->blk_device << " at boot"; + LINFO << "Verified verity partition " << entry->blk_device << " at boot"; verified_at_boot = true; } } // assign the new verity block device as the block device if (!verified_at_boot) { - free(fstab->blk_device); - fstab->blk_device = strdup(verity_blk_name.c_str()); + entry->blk_device = verity_blk_name; } else if (!dm.DeleteDevice(mount_point)) { LERROR << "Failed to remove verity device " << mount_point.c_str(); goto out; } // make sure we've set everything up properly - if (wait_for_verity_dev && !fs_mgr_wait_for_file(fstab->blk_device, 1s)) { + if (wait_for_verity_dev && !fs_mgr_wait_for_file(entry->blk_device, 1s)) { goto out; } diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index c1dc7314b..814ba4690 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -59,7 +59,8 @@ enum mount_mode { #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0 #define FS_MGR_MNTALL_FAIL (-1) -int fs_mgr_mount_all(fstab* fstab, int mount_mode); +// fs_mgr_mount_all() updates fstab entries that reference device-mapper. +int fs_mgr_mount_all(Fstab* fstab, int mount_mode); #define FS_MGR_DOMNT_FAILED (-1) #define FS_MGR_DOMNT_BUSY (-2) @@ -68,6 +69,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode); int fs_mgr_do_mount(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, bool need_cp); +int fs_mgr_do_mount_one(const FstabEntry& entry); int fs_mgr_do_mount_one(fstab_rec* rec); int fs_mgr_do_tmpfs_mount(const char *n_name); fstab_rec const* fs_mgr_get_crypt_entry(fstab const* fstab); @@ -76,15 +78,17 @@ bool fs_mgr_load_verity_state(int* mode); bool fs_mgr_update_verity_state( std::function callback); bool fs_mgr_swapon_all(const Fstab& fstab); +bool fs_mgr_update_logical_partition(FstabEntry* entry); bool fs_mgr_update_logical_partition(struct fstab_rec* rec); -int fs_mgr_do_format(fstab_rec* fstab, bool reserve_footer); +int fs_mgr_do_format(const FstabEntry& entry, bool reserve_footer); +int fs_mgr_do_format(fstab_rec* rec, bool reserve_footer); #define FS_MGR_SETUP_VERITY_SKIPPED (-3) #define FS_MGR_SETUP_VERITY_DISABLED (-2) #define FS_MGR_SETUP_VERITY_FAIL (-1) #define FS_MGR_SETUP_VERITY_SUCCESS 0 -int fs_mgr_setup_verity(fstab_rec* fstab, bool wait_for_verity_dev); +int fs_mgr_setup_verity(FstabEntry* fstab, bool wait_for_verity_dev); // Return the name of the super partition if it exists. If a slot number is // specified, the super partition for the corresponding metadata slot will be diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h index 0dd91212f..4bf223891 100644 --- a/fs_mgr/include/fs_mgr_overlayfs.h +++ b/fs_mgr/include/fs_mgr_overlayfs.h @@ -21,10 +21,8 @@ #include #include -bool fs_mgr_overlayfs_mount_all(fstab* fstab); -bool fs_mgr_overlayfs_mount_all(const std::vector& fstab); -std::vector fs_mgr_overlayfs_required_devices(fstab* fstab); -std::vector fs_mgr_overlayfs_required_devices(const std::vector& fstab); +bool fs_mgr_overlayfs_mount_all(Fstab* fstab); +std::vector fs_mgr_overlayfs_required_devices(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/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h index 470602828..26a1e5cbd 100644 --- a/fs_mgr/include_fstab/fstab/fstab.h +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -156,6 +156,7 @@ struct FstabEntry { bool logical : 1; bool checkpoint_blk : 1; bool checkpoint_fs : 1; + bool first_stage_mount : 1; }; } fs_mgr_flags; diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp index c4accada0..89c755ea6 100644 --- a/fs_mgr/libfs_avb/fs_avb.cpp +++ b/fs_mgr/libfs_avb/fs_avb.cpp @@ -265,7 +265,7 @@ static bool construct_verity_table(const AvbHashtreeDescriptor& hashtree_desc, return table->AddTarget(std::make_unique(target)); } -static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry, +static bool hashtree_dm_verity_setup(FstabEntry* fstab_entry, const AvbHashtreeDescriptor& hashtree_desc, const std::string& salt, const std::string& root_digest, bool wait_for_verity_dev) { @@ -278,7 +278,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry, } table.set_readonly(true); - const std::string mount_point(basename(fstab_entry->mount_point)); + const std::string mount_point(basename(fstab_entry->mount_point.c_str())); android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance(); if (!dm.CreateDevice(mount_point, table)) { LERROR << "Couldn't create verity device!"; @@ -295,8 +295,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry, fs_mgr_set_blk_ro(fstab_entry->blk_device); // Updates fstab_rec->blk_device to verity device name. - free(fstab_entry->blk_device); - fstab_entry->blk_device = strdup(dev_path.c_str()); + fstab_entry->blk_device = dev_path; // Makes sure we've set everything up properly. if (wait_for_verity_dev && !fs_mgr_wait_for_file(dev_path, 1s)) { @@ -449,8 +448,7 @@ AvbUniquePtr AvbHandle::Open() { return avb_handle; } -AvbHashtreeResult AvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry, - bool wait_for_verity_dev) { +AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) { if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) { return AvbHashtreeResult::kFail; @@ -464,13 +462,13 @@ AvbHashtreeResult AvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry, // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix. std::string partition_name; - if (fstab_entry->fs_mgr_flags & MF_LOGICAL) { + if (fstab_entry->fs_mgr_flags.logical) { partition_name = fstab_entry->logical_partition_name; } else { - partition_name = basename(fstab_entry->blk_device); + partition_name = basename(fstab_entry->blk_device.c_str()); } - if (fstab_entry->fs_mgr_flags & MF_SLOTSELECT) { + if (fstab_entry->fs_mgr_flags.slot_select) { auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix()); if (ab_suffix != std::string::npos) { partition_name.erase(ab_suffix); diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h index 9adab3dc9..08bdbdce2 100644 --- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h +++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h @@ -85,7 +85,7 @@ class AvbHandle { // failed to get the HASHTREE descriptor, runtime error when set up // device-mapper, etc. // - kDisabled: hashtree is disabled. - AvbHashtreeResult SetUpAvbHashtree(fstab_rec* fstab_entry, bool wait_for_verity_dev); + AvbHashtreeResult SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev); const std::string& avb_version() const { return avb_version_; } diff --git a/init/builtins.cpp b/init/builtins.cpp index 2bebe7673..7fd4e2737 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -473,9 +473,10 @@ static Result mount_fstab(const char* fstabfile, int mount_mode) { // Only needed if someone explicitly changes the default log level in their init.rc. android::base::ScopedLogSeverity info(android::base::INFO); - struct fstab* fstab = fs_mgr_read_fstab(fstabfile); - int child_ret = fs_mgr_mount_all(fstab, mount_mode); - fs_mgr_free_fstab(fstab); + Fstab fstab; + ReadFstabFromFile(fstabfile, &fstab); + + int child_ret = fs_mgr_mount_all(&fstab, mount_mode); if (child_ret == -1) { PLOG(ERROR) << "fs_mgr_mount_all returned an error"; } diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 6ae112342..f5b291e0f 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -70,7 +70,7 @@ class FirstStageMount { bool InitRequiredDevices(); bool InitMappedDevice(const std::string& verity_device); bool CreateLogicalPartitions(); - bool MountPartition(fstab_rec* fstab_rec); + bool MountPartition(FstabEntry* fstab_entry); bool MountPartitions(); bool IsDmLinearEnabled(); bool GetDmLinearMetadataDevice(); @@ -80,13 +80,12 @@ class FirstStageMount { // Pure virtual functions. virtual bool GetDmVerityDevices() = 0; - virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; + virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0; bool need_dm_verity_; - std::unique_ptr fstab_; + Fstab fstab_; std::string lp_metadata_partition_; - std::vector mount_fstab_recs_; std::set required_devices_partition_names_; std::string super_partition_name_; std::unique_ptr device_handler_; @@ -100,7 +99,7 @@ class FirstStageMountVBootV1 : public FirstStageMount { protected: bool GetDmVerityDevices() override; - bool SetUpDmVerity(fstab_rec* fstab_rec) override; + bool SetUpDmVerity(FstabEntry* fstab_entry) override; }; class FirstStageMountVBootV2 : public FirstStageMount { @@ -112,7 +111,7 @@ class FirstStageMountVBootV2 : public FirstStageMount { protected: bool GetDmVerityDevices() override; - bool SetUpDmVerity(fstab_rec* fstab_rec) override; + bool SetUpDmVerity(FstabEntry* fstab_entry) override; bool InitAvbHandle(); std::string device_tree_vbmeta_parts_; @@ -131,29 +130,16 @@ static bool IsRecoveryMode() { // Class Definitions // ----------------- -FirstStageMount::FirstStageMount() - : need_dm_verity_(false), - fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab), - uevent_listener_(16 * 1024 * 1024) { - // Stores fstab_->recs[] into mount_fstab_recs_ (vector) - // for easier manipulation later, e.g., range-base for loop. - if (fstab_) { - // DT Fstab predated having a first_stage_mount fs_mgr flag, so if it exists, we use it. - for (int i = 0; i < fstab_->num_entries; i++) { - mount_fstab_recs_.push_back(&fstab_->recs[i]); - } - } else { - // Fstab found in first stage ramdisk, which should be a copy of the normal fstab. - // Mounts intended for first stage are explicitly flagged as such. - fstab_.reset(fs_mgr_read_fstab_default()); - if (fstab_) { - for (int i = 0; i < fstab_->num_entries; i++) { - if (fs_mgr_is_first_stage_mount(&fstab_->recs[i])) { - mount_fstab_recs_.push_back(&fstab_->recs[i]); - } - } +FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) { + if (!ReadFstabFromDt(&fstab_)) { + if (ReadDefaultFstab(&fstab_)) { + fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(), + [](const auto& entry) { + return !entry.fs_mgr_flags.first_stage_mount; + }), + fstab_.end()); } else { - LOG(INFO) << "Failed to read fstab from device tree"; + LOG(INFO) << "Failed to fstab for first stage mount"; } } @@ -174,7 +160,7 @@ std::unique_ptr FirstStageMount::Create() { } bool FirstStageMount::DoFirstStageMount() { - if (!IsDmLinearEnabled() && mount_fstab_recs_.empty()) { + if (!IsDmLinearEnabled() && fstab_.empty()) { // Nothing to mount. LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; return true; @@ -194,8 +180,8 @@ bool FirstStageMount::InitDevices() { } bool FirstStageMount::IsDmLinearEnabled() { - for (auto fstab_rec : mount_fstab_recs_) { - if (fs_mgr_is_logical(fstab_rec)) return true; + for (const auto& entry : fstab_) { + if (entry.fs_mgr_flags.logical) return true; } return false; } @@ -381,21 +367,21 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) { return true; } -bool FirstStageMount::MountPartition(fstab_rec* fstab_rec) { - if (fs_mgr_is_logical(fstab_rec)) { - if (!fs_mgr_update_logical_partition(fstab_rec)) { +bool FirstStageMount::MountPartition(FstabEntry* fstab_entry) { + if (fstab_entry->fs_mgr_flags.logical) { + if (!fs_mgr_update_logical_partition(fstab_entry)) { return false; } - if (!InitMappedDevice(fstab_rec->blk_device)) { + if (!InitMappedDevice(fstab_entry->blk_device)) { return false; } } - if (!SetUpDmVerity(fstab_rec)) { - PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'"; + if (!SetUpDmVerity(fstab_entry)) { + PLOG(ERROR) << "Failed to setup verity for '" << fstab_entry->mount_point << "'"; return false; } - if (fs_mgr_do_mount_one(fstab_rec)) { - PLOG(ERROR) << "Failed to mount '" << fstab_rec->mount_point << "'"; + if (fs_mgr_do_mount_one(*fstab_entry)) { + PLOG(ERROR) << "Failed to mount '" << fstab_entry->mount_point << "'"; return false; } return true; @@ -405,28 +391,28 @@ bool FirstStageMount::MountPartitions() { // If system is in the fstab then we're not a system-as-root device, and in // this case, we mount system first then pivot to it. From that point on, // we are effectively identical to a system-as-root device. - auto system_partition = - std::find_if(mount_fstab_recs_.begin(), mount_fstab_recs_.end(), - [](const auto& rec) { return rec->mount_point == "/system"s; }); + auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) { + return entry.mount_point == "/system"; + }); - if (system_partition != mount_fstab_recs_.end()) { - if (!MountPartition(*system_partition)) { + if (system_partition != fstab_.end()) { + if (!MountPartition(&(*system_partition))) { return false; } - SwitchRoot((*system_partition)->mount_point); + SwitchRoot((*system_partition).mount_point); - mount_fstab_recs_.erase(system_partition); + fstab_.erase(system_partition); } - for (auto fstab_rec : mount_fstab_recs_) { - if (!MountPartition(fstab_rec) && !fs_mgr_is_nofail(fstab_rec)) { + for (auto& fstab_entry : fstab_) { + if (!MountPartition(&fstab_entry) && !fstab_entry.fs_mgr_flags.no_fail) { return false; } } // heads up for instantiating required device(s) for overlayfs logic - const auto devices = fs_mgr_overlayfs_required_devices(mount_fstab_recs_); + const auto devices = fs_mgr_overlayfs_required_devices(&fstab_); for (auto const& device : devices) { if (android::base::StartsWith(device, "/dev/block/by-name/")) { required_devices_partition_names_.emplace(basename(device.c_str())); @@ -438,7 +424,7 @@ bool FirstStageMount::MountPartitions() { } } - fs_mgr_overlayfs_mount_all(mount_fstab_recs_); + fs_mgr_overlayfs_mount_all(&fstab_); return true; } @@ -447,25 +433,25 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() { std::string verity_loc_device; need_dm_verity_ = false; - for (auto fstab_rec : mount_fstab_recs_) { + for (const auto& fstab_entry : fstab_) { // Don't allow verifyatboot in the first stage. - if (fs_mgr_is_verifyatboot(fstab_rec)) { + if (fstab_entry.fs_mgr_flags.verify_at_boot) { LOG(ERROR) << "Partitions can't be verified at boot"; return false; } // Checks for verified partitions. - if (fs_mgr_is_verified(fstab_rec)) { + if (fstab_entry.fs_mgr_flags.verify) { need_dm_verity_ = true; } // Checks if verity metadata is on a separate partition. Note that it is // not partition specific, so there must be only one additional partition // that carries verity state. - if (fstab_rec->verity_loc) { + if (!fstab_entry.verity_loc.empty()) { if (verity_loc_device.empty()) { - verity_loc_device = fstab_rec->verity_loc; - } else if (verity_loc_device != fstab_rec->verity_loc) { + verity_loc_device = fstab_entry.verity_loc; + } else if (verity_loc_device != fstab_entry.verity_loc) { LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", " - << fstab_rec->verity_loc; + << fstab_entry.verity_loc; return false; } } @@ -473,9 +459,9 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() { // Includes the partition names of fstab records and verity_loc_device (if any). // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used. - for (auto fstab_rec : mount_fstab_recs_) { - if (!fs_mgr_is_logical(fstab_rec)) { - required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); + for (const auto& fstab_entry : fstab_) { + if (!fstab_entry.fs_mgr_flags.logical) { + required_devices_partition_names_.emplace(basename(fstab_entry.blk_device.c_str())); } } @@ -486,19 +472,19 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() { return true; } -bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { - if (fs_mgr_is_verified(fstab_rec)) { - int ret = fs_mgr_setup_verity(fstab_rec, false /* wait_for_verity_dev */); +bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) { + if (fstab_entry->fs_mgr_flags.verify) { + int ret = fs_mgr_setup_verity(fstab_entry, false /* wait_for_verity_dev */); switch (ret) { case FS_MGR_SETUP_VERITY_SKIPPED: case FS_MGR_SETUP_VERITY_DISABLED: - LOG(INFO) << "Verity disabled/skipped for '" << fstab_rec->mount_point << "'"; + LOG(INFO) << "Verity disabled/skipped for '" << fstab_entry->mount_point << "'"; return true; case FS_MGR_SETUP_VERITY_SUCCESS: // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. - return InitMappedDevice(fstab_rec->blk_device); + return InitMappedDevice(fstab_entry->blk_device); default: return false; } @@ -531,15 +517,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() { std::set logical_partitions; // fstab_rec->blk_device has A/B suffix. - for (auto fstab_rec : mount_fstab_recs_) { - if (fs_mgr_is_avb(fstab_rec)) { + for (const auto& fstab_entry : fstab_) { + if (fstab_entry.fs_mgr_flags.avb) { need_dm_verity_ = true; } - if (fs_mgr_is_logical(fstab_rec)) { + if (fstab_entry.fs_mgr_flags.logical) { // Don't try to find logical partitions via uevent regeneration. - logical_partitions.emplace(basename(fstab_rec->blk_device)); + logical_partitions.emplace(basename(fstab_entry.blk_device.c_str())); } else { - required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); + required_devices_partition_names_.emplace(basename(fstab_entry.blk_device.c_str())); } } @@ -569,11 +555,11 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() { return true; } -bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { - if (fs_mgr_is_avb(fstab_rec)) { +bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) { + if (fstab_entry->fs_mgr_flags.avb) { if (!InitAvbHandle()) return false; AvbHashtreeResult hashtree_result = - avb_handle_->SetUpAvbHashtree(fstab_rec, false /* wait_for_verity_dev */); + avb_handle_->SetUpAvbHashtree(fstab_entry, false /* wait_for_verity_dev */); switch (hashtree_result) { case AvbHashtreeResult::kDisabled: return true; // Returns true to mount the partition. @@ -581,7 +567,7 @@ bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { // The exact block device name (fstab_rec->blk_device) is changed to // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init // first stage. - return InitMappedDevice(fstab_rec->blk_device); + return InitMappedDevice(fstab_entry->blk_device); default: return false; } diff --git a/libcutils/include/cutils/partition_utils.h b/libcutils/include/cutils/partition_utils.h index 7518559a4..8bc9b48b3 100644 --- a/libcutils/include/cutils/partition_utils.h +++ b/libcutils/include/cutils/partition_utils.h @@ -21,7 +21,7 @@ __BEGIN_DECLS -int partition_wiped(char *source); +int partition_wiped(const char* source); __END_DECLS diff --git a/libcutils/partition_utils.cpp b/libcutils/partition_utils.cpp index 2211ff6ad..b8405595c 100644 --- a/libcutils/partition_utils.cpp +++ b/libcutils/partition_utils.cpp @@ -39,8 +39,7 @@ static int only_one_char(uint8_t *buf, int len, uint8_t c) return ret; } -int partition_wiped(char *source) -{ +int partition_wiped(const char* source) { uint8_t buf[4096]; int fd, ret; @@ -67,4 +66,3 @@ int partition_wiped(char *source) return 0; } -