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

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

Merge "Handle retry count correctly"

parents 9810709d b920cb44
Loading
Loading
Loading
Loading
+108 −60
Original line number Diff line number Diff line
@@ -851,7 +851,61 @@ bool fs_mgr_update_logical_partition(struct fstab_rec* rec) {
    return true;
}

bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
class CheckpointManager {
  public:
    CheckpointManager(int needs_checkpoint = -1) : needs_checkpoint_(needs_checkpoint) {}

    bool Update(struct fstab_rec* rec) {
        if (!fs_mgr_is_checkpoint(rec)) {
            return true;
        }

        if (fs_mgr_is_checkpoint_blk(rec)) {
            call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device});
        }

        if (needs_checkpoint_ == UNKNOWN &&
            !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &needs_checkpoint_)) {
            LERROR << "Failed to find if checkpointing is needed. Assuming no.";
            needs_checkpoint_ = NO;
        }

        if (needs_checkpoint_ != YES) {
            return true;
        }

        if (!UpdateCheckpointPartition(rec)) {
            LERROR << "Could not set up checkpoint partition, skipping!";
            return false;
        }

        return true;
    }

    bool Revert(struct fstab_rec* rec) {
        if (!fs_mgr_is_checkpoint(rec)) {
            return true;
        }

        if (device_map_.find(rec->blk_device) == device_map_.end()) {
            return true;
        }

        std::string bow_device = rec->blk_device;
        free(rec->blk_device);
        rec->blk_device = strdup(device_map_[bow_device].c_str());
        device_map_.erase(bow_device);

        DeviceMapper& dm = DeviceMapper::Instance();
        if (!dm.DeleteDevice("bow")) {
            PERROR << "Failed to remove bow device";
        }

        return true;
    }

  private:
    bool UpdateCheckpointPartition(struct fstab_rec* rec) {
        if (fs_mgr_is_checkpoint_fs(rec)) {
            if (!strcmp(rec->fs_type, "f2fs")) {
                std::string opts(rec->fs_options);
@@ -863,8 +917,6 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
                LERROR << rec->fs_type << " does not implement checkpoints.";
            }
        } else if (fs_mgr_is_checkpoint_blk(rec)) {
        call_vdc({"checkpoint", "restoreCheckpoint", rec->blk_device});

            android::base::unique_fd fd(
                    TEMP_FAILURE_RETRY(open(rec->blk_device, O_RDONLY | O_CLOEXEC)));
            if (!fd) {
@@ -881,7 +933,7 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
            android::dm::DmTable table;
            if (!table.AddTarget(
                        std::make_unique<android::dm::DmTargetBow>(0, size, rec->blk_device))) {
            LERROR << "Failed to add Bow target";
                LERROR << "Failed to add bow target";
                return false;
            }

@@ -897,11 +949,18 @@ bool fs_mgr_update_checkpoint_partition(struct fstab_rec* rec) {
                return false;
            }

            device_map_[name] = rec->blk_device;
            free(rec->blk_device);
            rec->blk_device = strdup(name.c_str());
        }
        return true;
    }

    enum { UNKNOWN = -1, NO = 0, YES = 1 };
    int needs_checkpoint_;
    std::map<std::string, std::string> device_map_;
};

/* 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.
@@ -914,7 +973,7 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;
    int need_checkpoint = -1;
    CheckpointManager checkpoint_manager;
    FsManagerAvbUniquePtr avb_handle(nullptr);

    if (!fstab) {
@@ -961,17 +1020,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
            }
        }

        if (fs_mgr_is_checkpoint(&fstab->recs[i])) {
            if (need_checkpoint == -1 &&
                !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) {
                LERROR << "Failed to find if checkpointing is needed. Assuming no.";
                need_checkpoint = 0;
            }
            if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) {
                LERROR << "Could not set up checkpoint partition, skipping!";
        if (!checkpoint_manager.Update(&fstab->recs[i])) {
            continue;
        }
        }

        if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
            !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
@@ -1053,6 +1104,9 @@ int fs_mgr_mount_all(fstab* fstab, int mount_mode) {
                   << " is wiped and " << fstab->recs[top_idx].mount_point
                   << " " << fstab->recs[top_idx].fs_type
                   << " is formattable. Format it.";

            checkpoint_manager.Revert(&fstab->recs[top_idx]);

            if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
                strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
                int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY);
@@ -1173,11 +1227,12 @@ int fs_mgr_do_mount_one(struct fstab_rec *rec)
 * in turn, and stop on 1st success, or no more match.
 */
static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_device,
                                  char* tmp_mount_point, int need_checkpoint) {
                                  char* tmp_mount_point, int needs_checkpoint) {
    int i = 0;
    int mount_errors = 0;
    int first_mount_errno = 0;
    char* mount_point;
    CheckpointManager checkpoint_manager(needs_checkpoint);
    FsManagerAvbUniquePtr avb_handle(nullptr);

    if (!fstab) {
@@ -1206,17 +1261,10 @@ static int fs_mgr_do_mount_helper(fstab* fstab, const char* n_name, char* n_blk_
            }
        }

        if (fs_mgr_is_checkpoint(&fstab->recs[i])) {
            if (need_checkpoint == -1 &&
                !call_vdc_ret({"checkpoint", "needsCheckpoint"}, &need_checkpoint)) {
                LERROR << "Failed to find if checkpointing is needed. Assuming no.";
                need_checkpoint = 0;
            }
            if (need_checkpoint == 1 && !fs_mgr_update_checkpoint_partition(&fstab->recs[i])) {
        if (!checkpoint_manager.Update(&fstab->recs[i])) {
            LERROR << "Could not set up checkpoint partition, skipping!";
            continue;
        }
        }

        /* First check the filesystem if requested */
        if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
@@ -1292,8 +1340,8 @@ int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char*
}

int fs_mgr_do_mount(fstab* fstab, const char* n_name, char* n_blk_device, char* tmp_mount_point,
                    bool needs_cp) {
    return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_cp);
                    bool needs_checkpoint) {
    return fs_mgr_do_mount_helper(fstab, n_name, n_blk_device, tmp_mount_point, needs_checkpoint);
}

/*
+4 −2
Original line number Diff line number Diff line
@@ -398,6 +398,10 @@ on late-fs
    class_start early_hal

on post-fs-data
    # Start checkpoint before we touch data
    start vold
    exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint

    # We chown/chmod /data again so because mount is run as root + defaults
    chown system system /data
    chmod 0771 /data
@@ -405,8 +409,6 @@ on post-fs-data
    restorecon /data

    # Make sure we have the device encryption key.
    start vold
    exec - system system -- /system/bin/vdc checkpoint prepareDriveForCheckpoint /data
    installkey /data

    # Start bootcharting as soon as possible after the data partition is