payload_generation_config.cc revision f1cbe1783dd025bd7243a8df12f20548196cc023
1// 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
7#include "update_engine/delta_performer.h"
8#include "update_engine/payload_generator/delta_diff_generator.h"
9#include "update_engine/utils.h"
10
11namespace chromeos_update_engine {
12
13bool ImageConfig::ValidateRootfsExists() const {
14  TEST_AND_RETURN_FALSE(!rootfs_part.empty());
15  TEST_AND_RETURN_FALSE(utils::FileExists(rootfs_part.c_str()));
16  TEST_AND_RETURN_FALSE(rootfs_size > 0);
17  // The requested size is within the limits of the file.
18  TEST_AND_RETURN_FALSE(static_cast<off_t>(rootfs_size) <=
19                        utils::FileSize(rootfs_part.c_str()));
20  return true;
21}
22
23bool ImageConfig::ValidateKernelExists() const {
24  TEST_AND_RETURN_FALSE(!kernel_part.empty());
25  TEST_AND_RETURN_FALSE(utils::FileExists(kernel_part.c_str()));
26  TEST_AND_RETURN_FALSE(kernel_size > 0);
27  TEST_AND_RETURN_FALSE(static_cast<off_t>(kernel_size) <=
28                        utils::FileSize(kernel_part.c_str()));
29  return true;
30}
31
32bool ImageConfig::ValidateIsEmpty() const {
33  TEST_AND_RETURN_FALSE(ImageInfoIsEmpty());
34
35  TEST_AND_RETURN_FALSE(rootfs_part.empty());
36  TEST_AND_RETURN_FALSE(rootfs_size == 0);
37  TEST_AND_RETURN_FALSE(rootfs_mountpt.empty());
38  TEST_AND_RETURN_FALSE(kernel_part.empty());
39  TEST_AND_RETURN_FALSE(kernel_size == 0);
40  return true;
41}
42
43bool ImageConfig::LoadImageSize() {
44  TEST_AND_RETURN_FALSE(!rootfs_part.empty());
45  int rootfs_block_count, rootfs_block_size;
46  TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(rootfs_part,
47                                                 &rootfs_block_count,
48                                                 &rootfs_block_size));
49  rootfs_size = static_cast<size_t>(rootfs_block_count) * rootfs_block_size;
50  if (!kernel_part.empty())
51    kernel_size = utils::FileSize(kernel_part);
52
53  // TODO(deymo): The delta generator algorithm doesn't support a block size
54  // different than 4 KiB. Remove this check once that's fixed. crbug.com/455045
55  if (rootfs_block_size != 4096) {
56    LOG(ERROR) << "The filesystem provided in " << rootfs_part
57               << " has a block size of " << rootfs_block_size
58               << " but delta_generator only supports 4096.";
59    return false;
60  }
61  return true;
62}
63
64bool ImageConfig::ImageInfoIsEmpty() const {
65  return image_info.board().empty()
66    && image_info.key().empty()
67    && image_info.channel().empty()
68    && image_info.version().empty()
69    && image_info.build_channel().empty()
70    && image_info.build_version().empty();
71}
72
73bool PayloadGenerationConfig::Validate() const {
74  if (is_delta) {
75    TEST_AND_RETURN_FALSE(source.ValidateRootfsExists());
76    TEST_AND_RETURN_FALSE(source.rootfs_size % block_size == 0);
77
78    if (!source.kernel_part.empty()) {
79      TEST_AND_RETURN_FALSE(source.ValidateKernelExists());
80      TEST_AND_RETURN_FALSE(source.kernel_size % block_size == 0);
81    }
82
83    // For deltas, we also need to check that the image is mounted in order to
84    // inspect the contents.
85    TEST_AND_RETURN_FALSE(!source.rootfs_mountpt.empty());
86    TEST_AND_RETURN_FALSE(utils::IsDir(source.rootfs_mountpt.c_str()));
87
88    TEST_AND_RETURN_FALSE(!target.rootfs_mountpt.empty());
89    TEST_AND_RETURN_FALSE(utils::IsDir(target.rootfs_mountpt.c_str()));
90
91    // Check for the supported minor_version values.
92    TEST_AND_RETURN_FALSE(minor_version == kInPlaceMinorPayloadVersion ||
93                          minor_version == kSourceMinorPayloadVersion);
94
95    // If new_image_info is present, old_image_info must be present.
96    TEST_AND_RETURN_FALSE(source.ImageInfoIsEmpty() ==
97                          target.ImageInfoIsEmpty());
98  } else {
99    // All the "source" image fields must be empty for full payloads.
100    TEST_AND_RETURN_FALSE(source.ValidateIsEmpty());
101    TEST_AND_RETURN_FALSE(minor_version ==
102                          DeltaPerformer::kFullPayloadMinorVersion);
103  }
104
105  // In all cases, the target image must exists.
106  TEST_AND_RETURN_FALSE(target.ValidateRootfsExists());
107  TEST_AND_RETURN_FALSE(target.ValidateKernelExists());
108  TEST_AND_RETURN_FALSE(target.rootfs_size % block_size == 0);
109  TEST_AND_RETURN_FALSE(target.kernel_size % block_size == 0);
110
111  TEST_AND_RETURN_FALSE(chunk_size == -1 || chunk_size % block_size == 0);
112  return true;
113}
114
115}  // namespace chromeos_update_engine
116