payload_generation_config.cc revision b42b98db059a12c44110588fc0b3d5f82d32a2f8
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 <base/logging.h> 8 9#include "update_engine/delta_performer.h" 10#include "update_engine/payload_generator/delta_diff_generator.h" 11#include "update_engine/payload_generator/ext2_filesystem.h" 12#include "update_engine/payload_generator/raw_filesystem.h" 13#include "update_engine/payload_generator/verity_utils.h" 14#include "update_engine/utils.h" 15 16namespace chromeos_update_engine { 17 18bool PartitionConfig::ValidateExists() const { 19 TEST_AND_RETURN_FALSE(!path.empty()); 20 TEST_AND_RETURN_FALSE(utils::FileExists(path.c_str())); 21 TEST_AND_RETURN_FALSE(size > 0); 22 // The requested size is within the limits of the file. 23 TEST_AND_RETURN_FALSE(static_cast<off_t>(size) <= 24 utils::FileSize(path.c_str())); 25 return true; 26} 27 28bool PartitionConfig::OpenFilesystem() { 29 if (path.empty()) 30 return true; 31 fs_interface.reset(); 32 if (name == PartitionName::kRootfs) { 33 fs_interface = Ext2Filesystem::CreateFromFile(path); 34 } 35 36 if (!fs_interface) { 37 // Fall back to a RAW filesystem. 38 TEST_AND_RETURN_FALSE(size % kBlockSize == 0); 39 std::string str_name = "other"; 40 switch (name) { 41 case PartitionName::kKernel: 42 str_name = "kernel"; 43 break; 44 case PartitionName::kRootfs: 45 str_name = "rootfs"; 46 break; 47 } 48 fs_interface = RawFilesystem::Create( 49 "<" + str_name + "-partition>", 50 kBlockSize, 51 size / kBlockSize); 52 } 53 return true; 54} 55 56bool ImageConfig::ValidateIsEmpty() const { 57 TEST_AND_RETURN_FALSE(ImageInfoIsEmpty()); 58 59 TEST_AND_RETURN_FALSE(rootfs.path.empty()); 60 TEST_AND_RETURN_FALSE(rootfs.size == 0); 61 TEST_AND_RETURN_FALSE(kernel.path.empty()); 62 TEST_AND_RETURN_FALSE(kernel.size == 0); 63 return true; 64} 65 66bool ImageConfig::LoadImageSize() { 67 TEST_AND_RETURN_FALSE(!rootfs.path.empty()); 68 int rootfs_block_count, rootfs_block_size; 69 TEST_AND_RETURN_FALSE(utils::GetFilesystemSize(rootfs.path, 70 &rootfs_block_count, 71 &rootfs_block_size)); 72 rootfs.size = static_cast<uint64_t>(rootfs_block_count) * rootfs_block_size; 73 if (!kernel.path.empty()) 74 kernel.size = utils::FileSize(kernel.path); 75 76 // TODO(deymo): The delta generator algorithm doesn't support a block size 77 // different than 4 KiB. Remove this check once that's fixed. crbug.com/455045 78 if (rootfs_block_size != 4096) { 79 LOG(ERROR) << "The filesystem provided in " << rootfs.path 80 << " has a block size of " << rootfs_block_size 81 << " but delta_generator only supports 4096."; 82 return false; 83 } 84 return true; 85} 86 87bool ImageConfig::LoadVerityRootfsSize() { 88 if (kernel.path.empty()) 89 return false; 90 uint64_t verity_rootfs_size = 0; 91 if (!GetVerityRootfsSize(kernel.path, &verity_rootfs_size)) { 92 LOG(INFO) << "Couldn't find verity options in source kernel config, will " 93 << "use the rootfs filesystem size instead: " << rootfs.size; 94 return false; 95 } 96 if (rootfs.size != verity_rootfs_size) { 97 LOG(WARNING) << "Using the rootfs size found in the kernel config (" 98 << verity_rootfs_size << ") instead of the rootfs filesystem " 99 << " size (" << rootfs.size << ")."; 100 rootfs.size = verity_rootfs_size; 101 } 102 return true; 103} 104 105bool ImageConfig::ImageInfoIsEmpty() const { 106 return image_info.board().empty() 107 && image_info.key().empty() 108 && image_info.channel().empty() 109 && image_info.version().empty() 110 && image_info.build_channel().empty() 111 && image_info.build_version().empty(); 112} 113 114bool PayloadGenerationConfig::Validate() const { 115 if (is_delta) { 116 TEST_AND_RETURN_FALSE(source.rootfs.ValidateExists()); 117 TEST_AND_RETURN_FALSE(source.rootfs.size % block_size == 0); 118 119 if (!source.kernel.path.empty()) { 120 TEST_AND_RETURN_FALSE(source.kernel.ValidateExists()); 121 TEST_AND_RETURN_FALSE(source.kernel.size % block_size == 0); 122 } 123 124 // Check for the supported minor_version values. 125 TEST_AND_RETURN_FALSE(minor_version == kInPlaceMinorPayloadVersion || 126 minor_version == kSourceMinorPayloadVersion); 127 128 // If new_image_info is present, old_image_info must be present. 129 TEST_AND_RETURN_FALSE(source.ImageInfoIsEmpty() == 130 target.ImageInfoIsEmpty()); 131 } else { 132 // All the "source" image fields must be empty for full payloads. 133 TEST_AND_RETURN_FALSE(source.ValidateIsEmpty()); 134 TEST_AND_RETURN_FALSE(minor_version == 135 DeltaPerformer::kFullPayloadMinorVersion); 136 } 137 138 // In all cases, the target image must exists. 139 TEST_AND_RETURN_FALSE(target.rootfs.ValidateExists()); 140 TEST_AND_RETURN_FALSE(target.kernel.ValidateExists()); 141 TEST_AND_RETURN_FALSE(target.rootfs.size % block_size == 0); 142 TEST_AND_RETURN_FALSE(target.kernel.size % block_size == 0); 143 144 TEST_AND_RETURN_FALSE(chunk_size == -1 || chunk_size % block_size == 0); 145 146 TEST_AND_RETURN_FALSE(rootfs_partition_size % block_size == 0); 147 TEST_AND_RETURN_FALSE(rootfs_partition_size >= target.rootfs.size); 148 149 return true; 150} 151 152} // namespace chromeos_update_engine 153