• 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 "update_engine/payload_consumer/payload_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   // The extent for data covered by verity hash tree.
62   Extent hash_tree_data_extent;
63 
64   // The extent to store verity hash tree.
65   Extent hash_tree_extent;
66 
67   // The hash algorithm used in verity hash tree.
68   std::string hash_tree_algorithm;
69 
70   // The salt used for verity hash tree.
71   brillo::Blob hash_tree_salt;
72 
73   // The extent for data covered by FEC.
74   Extent fec_data_extent;
75 
76   // The extent to store FEC.
77   Extent fec_extent;
78 
79   // The number of FEC roots.
80   uint32_t fec_roots = 0;
81 };
82 
83 struct PartitionConfig {
PartitionConfigPartitionConfig84   explicit PartitionConfig(std::string name) : name(name) {}
85 
86   // Returns whether the PartitionConfig is not an empty image and all the
87   // fields are set correctly to a valid image file.
88   bool ValidateExists() const;
89 
90   // Open then filesystem stored in this partition and stores it in
91   // |fs_interface|. Returns whether opening the filesystem worked.
92   bool OpenFilesystem();
93 
94   // The path to the partition file. This can be a regular file or a block
95   // device such as a loop device.
96   std::string path;
97 
98   // The path to the .map file associated with |path| if any. The .map file is
99   // generated by the Android filesystem generation tools when creating a
100   // filesystem and describes the blocks used by each file.
101   std::string mapfile_path;
102 
103   // The size of the data in |path|. If rootfs verification is used (verity)
104   // this value should match the size of the verity device for the rootfs, and
105   // the size of the whole kernel. This value could be smaller than the
106   // partition and is the size of the data update_engine assumes verified for
107   // the source image, and the size of that data it should generate for the
108   // target image.
109   uint64_t size = 0;
110 
111   // The FilesystemInterface implementation used to access this partition's
112   // files.
113   std::unique_ptr<FilesystemInterface> fs_interface;
114 
115   std::string name;
116 
117   PostInstallConfig postinstall;
118   VerityConfig verity;
119 };
120 
121 // The ImageConfig struct describes a pair of binaries kernel and rootfs and the
122 // metadata associated with the image they are part of, like build number, size,
123 // etc.
124 struct ImageConfig {
125   // Returns whether the ImageConfig is an empty image.
126   bool ValidateIsEmpty() const;
127 
128   // Load |rootfs_size| and |kernel.size| from the respective image files. For
129   // the kernel, the whole |kernel.path| file is assumed. For the rootfs, the
130   // size is detected from the filesystem.
131   // Returns whether the image size was properly detected.
132   bool LoadImageSize();
133 
134   // Load postinstall config from a key value store.
135   bool LoadPostInstallConfig(const brillo::KeyValueStore& store);
136 
137   // Load verity config by parsing the partition images.
138   bool LoadVerityConfig();
139 
140   // Load dynamic partition info from a key value store.
141   bool LoadDynamicPartitionMetadata(const brillo::KeyValueStore& store);
142 
143   // Validate |dynamic_partition_metadata| against |partitions|.
144   bool ValidateDynamicPartitionMetadata() const;
145 
146   // Returns whether the |image_info| field is empty.
147   bool ImageInfoIsEmpty() const;
148 
149   // The ImageInfo message defined in the update_metadata.proto file describes
150   // the metadata of the image.
151   ImageInfo image_info;
152 
153   // The updated partitions.
154   std::vector<PartitionConfig> partitions;
155 
156   // The super partition metadata.
157   std::unique_ptr<DynamicPartitionMetadata> dynamic_partition_metadata;
158 };
159 
160 struct PayloadVersion {
PayloadVersionPayloadVersion161   PayloadVersion() : PayloadVersion(0, 0) {}
162   PayloadVersion(uint64_t major_version, uint32_t minor_version);
163 
164   // Returns whether the PayloadVersion is valid.
165   bool Validate() const;
166 
167   // Return whether the passed |operation| is allowed by this payload.
168   bool OperationAllowed(InstallOperation::Type operation) const;
169 
170   // Whether this payload version is a delta payload.
171   bool IsDelta() const;
172 
173   // Tells whether the update is done in-place, that is, whether the operations
174   // read and write from the same partition.
175   bool InplaceUpdate() const;
176 
177   // The major version of the payload.
178   uint64_t major;
179 
180   // The minor version of the payload.
181   uint32_t minor;
182 };
183 
184 // The PayloadGenerationConfig struct encapsulates all the configuration to
185 // build the requested payload. This includes information about the old and new
186 // image as well as the restrictions applied to the payload (like minor-version
187 // and full/delta payload).
188 struct PayloadGenerationConfig {
189   // Returns whether the PayloadGenerationConfig is valid.
190   bool Validate() const;
191 
192   // Image information about the new image that's the target of this payload.
193   ImageConfig target;
194 
195   // Image information pertaining the old image, if any. This is only valid
196   // if is_full is false, so we are requested a delta payload.
197   ImageConfig source;
198 
199   // Whether the requested payload is a delta payload.
200   bool is_delta = false;
201 
202   // The major/minor version of the payload.
203   PayloadVersion version;
204 
205   // The size of the rootfs partition, that not necessarily is the same as the
206   // filesystem in either source or target version, since there is some space
207   // after the partition used to store the verity hashes and or the bootcache.
208   uint64_t rootfs_partition_size = 0;
209 
210   // The |hard_chunk_size| is the maximum size that a single operation should
211   // write in the destination. Operations bigger than chunk_size should be
212   // split. A value of -1 means no hard chunk size limit. A very low limit
213   // means more operations, and less of a chance to reuse the data.
214   ssize_t hard_chunk_size = -1;
215 
216   // The |soft_chunk_size| is the preferred chunk size to use when there's no
217   // significant impact to the operations. For example, REPLACE, MOVE and
218   // SOURCE_COPY operations are not significantly impacted by the chunk size,
219   // except for a few bytes overhead in the manifest to describe extra
220   // operations. On the other hand, splitting BSDIFF operations impacts the
221   // payload size since it is not possible to use the redundancy *between*
222   // chunks.
223   size_t soft_chunk_size = 2 * 1024 * 1024;
224 
225   // TODO(deymo): Remove the block_size member and maybe replace it with a
226   // minimum alignment size for blocks (if needed). Algorithms should be able to
227   // pick the block_size they want, but for now only 4 KiB is supported.
228 
229   // The block size used for all the operations in the manifest.
230   size_t block_size = 4096;
231 
232   // The maximum timestamp of the OS allowed to apply this payload.
233   int64_t max_timestamp = 0;
234 };
235 
236 }  // namespace chromeos_update_engine
237 
238 #endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
239