Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c49e7dd authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Format if Encryption was Interrupted" into main

parents be8f723e 9ca9303b
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -930,7 +930,8 @@ static bool should_use_metadata_encryption(const FstabEntry& entry) {
// 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 @@ static bool mount_with_alternatives(Fstab& fstab, int start_idx, int* end_idx, i
            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 @@ static bool IsMountPointMounted(const std::string& mount_point) {
    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 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
        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 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
        // 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.
            if (wiped)
                LERROR << __FUNCTION__ << "(): " << realpath(current_entry.blk_device)
                   << " is wiped and " << current_entry.mount_point << " " << current_entry.fs_type
                   << " is formattable. Format it.";
                       << " 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 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
        }

        // 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 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
            // 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());
+4 −0
Original line number Diff line number Diff line
@@ -144,3 +144,7 @@ bool fs_mgr_create_canonical_mount_point(const std::string& mount_point);
// 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);