diff options
author | Scott Lobdell <slobdell@google.com> | 2023-04-14 18:48:08 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2023-04-14 18:48:52 +0000 |
commit | aba764c6b05c00f9fc5c9b5c65dbe00eb5a017d2 (patch) | |
tree | a1006df75bd9a57e2e6e3dcb36ea58e71a4a7c76 | |
parent | d49375d29c07b8579a25ad7132bcd0c86aaf045b (diff) | |
parent | 2cc824c1110422b88adffb7848d4fd79d7304ec3 (diff) |
Merge UP1A.230407.001
Change-Id: Ia68f86bacd8f464d0ae25582975c1b9acb331cc7
-rw-r--r-- | aosp/apex_handler_android.cc | 1 | ||||
-rw-r--r-- | aosp/logging_android.cc | 2 | ||||
-rw-r--r-- | payload_consumer/vabc_partition_writer.cc | 6 | ||||
-rw-r--r-- | payload_consumer/xor_extent_writer.cc | 25 | ||||
-rw-r--r-- | payload_consumer/xor_extent_writer.h | 12 | ||||
-rw-r--r-- | payload_consumer/xor_extent_writer_unittest.cc | 56 |
6 files changed, 86 insertions, 16 deletions
diff --git a/aosp/apex_handler_android.cc b/aosp/apex_handler_android.cc index f47889ba..acc6becf 100644 --- a/aosp/apex_handler_android.cc +++ b/aosp/apex_handler_android.cc @@ -22,7 +22,6 @@ #include <ApexProperties.sysprop.h> #include "update_engine/aosp/apex_handler_android.h" -#include "update_engine/common/utils.h" namespace chromeos_update_engine { diff --git a/aosp/logging_android.cc b/aosp/logging_android.cc index 8b5465a0..5940f785 100644 --- a/aosp/logging_android.cc +++ b/aosp/logging_android.cc @@ -265,7 +265,7 @@ bool RedirectToLiblog(int severity, } else { // This will eventually be redirected to CombinedLogger. // Use nullptr as tag so that liblog infers log tag from getprogname(). - if (file == nullptr || file[0] == 0 || line == 0) { + if (file == nullptr || file[0] == 0 || line == 0 || message_start != 0) { __android_log_write(priority, nullptr /* tag */, str.c_str()); } else { __android_log_print(priority, diff --git a/payload_consumer/vabc_partition_writer.cc b/payload_consumer/vabc_partition_writer.cc index 92f27a90..17b7d50d 100644 --- a/payload_consumer/vabc_partition_writer.cc +++ b/payload_consumer/vabc_partition_writer.cc @@ -358,7 +358,11 @@ bool VABCPartitionWriter::PerformDiffOperation( std::unique_ptr<ExtentWriter> writer = IsXorEnabled() ? std::make_unique<XORExtentWriter>( - operation, source_fd, cow_writer_.get(), xor_map_) + operation, + source_fd, + cow_writer_.get(), + xor_map_, + partition_update_.old_partition_info().size()) : CreateBaseExtentWriter(); return executor_.ExecuteDiffOperation( operation, std::move(writer), source_fd, data, count); diff --git a/payload_consumer/xor_extent_writer.cc b/payload_consumer/xor_extent_writer.cc index 1a02a2d9..4534c05e 100644 --- a/payload_consumer/xor_extent_writer.cc +++ b/payload_consumer/xor_extent_writer.cc @@ -64,6 +64,23 @@ bool XORExtentWriter::WriteExtent(const void* bytes, const auto src_block = merge_op->src_extent().start_block() + xor_ext.start_block() - merge_op->dst_extent().start_block(); + const auto i = xor_ext.start_block() - extent.start_block(); + const auto dst_block_data = + static_cast<const unsigned char*>(bytes) + i * BlockSize(); + const auto is_out_of_bound_read = + (src_block + xor_ext.num_blocks()) * BlockSize() + src_offset > + partition_size_ && + partition_size_ != 0; + if (is_out_of_bound_read) { + LOG(INFO) << "Getting partial read for last block, converting " + "XOR operation to a regular replace " + << xor_ext; + TEST_AND_RETURN_FALSE( + cow_writer_->AddRawBlocks(xor_ext.start_block(), + dst_block_data, + xor_ext.num_blocks() * BlockSize())); + continue; + } xor_block_data.resize(BlockSize() * xor_ext.num_blocks()); ssize_t bytes_read = 0; TEST_AND_RETURN_FALSE_ERRNO( @@ -73,14 +90,12 @@ bool XORExtentWriter::WriteExtent(const void* bytes, src_offset + src_block * BlockSize(), &bytes_read)); if (bytes_read != static_cast<ssize_t>(xor_block_data.size())) { - LOG(ERROR) << "bytes_read: " << bytes_read; + LOG(ERROR) << "bytes_read: " << bytes_read << ", expected to read " + << xor_block_data.size() << " at block " << src_block + << " offset " << src_offset; return false; } - const auto i = xor_ext.start_block() - extent.start_block(); - - const auto dst_block_data = - static_cast<const unsigned char*>(bytes) + i * BlockSize(); std::transform(xor_block_data.cbegin(), xor_block_data.cbegin() + xor_block_data.size(), dst_block_data, diff --git a/payload_consumer/xor_extent_writer.h b/payload_consumer/xor_extent_writer.h index 35565eab..57c99c22 100644 --- a/payload_consumer/xor_extent_writer.h +++ b/payload_consumer/xor_extent_writer.h @@ -19,12 +19,9 @@ #include <vector> +#include "common/utils.h" #include "update_engine/payload_consumer/block_extent_writer.h" #include "update_engine/payload_consumer/extent_map.h" -#include "update_engine/payload_consumer/extent_reader.h" -#include "update_engine/payload_consumer/extent_writer.h" -#include "update_engine/payload_generator/extent_ranges.h" -#include "update_engine/payload_generator/extent_utils.h" #include <update_engine/update_metadata.pb.h> #include <libsnapshot/cow_writer.h> @@ -38,11 +35,13 @@ class XORExtentWriter : public BlockExtentWriter { XORExtentWriter(const InstallOperation& op, FileDescriptorPtr source_fd, android::snapshot::ICowWriter* cow_writer, - const ExtentMap<const CowMergeOperation*>& xor_map) + const ExtentMap<const CowMergeOperation*>& xor_map, + size_t partition_size) : src_extents_(op.src_extents()), source_fd_(source_fd), xor_map_(xor_map), - cow_writer_(cow_writer) { + cow_writer_(cow_writer), + partition_size_(partition_size) { CHECK(source_fd->IsOpen()); } ~XORExtentWriter() = default; @@ -61,6 +60,7 @@ class XORExtentWriter : public BlockExtentWriter { const FileDescriptorPtr source_fd_; const ExtentMap<const CowMergeOperation*>& xor_map_; android::snapshot::ICowWriter* cow_writer_; + const size_t partition_size_; }; } // namespace chromeos_update_engine diff --git a/payload_consumer/xor_extent_writer_unittest.cc b/payload_consumer/xor_extent_writer_unittest.cc index 015c9ab1..55c3c6c0 100644 --- a/payload_consumer/xor_extent_writer_unittest.cc +++ b/payload_consumer/xor_extent_writer_unittest.cc @@ -94,7 +94,8 @@ TEST_F(XorExtentWriterTest, StreamTest) { ASSERT_TRUE(xor_map_.AddExtent(op3.dst_extent(), &op3)); *op_.add_src_extents() = ExtentForRange(12, 4); *op_.add_dst_extents() = ExtentForRange(320, 4); - XORExtentWriter writer_{op_, source_fd_, &cow_writer_, xor_map_}; + XORExtentWriter writer_{ + op_, source_fd_, &cow_writer_, xor_map_, NUM_BLOCKS * kBlockSize}; // OTA op: // [5-6] => [5-6], [45-47] => [455-457], [12-15] => [320-323] @@ -146,7 +147,8 @@ TEST_F(XorExtentWriterTest, SubsetExtentTest) { *op_.add_dst_extents() = ExtentForRange(420, 3); *op_.add_src_extents() = ExtentForRange(15, 1); *op_.add_dst_extents() = ExtentForRange(323, 1); - XORExtentWriter writer_{op_, source_fd_, &cow_writer_, xor_map_}; + XORExtentWriter writer_{ + op_, source_fd_, &cow_writer_, xor_map_, NUM_BLOCKS * kBlockSize}; // OTA op: // [12-14] => [320-322], [20-22] => [420-422], [15-16] => [323-324] @@ -173,4 +175,54 @@ TEST_F(XorExtentWriterTest, SubsetExtentTest) { ASSERT_TRUE(writer_.Write(zeros->data(), zeros->size())); } +TEST_F(XorExtentWriterTest, LastBlockTest) { + constexpr auto COW_XOR = CowMergeOperation::COW_XOR; + ON_CALL(cow_writer_, EmitXorBlocks(_, _, _, _, _)) + .WillByDefault(Return(true)); + + const auto op3 = CreateCowMergeOperation( + ExtentForRange(NUM_BLOCKS - 1, 1), ExtentForRange(2, 1), COW_XOR, 777); + ASSERT_TRUE(xor_map_.AddExtent(op3.dst_extent(), &op3)); + + *op_.add_src_extents() = ExtentForRange(12, 3); + *op_.add_dst_extents() = ExtentForRange(320, 3); + + *op_.add_src_extents() = ExtentForRange(20, 3); + *op_.add_dst_extents() = ExtentForRange(420, 3); + + *op_.add_src_extents() = ExtentForRange(NUM_BLOCKS - 3, 3); + *op_.add_dst_extents() = ExtentForRange(2, 3); + XORExtentWriter writer_{ + op_, source_fd_, &cow_writer_, xor_map_, NUM_BLOCKS * kBlockSize}; + + // OTA op: + // [12-14] => [320-322], [20-22] => [420-422], [NUM_BLOCKS-3] => [2-5] + + // merge op: + // [NUM_BLOCKS-1] => [2-3] + + // Expected result: + // [12-16] should be REPLACE blocks + // [420-422] should be REPLACE blocks + // [2-4] should be REPLACE blocks + + auto zeros = utils::GetReadonlyZeroBlock(kBlockSize * 9); + EXPECT_CALL(cow_writer_, EmitRawBlocks(320, zeros->data(), kBlockSize * 3)) + .WillOnce(Return(true)); + EXPECT_CALL( + cow_writer_, + EmitRawBlocks(420, zeros->data() + 3 * kBlockSize, kBlockSize * 3)) + .WillOnce(Return(true)); + + EXPECT_CALL(cow_writer_, + EmitRawBlocks(2, zeros->data() + 6 * kBlockSize, kBlockSize)) + .WillOnce(Return(true)); + EXPECT_CALL(cow_writer_, + EmitRawBlocks(3, zeros->data() + 7 * kBlockSize, kBlockSize * 2)) + .WillOnce(Return(true)); + + ASSERT_TRUE(writer_.Init(op_.dst_extents(), kBlockSize)); + ASSERT_TRUE(writer_.Write(zeros->data(), zeros->size())); +} + } // namespace chromeos_update_engine |