1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <libsnapshot/cow_writer.h>
18 
19 namespace android {
20 namespace snapshot {
21 
22 class CowWriterBase : public ICowWriter {
23   public:
24     CowWriterBase(const CowOptions& options, android::base::unique_fd&& fd);
~CowWriterBase()25     virtual ~CowWriterBase() {}
26 
27     // Set up the writer.
28     // The file starts from the beginning.
29     //
30     // If fd is < 0, the CowWriter will be opened against /dev/null. This is for
31     // computing COW sizes without using storage space.
32     //
33     // If a label is given, any operations after the given label will be dropped.
34     // If the given label is not found, Initialize will fail.
35     virtual bool Initialize(std::optional<uint64_t> label = {}) = 0;
36 
37     bool Sync();
38     bool AddCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) override;
39     bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size) override;
40     bool AddXorBlocks(uint32_t new_block_start, const void* data, size_t size, uint32_t old_block,
41                       uint16_t offset) override;
42     bool AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override;
43     bool AddLabel(uint64_t label) override;
44     bool AddSequenceData(size_t num_ops, const uint32_t* data) override;
GetBlockSize()45     uint32_t GetBlockSize() const override { return options_.block_size; }
GetMaxBlocks()46     std::optional<uint32_t> GetMaxBlocks() const override { return options_.max_blocks; }
47     std::unique_ptr<ICowReader> OpenReader() override;
48     std::unique_ptr<FileDescriptor> OpenFileDescriptor(
49             const std::optional<std::string>& source_device) override;
50 
options()51     const CowOptions& options() const { return options_; }
52 
53   protected:
54     virtual bool EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks = 1) = 0;
55     virtual bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) = 0;
56     virtual bool EmitXorBlocks(uint32_t new_block_start, const void* data, size_t size,
57                                uint32_t old_block, uint16_t offset) = 0;
58     virtual bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) = 0;
59     virtual bool EmitLabel(uint64_t label) = 0;
60     virtual bool EmitSequenceData(size_t num_ops, const uint32_t* data) = 0;
61 
62     bool InitFd();
63     bool ValidateNewBlock(uint64_t new_block);
64 
IsEstimating()65     bool IsEstimating() const { return is_dev_null_; }
66 
67     CowOptions options_;
68 
69     android::base::unique_fd fd_;
70     bool is_dev_null_ = false;
71     bool is_block_device_ = false;
72     uint64_t cow_image_size_ = INT64_MAX;
73 };
74 
75 }  // namespace snapshot
76 }  // namespace android
77