| Alex Deymo | aea4c1c | 2015-08-19 20:24:43 -0700 | [diff] [blame] | 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 | // |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 16 | |
| 17 | #include "update_engine/payload_generator/payload_generation_config.h" |
| 18 | |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 19 | #include <algorithm> |
| 20 | #include <map> |
| 21 | #include <utility> |
| 22 | |
| Alex Deymo | a26432a | 2015-03-12 16:08:04 -0700 | [diff] [blame] | 23 | #include <base/logging.h> |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 24 | #include <base/strings/string_number_conversions.h> |
| 25 | #include <brillo/strings/string_utils.h> |
| Alex Deymo | a26432a | 2015-03-12 16:08:04 -0700 | [diff] [blame] | 26 | |
| Alex Deymo | 39910dc | 2015-11-09 17:04:30 -0800 | [diff] [blame] | 27 | #include "update_engine/common/utils.h" |
| 28 | #include "update_engine/payload_consumer/delta_performer.h" |
| Sen Jiang | 0a582fb | 2018-06-26 19:27:21 -0700 | [diff] [blame] | 29 | #include "update_engine/payload_generator/boot_img_filesystem.h" |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 30 | #include "update_engine/payload_generator/delta_diff_generator.h" |
| Sen Jiang | dcbc0ae | 2016-03-18 15:33:19 -0700 | [diff] [blame] | 31 | #include "update_engine/payload_generator/delta_diff_utils.h" |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 32 | #include "update_engine/payload_generator/ext2_filesystem.h" |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 33 | #include "update_engine/payload_generator/mapfile_filesystem.h" |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 34 | #include "update_engine/payload_generator/raw_filesystem.h" |
| Amin Hassani | 77c25fc | 2019-01-29 10:24:19 -0800 | [diff] [blame] | 35 | #include "update_engine/payload_generator/squashfs_filesystem.h" |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 36 | |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 37 | using std::string; |
| 38 | |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 39 | namespace chromeos_update_engine { |
| 40 | |
| Sen Jiang | 05feee0 | 2015-11-11 15:59:49 -0800 | [diff] [blame] | 41 | bool PostInstallConfig::IsEmpty() const { |
| Alex Deymo | 5b91c6b | 2016-08-04 20:33:36 -0700 | [diff] [blame] | 42 | return !run && path.empty() && filesystem_type.empty() && !optional; |
| Sen Jiang | 05feee0 | 2015-11-11 15:59:49 -0800 | [diff] [blame] | 43 | } |
| 44 | |
| Sen Jiang | 3a4dfac | 2018-08-30 16:57:38 -0700 | [diff] [blame] | 45 | bool VerityConfig::IsEmpty() const { |
| 46 | return hash_tree_data_extent.num_blocks() == 0 && |
| 47 | hash_tree_extent.num_blocks() == 0 && hash_tree_algorithm.empty() && |
| 48 | hash_tree_salt.empty() && fec_data_extent.num_blocks() == 0 && |
| 49 | fec_extent.num_blocks() == 0 && fec_roots == 0; |
| 50 | } |
| 51 | |
| Alex Deymo | 35589c2 | 2015-06-07 17:33:18 +0200 | [diff] [blame] | 52 | bool PartitionConfig::ValidateExists() const { |
| 53 | TEST_AND_RETURN_FALSE(!path.empty()); |
| 54 | TEST_AND_RETURN_FALSE(utils::FileExists(path.c_str())); |
| 55 | TEST_AND_RETURN_FALSE(size > 0); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 56 | // The requested size is within the limits of the file. |
| Alex Deymo | 35589c2 | 2015-06-07 17:33:18 +0200 | [diff] [blame] | 57 | TEST_AND_RETURN_FALSE(static_cast<off_t>(size) <= |
| 58 | utils::FileSize(path.c_str())); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 59 | return true; |
| 60 | } |
| 61 | |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 62 | bool PartitionConfig::OpenFilesystem() { |
| 63 | if (path.empty()) |
| 64 | return true; |
| 65 | fs_interface.reset(); |
| Sen Jiang | dcbc0ae | 2016-03-18 15:33:19 -0700 | [diff] [blame] | 66 | if (diff_utils::IsExtFilesystem(path)) { |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 67 | fs_interface = Ext2Filesystem::CreateFromFile(path); |
| Sen Jiang | dcbc0ae | 2016-03-18 15:33:19 -0700 | [diff] [blame] | 68 | // TODO(deymo): The delta generator algorithm doesn't support a block size |
| 69 | // different than 4 KiB. Remove this check once that's fixed. b/26972455 |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 70 | if (fs_interface) { |
| Sen Jiang | dcbc0ae | 2016-03-18 15:33:19 -0700 | [diff] [blame] | 71 | TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize); |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 72 | return true; |
| 73 | } |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 74 | } |
| 75 | |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 76 | if (!mapfile_path.empty()) { |
| 77 | fs_interface = MapfileFilesystem::CreateFromFile(path, mapfile_path); |
| 78 | if (fs_interface) { |
| 79 | TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize); |
| 80 | return true; |
| 81 | } |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 82 | } |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 83 | |
| Sen Jiang | 0a582fb | 2018-06-26 19:27:21 -0700 | [diff] [blame] | 84 | fs_interface = BootImgFilesystem::CreateFromFile(path); |
| 85 | if (fs_interface) { |
| 86 | TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize); |
| 87 | return true; |
| 88 | } |
| 89 | |
| Amin Hassani | 77c25fc | 2019-01-29 10:24:19 -0800 | [diff] [blame] | 90 | fs_interface = SquashfsFilesystem::CreateFromFile(path, |
| 91 | /*extract_deflates=*/true, |
| 92 | /*load_settings=*/true); |
| 93 | if (fs_interface) { |
| 94 | TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize); |
| 95 | return true; |
| 96 | } |
| 97 | |
| Alex Deymo | 20bdc70 | 2016-12-07 21:07:11 -0800 | [diff] [blame] | 98 | // Fall back to a RAW filesystem. |
| 99 | TEST_AND_RETURN_FALSE(size % kBlockSize == 0); |
| 100 | fs_interface = RawFilesystem::Create( |
| 101 | "<" + name + "-partition>", kBlockSize, size / kBlockSize); |
| Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 102 | return true; |
| 103 | } |
| 104 | |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 105 | bool ImageConfig::ValidateIsEmpty() const { |
| Sen Jiang | 981eb11 | 2015-08-25 17:03:18 -0700 | [diff] [blame] | 106 | return partitions.empty(); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | bool ImageConfig::LoadImageSize() { |
| Sen Jiang | 981eb11 | 2015-08-25 17:03:18 -0700 | [diff] [blame] | 110 | for (PartitionConfig& part : partitions) { |
| 111 | if (part.path.empty()) |
| 112 | continue; |
| 113 | part.size = utils::FileSize(part.path); |
| 114 | } |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 115 | return true; |
| 116 | } |
| 117 | |
| Sen Jiang | 05feee0 | 2015-11-11 15:59:49 -0800 | [diff] [blame] | 118 | bool ImageConfig::LoadPostInstallConfig(const brillo::KeyValueStore& store) { |
| 119 | bool found_postinstall = false; |
| 120 | for (PartitionConfig& part : partitions) { |
| 121 | bool run_postinstall; |
| 122 | if (!store.GetBoolean("RUN_POSTINSTALL_" + part.name, &run_postinstall) || |
| 123 | !run_postinstall) |
| 124 | continue; |
| 125 | found_postinstall = true; |
| 126 | part.postinstall.run = true; |
| 127 | store.GetString("POSTINSTALL_PATH_" + part.name, &part.postinstall.path); |
| 128 | store.GetString("FILESYSTEM_TYPE_" + part.name, |
| 129 | &part.postinstall.filesystem_type); |
| Alex Deymo | 5b91c6b | 2016-08-04 20:33:36 -0700 | [diff] [blame] | 130 | store.GetBoolean("POSTINSTALL_OPTIONAL_" + part.name, |
| 131 | &part.postinstall.optional); |
| Sen Jiang | 05feee0 | 2015-11-11 15:59:49 -0800 | [diff] [blame] | 132 | } |
| 133 | if (!found_postinstall) { |
| 134 | LOG(ERROR) << "No valid postinstall config found."; |
| 135 | return false; |
| 136 | } |
| 137 | return true; |
| 138 | } |
| 139 | |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 140 | bool ImageConfig::LoadDynamicPartitionMetadata( |
| 141 | const brillo::KeyValueStore& store) { |
| 142 | auto metadata = std::make_unique<DynamicPartitionMetadata>(); |
| 143 | string buf; |
| 144 | if (!store.GetString("super_partition_groups", &buf)) { |
| 145 | LOG(ERROR) << "Dynamic partition info missing super_partition_groups."; |
| 146 | return false; |
| 147 | } |
| 148 | auto group_names = brillo::string_utils::Split(buf, " "); |
| 149 | for (const auto& group_name : group_names) { |
| 150 | DynamicPartitionGroup* group = metadata->add_groups(); |
| 151 | group->set_name(group_name); |
| Yifan Hong | 8683ed4 | 2019-11-01 16:58:29 -0700 | [diff] [blame] | 152 | if (!store.GetString("super_" + group_name + "_group_size", &buf) && |
| 153 | !store.GetString(group_name + "_size", &buf)) { |
| 154 | LOG(ERROR) << "Missing super_" << group_name + "_group_size or " |
| 155 | << group_name << "_size."; |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 156 | return false; |
| 157 | } |
| 158 | |
| 159 | uint64_t max_size; |
| 160 | if (!base::StringToUint64(buf, &max_size)) { |
| Yifan Hong | 8683ed4 | 2019-11-01 16:58:29 -0700 | [diff] [blame] | 161 | LOG(ERROR) << "Group size for " << group_name << " = " << buf |
| 162 | << " is not an integer."; |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 163 | return false; |
| 164 | } |
| 165 | group->set_size(max_size); |
| 166 | |
| Yifan Hong | 8683ed4 | 2019-11-01 16:58:29 -0700 | [diff] [blame] | 167 | if (store.GetString("super_" + group_name + "_partition_list", &buf) || |
| 168 | store.GetString(group_name + "_partition_list", &buf)) { |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 169 | auto partition_names = brillo::string_utils::Split(buf, " "); |
| 170 | for (const auto& partition_name : partition_names) { |
| 171 | group->add_partition_names()->assign(partition_name); |
| 172 | } |
| 173 | } |
| 174 | } |
| Yifan Hong | 05b3b96 | 2019-09-26 17:19:21 -0700 | [diff] [blame] | 175 | |
| 176 | bool snapshot_enabled = false; |
| 177 | store.GetBoolean("virtual_ab", &snapshot_enabled); |
| 178 | metadata->set_snapshot_enabled(snapshot_enabled); |
| Kelvin Zhang | ad8ea10 | 2021-01-14 10:14:44 -0500 | [diff] [blame] | 179 | bool vabc_enabled = false; |
| Kelvin Zhang | 413982e | 2021-03-02 15:34:50 -0500 | [diff] [blame^] | 180 | if (store.GetBoolean("virtual_ab_compression", &vabc_enabled) && |
| 181 | vabc_enabled) { |
| 182 | LOG(INFO) << "Target build supports VABC"; |
| Kelvin Zhang | ad8ea10 | 2021-01-14 10:14:44 -0500 | [diff] [blame] | 183 | metadata->set_vabc_enabled(vabc_enabled); |
| 184 | } |
| Kelvin Zhang | 4ca06c1 | 2021-02-04 17:16:40 -0500 | [diff] [blame] | 185 | // We use "gz" compression by default for VABC. |
| 186 | if (metadata->vabc_enabled()) { |
| 187 | metadata->set_vabc_compression_param("gz"); |
| 188 | } |
| Yifan Hong | 398cb54 | 2018-10-18 11:29:40 -0700 | [diff] [blame] | 189 | dynamic_partition_metadata = std::move(metadata); |
| 190 | return true; |
| 191 | } |
| 192 | |
| 193 | bool ImageConfig::ValidateDynamicPartitionMetadata() const { |
| 194 | if (dynamic_partition_metadata == nullptr) { |
| 195 | LOG(ERROR) << "dynamic_partition_metadata is not loaded."; |
| 196 | return false; |
| 197 | } |
| 198 | |
| 199 | for (const auto& group : dynamic_partition_metadata->groups()) { |
| 200 | uint64_t sum_size = 0; |
| 201 | for (const auto& partition_name : group.partition_names()) { |
| 202 | auto partition_config = std::find_if(partitions.begin(), |
| 203 | partitions.end(), |
| 204 | [&partition_name](const auto& e) { |
| 205 | return e.name == partition_name; |
| 206 | }); |
| 207 | |
| 208 | if (partition_config == partitions.end()) { |
| 209 | LOG(ERROR) << "Cannot find partition " << partition_name |
| 210 | << " which is in " << group.name() << "_partition_list"; |
| 211 | return false; |
| 212 | } |
| 213 | sum_size += partition_config->size; |
| 214 | } |
| 215 | |
| 216 | if (sum_size > group.size()) { |
| 217 | LOG(ERROR) << "Sum of sizes in " << group.name() << "_partition_list is " |
| 218 | << sum_size << ", which is greater than " << group.name() |
| 219 | << "_size (" << group.size() << ")"; |
| 220 | return false; |
| 221 | } |
| 222 | } |
| 223 | return true; |
| 224 | } |
| 225 | |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 226 | PayloadVersion::PayloadVersion(uint64_t major_version, uint32_t minor_version) { |
| 227 | major = major_version; |
| 228 | minor = minor_version; |
| 229 | } |
| 230 | |
| 231 | bool PayloadVersion::Validate() const { |
| Amin Hassani | 55c7541 | 2019-10-07 11:20:39 -0700 | [diff] [blame] | 232 | TEST_AND_RETURN_FALSE(major == kBrilloMajorPayloadVersion); |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 233 | TEST_AND_RETURN_FALSE(minor == kFullPayloadMinorVersion || |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 234 | minor == kSourceMinorPayloadVersion || |
| 235 | minor == kOpSrcHashMinorPayloadVersion || |
| Amin Hassani | 77d7cbc | 2018-02-07 16:21:33 -0800 | [diff] [blame] | 236 | minor == kBrotliBsdiffMinorPayloadVersion || |
| Sen Jiang | 3a4dfac | 2018-08-30 16:57:38 -0700 | [diff] [blame] | 237 | minor == kPuffdiffMinorPayloadVersion || |
| Tianjie | f5baff4 | 2020-07-17 21:43:22 -0700 | [diff] [blame] | 238 | minor == kVerityMinorPayloadVersion || |
| 239 | minor == kPartialUpdateMinorPayloadVersion); |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 240 | return true; |
| 241 | } |
| 242 | |
| Sen Jiang | cebb688 | 2019-02-26 16:23:28 +0800 | [diff] [blame] | 243 | bool PayloadVersion::OperationAllowed(InstallOperation::Type operation) const { |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 244 | switch (operation) { |
| 245 | // Full operations: |
| 246 | case InstallOperation::REPLACE: |
| 247 | case InstallOperation::REPLACE_BZ: |
| 248 | // These operations were included in the original payload format. |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 249 | case InstallOperation::REPLACE_XZ: |
| Amin Hassani | 55c7541 | 2019-10-07 11:20:39 -0700 | [diff] [blame] | 250 | // These operations are included minor version 3 or newer and full |
| 251 | // payloads. |
| 252 | return true; |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 253 | |
| Alex Deymo | 0497d05 | 2016-03-23 09:16:59 -0700 | [diff] [blame] | 254 | case InstallOperation::ZERO: |
| 255 | case InstallOperation::DISCARD: |
| 256 | // The implementation of these operations had a bug in earlier versions |
| 257 | // that prevents them from being used in any payload. We will enable |
| 258 | // them for delta payloads for now. |
| Amin Hassani | 77d7cbc | 2018-02-07 16:21:33 -0800 | [diff] [blame] | 259 | return minor >= kBrotliBsdiffMinorPayloadVersion; |
| Alex Deymo | 0497d05 | 2016-03-23 09:16:59 -0700 | [diff] [blame] | 260 | |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 261 | case InstallOperation::SOURCE_COPY: |
| 262 | case InstallOperation::SOURCE_BSDIFF: |
| 263 | return minor >= kSourceMinorPayloadVersion; |
| 264 | |
| Amin Hassani | efa62d9 | 2017-11-09 13:46:56 -0800 | [diff] [blame] | 265 | case InstallOperation::BROTLI_BSDIFF: |
| Amin Hassani | 77d7cbc | 2018-02-07 16:21:33 -0800 | [diff] [blame] | 266 | return minor >= kBrotliBsdiffMinorPayloadVersion; |
| 267 | |
| Tianjie Xu | 15de2fd | 2018-02-05 17:46:48 -0800 | [diff] [blame] | 268 | case InstallOperation::PUFFDIFF: |
| Amin Hassani | 77d7cbc | 2018-02-07 16:21:33 -0800 | [diff] [blame] | 269 | return minor >= kPuffdiffMinorPayloadVersion; |
| Amin Hassani | 2fe8432 | 2020-10-28 21:43:23 +0000 | [diff] [blame] | 270 | |
| 271 | case InstallOperation::MOVE: |
| 272 | case InstallOperation::BSDIFF: |
| 273 | NOTREACHED(); |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 274 | } |
| 275 | return false; |
| 276 | } |
| 277 | |
| Tianjie | f5baff4 | 2020-07-17 21:43:22 -0700 | [diff] [blame] | 278 | bool PayloadVersion::IsDeltaOrPartial() const { |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 279 | return minor != kFullPayloadMinorVersion; |
| 280 | } |
| 281 | |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 282 | bool PayloadGenerationConfig::Validate() const { |
| Alex Deymo | a4073ef | 2016-03-22 23:40:53 -0700 | [diff] [blame] | 283 | TEST_AND_RETURN_FALSE(version.Validate()); |
| Tianjie | f5baff4 | 2020-07-17 21:43:22 -0700 | [diff] [blame] | 284 | TEST_AND_RETURN_FALSE(version.IsDeltaOrPartial() == |
| 285 | (is_delta || is_partial_update)); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 286 | if (is_delta) { |
| Sen Jiang | 981eb11 | 2015-08-25 17:03:18 -0700 | [diff] [blame] | 287 | for (const PartitionConfig& part : source.partitions) { |
| 288 | if (!part.path.empty()) { |
| 289 | TEST_AND_RETURN_FALSE(part.ValidateExists()); |
| 290 | TEST_AND_RETURN_FALSE(part.size % block_size == 0); |
| 291 | } |
| Sen Jiang | 3a4dfac | 2018-08-30 16:57:38 -0700 | [diff] [blame] | 292 | // Source partition should not have postinstall or verity config. |
| Sen Jiang | 05feee0 | 2015-11-11 15:59:49 -0800 | [diff] [blame] | 293 | TEST_AND_RETURN_FALSE(part.postinstall.IsEmpty()); |
| Sen Jiang | 3a4dfac | 2018-08-30 16:57:38 -0700 | [diff] [blame] | 294 | TEST_AND_RETURN_FALSE(part.verity.IsEmpty()); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 295 | } |
| 296 | |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 297 | } else { |
| 298 | // All the "source" image fields must be empty for full payloads. |
| 299 | TEST_AND_RETURN_FALSE(source.ValidateIsEmpty()); |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 300 | } |
| 301 | |
| 302 | // In all cases, the target image must exists. |
| Sen Jiang | 981eb11 | 2015-08-25 17:03:18 -0700 | [diff] [blame] | 303 | for (const PartitionConfig& part : target.partitions) { |
| 304 | TEST_AND_RETURN_FALSE(part.ValidateExists()); |
| 305 | TEST_AND_RETURN_FALSE(part.size % block_size == 0); |
| Sen Jiang | 3a4dfac | 2018-08-30 16:57:38 -0700 | [diff] [blame] | 306 | if (version.minor < kVerityMinorPayloadVersion) |
| 307 | TEST_AND_RETURN_FALSE(part.verity.IsEmpty()); |
| Sen Jiang | 981eb11 | 2015-08-25 17:03:18 -0700 | [diff] [blame] | 308 | } |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 309 | |
| Tianjie | f5baff4 | 2020-07-17 21:43:22 -0700 | [diff] [blame] | 310 | if (version.minor < kPartialUpdateMinorPayloadVersion) { |
| 311 | TEST_AND_RETURN_FALSE(!is_partial_update); |
| 312 | } |
| 313 | |
| Alex Deymo | 2d3b2d6 | 2015-07-17 17:34:36 -0700 | [diff] [blame] | 314 | TEST_AND_RETURN_FALSE(hard_chunk_size == -1 || |
| 315 | hard_chunk_size % block_size == 0); |
| 316 | TEST_AND_RETURN_FALSE(soft_chunk_size % block_size == 0); |
| Alex Deymo | 9b244df | 2015-03-11 21:51:18 -0700 | [diff] [blame] | 317 | |
| 318 | TEST_AND_RETURN_FALSE(rootfs_partition_size % block_size == 0); |
| Alex Deymo | 9b244df | 2015-03-11 21:51:18 -0700 | [diff] [blame] | 319 | |
| Alex Deymo | f1cbe17 | 2015-03-05 15:58:37 -0800 | [diff] [blame] | 320 | return true; |
| 321 | } |
| 322 | |
| 323 | } // namespace chromeos_update_engine |