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

Commit f897650f authored by Daniel Zheng's avatar Daniel Zheng
Browse files

libsnapshot: resume_point_count

We want to add a resume_point_count in the header to represent how many
resume points we've written. In the case that we've written less than
resume_buffer_size, we only want to read the valid resume points.

without these changes incremental OTA runs into segfault or have faulty
data when trying to FindResumeOp() as our resume points contain invalid
entries

Test: full ota followed by inc ota on cuttlefish
Change-Id: I0a8971955439639f2d0f39d9d518c1145ae15c3d
parent a5034537
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -107,8 +107,10 @@ static constexpr uint8_t kNumResumePoints = 4;
struct CowHeaderV3 : public CowHeader {
    // Location of sequence buffer in COW.
    uint64_t sequence_buffer_offset;
    // number of currently written resume points
    uint32_t resume_point_count;
    // Size, in bytes, of the CowResumePoint buffer.
    uint32_t resume_buffer_size;
    uint32_t resume_point_max;
    // Number of CowOperationV3 structs in the operation buffer, currently and total
    // region size.
    uint32_t op_count;
+4 −4
Original line number Diff line number Diff line
@@ -75,10 +75,10 @@ bool CowParserV3::Parse(borrowed_fd fd, const CowHeaderV3& header, std::optional
}

bool CowParserV3::ReadResumeBuffer(borrowed_fd fd) {
    resume_points_ = std::make_shared<std::vector<ResumePoint>>(header_.resume_buffer_size);
    resume_points_ = std::make_shared<std::vector<ResumePoint>>(header_.resume_point_count);

    return android::base::ReadFullyAtOffset(fd, resume_points_->data(),
                                            header_.resume_buffer_size * sizeof(ResumePoint),
                                            header_.resume_point_count * sizeof(ResumePoint),
                                            header_.prefix.header_size + header_.buffer_size);
}

@@ -96,7 +96,7 @@ std::optional<uint32_t> CowParserV3::FindResumeOp(const uint64_t label) {

off_t CowParserV3::GetDataOffset() const {
    return sizeof(CowHeaderV3) + header_.buffer_size +
           header_.resume_buffer_size * sizeof(ResumePoint) +
           header_.resume_point_max * sizeof(ResumePoint) +
           header_.op_count_max * sizeof(CowOperation);
}

@@ -105,7 +105,7 @@ bool CowParserV3::ParseOps(borrowed_fd fd, const uint32_t op_index) {
    ops_->resize(op_index);

    const off_t offset = header_.prefix.header_size + header_.buffer_size +
                         header_.resume_buffer_size * sizeof(ResumePoint);
                         header_.resume_point_max * sizeof(ResumePoint);
    if (!android::base::ReadFullyAtOffset(fd, ops_->data(), ops_->size() * sizeof(CowOperationV3),
                                          offset)) {
        PLOG(ERROR) << "read ops failed";
+5 −3
Original line number Diff line number Diff line
@@ -78,7 +78,8 @@ void CowWriterV3::SetupHeaders() {
    // WIP: not quite sure how some of these are calculated yet, assuming buffer_size is determined
    // during COW size estimation
    header_.sequence_buffer_offset = 0;
    header_.resume_buffer_size = kNumResumePoints;
    header_.resume_point_count = 0;
    header_.resume_point_max = kNumResumePoints;
    header_.op_count = 0;
    header_.op_count_max = 0;
    header_.compression_algorithm = kCowCompressNone;
@@ -296,12 +297,13 @@ bool CowWriterV3::EmitLabel(uint64_t label) {
            resume_points_->end());

    resume_points_->push_back({label, header_.op_count});
    header_.resume_point_count++;
    // remove the oldest resume point if resume_buffer is full
    while (resume_points_->size() > header_.resume_buffer_size) {
    while (resume_points_->size() > header_.resume_point_max) {
        resume_points_->erase(resume_points_->begin());
    }

    CHECK_LE(resume_points_->size(), header_.resume_buffer_size);
    CHECK_LE(resume_points_->size(), header_.resume_point_max);

    if (!android::base::WriteFullyAtOffset(fd_, resume_points_->data(),
                                           resume_points_->size() * sizeof(ResumePoint),
+2 −2
Original line number Diff line number Diff line
@@ -52,12 +52,12 @@ class CowWriterV3 : public CowWriterBase {
    off_t GetOpOffset(uint32_t op_index) const {
        CHECK_LT(op_index, header_.op_count_max);
        return header_.prefix.header_size + header_.buffer_size +
               (header_.resume_buffer_size * sizeof(ResumePoint)) +
               (header_.resume_point_max * sizeof(ResumePoint)) +
               (op_index * sizeof(CowOperationV3));
    }
    off_t GetDataOffset() const {
        return sizeof(CowHeaderV3) + header_.buffer_size +
               (header_.resume_buffer_size * sizeof(ResumePoint)) +
               (header_.resume_point_max * sizeof(ResumePoint)) +
               header_.op_count_max * sizeof(CowOperation);
    }
    off_t GetResumeOffset() const { return sizeof(CowHeaderV3) + header_.buffer_size; }