• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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