• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2015 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 #ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
18 #define UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
19 
20 #include <cstddef>
21 
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include <brillo/key_value_store.h>
27 #include <brillo/secure_blob.h>
28 
29 #include "bsdiff/constants.h"
30 #include "update_engine/payload_consumer/payload_constants.h"
31 #include "update_engine/payload_generator/filesystem_interface.h"
32 #include "update_engine/update_metadata.pb.h"
33 
34 namespace chromeos_update_engine {
35 
36 struct PostInstallConfig {
37   // Whether the postinstall config is empty.
38   bool IsEmpty() const;
39 
40   // Whether this partition carries a filesystem with post-install program that
41   // must be run to finalize the update process.
42   bool run = false;
43 
44   // The path to the post-install program relative to the root of this
45   // filesystem.
46   std::string path;
47 
48   // The filesystem type used to mount the partition in order to run the
49   // post-install program.
50   std::string filesystem_type;
51 
52   // Whether this postinstall script should be ignored if it fails.
53   bool optional = false;
54 };
55 
56 // Data will be written to the payload and used for hash tree and FEC generation
57 // at device update time.
58 struct VerityConfig {
59   // Whether the verity config is empty.
60   bool IsEmpty() const;
61 
62   // The extent for data covered by verity hash tree.
63   Extent hash_tree_data_extent;
64 
65   // The extent to store verity hash tree.
66   Extent hash_tree_extent;
67 
68   // The hash algorithm used in verity hash tree.
69   std::string hash_tree_algorithm;
70 
71   // The salt used for verity hash tree.
72   brillo::Blob hash_tree_salt;
73 
74   // The extent for data covered by FEC.
75   Extent fec_data_extent;
76 
77   // The extent to store FEC.
78   Extent fec_extent;
79 
80   // The number of FEC roots.
81   uint32_t fec_roots = 0;
82 };
83 
84 struct PartitionConfig {
PartitionConfigPartitionConfig85   explicit PartitionConfig(std::string name) : name(name) {}
86   static CompressionAlgorithm ParseCompressionParam(std::string_view param);
GetDefaultCompressionParamPartitionConfig87   static CompressionAlgorithm GetDefaultCompressionParam() {
88     CompressionAlgorithm algo;
89     algo.set_type(CompressionAlgorithm::LZ4HC);
90     algo.set_level(9);
91     return algo;
92   }
93 
94   // Returns whether the PartitionConfig is not an empty image and all the
95   // fields are set correctly to a valid image file.
96   bool ValidateExists() const;
97 
98   // Open then filesystem stored in this partition and stores it in
99   // |fs_interface|. Returns whether opening the filesystem worked.
100   bool OpenFilesystem();
101 
102   // The path to the partition file. This can be a regular file or a block
103   // device such as a loop device.
104   std::string path;
105 
106   // The path to the .map file associated with |path| if any. The .map file is
107   // generated by the Android filesystem generation tools when creating a
108   // filesystem and describes the blocks used by each file.
109   std::string mapfile_path;
110 
111   // The size of the data in |path|. If rootfs verification is used (verity)
112   // this value should match the size of the verity device for the rootfs, and
113   // the size of the whole kernel. This value could be smaller than the
114   // partition and is the size of the data update_engine assumes verified for
115   // the source image, and the size of that data it should generate for the
116   // target image.
117   uint64_t size = 0;
118 
119   // The FilesystemInterface implementation used to access this partition's
120   // files.
121   std::unique_ptr<FilesystemInterface> fs_interface;
122 
123   std::string name;
124 
125   PostInstallConfig postinstall;
126   VerityConfig verity;
127 
128   // Enables the on device fec data computation by default.
129   bool disable_fec_computation = false;
130 
131   // Per-partition version, usually a number representing timestamp.
132   std::string version;
133 
134   // parameter passed to mkfs.erofs's -z option.
135   // In the format of "compressor,compression_level"
136   // Examples: lz4    lz4hc,9
137   // The default is usually lz4hc,9 for mkfs.erofs
138   CompressionAlgorithm erofs_compression_param = GetDefaultCompressionParam();
139 };
140 
141 // The ImageConfig struct describes a pair of binaries kernel and rootfs and the
142 // metadata associated with the image they are part of, like build number, size,
143 // etc.
144 struct ImageConfig {
145   // Returns whether the ImageConfig is an empty image.
146   bool ValidateIsEmpty() const;
147 
148   // Load |rootfs_size| and |kernel.size| from the respective image files. For
149   // the kernel, the whole |kernel.path| file is assumed. For the rootfs, the
150   // size is detected from the filesystem.
151   // Returns whether the image size was properly detected.
152   bool LoadImageSize();
153 
154   // Load postinstall config from a key value store.
155   bool LoadPostInstallConfig(const brillo::KeyValueStore& store);
156 
157   // Load verity config by parsing the partition images.
158   bool LoadVerityConfig();
159 
160   // Load dynamic partition info from a key value store.
161   bool LoadDynamicPartitionMetadata(const brillo::KeyValueStore& store);
162 
163   // Validate |dynamic_partition_metadata| against |partitions|.
164   bool ValidateDynamicPartitionMetadata() const;
165 
166   // The updated partitions.
167   std::vector<PartitionConfig> partitions;
168 
169   // The super partition metadata.
170   std::unique_ptr<DynamicPartitionMetadata> dynamic_partition_metadata;
171 };
172 
173 struct PayloadVersion {
PayloadVersionPayloadVersion174   PayloadVersion() : PayloadVersion(0, 0) {}
175   PayloadVersion(uint64_t major_version, uint32_t minor_version);
176 
177   // Returns whether the PayloadVersion is valid.
178   bool Validate() const;
179 
180   // Return whether the passed |operation| is allowed by this payload.
181   bool OperationAllowed(InstallOperation::Type operation) const;
182 
183   // Whether this payload version is a delta or partial payload.
184   bool IsDeltaOrPartial() const;
185 
186   // The major version of the payload.
187   uint64_t major;
188 
189   // The minor version of the payload.
190   uint32_t minor;
191 };
192 
193 // The PayloadGenerationConfig struct encapsulates all the configuration to
194 // build the requested payload. This includes information about the old and new
195 // image as well as the restrictions applied to the payload (like minor-version
196 // and full/delta payload).
197 struct PayloadGenerationConfig {
198   // Returns whether the PayloadGenerationConfig is valid.
199   bool Validate() const;
200 
201   void ParseCompressorTypes(const std::string& compressor_types);
202 
203   // Image information about the new image that's the target of this payload.
204   ImageConfig target;
205 
206   // Image information pertaining the old image, if any. This is only valid
207   // if is_full is false, so we are requested a delta payload.
208   ImageConfig source;
209 
210   // Whether the requested payload is a delta payload.
211   bool is_delta = false;
212 
213   // Whether the requested payload is a partial payload, i.e. only update a
214   // subset of partitions on device.
215   bool is_partial_update = false;
216 
217   // The major/minor version of the payload.
218   PayloadVersion version;
219 
220   // The size of the rootfs partition, that not necessarily is the same as the
221   // filesystem in either source or target version, since there is some space
222   // after the partition used to store the verity hashes and or the bootcache.
223   uint64_t rootfs_partition_size = 0;
224 
225   // The |hard_chunk_size| is the maximum size that a single operation should
226   // write in the destination. Operations bigger than chunk_size should be
227   // split. A value of -1 means no hard chunk size limit. A very low limit
228   // means more operations, and less of a chance to reuse the data.
229   ssize_t hard_chunk_size = -1;
230 
231   // The |soft_chunk_size| is the preferred chunk size to use when there's no
232   // significant impact to the operations. For example, REPLACE, MOVE and
233   // SOURCE_COPY operations are not significantly impacted by the chunk size,
234   // except for a few bytes overhead in the manifest to describe extra
235   // operations. On the other hand, splitting BSDIFF operations impacts the
236   // payload size since it is not possible to use the redundancy *between*
237   // chunks.
238   size_t soft_chunk_size = 2 * 1024 * 1024;
239 
240   // TODO(deymo): Remove the block_size member and maybe replace it with a
241   // minimum alignment size for blocks (if needed). Algorithms should be able to
242   // pick the block_size they want, but for now only 4 KiB is supported.
243 
244   // The block size used for all the operations in the manifest.
245   size_t block_size = 4096;
246 
247   // The maximum timestamp of the OS allowed to apply this payload.
248   int64_t max_timestamp = 0;
249 
250   // Path to apex_info.pb, extracted from target_file.zip
251   std::string apex_info_file;
252 
253   // Whether to enable VABC xor op
254   bool enable_vabc_xor = false;
255 
256   // Whether to enable LZ4diff ops
257   bool enable_lz4diff = false;
258 
259   // Whether to enable zucchini ops
260   bool enable_zucchini = true;
261 
262   std::vector<bsdiff::CompressorType> compressors{
263       bsdiff::CompressorType::kBZ2, bsdiff::CompressorType::kBrotli};
264 
265   [[nodiscard]] bool OperationEnabled(InstallOperation::Type op) const noexcept;
266 };
267 
268 }  // namespace chromeos_update_engine
269 
270 #endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
271