blob: b1902de66c3d9b57f27f2d5032d1f58d5fde772e [file] [log] [blame]
Alex Deymo21ec92f2016-11-04 15:49:53 -07001//
2// Copyright (C) 2017 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//
16
17#include "update_engine/payload_consumer/file_descriptor_utils.h"
18
19#include <algorithm>
20
21#include <base/logging.h>
22
23#include "update_engine/common/hash_calculator.h"
24#include "update_engine/common/utils.h"
Amin Hassanidb56be92017-09-06 12:41:23 -070025#include "update_engine/payload_consumer/extent_reader.h"
Alex Deymo21ec92f2016-11-04 15:49:53 -070026#include "update_engine/payload_consumer/extent_writer.h"
27
28using google::protobuf::RepeatedPtrField;
29using std::min;
30
31namespace chromeos_update_engine {
32
33namespace {
34
35// Size of the buffer used to copy blocks.
Amin Hassanib379d192017-12-06 15:31:17 -080036const uint64_t kMaxCopyBufferSize = 1024 * 1024;
37
38bool CommonHashExtents(FileDescriptorPtr source,
39 const RepeatedPtrField<Extent>& src_extents,
Sen Jiangbcb15aa2018-02-07 18:01:48 -080040 DirectExtentWriter* writer,
Amin Hassanib379d192017-12-06 15:31:17 -080041 uint64_t block_size,
42 brillo::Blob* hash_out) {
43 auto total_blocks = utils::BlocksInExtents(src_extents);
44 auto buffer_blocks = kMaxCopyBufferSize / block_size;
45 // Ensure we copy at least one block at a time.
46 if (buffer_blocks < 1)
47 buffer_blocks = 1;
48 brillo::Blob buf(buffer_blocks * block_size);
49
50 DirectExtentReader reader;
51 TEST_AND_RETURN_FALSE(reader.Init(source, src_extents, block_size));
Amin Hassanib379d192017-12-06 15:31:17 -080052
53 HashCalculator source_hasher;
54 while (total_blocks > 0) {
55 auto read_blocks = std::min(total_blocks, buffer_blocks);
56 TEST_AND_RETURN_FALSE(reader.Read(buf.data(), read_blocks * block_size));
57 if (hash_out != nullptr) {
58 TEST_AND_RETURN_FALSE(
59 source_hasher.Update(buf.data(), read_blocks * block_size));
60 }
Sen Jiangbcb15aa2018-02-07 18:01:48 -080061 if (writer) {
62 TEST_AND_RETURN_FALSE(
63 writer->Write(buf.data(), read_blocks * block_size));
Amin Hassanib379d192017-12-06 15:31:17 -080064 }
65 total_blocks -= read_blocks;
66 }
Amin Hassanib379d192017-12-06 15:31:17 -080067
68 if (hash_out != nullptr) {
69 TEST_AND_RETURN_FALSE(source_hasher.Finalize());
70 *hash_out = source_hasher.raw_hash();
71 }
72 return true;
73}
Alex Deymo21ec92f2016-11-04 15:49:53 -070074
Alex Deymo21ec92f2016-11-04 15:49:53 -070075} // namespace
76
77namespace fd_utils {
78
79bool CopyAndHashExtents(FileDescriptorPtr source,
80 const RepeatedPtrField<Extent>& src_extents,
81 FileDescriptorPtr target,
82 const RepeatedPtrField<Extent>& tgt_extents,
Amin Hassanib379d192017-12-06 15:31:17 -080083 uint64_t block_size,
Alex Deymo21ec92f2016-11-04 15:49:53 -070084 brillo::Blob* hash_out) {
Sen Jiangbcb15aa2018-02-07 18:01:48 -080085 DirectExtentWriter writer;
86 TEST_AND_RETURN_FALSE(writer.Init(target, tgt_extents, block_size));
87 TEST_AND_RETURN_FALSE(utils::BlocksInExtents(src_extents) ==
88 utils::BlocksInExtents(tgt_extents));
89 TEST_AND_RETURN_FALSE(
90 CommonHashExtents(source, src_extents, &writer, block_size, hash_out));
91 TEST_AND_RETURN_FALSE(writer.End());
Amin Hassanib379d192017-12-06 15:31:17 -080092 return true;
93}
Amin Hassanidb56be92017-09-06 12:41:23 -070094
Amin Hassanib379d192017-12-06 15:31:17 -080095bool ReadAndHashExtents(FileDescriptorPtr source,
96 const RepeatedPtrField<Extent>& extents,
97 uint64_t block_size,
98 brillo::Blob* hash_out) {
99 TEST_AND_RETURN_FALSE(hash_out != nullptr);
100 TEST_AND_RETURN_FALSE(
Sen Jiangbcb15aa2018-02-07 18:01:48 -0800101 CommonHashExtents(source, extents, nullptr, block_size, hash_out));
Alex Deymo21ec92f2016-11-04 15:49:53 -0700102 return true;
103}
104
105} // namespace fd_utils
106
107} // namespace chromeos_update_engine