Merge "Reland "Migrate init.environ.rc module to Soong"" into main
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 5156754..003c6fb 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -930,7 +930,8 @@
// 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(Fstab& fstab, int start_idx, int* end_idx, int* attempted_idx) {
+static bool mount_with_alternatives(Fstab& fstab, int start_idx, bool interrupted, int* end_idx,
+ int* attempted_idx) {
unsigned long i;
int mount_errno = 0;
bool mounted = false;
@@ -949,6 +950,13 @@
continue;
}
+ if (interrupted) {
+ LINFO << __FUNCTION__ << "(): skipping fstab mountpoint=" << fstab[i].mount_point
+ << " rec[" << i << "].fs_type=" << fstab[i].fs_type
+ << " (previously interrupted during encryption step)";
+ continue;
+ }
+
// fstab[start_idx].blk_device is already updated to /dev/dm-<N> by
// AVB related functions. Copy it from start_idx to the current index i.
if ((i != start_idx) && fstab[i].fs_mgr_flags.logical &&
@@ -1416,6 +1424,15 @@
return GetEntryForMountPoint(&fstab, mount_point) != nullptr;
}
+std::string fs_mgr_metadata_encryption_in_progress_file_name(const FstabEntry& entry) {
+ return entry.metadata_key_dir + "/in_progress";
+}
+
+bool WasMetadataEncryptionInterrupted(const FstabEntry& entry) {
+ if (!should_use_metadata_encryption(entry)) return false;
+ return access(fs_mgr_metadata_encryption_in_progress_file_name(entry).c_str(), R_OK) == 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.
@@ -1530,7 +1547,9 @@
int top_idx = i;
int attempted_idx = -1;
- bool mret = mount_with_alternatives(*fstab, i, &last_idx_inspected, &attempted_idx);
+ bool encryption_interrupted = WasMetadataEncryptionInterrupted(current_entry);
+ bool mret = mount_with_alternatives(*fstab, i, encryption_interrupted, &last_idx_inspected,
+ &attempted_idx);
auto& attempted_entry = (*fstab)[attempted_idx];
i = last_idx_inspected;
int mount_errno = errno;
@@ -1579,13 +1598,18 @@
// Mounting failed, understand why and retry.
wiped = partition_wiped(current_entry.blk_device.c_str());
if (mount_errno != EBUSY && mount_errno != EACCES &&
- current_entry.fs_mgr_flags.formattable && wiped) {
+ current_entry.fs_mgr_flags.formattable && (wiped || encryption_interrupted)) {
// 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.";
+ if (wiped)
+ LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device)
+ << " is wiped and " << current_entry.mount_point << " "
+ << current_entry.fs_type << " is formattable. Format it.";
+ if (encryption_interrupted)
+ LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device)
+ << " was interrupted during encryption and " << current_entry.mount_point
+ << " " << current_entry.fs_type << " is formattable. Format it.";
checkpoint_manager.Revert(¤t_entry);
@@ -1625,7 +1649,7 @@
}
// mount(2) returned an error, handle the encryptable/formattable case.
- if (mount_errno != EBUSY && mount_errno != EACCES &&
+ if (mount_errno != EBUSY && mount_errno != EACCES && !encryption_interrupted &&
should_use_metadata_encryption(attempted_entry)) {
if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device,
attempted_entry.mount_point,
@@ -1643,13 +1667,13 @@
// Use StringPrintf to output "(null)" instead.
if (attempted_entry.fs_mgr_flags.no_fail) {
PERROR << android::base::StringPrintf(
- "Ignoring failure to mount an un-encryptable or wiped "
+ "Ignoring failure to mount an un-encryptable, interrupted, 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 "
+ "Failed to mount an un-encryptable, interrupted, 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());
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index bc4a7a6..2e1cf76 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -144,3 +144,7 @@
// Unlike fs_mgr_overlayfs, mount overlayfs without upperdir and workdir, so the
// filesystem cannot be remount read-write.
bool fs_mgr_mount_overlayfs_fstab_entry(const android::fs_mgr::FstabEntry& entry);
+
+// File name used to track if encryption was interrupted, leading to a known bad fs state
+std::string fs_mgr_metadata_encryption_in_progress_file_name(
+ const android::fs_mgr::FstabEntry& entry);