1 // Copyright (C) 2019 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 <stdint.h> 18 #include <string> 19 20 namespace android { 21 namespace snapshot { 22 23 static constexpr uint64_t kCowMagicNumber = 0x436f77634f572121ULL; 24 static constexpr uint32_t kCowVersionMajor = 2; 25 static constexpr uint32_t kCowVersionMinor = 0; 26 27 static constexpr uint32_t kCowVersionManifest = 2; 28 29 static constexpr uint32_t BLOCK_SZ = 4096; 30 static constexpr uint32_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SZ) - 1); 31 32 // This header appears as the first sequence of bytes in the COW. All fields 33 // in the layout are little-endian encoded. The on-disk layout is: 34 // 35 // +-----------------------+ 36 // | Header (fixed) | 37 // +-----------------------+ 38 // | Scratch space | 39 // +-----------------------+ 40 // | Operation (variable) | 41 // | Data (variable) | 42 // +-----------------------+ 43 // | Footer (fixed) | 44 // +-----------------------+ 45 // 46 // The operations begin immediately after the header, and the "raw data" 47 // immediately follows the operation which refers to it. While streaming 48 // an OTA, we can immediately write the op and data, syncing after each pair, 49 // while storing operation metadata in memory. At the end, we compute data and 50 // hashes for the footer, which is placed at the tail end of the file. 51 // 52 // A missing or corrupt footer likely indicates that writing was cut off 53 // between writing the last operation/data pair, or the footer itself. In this 54 // case, the safest way to proceed is to assume the last operation is faulty. 55 56 struct CowHeader { 57 uint64_t magic; 58 uint16_t major_version; 59 uint16_t minor_version; 60 61 // Size of this struct. 62 uint16_t header_size; 63 64 // Size of footer struct 65 uint16_t footer_size; 66 67 // Size of op struct 68 uint16_t op_size; 69 70 // The size of block operations, in bytes. 71 uint32_t block_size; 72 73 // The number of ops to cluster together. 0 For no clustering. Cannot be 1. 74 uint32_t cluster_ops; 75 76 // Tracks merge operations completed 77 uint64_t num_merge_ops; 78 79 // Scratch space used during merge 80 uint32_t buffer_size; 81 } __attribute__((packed)); 82 83 // This structure is the same size of a normal Operation, but is repurposed for the footer. 84 struct CowFooterOperation { 85 // The operation code (always kCowFooterOp). 86 uint8_t type; 87 88 // If this operation reads from the data section of the COW, this contains 89 // the compression type of that data (see constants below). 90 uint8_t compression; 91 92 // Length of Footer Data. Currently 64 for both checksums 93 uint16_t data_length; 94 95 // The amount of file space used by Cow operations 96 uint64_t ops_size; 97 98 // The number of cow operations in the file 99 uint64_t num_ops; 100 } __attribute__((packed)); 101 102 struct CowFooterData { 103 // SHA256 checksums of Footer op 104 uint8_t footer_checksum[32]; 105 106 // SHA256 of the operation sequence. 107 uint8_t ops_checksum[32]; 108 } __attribute__((packed)); 109 110 // Cow operations are currently fixed-size entries, but this may change if 111 // needed. 112 struct CowOperation { 113 // The operation code (see the constants and structures below). 114 uint8_t type; 115 116 // If this operation reads from the data section of the COW, this contains 117 // the compression type of that data (see constants below). 118 uint8_t compression; 119 120 // If this operation reads from the data section of the COW, this contains 121 // the length. 122 uint16_t data_length; 123 124 // The block of data in the new image that this operation modifies. 125 uint64_t new_block; 126 127 // The value of |source| depends on the operation code. 128 // 129 // For copy operations, this is a block location in the source image. 130 // 131 // For replace operations, this is a byte offset within the COW's data 132 // sections (eg, not landing within the header or metadata). It is an 133 // absolute position within the image. 134 // 135 // For zero operations (replace with all zeroes), this is unused and must 136 // be zero. 137 // 138 // For Label operations, this is the value of the applied label. 139 // 140 // For Cluster operations, this is the length of the following data region 141 uint64_t source; 142 } __attribute__((packed)); 143 144 static_assert(sizeof(CowOperation) == sizeof(CowFooterOperation)); 145 146 static constexpr uint8_t kCowCopyOp = 1; 147 static constexpr uint8_t kCowReplaceOp = 2; 148 static constexpr uint8_t kCowZeroOp = 3; 149 static constexpr uint8_t kCowLabelOp = 4; 150 static constexpr uint8_t kCowClusterOp = 5; 151 static constexpr uint8_t kCowFooterOp = -1; 152 153 static constexpr uint8_t kCowCompressNone = 0; 154 static constexpr uint8_t kCowCompressGz = 1; 155 static constexpr uint8_t kCowCompressBrotli = 2; 156 157 static constexpr uint8_t kCowReadAheadNotStarted = 0; 158 static constexpr uint8_t kCowReadAheadInProgress = 1; 159 static constexpr uint8_t kCowReadAheadDone = 2; 160 161 struct CowFooter { 162 CowFooterOperation op; 163 CowFooterData data; 164 } __attribute__((packed)); 165 166 struct ScratchMetadata { 167 // Block of data in the image that operation modifies 168 // and read-ahead thread stores the modified data 169 // in the scratch space 170 uint64_t new_block; 171 // Offset within the file to read the data 172 uint64_t file_offset; 173 } __attribute__((packed)); 174 175 struct BufferState { 176 uint8_t read_ahead_state; 177 } __attribute__((packed)); 178 179 // 2MB Scratch space used for read-ahead 180 static constexpr uint64_t BUFFER_REGION_DEFAULT_SIZE = (1ULL << 21); 181 182 std::ostream& operator<<(std::ostream& os, CowOperation const& arg); 183 184 int64_t GetNextOpOffset(const CowOperation& op, uint32_t cluster_size); 185 int64_t GetNextDataOffset(const CowOperation& op, uint32_t cluster_size); 186 187 bool IsMetadataOp(const CowOperation& op); 188 189 } // namespace snapshot 190 } // namespace android 191