Merge "Do SetUpDmVerity only once for the same mount point"

This commit is contained in:
Treehugger Robot 2019-01-24 11:06:03 +00:00 committed by Gerrit Code Review
commit 24a2c1a70c

View file

@ -73,7 +73,9 @@ 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(FstabEntry* fstab_entry); bool MountPartition(const Fstab::iterator& begin, bool erase_used_fstab_entry,
Fstab::iterator* end = nullptr);
bool MountPartitions(); bool MountPartitions();
bool TrySwitchSystemAsRoot(); bool TrySwitchSystemAsRoot();
bool TrySkipMountingPartitions(); bool TrySkipMountingPartitions();
@ -385,29 +387,40 @@ bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
return true; return true;
} }
bool FirstStageMount::MountPartition(FstabEntry* fstab_entry) { bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_used_fstab_entry,
if (fstab_entry->fs_mgr_flags.logical) { Fstab::iterator* end) {
if (!fs_mgr_update_logical_partition(fstab_entry)) { if (begin->fs_mgr_flags.logical) {
if (!fs_mgr_update_logical_partition(&(*begin))) {
return false; return false;
} }
if (!InitMappedDevice(fstab_entry->blk_device)) { if (!InitMappedDevice(begin->blk_device)) {
return false; return false;
} }
} }
if (!SetUpDmVerity(fstab_entry)) { if (!SetUpDmVerity(&(*begin))) {
PLOG(ERROR) << "Failed to setup verity for '" << fstab_entry->mount_point << "'"; PLOG(ERROR) << "Failed to setup verity for '" << begin->mount_point << "'";
return false; return false;
} }
if (fs_mgr_do_mount_one(*fstab_entry)) {
if (fstab_entry->fs_mgr_flags.formattable) { bool mounted = (fs_mgr_do_mount_one(*begin) == 0);
PLOG(INFO) << "Failed to mount '" << fstab_entry->mount_point << "', "
<< "ignoring mount for formattable partition"; // Try other mounts with the same mount point.
return true; Fstab::iterator current = begin + 1;
for (; current != fstab_.end() && current->mount_point == begin->mount_point; current++) {
if (!mounted) {
// blk_device is already updated to /dev/dm-<N> by SetUpDmVerity() above.
// Copy it from the begin iterator.
current->blk_device = begin->blk_device;
mounted = (fs_mgr_do_mount_one(*current) == 0);
} }
PLOG(ERROR) << "Failed to mount '" << fstab_entry->mount_point << "'";
return false;
} }
return true; if (erase_used_fstab_entry) {
current = fstab_.erase(begin, current);
}
if (end) {
*end = current;
}
return mounted;
} }
// 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
@ -418,8 +431,7 @@ bool FirstStageMount::TrySwitchSystemAsRoot() {
return entry.mount_point == "/metadata"; return entry.mount_point == "/metadata";
}); });
if (metadata_partition != fstab_.end()) { if (metadata_partition != fstab_.end()) {
if (MountPartition(&(*metadata_partition))) { if (MountPartition(metadata_partition, true /* erase_used_fstab_entry */)) {
fstab_.erase(metadata_partition);
UseGsiIfPresent(); UseGsiIfPresent();
} }
} }
@ -430,30 +442,13 @@ bool FirstStageMount::TrySwitchSystemAsRoot() {
if (system_partition == fstab_.end()) return true; if (system_partition == fstab_.end()) return true;
bool mounted = false; if (MountPartition(system_partition, true /* erase_used_fstab_entry */)) {
bool no_fail = false; SwitchRoot("/system");
for (auto it = system_partition; it != fstab_.end();) { } else {
if (it->mount_point != "/system") { PLOG(ERROR) << "Failed to mount /system";
break;
}
no_fail |= (it->fs_mgr_flags).no_fail;
if (MountPartition(&(*it))) {
mounted = true;
SwitchRoot("/system");
break;
}
it++;
}
if (!mounted && !no_fail) {
LOG(ERROR) << "Failed to mount /system";
return false; return false;
} }
auto it = std::remove_if(fstab_.begin(), fstab_.end(),
[](const auto& entry) { return entry.mount_point == "/system"; });
fstab_.erase(it, fstab_.end());
return true; return true;
} }
@ -490,23 +485,21 @@ bool FirstStageMount::MountPartitions() {
if (!TrySkipMountingPartitions()) return false; if (!TrySkipMountingPartitions()) return false;
for (auto it = fstab_.begin(); it != fstab_.end();) { for (auto current = fstab_.begin(); current != fstab_.end();) {
bool mounted = false; Fstab::iterator end;
bool no_fail = false; if (!MountPartition(current, false, &end)) {
auto start_mount_point = it->mount_point; if (current->fs_mgr_flags.no_fail) {
do { LOG(INFO) << "Failed to mount " << current->mount_point
no_fail |= (it->fs_mgr_flags).no_fail; << ", ignoring mount for no_fail partition";
if (!mounted) } else if (current->fs_mgr_flags.formattable) {
mounted = MountPartition(&(*it)); LOG(INFO) << "Failed to mount " << current->mount_point
else << ", ignoring mount for formattable partition";
LOG(INFO) << "Skip already-mounted partition: " << start_mount_point; } else {
it++; PLOG(ERROR) << "Failed to mount " << current->mount_point;
} while (it != fstab_.end() && it->mount_point == start_mount_point); return false;
}
if (!mounted && !no_fail) {
LOG(ERROR) << start_mount_point << " mounted unsuccessfully but it is required!";
return false;
} }
current = end;
} }
// heads up for instantiating required device(s) for overlayfs logic // heads up for instantiating required device(s) for overlayfs logic