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(&current_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);