Merge "Start using new C++ Fstab class widely"

am: 07eea062d5

Change-Id: I9b362037be9e4a105e2386cbd8e513e324550a04
This commit is contained in:
Tom Cherry 2018-12-12 10:04:13 -08:00 committed by android-build-merger
commit 7481fe9316
15 changed files with 509 additions and 597 deletions

View file

@ -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 // If we can use overlayfs, lets get it in place first
// before we struggle with determining deduplication operations. // before we struggle with determining deduplication operations.
if (!verity_enabled && fs_mgr_overlayfs_setup()) { if (!verity_enabled && fs_mgr_overlayfs_setup()) {
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), Fstab fstab;
fs_mgr_free_fstab); if (ReadDefaultFstab(&fstab) && fs_mgr_overlayfs_mount_all(&fstab)) {
if (fs_mgr_overlayfs_mount_all(fstab.get())) {
WriteFdExactly(fd.get(), "overlayfs mounted\n"); WriteFdExactly(fd.get(), "overlayfs mounted\n");
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -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); LOG_KLOG, true, nullptr, nullptr, 0);
} }
int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer) int fs_mgr_do_format(const FstabEntry& entry, bool crypt_footer) {
{ LERROR << __FUNCTION__ << ": Format " << entry.blk_device << " as '" << entry.fs_type << "'";
int rc = -EINVAL;
LERROR << __FUNCTION__ << ": Format " << fstab->blk_device if (entry.fs_type == "f2fs") {
<< " as '" << fstab->fs_type << "'"; return format_f2fs(entry.blk_device, entry.length, crypt_footer);
} else if (entry.fs_type == "ext4") {
if (!strncmp(fstab->fs_type, "f2fs", 4)) { return format_ext4(entry.blk_device, entry.mount_point, crypt_footer);
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);
} else { } 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);
} }

View file

@ -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 #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; return false;
} }
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>&) { std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
return false;
}
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab*) {
return {};
}
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>&) {
return {}; 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, // At less than 1% free space return value of false,
// means we will try to wrap with overlayfs. // 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 // If we have access issues to find out space remaining, return true
// to prevent us trying to override with overlayfs. // to prevent us trying to override with overlayfs.
struct statvfs vst; 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% static constexpr int kPercentThreshold = 1; // 1%
return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100)); 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 // readonly filesystem, can not be mount -o remount,rw
// if squashfs or if free space is (near) zero making such a remount // 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 // 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; return true;
} }
if (fs_mgr_is_logical(fsrec)) { if (entry->fs_mgr_flags.logical) {
fs_mgr_update_logical_partition(fsrec); 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) { 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) { bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true) {
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab("/proc/mounts"), Fstab fstab;
fs_mgr_free_fstab); if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
if (!fstab) return false; return false;
}
const auto lowerdir = kLowerdirOption + mount_point; const auto lowerdir = kLowerdirOption + mount_point;
for (auto i = 0; i < fstab->num_entries; ++i) { for (const auto& entry : fstab) {
const auto fsrec = &fstab->recs[i]; if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
const auto fs_type = fsrec->fs_type; if (mount_point != entry.mount_point) continue;
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;
if (!overlay_only) return true; if (!overlay_only) return true;
const auto fs_options = fsrec->fs_options; const auto options = android::base::Split(entry.fs_options, ",");
if (!fs_options) continue;
const auto options = android::base::Split(fs_options, ",");
for (const auto& opt : options) { for (const auto& opt : options) {
if (opt == lowerdir) { if (opt == lowerdir) {
return true; return true;
@ -282,28 +268,20 @@ std::vector<std::string> fs_mgr_overlayfs_verity_enabled_list() {
return ret; return ret;
} }
bool fs_mgr_wants_overlayfs(fstab_rec* fsrec) { bool fs_mgr_wants_overlayfs(FstabEntry* entry) {
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;
// Don't check entries that are managed by vold. // 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. // 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 // If unbindable, do not allow overlayfs as this could expose us to
// security issues. On Android, this could also be used to turn off // security issues. On Android, this could also be used to turn off
// the ability to overlay an otherwise acceptable filesystem since // the ability to overlay an otherwise acceptable filesystem since
// /system and /vendor are never bound(sic) to. // /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; 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); return kPhysicalDevice + fs_mgr_get_super_partition_name(slot_number);
} }
bool fs_mgr_overlayfs_has_logical(const fstab* fstab) { bool fs_mgr_overlayfs_has_logical(const Fstab& fstab) {
if (!fstab) return false; for (const auto& entry : fstab) {
for (auto i = 0; i < fstab->num_entries; i++) { if (entry.fs_mgr_flags.logical) {
const auto fsrec = &fstab->recs[i]; return true;
if (fs_mgr_is_logical(fsrec)) return true; }
} }
return false; return false;
} }
@ -540,15 +518,12 @@ bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
} }
} }
std::vector<std::string> fs_mgr_candidate_list(fstab* fstab, const char* mount_point = nullptr) { std::vector<std::string> fs_mgr_candidate_list(Fstab* fstab, const char* mount_point = nullptr) {
std::vector<std::string> mounts; std::vector<std::string> mounts;
if (!fstab) return mounts;
auto verity = fs_mgr_overlayfs_verity_enabled_list(); auto verity = fs_mgr_overlayfs_verity_enabled_list();
for (auto i = 0; i < fstab->num_entries; i++) { for (auto& entry : *fstab) {
const auto fsrec = &fstab->recs[i]; if (!fs_mgr_wants_overlayfs(&entry)) continue;
if (!fs_mgr_wants_overlayfs(fsrec)) continue; std::string new_mount_point(fs_mgr_mount_point(entry.mount_point.c_str()));
std::string new_mount_point(fs_mgr_mount_point(fsrec->mount_point));
if (mount_point && (new_mount_point != mount_point)) continue; if (mount_point && (new_mount_point != mount_point)) continue;
if (std::find(verity.begin(), verity.end(), android::base::Basename(new_mount_point)) != if (std::find(verity.begin(), verity.end(), android::base::Basename(new_mount_point)) !=
verity.end()) { verity.end()) {
@ -580,10 +555,9 @@ std::vector<std::string> fs_mgr_candidate_list(fstab* fstab, const char* mount_p
if (std::find(verity.begin(), verity.end(), "system") != verity.end()) return mounts; if (std::find(verity.begin(), verity.end(), "system") != verity.end()) return mounts;
// confirm that fstab is missing system // confirm that fstab is missing system
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), "/")) { if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) {
return mounts; return entry.mount_point == "/" || entry.mount_point == "/system ";
} }) != fstab->end()) {
if (fs_mgr_get_entry_for_mount_point(const_cast<struct fstab*>(fstab), "/system")) {
return mounts; return mounts;
} }
@ -605,26 +579,20 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s
PERROR << "create " << kScratchMountPoint; PERROR << "create " << kScratchMountPoint;
} }
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> local_fstab( FstabEntry entry;
static_cast<fstab*>(calloc(1, sizeof(fstab))), fs_mgr_free_fstab); entry.blk_device = device_path;
auto fsrec = static_cast<fstab_rec*>(calloc(1, sizeof(fstab_rec))); entry.mount_point = kScratchMountPoint;
local_fstab->num_entries = 1; entry.fs_type = mnt_type;
local_fstab->recs = fsrec; entry.flags = MS_RELATIME;
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("");
auto save_errno = errno; auto save_errno = errno;
auto mounted = fs_mgr_do_mount_one(fsrec) == 0; auto mounted = fs_mgr_do_mount_one(entry) == 0;
if (!mounted) { if (!mounted) {
free(fsrec->fs_type);
if (mnt_type == "f2fs") { if (mnt_type == "f2fs") {
fsrec->fs_type = strdup("ext4"); entry.fs_type = "ext4";
} else { } 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; if (!mounted) save_errno = errno;
} }
setfscreatecon(nullptr); setfscreatecon(nullptr);
@ -681,7 +649,7 @@ bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std:
return true; 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) { bool* partition_exists, bool* change) {
*scratch_device = fs_mgr_overlayfs_scratch_device(); *scratch_device = fs_mgr_overlayfs_scratch_device();
*partition_exists = fs_mgr_rw_access(*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 // 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; if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
std::string scratch_device; 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; 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; if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return true;
// in recovery or fastbootd mode, not allowed! // in recovery or fastbootd mode, not allowed!
if (fs_mgr_access("/system/bin/recovery")) return true; if (fs_mgr_access("/system/bin/recovery")) return true;
return !fstab; return false;
} }
} // namespace } // namespace
bool fs_mgr_overlayfs_mount_all(fstab* fstab) { bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
auto ret = false; auto ret = false;
if (fs_mgr_overlayfs_invalid(fstab)) return ret; if (fs_mgr_overlayfs_invalid()) return ret;
auto scratch_can_be_mounted = true; auto scratch_can_be_mounted = true;
for (const auto& mount_point : fs_mgr_candidate_list(fstab)) { for (const auto& mount_point : fs_mgr_candidate_list(fstab)) {
@ -839,17 +807,12 @@ bool fs_mgr_overlayfs_mount_all(fstab* fstab) {
return ret; return ret;
} }
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fsrecs) { std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab) {
std::vector<fstab_rec> recs; if (fs_mgr_overlayfs_invalid()) return {};
for (const auto& rec : fsrecs) recs.push_back(*rec);
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
return fs_mgr_overlayfs_mount_all(&fstab);
}
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) { if (std::find_if(fstab->begin(), fstab->end(), [](const auto& entry) {
if (fs_mgr_overlayfs_invalid(fstab)) return {}; return entry.mount_point == kScratchMountPoint;
}) != fstab->end()) {
if (fs_mgr_get_entry_for_mount_point(fstab, kScratchMountPoint)) {
return {}; return {};
} }
@ -862,13 +825,6 @@ std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab) {
return {}; return {};
} }
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fsrecs) {
std::vector<fstab_rec> recs;
for (const auto& rec : fsrecs) recs.push_back(*rec);
fstab fstab = {static_cast<int>(fsrecs.size()), &recs[0]};
return fs_mgr_overlayfs_required_devices(&fstab);
}
// Returns false if setup not permitted, errno set to last error. // Returns false if setup not permitted, errno set to last error.
// If something is altered, set *change. // If something is altered, set *change.
bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* 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; return ret;
} }
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), Fstab fstab;
fs_mgr_free_fstab); if (!ReadDefaultFstab(&fstab)) {
if (!fstab) return ret; return false;
auto mounts = fs_mgr_candidate_list(fstab.get(), fs_mgr_mount_point(mount_point)); }
auto mounts = fs_mgr_candidate_list(&fstab, fs_mgr_mount_point(mount_point));
if (mounts.empty()) return ret; if (mounts.empty()) return ret;
std::string dir; 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 (backing && backing[0] && (overlay_mount_point != backing)) continue;
if (overlay_mount_point == kScratchMountPoint) { if (overlay_mount_point == kScratchMountPoint) {
if (!fs_mgr_rw_access(fs_mgr_overlayfs_super_device(fs_mgr_overlayfs_slot_number())) || 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; continue;
} }
if (!fs_mgr_overlayfs_setup_scratch(fstab.get(), change)) continue; if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
} else { } 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; dir = overlay_mount_point;
break; break;
@ -959,10 +920,12 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) {
bool fs_mgr_overlayfs_is_setup() { bool fs_mgr_overlayfs_is_setup() {
if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true; if (fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) return true;
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(), Fstab fstab;
fs_mgr_free_fstab); if (!ReadDefaultFstab(&fstab)) {
if (fs_mgr_overlayfs_invalid(fstab.get())) return false; return false;
for (const auto& mount_point : fs_mgr_candidate_list(fstab.get())) { }
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; if (fs_mgr_overlayfs_already_mounted(mount_point)) return true;
} }
return false; return false;

View file

@ -137,6 +137,6 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab);
bool fs_mgr_is_device_unlocked(); bool fs_mgr_is_device_unlocked();
const std::string& get_android_dt_dir(); const std::string& get_android_dt_dir();
bool is_dt_compatible(); 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 */ #endif /* __CORE_FS_MGR_PRIV_H */

View file

@ -536,8 +536,7 @@ static int read_partition(const char *path, uint64_t size)
return 0; 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]; char tag[METADATA_TAG_MAX_LENGTH + 1];
int fd = -1; int fd = -1;
int rc = -1; int rc = -1;
@ -549,42 +548,40 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match)
*match = 1; *match = 1;
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, if (fec_open(&f, entry.blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) ==
FEC_DEFAULT_ROOTS) == -1) { -1) {
PERROR << "Failed to open '" << fstab->blk_device << "'"; PERROR << "Failed to open '" << entry.blk_device << "'";
return rc; return rc;
} }
// read verity metadata // read verity metadata
if (fec_verity_get_metadata(f, &verity) == -1) { 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; goto out;
} }
SHA256(verity.signature, sizeof(verity.signature), curr); SHA256(verity.signature, sizeof(verity.signature), curr);
if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", basename(entry.mount_point.c_str())) >=
basename(fstab->mount_point)) >= (int)sizeof(tag)) { (int)sizeof(tag)) {
LERROR << "Metadata tag name too long for " << fstab->mount_point; LERROR << "Metadata tag name too long for " << entry.mount_point;
goto out; goto out;
} }
if (metadata_find(fstab->verity_loc, tag, SHA256_DIGEST_LENGTH, if (metadata_find(entry.verity_loc.c_str(), tag, SHA256_DIGEST_LENGTH, &offset) < 0) {
&offset) < 0) {
goto out; 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) { if (fd == -1) {
PERROR << "Failed to open " << fstab->verity_loc; PERROR << "Failed to open " << entry.verity_loc;
goto out; goto out;
} }
if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), offset)) != sizeof(prev)) {
offset)) != sizeof(prev)) { PERROR << "Failed to read " << sizeof(prev) << " bytes from " << entry.verity_loc
PERROR << "Failed to read " << sizeof(prev) << " bytes from " << " offset " << offset;
<< fstab->verity_loc << " offset " << offset;
goto out; goto out;
} }
@ -594,8 +591,8 @@ static int compare_last_signature(struct fstab_rec *fstab, int *match)
/* update current signature hash */ /* update current signature hash */
if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr), if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr),
offset)) != sizeof(curr)) { offset)) != sizeof(curr)) {
PERROR << "Failed to write " << sizeof(curr) << " bytes to " PERROR << "Failed to write " << sizeof(curr) << " bytes to " << entry.verity_loc
<< fstab->verity_loc << " offset " << offset; << " offset " << offset;
goto out; goto out;
} }
} }
@ -607,28 +604,23 @@ out:
return rc; 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]; char tag[METADATA_TAG_MAX_LENGTH + 1];
if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", basename(entry.mount_point.c_str())) >=
basename(fstab->mount_point)) >= (int)sizeof(tag)) { (int)sizeof(tag)) {
LERROR << "Metadata tag name too long for " << fstab->mount_point; LERROR << "Metadata tag name too long for " << entry.mount_point;
return -1; return -1;
} }
return metadata_find(fstab->verity_loc, tag, sizeof(struct verity_state), return metadata_find(entry.verity_loc.c_str(), tag, sizeof(struct verity_state), offset);
offset);
} }
int load_verity_state(struct fstab_rec* fstab, int* mode) { int load_verity_state(const FstabEntry& entry, int* mode) {
int match = 0; // unless otherwise specified, use EIO mode.
off64_t offset = 0;
/* unless otherwise specified, use EIO mode */
*mode = VERITY_MODE_EIO; *mode = VERITY_MODE_EIO;
/* use the kernel parameter if set */ // use the kernel parameter if set.
std::string veritymode; std::string veritymode;
if (fs_mgr_get_boot_config("veritymode", &veritymode)) { if (fs_mgr_get_boot_config("veritymode", &veritymode)) {
if (veritymode == "enforcing") { if (veritymode == "enforcing") {
@ -637,7 +629,8 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) {
return 0; 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 */ /* fall back to stateless behavior */
return 0; return 0;
} }
@ -645,16 +638,17 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) {
if (was_verity_restart()) { if (was_verity_restart()) {
/* device was restarted after dm-verity detected a corrupted /* device was restarted after dm-verity detected a corrupted
* block, so use EIO mode */ * 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 */ /* partition has been reflashed, reset dm-verity state */
*mode = VERITY_MODE_DEFAULT; *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. // 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 // prepares the verity enabled (MF_VERIFY / MF_VERIFYATBOOT) fstab record for
// mount. The 'wait_for_verity_dev' parameter makes this function wait for the // mount. The 'wait_for_verity_dev' parameter makes this function wait for the
// verity device to get created before return // 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 retval = FS_MGR_SETUP_VERITY_FAIL;
int fd = -1; int fd = -1;
std::string verity_blk_name; 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 fec_verity_metadata verity;
struct verity_table_params params = { .table = NULL }; 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; bool verified_at_boot = false;
android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance(); android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE, if (fec_open(&f, entry->blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) <
FEC_DEFAULT_ROOTS) < 0) { 0) {
PERROR << "Failed to open '" << fstab->blk_device << "'"; PERROR << "Failed to open '" << entry->blk_device << "'";
return retval; return retval;
} }
// read verity metadata // read verity metadata
if (fec_verity_get_metadata(f, &verity) < 0) { 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 // Allow verity disabled when the device is unlocked without metadata
if (fs_mgr_is_device_unlocked()) { if (fs_mgr_is_device_unlocked()) {
retval = FS_MGR_SETUP_VERITY_SKIPPED; 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.valid = false;
} }
params.ecc_dev = fstab->blk_device; params.ecc_dev = entry->blk_device.c_str();
if (load_verity_state(fstab, &params.mode) < 0) { if (load_verity_state(*entry, &params.mode) < 0) {
/* if accessing or updating the state failed, switch to the default /* 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 * 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 * 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 << ")"; << " (mode " << params.mode << ")";
// Update the verity params using the actual block device path // Update the verity params using the actual block device path
update_verity_table_blk_device(fstab->blk_device, &params.table, update_verity_table_blk_device(entry->blk_device, &params.table,
fstab->fs_mgr_flags & MF_SLOTSELECT); entry->fs_mgr_flags.slot_select);
// load the verity mapping table // load the verity mapping table
if (load_verity_table(dm, mount_point, verity.data_size, &params, format_verity_table) == 0) { if (load_verity_table(dm, mount_point, verity.data_size, &params, format_verity_table) == 0) {
@ -848,31 +841,29 @@ loaded:
} }
// mark the underlying block device as read-only // 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 // Verify the entire partition in one go
// If there is an error, allow it to mount as a normal verity partition. // If there is an error, allow it to mount as a normal verity partition.
if (fstab->fs_mgr_flags & MF_VERIFYATBOOT) { if (entry->fs_mgr_flags.verify_at_boot) {
LINFO << "Verifying partition " << fstab->blk_device << " at boot"; LINFO << "Verifying partition " << entry->blk_device << " at boot";
int err = read_partition(verity_blk_name.c_str(), verity.data_size); int err = read_partition(verity_blk_name.c_str(), verity.data_size);
if (!err) { if (!err) {
LINFO << "Verified verity partition " LINFO << "Verified verity partition " << entry->blk_device << " at boot";
<< fstab->blk_device << " at boot";
verified_at_boot = true; verified_at_boot = true;
} }
} }
// assign the new verity block device as the block device // assign the new verity block device as the block device
if (!verified_at_boot) { if (!verified_at_boot) {
free(fstab->blk_device); entry->blk_device = verity_blk_name;
fstab->blk_device = strdup(verity_blk_name.c_str());
} else if (!dm.DeleteDevice(mount_point)) { } else if (!dm.DeleteDevice(mount_point)) {
LERROR << "Failed to remove verity device " << mount_point.c_str(); LERROR << "Failed to remove verity device " << mount_point.c_str();
goto out; goto out;
} }
// make sure we've set everything up properly // 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; goto out;
} }

View file

@ -59,7 +59,8 @@ enum mount_mode {
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 1
#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE 0
#define FS_MGR_MNTALL_FAIL (-1) #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_FAILED (-1)
#define FS_MGR_DOMNT_BUSY (-2) #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);
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); 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_mount_one(fstab_rec* rec);
int fs_mgr_do_tmpfs_mount(const char *n_name); int fs_mgr_do_tmpfs_mount(const char *n_name);
fstab_rec const* fs_mgr_get_crypt_entry(fstab const* fstab); 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( bool fs_mgr_update_verity_state(
std::function<void(const std::string& mount_point, int mode)> callback); std::function<void(const std::string& mount_point, int mode)> callback);
bool fs_mgr_swapon_all(const Fstab& fstab); 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); 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_SKIPPED (-3)
#define FS_MGR_SETUP_VERITY_DISABLED (-2) #define FS_MGR_SETUP_VERITY_DISABLED (-2)
#define FS_MGR_SETUP_VERITY_FAIL (-1) #define FS_MGR_SETUP_VERITY_FAIL (-1)
#define FS_MGR_SETUP_VERITY_SUCCESS 0 #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 // 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 // specified, the super partition for the corresponding metadata slot will be

View file

@ -21,10 +21,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
bool fs_mgr_overlayfs_mount_all(fstab* fstab); bool fs_mgr_overlayfs_mount_all(Fstab* fstab);
bool fs_mgr_overlayfs_mount_all(const std::vector<fstab_rec*>& fstab); std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab* fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(fstab* fstab);
std::vector<std::string> fs_mgr_overlayfs_required_devices(const std::vector<fstab_rec*>& fstab);
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr, bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
bool* change = nullptr); bool* change = nullptr);
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr); bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);

View file

@ -156,6 +156,7 @@ struct FstabEntry {
bool logical : 1; bool logical : 1;
bool checkpoint_blk : 1; bool checkpoint_blk : 1;
bool checkpoint_fs : 1; bool checkpoint_fs : 1;
bool first_stage_mount : 1;
}; };
} fs_mgr_flags; } fs_mgr_flags;

View file

@ -265,7 +265,7 @@ static bool construct_verity_table(const AvbHashtreeDescriptor& hashtree_desc,
return table->AddTarget(std::make_unique<android::dm::DmTargetVerity>(target)); return table->AddTarget(std::make_unique<android::dm::DmTargetVerity>(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 AvbHashtreeDescriptor& hashtree_desc,
const std::string& salt, const std::string& root_digest, const std::string& salt, const std::string& root_digest,
bool wait_for_verity_dev) { bool wait_for_verity_dev) {
@ -278,7 +278,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
} }
table.set_readonly(true); 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(); android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance();
if (!dm.CreateDevice(mount_point, table)) { if (!dm.CreateDevice(mount_point, table)) {
LERROR << "Couldn't create verity device!"; 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); fs_mgr_set_blk_ro(fstab_entry->blk_device);
// Updates fstab_rec->blk_device to verity device name. // Updates fstab_rec->blk_device to verity device name.
free(fstab_entry->blk_device); fstab_entry->blk_device = dev_path;
fstab_entry->blk_device = strdup(dev_path.c_str());
// Makes sure we've set everything up properly. // Makes sure we've set everything up properly.
if (wait_for_verity_dev && !fs_mgr_wait_for_file(dev_path, 1s)) { if (wait_for_verity_dev && !fs_mgr_wait_for_file(dev_path, 1s)) {
@ -449,8 +448,7 @@ AvbUniquePtr AvbHandle::Open() {
return avb_handle; return avb_handle;
} }
AvbHashtreeResult AvbHandle::SetUpAvbHashtree(struct fstab_rec* fstab_entry, AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) {
bool wait_for_verity_dev) {
if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ || if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ ||
avb_slot_data_->num_vbmeta_images < 1) { avb_slot_data_->num_vbmeta_images < 1) {
return AvbHashtreeResult::kFail; 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 // 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. // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
std::string partition_name; 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; partition_name = fstab_entry->logical_partition_name;
} else { } 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()); auto ab_suffix = partition_name.rfind(fs_mgr_get_slot_suffix());
if (ab_suffix != std::string::npos) { if (ab_suffix != std::string::npos) {
partition_name.erase(ab_suffix); partition_name.erase(ab_suffix);

View file

@ -85,7 +85,7 @@ class AvbHandle {
// failed to get the HASHTREE descriptor, runtime error when set up // failed to get the HASHTREE descriptor, runtime error when set up
// device-mapper, etc. // device-mapper, etc.
// - kDisabled: hashtree is disabled. // - 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_; } const std::string& avb_version() const { return avb_version_; }

View file

@ -473,9 +473,10 @@ static Result<int> mount_fstab(const char* fstabfile, int mount_mode) {
// Only needed if someone explicitly changes the default log level in their init.rc. // Only needed if someone explicitly changes the default log level in their init.rc.
android::base::ScopedLogSeverity info(android::base::INFO); android::base::ScopedLogSeverity info(android::base::INFO);
struct fstab* fstab = fs_mgr_read_fstab(fstabfile); Fstab fstab;
int child_ret = fs_mgr_mount_all(fstab, mount_mode); ReadFstabFromFile(fstabfile, &fstab);
fs_mgr_free_fstab(fstab);
int child_ret = fs_mgr_mount_all(&fstab, mount_mode);
if (child_ret == -1) { if (child_ret == -1) {
PLOG(ERROR) << "fs_mgr_mount_all returned an error"; PLOG(ERROR) << "fs_mgr_mount_all returned an error";
} }

View file

@ -70,7 +70,7 @@ class FirstStageMount {
bool InitRequiredDevices(); bool InitRequiredDevices();
bool InitMappedDevice(const std::string& verity_device); bool InitMappedDevice(const std::string& verity_device);
bool CreateLogicalPartitions(); bool CreateLogicalPartitions();
bool MountPartition(fstab_rec* fstab_rec); bool MountPartition(FstabEntry* fstab_entry);
bool MountPartitions(); bool MountPartitions();
bool IsDmLinearEnabled(); bool IsDmLinearEnabled();
bool GetDmLinearMetadataDevice(); bool GetDmLinearMetadataDevice();
@ -80,13 +80,12 @@ class FirstStageMount {
// Pure virtual functions. // Pure virtual functions.
virtual bool GetDmVerityDevices() = 0; virtual bool GetDmVerityDevices() = 0;
virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0; virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
bool need_dm_verity_; bool need_dm_verity_;
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab_; Fstab fstab_;
std::string lp_metadata_partition_; std::string lp_metadata_partition_;
std::vector<fstab_rec*> mount_fstab_recs_;
std::set<std::string> required_devices_partition_names_; std::set<std::string> required_devices_partition_names_;
std::string super_partition_name_; std::string super_partition_name_;
std::unique_ptr<DeviceHandler> device_handler_; std::unique_ptr<DeviceHandler> device_handler_;
@ -100,7 +99,7 @@ class FirstStageMountVBootV1 : public FirstStageMount {
protected: protected:
bool GetDmVerityDevices() override; bool GetDmVerityDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override; bool SetUpDmVerity(FstabEntry* fstab_entry) override;
}; };
class FirstStageMountVBootV2 : public FirstStageMount { class FirstStageMountVBootV2 : public FirstStageMount {
@ -112,7 +111,7 @@ class FirstStageMountVBootV2 : public FirstStageMount {
protected: protected:
bool GetDmVerityDevices() override; bool GetDmVerityDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override; bool SetUpDmVerity(FstabEntry* fstab_entry) override;
bool InitAvbHandle(); bool InitAvbHandle();
std::string device_tree_vbmeta_parts_; std::string device_tree_vbmeta_parts_;
@ -131,29 +130,16 @@ static bool IsRecoveryMode() {
// Class Definitions // Class Definitions
// ----------------- // -----------------
FirstStageMount::FirstStageMount() FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) {
: need_dm_verity_(false), if (!ReadFstabFromDt(&fstab_)) {
fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab), if (ReadDefaultFstab(&fstab_)) {
uevent_listener_(16 * 1024 * 1024) { fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(),
// Stores fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>) [](const auto& entry) {
// for easier manipulation later, e.g., range-base for loop. return !entry.fs_mgr_flags.first_stage_mount;
if (fstab_) { }),
// DT Fstab predated having a first_stage_mount fs_mgr flag, so if it exists, we use it. fstab_.end());
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]);
}
}
} else { } 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> FirstStageMount::Create() {
} }
bool FirstStageMount::DoFirstStageMount() { bool FirstStageMount::DoFirstStageMount() {
if (!IsDmLinearEnabled() && mount_fstab_recs_.empty()) { if (!IsDmLinearEnabled() && fstab_.empty()) {
// Nothing to mount. // Nothing to mount.
LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)"; LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
return true; return true;
@ -194,8 +180,8 @@ bool FirstStageMount::InitDevices() {
} }
bool FirstStageMount::IsDmLinearEnabled() { bool FirstStageMount::IsDmLinearEnabled() {
for (auto fstab_rec : mount_fstab_recs_) { for (const auto& entry : fstab_) {
if (fs_mgr_is_logical(fstab_rec)) return true; if (entry.fs_mgr_flags.logical) return true;
} }
return false; return false;
} }
@ -381,21 +367,21 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
return true; return true;
} }
bool FirstStageMount::MountPartition(fstab_rec* fstab_rec) { bool FirstStageMount::MountPartition(FstabEntry* fstab_entry) {
if (fs_mgr_is_logical(fstab_rec)) { if (fstab_entry->fs_mgr_flags.logical) {
if (!fs_mgr_update_logical_partition(fstab_rec)) { if (!fs_mgr_update_logical_partition(fstab_entry)) {
return false; return false;
} }
if (!InitMappedDevice(fstab_rec->blk_device)) { if (!InitMappedDevice(fstab_entry->blk_device)) {
return false; return false;
} }
} }
if (!SetUpDmVerity(fstab_rec)) { if (!SetUpDmVerity(fstab_entry)) {
PLOG(ERROR) << "Failed to setup verity for '" << fstab_rec->mount_point << "'"; PLOG(ERROR) << "Failed to setup verity for '" << fstab_entry->mount_point << "'";
return false; return false;
} }
if (fs_mgr_do_mount_one(fstab_rec)) { if (fs_mgr_do_mount_one(*fstab_entry)) {
PLOG(ERROR) << "Failed to mount '" << fstab_rec->mount_point << "'"; PLOG(ERROR) << "Failed to mount '" << fstab_entry->mount_point << "'";
return false; return false;
} }
return true; 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 // 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, // this case, we mount system first then pivot to it. From that point on,
// we are effectively identical to a system-as-root device. // we are effectively identical to a system-as-root device.
auto system_partition = auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
std::find_if(mount_fstab_recs_.begin(), mount_fstab_recs_.end(), return entry.mount_point == "/system";
[](const auto& rec) { return rec->mount_point == "/system"s; }); });
if (system_partition != mount_fstab_recs_.end()) { if (system_partition != fstab_.end()) {
if (!MountPartition(*system_partition)) { if (!MountPartition(&(*system_partition))) {
return false; 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_) { for (auto& fstab_entry : fstab_) {
if (!MountPartition(fstab_rec) && !fs_mgr_is_nofail(fstab_rec)) { if (!MountPartition(&fstab_entry) && !fstab_entry.fs_mgr_flags.no_fail) {
return false; return false;
} }
} }
// heads up for instantiating required device(s) for overlayfs logic // 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) { for (auto const& device : devices) {
if (android::base::StartsWith(device, "/dev/block/by-name/")) { if (android::base::StartsWith(device, "/dev/block/by-name/")) {
required_devices_partition_names_.emplace(basename(device.c_str())); 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; return true;
} }
@ -447,25 +433,25 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
std::string verity_loc_device; std::string verity_loc_device;
need_dm_verity_ = false; 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. // 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"; LOG(ERROR) << "Partitions can't be verified at boot";
return false; return false;
} }
// Checks for verified partitions. // Checks for verified partitions.
if (fs_mgr_is_verified(fstab_rec)) { if (fstab_entry.fs_mgr_flags.verify) {
need_dm_verity_ = true; need_dm_verity_ = true;
} }
// Checks if verity metadata is on a separate partition. Note that it is // Checks if verity metadata is on a separate partition. Note that it is
// not partition specific, so there must be only one additional partition // not partition specific, so there must be only one additional partition
// that carries verity state. // that carries verity state.
if (fstab_rec->verity_loc) { if (!fstab_entry.verity_loc.empty()) {
if (verity_loc_device.empty()) { if (verity_loc_device.empty()) {
verity_loc_device = fstab_rec->verity_loc; verity_loc_device = fstab_entry.verity_loc;
} else if (verity_loc_device != fstab_rec->verity_loc) { } else if (verity_loc_device != fstab_entry.verity_loc) {
LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", " LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", "
<< fstab_rec->verity_loc; << fstab_entry.verity_loc;
return false; return false;
} }
} }
@ -473,9 +459,9 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
// Includes the partition names of fstab records and verity_loc_device (if any). // 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. // 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_) { for (const auto& fstab_entry : fstab_) {
if (!fs_mgr_is_logical(fstab_rec)) { if (!fstab_entry.fs_mgr_flags.logical) {
required_devices_partition_names_.emplace(basename(fstab_rec->blk_device)); required_devices_partition_names_.emplace(basename(fstab_entry.blk_device.c_str()));
} }
} }
@ -486,19 +472,19 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() {
return true; return true;
} }
bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) {
if (fs_mgr_is_verified(fstab_rec)) { if (fstab_entry->fs_mgr_flags.verify) {
int ret = fs_mgr_setup_verity(fstab_rec, false /* wait_for_verity_dev */); int ret = fs_mgr_setup_verity(fstab_entry, false /* wait_for_verity_dev */);
switch (ret) { switch (ret) {
case FS_MGR_SETUP_VERITY_SKIPPED: case FS_MGR_SETUP_VERITY_SKIPPED:
case FS_MGR_SETUP_VERITY_DISABLED: 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; return true;
case FS_MGR_SETUP_VERITY_SUCCESS: case FS_MGR_SETUP_VERITY_SUCCESS:
// The exact block device name (fstab_rec->blk_device) is changed to // 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 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage. // first stage.
return InitMappedDevice(fstab_rec->blk_device); return InitMappedDevice(fstab_entry->blk_device);
default: default:
return false; return false;
} }
@ -531,15 +517,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
std::set<std::string> logical_partitions; std::set<std::string> logical_partitions;
// fstab_rec->blk_device has A/B suffix. // fstab_rec->blk_device has A/B suffix.
for (auto fstab_rec : mount_fstab_recs_) { for (const auto& fstab_entry : fstab_) {
if (fs_mgr_is_avb(fstab_rec)) { if (fstab_entry.fs_mgr_flags.avb) {
need_dm_verity_ = true; 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. // 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 { } 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; return true;
} }
bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) { bool FirstStageMountVBootV2::SetUpDmVerity(FstabEntry* fstab_entry) {
if (fs_mgr_is_avb(fstab_rec)) { if (fstab_entry->fs_mgr_flags.avb) {
if (!InitAvbHandle()) return false; if (!InitAvbHandle()) return false;
AvbHashtreeResult hashtree_result = 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) { switch (hashtree_result) {
case AvbHashtreeResult::kDisabled: case AvbHashtreeResult::kDisabled:
return true; // Returns true to mount the partition. 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 // 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 // "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage. // first stage.
return InitMappedDevice(fstab_rec->blk_device); return InitMappedDevice(fstab_entry->blk_device);
default: default:
return false; return false;
} }

View file

@ -21,7 +21,7 @@
__BEGIN_DECLS __BEGIN_DECLS
int partition_wiped(char *source); int partition_wiped(const char* source);
__END_DECLS __END_DECLS

View file

@ -39,8 +39,7 @@ static int only_one_char(uint8_t *buf, int len, uint8_t c)
return ret; return ret;
} }
int partition_wiped(char *source) int partition_wiped(const char* source) {
{
uint8_t buf[4096]; uint8_t buf[4096];
int fd, ret; int fd, ret;
@ -67,4 +66,3 @@ int partition_wiped(char *source)
return 0; return 0;
} }