1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2015 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
16f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
17f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo#include "update_engine/payload_generator/payload_generation_config.h"
18f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
19a26432a8fe5981ca1bb41cb6aacddfc3765666acAlex Deymo#include <base/logging.h>
20a26432a8fe5981ca1bb41cb6aacddfc3765666acAlex Deymo
2139910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h"
2239910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/delta_performer.h"
23f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo#include "update_engine/payload_generator/delta_diff_generator.h"
24dcbc0ae6a5c48b40a1bc7d3c2ed62ec2a9fe7748Sen Jiang#include "update_engine/payload_generator/delta_diff_utils.h"
25b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo#include "update_engine/payload_generator/ext2_filesystem.h"
2620bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo#include "update_engine/payload_generator/mapfile_filesystem.h"
27b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo#include "update_engine/payload_generator/raw_filesystem.h"
28f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
29f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymonamespace chromeos_update_engine {
30f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
3105feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiangbool PostInstallConfig::IsEmpty() const {
325b91c6b141970c2b0095775a61e3f941417aa1ffAlex Deymo  return !run && path.empty() && filesystem_type.empty() && !optional;
3305feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang}
3405feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang
3535589c2b9a0e20b42661b132890128d8025c1954Alex Deymobool PartitionConfig::ValidateExists() const {
3635589c2b9a0e20b42661b132890128d8025c1954Alex Deymo  TEST_AND_RETURN_FALSE(!path.empty());
3735589c2b9a0e20b42661b132890128d8025c1954Alex Deymo  TEST_AND_RETURN_FALSE(utils::FileExists(path.c_str()));
3835589c2b9a0e20b42661b132890128d8025c1954Alex Deymo  TEST_AND_RETURN_FALSE(size > 0);
39f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  // The requested size is within the limits of the file.
4035589c2b9a0e20b42661b132890128d8025c1954Alex Deymo  TEST_AND_RETURN_FALSE(static_cast<off_t>(size) <=
4135589c2b9a0e20b42661b132890128d8025c1954Alex Deymo                        utils::FileSize(path.c_str()));
42f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  return true;
43f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}
44f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
45b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymobool PartitionConfig::OpenFilesystem() {
46b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  if (path.empty())
47b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo    return true;
48b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  fs_interface.reset();
49dcbc0ae6a5c48b40a1bc7d3c2ed62ec2a9fe7748Sen Jiang  if (diff_utils::IsExtFilesystem(path)) {
50b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo    fs_interface = Ext2Filesystem::CreateFromFile(path);
51dcbc0ae6a5c48b40a1bc7d3c2ed62ec2a9fe7748Sen Jiang    // TODO(deymo): The delta generator algorithm doesn't support a block size
52dcbc0ae6a5c48b40a1bc7d3c2ed62ec2a9fe7748Sen Jiang    // different than 4 KiB. Remove this check once that's fixed. b/26972455
5320bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo    if (fs_interface) {
54dcbc0ae6a5c48b40a1bc7d3c2ed62ec2a9fe7748Sen Jiang      TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize);
5520bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo      return true;
5620bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo    }
57b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  }
58b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo
5920bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo  if (!mapfile_path.empty()) {
6020bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo    fs_interface = MapfileFilesystem::CreateFromFile(path, mapfile_path);
6120bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo    if (fs_interface) {
6220bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo      TEST_AND_RETURN_FALSE(fs_interface->GetBlockSize() == kBlockSize);
6320bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo      return true;
6420bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo    }
65b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  }
6620bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo
6720bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo  // Fall back to a RAW filesystem.
6820bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo  TEST_AND_RETURN_FALSE(size % kBlockSize == 0);
6920bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo  fs_interface = RawFilesystem::Create(
7020bdc70e540e021c4a26553dfdbfd2fabe8ea432Alex Deymo      "<" + name + "-partition>", kBlockSize, size / kBlockSize);
71b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  return true;
72b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo}
73b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo
74f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymobool ImageConfig::ValidateIsEmpty() const {
75f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  TEST_AND_RETURN_FALSE(ImageInfoIsEmpty());
76981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang  return partitions.empty();
77f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}
78f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
79f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymobool ImageConfig::LoadImageSize() {
80981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang  for (PartitionConfig& part : partitions) {
81981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    if (part.path.empty())
82981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang      continue;
83981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    part.size = utils::FileSize(part.path);
84981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang  }
85f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  return true;
86f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}
87f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
8805feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiangbool ImageConfig::LoadPostInstallConfig(const brillo::KeyValueStore& store) {
8905feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  bool found_postinstall = false;
9005feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  for (PartitionConfig& part : partitions) {
9105feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    bool run_postinstall;
9205feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    if (!store.GetBoolean("RUN_POSTINSTALL_" + part.name, &run_postinstall) ||
9305feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang        !run_postinstall)
9405feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang      continue;
9505feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    found_postinstall = true;
9605feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    part.postinstall.run = true;
9705feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    store.GetString("POSTINSTALL_PATH_" + part.name, &part.postinstall.path);
9805feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    store.GetString("FILESYSTEM_TYPE_" + part.name,
9905feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang                    &part.postinstall.filesystem_type);
1005b91c6b141970c2b0095775a61e3f941417aa1ffAlex Deymo    store.GetBoolean("POSTINSTALL_OPTIONAL_" + part.name,
1015b91c6b141970c2b0095775a61e3f941417aa1ffAlex Deymo                     &part.postinstall.optional);
10205feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  }
10305feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  if (!found_postinstall) {
10405feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    LOG(ERROR) << "No valid postinstall config found.";
10505feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang    return false;
10605feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  }
10705feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang  return true;
10805feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang}
10905feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang
110f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymobool ImageConfig::ImageInfoIsEmpty() const {
111f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  return image_info.board().empty()
112f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    && image_info.key().empty()
113f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    && image_info.channel().empty()
114f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    && image_info.version().empty()
115f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    && image_info.build_channel().empty()
116f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    && image_info.build_version().empty();
117f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}
118f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
119a4073ef63482fd08c3678982f7d153360b088094Alex DeymoPayloadVersion::PayloadVersion(uint64_t major_version, uint32_t minor_version) {
120a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  major = major_version;
121a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  minor = minor_version;
122a4073ef63482fd08c3678982f7d153360b088094Alex Deymo}
123a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
124a4073ef63482fd08c3678982f7d153360b088094Alex Deymobool PayloadVersion::Validate() const {
125a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  TEST_AND_RETURN_FALSE(major == kChromeOSMajorPayloadVersion ||
126a4073ef63482fd08c3678982f7d153360b088094Alex Deymo                        major == kBrilloMajorPayloadVersion);
127a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  TEST_AND_RETURN_FALSE(minor == kFullPayloadMinorVersion ||
128a4073ef63482fd08c3678982f7d153360b088094Alex Deymo                        minor == kInPlaceMinorPayloadVersion ||
129a4073ef63482fd08c3678982f7d153360b088094Alex Deymo                        minor == kSourceMinorPayloadVersion ||
130a4073ef63482fd08c3678982f7d153360b088094Alex Deymo                        minor == kOpSrcHashMinorPayloadVersion ||
131a4073ef63482fd08c3678982f7d153360b088094Alex Deymo                        minor == kImgdiffMinorPayloadVersion);
132a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  return true;
133a4073ef63482fd08c3678982f7d153360b088094Alex Deymo}
134a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
135a4073ef63482fd08c3678982f7d153360b088094Alex Deymobool PayloadVersion::OperationAllowed(InstallOperation_Type operation) const {
136a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  switch (operation) {
137a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    // Full operations:
138a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::REPLACE:
139a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::REPLACE_BZ:
140a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // These operations were included in the original payload format.
141a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      return true;
142a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
143a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::REPLACE_XZ:
144a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // These operations are included in the major version used in Brillo, but
145a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // can also be used with minor version 3 or newer.
146a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      return major == kBrilloMajorPayloadVersion ||
147a4073ef63482fd08c3678982f7d153360b088094Alex Deymo             minor >= kOpSrcHashMinorPayloadVersion;
148a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
1490497d05764dcae38e7a7419a2f25eff043172850Alex Deymo    case InstallOperation::ZERO:
1500497d05764dcae38e7a7419a2f25eff043172850Alex Deymo    case InstallOperation::DISCARD:
1510497d05764dcae38e7a7419a2f25eff043172850Alex Deymo      // The implementation of these operations had a bug in earlier versions
1520497d05764dcae38e7a7419a2f25eff043172850Alex Deymo      // that prevents them from being used in any payload. We will enable
1530497d05764dcae38e7a7419a2f25eff043172850Alex Deymo      // them for delta payloads for now.
1540497d05764dcae38e7a7419a2f25eff043172850Alex Deymo      return minor >= kImgdiffMinorPayloadVersion;
1550497d05764dcae38e7a7419a2f25eff043172850Alex Deymo
156a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    // Delta operations:
157a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::MOVE:
158a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::BSDIFF:
159a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // MOVE and BSDIFF were replaced by SOURCE_COPY and SOURCE_BSDIFF and
160a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // should not be used in newer delta versions, since the idempotent checks
161a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      // were removed.
162a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      return minor == kInPlaceMinorPayloadVersion;
163a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
164a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::SOURCE_COPY:
165a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::SOURCE_BSDIFF:
166a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      return minor >= kSourceMinorPayloadVersion;
167a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
168a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    case InstallOperation::IMGDIFF:
169a4073ef63482fd08c3678982f7d153360b088094Alex Deymo      return minor >= kImgdiffMinorPayloadVersion && imgdiff_allowed;
170a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  }
171a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  return false;
172a4073ef63482fd08c3678982f7d153360b088094Alex Deymo}
173a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
174a4073ef63482fd08c3678982f7d153360b088094Alex Deymobool PayloadVersion::IsDelta() const {
175a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  return minor != kFullPayloadMinorVersion;
176a4073ef63482fd08c3678982f7d153360b088094Alex Deymo}
177a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
178a4073ef63482fd08c3678982f7d153360b088094Alex Deymobool PayloadVersion::InplaceUpdate() const {
179a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  return minor == kInPlaceMinorPayloadVersion;
180a4073ef63482fd08c3678982f7d153360b088094Alex Deymo}
181a4073ef63482fd08c3678982f7d153360b088094Alex Deymo
182f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymobool PayloadGenerationConfig::Validate() const {
183a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  TEST_AND_RETURN_FALSE(version.Validate());
184a4073ef63482fd08c3678982f7d153360b088094Alex Deymo  TEST_AND_RETURN_FALSE(version.IsDelta() == is_delta);
185f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  if (is_delta) {
186981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    for (const PartitionConfig& part : source.partitions) {
187981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang      if (!part.path.empty()) {
188981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang        TEST_AND_RETURN_FALSE(part.ValidateExists());
189981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang        TEST_AND_RETURN_FALSE(part.size % block_size == 0);
190981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang      }
19105feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang      // Source partition should not have postinstall.
19205feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang      TEST_AND_RETURN_FALSE(part.postinstall.IsEmpty());
193f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    }
194f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
195f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    // If new_image_info is present, old_image_info must be present.
196f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    TEST_AND_RETURN_FALSE(source.ImageInfoIsEmpty() ==
197f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo                          target.ImageInfoIsEmpty());
198f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  } else {
199f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    // All the "source" image fields must be empty for full payloads.
200f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo    TEST_AND_RETURN_FALSE(source.ValidateIsEmpty());
201f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  }
202f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
203f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  // In all cases, the target image must exists.
204981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang  for (const PartitionConfig& part : target.partitions) {
205981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    TEST_AND_RETURN_FALSE(part.ValidateExists());
206981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    TEST_AND_RETURN_FALSE(part.size % block_size == 0);
207a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    if (version.minor == kInPlaceMinorPayloadVersion &&
208981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang        part.name == kLegacyPartitionNameRoot)
209981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang      TEST_AND_RETURN_FALSE(rootfs_partition_size >= part.size);
210a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    if (version.major == kChromeOSMajorPayloadVersion)
21105feee0fc8f4f10b425f04e1f5cdd4831bbfb969Sen Jiang      TEST_AND_RETURN_FALSE(part.postinstall.IsEmpty());
212981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang  }
213f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
2142d3b2d635e50c6886e285afb86c3187d9e0bd360Alex Deymo  TEST_AND_RETURN_FALSE(hard_chunk_size == -1 ||
2152d3b2d635e50c6886e285afb86c3187d9e0bd360Alex Deymo                        hard_chunk_size % block_size == 0);
2162d3b2d635e50c6886e285afb86c3187d9e0bd360Alex Deymo  TEST_AND_RETURN_FALSE(soft_chunk_size % block_size == 0);
2179b244df41f1bdaddd87b7dbd8e1559556059ed1bAlex Deymo
2189b244df41f1bdaddd87b7dbd8e1559556059ed1bAlex Deymo  TEST_AND_RETURN_FALSE(rootfs_partition_size % block_size == 0);
2199b244df41f1bdaddd87b7dbd8e1559556059ed1bAlex Deymo
220f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo  return true;
221f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}
222f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo
223f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo}  // namespace chromeos_update_engine
224