blob: 4249b9eb4a8c7759290db897c3822738bb6f23db [file] [log] [blame]
Alex Deymof1cbe172015-03-05 15:58:37 -08001// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/payload_generator/payload_generation_config.h"
6
Alex Deymoa26432a2015-03-12 16:08:04 -07007#include <base/logging.h>
8
Alex Deymof1cbe172015-03-05 15:58:37 -08009#include "update_engine/delta_performer.h"
10#include "update_engine/payload_generator/delta_diff_generator.h"
Alex Deymoa26432a2015-03-12 16:08:04 -070011#include "update_engine/payload_generator/verity_utils.h"
Alex Deymof1cbe172015-03-05 15:58:37 -080012#include "update_engine/utils.h"
13
14namespace chromeos_update_engine {
15
16bool ImageConfig::ValidateRootfsExists() const {
17 TEST_AND_RETURN_FALSE(!rootfs_part.empty());
18 TEST_AND_RETURN_FALSE(utils::FileExists(rootfs_part.c_str()));
19 TEST_AND_RETURN_FALSE(rootfs_size > 0);
20 // The requested size is within the limits of the file.
21 TEST_AND_RETURN_FALSE(static_cast<off_t>(rootfs_size) <=
22 utils::FileSize(rootfs_part.c_str()));
23 return true;
24}
25
26bool ImageConfig::ValidateKernelExists() const {
27 TEST_AND_RETURN_FALSE(!kernel_part.empty());
28 TEST_AND_RETURN_FALSE(utils::FileExists(kernel_part.c_str()));
29 TEST_AND_RETURN_FALSE(kernel_size > 0);
30 TEST_AND_RETURN_FALSE(static_cast<off_t>(kernel_size) <=
31 utils::FileSize(kernel_part.c_str()));
32 return true;
33}
34
35bool ImageConfig::ValidateIsEmpty() const {
36 TEST_AND_RETURN_FALSE(ImageInfoIsEmpty());
37
38 TEST_AND_RETURN_FALSE(rootfs_part.empty());
39 TEST_AND_RETURN_FALSE(rootfs_size == 0);
40 TEST_AND_RETURN_FALSE(rootfs_mountpt.empty());
41 TEST_AND_RETURN_FALSE(kernel_part.empty());
42 TEST_AND_RETURN_FALSE(kernel_size == 0);
43 return true;
44}
45
46bool ImageConfig::LoadImageSize() {
47 TEST_AND_RETURN_FALSE(!rootfs_part.empty());
48 int rootfs_block_count, rootfs_block_size;
49 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(rootfs_part,
50 &rootfs_block_count,
51 &rootfs_block_size));
Alex Deymoa26432a2015-03-12 16:08:04 -070052 rootfs_size = static_cast<uint64_t>(rootfs_block_count) * rootfs_block_size;
Alex Deymof1cbe172015-03-05 15:58:37 -080053 if (!kernel_part.empty())
54 kernel_size = utils::FileSize(kernel_part);
55
56 // TODO(deymo): The delta generator algorithm doesn't support a block size
57 // different than 4 KiB. Remove this check once that's fixed. crbug.com/455045
58 if (rootfs_block_size != 4096) {
59 LOG(ERROR) << "The filesystem provided in " << rootfs_part
60 << " has a block size of " << rootfs_block_size
61 << " but delta_generator only supports 4096.";
62 return false;
63 }
64 return true;
65}
66
Alex Deymoa26432a2015-03-12 16:08:04 -070067bool ImageConfig::LoadVerityRootfsSize() {
68 if (kernel_part.empty())
69 return false;
70 uint64_t verity_rootfs_size = 0;
71 if (!GetVerityRootfsSize(kernel_part, &verity_rootfs_size)) {
72 LOG(INFO) << "Couldn't find verity options in source kernel config, will "
73 << "use the rootfs filesystem size instead: " << rootfs_size;
74 return false;
75 }
76 if (rootfs_size != verity_rootfs_size) {
77 LOG(WARNING) << "Using the rootfs size found in the kernel config ("
78 << verity_rootfs_size << ") instead of the rootfs filesystem "
79 << " size (" << rootfs_size << ").";
80 rootfs_size = verity_rootfs_size;
81 }
82 return true;
83}
84
Alex Deymof1cbe172015-03-05 15:58:37 -080085bool ImageConfig::ImageInfoIsEmpty() const {
86 return image_info.board().empty()
87 && image_info.key().empty()
88 && image_info.channel().empty()
89 && image_info.version().empty()
90 && image_info.build_channel().empty()
91 && image_info.build_version().empty();
92}
93
94bool PayloadGenerationConfig::Validate() const {
95 if (is_delta) {
96 TEST_AND_RETURN_FALSE(source.ValidateRootfsExists());
97 TEST_AND_RETURN_FALSE(source.rootfs_size % block_size == 0);
98
99 if (!source.kernel_part.empty()) {
100 TEST_AND_RETURN_FALSE(source.ValidateKernelExists());
101 TEST_AND_RETURN_FALSE(source.kernel_size % block_size == 0);
102 }
103
104 // For deltas, we also need to check that the image is mounted in order to
105 // inspect the contents.
106 TEST_AND_RETURN_FALSE(!source.rootfs_mountpt.empty());
107 TEST_AND_RETURN_FALSE(utils::IsDir(source.rootfs_mountpt.c_str()));
108
109 TEST_AND_RETURN_FALSE(!target.rootfs_mountpt.empty());
110 TEST_AND_RETURN_FALSE(utils::IsDir(target.rootfs_mountpt.c_str()));
111
112 // Check for the supported minor_version values.
113 TEST_AND_RETURN_FALSE(minor_version == kInPlaceMinorPayloadVersion ||
114 minor_version == kSourceMinorPayloadVersion);
115
116 // If new_image_info is present, old_image_info must be present.
117 TEST_AND_RETURN_FALSE(source.ImageInfoIsEmpty() ==
118 target.ImageInfoIsEmpty());
119 } else {
120 // All the "source" image fields must be empty for full payloads.
121 TEST_AND_RETURN_FALSE(source.ValidateIsEmpty());
122 TEST_AND_RETURN_FALSE(minor_version ==
123 DeltaPerformer::kFullPayloadMinorVersion);
124 }
125
126 // In all cases, the target image must exists.
127 TEST_AND_RETURN_FALSE(target.ValidateRootfsExists());
128 TEST_AND_RETURN_FALSE(target.ValidateKernelExists());
129 TEST_AND_RETURN_FALSE(target.rootfs_size % block_size == 0);
130 TEST_AND_RETURN_FALSE(target.kernel_size % block_size == 0);
131
132 TEST_AND_RETURN_FALSE(chunk_size == -1 || chunk_size % block_size == 0);
Alex Deymo9b244df2015-03-11 21:51:18 -0700133
134 TEST_AND_RETURN_FALSE(rootfs_partition_size % block_size == 0);
135 TEST_AND_RETURN_FALSE(rootfs_partition_size >= target.rootfs_size);
136
Alex Deymof1cbe172015-03-05 15:58:37 -0800137 return true;
138}
139
140} // namespace chromeos_update_engine