1 // Copyright (C) 2020 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 <optional> 18 19 #include <android-base/unique_fd.h> 20 21 #include <libsnapshot/cow_writer.h> 22 23 namespace chromeos_update_engine { 24 class FileDescriptor; 25 } // namespace chromeos_update_engine 26 27 namespace android { 28 namespace snapshot { 29 30 class ISnapshotWriter : public ICowWriter { 31 public: 32 using FileDescriptor = chromeos_update_engine::FileDescriptor; 33 34 explicit ISnapshotWriter(const CowOptions& options); 35 36 // Set the source device. This is used for AddCopy() operations, if the 37 // underlying writer needs the original bytes (for example if backed by 38 // dm-snapshot or if writing directly to an unsnapshotted region). The 39 // device is only opened on the first operation that requires it. 40 void SetSourceDevice(const std::string& source_device); 41 42 // Open the writer in write mode (no append). 43 virtual bool Initialize() = 0; 44 45 // Open the writer in append mode, with the last label to resume 46 // from. See CowWriter::InitializeAppend. 47 virtual bool InitializeAppend(uint64_t label) = 0; 48 49 virtual std::unique_ptr<FileDescriptor> OpenReader() = 0; 50 51 protected: 52 android::base::borrowed_fd GetSourceFd(); 53 54 std::optional<std::string> source_device_; 55 56 private: 57 android::base::unique_fd source_fd_; 58 }; 59 60 // Send writes to a COW or a raw device directly, based on a threshold. 61 class CompressedSnapshotWriter : public ISnapshotWriter { 62 public: 63 CompressedSnapshotWriter(const CowOptions& options); 64 65 // Sets the COW device; this is required. 66 bool SetCowDevice(android::base::unique_fd&& cow_device); 67 68 bool Initialize() override; 69 bool InitializeAppend(uint64_t label) override; 70 bool Finalize() override; 71 uint64_t GetCowSize() override; 72 std::unique_ptr<FileDescriptor> OpenReader() override; 73 74 protected: 75 bool EmitCopy(uint64_t new_block, uint64_t old_block) override; 76 bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override; 77 bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; 78 bool EmitLabel(uint64_t label) override; 79 80 private: 81 android::base::unique_fd cow_device_; 82 83 std::unique_ptr<CowWriter> cow_; 84 }; 85 86 // Write directly to a dm-snapshot device. 87 class OnlineKernelSnapshotWriter : public ISnapshotWriter { 88 public: 89 OnlineKernelSnapshotWriter(const CowOptions& options); 90 91 // Set the device used for all writes. 92 void SetSnapshotDevice(android::base::unique_fd&& snapshot_fd, uint64_t cow_size); 93 Initialize()94 bool Initialize() override { return true; } InitializeAppend(uint64_t)95 bool InitializeAppend(uint64_t) override { return true; } 96 97 bool Finalize() override; GetCowSize()98 uint64_t GetCowSize() override { return cow_size_; } 99 std::unique_ptr<FileDescriptor> OpenReader() override; 100 101 protected: 102 bool EmitRawBlocks(uint64_t new_block_start, const void* data, size_t size) override; 103 bool EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) override; 104 bool EmitCopy(uint64_t new_block, uint64_t old_block) override; 105 bool EmitLabel(uint64_t label) override; 106 107 private: 108 android::base::unique_fd snapshot_fd_; 109 uint64_t cow_size_ = 0; 110 }; 111 112 } // namespace snapshot 113 } // namespace android 114