/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "Checkpoint"
#include "Checkpoint.h"
#include "VoldUtil.h"
#include "VolumeManager.h"

#include <fstream>
#include <list>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <cutils/android_reboot.h>
#include <fcntl.h>
#include <fs_mgr.h>
#include <linux/fs.h>
#include <mntent.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <unistd.h>

using android::base::GetBoolProperty;
using android::base::GetUintProperty;
using android::base::SetProperty;
using android::binder::Status;
using android::fs_mgr::Fstab;
using android::fs_mgr::ReadDefaultFstab;
using android::fs_mgr::ReadFstabFromFile;
using android::hardware::hidl_string;
using android::hardware::boot::V1_0::BoolResult;
using android::hardware::boot::V1_0::CommandResult;
using android::hardware::boot::V1_0::IBootControl;
using android::hardware::boot::V1_0::Slot;

namespace android {
namespace vold {

namespace {
const std::string kMetadataCPFile = "/metadata/vold/checkpoint";

binder::Status error(const std::string& msg) {
    PLOG(ERROR) << msg;
    return binder::Status::fromServiceSpecificError(errno, String8(msg.c_str()));
}

binder::Status error(int error, const std::string& msg) {
    LOG(ERROR) << msg;
    return binder::Status::fromServiceSpecificError(error, String8(msg.c_str()));
}

bool setBowState(std::string const& block_device, std::string const& state) {
    if (block_device.substr(0, 5) != "/dev/") {
        LOG(ERROR) << "Expected block device, got " << block_device;
        return false;
    }

    std::string state_filename = std::string("/sys/") + block_device.substr(5) + "/bow/state";
    if (!android::base::WriteStringToFile(state, state_filename)) {
        PLOG(ERROR) << "Failed to write to file " << state_filename;
        return false;
    }

    return true;
}

}  // namespace

Status cp_supportsCheckpoint(bool& result) {
    result = false;

    for (const auto& entry : fstab_default) {
        if (entry.fs_mgr_flags.checkpoint_blk || entry.fs_mgr_flags.checkpoint_fs) {
            result = true;
            return Status::ok();
        }
    }
    return Status::ok();
}

Status cp_supportsBlockCheckpoint(bool& result) {
    result = false;

    for (const auto& entry : fstab_default) {
        if (entry.fs_mgr_flags.checkpoint_blk) {
            result = true;
            return Status::ok();
        }
    }
    return Status::ok();
}

Status cp_supportsFileCheckpoint(bool& result) {
    result = false;

    for (const auto& entry : fstab_default) {
        if (entry.fs_mgr_flags.checkpoint_fs) {
            result = true;
            return Status::ok();
        }
    }
    return Status::ok();
}

Status cp_startCheckpoint(int retry) {
    bool result;
    if (!cp_supportsCheckpoint(result).isOk() || !result)
        return error(ENOTSUP, "Checkpoints not supported");

    if (retry < -1) return error(EINVAL, "Retry count must be more than -1");
    std::string content = std::to_string(retry + 1);
    if (retry == -1) {
        sp<IBootControl> module = IBootControl::getService();
        if (module) {
            std::string suffix;
            auto cb = [&suffix](hidl_string s) { suffix = s; };
            if (module->getSuffix(module->getCurrentSlot(), cb).isOk()) content += " " + suffix;
        }
    }
    if (!android::base::WriteStringToFile(content, kMetadataCPFile))
        return error("Failed to write checkpoint file");
    return Status::ok();
}

namespace {

volatile bool isCheckpointing = false;
}

Status cp_commitChanges() {
    if (!isCheckpointing) {
        return Status::ok();
    }
    if (android::base::GetProperty("persist.vold.dont_commit_checkpoint", "0") == "1") {
        LOG(WARNING)
            << "NOT COMMITTING CHECKPOINT BECAUSE persist.vold.dont_commit_checkpoint IS 1";
        return Status::ok();
    }
    sp<IBootControl> module = IBootControl::getService();
    if (module) {
        CommandResult cr;
        module->markBootSuccessful([&cr](CommandResult result) { cr = result; });
        if (!cr.success)
            return error(EINVAL, "Error marking booted successfully: " + std::string(cr.errMsg));
        LOG(INFO) << "Marked slot as booted successfully.";
    }
    // Must take action for list of mounted checkpointed things here
    // To do this, we walk the list of mounted file systems.
    // But we also need to get the matching fstab entries to see
    // the original flags
    std::string err_str;

    Fstab mounts;
    if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
        return error(EINVAL, "Failed to get /proc/mounts");
    }

    // Walk mounted file systems
    for (const auto& mount_rec : mounts) {
        const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
        if (!fstab_rec) continue;

        if (fstab_rec->fs_mgr_flags.checkpoint_fs) {
            if (fstab_rec->fs_type == "f2fs") {
                std::string options = mount_rec.fs_options + ",checkpoint=enable";
                if (mount(mount_rec.blk_device.c_str(), mount_rec.mount_point.c_str(), "none",
                          MS_REMOUNT | fstab_rec->flags, options.c_str())) {
                    return error(EINVAL, "Failed to remount");
                }
            }
        } else if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
            if (!setBowState(mount_rec.blk_device, "2"))
                return error(EINVAL, "Failed to set bow state");
        }
    }
    SetProperty("vold.checkpoint_committed", "1");
    LOG(INFO) << "Checkpoint has been committed.";
    isCheckpointing = false;
    if (!android::base::RemoveFileIfExists(kMetadataCPFile, &err_str))
        return error(err_str.c_str());

    return Status::ok();
}

namespace {
void abort_metadata_file() {
    std::string oldContent, newContent;
    int retry = 0;
    struct stat st;
    int result = stat(kMetadataCPFile.c_str(), &st);

    // If the file doesn't exist, we aren't managing a checkpoint retry counter
    if (result != 0) return;
    if (!android::base::ReadFileToString(kMetadataCPFile, &oldContent)) {
        PLOG(ERROR) << "Failed to read checkpoint file";
        return;
    }
    std::string retryContent = oldContent.substr(0, oldContent.find_first_of(" "));

    if (!android::base::ParseInt(retryContent, &retry)) {
        PLOG(ERROR) << "Could not parse retry count";
        return;
    }
    if (retry > 0) {
        newContent = "0";
        if (!android::base::WriteStringToFile(newContent, kMetadataCPFile))
            PLOG(ERROR) << "Could not write checkpoint file";
    }
}
}  // namespace

void cp_abortChanges(const std::string& message, bool retry) {
    if (!cp_needsCheckpoint()) return;
    if (!retry) abort_metadata_file();
    android_reboot(ANDROID_RB_RESTART2, 0, message.c_str());
}

bool cp_needsRollback() {
    std::string content;
    bool ret;

    ret = android::base::ReadFileToString(kMetadataCPFile, &content);
    if (ret) {
        if (content == "0") return true;
        if (content.substr(0, 3) == "-1 ") {
            std::string oldSuffix = content.substr(3);
            sp<IBootControl> module = IBootControl::getService();
            std::string newSuffix;

            if (module) {
                auto cb = [&newSuffix](hidl_string s) { newSuffix = s; };
                module->getSuffix(module->getCurrentSlot(), cb);
                if (oldSuffix == newSuffix) return true;
            }
        }
    }
    return false;
}

bool cp_needsCheckpoint() {
    bool ret;
    std::string content;
    sp<IBootControl> module = IBootControl::getService();

    if (isCheckpointing) return isCheckpointing;

    if (module && module->isSlotMarkedSuccessful(module->getCurrentSlot()) == BoolResult::FALSE) {
        isCheckpointing = true;
        return true;
    }
    ret = android::base::ReadFileToString(kMetadataCPFile, &content);
    if (ret) {
        ret = content != "0";
        isCheckpointing = ret;
        return ret;
    }
    return false;
}

namespace {
const std::string kSleepTimeProp = "ro.sys.cp_msleeptime";
const uint32_t msleeptime_default = 1000;  // 1 s
const uint32_t max_msleeptime = 3600000;   // 1 h

const std::string kMinFreeBytesProp = "ro.sys.cp_min_free_bytes";
const uint64_t min_free_bytes_default = 100 * (1 << 20);  // 100 MiB

const std::string kCommitOnFullProp = "ro.sys.cp_commit_on_full";
const bool commit_on_full_default = true;

static void cp_healthDaemon(std::string mnt_pnt, std::string blk_device, bool is_fs_cp) {
    struct statvfs data;
    uint64_t free_bytes = 0;
    uint32_t msleeptime = GetUintProperty(kSleepTimeProp, msleeptime_default, max_msleeptime);
    uint64_t min_free_bytes =
        GetUintProperty(kMinFreeBytesProp, min_free_bytes_default, (uint64_t)-1);
    bool commit_on_full = GetBoolProperty(kCommitOnFullProp, commit_on_full_default);

    struct timespec req;
    req.tv_sec = msleeptime / 1000;
    msleeptime %= 1000;
    req.tv_nsec = msleeptime * 1000000;
    while (isCheckpointing) {
        if (is_fs_cp) {
            statvfs(mnt_pnt.c_str(), &data);
            free_bytes = data.f_bavail * data.f_frsize;
        } else {
            int ret;
            std::string size_filename = std::string("/sys/") + blk_device.substr(5) + "/bow/free";
            std::string content;
            ret = android::base::ReadFileToString(size_filename, &content);
            if (ret) {
                free_bytes = std::strtoul(content.c_str(), NULL, 10);
            }
        }
        if (free_bytes < min_free_bytes) {
            if (commit_on_full) {
                LOG(INFO) << "Low space for checkpointing. Commiting changes";
                cp_commitChanges();
                break;
            } else {
                LOG(INFO) << "Low space for checkpointing. Rebooting";
                cp_abortChanges("checkpoint,low_space", false);
                break;
            }
        }
        nanosleep(&req, NULL);
    }
}

}  // namespace

Status cp_prepareCheckpoint() {
    if (!isCheckpointing) {
        return Status::ok();
    }

    Fstab mounts;
    if (!ReadFstabFromFile("/proc/mounts", &mounts)) {
        return error(EINVAL, "Failed to get /proc/mounts");
    }

    for (const auto& mount_rec : mounts) {
        const auto fstab_rec = GetEntryForMountPoint(&fstab_default, mount_rec.mount_point);
        if (!fstab_rec) continue;

        if (fstab_rec->fs_mgr_flags.checkpoint_blk) {
            android::base::unique_fd fd(
                TEMP_FAILURE_RETRY(open(mount_rec.mount_point.c_str(), O_RDONLY | O_CLOEXEC)));
            if (fd == -1) {
                PLOG(ERROR) << "Failed to open mount point" << mount_rec.mount_point;
                continue;
            }

            struct fstrim_range range = {};
            range.len = ULLONG_MAX;
            nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
            if (ioctl(fd, FITRIM, &range)) {
                PLOG(ERROR) << "Failed to trim " << mount_rec.mount_point;
                continue;
            }
            nsecs_t time = systemTime(SYSTEM_TIME_BOOTTIME) - start;
            LOG(INFO) << "Trimmed " << range.len << " bytes on " << mount_rec.mount_point << " in "
                      << nanoseconds_to_milliseconds(time) << "ms for checkpoint";

            setBowState(mount_rec.blk_device, "1");
        }
        if (fstab_rec->fs_mgr_flags.checkpoint_blk || fstab_rec->fs_mgr_flags.checkpoint_fs) {
            std::thread(cp_healthDaemon, std::string(mount_rec.mount_point),
                        std::string(mount_rec.blk_device),
                        fstab_rec->fs_mgr_flags.checkpoint_fs == 1)
                .detach();
        }
    }
    return Status::ok();
}

namespace {
const int kSectorSize = 512;

typedef uint64_t sector_t;

struct log_entry {
    sector_t source;  // in sectors of size kSectorSize
    sector_t dest;    // in sectors of size kSectorSize
    uint32_t size;    // in bytes
    uint32_t checksum;
} __attribute__((packed));

struct log_sector_v1_0 {
    uint32_t magic;
    uint16_t header_version;
    uint16_t header_size;
    uint32_t block_size;
    uint32_t count;
    uint32_t sequence;
    uint64_t sector0;
} __attribute__((packed));

// MAGIC is BOW in ascii
const int kMagic = 0x00574f42;
// Partially restored MAGIC is WOB in ascii
const int kPartialRestoreMagic = 0x00424f57;

void crc32(const void* data, size_t n_bytes, uint32_t* crc) {
    static uint32_t table[0x100] = {
        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
        0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
        0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
        0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
        0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
        0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
        0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
        0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
        0xB6662D3D,

        0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5,
        0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
        0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
        0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
        0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC,
        0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C,
        0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B,
        0xC0BA6CAD,

        0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
        0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
        0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D,
        0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4,
        0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
        0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C,
        0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
        0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B,
        0x5BDEAE1D,

        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785,
        0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
        0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD,
        0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
        0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354,
        0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C,
        0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
        0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
        0x2D02EF8D};

    for (size_t i = 0; i < n_bytes; ++i) {
        *crc ^= ((uint8_t*)data)[i];
        *crc = table[(uint8_t)*crc] ^ *crc >> 8;
    }
}

// A map of relocations.
// The map must be initialized so that relocations[0] = 0
// During restore, we replay the log records in reverse, copying from dest to
// source
// To validate, we must be able to read the 'dest' sectors as though they had
// been copied but without actually copying. This map represents how the sectors
// would have been moved. To read a sector s, find the index <= s and read
// relocations[index] + s - index
typedef std::map<sector_t, sector_t> Relocations;

void relocate(Relocations& relocations, sector_t dest, sector_t source, int count) {
    // Find first one we're equal to or greater than
    auto s = --relocations.upper_bound(source);

    // Take slice
    Relocations slice;
    slice[dest] = source - s->first + s->second;
    ++s;

    // Add rest of elements
    for (; s != relocations.end() && s->first < source + count; ++s)
        slice[dest - source + s->first] = s->second;

    // Split range at end of dest
    auto dest_end = --relocations.upper_bound(dest + count);
    relocations[dest + count] = dest + count - dest_end->first + dest_end->second;

    // Remove all elements in [dest, dest + count)
    relocations.erase(relocations.lower_bound(dest), relocations.lower_bound(dest + count));

    // Add new elements
    relocations.insert(slice.begin(), slice.end());
}

// A map of sectors that have been written to.
// The final entry must always be False.
// When we restart the restore after an interruption, we must take care that
// when we copy from dest to source, that the block we copy to was not
// previously copied from.
// i e. A->B C->A; If we replay this sequence, we end up copying C->B
// We must save our partial result whenever we finish a page, or when we copy
// to a location that was copied from earlier (our source is an earlier dest)
typedef std::map<sector_t, bool> Used_Sectors;

bool checkCollision(Used_Sectors& used_sectors, sector_t start, sector_t end) {
    auto second_overlap = used_sectors.upper_bound(start);
    auto first_overlap = --second_overlap;

    if (first_overlap->second) {
        return true;
    } else if (second_overlap != used_sectors.end() && second_overlap->first < end) {
        return true;
    }
    return false;
}

void markUsed(Used_Sectors& used_sectors, sector_t start, sector_t end) {
    auto start_pos = used_sectors.insert_or_assign(start, true).first;
    auto end_pos = used_sectors.insert_or_assign(end, false).first;

    if (start_pos == used_sectors.begin() || !std::prev(start_pos)->second) {
        start_pos++;
    }
    if (std::next(end_pos) != used_sectors.end() && !std::next(end_pos)->second) {
        end_pos++;
    }
    if (start_pos->first < end_pos->first) {
        used_sectors.erase(start_pos, end_pos);
    }
}

// Restores the given log_entry's data from dest -> source
// If that entry is a log sector, set the magic to kPartialRestoreMagic and flush.
void restoreSector(int device_fd, Used_Sectors& used_sectors, std::vector<char>& ls_buffer,
                   log_entry* le, std::vector<char>& buffer) {
    log_sector_v1_0& ls = *reinterpret_cast<log_sector_v1_0*>(&ls_buffer[0]);
    uint32_t index = le - ((log_entry*)&ls_buffer[ls.header_size]);
    int count = (le->size - 1) / kSectorSize + 1;

    if (checkCollision(used_sectors, le->source, le->source + count)) {
        fsync(device_fd);
        lseek64(device_fd, 0, SEEK_SET);
        ls.count = index + 1;
        ls.magic = kPartialRestoreMagic;
        write(device_fd, &ls_buffer[0], ls.block_size);
        fsync(device_fd);
        used_sectors.clear();
        used_sectors[0] = false;
    }

    markUsed(used_sectors, le->dest, le->dest + count);

    if (index == 0 && ls.sequence != 0) {
        log_sector_v1_0* next = reinterpret_cast<log_sector_v1_0*>(&buffer[0]);
        if (next->magic == kMagic) {
            next->magic = kPartialRestoreMagic;
        }
    }

    lseek64(device_fd, le->source * kSectorSize, SEEK_SET);
    write(device_fd, &buffer[0], le->size);

    if (index == 0) {
        fsync(device_fd);
    }
}

// Read from the device
// If we are validating, the read occurs as though the relocations had happened
std::vector<char> relocatedRead(int device_fd, Relocations const& relocations, bool validating,
                                sector_t sector, uint32_t size, uint32_t block_size) {
    if (!validating) {
        std::vector<char> buffer(size);
        lseek64(device_fd, sector * kSectorSize, SEEK_SET);
        read(device_fd, &buffer[0], size);
        return buffer;
    }

    std::vector<char> buffer(size);
    for (uint32_t i = 0; i < size; i += block_size, sector += block_size / kSectorSize) {
        auto relocation = --relocations.upper_bound(sector);
        lseek64(device_fd, (sector + relocation->second - relocation->first) * kSectorSize,
                SEEK_SET);
        read(device_fd, &buffer[i], block_size);
    }

    return buffer;
}

}  // namespace

Status cp_restoreCheckpoint(const std::string& blockDevice, int restore_limit) {
    bool validating = true;
    std::string action = "Validating";
    int restore_count = 0;

    for (;;) {
        Relocations relocations;
        relocations[0] = 0;
        Status status = Status::ok();

        LOG(INFO) << action << " checkpoint on " << blockDevice;
        base::unique_fd device_fd(open(blockDevice.c_str(), O_RDWR | O_CLOEXEC));
        if (device_fd < 0) return error("Cannot open " + blockDevice);

        log_sector_v1_0 original_ls;
        read(device_fd, reinterpret_cast<char*>(&original_ls), sizeof(original_ls));
        if (original_ls.magic == kPartialRestoreMagic) {
            validating = false;
            action = "Restoring";
        } else if (original_ls.magic != kMagic) {
            return error(EINVAL, "No magic");
        }

        LOG(INFO) << action << " " << original_ls.sequence << " log sectors";

        for (int sequence = original_ls.sequence; sequence >= 0 && status.isOk(); sequence--) {
            auto ls_buffer = relocatedRead(device_fd, relocations, validating, 0,
                                           original_ls.block_size, original_ls.block_size);
            log_sector_v1_0& ls = *reinterpret_cast<log_sector_v1_0*>(&ls_buffer[0]);

            Used_Sectors used_sectors;
            used_sectors[0] = false;

            if (ls.magic != kMagic && (ls.magic != kPartialRestoreMagic || validating)) {
                status = error(EINVAL, "No magic");
                break;
            }

            if (ls.block_size != original_ls.block_size) {
                status = error(EINVAL, "Block size mismatch");
                break;
            }

            if ((int)ls.sequence != sequence) {
                status = error(EINVAL, "Expecting log sector " + std::to_string(sequence) +
                                           " but got " + std::to_string(ls.sequence));
                break;
            }

            LOG(INFO) << action << " from log sector " << ls.sequence;
            for (log_entry* le =
                     reinterpret_cast<log_entry*>(&ls_buffer[ls.header_size]) + ls.count - 1;
                 le >= reinterpret_cast<log_entry*>(&ls_buffer[ls.header_size]); --le) {
                // This is very noisy - limit to DEBUG only
                LOG(VERBOSE) << action << " " << le->size << " bytes from sector " << le->dest
                             << " to " << le->source << " with checksum " << std::hex
                             << le->checksum;

                auto buffer = relocatedRead(device_fd, relocations, validating, le->dest, le->size,
                                            ls.block_size);
                uint32_t checksum = le->source / (ls.block_size / kSectorSize);
                for (size_t i = 0; i < le->size; i += ls.block_size) {
                    crc32(&buffer[i], ls.block_size, &checksum);
                }

                if (le->checksum && checksum != le->checksum) {
                    status = error(EINVAL, "Checksums don't match");
                    break;
                }

                if (validating) {
                    relocate(relocations, le->source, le->dest, (le->size - 1) / kSectorSize + 1);
                } else {
                    restoreSector(device_fd, used_sectors, ls_buffer, le, buffer);
                    restore_count++;
                    if (restore_limit && restore_count >= restore_limit) {
                        status = error(EAGAIN, "Hit the test limit");
                        break;
                    }
                }
            }
        }

        if (!status.isOk()) {
            if (!validating) {
                LOG(ERROR) << "Checkpoint restore failed even though checkpoint validation passed";
                return status;
            }

            LOG(WARNING) << "Checkpoint validation failed - attempting to roll forward";
            auto buffer = relocatedRead(device_fd, relocations, false, original_ls.sector0,
                                        original_ls.block_size, original_ls.block_size);
            lseek64(device_fd, 0, SEEK_SET);
            write(device_fd, &buffer[0], original_ls.block_size);
            return Status::ok();
        }

        if (!validating) break;

        validating = false;
        action = "Restoring";
    }

    return Status::ok();
}

Status cp_markBootAttempt() {
    std::string oldContent, newContent;
    int retry = 0;
    struct stat st;
    int result = stat(kMetadataCPFile.c_str(), &st);

    // If the file doesn't exist, we aren't managing a checkpoint retry counter
    if (result != 0) return Status::ok();
    if (!android::base::ReadFileToString(kMetadataCPFile, &oldContent))
        return error("Failed to read checkpoint file");
    std::string retryContent = oldContent.substr(0, oldContent.find_first_of(" "));

    if (!android::base::ParseInt(retryContent, &retry))
        return error(EINVAL, "Could not parse retry count");
    if (retry > 0) {
        retry--;

        newContent = std::to_string(retry);
        if (!android::base::WriteStringToFile(newContent, kMetadataCPFile))
            return error("Could not write checkpoint file");
    }
    return Status::ok();
}

}  // namespace vold
}  // namespace android
