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