blob: 1578f29e0fa52c7012925521c1235a8a1534d1ea [file] [log] [blame]
Kelvin Zhang94f51cc2020-09-25 11:34:49 -04001//
2// Copyright (C) 2020 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "update_engine/payload_consumer/vabc_partition_writer.h"
18
19#include <memory>
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040020#include <vector>
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040021
22#include <libsnapshot/cow_writer.h>
23
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040024#include "update_engine/common/cow_operation_convert.h"
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040025#include "update_engine/common/utils.h"
26#include "update_engine/payload_consumer/extent_writer.h"
27#include "update_engine/payload_consumer/install_plan.h"
28#include "update_engine/payload_consumer/partition_writer.h"
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040029#include "update_engine/payload_consumer/snapshot_extent_writer.h"
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040030
31namespace chromeos_update_engine {
32bool VABCPartitionWriter::Init(const InstallPlan* install_plan,
33 bool source_may_exist) {
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040034 TEST_AND_RETURN_FALSE(install_plan != nullptr);
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040035 TEST_AND_RETURN_FALSE(PartitionWriter::Init(install_plan, source_may_exist));
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040036 cow_writer_ = dynamic_control_->OpenCowWriter(
37 install_part_.name, install_part_.source_path, install_plan->is_resume);
38 TEST_AND_RETURN_FALSE(cow_writer_ != nullptr);
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040039
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040040 // TODO(zhangkelvin) Emit a label before writing SOURCE_COPY. When resuming,
41 // use pref or CowWriter::GetLastLabel to determine if the SOURCE_COPY ops are
42 // written. No need to handle SOURCE_COPY operations when resuming.
43
44 // ===== Resume case handling code goes here ====
45
46 // ==============================================
47
48 // TODO(zhangkelvin) Rewrite this in C++20 coroutine once that's available.
49 auto converted = ConvertToCowOperations(partition_update_.operations(),
50 partition_update_.merge_operations());
51 std::vector<uint8_t> buffer(block_size_);
52 for (const auto& cow_op : converted) {
53 switch (cow_op.op) {
54 case CowOperation::CowCopy:
55 TEST_AND_RETURN_FALSE(
56 cow_writer_->AddCopy(cow_op.dst_block, cow_op.src_block));
57 break;
58 case CowOperation::CowReplace:
59 ssize_t bytes_read = 0;
60 TEST_AND_RETURN_FALSE(utils::PReadAll(source_fd_,
61 buffer.data(),
62 block_size_,
63 cow_op.src_block * block_size_,
64 &bytes_read));
65 if (bytes_read <= 0 || static_cast<size_t>(bytes_read) != block_size_) {
66 LOG(ERROR) << "source_fd->Read failed: " << bytes_read;
67 return false;
68 }
69 TEST_AND_RETURN_FALSE(cow_writer_->AddRawBlocks(
70 cow_op.dst_block, buffer.data(), block_size_));
71 break;
72 }
73 }
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040074 return true;
75}
76
77std::unique_ptr<ExtentWriter> VABCPartitionWriter::CreateBaseExtentWriter() {
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040078 return std::make_unique<SnapshotExtentWriter>(cow_writer_.get());
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040079}
80
81[[nodiscard]] bool VABCPartitionWriter::PerformZeroOrDiscardOperation(
82 const InstallOperation& operation) {
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040083 for (const auto& extent : operation.dst_extents()) {
84 TEST_AND_RETURN_FALSE(
85 cow_writer_->AddZeroBlocks(extent.start_block(), extent.num_blocks()));
86 }
87 return true;
Kelvin Zhang94f51cc2020-09-25 11:34:49 -040088}
89
90[[nodiscard]] bool VABCPartitionWriter::PerformSourceCopyOperation(
91 const InstallOperation& operation, ErrorCode* error) {
92 // TODO(zhangkelvin) Probably just ignore SOURCE_COPY? They should be taken
93 // care of during Init();
94 return true;
95}
96
Kelvin Zhang9b10dba2020-09-25 17:09:11 -040097bool VABCPartitionWriter::Flush() {
98 // No need to do anything, as CowWriter automatically flushes every OP added.
99 return true;
100}
101
102VABCPartitionWriter::~VABCPartitionWriter() {
103 cow_writer_->Finalize();
104}
Kelvin Zhang94f51cc2020-09-25 11:34:49 -0400105
106} // namespace chromeos_update_engine