payload_generation_config.h revision 5b91c6b141970c2b0095775a61e3f941417aa1ff
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
28#include "update_engine/payload_consumer/payload_constants.h"
29#include "update_engine/payload_generator/filesystem_interface.h"
30#include "update_engine/update_metadata.pb.h"
31
32namespace chromeos_update_engine {
33
34struct PostInstallConfig {
35  // Whether the postinstall config is empty.
36  bool IsEmpty() const;
37
38  // Whether this partition carries a filesystem with post-install program that
39  // must be run to finalize the update process.
40  bool run = false;
41
42  // The path to the post-install program relative to the root of this
43  // filesystem.
44  std::string path;
45
46  // The filesystem type used to mount the partition in order to run the
47  // post-install program.
48  std::string filesystem_type;
49
50  // Whether this postinstall script should be ignored if it fails.
51  bool optional = false;
52};
53
54struct PartitionConfig {
55  explicit PartitionConfig(std::string name) : name(name) {}
56
57  // Returns whether the PartitionConfig is not an empty image and all the
58  // fields are set correctly to a valid image file.
59  bool ValidateExists() const;
60
61  // Open then filesystem stored in this partition and stores it in
62  // |fs_interface|. Returns whether opening the filesystem worked.
63  bool OpenFilesystem();
64
65  // The path to the partition file. This can be a regular file or a block
66  // device such as a loop device.
67  std::string path;
68
69  // The size of the data in |path|. If rootfs verification is used (verity)
70  // this value should match the size of the verity device for the rootfs, and
71  // the size of the whole kernel. This value could be smaller than the
72  // partition and is the size of the data update_engine assumes verified for
73  // the source image, and the size of that data it should generate for the
74  // target image.
75  uint64_t size = 0;
76
77  // The FilesystemInterface implementation used to access this partition's
78  // files.
79  std::unique_ptr<FilesystemInterface> fs_interface;
80
81  std::string name;
82
83  PostInstallConfig postinstall;
84};
85
86// The ImageConfig struct describes a pair of binaries kernel and rootfs and the
87// metadata associated with the image they are part of, like build number, size,
88// etc.
89struct ImageConfig {
90  // Returns whether the ImageConfig is an empty image.
91  bool ValidateIsEmpty() const;
92
93  // Load |rootfs_size| and |kernel.size| from the respective image files. For
94  // the kernel, the whole |kernel.path| file is assumed. For the rootfs, the
95  // size is detected from the filesystem.
96  // Returns whether the image size was properly detected.
97  bool LoadImageSize();
98
99  // Load postinstall config from a key value store.
100  bool LoadPostInstallConfig(const brillo::KeyValueStore& store);
101
102  // Returns whether the |image_info| field is empty.
103  bool ImageInfoIsEmpty() const;
104
105  // The ImageInfo message defined in the update_metadata.proto file describes
106  // the metadata of the image.
107  ImageInfo image_info;
108
109  // The updated partitions.
110  std::vector<PartitionConfig> partitions;
111};
112
113struct PayloadVersion {
114  PayloadVersion() : PayloadVersion(0, 0) {}
115  PayloadVersion(uint64_t major_version, uint32_t minor_version);
116
117  // Returns whether the PayloadVersion is valid.
118  bool Validate() const;
119
120  // Return whether the passed |operation| is allowed by this payload.
121  bool OperationAllowed(InstallOperation_Type operation) const;
122
123  // Whether this payload version is a delta payload.
124  bool IsDelta() const;
125
126  // Tells whether the update is done in-place, that is, whether the operations
127  // read and write from the same partition.
128  bool InplaceUpdate() const;
129
130  // The major version of the payload.
131  uint64_t major;
132
133  // The minor version of the payload.
134  uint32_t minor;
135
136  // Wheter the IMGDIFF operation is allowed based on the available compressor
137  // in the delta_generator and the one supported by the target.
138  bool imgdiff_allowed = false;
139};
140
141// The PayloadGenerationConfig struct encapsulates all the configuration to
142// build the requested payload. This includes information about the old and new
143// image as well as the restrictions applied to the payload (like minor-version
144// and full/delta payload).
145struct PayloadGenerationConfig {
146  // Returns whether the PayloadGenerationConfig is valid.
147  bool Validate() const;
148
149  // Image information about the new image that's the target of this payload.
150  ImageConfig target;
151
152  // Image information pertaining the old image, if any. This is only valid
153  // if is_full is false, so we are requested a delta payload.
154  ImageConfig source;
155
156  // Wheter the requested payload is a delta payload.
157  bool is_delta = false;
158
159  // The major/minor version of the payload.
160  PayloadVersion version;
161
162  // The size of the rootfs partition, that not necessarily is the same as the
163  // filesystem in either source or target version, since there is some space
164  // after the partition used to store the verity hashes and or the bootcache.
165  uint64_t rootfs_partition_size = 0;
166
167  // The |hard_chunk_size| is the maximum size that a single operation should
168  // write in the destination. Operations bigger than chunk_size should be
169  // split. A value of -1 means no hard chunk size limit. A very low limit
170  // means more operations, and less of a chance to reuse the data.
171  ssize_t hard_chunk_size = -1;
172
173  // The |soft_chunk_size| is the preferred chunk size to use when there's no
174  // significant impact to the operations. For example, REPLACE, MOVE and
175  // SOURCE_COPY operations are not significantly impacted by the chunk size,
176  // except for a few bytes overhead in the manifest to describe extra
177  // operations. On the other hand, splitting BSDIFF operations impacts the
178  // payload size since it is not possible to use the redundancy *between*
179  // chunks.
180  size_t soft_chunk_size = 2 * 1024 * 1024;
181
182  // TODO(deymo): Remove the block_size member and maybe replace it with a
183  // minimum alignment size for blocks (if needed). Algorithms should be able to
184  // pick the block_size they want, but for now only 4 KiB is supported.
185
186  // The block size used for all the operations in the manifest.
187  size_t block_size = 4096;
188};
189
190}  // namespace chromeos_update_engine
191
192#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
193