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

Commit 9ccbab0d authored by Akilesh Kailash's avatar Akilesh Kailash
Browse files

libsnapshot_cow: Create snapshot patch for full OTA



create_snapshot --target=$ANDROID_PRODUCT_OUT/product.img --compression="zstd"
Snapshot patch: product.patch created successfully

Snapshot patch: product.patch created successfully
$ ls -lh product.patch
-rw-r--r-- 1 akailash primarygroup 1.8G Sep 17 22:21 product.patch

Default compression set to lz4.

Bug: 299011882
Test: create_snapshot --target=$ANDROID_PRODUCT_OUT/product.img --compression="zstd"
Change-Id: I42845ccf5d55fddd2bdfc7dae92510d247bb71e6
Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
parent c55b2ad4
Loading
Loading
Loading
Loading
+42 −18
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ class CreateSnapshot {
     */
    std::string parsing_file_;
    bool create_snapshot_patch_ = false;
    bool incremental_ = true;

    const int kNumThreads = 6;
    const size_t kBlockSizeToRead = 1_MiB;
@@ -103,6 +104,7 @@ class CreateSnapshot {
    bool ReadBlocks(off_t offset, const int skip_blocks, const uint64_t dev_sz);
    std::string ToHexString(const uint8_t* buf, size_t len);

    bool CreateSnapshotFullOta();
    bool CreateSnapshotFile();
    bool FindSourceBlockHash();
    bool PrepareParse(std::string& parsing_file, const bool createSnapshot);
@@ -144,6 +146,10 @@ CreateSnapshot::CreateSnapshot(const std::string& src_file, const std::string& t
    if (!compression.empty()) {
        compression_ = compression;
    }

    if (src_file_.empty()) {
        incremental_ = false;
    }
}

bool CreateSnapshot::PrepareParse(std::string& parsing_file, const bool createSnapshot) {
@@ -259,10 +265,21 @@ bool CreateSnapshot::CreateSnapshotFile() {
    return ParsePartition();
}

bool CreateSnapshot::CreateSnapshotFullOta() {
    if (!PrepareParse(target_file_, true)) {
        return false;
    }
    return ParsePartition();
}

/*
 * Creates snapshot patch file by comparing source.img and target.img
 */
bool CreateSnapshot::CreateSnapshotPatch() {
    if (!incremental_) {
        return CreateSnapshotFullOta();
    }

    if (!FindSourceBlockHash()) {
        return false;
    }
@@ -289,6 +306,7 @@ std::string CreateSnapshot::ToHexString(const uint8_t* buf, size_t len) {

void CreateSnapshot::PrepareMergeBlock(const void* buffer, uint64_t block,
                                       std::string& block_hash) {
    if (incremental_) {
        if (std::memcmp(zblock_.get(), buffer, BLOCK_SZ) == 0) {
            std::lock_guard<std::mutex> lock(write_lock_);
            zero_blocks_.push_back(block);
@@ -306,6 +324,7 @@ void CreateSnapshot::PrepareMergeBlock(const void* buffer, uint64_t block,
            }
            return;
        }
    }
    std::lock_guard<std::mutex> lock(write_lock_);
    replace_blocks_.push_back(block);
}
@@ -615,10 +634,10 @@ bool CreateSnapshot::ParsePartition() {

constexpr char kUsage[] = R"(
NAME
    create_snapshot - Create snapshot patches by comparing two partition images
    create_snapshot - Create snapshot patches

SYNOPSIS
    create_snapshot --source=<source.img> --target=<target.img> --compression="<compression-algorithm"
    $create_snapshot --source=<source.img> --target=<target.img> --compression="<compression-algorithm"

    source.img -> Source partition image
    target.img -> Target partition image
@@ -639,7 +658,12 @@ int main(int argc, char* argv[]) {
    ::gflags::SetUsageMessage(kUsage);
    ::gflags::ParseCommandLineFlags(&argc, &argv, true);

    if (FLAGS_source.empty() || FLAGS_target.empty()) {
    if (FLAGS_target.empty()) {
        LOG(INFO) << kUsage;
        return 0;
    }

    if (FLAGS_target.empty() && !FLAGS_source.empty()) {
        LOG(INFO) << kUsage;
        return 0;
    }