update_engine: Deprecate minor version 1
Minor version 1 was for the old days where we rewrite the signle
partition with an update (no A/B partitions). But those days are long
over and we don't think there is any device out that has this capability
anymore. Even if there is, we can always serve full payloads along with
the stepping stone we have in M53. So this is safe to go.
BUG=chromium:1008553
TEST=sudo FEATURES=test emerge update_engine
TEST=ran cros flash two times.
Change-Id: Ib928ade36af5136cd4013a30dfb39ee7fd5b07b1
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/1829160
Tested-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Sen Jiang <senj@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
diff --git a/Android.bp b/Android.bp
index 2e215c5..47f0318 100644
--- a/Android.bp
+++ b/Android.bp
@@ -440,7 +440,6 @@
"payload_generator/block_mapping.cc",
"payload_generator/boot_img_filesystem.cc",
"payload_generator/bzip.cc",
- "payload_generator/cycle_breaker.cc",
"payload_generator/deflate_utils.cc",
"payload_generator/delta_diff_generator.cc",
"payload_generator/delta_diff_utils.cc",
@@ -448,9 +447,6 @@
"payload_generator/extent_ranges.cc",
"payload_generator/extent_utils.cc",
"payload_generator/full_update_generator.cc",
- "payload_generator/graph_types.cc",
- "payload_generator/graph_utils.cc",
- "payload_generator/inplace_generator.cc",
"payload_generator/mapfile_filesystem.cc",
"payload_generator/payload_file.cc",
"payload_generator/payload_generation_config_android.cc",
@@ -459,8 +455,6 @@
"payload_generator/payload_signer.cc",
"payload_generator/raw_filesystem.cc",
"payload_generator/squashfs_filesystem.cc",
- "payload_generator/tarjan.cc",
- "payload_generator/topological_sort.cc",
"payload_generator/xz_android.cc",
],
}
@@ -639,7 +633,6 @@
"payload_generator/blob_file_writer_unittest.cc",
"payload_generator/block_mapping_unittest.cc",
"payload_generator/boot_img_filesystem_unittest.cc",
- "payload_generator/cycle_breaker_unittest.cc",
"payload_generator/deflate_utils_unittest.cc",
"payload_generator/delta_diff_utils_unittest.cc",
"payload_generator/ext2_filesystem_unittest.cc",
@@ -647,8 +640,6 @@
"payload_generator/extent_utils_unittest.cc",
"payload_generator/fake_filesystem.cc",
"payload_generator/full_update_generator_unittest.cc",
- "payload_generator/graph_utils_unittest.cc",
- "payload_generator/inplace_generator_unittest.cc",
"payload_generator/mapfile_filesystem_unittest.cc",
"payload_generator/payload_file_unittest.cc",
"payload_generator/payload_generation_config_android_unittest.cc",
@@ -656,8 +647,6 @@
"payload_generator/payload_properties_unittest.cc",
"payload_generator/payload_signer_unittest.cc",
"payload_generator/squashfs_filesystem_unittest.cc",
- "payload_generator/tarjan_unittest.cc",
- "payload_generator/topological_sort_unittest.cc",
"payload_generator/zip_unittest.cc",
"testrunner.cc",
"update_attempter_android_unittest.cc",
diff --git a/BUILD.gn b/BUILD.gn
index 5f5aa54..1e803a0 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -329,7 +329,6 @@
"payload_generator/block_mapping.cc",
"payload_generator/boot_img_filesystem.cc",
"payload_generator/bzip.cc",
- "payload_generator/cycle_breaker.cc",
"payload_generator/deflate_utils.cc",
"payload_generator/delta_diff_generator.cc",
"payload_generator/delta_diff_utils.cc",
@@ -337,9 +336,6 @@
"payload_generator/extent_ranges.cc",
"payload_generator/extent_utils.cc",
"payload_generator/full_update_generator.cc",
- "payload_generator/graph_types.cc",
- "payload_generator/graph_utils.cc",
- "payload_generator/inplace_generator.cc",
"payload_generator/mapfile_filesystem.cc",
"payload_generator/payload_file.cc",
"payload_generator/payload_generation_config.cc",
@@ -348,8 +344,6 @@
"payload_generator/payload_signer.cc",
"payload_generator/raw_filesystem.cc",
"payload_generator/squashfs_filesystem.cc",
- "payload_generator/tarjan.cc",
- "payload_generator/topological_sort.cc",
"payload_generator/xz_chromeos.cc",
]
configs += [ ":target_defaults" ]
@@ -499,23 +493,18 @@
"payload_generator/blob_file_writer_unittest.cc",
"payload_generator/block_mapping_unittest.cc",
"payload_generator/boot_img_filesystem_unittest.cc",
- "payload_generator/cycle_breaker_unittest.cc",
"payload_generator/deflate_utils_unittest.cc",
"payload_generator/delta_diff_utils_unittest.cc",
"payload_generator/ext2_filesystem_unittest.cc",
"payload_generator/extent_ranges_unittest.cc",
"payload_generator/extent_utils_unittest.cc",
"payload_generator/full_update_generator_unittest.cc",
- "payload_generator/graph_utils_unittest.cc",
- "payload_generator/inplace_generator_unittest.cc",
"payload_generator/mapfile_filesystem_unittest.cc",
"payload_generator/payload_file_unittest.cc",
"payload_generator/payload_generation_config_unittest.cc",
"payload_generator/payload_properties_unittest.cc",
"payload_generator/payload_signer_unittest.cc",
"payload_generator/squashfs_filesystem_unittest.cc",
- "payload_generator/tarjan_unittest.cc",
- "payload_generator/topological_sort_unittest.cc",
"payload_generator/zip_unittest.cc",
"payload_state_unittest.cc",
"testrunner.cc",
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 53acc11..cc39943 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -315,9 +315,8 @@
install_plan_->partitions.size() - partitions_.size();
const InstallPlan::Partition& install_part =
install_plan_->partitions[num_previous_partitions + current_partition_];
- // Open source fds if we have a delta payload with minor version >= 2.
- if (payload_->type == InstallPayloadType::kDelta &&
- GetMinorVersion() != kInPlaceMinorPayloadVersion) {
+ // Open source fds if we have a delta payload.
+ if (payload_->type == InstallPayloadType::kDelta) {
source_path_ = install_part.source_path;
int err;
source_fd_ = OpenFile(source_path_.c_str(), O_RDONLY, false, &err);
@@ -369,9 +368,8 @@
if (current_partition_ >= partitions_.size())
return false;
- // No support for ECC in minor version 1 or full payloads.
- if (payload_->type == InstallPayloadType::kFull ||
- GetMinorVersion() == kInPlaceMinorPayloadVersion)
+ // No support for ECC for full payloads.
+ if (payload_->type == InstallPayloadType::kFull)
return false;
#if USE_FEC
@@ -685,14 +683,6 @@
op_result = PerformZeroOrDiscardOperation(op);
OP_DURATION_HISTOGRAM("ZERO_OR_DISCARD", op_start_time);
break;
- case InstallOperation::MOVE:
- op_result = PerformMoveOperation(op);
- OP_DURATION_HISTOGRAM("MOVE", op_start_time);
- break;
- case InstallOperation::BSDIFF:
- op_result = PerformBsdiffOperation(op);
- OP_DURATION_HISTOGRAM("BSDIFF", op_start_time);
- break;
case InstallOperation::SOURCE_COPY:
op_result = PerformSourceCopyOperation(op, error);
OP_DURATION_HISTOGRAM("SOURCE_COPY", op_start_time);
@@ -1030,57 +1020,6 @@
return true;
}
-bool DeltaPerformer::PerformMoveOperation(const InstallOperation& operation) {
- // Calculate buffer size. Note, this function doesn't do a sliding
- // window to copy in case the source and destination blocks overlap.
- // If we wanted to do a sliding window, we could program the server
- // to generate deltas that effectively did a sliding window.
-
- uint64_t blocks_to_read = 0;
- for (int i = 0; i < operation.src_extents_size(); i++)
- blocks_to_read += operation.src_extents(i).num_blocks();
-
- uint64_t blocks_to_write = 0;
- for (int i = 0; i < operation.dst_extents_size(); i++)
- blocks_to_write += operation.dst_extents(i).num_blocks();
-
- DCHECK_EQ(blocks_to_write, blocks_to_read);
- brillo::Blob buf(blocks_to_write * block_size_);
-
- // Read in bytes.
- ssize_t bytes_read = 0;
- for (int i = 0; i < operation.src_extents_size(); i++) {
- ssize_t bytes_read_this_iteration = 0;
- const Extent& extent = operation.src_extents(i);
- const size_t bytes = extent.num_blocks() * block_size_;
- TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
- TEST_AND_RETURN_FALSE(utils::PReadAll(target_fd_,
- &buf[bytes_read],
- bytes,
- extent.start_block() * block_size_,
- &bytes_read_this_iteration));
- TEST_AND_RETURN_FALSE(bytes_read_this_iteration ==
- static_cast<ssize_t>(bytes));
- bytes_read += bytes_read_this_iteration;
- }
-
- // Write bytes out.
- ssize_t bytes_written = 0;
- for (int i = 0; i < operation.dst_extents_size(); i++) {
- const Extent& extent = operation.dst_extents(i);
- const size_t bytes = extent.num_blocks() * block_size_;
- TEST_AND_RETURN_FALSE(extent.start_block() != kSparseHole);
- TEST_AND_RETURN_FALSE(utils::PWriteAll(target_fd_,
- &buf[bytes_written],
- bytes,
- extent.start_block() * block_size_));
- bytes_written += bytes;
- }
- DCHECK_EQ(bytes_written, bytes_read);
- DCHECK_EQ(bytes_written, static_cast<ssize_t>(buf.size()));
- return true;
-}
-
bool DeltaPerformer::ValidateSourceHash(const brillo::Blob& calculated_hash,
const InstallOperation& operation,
const FileDescriptorPtr source_fd,
@@ -1265,47 +1204,6 @@
return true;
}
-bool DeltaPerformer::PerformBsdiffOperation(const InstallOperation& operation) {
- // Since we delete data off the beginning of the buffer as we use it,
- // the data we need should be exactly at the beginning of the buffer.
- TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
- TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
-
- string input_positions;
- TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.src_extents(),
- block_size_,
- operation.src_length(),
- &input_positions));
- string output_positions;
- TEST_AND_RETURN_FALSE(ExtentsToBsdiffPositionsString(operation.dst_extents(),
- block_size_,
- operation.dst_length(),
- &output_positions));
-
- TEST_AND_RETURN_FALSE(bsdiff::bspatch(target_path_.c_str(),
- target_path_.c_str(),
- buffer_.data(),
- buffer_.size(),
- input_positions.c_str(),
- output_positions.c_str()) == 0);
- DiscardBuffer(true, buffer_.size());
-
- if (operation.dst_length() % block_size_) {
- // Zero out rest of final block.
- // TODO(adlr): build this into bspatch; it's more efficient that way.
- const Extent& last_extent =
- operation.dst_extents(operation.dst_extents_size() - 1);
- const uint64_t end_byte =
- (last_extent.start_block() + last_extent.num_blocks()) * block_size_;
- const uint64_t begin_byte =
- end_byte - (block_size_ - operation.dst_length() % block_size_);
- brillo::Blob zeros(end_byte - begin_byte);
- TEST_AND_RETURN_FALSE(utils::PWriteAll(
- target_fd_, zeros.data(), end_byte - begin_byte, begin_byte));
- }
- return true;
-}
-
namespace {
class BsdiffExtentFile : public bsdiff::FileInterface {
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index 55cb2a4..4493c2a 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -223,8 +223,6 @@
// set even if it fails.
bool PerformReplaceOperation(const InstallOperation& operation);
bool PerformZeroOrDiscardOperation(const InstallOperation& operation);
- bool PerformMoveOperation(const InstallOperation& operation);
- bool PerformBsdiffOperation(const InstallOperation& operation);
bool PerformSourceCopyOperation(const InstallOperation& operation,
ErrorCode* error);
bool PerformSourceBsdiffOperation(const InstallOperation& operation,
diff --git a/payload_consumer/delta_performer_integration_test.cc b/payload_consumer/delta_performer_integration_test.cc
index e064077..904ea5a 100644
--- a/payload_consumer/delta_performer_integration_test.cc
+++ b/payload_consumer/delta_performer_integration_test.cc
@@ -291,7 +291,6 @@
static void GenerateDeltaFile(bool full_kernel,
bool full_rootfs,
- bool noop,
ssize_t chunk_size,
SignatureTest signature_test,
DeltaState* state,
@@ -368,24 +367,16 @@
ones.size()));
}
- if (noop) {
- EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
- base::FilePath(state->b_img)));
- old_image_info = new_image_info;
- } else {
- if (minor_version == kSourceMinorPayloadVersion) {
- // Create a result image with image_size bytes of garbage.
- brillo::Blob ones(state->image_size, 0xff);
- EXPECT_TRUE(utils::WriteFile(
- state->result_img.c_str(), ones.data(), ones.size()));
- EXPECT_EQ(utils::FileSize(state->a_img),
- utils::FileSize(state->result_img));
- }
+ // Create a result image with image_size bytes of garbage.
+ brillo::Blob ones(state->image_size, 0xff);
+ EXPECT_TRUE(
+ utils::WriteFile(state->result_img.c_str(), ones.data(), ones.size()));
+ EXPECT_EQ(utils::FileSize(state->a_img), utils::FileSize(state->result_img));
- EXPECT_TRUE(
- base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
- base::FilePath(state->b_img)));
-
+ EXPECT_TRUE(
+ base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
+ base::FilePath(state->b_img)));
+ {
// Make some changes to the B image.
string b_mnt;
ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
@@ -460,10 +451,6 @@
std::copy(
std::begin(kNewData), std::end(kNewData), state->new_kernel_data.begin());
- if (noop) {
- state->old_kernel_data = state->new_kernel_data;
- }
-
// Write kernels to disk
EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
state->old_kernel_data.data(),
@@ -564,7 +551,6 @@
static void ApplyDeltaFile(bool full_kernel,
bool full_rootfs,
- bool noop,
SignatureTest signature_test,
DeltaState* state,
bool hash_checks_mandatory,
@@ -611,11 +597,6 @@
EXPECT_FALSE(signature.data().empty());
}
- if (noop) {
- EXPECT_EQ(0, manifest.install_operations_size());
- EXPECT_EQ(1, manifest.kernel_install_operations_size());
- }
-
if (full_kernel) {
EXPECT_FALSE(manifest.has_old_kernel_info());
} else {
@@ -632,25 +613,12 @@
EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
if (!full_rootfs) {
- if (noop) {
- EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
- EXPECT_EQ(manifest.old_image_info().board(), "test-board");
- EXPECT_EQ(manifest.old_image_info().version(), "test-version");
- EXPECT_EQ(manifest.old_image_info().key(), "test-key");
- EXPECT_EQ(manifest.old_image_info().build_channel(),
- "test-build-channel");
- EXPECT_EQ(manifest.old_image_info().build_version(),
- "test-build-version");
- } else {
- EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
- EXPECT_EQ(manifest.old_image_info().board(), "src-board");
- EXPECT_EQ(manifest.old_image_info().version(), "src-version");
- EXPECT_EQ(manifest.old_image_info().key(), "src-key");
- EXPECT_EQ(manifest.old_image_info().build_channel(),
- "src-build-channel");
- EXPECT_EQ(manifest.old_image_info().build_version(),
- "src-build-version");
- }
+ EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
+ EXPECT_EQ(manifest.old_image_info().board(), "src-board");
+ EXPECT_EQ(manifest.old_image_info().version(), "src-version");
+ EXPECT_EQ(manifest.old_image_info().key(), "src-key");
+ EXPECT_EQ(manifest.old_image_info().build_channel(), "src-build-channel");
+ EXPECT_EQ(manifest.old_image_info().build_version(), "src-build-version");
}
if (full_rootfs) {
@@ -741,25 +709,14 @@
// The partitions should be empty before DeltaPerformer.
install_plan->partitions.clear();
- // With minor version 2, we want the target to be the new image, result_img,
- // but with version 1, we want to update A in place.
- string target_root, target_kernel;
- if (minor_version == kSourceMinorPayloadVersion) {
- target_root = state->result_img;
- target_kernel = state->result_kernel;
- } else {
- target_root = state->a_img;
- target_kernel = state->old_kernel;
- }
-
state->fake_boot_control_.SetPartitionDevice(
kPartitionNameRoot, install_plan->source_slot, state->a_img);
state->fake_boot_control_.SetPartitionDevice(
kPartitionNameKernel, install_plan->source_slot, state->old_kernel);
state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameRoot, install_plan->target_slot, target_root);
+ kPartitionNameRoot, install_plan->target_slot, state->result_img);
state->fake_boot_control_.SetPartitionDevice(
- kPartitionNameKernel, install_plan->target_slot, target_kernel);
+ kPartitionNameKernel, install_plan->target_slot, state->result_kernel);
ErrorCode expected_error, actual_error;
bool continue_writing;
@@ -838,20 +795,12 @@
return;
}
- brillo::Blob updated_kernel_partition;
- if (minor_version == kSourceMinorPayloadVersion) {
- CompareFilesByBlock(
- state->result_kernel, state->new_kernel, state->kernel_size);
- CompareFilesByBlock(state->result_img, state->b_img, state->image_size);
- EXPECT_TRUE(
- utils::ReadFile(state->result_kernel, &updated_kernel_partition));
- } else {
- CompareFilesByBlock(
- state->old_kernel, state->new_kernel, state->kernel_size);
- CompareFilesByBlock(state->a_img, state->b_img, state->image_size);
- EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
- }
+ CompareFilesByBlock(
+ state->result_kernel, state->new_kernel, state->kernel_size);
+ CompareFilesByBlock(state->result_img, state->b_img, state->image_size);
+ brillo::Blob updated_kernel_partition;
+ EXPECT_TRUE(utils::ReadFile(state->result_kernel, &updated_kernel_partition));
ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
EXPECT_TRUE(std::equal(std::begin(kNewData),
std::end(kNewData),
@@ -897,7 +846,6 @@
void DoSmallImageTest(bool full_kernel,
bool full_rootfs,
- bool noop,
ssize_t chunk_size,
SignatureTest signature_test,
bool hash_checks_mandatory,
@@ -906,7 +854,6 @@
DeltaPerformer* performer = nullptr;
GenerateDeltaFile(full_kernel,
full_rootfs,
- noop,
chunk_size,
signature_test,
&state,
@@ -921,7 +868,6 @@
ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
ApplyDeltaFile(full_kernel,
full_rootfs,
- noop,
signature_test,
&state,
hash_checks_mandatory,
@@ -936,8 +882,7 @@
bool hash_checks_mandatory) {
DeltaState state;
uint64_t minor_version = kFullPayloadMinorVersion;
- GenerateDeltaFile(
- true, true, false, -1, kSignatureGenerated, &state, minor_version);
+ GenerateDeltaFile(true, true, -1, kSignatureGenerated, &state, minor_version);
ScopedPathUnlinker a_img_unlinker(state.a_img);
ScopedPathUnlinker b_img_unlinker(state.b_img);
ScopedPathUnlinker delta_unlinker(state.delta_path);
@@ -946,7 +891,6 @@
DeltaPerformer* performer = nullptr;
ApplyDeltaFile(true,
true,
- false,
kSignatureGenerated,
&state,
hash_checks_mandatory,
@@ -957,24 +901,18 @@
}
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageTest) {
- DoSmallImageTest(false,
- false,
- false,
- -1,
- kSignatureGenerator,
- false,
- kInPlaceMinorPayloadVersion);
+ DoSmallImageTest(
+ false, false, -1, kSignatureGenerator, false, kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest,
RunAsRootSmallImageSignaturePlaceholderTest) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGeneratedPlaceholder,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest,
@@ -982,120 +920,87 @@
DeltaState state;
GenerateDeltaFile(false,
false,
- false,
-1,
kSignatureGeneratedPlaceholderMismatch,
&state,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageChunksTest) {
DoSmallImageTest(false,
false,
- false,
kBlockSize,
kSignatureGenerator,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootFullKernelSmallImageTest) {
- DoSmallImageTest(true,
- false,
- false,
- -1,
- kSignatureGenerator,
- false,
- kInPlaceMinorPayloadVersion);
+ DoSmallImageTest(
+ true, false, -1, kSignatureGenerator, false, kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootFullSmallImageTest) {
DoSmallImageTest(true,
true,
- false,
-1,
kSignatureGenerator,
true,
kFullPayloadMinorVersion);
}
-TEST(DeltaPerformerIntegrationTest, RunAsRootNoopSmallImageTest) {
- DoSmallImageTest(false,
- false,
- true,
- -1,
- kSignatureGenerator,
- false,
- kInPlaceMinorPayloadVersion);
-}
-
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignNoneTest) {
- DoSmallImageTest(false,
- false,
- false,
- -1,
- kSignatureNone,
- false,
- kInPlaceMinorPayloadVersion);
+ DoSmallImageTest(
+ false, false, -1, kSignatureNone, false, kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedTest) {
- DoSmallImageTest(false,
- false,
- false,
- -1,
- kSignatureGenerated,
- true,
- kInPlaceMinorPayloadVersion);
+ DoSmallImageTest(
+ false, false, -1, kSignatureGenerated, true, kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellTest) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGeneratedShell,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest,
RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGeneratedShellBadKey,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest,
RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGeneratedShellRotateCl1,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest,
RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGeneratedShellRotateCl2,
false,
- kInPlaceMinorPayloadVersion);
+ kSourceMinorPayloadVersion);
}
TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSourceOpsTest) {
DoSmallImageTest(false,
false,
- false,
-1,
kSignatureGenerator,
false,
diff --git a/payload_consumer/payload_constants.cc b/payload_consumer/payload_constants.cc
index 213d798..9e684d7 100644
--- a/payload_consumer/payload_constants.cc
+++ b/payload_consumer/payload_constants.cc
@@ -16,22 +16,24 @@
#include "update_engine/payload_consumer/payload_constants.h"
+#include <base/logging.h>
+
namespace chromeos_update_engine {
const uint64_t kChromeOSMajorPayloadVersion = 1;
const uint64_t kBrilloMajorPayloadVersion = 2;
-const uint32_t kMinSupportedMinorPayloadVersion = 1;
-const uint32_t kMaxSupportedMinorPayloadVersion = 6;
-
const uint32_t kFullPayloadMinorVersion = 0;
-const uint32_t kInPlaceMinorPayloadVersion = 1;
+// const uint32_t kInPlaceMinorPayloadVersion = 1; DEPRECATED
const uint32_t kSourceMinorPayloadVersion = 2;
const uint32_t kOpSrcHashMinorPayloadVersion = 3;
const uint32_t kBrotliBsdiffMinorPayloadVersion = 4;
const uint32_t kPuffdiffMinorPayloadVersion = 5;
const uint32_t kVerityMinorPayloadVersion = 6;
+const uint32_t kMinSupportedMinorPayloadVersion = kSourceMinorPayloadVersion;
+const uint32_t kMaxSupportedMinorPayloadVersion = kVerityMinorPayloadVersion;
+
const uint64_t kMinSupportedMajorPayloadVersion = 1;
const uint64_t kMaxSupportedMajorPayloadVersion = 2;
@@ -44,10 +46,6 @@
const char* InstallOperationTypeName(InstallOperation_Type op_type) {
switch (op_type) {
- case InstallOperation::BSDIFF:
- return "BSDIFF";
- case InstallOperation::MOVE:
- return "MOVE";
case InstallOperation::REPLACE:
return "REPLACE";
case InstallOperation::REPLACE_BZ:
@@ -66,6 +64,10 @@
return "PUFFDIFF";
case InstallOperation::BROTLI_BSDIFF:
return "BROTLI_BSDIFF";
+
+ case InstallOperation::BSDIFF:
+ case InstallOperation::MOVE:
+ NOTREACHED();
}
return "<unknown_op>";
}
diff --git a/payload_consumer/payload_constants.h b/payload_consumer/payload_constants.h
index 7f76898..fe823f4 100644
--- a/payload_consumer/payload_constants.h
+++ b/payload_consumer/payload_constants.h
@@ -39,7 +39,7 @@
extern const uint32_t kFullPayloadMinorVersion;
// The minor version used by the in-place delta generator algorithm.
-extern const uint32_t kInPlaceMinorPayloadVersion;
+// extern const uint32_t kInPlaceMinorPayloadVersion; DEPRECATED
// The minor version used by the A to B delta generator algorithm.
extern const uint32_t kSourceMinorPayloadVersion;
diff --git a/payload_generator/cycle_breaker.cc b/payload_generator/cycle_breaker.cc
deleted file mode 100644
index d76f679..0000000
--- a/payload_generator/cycle_breaker.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-//
-// Copyright (C) 2012 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/cycle_breaker.h"
-
-#include <inttypes.h>
-
-#include <limits>
-#include <set>
-#include <string>
-#include <utility>
-
-#include <base/stl_util.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-
-#include "update_engine/payload_generator/graph_utils.h"
-#include "update_engine/payload_generator/tarjan.h"
-
-using std::make_pair;
-using std::set;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-// This is the outer function from the original paper.
-void CycleBreaker::BreakCycles(const Graph& graph, set<Edge>* out_cut_edges) {
- cut_edges_.clear();
-
- // Make a copy, which we will modify by removing edges. Thus, in each
- // iteration subgraph_ is the current subgraph or the original with
- // vertices we desire. This variable was "A_K" in the original paper.
- subgraph_ = graph;
-
- // The paper calls for the "adjacency structure (i.e., graph) of
- // strong (-ly connected) component K with least vertex in subgraph
- // induced by {s, s + 1, ..., n}".
- // We arbitrarily order each vertex by its index in the graph. Thus,
- // each iteration, we are looking at the subgraph {s, s + 1, ..., n}
- // and looking for the strongly connected component with vertex s.
-
- TarjanAlgorithm tarjan;
- skipped_ops_ = 0;
-
- for (Graph::size_type i = 0; i < subgraph_.size(); i++) {
- InstallOperation_Type op_type = graph[i].aop.op.type();
- if (op_type == InstallOperation::REPLACE ||
- op_type == InstallOperation::REPLACE_BZ) {
- skipped_ops_++;
- continue;
- }
-
- if (i > 0) {
- // Erase node (i - 1) from subgraph_. First, erase what it points to
- subgraph_[i - 1].out_edges.clear();
- // Now, erase any pointers to node (i - 1)
- for (Graph::size_type j = i; j < subgraph_.size(); j++) {
- subgraph_[j].out_edges.erase(i - 1);
- }
- }
-
- // Calculate SCC (strongly connected component) with vertex i.
- vector<Vertex::Index> component_indexes;
- tarjan.Execute(i, &subgraph_, &component_indexes);
-
- // Set subgraph edges for the components in the SCC.
- for (vector<Vertex::Index>::iterator it = component_indexes.begin();
- it != component_indexes.end();
- ++it) {
- subgraph_[*it].subgraph_edges.clear();
- for (vector<Vertex::Index>::iterator jt = component_indexes.begin();
- jt != component_indexes.end();
- ++jt) {
- // If there's a link from *it -> *jt in the graph,
- // add a subgraph_ edge
- if (base::ContainsKey(subgraph_[*it].out_edges, *jt))
- subgraph_[*it].subgraph_edges.insert(*jt);
- }
- }
-
- current_vertex_ = i;
- blocked_.clear();
- blocked_.resize(subgraph_.size());
- blocked_graph_.clear();
- blocked_graph_.resize(subgraph_.size());
- Circuit(current_vertex_, 0);
- }
-
- out_cut_edges->swap(cut_edges_);
- LOG(INFO) << "Cycle breaker skipped " << skipped_ops_ << " ops.";
- DCHECK(stack_.empty());
-}
-
-static const size_t kMaxEdgesToConsider = 2;
-
-void CycleBreaker::HandleCircuit() {
- stack_.push_back(current_vertex_);
- CHECK_GE(stack_.size(), static_cast<vector<Vertex::Index>::size_type>(2));
- Edge min_edge = make_pair(stack_[0], stack_[1]);
- uint64_t min_edge_weight = std::numeric_limits<uint64_t>::max();
- size_t edges_considered = 0;
- for (vector<Vertex::Index>::const_iterator it = stack_.begin();
- it != (stack_.end() - 1);
- ++it) {
- Edge edge = make_pair(*it, *(it + 1));
- if (cut_edges_.find(edge) != cut_edges_.end()) {
- stack_.pop_back();
- return;
- }
- uint64_t edge_weight = graph_utils::EdgeWeight(subgraph_, edge);
- if (edge_weight < min_edge_weight) {
- min_edge_weight = edge_weight;
- min_edge = edge;
- }
- edges_considered++;
- if (edges_considered == kMaxEdgesToConsider)
- break;
- }
- cut_edges_.insert(min_edge);
- stack_.pop_back();
-}
-
-void CycleBreaker::Unblock(Vertex::Index u) {
- blocked_[u] = false;
-
- for (Vertex::EdgeMap::iterator it = blocked_graph_[u].out_edges.begin();
- it != blocked_graph_[u].out_edges.end();) {
- Vertex::Index w = it->first;
- blocked_graph_[u].out_edges.erase(it++);
- if (blocked_[w])
- Unblock(w);
- }
-}
-
-bool CycleBreaker::StackContainsCutEdge() const {
- for (vector<Vertex::Index>::const_iterator it = ++stack_.begin(),
- e = stack_.end();
- it != e;
- ++it) {
- Edge edge = make_pair(*(it - 1), *it);
- if (base::ContainsKey(cut_edges_, edge)) {
- return true;
- }
- }
- return false;
-}
-
-bool CycleBreaker::Circuit(Vertex::Index vertex, Vertex::Index depth) {
- // "vertex" was "v" in the original paper.
- bool found = false; // Was "f" in the original paper.
- stack_.push_back(vertex);
- blocked_[vertex] = true;
- {
- static int counter = 0;
- counter++;
- if (counter == 10000) {
- counter = 0;
- std::string stack_str;
- for (Vertex::Index index : stack_) {
- stack_str += std::to_string(index);
- stack_str += " -> ";
- }
- LOG(INFO) << "stack: " << stack_str;
- }
- }
-
- for (Vertex::SubgraphEdgeMap::iterator w =
- subgraph_[vertex].subgraph_edges.begin();
- w != subgraph_[vertex].subgraph_edges.end();
- ++w) {
- if (*w == current_vertex_) {
- // The original paper called for printing stack_ followed by
- // current_vertex_ here, which is a cycle. Instead, we call
- // HandleCircuit() to break it.
- HandleCircuit();
- found = true;
- } else if (!blocked_[*w]) {
- if (Circuit(*w, depth + 1)) {
- found = true;
- if ((depth > kMaxEdgesToConsider) || StackContainsCutEdge())
- break;
- }
- }
- }
-
- if (found) {
- Unblock(vertex);
- } else {
- for (Vertex::SubgraphEdgeMap::iterator w =
- subgraph_[vertex].subgraph_edges.begin();
- w != subgraph_[vertex].subgraph_edges.end();
- ++w) {
- if (blocked_graph_[*w].out_edges.find(vertex) ==
- blocked_graph_[*w].out_edges.end()) {
- blocked_graph_[*w].out_edges.insert(
- make_pair(vertex, EdgeProperties()));
- }
- }
- }
- CHECK_EQ(vertex, stack_.back());
- stack_.pop_back();
- return found;
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/cycle_breaker.h b/payload_generator/cycle_breaker.h
deleted file mode 100644
index 01518fe..0000000
--- a/payload_generator/cycle_breaker.h
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_CYCLE_BREAKER_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_CYCLE_BREAKER_H_
-
-// This is a modified implementation of Donald B. Johnson's algorithm for
-// finding all elementary cycles (a.k.a. circuits) in a directed graph.
-// See the paper "Finding All the Elementary Circuits of a Directed Graph"
-// at http://dutta.csc.ncsu.edu/csc791_spring07/wrap/circuits_johnson.pdf
-// for reference.
-
-// Note: this version of the algorithm not only finds cycles, but breaks them.
-// It uses a simple greedy algorithm for cutting: when a cycle is discovered,
-// the edge with the least weight is cut. Longer term we may wish to do
-// something more intelligent, since the goal is (ideally) to minimize the
-// sum of the weights of all cut cycles. In practice, it's intractable
-// to consider all cycles before cutting any; there are simply too many.
-// In a sample graph representative of a typical workload, I found over
-// 5 * 10^15 cycles.
-
-#include <set>
-#include <vector>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-namespace chromeos_update_engine {
-
-class CycleBreaker {
- public:
- CycleBreaker() : skipped_ops_(0) {}
- // out_cut_edges is replaced with the cut edges.
- void BreakCycles(const Graph& graph, std::set<Edge>* out_cut_edges);
-
- size_t skipped_ops() const { return skipped_ops_; }
-
- private:
- void HandleCircuit();
- void Unblock(Vertex::Index u);
- bool Circuit(Vertex::Index vertex, Vertex::Index depth);
- bool StackContainsCutEdge() const;
-
- std::vector<bool> blocked_; // "blocked" in the paper
- Vertex::Index current_vertex_; // "s" in the paper
- std::vector<Vertex::Index> stack_; // the stack variable in the paper
- Graph subgraph_; // "A_K" in the paper
- Graph blocked_graph_; // "B" in the paper
-
- std::set<Edge> cut_edges_;
-
- // Number of operations skipped b/c we know they don't have any
- // incoming edges.
- size_t skipped_ops_;
-};
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_CYCLE_BREAKER_H_
diff --git a/payload_generator/cycle_breaker_unittest.cc b/payload_generator/cycle_breaker_unittest.cc
deleted file mode 100644
index fdcf49b..0000000
--- a/payload_generator/cycle_breaker_unittest.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/cycle_breaker.h"
-
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/logging.h>
-#include <base/stl_util.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-using std::make_pair;
-using std::pair;
-using std::set;
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-namespace {
-void SetOpForNodes(Graph* graph) {
- for (Vertex& vertex : *graph) {
- vertex.aop.op.set_type(InstallOperation::MOVE);
- }
-}
-} // namespace
-
-class CycleBreakerTest : public ::testing::Test {};
-
-TEST(CycleBreakerTest, SimpleTest) {
- int counter = 0;
- const Vertex::Index n_a = counter++;
- const Vertex::Index n_b = counter++;
- const Vertex::Index n_c = counter++;
- const Vertex::Index n_d = counter++;
- const Vertex::Index n_e = counter++;
- const Vertex::Index n_f = counter++;
- const Vertex::Index n_g = counter++;
- const Vertex::Index n_h = counter++;
- const Graph::size_type kNodeCount = counter++;
-
- Graph graph(kNodeCount);
- SetOpForNodes(&graph);
-
- graph[n_a].out_edges.insert(make_pair(n_e, EdgeProperties()));
- graph[n_a].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_b].out_edges.insert(make_pair(n_a, EdgeProperties()));
- graph[n_c].out_edges.insert(make_pair(n_d, EdgeProperties()));
- graph[n_d].out_edges.insert(make_pair(n_e, EdgeProperties()));
- graph[n_d].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_b, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_c, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_f].out_edges.insert(make_pair(n_g, EdgeProperties()));
- graph[n_g].out_edges.insert(make_pair(n_h, EdgeProperties()));
- graph[n_h].out_edges.insert(make_pair(n_g, EdgeProperties()));
-
- CycleBreaker breaker;
-
- set<Edge> broken_edges;
- breaker.BreakCycles(graph, &broken_edges);
-
- // The following cycles must be cut:
- // A->E->B
- // C->D->E
- // G->H
-
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_a, n_e)) ||
- base::ContainsKey(broken_edges, make_pair(n_e, n_b)) ||
- base::ContainsKey(broken_edges, make_pair(n_b, n_a)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_c, n_d)) ||
- base::ContainsKey(broken_edges, make_pair(n_d, n_e)) ||
- base::ContainsKey(broken_edges, make_pair(n_e, n_c)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_g, n_h)) ||
- base::ContainsKey(broken_edges, make_pair(n_h, n_g)));
- EXPECT_EQ(3U, broken_edges.size());
-}
-
-namespace {
-pair<Vertex::Index, EdgeProperties> EdgeWithWeight(Vertex::Index dest,
- uint64_t weight) {
- EdgeProperties props;
- props.extents.resize(1);
- props.extents[0].set_num_blocks(weight);
- return make_pair(dest, props);
-}
-} // namespace
-
-// This creates a bunch of cycles like this:
-//
-// root <------.
-// (t)-> / | \ |
-// V V V |
-// N N N |
-// \ | / |
-// VVV |
-// N |
-// / | \ |
-// V V V |
-// N N N |
-// ... |
-// (s)-> \ | / |
-// VVV |
-// N |
-// \_________/
-//
-// such that the original cutting algo would cut edges (s). We changed
-// the algorithm to cut cycles (t) instead, since they are closer to the
-// root, and that can massively speed up cycle cutting.
-TEST(CycleBreakerTest, AggressiveCutTest) {
- size_t counter = 0;
-
- const int kNodesPerGroup = 4;
- const int kGroups = 33;
-
- Graph graph(kGroups * kNodesPerGroup + 1); // + 1 for the root node
- SetOpForNodes(&graph);
-
- const Vertex::Index n_root = counter++;
-
- Vertex::Index last_hub = n_root;
- for (int i = 0; i < kGroups; i++) {
- uint64_t weight = 5;
- if (i == 0)
- weight = 2;
- else if (i == (kGroups - 1))
- weight = 1;
-
- const Vertex::Index next_hub = counter++;
-
- for (int j = 0; j < (kNodesPerGroup - 1); j++) {
- const Vertex::Index node = counter++;
- graph[last_hub].out_edges.insert(EdgeWithWeight(node, weight));
- graph[node].out_edges.insert(EdgeWithWeight(next_hub, weight));
- }
- last_hub = next_hub;
- }
-
- graph[last_hub].out_edges.insert(EdgeWithWeight(n_root, 5));
-
- EXPECT_EQ(counter, graph.size());
-
- CycleBreaker breaker;
-
- set<Edge> broken_edges;
- LOG(INFO) << "If this hangs for more than 1 second, the test has failed.";
- breaker.BreakCycles(graph, &broken_edges);
-
- set<Edge> expected_cuts;
-
- for (Vertex::EdgeMap::const_iterator it = graph[n_root].out_edges.begin(),
- e = graph[n_root].out_edges.end();
- it != e;
- ++it) {
- expected_cuts.insert(make_pair(n_root, it->first));
- }
-
- EXPECT_TRUE(broken_edges == expected_cuts);
-}
-
-TEST(CycleBreakerTest, WeightTest) {
- size_t counter = 0;
- const Vertex::Index n_a = counter++;
- const Vertex::Index n_b = counter++;
- const Vertex::Index n_c = counter++;
- const Vertex::Index n_d = counter++;
- const Vertex::Index n_e = counter++;
- const Vertex::Index n_f = counter++;
- const Vertex::Index n_g = counter++;
- const Vertex::Index n_h = counter++;
- const Vertex::Index n_i = counter++;
- const Vertex::Index n_j = counter++;
- const Graph::size_type kNodeCount = counter++;
-
- Graph graph(kNodeCount);
- SetOpForNodes(&graph);
-
- graph[n_a].out_edges.insert(EdgeWithWeight(n_b, 4));
- graph[n_a].out_edges.insert(EdgeWithWeight(n_f, 3));
- graph[n_a].out_edges.insert(EdgeWithWeight(n_h, 2));
- graph[n_b].out_edges.insert(EdgeWithWeight(n_a, 3));
- graph[n_b].out_edges.insert(EdgeWithWeight(n_c, 4));
- graph[n_c].out_edges.insert(EdgeWithWeight(n_b, 5));
- graph[n_c].out_edges.insert(EdgeWithWeight(n_d, 3));
- graph[n_d].out_edges.insert(EdgeWithWeight(n_a, 6));
- graph[n_d].out_edges.insert(EdgeWithWeight(n_e, 3));
- graph[n_e].out_edges.insert(EdgeWithWeight(n_d, 4));
- graph[n_e].out_edges.insert(EdgeWithWeight(n_g, 5));
- graph[n_f].out_edges.insert(EdgeWithWeight(n_g, 2));
- graph[n_g].out_edges.insert(EdgeWithWeight(n_f, 3));
- graph[n_g].out_edges.insert(EdgeWithWeight(n_d, 5));
- graph[n_h].out_edges.insert(EdgeWithWeight(n_i, 8));
- graph[n_i].out_edges.insert(EdgeWithWeight(n_e, 4));
- graph[n_i].out_edges.insert(EdgeWithWeight(n_h, 9));
- graph[n_i].out_edges.insert(EdgeWithWeight(n_j, 6));
-
- CycleBreaker breaker;
-
- set<Edge> broken_edges;
- breaker.BreakCycles(graph, &broken_edges);
-
- // These are required to be broken:
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_b, n_a)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_b, n_c)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_d, n_e)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_f, n_g)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_h, n_i)));
-}
-
-TEST(CycleBreakerTest, UnblockGraphTest) {
- size_t counter = 0;
- const Vertex::Index n_a = counter++;
- const Vertex::Index n_b = counter++;
- const Vertex::Index n_c = counter++;
- const Vertex::Index n_d = counter++;
- const Graph::size_type kNodeCount = counter++;
-
- Graph graph(kNodeCount);
- SetOpForNodes(&graph);
-
- graph[n_a].out_edges.insert(EdgeWithWeight(n_b, 1));
- graph[n_a].out_edges.insert(EdgeWithWeight(n_c, 1));
- graph[n_b].out_edges.insert(EdgeWithWeight(n_c, 2));
- graph[n_c].out_edges.insert(EdgeWithWeight(n_b, 2));
- graph[n_b].out_edges.insert(EdgeWithWeight(n_d, 2));
- graph[n_d].out_edges.insert(EdgeWithWeight(n_a, 2));
-
- CycleBreaker breaker;
-
- set<Edge> broken_edges;
- breaker.BreakCycles(graph, &broken_edges);
-
- // These are required to be broken:
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_a, n_b)));
- EXPECT_TRUE(base::ContainsKey(broken_edges, make_pair(n_a, n_c)));
-}
-
-TEST(CycleBreakerTest, SkipOpsTest) {
- size_t counter = 0;
- const Vertex::Index n_a = counter++;
- const Vertex::Index n_b = counter++;
- const Vertex::Index n_c = counter++;
- const Graph::size_type kNodeCount = counter++;
-
- Graph graph(kNodeCount);
- SetOpForNodes(&graph);
- graph[n_a].aop.op.set_type(InstallOperation::REPLACE_BZ);
- graph[n_c].aop.op.set_type(InstallOperation::REPLACE);
-
- graph[n_a].out_edges.insert(EdgeWithWeight(n_b, 1));
- graph[n_c].out_edges.insert(EdgeWithWeight(n_b, 1));
-
- CycleBreaker breaker;
-
- set<Edge> broken_edges;
- breaker.BreakCycles(graph, &broken_edges);
-
- EXPECT_EQ(2U, breaker.skipped_ops());
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index d484d32..595a41e 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -37,7 +37,6 @@
#include "update_engine/payload_generator/blob_file_writer.h"
#include "update_engine/payload_generator/delta_diff_utils.h"
#include "update_engine/payload_generator/full_update_generator.h"
-#include "update_engine/payload_generator/inplace_generator.h"
#include "update_engine/payload_generator/payload_file.h"
using std::string;
@@ -93,13 +92,8 @@
unique_ptr<OperationsGenerator> strategy;
if (!old_part.path.empty()) {
// Delta update.
- if (config.version.minor == kInPlaceMinorPayloadVersion) {
- LOG(INFO) << "Using generator InplaceGenerator().";
- strategy.reset(new InplaceGenerator());
- } else {
- LOG(INFO) << "Using generator ABGenerator().";
- strategy.reset(new ABGenerator());
- }
+ LOG(INFO) << "Using generator ABGenerator().";
+ strategy.reset(new ABGenerator());
} else {
LOG(INFO) << "Using generator FullUpdateGenerator().";
strategy.reset(new FullUpdateGenerator());
@@ -110,11 +104,6 @@
TEST_AND_RETURN_FALSE(strategy->GenerateOperations(
config, old_part, new_part, &blob_file, &aops));
- // Filter the no-operations. OperationsGenerators should not output this
- // kind of operations normally, but this is an extra step to fix that if
- // happened.
- diff_utils::FilterNoopOperations(&aops);
-
TEST_AND_RETURN_FALSE(payload.AddPartition(old_part, new_part, aops));
}
}
diff --git a/payload_generator/delta_diff_utils.cc b/payload_generator/delta_diff_utils.cc
index 1bad4d7..db69d74 100644
--- a/payload_generator/delta_diff_utils.cc
+++ b/payload_generator/delta_diff_utils.cc
@@ -83,103 +83,6 @@
const int kBrotliCompressionQuality = 11;
-// Process a range of blocks from |range_start| to |range_end| in the extent at
-// position |*idx_p| of |extents|. If |do_remove| is true, this range will be
-// removed, which may cause the extent to be trimmed, split or removed entirely.
-// The value of |*idx_p| is updated to point to the next extent to be processed.
-// Returns true iff the next extent to process is a new or updated one.
-bool ProcessExtentBlockRange(vector<Extent>* extents,
- size_t* idx_p,
- const bool do_remove,
- uint64_t range_start,
- uint64_t range_end) {
- size_t idx = *idx_p;
- uint64_t start_block = (*extents)[idx].start_block();
- uint64_t num_blocks = (*extents)[idx].num_blocks();
- uint64_t range_size = range_end - range_start;
-
- if (do_remove) {
- if (range_size == num_blocks) {
- // Remove the entire extent.
- extents->erase(extents->begin() + idx);
- } else if (range_end == num_blocks) {
- // Trim the end of the extent.
- (*extents)[idx].set_num_blocks(num_blocks - range_size);
- idx++;
- } else if (range_start == 0) {
- // Trim the head of the extent.
- (*extents)[idx].set_start_block(start_block + range_size);
- (*extents)[idx].set_num_blocks(num_blocks - range_size);
- } else {
- // Trim the middle, splitting the remainder into two parts.
- (*extents)[idx].set_num_blocks(range_start);
- Extent e;
- e.set_start_block(start_block + range_end);
- e.set_num_blocks(num_blocks - range_end);
- idx++;
- extents->insert(extents->begin() + idx, e);
- }
- } else if (range_end == num_blocks) {
- // Done with this extent.
- idx++;
- } else {
- return false;
- }
-
- *idx_p = idx;
- return true;
-}
-
-// Remove identical corresponding block ranges in |src_extents| and
-// |dst_extents|. Used for preventing moving of blocks onto themselves during
-// MOVE operations. The value of |total_bytes| indicates the actual length of
-// content; this may be slightly less than the total size of blocks, in which
-// case the last block is only partly occupied with data. Returns the total
-// number of bytes removed.
-size_t RemoveIdenticalBlockRanges(vector<Extent>* src_extents,
- vector<Extent>* dst_extents,
- const size_t total_bytes) {
- size_t src_idx = 0;
- size_t dst_idx = 0;
- uint64_t src_offset = 0, dst_offset = 0;
- size_t removed_bytes = 0, nonfull_block_bytes;
- bool do_remove = false;
- while (src_idx < src_extents->size() && dst_idx < dst_extents->size()) {
- do_remove = ((*src_extents)[src_idx].start_block() + src_offset ==
- (*dst_extents)[dst_idx].start_block() + dst_offset);
-
- uint64_t src_num_blocks = (*src_extents)[src_idx].num_blocks();
- uint64_t dst_num_blocks = (*dst_extents)[dst_idx].num_blocks();
- uint64_t min_num_blocks =
- std::min(src_num_blocks - src_offset, dst_num_blocks - dst_offset);
- uint64_t prev_src_offset = src_offset;
- uint64_t prev_dst_offset = dst_offset;
- src_offset += min_num_blocks;
- dst_offset += min_num_blocks;
-
- bool new_src = ProcessExtentBlockRange(
- src_extents, &src_idx, do_remove, prev_src_offset, src_offset);
- bool new_dst = ProcessExtentBlockRange(
- dst_extents, &dst_idx, do_remove, prev_dst_offset, dst_offset);
- if (new_src) {
- src_offset = 0;
- }
- if (new_dst) {
- dst_offset = 0;
- }
-
- if (do_remove)
- removed_bytes += min_num_blocks * kBlockSize;
- }
-
- // If we removed the last block and this block is only partly used by file
- // content, deduct the unused portion from the total removed byte count.
- if (do_remove && (nonfull_block_bytes = total_bytes % kBlockSize))
- removed_bytes -= kBlockSize - nonfull_block_bytes;
-
- return removed_bytes;
-}
-
// Storing a diff operation has more overhead over replace operation in the
// manifest, we need to store an additional src_sha256_hash which is 32 bytes
// and not compressible, and also src_extents which could use anywhere from a
@@ -318,13 +221,11 @@
return;
}
- if (!version_.InplaceUpdate()) {
- if (!ABGenerator::FragmentOperations(
- version_, &file_aops_, new_part_, blob_file_)) {
- LOG(ERROR) << "Failed to fragment operations for " << name_;
- failed_ = true;
- return;
- }
+ if (!ABGenerator::FragmentOperations(
+ version_, &file_aops_, new_part_, blob_file_)) {
+ LOG(ERROR) << "Failed to fragment operations for " << name_;
+ failed_ = true;
+ return;
}
LOG(INFO) << "Encoded file " << name_ << " (" << new_extents_blocks_
@@ -447,12 +348,8 @@
// from the same source blocks. At that time, this code can die. -adlr
FilesystemInterface::File old_file =
GetOldFile(old_files_map, new_file.name);
- vector<Extent> old_file_extents;
- if (version.InplaceUpdate())
- old_file_extents =
- FilterExtentRanges(old_file.extents, old_visited_blocks);
- else
- old_file_extents = FilterExtentRanges(old_file.extents, old_zero_blocks);
+ auto old_file_extents =
+ FilterExtentRanges(old_file.extents, old_zero_blocks);
old_visited_blocks.AddExtents(old_file_extents);
file_delta_processors.emplace_back(old_part.path,
@@ -541,21 +438,6 @@
&old_block_ids,
&new_block_ids));
- // If the update is inplace, we map all the blocks that didn't move,
- // regardless of the contents since they are already copied and no operation
- // is required.
- if (version.InplaceUpdate()) {
- uint64_t num_blocks = std::min(old_num_blocks, new_num_blocks);
- for (uint64_t block = 0; block < num_blocks; block++) {
- if (old_block_ids[block] == new_block_ids[block] &&
- !old_visited_blocks->ContainsBlock(block) &&
- !new_visited_blocks->ContainsBlock(block)) {
- old_visited_blocks->AddBlock(block);
- new_visited_blocks->AddBlock(block);
- }
- }
- }
-
// A mapping from the block_id to the list of block numbers with that block id
// in the old partition. This is used to lookup where in the old partition
// is a block from the new partition.
@@ -602,10 +484,6 @@
AppendBlockToExtents(&old_identical_blocks,
old_blocks_map_it->second.back());
AppendBlockToExtents(&new_identical_blocks, block);
- // We can't reuse source blocks in minor version 1 because the cycle
- // breaking algorithm used in the in-place update doesn't support that.
- if (version.InplaceUpdate())
- old_blocks_map_it->second.pop_back();
}
if (chunk_blocks == -1)
@@ -657,9 +535,7 @@
aops->emplace_back();
AnnotatedOperation* aop = &aops->back();
aop->name = "<identical-blocks>";
- aop->op.set_type(version.OperationAllowed(InstallOperation::SOURCE_COPY)
- ? InstallOperation::SOURCE_COPY
- : InstallOperation::MOVE);
+ aop->op.set_type(InstallOperation::SOURCE_COPY);
uint64_t chunk_num_blocks =
std::min(static_cast<uint64_t>(extent.num_blocks()) - op_block_offset,
@@ -732,13 +608,8 @@
// Check if the operation writes nothing.
if (operation.dst_extents_size() == 0) {
- if (operation.type() == InstallOperation::MOVE) {
- LOG(INFO) << "Empty MOVE operation (" << name << "), skipping";
- continue;
- } else {
- LOG(ERROR) << "Empty non-MOVE operation";
- return false;
- }
+ LOG(ERROR) << "Empty non-MOVE operation";
+ return false;
}
// Now, insert into the list of operations.
@@ -828,8 +699,7 @@
// Disable bsdiff, and puffdiff when the data is too big.
bool bsdiff_allowed =
- version.OperationAllowed(InstallOperation::SOURCE_BSDIFF) ||
- version.OperationAllowed(InstallOperation::BSDIFF);
+ version.OperationAllowed(InstallOperation::SOURCE_BSDIFF);
if (bsdiff_allowed &&
blocks_to_read * kBlockSize > kMaxBsdiffDestinationSize) {
LOG(INFO) << "bsdiff blacklisted, data too big: "
@@ -878,9 +748,7 @@
kBlockSize));
if (old_data == new_data) {
// No change in data.
- operation.set_type(version.OperationAllowed(InstallOperation::SOURCE_COPY)
- ? InstallOperation::SOURCE_COPY
- : InstallOperation::MOVE);
+ operation.set_type(InstallOperation::SOURCE_COPY);
data_blob = brillo::Blob();
} else if (IsDiffOperationBetter(
operation, data_blob.size(), 0, src_extents.size())) {
@@ -892,7 +760,7 @@
ScopedPathUnlinker unlinker(patch.value());
std::unique_ptr<bsdiff::PatchWriterInterface> bsdiff_patch_writer;
- InstallOperation_Type operation_type = InstallOperation::BSDIFF;
+ InstallOperation_Type operation_type = InstallOperation::SOURCE_BSDIFF;
if (version.OperationAllowed(InstallOperation::BROTLI_BSDIFF)) {
bsdiff_patch_writer =
bsdiff::CreateBSDF2PatchWriter(patch.value(),
@@ -901,9 +769,6 @@
operation_type = InstallOperation::BROTLI_BSDIFF;
} else {
bsdiff_patch_writer = bsdiff::CreateBsdiffPatchWriter(patch.value());
- if (version.OperationAllowed(InstallOperation::SOURCE_BSDIFF)) {
- operation_type = InstallOperation::SOURCE_BSDIFF;
- }
}
brillo::Blob bsdiff_delta;
@@ -976,23 +841,14 @@
}
}
- // Remove identical src/dst block ranges in MOVE operations.
- if (operation.type() == InstallOperation::MOVE) {
- auto removed_bytes =
- RemoveIdenticalBlockRanges(&src_extents, &dst_extents, new_data.size());
- operation.set_src_length(old_data.size() - removed_bytes);
- operation.set_dst_length(new_data.size() - removed_bytes);
- }
-
// WARNING: We always set legacy |src_length| and |dst_length| fields for
// BSDIFF. For SOURCE_BSDIFF we only set them for minor version 3 and
// lower. This is needed because we used to use these two parameters in the
// SOURCE_BSDIFF for minor version 3 and lower, but we do not need them
// anymore in higher minor versions. This means if we stop adding these
// parameters for those minor versions, the delta payloads will be invalid.
- if (operation.type() == InstallOperation::BSDIFF ||
- (operation.type() == InstallOperation::SOURCE_BSDIFF &&
- version.minor <= kOpSrcHashMinorPayloadVersion)) {
+ if (operation.type() == InstallOperation::SOURCE_BSDIFF &&
+ version.minor <= kOpSrcHashMinorPayloadVersion) {
operation.set_src_length(old_data.size());
operation.set_dst_length(new_data.size());
}
@@ -1021,22 +877,6 @@
op_type == InstallOperation::DISCARD);
}
-// Returns true if |op| is a no-op operation that doesn't do any useful work
-// (e.g., a move operation that copies blocks onto themselves).
-bool IsNoopOperation(const InstallOperation& op) {
- return (op.type() == InstallOperation::MOVE &&
- ExpandExtents(op.src_extents()) == ExpandExtents(op.dst_extents()));
-}
-
-void FilterNoopOperations(vector<AnnotatedOperation>* ops) {
- ops->erase(std::remove_if(ops->begin(),
- ops->end(),
- [](const AnnotatedOperation& aop) {
- return IsNoopOperation(aop.op);
- }),
- ops->end());
-}
-
bool InitializePartitionInfo(const PartitionConfig& part, PartitionInfo* info) {
info->set_size(part.size);
HashCalculator hasher;
diff --git a/payload_generator/delta_diff_utils.h b/payload_generator/delta_diff_utils.h
index 2306572..a062327 100644
--- a/payload_generator/delta_diff_utils.h
+++ b/payload_generator/delta_diff_utils.h
@@ -127,14 +127,6 @@
// Returns true if an operation with type |op_type| has no |src_extents|.
bool IsNoSourceOperation(InstallOperation_Type op_type);
-// Returns true if |op| is a no-op operation that doesn't do any useful work
-// (e.g., a move operation that copies blocks onto themselves).
-bool IsNoopOperation(const InstallOperation& op);
-
-// Filters all the operations that are no-op, maintaining the relative order
-// of the rest of the operations.
-void FilterNoopOperations(std::vector<AnnotatedOperation>* ops);
-
bool InitializePartitionInfo(const PartitionConfig& partition,
PartitionInfo* info);
diff --git a/payload_generator/delta_diff_utils_unittest.cc b/payload_generator/delta_diff_utils_unittest.cc
index f730cc9..e25c867 100644
--- a/payload_generator/delta_diff_utils_unittest.cc
+++ b/payload_generator/delta_diff_utils_unittest.cc
@@ -194,164 +194,6 @@
}
}
-TEST_F(DeltaDiffUtilsTest, MoveSmallTest) {
- brillo::Blob data_blob(block_size_);
- test_utils::FillWithData(&data_blob);
-
- // The old file is on a different block than the new one.
- vector<Extent> old_extents = {ExtentForRange(11, 1)};
- vector<Extent> new_extents = {ExtentForRange(1, 1)};
-
- EXPECT_TRUE(WriteExtents(old_part_.path, old_extents, kBlockSize, data_blob));
- EXPECT_TRUE(WriteExtents(new_part_.path, new_extents, kBlockSize, data_blob));
-
- brillo::Blob data;
- InstallOperation op;
- EXPECT_TRUE(diff_utils::ReadExtentsToDiff(
- old_part_.path,
- new_part_.path,
- old_extents,
- new_extents,
- {}, // old_deflates
- {}, // new_deflates
- PayloadVersion(kChromeOSMajorPayloadVersion, kInPlaceMinorPayloadVersion),
- &data,
- &op));
- EXPECT_TRUE(data.empty());
-
- EXPECT_TRUE(op.has_type());
- EXPECT_EQ(InstallOperation::MOVE, op.type());
- EXPECT_FALSE(op.has_data_offset());
- EXPECT_FALSE(op.has_data_length());
- EXPECT_EQ(1, op.src_extents_size());
- EXPECT_EQ(kBlockSize, op.src_length());
- EXPECT_EQ(1, op.dst_extents_size());
- EXPECT_EQ(kBlockSize, op.dst_length());
- EXPECT_EQ(utils::BlocksInExtents(op.src_extents()),
- utils::BlocksInExtents(op.dst_extents()));
- EXPECT_EQ(1U, utils::BlocksInExtents(op.dst_extents()));
-}
-
-TEST_F(DeltaDiffUtilsTest, MoveWithSameBlock) {
- // Setup the old/new files so that it has immobile chunks; we make sure to
- // utilize all sub-cases of such chunks: blocks 21--22 induce a split (src)
- // and complete removal (dst), whereas blocks 24--25 induce trimming of the
- // tail (src) and head (dst) of extents. The final block (29) is used for
- // ensuring we properly account for the number of bytes removed in cases where
- // the last block is partly filled. The detailed configuration:
- //
- // Old: [ 20 21 22 23 24 25 ] [ 28 29 ]
- // New: [ 18 ] [ 21 22 ] [ 20 ] [ 24 25 26 ] [ 29 ]
- // Same: ^^ ^^ ^^ ^^ ^^
- vector<Extent> old_extents = {ExtentForRange(20, 6), ExtentForRange(28, 2)};
- vector<Extent> new_extents = {ExtentForRange(18, 1),
- ExtentForRange(21, 2),
- ExtentForRange(20, 1),
- ExtentForRange(24, 3),
- ExtentForRange(29, 1)};
-
- uint64_t num_blocks = utils::BlocksInExtents(old_extents);
- EXPECT_EQ(num_blocks, utils::BlocksInExtents(new_extents));
-
- // The size of the data should match the total number of blocks. Each block
- // has a different content.
- brillo::Blob file_data;
- for (uint64_t i = 0; i < num_blocks; ++i) {
- file_data.resize(file_data.size() + kBlockSize, 'a' + i);
- }
-
- EXPECT_TRUE(WriteExtents(old_part_.path, old_extents, kBlockSize, file_data));
- EXPECT_TRUE(WriteExtents(new_part_.path, new_extents, kBlockSize, file_data));
-
- brillo::Blob data;
- InstallOperation op;
- EXPECT_TRUE(diff_utils::ReadExtentsToDiff(
- old_part_.path,
- new_part_.path,
- old_extents,
- new_extents,
- {}, // old_deflates
- {}, // new_deflates
- PayloadVersion(kChromeOSMajorPayloadVersion, kInPlaceMinorPayloadVersion),
- &data,
- &op));
-
- EXPECT_TRUE(data.empty());
-
- EXPECT_TRUE(op.has_type());
- EXPECT_EQ(InstallOperation::MOVE, op.type());
- EXPECT_FALSE(op.has_data_offset());
- EXPECT_FALSE(op.has_data_length());
-
- // The expected old and new extents that actually moved. See comment above.
- old_extents = {
- ExtentForRange(20, 1), ExtentForRange(23, 1), ExtentForRange(28, 1)};
- new_extents = {
- ExtentForRange(18, 1), ExtentForRange(20, 1), ExtentForRange(26, 1)};
- num_blocks = utils::BlocksInExtents(old_extents);
-
- EXPECT_EQ(num_blocks * kBlockSize, op.src_length());
- EXPECT_EQ(num_blocks * kBlockSize, op.dst_length());
-
- EXPECT_EQ(old_extents.size(), static_cast<size_t>(op.src_extents_size()));
- for (int i = 0; i < op.src_extents_size(); i++) {
- EXPECT_EQ(old_extents[i].start_block(), op.src_extents(i).start_block())
- << "i == " << i;
- EXPECT_EQ(old_extents[i].num_blocks(), op.src_extents(i).num_blocks())
- << "i == " << i;
- }
-
- EXPECT_EQ(new_extents.size(), static_cast<size_t>(op.dst_extents_size()));
- for (int i = 0; i < op.dst_extents_size(); i++) {
- EXPECT_EQ(new_extents[i].start_block(), op.dst_extents(i).start_block())
- << "i == " << i;
- EXPECT_EQ(new_extents[i].num_blocks(), op.dst_extents(i).num_blocks())
- << "i == " << i;
- }
-}
-
-TEST_F(DeltaDiffUtilsTest, BsdiffSmallTest) {
- // Test a BSDIFF operation from block 1 to block 2.
- brillo::Blob data_blob(kBlockSize);
- test_utils::FillWithData(&data_blob);
-
- // The old file is on a different block than the new one.
- vector<Extent> old_extents = {ExtentForRange(1, 1)};
- vector<Extent> new_extents = {ExtentForRange(2, 1)};
-
- EXPECT_TRUE(WriteExtents(old_part_.path, old_extents, kBlockSize, data_blob));
- // Modify one byte in the new file.
- data_blob[0]++;
- EXPECT_TRUE(WriteExtents(new_part_.path, new_extents, kBlockSize, data_blob));
-
- brillo::Blob data;
- InstallOperation op;
- EXPECT_TRUE(diff_utils::ReadExtentsToDiff(
- old_part_.path,
- new_part_.path,
- old_extents,
- new_extents,
- {}, // old_deflates
- {}, // new_deflates
- PayloadVersion(kChromeOSMajorPayloadVersion, kInPlaceMinorPayloadVersion),
- &data,
- &op));
-
- EXPECT_FALSE(data.empty());
-
- EXPECT_TRUE(op.has_type());
- EXPECT_EQ(InstallOperation::BSDIFF, op.type());
- EXPECT_FALSE(op.has_data_offset());
- EXPECT_FALSE(op.has_data_length());
- EXPECT_EQ(1, op.src_extents_size());
- EXPECT_EQ(kBlockSize, op.src_length());
- EXPECT_EQ(1, op.dst_extents_size());
- EXPECT_EQ(kBlockSize, op.dst_length());
- EXPECT_EQ(utils::BlocksInExtents(op.src_extents()),
- utils::BlocksInExtents(op.dst_extents()));
- EXPECT_EQ(1U, utils::BlocksInExtents(op.dst_extents()));
-}
-
TEST_F(DeltaDiffUtilsTest, ReplaceSmallTest) {
// The old file is on a different block than the new one.
vector<Extent> old_extents = {ExtentForRange(1, 1)};
@@ -384,7 +226,7 @@
{}, // old_deflates
{}, // new_deflates
PayloadVersion(kChromeOSMajorPayloadVersion,
- kInPlaceMinorPayloadVersion),
+ kSourceMinorPayloadVersion),
&data,
&op));
EXPECT_FALSE(data.empty());
@@ -500,49 +342,6 @@
EXPECT_EQ(InstallOperation::REPLACE_BZ, op.type());
}
-TEST_F(DeltaDiffUtilsTest, IsNoopOperationTest) {
- InstallOperation op;
- op.set_type(InstallOperation::REPLACE_BZ);
- EXPECT_FALSE(diff_utils::IsNoopOperation(op));
- op.set_type(InstallOperation::MOVE);
- EXPECT_TRUE(diff_utils::IsNoopOperation(op));
- *(op.add_src_extents()) = ExtentForRange(3, 2);
- *(op.add_dst_extents()) = ExtentForRange(3, 2);
- EXPECT_TRUE(diff_utils::IsNoopOperation(op));
- *(op.add_src_extents()) = ExtentForRange(7, 5);
- *(op.add_dst_extents()) = ExtentForRange(7, 5);
- EXPECT_TRUE(diff_utils::IsNoopOperation(op));
- *(op.add_src_extents()) = ExtentForRange(20, 2);
- *(op.add_dst_extents()) = ExtentForRange(20, 1);
- *(op.add_dst_extents()) = ExtentForRange(21, 1);
- EXPECT_TRUE(diff_utils::IsNoopOperation(op));
- *(op.add_src_extents()) = ExtentForRange(24, 1);
- *(op.add_dst_extents()) = ExtentForRange(25, 1);
- EXPECT_FALSE(diff_utils::IsNoopOperation(op));
-}
-
-TEST_F(DeltaDiffUtilsTest, FilterNoopOperations) {
- AnnotatedOperation aop1;
- aop1.op.set_type(InstallOperation::REPLACE_BZ);
- *(aop1.op.add_dst_extents()) = ExtentForRange(3, 2);
- aop1.name = "aop1";
-
- AnnotatedOperation aop2 = aop1;
- aop2.name = "aop2";
-
- AnnotatedOperation noop;
- noop.op.set_type(InstallOperation::MOVE);
- *(noop.op.add_src_extents()) = ExtentForRange(3, 2);
- *(noop.op.add_dst_extents()) = ExtentForRange(3, 2);
- noop.name = "noop";
-
- vector<AnnotatedOperation> ops = {noop, aop1, noop, noop, aop2, noop};
- diff_utils::FilterNoopOperations(&ops);
- EXPECT_EQ(2u, ops.size());
- EXPECT_EQ("aop1", ops[0].name);
- EXPECT_EQ("aop2", ops[1].name);
-}
-
// Test the simple case where all the blocks are different and no new blocks are
// zeroed.
TEST_F(DeltaDiffUtilsTest, NoZeroedOrUniqueBlocksDetected) {
@@ -550,7 +349,7 @@
InitializePartitionWithUniqueBlocks(new_part_, block_size_, 42);
EXPECT_TRUE(RunDeltaMovedAndZeroBlocks(-1, // chunk_blocks
- kInPlaceMinorPayloadVersion));
+ kSourceMinorPayloadVersion));
EXPECT_EQ(0U, old_visited_blocks_.blocks());
EXPECT_EQ(0U, new_visited_blocks_.blocks());
@@ -558,29 +357,6 @@
EXPECT_TRUE(aops_.empty());
}
-// Test that when the partitions have identical blocks in the same positions no
-// MOVE operation is performed and all the blocks are handled.
-TEST_F(DeltaDiffUtilsTest, IdenticalPartitionsDontMove) {
- InitializePartitionWithUniqueBlocks(old_part_, block_size_, 42);
- InitializePartitionWithUniqueBlocks(new_part_, block_size_, 42);
-
- // Mark some of the blocks as already visited.
- vector<Extent> already_visited = {ExtentForRange(5, 10),
- ExtentForRange(25, 10)};
- old_visited_blocks_.AddExtents(already_visited);
- new_visited_blocks_.AddExtents(already_visited);
-
- // Most of the blocks rest in the same place, but there's no need for MOVE
- // operations on those blocks.
- EXPECT_TRUE(RunDeltaMovedAndZeroBlocks(-1, // chunk_blocks
- kInPlaceMinorPayloadVersion));
-
- EXPECT_EQ(kDefaultBlockCount, old_visited_blocks_.blocks());
- EXPECT_EQ(kDefaultBlockCount, new_visited_blocks_.blocks());
- EXPECT_EQ(0, blob_size_);
- EXPECT_TRUE(aops_.empty());
-}
-
// Test that when the partitions have identical blocks in the same positions
// MOVE operation is performed and all the blocks are handled.
TEST_F(DeltaDiffUtilsTest, IdenticalBlocksAreCopiedFromSource) {
@@ -701,16 +477,14 @@
EXPECT_TRUE(WriteExtents(old_part_.path, old_zeros, block_size_, zeros_data));
EXPECT_TRUE(RunDeltaMovedAndZeroBlocks(5, // chunk_blocks
- kInPlaceMinorPayloadVersion));
+ kSourceMinorPayloadVersion));
- // Zeroed blocks from old_visited_blocks_ were copied over, so me actually
- // use them regardless of the trivial MOVE operation not being emitted.
+ // Zeroed blocks from |old_visited_blocks_| were copied over.
EXPECT_EQ(old_zeros,
old_visited_blocks_.GetExtentsForBlockCount(
old_visited_blocks_.blocks()));
- // All the new zeroed blocks should be used, part with REPLACE_BZ and part
- // trivial MOVE operations (not included).
+ // All the new zeroed blocks should be used with REPLACE_BZ.
EXPECT_EQ(new_zeros,
new_visited_blocks_.GetExtentsForBlockCount(
new_visited_blocks_.blocks()));
@@ -721,7 +495,8 @@
// This range should be split.
ExtentForRange(30, 5),
ExtentForRange(35, 5),
- ExtentForRange(40, 3),
+ ExtentForRange(40, 5),
+ ExtentForRange(45, 5),
};
EXPECT_EQ(expected_op_extents.size(), aops_.size());
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index ddb9a35..16f360f 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -642,7 +642,6 @@
// Autodetect minor_version by looking at the update_engine.conf in the old
// image.
if (payload_config.is_delta) {
- payload_config.version.minor = kInPlaceMinorPayloadVersion;
brillo::KeyValueStore store;
uint32_t minor_version;
bool minor_version_found = false;
@@ -656,9 +655,10 @@
break;
}
}
- LOG_IF(WARNING, !minor_version_found)
- << "Failed to detect minor version defaulting to minor_version="
- << payload_config.version.minor;
+ if (!minor_version_found) {
+ LOG(FATAL) << "Failed to detect the minor version.";
+ return 1;
+ }
} else {
payload_config.version.minor = kFullPayloadMinorVersion;
LOG(INFO) << "Using non-delta minor_version="
@@ -669,6 +669,13 @@
LOG(INFO) << "Using provided minor_version=" << FLAGS_minor_version;
}
+ if (payload_config.version.minor != kFullPayloadMinorVersion &&
+ (payload_config.version.minor < kMinSupportedMinorPayloadVersion ||
+ payload_config.version.minor > kMaxSupportedMinorPayloadVersion)) {
+ LOG(FATAL) << "Unsupported minor version " << payload_config.version.minor;
+ return 1;
+ }
+
payload_config.max_timestamp = FLAGS_max_timestamp;
if (payload_config.version.minor >= kVerityMinorPayloadVersion)
diff --git a/payload_generator/graph_types.cc b/payload_generator/graph_types.cc
deleted file mode 100644
index c03766d..0000000
--- a/payload_generator/graph_types.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/graph_types.h"
-
-namespace chromeos_update_engine {
-
-const Vertex::Index Vertex::kInvalidIndex = static_cast<Vertex::Index>(-1);
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/graph_types.h b/payload_generator/graph_types.h
deleted file mode 100644
index f96b0f3..0000000
--- a/payload_generator/graph_types.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_TYPES_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_TYPES_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/macros.h>
-
-#include "update_engine/payload_generator/annotated_operation.h"
-#include "update_engine/payload_generator/extent_utils.h"
-#include "update_engine/update_metadata.pb.h"
-
-// A few classes that help in generating delta images use these types
-// for the graph work.
-
-namespace chromeos_update_engine {
-
-struct EdgeProperties {
- // Read-before extents. I.e., blocks in |extents| must be read by the
- // node pointed to before the pointing node runs (presumably b/c it
- // overwrites these blocks).
- std::vector<Extent> extents;
-
- // Write before extents. I.e., blocks in |write_extents| must be written
- // by the node pointed to before the pointing node runs (presumably
- // b/c it reads the data written by the other node).
- std::vector<Extent> write_extents;
-
- bool operator==(const EdgeProperties& that) const {
- return extents == that.extents && write_extents == that.write_extents;
- }
-};
-
-struct Vertex {
- Vertex() : valid(true), index(-1), lowlink(-1) {}
- bool valid;
-
- typedef std::map<std::vector<Vertex>::size_type, EdgeProperties> EdgeMap;
- EdgeMap out_edges;
-
- // We sometimes wish to consider a subgraph of a graph. A subgraph would have
- // a subset of the vertices from the graph and a subset of the edges.
- // When considering this vertex within a subgraph, subgraph_edges stores
- // the out-edges.
- typedef std::set<std::vector<Vertex>::size_type> SubgraphEdgeMap;
- SubgraphEdgeMap subgraph_edges;
-
- // For Tarjan's algorithm:
- std::vector<Vertex>::size_type index;
- std::vector<Vertex>::size_type lowlink;
-
- // Other Vertex properties:
- AnnotatedOperation aop;
-
- typedef std::vector<Vertex>::size_type Index;
- static const Vertex::Index kInvalidIndex;
-};
-
-typedef std::vector<Vertex> Graph;
-
-typedef std::pair<Vertex::Index, Vertex::Index> Edge;
-
-const uint64_t kTempBlockStart = 1ULL << 60;
-static_assert(kTempBlockStart != 0, "kTempBlockStart invalid");
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_TYPES_H_
diff --git a/payload_generator/graph_utils.cc b/payload_generator/graph_utils.cc
deleted file mode 100644
index 7f5cf8f..0000000
--- a/payload_generator/graph_utils.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/graph_utils.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/logging.h>
-#include <base/macros.h>
-
-#include "update_engine/payload_consumer/payload_constants.h"
-#include "update_engine/payload_generator/annotated_operation.h"
-#include "update_engine/payload_generator/extent_utils.h"
-
-using std::make_pair;
-using std::pair;
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-namespace graph_utils {
-
-uint64_t EdgeWeight(const Graph& graph, const Edge& edge) {
- uint64_t weight = 0;
- const vector<Extent>& extents =
- graph[edge.first].out_edges.find(edge.second)->second.extents;
- for (vector<Extent>::const_iterator it = extents.begin(); it != extents.end();
- ++it) {
- if (it->start_block() != kSparseHole)
- weight += it->num_blocks();
- }
- return weight;
-}
-
-void AddReadBeforeDep(Vertex* src, Vertex::Index dst, uint64_t block) {
- Vertex::EdgeMap::iterator edge_it = src->out_edges.find(dst);
- if (edge_it == src->out_edges.end()) {
- // Must create new edge
- pair<Vertex::EdgeMap::iterator, bool> result =
- src->out_edges.insert(make_pair(dst, EdgeProperties()));
- CHECK(result.second);
- edge_it = result.first;
- }
- AppendBlockToExtents(&edge_it->second.extents, block);
-}
-
-void AddReadBeforeDepExtents(Vertex* src,
- Vertex::Index dst,
- const vector<Extent>& extents) {
- // TODO(adlr): Be more efficient than adding each block individually.
- for (vector<Extent>::const_iterator it = extents.begin(), e = extents.end();
- it != e;
- ++it) {
- const Extent& extent = *it;
- for (uint64_t block = extent.start_block(),
- block_end = extent.start_block() + extent.num_blocks();
- block != block_end;
- ++block) {
- AddReadBeforeDep(src, dst, block);
- }
- }
-}
-
-void DropWriteBeforeDeps(Vertex::EdgeMap* edge_map) {
- // Specially crafted for-loop for the map-iterate-delete dance.
- for (Vertex::EdgeMap::iterator it = edge_map->begin();
- it != edge_map->end();) {
- if (!it->second.write_extents.empty())
- it->second.write_extents.clear();
- if (it->second.extents.empty()) {
- // Erase *it, as it contains no blocks
- edge_map->erase(it++);
- } else {
- ++it;
- }
- }
-}
-
-// For each node N in graph, drop all edges N->|index|.
-void DropIncomingEdgesTo(Graph* graph, Vertex::Index index) {
- // This would be much more efficient if we had doubly-linked
- // edges in the graph.
- for (Graph::iterator it = graph->begin(), e = graph->end(); it != e; ++it) {
- it->out_edges.erase(index);
- }
-}
-
-namespace {
-template <typename T>
-void DumpExtents(const T& field, int prepend_space_count) {
- string header(prepend_space_count, ' ');
- for (const auto& extent : field) {
- LOG(INFO) << header << "(" << extent.start_block() << ", "
- << extent.num_blocks() << ")";
- }
-}
-
-void DumpOutEdges(const Vertex::EdgeMap& out_edges) {
- for (Vertex::EdgeMap::const_iterator it = out_edges.begin(),
- e = out_edges.end();
- it != e;
- ++it) {
- LOG(INFO) << " " << it->first << " read-before:";
- DumpExtents(it->second.extents, 6);
- LOG(INFO) << " write-before:";
- DumpExtents(it->second.write_extents, 6);
- }
-}
-} // namespace
-
-void DumpGraph(const Graph& graph) {
- LOG(INFO) << "Graph length: " << graph.size();
- for (Graph::size_type i = 0, e = graph.size(); i != e; ++i) {
- LOG(INFO) << i << (graph[i].valid ? "" : "-INV") << ": "
- << graph[i].aop.name << ": "
- << InstallOperationTypeName(graph[i].aop.op.type());
- LOG(INFO) << " src_extents:";
- DumpExtents(graph[i].aop.op.src_extents(), 4);
- LOG(INFO) << " dst_extents:";
- DumpExtents(graph[i].aop.op.dst_extents(), 4);
- LOG(INFO) << " out edges:";
- DumpOutEdges(graph[i].out_edges);
- }
-}
-
-} // namespace graph_utils
-} // namespace chromeos_update_engine
diff --git a/payload_generator/graph_utils.h b/payload_generator/graph_utils.h
deleted file mode 100644
index 7024215..0000000
--- a/payload_generator/graph_utils.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_UTILS_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_UTILS_H_
-
-#include <vector>
-
-#include <base/macros.h>
-
-#include "update_engine/payload_generator/graph_types.h"
-#include "update_engine/update_metadata.pb.h"
-
-// A few utility functions for graphs
-
-namespace chromeos_update_engine {
-
-namespace graph_utils {
-
-// Returns the number of blocks represented by all extents in the edge.
-uint64_t EdgeWeight(const Graph& graph, const Edge& edge);
-
-// These add a read-before dependency from graph[src] -> graph[dst]. If the dep
-// already exists, the block/s is/are added to the existing edge.
-void AddReadBeforeDep(Vertex* src, Vertex::Index dst, uint64_t block);
-void AddReadBeforeDepExtents(Vertex* src,
- Vertex::Index dst,
- const std::vector<Extent>& extents);
-
-void DropWriteBeforeDeps(Vertex::EdgeMap* edge_map);
-
-// For each node N in graph, drop all edges N->|index|.
-void DropIncomingEdgesTo(Graph* graph, Vertex::Index index);
-
-void DumpGraph(const Graph& graph);
-
-} // namespace graph_utils
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_GRAPH_UTILS_H_
diff --git a/payload_generator/graph_utils_unittest.cc b/payload_generator/graph_utils_unittest.cc
deleted file mode 100644
index 07e7664..0000000
--- a/payload_generator/graph_utils_unittest.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/graph_utils.h"
-
-#include <utility>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "update_engine/payload_consumer/payload_constants.h"
-#include "update_engine/payload_generator/extent_ranges.h"
-#include "update_engine/payload_generator/extent_utils.h"
-
-using std::make_pair;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-class GraphUtilsTest : public ::testing::Test {};
-
-TEST(GraphUtilsTest, SimpleTest) {
- Graph graph(2);
-
- graph[0].out_edges.insert(make_pair(1, EdgeProperties()));
-
- vector<Extent>& extents = graph[0].out_edges[1].extents;
-
- EXPECT_EQ(0U, extents.size());
- AppendBlockToExtents(&extents, 0);
- EXPECT_EQ(1U, extents.size());
- AppendBlockToExtents(&extents, 1);
- AppendBlockToExtents(&extents, 2);
- EXPECT_EQ(1U, extents.size());
- AppendBlockToExtents(&extents, 4);
-
- EXPECT_EQ(2U, extents.size());
- EXPECT_EQ(0U, extents[0].start_block());
- EXPECT_EQ(3U, extents[0].num_blocks());
- EXPECT_EQ(4U, extents[1].start_block());
- EXPECT_EQ(1U, extents[1].num_blocks());
-
- EXPECT_EQ(4U, graph_utils::EdgeWeight(graph, make_pair(0, 1)));
-}
-
-TEST(GraphUtilsTest, DepsTest) {
- Graph graph(3);
-
- graph_utils::AddReadBeforeDep(&graph[0], 1, 3);
- EXPECT_EQ(1U, graph[0].out_edges.size());
- {
- Extent& extent = graph[0].out_edges[1].extents[0];
- EXPECT_EQ(3U, extent.start_block());
- EXPECT_EQ(1U, extent.num_blocks());
- }
- graph_utils::AddReadBeforeDep(&graph[0], 1, 4);
- EXPECT_EQ(1U, graph[0].out_edges.size());
- {
- Extent& extent = graph[0].out_edges[1].extents[0];
- EXPECT_EQ(3U, extent.start_block());
- EXPECT_EQ(2U, extent.num_blocks());
- }
- graph_utils::AddReadBeforeDepExtents(
- &graph[2], 1, vector<Extent>(1, ExtentForRange(5, 2)));
- EXPECT_EQ(1U, graph[2].out_edges.size());
- {
- Extent& extent = graph[2].out_edges[1].extents[0];
- EXPECT_EQ(5U, extent.start_block());
- EXPECT_EQ(2U, extent.num_blocks());
- }
- // Change most recent edge from read-before to write-before
- graph[2].out_edges[1].write_extents.swap(graph[2].out_edges[1].extents);
- graph_utils::DropWriteBeforeDeps(&graph[2].out_edges);
- EXPECT_EQ(0U, graph[2].out_edges.size());
-
- EXPECT_EQ(1U, graph[0].out_edges.size());
- graph_utils::DropIncomingEdgesTo(&graph, 1);
- EXPECT_EQ(0U, graph[0].out_edges.size());
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/inplace_generator.cc b/payload_generator/inplace_generator.cc
deleted file mode 100644
index ee19b62..0000000
--- a/payload_generator/inplace_generator.cc
+++ /dev/null
@@ -1,798 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/inplace_generator.h"
-
-#include <algorithm>
-#include <map>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/stl_util.h>
-
-#include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/payload_constants.h"
-#include "update_engine/payload_generator/cycle_breaker.h"
-#include "update_engine/payload_generator/delta_diff_generator.h"
-#include "update_engine/payload_generator/delta_diff_utils.h"
-#include "update_engine/payload_generator/extent_ranges.h"
-#include "update_engine/payload_generator/graph_types.h"
-#include "update_engine/payload_generator/graph_utils.h"
-#include "update_engine/payload_generator/topological_sort.h"
-#include "update_engine/update_metadata.pb.h"
-
-using std::make_pair;
-using std::map;
-using std::pair;
-using std::set;
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-using Block = InplaceGenerator::Block;
-
-namespace {
-
-// The only PayloadVersion supported by this implementation.
-const PayloadVersion kInPlacePayloadVersion{kChromeOSMajorPayloadVersion,
- kInPlaceMinorPayloadVersion};
-
-// This class allocates non-existent temp blocks, starting from
-// kTempBlockStart. Other code is responsible for converting these
-// temp blocks into real blocks, as the client can't read or write to
-// these blocks.
-class DummyExtentAllocator {
- public:
- vector<Extent> Allocate(const uint64_t block_count) {
- vector<Extent> ret(1);
- ret[0].set_start_block(next_block_);
- ret[0].set_num_blocks(block_count);
- next_block_ += block_count;
- return ret;
- }
-
- private:
- uint64_t next_block_{kTempBlockStart};
-};
-
-// Takes a vector of blocks and returns an equivalent vector of Extent
-// objects.
-vector<Extent> CompressExtents(const vector<uint64_t>& blocks) {
- vector<Extent> new_extents;
- for (uint64_t block : blocks) {
- AppendBlockToExtents(&new_extents, block);
- }
- return new_extents;
-}
-
-// Helper class to compare two operations by start block of the first Extent in
-// their destination extents given the index of the operations in the graph.
-class IndexedInstallOperationsDstComparator {
- public:
- explicit IndexedInstallOperationsDstComparator(Graph* graph)
- : graph_(graph) {}
-
- // Compares the operations in the vertex a and b of graph_.
- bool operator()(size_t a, size_t b) const {
- return diff_utils::CompareAopsByDestination((*graph_)[a].aop,
- (*graph_)[b].aop);
- }
-
- private:
- const Graph* const graph_;
-};
-
-} // namespace
-
-void InplaceGenerator::CheckGraph(const Graph& graph) {
- for (const Vertex& v : graph) {
- CHECK(v.aop.op.has_type());
- }
-}
-
-void InplaceGenerator::SubstituteBlocks(Vertex* vertex,
- const vector<Extent>& remove_extents,
- const vector<Extent>& replace_extents) {
- // First, expand out the blocks that op reads from
- vector<uint64_t> read_blocks = ExpandExtents(vertex->aop.op.src_extents());
- {
- // Expand remove_extents and replace_extents
- vector<uint64_t> remove_extents_expanded = ExpandExtents(remove_extents);
- vector<uint64_t> replace_extents_expanded = ExpandExtents(replace_extents);
- CHECK_EQ(remove_extents_expanded.size(), replace_extents_expanded.size());
- map<uint64_t, uint64_t> conversion;
- for (vector<uint64_t>::size_type i = 0; i < replace_extents_expanded.size();
- i++) {
- conversion[remove_extents_expanded[i]] = replace_extents_expanded[i];
- }
- ApplyMap(&read_blocks, conversion);
- for (auto& edge_prop_pair : vertex->out_edges) {
- vector<uint64_t> write_before_deps_expanded =
- ExpandExtents(edge_prop_pair.second.write_extents);
- ApplyMap(&write_before_deps_expanded, conversion);
- edge_prop_pair.second.write_extents =
- CompressExtents(write_before_deps_expanded);
- }
- }
- // Convert read_blocks back to extents
- vertex->aop.op.clear_src_extents();
- vector<Extent> new_extents = CompressExtents(read_blocks);
- StoreExtents(new_extents, vertex->aop.op.mutable_src_extents());
-}
-
-bool InplaceGenerator::CutEdges(Graph* graph,
- const set<Edge>& edges,
- vector<CutEdgeVertexes>* out_cuts) {
- DummyExtentAllocator scratch_allocator;
- vector<CutEdgeVertexes> cuts;
- cuts.reserve(edges.size());
-
- uint64_t scratch_blocks_used = 0;
- for (const Edge& edge : edges) {
- cuts.resize(cuts.size() + 1);
- vector<Extent> old_extents =
- (*graph)[edge.first].out_edges[edge.second].extents;
- // Choose some scratch space
- scratch_blocks_used += graph_utils::EdgeWeight(*graph, edge);
- cuts.back().tmp_extents =
- scratch_allocator.Allocate(graph_utils::EdgeWeight(*graph, edge));
- // create vertex to copy original->scratch
- cuts.back().new_vertex = graph->size();
- graph->emplace_back();
- cuts.back().old_src = edge.first;
- cuts.back().old_dst = edge.second;
-
- EdgeProperties& cut_edge_properties =
- (*graph)[edge.first].out_edges.find(edge.second)->second;
-
- // This should never happen, as we should only be cutting edges between
- // real file nodes, and write-before relationships are created from
- // a real file node to a temp copy node:
- CHECK(cut_edge_properties.write_extents.empty())
- << "Can't cut edge that has write-before relationship.";
-
- // make node depend on the copy operation
- (*graph)[edge.first].out_edges.insert(
- make_pair(graph->size() - 1, cut_edge_properties));
-
- // Set src/dst extents and other proto variables for copy operation
- graph->back().aop.op.set_type(InstallOperation::MOVE);
- StoreExtents(cut_edge_properties.extents,
- graph->back().aop.op.mutable_src_extents());
- StoreExtents(cuts.back().tmp_extents,
- graph->back().aop.op.mutable_dst_extents());
- graph->back().aop.op.set_src_length(graph_utils::EdgeWeight(*graph, edge) *
- kBlockSize);
- graph->back().aop.op.set_dst_length(graph->back().aop.op.src_length());
-
- // make the dest node read from the scratch space
- SubstituteBlocks(&((*graph)[edge.second]),
- (*graph)[edge.first].out_edges[edge.second].extents,
- cuts.back().tmp_extents);
-
- // delete the old edge
- CHECK_EQ(static_cast<Graph::size_type>(1),
- (*graph)[edge.first].out_edges.erase(edge.second));
-
- // Add an edge from dst to copy operation
- EdgeProperties write_before_edge_properties;
- write_before_edge_properties.write_extents = cuts.back().tmp_extents;
- (*graph)[edge.second].out_edges.insert(
- make_pair(graph->size() - 1, write_before_edge_properties));
- }
- out_cuts->swap(cuts);
- return true;
-}
-
-// Creates all the edges for the graph. Writers of a block point to
-// readers of the same block. This is because for an edge A->B, B
-// must complete before A executes.
-void InplaceGenerator::CreateEdges(Graph* graph, const vector<Block>& blocks) {
- for (vector<Block>::size_type i = 0; i < blocks.size(); i++) {
- // Blocks with both a reader and writer get an edge
- if (blocks[i].reader == Vertex::kInvalidIndex ||
- blocks[i].writer == Vertex::kInvalidIndex)
- continue;
- // Don't have a node depend on itself
- if (blocks[i].reader == blocks[i].writer)
- continue;
- // See if there's already an edge we can add onto
- Vertex::EdgeMap::iterator edge_it =
- (*graph)[blocks[i].writer].out_edges.find(blocks[i].reader);
- if (edge_it == (*graph)[blocks[i].writer].out_edges.end()) {
- // No existing edge. Create one
- (*graph)[blocks[i].writer].out_edges.insert(
- make_pair(blocks[i].reader, EdgeProperties()));
- edge_it = (*graph)[blocks[i].writer].out_edges.find(blocks[i].reader);
- CHECK(edge_it != (*graph)[blocks[i].writer].out_edges.end());
- }
- AppendBlockToExtents(&edge_it->second.extents, i);
- }
-}
-
-namespace {
-
-class SortCutsByTopoOrderLess {
- public:
- explicit SortCutsByTopoOrderLess(
- const vector<vector<Vertex::Index>::size_type>& table)
- : table_(table) {}
- bool operator()(const CutEdgeVertexes& a, const CutEdgeVertexes& b) {
- return table_[a.old_dst] < table_[b.old_dst];
- }
-
- private:
- const vector<vector<Vertex::Index>::size_type>& table_;
-};
-
-} // namespace
-
-void InplaceGenerator::GenerateReverseTopoOrderMap(
- const vector<Vertex::Index>& op_indexes,
- vector<vector<Vertex::Index>::size_type>* reverse_op_indexes) {
- vector<vector<Vertex::Index>::size_type> table(op_indexes.size());
- for (vector<Vertex::Index>::size_type i = 0, e = op_indexes.size(); i != e;
- ++i) {
- Vertex::Index node = op_indexes[i];
- if (table.size() < (node + 1)) {
- table.resize(node + 1);
- }
- table[node] = i;
- }
- reverse_op_indexes->swap(table);
-}
-
-void InplaceGenerator::SortCutsByTopoOrder(
- const vector<Vertex::Index>& op_indexes, vector<CutEdgeVertexes>* cuts) {
- // first, make a reverse lookup table.
- vector<vector<Vertex::Index>::size_type> table;
- GenerateReverseTopoOrderMap(op_indexes, &table);
- SortCutsByTopoOrderLess less(table);
- sort(cuts->begin(), cuts->end(), less);
-}
-
-void InplaceGenerator::MoveAndSortFullOpsToBack(
- Graph* graph, vector<Vertex::Index>* op_indexes) {
- vector<Vertex::Index> ret;
- vector<Vertex::Index> full_ops;
- ret.reserve(op_indexes->size());
- for (auto op_index : *op_indexes) {
- InstallOperation_Type type = (*graph)[op_index].aop.op.type();
- if (type == InstallOperation::REPLACE ||
- type == InstallOperation::REPLACE_BZ) {
- full_ops.push_back(op_index);
- } else {
- ret.push_back(op_index);
- }
- }
- LOG(INFO) << "Stats: " << full_ops.size() << " full ops out of "
- << (full_ops.size() + ret.size()) << " total ops.";
- // Sort full ops according to their dst_extents.
- sort(full_ops.begin(),
- full_ops.end(),
- IndexedInstallOperationsDstComparator(graph));
- ret.insert(ret.end(), full_ops.begin(), full_ops.end());
- op_indexes->swap(ret);
-}
-
-namespace {
-
-template <typename T>
-bool TempBlocksExistInExtents(const T& extents) {
- for (const auto& extent : extents) {
- uint64_t start = extent.start_block();
- uint64_t num = extent.num_blocks();
- if (start >= kTempBlockStart || (start + num) >= kTempBlockStart) {
- LOG(ERROR) << "temp block!";
- LOG(ERROR) << "start: " << start << ", num: " << num;
- LOG(ERROR) << "kTempBlockStart: " << kTempBlockStart;
- LOG(ERROR) << "returning true";
- return true;
- }
- // check for wrap-around, which would be a bug:
- CHECK(start <= (start + num));
- }
- return false;
-}
-
-// Converts the cuts, which must all have the same |old_dst| member,
-// to full. It does this by converting the |old_dst| to REPLACE or
-// REPLACE_BZ, dropping all incoming edges to |old_dst|, and marking
-// all temp nodes invalid.
-bool ConvertCutsToFull(
- Graph* graph,
- const string& new_part,
- BlobFileWriter* blob_file,
- vector<Vertex::Index>* op_indexes,
- vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
- const vector<CutEdgeVertexes>& cuts) {
- CHECK(!cuts.empty());
- set<Vertex::Index> deleted_nodes;
- for (const CutEdgeVertexes& cut : cuts) {
- TEST_AND_RETURN_FALSE(
- InplaceGenerator::ConvertCutToFullOp(graph, cut, new_part, blob_file));
- deleted_nodes.insert(cut.new_vertex);
- }
- deleted_nodes.insert(cuts[0].old_dst);
-
- vector<Vertex::Index> new_op_indexes;
- new_op_indexes.reserve(op_indexes->size());
- for (Vertex::Index vertex_index : *op_indexes) {
- if (base::ContainsKey(deleted_nodes, vertex_index))
- continue;
- new_op_indexes.push_back(vertex_index);
- }
- new_op_indexes.push_back(cuts[0].old_dst);
- op_indexes->swap(new_op_indexes);
- InplaceGenerator::GenerateReverseTopoOrderMap(*op_indexes,
- reverse_op_indexes);
- return true;
-}
-
-// Tries to assign temp blocks for a collection of cuts, all of which share
-// the same old_dst member. If temp blocks can't be found, old_dst will be
-// converted to a REPLACE or REPLACE_BZ operation. Returns true on success,
-// which can happen even if blocks are converted to full. Returns false
-// on exceptional error cases.
-bool AssignBlockForAdjoiningCuts(
- Graph* graph,
- const string& new_part,
- BlobFileWriter* blob_file,
- vector<Vertex::Index>* op_indexes,
- vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
- const vector<CutEdgeVertexes>& cuts) {
- CHECK(!cuts.empty());
- const Vertex::Index old_dst = cuts[0].old_dst;
- // Calculate # of blocks needed
- uint64_t blocks_needed = 0;
- vector<uint64_t> cuts_blocks_needed(cuts.size());
- for (vector<CutEdgeVertexes>::size_type i = 0; i < cuts.size(); ++i) {
- uint64_t cut_blocks_needed = 0;
- for (const Extent& extent : cuts[i].tmp_extents) {
- cut_blocks_needed += extent.num_blocks();
- }
- blocks_needed += cut_blocks_needed;
- cuts_blocks_needed[i] = cut_blocks_needed;
- }
-
- // Find enough blocks
- ExtentRanges scratch_ranges;
- // Each block that's supplying temp blocks and the corresponding blocks:
- typedef vector<pair<Vertex::Index, ExtentRanges>> SupplierVector;
- SupplierVector block_suppliers;
- uint64_t scratch_blocks_found = 0;
- for (vector<Vertex::Index>::size_type i = (*reverse_op_indexes)[old_dst] + 1,
- e = op_indexes->size();
- i < e;
- ++i) {
- Vertex::Index test_node = (*op_indexes)[i];
- if (!(*graph)[test_node].valid)
- continue;
- // See if this node has sufficient blocks
- ExtentRanges ranges;
- ranges.AddRepeatedExtents((*graph)[test_node].aop.op.dst_extents());
- ranges.SubtractExtent(
- ExtentForRange(kTempBlockStart, kSparseHole - kTempBlockStart));
- ranges.SubtractRepeatedExtents((*graph)[test_node].aop.op.src_extents());
- // For now, for simplicity, subtract out all blocks in read-before
- // dependencies.
- for (Vertex::EdgeMap::const_iterator
- edge_i = (*graph)[test_node].out_edges.begin(),
- edge_e = (*graph)[test_node].out_edges.end();
- edge_i != edge_e;
- ++edge_i) {
- ranges.SubtractExtents(edge_i->second.extents);
- }
-
- // Prevent using the block 0 as scratch space due to crbug.com/480751.
- if (ranges.ContainsBlock(0)) {
- LOG(INFO) << "Removing block 0 from the selected scratch range in vertex "
- << i;
- ranges.SubtractBlock(0);
- }
-
- if (ranges.blocks() == 0)
- continue;
-
- if (ranges.blocks() + scratch_blocks_found > blocks_needed) {
- // trim down ranges
- vector<Extent> new_ranges =
- ranges.GetExtentsForBlockCount(blocks_needed - scratch_blocks_found);
- ranges = ExtentRanges();
- ranges.AddExtents(new_ranges);
- }
- scratch_ranges.AddRanges(ranges);
- block_suppliers.push_back(make_pair(test_node, ranges));
- scratch_blocks_found += ranges.blocks();
- if (scratch_ranges.blocks() >= blocks_needed)
- break;
- }
- if (scratch_ranges.blocks() < blocks_needed) {
- LOG(INFO) << "Unable to find sufficient scratch";
- TEST_AND_RETURN_FALSE(ConvertCutsToFull(
- graph, new_part, blob_file, op_indexes, reverse_op_indexes, cuts));
- return true;
- }
- // Use the scratch we found
- TEST_AND_RETURN_FALSE(scratch_ranges.blocks() == scratch_blocks_found);
-
- // Make all the suppliers depend on this node
- for (const auto& index_range_pair : block_suppliers) {
- graph_utils::AddReadBeforeDepExtents(
- &(*graph)[index_range_pair.first],
- old_dst,
- index_range_pair.second.GetExtentsForBlockCount(
- index_range_pair.second.blocks()));
- }
-
- // Replace temp blocks in each cut
- for (vector<CutEdgeVertexes>::size_type i = 0; i < cuts.size(); ++i) {
- const CutEdgeVertexes& cut = cuts[i];
- vector<Extent> real_extents =
- scratch_ranges.GetExtentsForBlockCount(cuts_blocks_needed[i]);
- scratch_ranges.SubtractExtents(real_extents);
-
- // Fix the old dest node w/ the real blocks
- InplaceGenerator::SubstituteBlocks(
- &(*graph)[old_dst], cut.tmp_extents, real_extents);
-
- // Fix the new node w/ the real blocks. Since the new node is just a
- // copy operation, we can replace all the dest extents w/ the real
- // blocks.
- InstallOperation* op = &(*graph)[cut.new_vertex].aop.op;
- op->clear_dst_extents();
- StoreExtents(real_extents, op->mutable_dst_extents());
- }
- return true;
-}
-
-} // namespace
-
-bool InplaceGenerator::AssignTempBlocks(
- Graph* graph,
- const string& new_part,
- BlobFileWriter* blob_file,
- vector<Vertex::Index>* op_indexes,
- vector<vector<Vertex::Index>::size_type>* reverse_op_indexes,
- const vector<CutEdgeVertexes>& cuts) {
- CHECK(!cuts.empty());
-
- // group of cuts w/ the same old_dst:
- vector<CutEdgeVertexes> cuts_group;
-
- for (vector<CutEdgeVertexes>::size_type i = cuts.size() - 1, e = 0; true;
- --i) {
- LOG(INFO) << "Fixing temp blocks in cut " << i
- << ": old dst: " << cuts[i].old_dst
- << " new vertex: " << cuts[i].new_vertex
- << " path: " << (*graph)[cuts[i].old_dst].aop.name;
-
- if (cuts_group.empty() || (cuts_group[0].old_dst == cuts[i].old_dst)) {
- cuts_group.push_back(cuts[i]);
- } else {
- CHECK(!cuts_group.empty());
- TEST_AND_RETURN_FALSE(AssignBlockForAdjoiningCuts(graph,
- new_part,
- blob_file,
- op_indexes,
- reverse_op_indexes,
- cuts_group));
- cuts_group.clear();
- cuts_group.push_back(cuts[i]);
- }
-
- if (i == e) {
- // break out of for() loop
- break;
- }
- }
- CHECK(!cuts_group.empty());
- TEST_AND_RETURN_FALSE(AssignBlockForAdjoiningCuts(
- graph, new_part, blob_file, op_indexes, reverse_op_indexes, cuts_group));
- return true;
-}
-
-bool InplaceGenerator::NoTempBlocksRemain(const Graph& graph) {
- size_t idx = 0;
- for (Graph::const_iterator it = graph.begin(), e = graph.end(); it != e;
- ++it, ++idx) {
- if (!it->valid)
- continue;
- const InstallOperation& op = it->aop.op;
- if (TempBlocksExistInExtents(op.dst_extents()) ||
- TempBlocksExistInExtents(op.src_extents())) {
- LOG(INFO) << "bad extents in node " << idx;
- LOG(INFO) << "so yeah";
- return false;
- }
-
- // Check out-edges:
- for (const auto& edge_prop_pair : it->out_edges) {
- if (TempBlocksExistInExtents(edge_prop_pair.second.extents) ||
- TempBlocksExistInExtents(edge_prop_pair.second.write_extents)) {
- LOG(INFO) << "bad out edge in node " << idx;
- LOG(INFO) << "so yeah";
- return false;
- }
- }
- }
- return true;
-}
-
-bool InplaceGenerator::ConvertCutToFullOp(Graph* graph,
- const CutEdgeVertexes& cut,
- const string& new_part,
- BlobFileWriter* blob_file) {
- // Drop all incoming edges, keep all outgoing edges
-
- // Keep all outgoing edges
- if ((*graph)[cut.old_dst].aop.op.type() != InstallOperation::REPLACE_BZ &&
- (*graph)[cut.old_dst].aop.op.type() != InstallOperation::REPLACE) {
- Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges;
- graph_utils::DropWriteBeforeDeps(&out_edges);
-
- // Replace the operation with a REPLACE or REPLACE_BZ to generate the same
- // |new_extents| list of blocks and update the graph.
- vector<AnnotatedOperation> new_aop;
- vector<Extent> new_extents;
- ExtentsToVector((*graph)[cut.old_dst].aop.op.dst_extents(), &new_extents);
- TEST_AND_RETURN_FALSE(diff_utils::DeltaReadFile(
- &new_aop,
- "", // old_part
- new_part,
- vector<Extent>(), // old_extents
- new_extents,
- {}, // old_deflates
- {}, // new_deflates
- (*graph)[cut.old_dst].aop.name,
- -1, // chunk_blocks, forces to have a single operation.
- kInPlacePayloadVersion,
- blob_file));
- TEST_AND_RETURN_FALSE(new_aop.size() == 1);
- TEST_AND_RETURN_FALSE(AddInstallOpToGraph(
- graph, cut.old_dst, nullptr, new_aop.front().op, new_aop.front().name));
-
- (*graph)[cut.old_dst].out_edges = out_edges;
-
- // Right now we don't have doubly-linked edges, so we have to scan
- // the whole graph.
- graph_utils::DropIncomingEdgesTo(graph, cut.old_dst);
- }
-
- // Delete temp node
- (*graph)[cut.old_src].out_edges.erase(cut.new_vertex);
- CHECK((*graph)[cut.old_dst].out_edges.find(cut.new_vertex) ==
- (*graph)[cut.old_dst].out_edges.end());
- (*graph)[cut.new_vertex].valid = false;
- LOG(INFO) << "marked node invalid: " << cut.new_vertex;
- return true;
-}
-
-bool InplaceGenerator::ConvertGraphToDag(Graph* graph,
- const string& new_part,
- BlobFileWriter* blob_file,
- vector<Vertex::Index>* final_order,
- Vertex::Index scratch_vertex) {
- CycleBreaker cycle_breaker;
- LOG(INFO) << "Finding cycles...";
- set<Edge> cut_edges;
- cycle_breaker.BreakCycles(*graph, &cut_edges);
- LOG(INFO) << "done finding cycles";
- CheckGraph(*graph);
-
- // Calculate number of scratch blocks needed
-
- LOG(INFO) << "Cutting cycles...";
- vector<CutEdgeVertexes> cuts;
- TEST_AND_RETURN_FALSE(CutEdges(graph, cut_edges, &cuts));
- LOG(INFO) << "done cutting cycles";
- LOG(INFO) << "There are " << cuts.size() << " cuts.";
- CheckGraph(*graph);
-
- LOG(INFO) << "Creating initial topological order...";
- TopologicalSort(*graph, final_order);
- LOG(INFO) << "done with initial topo order";
- CheckGraph(*graph);
-
- LOG(INFO) << "Moving full ops to the back";
- MoveAndSortFullOpsToBack(graph, final_order);
- LOG(INFO) << "done moving full ops to back";
-
- vector<vector<Vertex::Index>::size_type> inverse_final_order;
- GenerateReverseTopoOrderMap(*final_order, &inverse_final_order);
-
- SortCutsByTopoOrder(*final_order, &cuts);
-
- if (!cuts.empty())
- TEST_AND_RETURN_FALSE(AssignTempBlocks(
- graph, new_part, blob_file, final_order, &inverse_final_order, cuts));
- LOG(INFO) << "Making sure all temp blocks have been allocated";
-
- // Remove the scratch node, if any
- if (scratch_vertex != Vertex::kInvalidIndex) {
- final_order->erase(final_order->begin() +
- inverse_final_order[scratch_vertex]);
- (*graph)[scratch_vertex].valid = false;
- GenerateReverseTopoOrderMap(*final_order, &inverse_final_order);
- }
-
- graph_utils::DumpGraph(*graph);
- CHECK(NoTempBlocksRemain(*graph));
- LOG(INFO) << "done making sure all temp blocks are allocated";
- return true;
-}
-
-void InplaceGenerator::CreateScratchNode(uint64_t start_block,
- uint64_t num_blocks,
- Vertex* vertex) {
- vertex->aop.name = "<scratch>";
- vertex->aop.op.set_type(InstallOperation::REPLACE_BZ);
- vertex->aop.op.set_data_offset(0);
- vertex->aop.op.set_data_length(0);
- Extent* extent = vertex->aop.op.add_dst_extents();
- extent->set_start_block(start_block);
- extent->set_num_blocks(num_blocks);
-}
-
-bool InplaceGenerator::AddInstallOpToBlocksVector(
- const InstallOperation& operation,
- const Graph& graph,
- Vertex::Index vertex,
- vector<Block>* blocks) {
- // See if this is already present.
- TEST_AND_RETURN_FALSE(operation.dst_extents_size() > 0);
-
- enum BlockField { READER = 0, WRITER, BLOCK_FIELD_COUNT };
- for (int field = READER; field < BLOCK_FIELD_COUNT; field++) {
- const char* past_participle = (field == READER) ? "read" : "written";
- const google::protobuf::RepeatedPtrField<Extent>& extents =
- (field == READER) ? operation.src_extents() : operation.dst_extents();
- Vertex::Index Block::*access_type =
- (field == READER) ? &Block::reader : &Block::writer;
-
- for (const Extent& extent : extents) {
- for (uint64_t block = extent.start_block();
- block < (extent.start_block() + extent.num_blocks());
- block++) {
- if ((*blocks)[block].*access_type != Vertex::kInvalidIndex) {
- LOG(FATAL) << "Block " << block << " is already " << past_participle
- << " by " << (*blocks)[block].*access_type << "("
- << graph[(*blocks)[block].*access_type].aop.name
- << ") and also " << vertex << "(" << graph[vertex].aop.name
- << ")";
- }
- (*blocks)[block].*access_type = vertex;
- }
- }
- }
- return true;
-}
-
-bool InplaceGenerator::AddInstallOpToGraph(Graph* graph,
- Vertex::Index existing_vertex,
- vector<Block>* blocks,
- const InstallOperation& operation,
- const string& op_name) {
- Vertex::Index vertex = existing_vertex;
- if (vertex == Vertex::kInvalidIndex) {
- graph->emplace_back();
- vertex = graph->size() - 1;
- }
- (*graph)[vertex].aop.op = operation;
- CHECK((*graph)[vertex].aop.op.has_type());
- (*graph)[vertex].aop.name = op_name;
-
- if (blocks)
- TEST_AND_RETURN_FALSE(InplaceGenerator::AddInstallOpToBlocksVector(
- (*graph)[vertex].aop.op, *graph, vertex, blocks));
- return true;
-}
-
-void InplaceGenerator::ApplyMap(vector<uint64_t>* collection,
- const map<uint64_t, uint64_t>& the_map) {
- for (uint64_t& elem : *collection) {
- const auto& map_it = the_map.find(elem);
- if (map_it != the_map.end())
- elem = map_it->second;
- }
-}
-
-bool InplaceGenerator::ResolveReadAfterWriteDependencies(
- const PartitionConfig& old_part,
- const PartitionConfig& new_part,
- uint64_t partition_size,
- size_t block_size,
- BlobFileWriter* blob_file,
- vector<AnnotatedOperation>* aops) {
- // Convert the operations to the graph.
- Graph graph;
- CheckGraph(graph);
- vector<Block> blocks(std::max(old_part.size, new_part.size) / block_size);
- for (const auto& aop : *aops) {
- AddInstallOpToGraph(
- &graph, Vertex::kInvalidIndex, &blocks, aop.op, aop.name);
- }
- CheckGraph(graph);
-
- // Final scratch block (if there's space)
- Vertex::Index scratch_vertex = Vertex::kInvalidIndex;
- if (blocks.size() < (partition_size / block_size)) {
- scratch_vertex = graph.size();
- graph.emplace_back();
- size_t scratch_blocks = (partition_size / block_size) - blocks.size();
- LOG(INFO) << "Added " << scratch_blocks << " scratch space blocks.";
- CreateScratchNode(blocks.size(), scratch_blocks, &graph.back());
- }
- CheckGraph(graph);
-
- LOG(INFO) << "Creating edges...";
- CreateEdges(&graph, blocks);
- LOG(INFO) << "Done creating edges";
- CheckGraph(graph);
-
- vector<Vertex::Index> final_order;
- TEST_AND_RETURN_FALSE(ConvertGraphToDag(
- &graph, new_part.path, blob_file, &final_order, scratch_vertex));
-
- // Copy operations over to the |aops| vector in the final_order generated by
- // the topological sort.
- aops->clear();
- aops->reserve(final_order.size());
- for (const Vertex::Index vertex_index : final_order) {
- const Vertex& vertex = graph[vertex_index];
- aops->push_back(vertex.aop);
- }
- return true;
-}
-
-bool InplaceGenerator::GenerateOperations(const PayloadGenerationConfig& config,
- const PartitionConfig& old_part,
- const PartitionConfig& new_part,
- BlobFileWriter* blob_file,
- vector<AnnotatedOperation>* aops) {
- TEST_AND_RETURN_FALSE(old_part.name == new_part.name);
- TEST_AND_RETURN_FALSE(config.version.major == kInPlacePayloadVersion.major);
- TEST_AND_RETURN_FALSE(config.version.minor == kInPlacePayloadVersion.minor);
-
- ssize_t hard_chunk_blocks =
- (config.hard_chunk_size == -1
- ? -1
- : config.hard_chunk_size / config.block_size);
- size_t soft_chunk_blocks = config.soft_chunk_size / config.block_size;
- uint64_t partition_size = new_part.size;
- if (new_part.name == kPartitionNameRoot)
- partition_size = config.rootfs_partition_size;
-
- LOG(INFO) << "Delta compressing " << new_part.name << " partition...";
- TEST_AND_RETURN_FALSE(diff_utils::DeltaReadPartition(aops,
- old_part,
- new_part,
- hard_chunk_blocks,
- soft_chunk_blocks,
- config.version,
- blob_file));
- LOG(INFO) << "Done reading " << new_part.name;
-
- TEST_AND_RETURN_FALSE(ResolveReadAfterWriteDependencies(
- old_part, new_part, partition_size, config.block_size, blob_file, aops));
- LOG(INFO) << "Done reordering " << new_part.name;
- return true;
-}
-
-}; // namespace chromeos_update_engine
diff --git a/payload_generator/inplace_generator.h b/payload_generator/inplace_generator.h
deleted file mode 100644
index e7298d2..0000000
--- a/payload_generator/inplace_generator.h
+++ /dev/null
@@ -1,240 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_INPLACE_GENERATOR_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_INPLACE_GENERATOR_H_
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "update_engine/payload_generator/blob_file_writer.h"
-#include "update_engine/payload_generator/delta_diff_generator.h"
-#include "update_engine/payload_generator/graph_types.h"
-#include "update_engine/payload_generator/operations_generator.h"
-
-// InplaceGenerator contains all functionality related to the inplace algorithm
-// for generating update payloads. These are the functions used when delta minor
-// version is 1.
-
-namespace chromeos_update_engine {
-
-// This struct stores all relevant info for an edge that is cut between
-// nodes old_src -> old_dst by creating new vertex new_vertex. The new
-// relationship is:
-// old_src -(read before)-> new_vertex <-(write before)- old_dst
-// new_vertex is a MOVE operation that moves some existing blocks into
-// temp space. The temp extents are, by necessity, stored in new_vertex
-// (as dst extents) and old_dst (as src extents), but they are also broken
-// out into tmp_extents, as the nodes themselves may contain many more
-// extents.
-struct CutEdgeVertexes {
- Vertex::Index new_vertex;
- Vertex::Index old_src;
- Vertex::Index old_dst;
- std::vector<Extent> tmp_extents;
-};
-
-class InplaceGenerator : public OperationsGenerator {
- public:
- // Represents a disk block on the install partition.
- struct Block {
- // During install, each block on the install partition will be written
- // and some may be read (in all likelihood, many will be read).
- // The reading and writing will be performed by InstallOperations,
- // each of which has a corresponding vertex in a graph.
- // A Block object tells which vertex will read or write this block
- // at install time.
- // Generally, there will be a vector of Block objects whose length
- // is the number of blocks on the install partition.
- Block() : reader(Vertex::kInvalidIndex), writer(Vertex::kInvalidIndex) {}
- Vertex::Index reader;
- Vertex::Index writer;
- };
-
- InplaceGenerator() = default;
-
- // Checks all the operations in the graph have a type assigned.
- static void CheckGraph(const Graph& graph);
-
- // Modifies blocks read by 'op' so that any blocks referred to by
- // 'remove_extents' are replaced with blocks from 'replace_extents'.
- // 'remove_extents' and 'replace_extents' must be the same number of blocks.
- // Blocks will be substituted in the order listed in the vectors.
- // E.g. if 'op' reads blocks 1, 2, 3, 4, 5, 6, 7, 8, remove_extents
- // contains blocks 6, 2, 3, 5, and replace blocks contains
- // 12, 13, 14, 15, then op will be changed to read from:
- // 1, 13, 14, 4, 15, 12, 7, 8
- static void SubstituteBlocks(Vertex* vertex,
- const std::vector<Extent>& remove_extents,
- const std::vector<Extent>& replace_extents);
-
- // Cuts 'edges' from 'graph' according to the AU algorithm. This means
- // for each edge A->B, remove the dependency that B occur before A.
- // Do this by creating a new operation X that copies from the blocks
- // specified by the edge's properties to temp space T. Modify B to read
- // from T rather than the blocks in the edge. Modify A to depend on X,
- // but not on B. Free space is found by looking in 'blocks'.
- // Returns true on success.
- static bool CutEdges(Graph* graph,
- const std::set<Edge>& edges,
- std::vector<CutEdgeVertexes>* out_cuts);
-
- // Creates all the edges for the graph. Writers of a block point to
- // readers of the same block. This is because for an edge A->B, B
- // must complete before A executes.
- static void CreateEdges(Graph* graph, const std::vector<Block>& blocks);
-
- // Takes |op_indexes|, which is effectively a mapping from order in
- // which the op is performed -> graph vertex index, and produces the
- // reverse: a mapping from graph vertex index -> op_indexes index.
- static void GenerateReverseTopoOrderMap(
- const std::vector<Vertex::Index>& op_indexes,
- std::vector<std::vector<Vertex::Index>::size_type>* reverse_op_indexes);
-
- // Sorts the vector |cuts| by its |cuts[].old_dest| member. Order is
- // determined by the order of elements in op_indexes.
- static void SortCutsByTopoOrder(const std::vector<Vertex::Index>& op_indexes,
- std::vector<CutEdgeVertexes>* cuts);
-
- // Given a topologically sorted graph |op_indexes| and |graph|, alters
- // |op_indexes| to move all the full operations to the end of the vector.
- // Full operations should not be depended on, so this is safe.
- static void MoveAndSortFullOpsToBack(Graph* graph,
- std::vector<Vertex::Index>* op_indexes);
-
- // Returns true iff there are no extents in the graph that refer to temp
- // blocks. Temp blocks are in the range [kTempBlockStart, kSparseHole).
- static bool NoTempBlocksRemain(const Graph& graph);
-
- // Takes a |graph|, which has edges that must be cut, as listed in
- // |cuts|. Cuts the edges. Maintains a list in which the operations
- // will be performed (in |op_indexes|) and the reverse (in
- // |reverse_op_indexes|). Cutting edges requires scratch space, and
- // if insufficient scratch is found, the file is reread and will be
- // send down (either as REPLACE or REPLACE_BZ). Returns true on
- // success.
- static bool AssignTempBlocks(
- Graph* graph,
- const std::string& new_part,
- BlobFileWriter* blob_file,
- std::vector<Vertex::Index>* op_indexes,
- std::vector<std::vector<Vertex::Index>::size_type>* reverse_op_indexes,
- const std::vector<CutEdgeVertexes>& cuts);
-
- // Handles allocation of temp blocks to a cut edge by converting the
- // dest node to a full op. This removes the need for temp blocks, but
- // comes at the cost of a worse compression ratio.
- // For example, say we have A->B->A. It would first be cut to form:
- // A->B->N<-A, where N copies blocks to temp space. If there are no
- // temp blocks, this function can be called to convert it to the form:
- // A->B. Now, A is a full operation.
- static bool ConvertCutToFullOp(Graph* graph,
- const CutEdgeVertexes& cut,
- const std::string& new_part,
- BlobFileWriter* blob_file);
-
- // Takes a graph, which is not a DAG, which represents the files just
- // read from disk, and converts it into a DAG by breaking all cycles
- // and finding temp space to resolve broken edges.
- // The final order of the nodes is given in |final_order|
- // Some files may need to be reread from disk, thus |fd| and
- // |data_file_size| are be passed.
- // If |scratch_vertex| is not kInvalidIndex, removes it from
- // |final_order| before returning.
- // Returns true on success.
- static bool ConvertGraphToDag(Graph* graph,
- const std::string& new_part,
- BlobFileWriter* blob_file,
- std::vector<Vertex::Index>* final_order,
- Vertex::Index scratch_vertex);
-
- // Creates a dummy REPLACE_BZ node in the given |vertex|. This can be used
- // to provide scratch space. The node writes |num_blocks| blocks starting at
- // |start_block|The node should be marked invalid before writing all nodes to
- // the output file.
- static void CreateScratchNode(uint64_t start_block,
- uint64_t num_blocks,
- Vertex* vertex);
-
- // The |blocks| vector contains a reader and writer for each block on the
- // filesystem that's being in-place updated. We populate the reader/writer
- // fields of |blocks| by calling this function.
- // For each block in |operation| that is read or written, find that block
- // in |blocks| and set the reader/writer field to the vertex passed.
- // |graph| is not strictly necessary, but useful for printing out
- // error messages.
- static bool AddInstallOpToBlocksVector(const InstallOperation& operation,
- const Graph& graph,
- Vertex::Index vertex,
- std::vector<Block>* blocks);
-
- // Add a vertex (if |existing_vertex| is kInvalidVertex) or update an
- // |existing_vertex| with the passed |operation|.
- // This method will also register the vertex as the reader or writer of the
- // blocks involved in the operation updating the |blocks| vector. The
- // |op_name| associated with the Vertex is used for logging purposes.
- static bool AddInstallOpToGraph(Graph* graph,
- Vertex::Index existing_vertex,
- std::vector<Block>* blocks,
- const InstallOperation& operation,
- const std::string& op_name);
-
- // Apply the transformation stored in |the_map| to the |collection| vector
- // replacing the map keys found in |collection| with its associated value in
- // |the_map|.
- static void ApplyMap(std::vector<uint64_t>* collection,
- const std::map<uint64_t, uint64_t>& the_map);
-
- // Resolve all read-after-write dependencies in the operation list |aops|. The
- // operations in |aops| are such that they generate the desired |new_part| if
- // applied reading always from the original image. This function reorders the
- // operations and generates new operations when needed to make these
- // operations produce the same |new_part| result when applied in-place.
- // The new operations will create blobs in |data_file_fd| and update
- // the file size pointed by |data_file_size| if needed.
- // On success, stores the new operations in |aops| in the right order and
- // returns true.
- static bool ResolveReadAfterWriteDependencies(
- const PartitionConfig& old_part,
- const PartitionConfig& new_part,
- uint64_t partition_size,
- size_t block_size,
- BlobFileWriter* blob_file,
- std::vector<AnnotatedOperation>* aops);
-
- // Generate the update payload operations for the given partition using
- // only operations that read from the target and/or write to the target,
- // hence, applying the payload "in-place" in the target partition. This method
- // assumes that the contents of the source image are pre-copied to the target
- // partition, up to the size of the source image. Use this method to generate
- // a delta update with the minor version kInPlaceMinorPayloadVersion.
- // The operations are stored in |aops|. All the offsets in the operations
- // reference the data written to |blob_file|.
- bool GenerateOperations(const PayloadGenerationConfig& config,
- const PartitionConfig& old_part,
- const PartitionConfig& new_part,
- BlobFileWriter* blob_file,
- std::vector<AnnotatedOperation>* aops) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InplaceGenerator);
-};
-
-}; // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_INPLACE_GENERATOR_H_
diff --git a/payload_generator/inplace_generator_unittest.cc b/payload_generator/inplace_generator_unittest.cc
deleted file mode 100644
index ab3b867..0000000
--- a/payload_generator/inplace_generator_unittest.cc
+++ /dev/null
@@ -1,752 +0,0 @@
-//
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/inplace_generator.h"
-
-#include <map>
-#include <memory>
-#include <set>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <base/format_macros.h>
-#include <base/logging.h>
-#include <base/strings/string_util.h>
-#include <base/strings/stringprintf.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/common/test_utils.h"
-#include "update_engine/common/utils.h"
-#include "update_engine/payload_generator/cycle_breaker.h"
-#include "update_engine/payload_generator/delta_diff_generator.h"
-#include "update_engine/payload_generator/delta_diff_utils.h"
-#include "update_engine/payload_generator/extent_ranges.h"
-#include "update_engine/payload_generator/graph_types.h"
-#include "update_engine/payload_generator/graph_utils.h"
-
-using std::map;
-using std::set;
-using std::string;
-using std::stringstream;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-using Block = InplaceGenerator::Block;
-
-namespace {
-
-void GenVertex(Vertex* out,
- const vector<Extent>& src_extents,
- const vector<Extent>& dst_extents,
- const string& path,
- InstallOperation_Type type) {
- out->aop.op.set_type(type);
- out->aop.name = path;
- StoreExtents(src_extents, out->aop.op.mutable_src_extents());
- StoreExtents(dst_extents, out->aop.op.mutable_dst_extents());
-}
-
-vector<Extent> VectOfExt(uint64_t start_block, uint64_t num_blocks) {
- return vector<Extent>(1, ExtentForRange(start_block, num_blocks));
-}
-
-EdgeProperties EdgeWithReadDep(const vector<Extent>& extents) {
- EdgeProperties ret;
- ret.extents = extents;
- return ret;
-}
-
-EdgeProperties EdgeWithWriteDep(const vector<Extent>& extents) {
- EdgeProperties ret;
- ret.write_extents = extents;
- return ret;
-}
-
-template <typename T>
-void DumpVect(const vector<T>& vect) {
- stringstream ss(stringstream::out);
- for (typename vector<T>::const_iterator it = vect.begin(), e = vect.end();
- it != e;
- ++it) {
- ss << *it << ", ";
- }
- LOG(INFO) << "{" << ss.str() << "}";
-}
-
-void AppendExtent(vector<Extent>* vect, uint64_t start, uint64_t length) {
- vect->resize(vect->size() + 1);
- vect->back().set_start_block(start);
- vect->back().set_num_blocks(length);
-}
-
-void OpAppendExtent(InstallOperation* op, uint64_t start, uint64_t length) {
- Extent* extent = op->add_src_extents();
- extent->set_start_block(start);
- extent->set_num_blocks(length);
-}
-
-} // namespace
-
-class InplaceGeneratorTest : public ::testing::Test {
- protected:
- // Initialize |blob_path_|, |blob_file_size_| and |blob_file_fd_| variables
- // with a new blob file. The file is closed and removed automatically when
- // the test finishes.
- void CreateBlobFile() {
- // blob_fd_closer_ takes a pointer to blob_fd_. Make sure we destroy a
- // previous instance before overriding blob_fd_.
- blob_fd_closer_.reset();
- EXPECT_TRUE(utils::MakeTempFile(
- "InplaceGenerator_blob_file.XXXXXX", &blob_path_, &blob_fd_));
- blob_path_unlinker_.reset(new ScopedPathUnlinker(blob_path_));
- blob_fd_closer_.reset(new ScopedFdCloser(&blob_fd_));
- blob_file_size_ = 0;
- EXPECT_GE(blob_fd_, 0);
- blob_file_.reset(new BlobFileWriter(blob_fd_, &blob_file_size_));
- }
-
- // Dump the list of operations |aops| in case of test failure.
- void DumpAopsOnFailure(const vector<AnnotatedOperation>& aops) {
- if (HasNonfatalFailure()) {
- LOG(INFO) << "Result operation list:";
- for (const auto& aop : aops) {
- LOG(INFO) << aop;
- }
- }
- }
-
- // Blob file name, file descriptor and file size used to store operation
- // blobs.
- string blob_path_;
- int blob_fd_{-1};
- off_t blob_file_size_{0};
- std::unique_ptr<BlobFileWriter> blob_file_;
- std::unique_ptr<ScopedPathUnlinker> blob_path_unlinker_;
- std::unique_ptr<ScopedFdCloser> blob_fd_closer_;
-};
-
-TEST_F(InplaceGeneratorTest, BlockDefaultValues) {
- // Tests that a Block is initialized with the default values as a
- // Vertex::kInvalidIndex. This is required by the delta generators.
- Block block;
- EXPECT_EQ(Vertex::kInvalidIndex, block.reader);
- EXPECT_EQ(Vertex::kInvalidIndex, block.writer);
-}
-
-TEST_F(InplaceGeneratorTest, SubstituteBlocksTest) {
- vector<Extent> remove_blocks;
- AppendExtent(&remove_blocks, 3, 3);
- AppendExtent(&remove_blocks, 7, 1);
- vector<Extent> replace_blocks;
- AppendExtent(&replace_blocks, 10, 2);
- AppendExtent(&replace_blocks, 13, 2);
- Vertex vertex;
- InstallOperation& op = vertex.aop.op;
- OpAppendExtent(&op, 4, 3);
- OpAppendExtent(&op, kSparseHole, 4); // Sparse hole in file
- OpAppendExtent(&op, 3, 1);
- OpAppendExtent(&op, 7, 3);
-
- InplaceGenerator::SubstituteBlocks(&vertex, remove_blocks, replace_blocks);
-
- EXPECT_EQ(7, op.src_extents_size());
- EXPECT_EQ(11U, op.src_extents(0).start_block());
- EXPECT_EQ(1U, op.src_extents(0).num_blocks());
- EXPECT_EQ(13U, op.src_extents(1).start_block());
- EXPECT_EQ(1U, op.src_extents(1).num_blocks());
- EXPECT_EQ(6U, op.src_extents(2).start_block());
- EXPECT_EQ(1U, op.src_extents(2).num_blocks());
- EXPECT_EQ(kSparseHole, op.src_extents(3).start_block());
- EXPECT_EQ(4U, op.src_extents(3).num_blocks());
- EXPECT_EQ(10U, op.src_extents(4).start_block());
- EXPECT_EQ(1U, op.src_extents(4).num_blocks());
- EXPECT_EQ(14U, op.src_extents(5).start_block());
- EXPECT_EQ(1U, op.src_extents(5).num_blocks());
- EXPECT_EQ(8U, op.src_extents(6).start_block());
- EXPECT_EQ(2U, op.src_extents(6).num_blocks());
-}
-
-TEST_F(InplaceGeneratorTest, CutEdgesTest) {
- Graph graph;
- vector<Block> blocks(9);
-
- // Create nodes in graph
- {
- graph.resize(graph.size() + 1);
- graph.back().aop.op.set_type(InstallOperation::MOVE);
- // Reads from blocks 3, 5, 7
- vector<Extent> extents;
- AppendBlockToExtents(&extents, 3);
- AppendBlockToExtents(&extents, 5);
- AppendBlockToExtents(&extents, 7);
- StoreExtents(extents, graph.back().aop.op.mutable_src_extents());
- blocks[3].reader = graph.size() - 1;
- blocks[5].reader = graph.size() - 1;
- blocks[7].reader = graph.size() - 1;
-
- // Writes to blocks 1, 2, 4
- extents.clear();
- AppendBlockToExtents(&extents, 1);
- AppendBlockToExtents(&extents, 2);
- AppendBlockToExtents(&extents, 4);
- StoreExtents(extents, graph.back().aop.op.mutable_dst_extents());
- blocks[1].writer = graph.size() - 1;
- blocks[2].writer = graph.size() - 1;
- blocks[4].writer = graph.size() - 1;
- }
- {
- graph.resize(graph.size() + 1);
- graph.back().aop.op.set_type(InstallOperation::MOVE);
- // Reads from blocks 1, 2, 4
- vector<Extent> extents;
- AppendBlockToExtents(&extents, 1);
- AppendBlockToExtents(&extents, 2);
- AppendBlockToExtents(&extents, 4);
- StoreExtents(extents, graph.back().aop.op.mutable_src_extents());
- blocks[1].reader = graph.size() - 1;
- blocks[2].reader = graph.size() - 1;
- blocks[4].reader = graph.size() - 1;
-
- // Writes to blocks 3, 5, 6
- extents.clear();
- AppendBlockToExtents(&extents, 3);
- AppendBlockToExtents(&extents, 5);
- AppendBlockToExtents(&extents, 6);
- StoreExtents(extents, graph.back().aop.op.mutable_dst_extents());
- blocks[3].writer = graph.size() - 1;
- blocks[5].writer = graph.size() - 1;
- blocks[6].writer = graph.size() - 1;
- }
-
- // Create edges
- InplaceGenerator::CreateEdges(&graph, blocks);
-
- // Find cycles
- CycleBreaker cycle_breaker;
- set<Edge> cut_edges;
- cycle_breaker.BreakCycles(graph, &cut_edges);
-
- EXPECT_EQ(1U, cut_edges.size());
- EXPECT_TRUE(cut_edges.end() !=
- cut_edges.find(std::pair<Vertex::Index, Vertex::Index>(1, 0)));
-
- vector<CutEdgeVertexes> cuts;
- EXPECT_TRUE(InplaceGenerator::CutEdges(&graph, cut_edges, &cuts));
-
- EXPECT_EQ(3U, graph.size());
-
- // Check new node in graph:
- EXPECT_EQ(InstallOperation::MOVE, graph.back().aop.op.type());
- EXPECT_EQ(2, graph.back().aop.op.src_extents_size());
- EXPECT_EQ(1, graph.back().aop.op.dst_extents_size());
- EXPECT_EQ(kTempBlockStart, graph.back().aop.op.dst_extents(0).start_block());
- EXPECT_EQ(2U, graph.back().aop.op.dst_extents(0).num_blocks());
- EXPECT_TRUE(graph.back().out_edges.empty());
-
- // Check that old node reads from new blocks
- EXPECT_EQ(2, graph[0].aop.op.src_extents_size());
- EXPECT_EQ(kTempBlockStart, graph[0].aop.op.src_extents(0).start_block());
- EXPECT_EQ(2U, graph[0].aop.op.src_extents(0).num_blocks());
- EXPECT_EQ(7U, graph[0].aop.op.src_extents(1).start_block());
- EXPECT_EQ(1U, graph[0].aop.op.src_extents(1).num_blocks());
-
- // And that the old dst extents haven't changed
- EXPECT_EQ(2, graph[0].aop.op.dst_extents_size());
- EXPECT_EQ(1U, graph[0].aop.op.dst_extents(0).start_block());
- EXPECT_EQ(2U, graph[0].aop.op.dst_extents(0).num_blocks());
- EXPECT_EQ(4U, graph[0].aop.op.dst_extents(1).start_block());
- EXPECT_EQ(1U, graph[0].aop.op.dst_extents(1).num_blocks());
-
- // Ensure it only depends on the next node and the new temp node
- EXPECT_EQ(2U, graph[0].out_edges.size());
- EXPECT_TRUE(graph[0].out_edges.end() != graph[0].out_edges.find(1));
- EXPECT_TRUE(graph[0].out_edges.end() !=
- graph[0].out_edges.find(graph.size() - 1));
-
- // Check second node has unchanged extents
- EXPECT_EQ(2, graph[1].aop.op.src_extents_size());
- EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).start_block());
- EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).num_blocks());
- EXPECT_EQ(4U, graph[1].aop.op.src_extents(1).start_block());
- EXPECT_EQ(1U, graph[1].aop.op.src_extents(1).num_blocks());
-
- EXPECT_EQ(2, graph[1].aop.op.dst_extents_size());
- EXPECT_EQ(3U, graph[1].aop.op.dst_extents(0).start_block());
- EXPECT_EQ(1U, graph[1].aop.op.dst_extents(0).num_blocks());
- EXPECT_EQ(5U, graph[1].aop.op.dst_extents(1).start_block());
- EXPECT_EQ(2U, graph[1].aop.op.dst_extents(1).num_blocks());
-
- // Ensure it only depends on the next node
- EXPECT_EQ(1U, graph[1].out_edges.size());
- EXPECT_TRUE(graph[1].out_edges.end() != graph[1].out_edges.find(2));
-}
-
-TEST_F(InplaceGeneratorTest, AssignTempBlocksReuseTest) {
- Graph graph(9);
-
- const vector<Extent> empt;
- uint64_t tmp = kTempBlockStart;
- const string kFilename = "/foo";
-
- vector<CutEdgeVertexes> cuts;
- cuts.resize(3);
-
- // Simple broken loop:
- GenVertex(
- &graph[0], VectOfExt(0, 1), VectOfExt(1, 1), "", InstallOperation::MOVE);
- GenVertex(&graph[1],
- VectOfExt(tmp, 1),
- VectOfExt(0, 1),
- "",
- InstallOperation::MOVE);
- GenVertex(&graph[2],
- VectOfExt(1, 1),
- VectOfExt(tmp, 1),
- "",
- InstallOperation::MOVE);
- // Corresponding edges:
- graph[0].out_edges[2] = EdgeWithReadDep(VectOfExt(1, 1));
- graph[1].out_edges[2] = EdgeWithWriteDep(VectOfExt(tmp, 1));
- graph[1].out_edges[0] = EdgeWithReadDep(VectOfExt(0, 1));
- // Store the cut:
- cuts[0].old_dst = 1;
- cuts[0].old_src = 0;
- cuts[0].new_vertex = 2;
- cuts[0].tmp_extents = VectOfExt(tmp, 1);
- tmp++;
-
- // Slightly more complex pair of loops:
- GenVertex(
- &graph[3], VectOfExt(4, 2), VectOfExt(2, 2), "", InstallOperation::MOVE);
- GenVertex(
- &graph[4], VectOfExt(6, 1), VectOfExt(7, 1), "", InstallOperation::MOVE);
- GenVertex(&graph[5],
- VectOfExt(tmp, 3),
- VectOfExt(4, 3),
- kFilename,
- InstallOperation::MOVE);
- GenVertex(&graph[6],
- VectOfExt(2, 2),
- VectOfExt(tmp, 2),
- "",
- InstallOperation::MOVE);
- GenVertex(&graph[7],
- VectOfExt(7, 1),
- VectOfExt(tmp + 2, 1),
- "",
- InstallOperation::MOVE);
- // Corresponding edges:
- graph[3].out_edges[6] = EdgeWithReadDep(VectOfExt(2, 2));
- graph[4].out_edges[7] = EdgeWithReadDep(VectOfExt(7, 1));
- graph[5].out_edges[6] = EdgeWithWriteDep(VectOfExt(tmp, 2));
- graph[5].out_edges[7] = EdgeWithWriteDep(VectOfExt(tmp + 2, 1));
- graph[5].out_edges[3] = EdgeWithReadDep(VectOfExt(4, 2));
- graph[5].out_edges[4] = EdgeWithReadDep(VectOfExt(6, 1));
- // Store the cuts:
- cuts[1].old_dst = 5;
- cuts[1].old_src = 3;
- cuts[1].new_vertex = 6;
- cuts[1].tmp_extents = VectOfExt(tmp, 2);
- cuts[2].old_dst = 5;
- cuts[2].old_src = 4;
- cuts[2].new_vertex = 7;
- cuts[2].tmp_extents = VectOfExt(tmp + 2, 1);
-
- // Supplier of temp block:
- GenVertex(&graph[8], empt, VectOfExt(8, 1), "", InstallOperation::REPLACE);
-
- // Specify the final order:
- vector<Vertex::Index> op_indexes;
- op_indexes.push_back(2);
- op_indexes.push_back(0);
- op_indexes.push_back(1);
- op_indexes.push_back(6);
- op_indexes.push_back(3);
- op_indexes.push_back(7);
- op_indexes.push_back(4);
- op_indexes.push_back(5);
- op_indexes.push_back(8);
-
- vector<vector<Vertex::Index>::size_type> reverse_op_indexes;
- InplaceGenerator::GenerateReverseTopoOrderMap(op_indexes,
- &reverse_op_indexes);
-
- CreateBlobFile();
- EXPECT_TRUE(InplaceGenerator::AssignTempBlocks(&graph,
- "/dev/zero",
- blob_file_.get(),
- &op_indexes,
- &reverse_op_indexes,
- cuts));
- EXPECT_FALSE(graph[6].valid);
- EXPECT_FALSE(graph[7].valid);
- EXPECT_EQ(1, graph[1].aop.op.src_extents_size());
- EXPECT_EQ(2U, graph[1].aop.op.src_extents(0).start_block());
- EXPECT_EQ(1U, graph[1].aop.op.src_extents(0).num_blocks());
- EXPECT_EQ(InstallOperation::REPLACE_BZ, graph[5].aop.op.type());
-}
-
-TEST_F(InplaceGeneratorTest, MoveAndSortFullOpsToBackTest) {
- Graph graph(4);
- graph[0].aop.name = "A";
- graph[0].aop.op.set_type(InstallOperation::REPLACE);
- graph[1].aop.name = "B";
- graph[1].aop.op.set_type(InstallOperation::BSDIFF);
- graph[2].aop.name = "C";
- graph[2].aop.op.set_type(InstallOperation::REPLACE_BZ);
- graph[3].aop.name = "D";
- graph[3].aop.op.set_type(InstallOperation::MOVE);
-
- vector<Vertex::Index> vect(graph.size());
-
- for (vector<Vertex::Index>::size_type i = 0; i < vect.size(); ++i) {
- vect[i] = i;
- }
- InplaceGenerator::MoveAndSortFullOpsToBack(&graph, &vect);
- EXPECT_EQ(vect.size(), graph.size());
- EXPECT_EQ(graph[vect[0]].aop.name, "B");
- EXPECT_EQ(graph[vect[1]].aop.name, "D");
- EXPECT_EQ(graph[vect[2]].aop.name, "A");
- EXPECT_EQ(graph[vect[3]].aop.name, "C");
-}
-
-TEST_F(InplaceGeneratorTest, AssignTempBlocksTest) {
- Graph graph(9);
- const vector<Extent> empt; // empty
- const string kFilename = "/foo";
-
- // Some scratch space:
- GenVertex(&graph[0], empt, VectOfExt(200, 1), "", InstallOperation::REPLACE);
- GenVertex(&graph[1], empt, VectOfExt(210, 10), "", InstallOperation::REPLACE);
- GenVertex(&graph[2], empt, VectOfExt(220, 1), "", InstallOperation::REPLACE);
-
- // A cycle that requires 10 blocks to break:
- GenVertex(&graph[3],
- VectOfExt(10, 11),
- VectOfExt(0, 9),
- "",
- InstallOperation::BSDIFF);
- graph[3].out_edges[4] = EdgeWithReadDep(VectOfExt(0, 9));
- GenVertex(&graph[4],
- VectOfExt(0, 9),
- VectOfExt(10, 11),
- "",
- InstallOperation::BSDIFF);
- graph[4].out_edges[3] = EdgeWithReadDep(VectOfExt(10, 11));
-
- // A cycle that requires 9 blocks to break:
- GenVertex(&graph[5],
- VectOfExt(40, 11),
- VectOfExt(30, 10),
- "",
- InstallOperation::BSDIFF);
- graph[5].out_edges[6] = EdgeWithReadDep(VectOfExt(30, 10));
- GenVertex(&graph[6],
- VectOfExt(30, 10),
- VectOfExt(40, 11),
- "",
- InstallOperation::BSDIFF);
- graph[6].out_edges[5] = EdgeWithReadDep(VectOfExt(40, 11));
-
- // A cycle that requires 40 blocks to break (which is too many):
- GenVertex(&graph[7],
- VectOfExt(120, 50),
- VectOfExt(60, 40),
- "",
- InstallOperation::BSDIFF);
- graph[7].out_edges[8] = EdgeWithReadDep(VectOfExt(60, 40));
- GenVertex(&graph[8],
- VectOfExt(60, 40),
- VectOfExt(120, 50),
- kFilename,
- InstallOperation::BSDIFF);
- graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));
-
- graph_utils::DumpGraph(graph);
-
- vector<Vertex::Index> final_order;
-
- CreateBlobFile();
- EXPECT_TRUE(InplaceGenerator::ConvertGraphToDag(&graph,
- "/dev/zero",
- blob_file_.get(),
- &final_order,
- Vertex::kInvalidIndex));
-
- Graph expected_graph(12);
- GenVertex(&expected_graph[0],
- empt,
- VectOfExt(200, 1),
- "",
- InstallOperation::REPLACE);
- GenVertex(&expected_graph[1],
- empt,
- VectOfExt(210, 10),
- "",
- InstallOperation::REPLACE);
- GenVertex(&expected_graph[2],
- empt,
- VectOfExt(220, 1),
- "",
- InstallOperation::REPLACE);
- GenVertex(&expected_graph[3],
- VectOfExt(10, 11),
- VectOfExt(0, 9),
- "",
- InstallOperation::BSDIFF);
- expected_graph[3].out_edges[9] = EdgeWithReadDep(VectOfExt(0, 9));
- GenVertex(&expected_graph[4],
- VectOfExt(60, 9),
- VectOfExt(10, 11),
- "",
- InstallOperation::BSDIFF);
- expected_graph[4].out_edges[3] = EdgeWithReadDep(VectOfExt(10, 11));
- expected_graph[4].out_edges[9] = EdgeWithWriteDep(VectOfExt(60, 9));
- GenVertex(&expected_graph[5],
- VectOfExt(40, 11),
- VectOfExt(30, 10),
- "",
- InstallOperation::BSDIFF);
- expected_graph[5].out_edges[10] = EdgeWithReadDep(VectOfExt(30, 10));
-
- GenVertex(&expected_graph[6],
- VectOfExt(60, 10),
- VectOfExt(40, 11),
- "",
- InstallOperation::BSDIFF);
- expected_graph[6].out_edges[5] = EdgeWithReadDep(VectOfExt(40, 11));
- expected_graph[6].out_edges[10] = EdgeWithWriteDep(VectOfExt(60, 10));
-
- GenVertex(&expected_graph[7],
- VectOfExt(120, 50),
- VectOfExt(60, 40),
- "",
- InstallOperation::BSDIFF);
- expected_graph[7].out_edges[6] = EdgeWithReadDep(VectOfExt(60, 10));
-
- GenVertex(&expected_graph[8],
- empt,
- VectOfExt(0, 50),
- "/foo",
- InstallOperation::REPLACE_BZ);
- expected_graph[8].out_edges[7] = EdgeWithReadDep(VectOfExt(120, 50));
-
- GenVertex(&expected_graph[9],
- VectOfExt(0, 9),
- VectOfExt(60, 9),
- "",
- InstallOperation::MOVE);
-
- GenVertex(&expected_graph[10],
- VectOfExt(30, 10),
- VectOfExt(60, 10),
- "",
- InstallOperation::MOVE);
- expected_graph[10].out_edges[4] = EdgeWithReadDep(VectOfExt(60, 9));
-
- EXPECT_EQ(12U, graph.size());
- EXPECT_FALSE(graph.back().valid);
- for (Graph::size_type i = 0; i < graph.size() - 1; i++) {
- EXPECT_TRUE(graph[i].out_edges == expected_graph[i].out_edges);
- if (i == 8) {
- // special case
- } else {
- // EXPECT_TRUE(graph[i] == expected_graph[i]) << "i = " << i;
- }
- }
-}
-
-TEST_F(InplaceGeneratorTest, CreateScratchNodeTest) {
- Vertex vertex;
- InplaceGenerator::CreateScratchNode(12, 34, &vertex);
- EXPECT_EQ(InstallOperation::REPLACE_BZ, vertex.aop.op.type());
- EXPECT_EQ(0U, vertex.aop.op.data_offset());
- EXPECT_EQ(0U, vertex.aop.op.data_length());
- EXPECT_EQ(1, vertex.aop.op.dst_extents_size());
- EXPECT_EQ(12U, vertex.aop.op.dst_extents(0).start_block());
- EXPECT_EQ(34U, vertex.aop.op.dst_extents(0).num_blocks());
-}
-
-TEST_F(InplaceGeneratorTest, ApplyMapTest) {
- vector<uint64_t> collection = {1, 2, 3, 4, 6};
- vector<uint64_t> expected_values = {1, 2, 5, 4, 8};
- map<uint64_t, uint64_t> value_map;
- value_map[3] = 5;
- value_map[6] = 8;
- value_map[5] = 10;
-
- InplaceGenerator::ApplyMap(&collection, value_map);
- EXPECT_EQ(expected_values, collection);
-}
-
-// We can't produce MOVE operations with a source or destination in the block 0.
-// This test checks that the cycle breaker procedure doesn't produce such
-// operations.
-TEST_F(InplaceGeneratorTest, ResolveReadAfterWriteDependenciesAvoidMoveToZero) {
- size_t block_size = 4096;
- size_t num_blocks = 4;
- vector<AnnotatedOperation> aops;
-
- // Create a REPLACE_BZ for block 0, and a circular dependency among all other
- // blocks. This situation would prefer to issue a MOVE to scratch space and
- // the only available block is 0.
- aops.emplace_back();
- aops.back().name = base::StringPrintf("<bz-block-0>");
- aops.back().op.set_type(InstallOperation::REPLACE_BZ);
- StoreExtents({ExtentForRange(0, 1)}, aops.back().op.mutable_dst_extents());
-
- for (size_t i = 1; i < num_blocks; i++) {
- AnnotatedOperation aop;
- aop.name = base::StringPrintf("<op-%" PRIuS ">", i);
- aop.op.set_type(InstallOperation::BSDIFF);
- StoreExtents({ExtentForRange(1 + i % (num_blocks - 1), 1)},
- aop.op.mutable_src_extents());
- StoreExtents({ExtentForRange(i, 1)}, aop.op.mutable_dst_extents());
- aops.push_back(aop);
- }
-
- PartitionConfig part("part");
- part.path = "/dev/zero";
- part.size = num_blocks * block_size;
-
- CreateBlobFile();
-
- // We ran two tests here. The first one without enough blocks for the scratch
- // space, forcing it to create a new full operation and the second case with
- // one extra block in the partition that can be used for the move operation.
- for (const auto part_blocks : vector<uint64_t>{num_blocks, num_blocks + 1}) {
- SCOPED_TRACE(
- base::StringPrintf("Using partition_blocks=%" PRIu64, part_blocks));
- vector<AnnotatedOperation> result_aops = aops;
- EXPECT_TRUE(InplaceGenerator::ResolveReadAfterWriteDependencies(
- part,
- part,
- part_blocks * block_size,
- block_size,
- blob_file_.get(),
- &result_aops));
-
- size_t full_ops = 0;
- for (const auto& aop : result_aops) {
- if (diff_utils::IsAReplaceOperation(aop.op.type()))
- full_ops++;
-
- if (aop.op.type() != InstallOperation::MOVE)
- continue;
- for (const Extent& extent : aop.op.src_extents()) {
- EXPECT_NE(0U, extent.start_block())
- << "On src extents for aop: " << aop;
- }
- for (const Extent& extent : aop.op.dst_extents()) {
- EXPECT_NE(0U, extent.start_block())
- << "On dst extents for aop: " << aop;
- }
- }
-
- // If there's extra space in the partition, it should not use a new full
- // operation for it.
- EXPECT_EQ(part_blocks == num_blocks ? 2U : 1U, full_ops);
-
- DumpAopsOnFailure(result_aops);
- }
-}
-
-// Test that we can shrink a filesystem and break cycles.
-TEST_F(InplaceGeneratorTest, ResolveReadAfterWriteDependenciesShrinkData) {
- size_t block_size = 4096;
- size_t old_blocks = 10;
- size_t new_blocks = 8;
- vector<AnnotatedOperation> aops;
-
- // Create a loop using the blocks 1-6 and one other operation writing to the
- // block 7 from outside the new partition. The loop in the blocks 1-6 uses
- // two-block operations, so it needs two blocks of scratch space. It can't use
- // the block 0 as scratch space (see previous test) and it can't use the
- // blocks 7 or 8 due the last move operation.
-
- aops.emplace_back();
- aops.back().name = base::StringPrintf("<bz-block-0>");
- aops.back().op.set_type(InstallOperation::REPLACE_BZ);
- StoreExtents({ExtentForRange(0, 1)}, aops.back().op.mutable_dst_extents());
-
- const size_t num_ops = 3;
- for (size_t i = 0; i < num_ops; i++) {
- AnnotatedOperation aop;
- aop.name = base::StringPrintf("<op-%" PRIuS ">", i);
- aop.op.set_type(InstallOperation::BSDIFF);
- StoreExtents({ExtentForRange(1 + 2 * i, 2)}, aop.op.mutable_src_extents());
- StoreExtents({ExtentForRange(1 + 2 * ((i + 1) % num_ops), 2)},
- aop.op.mutable_dst_extents());
- aops.push_back(aop);
- }
-
- {
- AnnotatedOperation aop;
- aop.name = "<op-shrink>";
- aop.op.set_type(InstallOperation::BSDIFF);
- StoreExtents({ExtentForRange(8, 1)}, aop.op.mutable_src_extents());
- StoreExtents({ExtentForRange(7, 1)}, aop.op.mutable_dst_extents());
- aops.push_back(aop);
- }
-
- PartitionConfig old_part("part");
- old_part.path = "/dev/zero";
- old_part.size = old_blocks * block_size;
-
- PartitionConfig new_part("part");
- new_part.path = "/dev/zero";
- new_part.size = new_blocks * block_size;
-
- CreateBlobFile();
-
- EXPECT_TRUE(InplaceGenerator::ResolveReadAfterWriteDependencies(
- old_part,
- new_part,
- (old_blocks + 2) * block_size, // enough scratch space.
- block_size,
- blob_file_.get(),
- &aops));
-
- size_t full_ops = 0;
- for (const auto& aop : aops) {
- if (diff_utils::IsAReplaceOperation(aop.op.type()))
- full_ops++;
- }
- // There should be only one REPLACE* operation, the one we added for block 0.
- EXPECT_EQ(1U, full_ops);
-
- // There should be only one MOVE operation, the one used to break the loop
- // which should write to scratch space past the block 7 (the last block of the
- // new partition) which is being written later.
- size_t move_ops = 0;
- for (const auto& aop : aops) {
- if (aop.op.type() == InstallOperation::MOVE) {
- move_ops++;
- for (const Extent& extent : aop.op.dst_extents()) {
- EXPECT_LE(7U, extent.start_block())
- << "On dst extents for aop: " << aop;
- }
- }
- }
- EXPECT_EQ(1U, move_ops);
-
- DumpAopsOnFailure(aops);
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/payload_generation_config.cc b/payload_generator/payload_generation_config.cc
index c364797..3b791c8 100644
--- a/payload_generator/payload_generation_config.cc
+++ b/payload_generator/payload_generation_config.cc
@@ -222,7 +222,6 @@
TEST_AND_RETURN_FALSE(major == kChromeOSMajorPayloadVersion ||
major == kBrilloMajorPayloadVersion);
TEST_AND_RETURN_FALSE(minor == kFullPayloadMinorVersion ||
- minor == kInPlaceMinorPayloadVersion ||
minor == kSourceMinorPayloadVersion ||
minor == kOpSrcHashMinorPayloadVersion ||
minor == kBrotliBsdiffMinorPayloadVersion ||
@@ -252,14 +251,6 @@
// them for delta payloads for now.
return minor >= kBrotliBsdiffMinorPayloadVersion;
- // Delta operations:
- case InstallOperation::MOVE:
- case InstallOperation::BSDIFF:
- // MOVE and BSDIFF were replaced by SOURCE_COPY and SOURCE_BSDIFF and
- // should not be used in newer delta versions, since the idempotent checks
- // were removed.
- return minor == kInPlaceMinorPayloadVersion;
-
case InstallOperation::SOURCE_COPY:
case InstallOperation::SOURCE_BSDIFF:
return minor >= kSourceMinorPayloadVersion;
@@ -269,6 +260,10 @@
case InstallOperation::PUFFDIFF:
return minor >= kPuffdiffMinorPayloadVersion;
+
+ case InstallOperation::MOVE:
+ case InstallOperation::BSDIFF:
+ NOTREACHED();
}
return false;
}
@@ -277,10 +272,6 @@
return minor != kFullPayloadMinorVersion;
}
-bool PayloadVersion::InplaceUpdate() const {
- return minor == kInPlaceMinorPayloadVersion;
-}
-
bool PayloadGenerationConfig::Validate() const {
TEST_AND_RETURN_FALSE(version.Validate());
TEST_AND_RETURN_FALSE(version.IsDelta() == is_delta);
@@ -307,9 +298,6 @@
for (const PartitionConfig& part : target.partitions) {
TEST_AND_RETURN_FALSE(part.ValidateExists());
TEST_AND_RETURN_FALSE(part.size % block_size == 0);
- if (version.minor == kInPlaceMinorPayloadVersion &&
- part.name == kPartitionNameRoot)
- TEST_AND_RETURN_FALSE(rootfs_partition_size >= part.size);
if (version.major == kChromeOSMajorPayloadVersion)
TEST_AND_RETURN_FALSE(part.postinstall.IsEmpty());
if (version.minor < kVerityMinorPayloadVersion)
diff --git a/payload_generator/payload_generation_config.h b/payload_generator/payload_generation_config.h
index 2153ab0..32f1229 100644
--- a/payload_generator/payload_generation_config.h
+++ b/payload_generator/payload_generation_config.h
@@ -170,10 +170,6 @@
// Whether this payload version is a delta payload.
bool IsDelta() const;
- // Tells whether the update is done in-place, that is, whether the operations
- // read and write from the same partition.
- bool InplaceUpdate() const;
-
// The major version of the payload.
uint64_t major;
diff --git a/payload_generator/tarjan.cc b/payload_generator/tarjan.cc
deleted file mode 100644
index 2d4ca31..0000000
--- a/payload_generator/tarjan.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#include "update_engine/payload_generator/tarjan.h"
-
-#include <algorithm>
-#include <vector>
-
-#include <base/logging.h>
-#include <base/stl_util.h>
-
-using std::min;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-namespace {
-const vector<Vertex>::size_type kInvalidIndex = -1;
-}
-
-void TarjanAlgorithm::Execute(Vertex::Index vertex,
- Graph* graph,
- vector<Vertex::Index>* out) {
- stack_.clear();
- components_.clear();
- index_ = 0;
- for (Graph::iterator it = graph->begin(); it != graph->end(); ++it)
- it->index = it->lowlink = kInvalidIndex;
- required_vertex_ = vertex;
-
- Tarjan(vertex, graph);
- if (!components_.empty())
- out->swap(components_[0]);
-}
-
-void TarjanAlgorithm::Tarjan(Vertex::Index vertex, Graph* graph) {
- CHECK_EQ((*graph)[vertex].index, kInvalidIndex);
- (*graph)[vertex].index = index_;
- (*graph)[vertex].lowlink = index_;
- index_++;
- stack_.push_back(vertex);
- for (Vertex::EdgeMap::iterator it = (*graph)[vertex].out_edges.begin();
- it != (*graph)[vertex].out_edges.end();
- ++it) {
- Vertex::Index vertex_next = it->first;
- if ((*graph)[vertex_next].index == kInvalidIndex) {
- Tarjan(vertex_next, graph);
- (*graph)[vertex].lowlink =
- min((*graph)[vertex].lowlink, (*graph)[vertex_next].lowlink);
- } else if (base::ContainsValue(stack_, vertex_next)) {
- (*graph)[vertex].lowlink =
- min((*graph)[vertex].lowlink, (*graph)[vertex_next].index);
- }
- }
- if ((*graph)[vertex].lowlink == (*graph)[vertex].index) {
- vector<Vertex::Index> component;
- Vertex::Index other_vertex;
- do {
- other_vertex = stack_.back();
- stack_.pop_back();
- component.push_back(other_vertex);
- } while (other_vertex != vertex && !stack_.empty());
-
- if (base::ContainsValue(component, required_vertex_)) {
- components_.resize(components_.size() + 1);
- component.swap(components_.back());
- }
- }
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/tarjan.h b/payload_generator/tarjan.h
deleted file mode 100644
index 39ac4e4..0000000
--- a/payload_generator/tarjan.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_TARJAN_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_TARJAN_H_
-
-// This is an implementation of Tarjan's algorithm which finds all
-// Strongly Connected Components in a graph.
-
-// Note: a true Tarjan algorithm would find all strongly connected components
-// in the graph. This implementation will only find the strongly connected
-// component containing the vertex passed in.
-
-#include <vector>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-namespace chromeos_update_engine {
-
-class TarjanAlgorithm {
- public:
- TarjanAlgorithm() : index_(0), required_vertex_(0) {}
-
- // 'out' is set to the result if there is one, otherwise it's untouched.
- void Execute(Vertex::Index vertex,
- Graph* graph,
- std::vector<Vertex::Index>* out);
-
- private:
- void Tarjan(Vertex::Index vertex, Graph* graph);
-
- Vertex::Index index_;
- Vertex::Index required_vertex_;
- std::vector<Vertex::Index> stack_;
- std::vector<std::vector<Vertex::Index>> components_;
-};
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_TARJAN_H_
diff --git a/payload_generator/tarjan_unittest.cc b/payload_generator/tarjan_unittest.cc
deleted file mode 100644
index b271227..0000000
--- a/payload_generator/tarjan_unittest.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/tarjan.h"
-
-#include <string>
-#include <utility>
-
-#include <base/logging.h>
-#include <base/stl_util.h>
-#include <gtest/gtest.h>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-using std::make_pair;
-using std::string;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-class TarjanAlgorithmTest : public ::testing::Test {};
-
-TEST(TarjanAlgorithmTest, SimpleTest) {
- const Vertex::Index n_a = 0;
- const Vertex::Index n_b = 1;
- const Vertex::Index n_c = 2;
- const Vertex::Index n_d = 3;
- const Vertex::Index n_e = 4;
- const Vertex::Index n_f = 5;
- const Vertex::Index n_g = 6;
- const Vertex::Index n_h = 7;
- const Graph::size_type kNodeCount = 8;
-
- Graph graph(kNodeCount);
-
- graph[n_a].out_edges.insert(make_pair(n_e, EdgeProperties()));
- graph[n_a].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_b].out_edges.insert(make_pair(n_a, EdgeProperties()));
- graph[n_c].out_edges.insert(make_pair(n_d, EdgeProperties()));
- graph[n_d].out_edges.insert(make_pair(n_e, EdgeProperties()));
- graph[n_d].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_b, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_c, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_f].out_edges.insert(make_pair(n_g, EdgeProperties()));
- graph[n_g].out_edges.insert(make_pair(n_h, EdgeProperties()));
- graph[n_h].out_edges.insert(make_pair(n_g, EdgeProperties()));
-
- TarjanAlgorithm tarjan;
-
- for (Vertex::Index i = n_a; i <= n_e; i++) {
- vector<Vertex::Index> vertex_indexes;
- tarjan.Execute(i, &graph, &vertex_indexes);
-
- EXPECT_EQ(5U, vertex_indexes.size());
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_a));
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_b));
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_c));
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_d));
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_e));
- }
-
- {
- vector<Vertex::Index> vertex_indexes;
- tarjan.Execute(n_f, &graph, &vertex_indexes);
-
- EXPECT_EQ(1U, vertex_indexes.size());
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_f));
- }
-
- for (Vertex::Index i = n_g; i <= n_h; i++) {
- vector<Vertex::Index> vertex_indexes;
- tarjan.Execute(i, &graph, &vertex_indexes);
-
- EXPECT_EQ(2U, vertex_indexes.size());
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_g));
- EXPECT_TRUE(base::ContainsValue(vertex_indexes, n_h));
- }
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/topological_sort.cc b/payload_generator/topological_sort.cc
deleted file mode 100644
index 0abd708..0000000
--- a/payload_generator/topological_sort.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/topological_sort.h"
-
-#include <set>
-#include <vector>
-
-#include <base/logging.h>
-
-using std::set;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-namespace {
-void TopologicalSortVisit(const Graph& graph,
- set<Vertex::Index>* visited_nodes,
- vector<Vertex::Index>* nodes,
- Vertex::Index node) {
- if (visited_nodes->find(node) != visited_nodes->end())
- return;
-
- visited_nodes->insert(node);
- // Visit all children.
- for (Vertex::EdgeMap::const_iterator it = graph[node].out_edges.begin();
- it != graph[node].out_edges.end();
- ++it) {
- TopologicalSortVisit(graph, visited_nodes, nodes, it->first);
- }
- // Visit this node.
- nodes->push_back(node);
-}
-} // namespace
-
-void TopologicalSort(const Graph& graph, vector<Vertex::Index>* out) {
- set<Vertex::Index> visited_nodes;
-
- for (Vertex::Index i = 0; i < graph.size(); i++) {
- TopologicalSortVisit(graph, &visited_nodes, out, i);
- }
-}
-
-} // namespace chromeos_update_engine
diff --git a/payload_generator/topological_sort.h b/payload_generator/topological_sort.h
deleted file mode 100644
index 461cbe1..0000000
--- a/payload_generator/topological_sort.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_TOPOLOGICAL_SORT_H_
-#define UPDATE_ENGINE_PAYLOAD_GENERATOR_TOPOLOGICAL_SORT_H_
-
-#include <vector>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-namespace chromeos_update_engine {
-
-// Performs a topological sort on the directed graph 'graph' and stores
-// the nodes, in order visited, in 'out'.
-// For example, this graph:
-// A ---> C ----.
-// \ v
-// `--> B --> D
-// Might result in this in 'out':
-// out[0] = D
-// out[1] = B
-// out[2] = C
-// out[3] = A
-// Note: results are undefined if there is a cycle in the graph.
-void TopologicalSort(const Graph& graph, std::vector<Vertex::Index>* out);
-
-} // namespace chromeos_update_engine
-
-#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_TOPOLOGICAL_SORT_H_
diff --git a/payload_generator/topological_sort_unittest.cc b/payload_generator/topological_sort_unittest.cc
deleted file mode 100644
index aa296d8..0000000
--- a/payload_generator/topological_sort_unittest.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "update_engine/payload_generator/topological_sort.h"
-
-#include <utility>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include "update_engine/payload_generator/graph_types.h"
-
-using std::make_pair;
-using std::vector;
-
-namespace chromeos_update_engine {
-
-class TopologicalSortTest : public ::testing::Test {};
-
-namespace {
-// Returns true if the value is found in vect. If found, the index is stored
-// in out_index if out_index is not null.
-template <typename T>
-bool IndexOf(const vector<T>& vect,
- const T& value,
- typename vector<T>::size_type* out_index) {
- for (typename vector<T>::size_type i = 0; i < vect.size(); i++) {
- if (vect[i] == value) {
- if (out_index) {
- *out_index = i;
- }
- return true;
- }
- }
- return false;
-}
-} // namespace
-
-TEST(TopologicalSortTest, SimpleTest) {
- int counter = 0;
- const Vertex::Index n_a = counter++;
- const Vertex::Index n_b = counter++;
- const Vertex::Index n_c = counter++;
- const Vertex::Index n_d = counter++;
- const Vertex::Index n_e = counter++;
- const Vertex::Index n_f = counter++;
- const Vertex::Index n_g = counter++;
- const Vertex::Index n_h = counter++;
- const Vertex::Index n_i = counter++;
- const Vertex::Index n_j = counter++;
- const Graph::size_type kNodeCount = counter++;
-
- Graph graph(kNodeCount);
-
- graph[n_i].out_edges.insert(make_pair(n_j, EdgeProperties()));
- graph[n_i].out_edges.insert(make_pair(n_c, EdgeProperties()));
- graph[n_i].out_edges.insert(make_pair(n_e, EdgeProperties()));
- graph[n_i].out_edges.insert(make_pair(n_h, EdgeProperties()));
- graph[n_c].out_edges.insert(make_pair(n_b, EdgeProperties()));
- graph[n_b].out_edges.insert(make_pair(n_a, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_d, EdgeProperties()));
- graph[n_e].out_edges.insert(make_pair(n_g, EdgeProperties()));
- graph[n_g].out_edges.insert(make_pair(n_d, EdgeProperties()));
- graph[n_g].out_edges.insert(make_pair(n_f, EdgeProperties()));
- graph[n_d].out_edges.insert(make_pair(n_a, EdgeProperties()));
-
- vector<Vertex::Index> sorted;
- TopologicalSort(graph, &sorted);
-
- for (Vertex::Index i = 0; i < graph.size(); i++) {
- vector<Vertex::Index>::size_type src_index = 0;
- EXPECT_TRUE(IndexOf(sorted, i, &src_index));
- for (Vertex::EdgeMap::const_iterator it = graph[i].out_edges.begin();
- it != graph[i].out_edges.end();
- ++it) {
- vector<Vertex::Index>::size_type dst_index = 0;
- EXPECT_TRUE(IndexOf(sorted, it->first, &dst_index));
- EXPECT_LT(dst_index, src_index);
- }
- }
-}
-
-} // namespace chromeos_update_engine
diff --git a/scripts/payload_info.py b/scripts/payload_info.py
index 09a7cf7..d10cb24 100755
--- a/scripts/payload_info.py
+++ b/scripts/payload_info.py
@@ -187,10 +187,6 @@
num_write_seeks += 1
last_ext = curr_ext
- if manifest.minor_version == 1:
- # Rootfs and kernel are written during the filesystem copy in version 1.
- written_blocks += manifest.old_rootfs_info.size / manifest.block_size
- written_blocks += manifest.old_kernel_info.size / manifest.block_size
# Old and new rootfs and kernel are read once during verification
read_blocks += manifest.old_rootfs_info.size / manifest.block_size
read_blocks += manifest.old_kernel_info.size / manifest.block_size
diff --git a/scripts/update_payload/applier.py b/scripts/update_payload/applier.py
index 21d8e87..3f64444 100644
--- a/scripts/update_payload/applier.py
+++ b/scripts/update_payload/applier.py
@@ -306,30 +306,6 @@
raise PayloadError('%s: wrote fewer bytes (%d) than expected (%d)' %
(op_name, data_start, data_length))
- def _ApplyMoveOperation(self, op, op_name, part_file):
- """Applies a MOVE operation.
-
- Note that this operation must read the whole block data from the input and
- only then dump it, due to our in-place update semantics; otherwise, it
- might clobber data midway through.
-
- Args:
- op: the operation object
- op_name: name string for error reporting
- part_file: the partition file object
-
- Raises:
- PayloadError if something goes wrong.
- """
- block_size = self.block_size
-
- # Gather input raw data from src extents.
- in_data = _ReadExtents(part_file, op.src_extents, block_size)
-
- # Dump extracted data to dst extents.
- _WriteExtents(part_file, in_data, op.dst_extents, block_size,
- '%s.dst_extents' % op_name)
-
def _ApplyZeroOperation(self, op, op_name, part_file):
"""Applies a ZERO operation.
@@ -439,8 +415,7 @@
# Diff from source partition.
old_file_name = '/dev/fd/%d' % old_part_file.fileno()
- if op.type in (common.OpType.BSDIFF, common.OpType.SOURCE_BSDIFF,
- common.OpType.BROTLI_BSDIFF):
+ if op.type in (common.OpType.SOURCE_BSDIFF, common.OpType.BROTLI_BSDIFF):
# Invoke bspatch on partition file with extents args.
bspatch_cmd = [self.bspatch_path, old_file_name, new_file_name,
patch_file_name, in_extents_arg, out_extents_arg]
@@ -477,8 +452,7 @@
with tempfile.NamedTemporaryFile(delete=False) as out_file:
out_file_name = out_file.name
- if op.type in (common.OpType.BSDIFF, common.OpType.SOURCE_BSDIFF,
- common.OpType.BROTLI_BSDIFF):
+ if op.type in (common.OpType.SOURCE_BSDIFF, common.OpType.BROTLI_BSDIFF):
# Invoke bspatch.
bspatch_cmd = [self.bspatch_path, in_file_name, out_file_name,
patch_file_name]
@@ -520,10 +494,6 @@
new_part_file, part_size):
"""Applies a sequence of update operations to a partition.
- This assumes an in-place update semantics for MOVE and BSDIFF, namely all
- reads are performed first, then the data is processed and written back to
- the same file.
-
Args:
operations: the sequence of operations
base_name: the name of the operation sequence
@@ -541,13 +511,8 @@
if op.type in (common.OpType.REPLACE, common.OpType.REPLACE_BZ,
common.OpType.REPLACE_XZ):
self._ApplyReplaceOperation(op, op_name, data, new_part_file, part_size)
- elif op.type == common.OpType.MOVE:
- self._ApplyMoveOperation(op, op_name, new_part_file)
elif op.type == common.OpType.ZERO:
self._ApplyZeroOperation(op, op_name, new_part_file)
- elif op.type == common.OpType.BSDIFF:
- self._ApplyDiffOperation(op, op_name, data, new_part_file,
- new_part_file)
elif op.type == common.OpType.SOURCE_COPY:
self._ApplySourceCopyOperation(op, op_name, old_part_file,
new_part_file)
@@ -583,15 +548,8 @@
_VerifySha256(old_part_file, old_part_info.hash,
'old ' + part_name, length=old_part_info.size)
new_part_file_mode = 'r+b'
- if self.minor_version == common.INPLACE_MINOR_PAYLOAD_VERSION:
- # Copy the src partition to the dst one; make sure we don't truncate it.
- shutil.copyfile(old_part_file_name, new_part_file_name)
- elif self.minor_version >= common.SOURCE_MINOR_PAYLOAD_VERSION:
- # In minor version >= 2, we don't want to copy the partitions, so
- # instead just make the new partition file.
- open(new_part_file_name, 'w').close()
- else:
- raise PayloadError("Unknown minor version: %d" % self.minor_version)
+ open(new_part_file_name, 'w').close()
+
else:
# We need to create/truncate the dst partition file.
new_part_file_mode = 'w+b'
diff --git a/scripts/update_payload/checker.py b/scripts/update_payload/checker.py
index e4fec2d..674d9f4 100644
--- a/scripts/update_payload/checker.py
+++ b/scripts/update_payload/checker.py
@@ -66,7 +66,6 @@
# Supported minor version map to payload types allowed to be using them.
_SUPPORTED_MINOR_VERSIONS = {
0: (_TYPE_FULL,),
- 1: (_TYPE_DELTA,),
2: (_TYPE_DELTA,),
3: (_TYPE_DELTA,),
4: (_TYPE_DELTA,),
@@ -74,8 +73,6 @@
6: (_TYPE_DELTA,),
}
-_OLD_DELTA_USABLE_PART_SIZE = 2 * 1024 * 1024 * 1024
-
#
# Helper functions.
#
@@ -806,89 +803,6 @@
'space (%d * %d).' %
(op_name, data_length, total_dst_blocks, self.block_size))
- def _CheckMoveOperation(self, op, data_offset, total_src_blocks,
- total_dst_blocks, op_name):
- """Specific checks for MOVE operations.
-
- Args:
- op: The operation object from the manifest.
- data_offset: The offset of a data blob for the operation.
- total_src_blocks: Total number of blocks in src_extents.
- total_dst_blocks: Total number of blocks in dst_extents.
- op_name: Operation name for error reporting.
-
- Raises:
- error.PayloadError if any check fails.
- """
- # Check: No data_{offset,length}.
- if data_offset is not None:
- raise error.PayloadError('%s: contains data_{offset,length}.' % op_name)
-
- # Check: total_src_blocks == total_dst_blocks.
- if total_src_blocks != total_dst_blocks:
- raise error.PayloadError(
- '%s: total src blocks (%d) != total dst blocks (%d).' %
- (op_name, total_src_blocks, total_dst_blocks))
-
- # Check: For all i, i-th src block index != i-th dst block index.
- i = 0
- src_extent_iter = iter(op.src_extents)
- dst_extent_iter = iter(op.dst_extents)
- src_extent = dst_extent = None
- src_idx = src_num = dst_idx = dst_num = 0
- while i < total_src_blocks:
- # Get the next source extent, if needed.
- if not src_extent:
- try:
- src_extent = src_extent_iter.next()
- except StopIteration:
- raise error.PayloadError('%s: ran out of src extents (%d/%d).' %
- (op_name, i, total_src_blocks))
- src_idx = src_extent.start_block
- src_num = src_extent.num_blocks
-
- # Get the next dest extent, if needed.
- if not dst_extent:
- try:
- dst_extent = dst_extent_iter.next()
- except StopIteration:
- raise error.PayloadError('%s: ran out of dst extents (%d/%d).' %
- (op_name, i, total_dst_blocks))
- dst_idx = dst_extent.start_block
- dst_num = dst_extent.num_blocks
-
- # Check: start block is not 0. See crbug/480751; there are still versions
- # of update_engine which fail when seeking to 0 in PReadAll and PWriteAll,
- # so we need to fail payloads that try to MOVE to/from block 0.
- if src_idx == 0 or dst_idx == 0:
- raise error.PayloadError(
- '%s: MOVE operation cannot have extent with start block 0' %
- op_name)
-
- if self.check_move_same_src_dst_block and src_idx == dst_idx:
- raise error.PayloadError(
- '%s: src/dst block number %d is the same (%d).' %
- (op_name, i, src_idx))
-
- advance = min(src_num, dst_num)
- i += advance
-
- src_idx += advance
- src_num -= advance
- if src_num == 0:
- src_extent = None
-
- dst_idx += advance
- dst_num -= advance
- if dst_num == 0:
- dst_extent = None
-
- # Make sure we've exhausted all src/dst extents.
- if src_extent:
- raise error.PayloadError('%s: excess src blocks.' % op_name)
- if dst_extent:
- raise error.PayloadError('%s: excess dst blocks.' % op_name)
-
def _CheckZeroOperation(self, op, op_name):
"""Specific checks for ZERO operations.
@@ -908,7 +822,7 @@
raise error.PayloadError('%s: contains data_offset.' % op_name)
def _CheckAnyDiffOperation(self, op, data_length, total_dst_blocks, op_name):
- """Specific checks for BSDIFF, SOURCE_BSDIFF, PUFFDIFF and BROTLI_BSDIFF
+ """Specific checks for SOURCE_BSDIFF, PUFFDIFF and BROTLI_BSDIFF
operations.
Args:
@@ -933,8 +847,7 @@
total_dst_blocks * self.block_size))
# Check the existence of src_length and dst_length for legacy bsdiffs.
- if (op.type == common.OpType.BSDIFF or
- (op.type == common.OpType.SOURCE_BSDIFF and self.minor_version <= 3)):
+ if op.type == common.OpType.SOURCE_BSDIFF and self.minor_version <= 3:
if not op.HasField('src_length') or not op.HasField('dst_length'):
raise error.PayloadError('%s: require {src,dst}_length.' % op_name)
else:
@@ -1074,13 +987,8 @@
(self.minor_version >= 3 or
self.major_version >= common.BRILLO_MAJOR_PAYLOAD_VERSION)):
self._CheckReplaceOperation(op, data_length, total_dst_blocks, op_name)
- elif op.type == common.OpType.MOVE and self.minor_version == 1:
- self._CheckMoveOperation(op, data_offset, total_src_blocks,
- total_dst_blocks, op_name)
elif op.type == common.OpType.ZERO and self.minor_version >= 4:
self._CheckZeroOperation(op, op_name)
- elif op.type == common.OpType.BSDIFF and self.minor_version == 1:
- self._CheckAnyDiffOperation(op, data_length, total_dst_blocks, op_name)
elif op.type == common.OpType.SOURCE_COPY and self.minor_version >= 2:
self._CheckSourceCopyOperation(data_offset, total_src_blocks,
total_dst_blocks, op_name)
@@ -1149,9 +1057,7 @@
common.OpType.REPLACE: 0,
common.OpType.REPLACE_BZ: 0,
common.OpType.REPLACE_XZ: 0,
- common.OpType.MOVE: 0,
common.OpType.ZERO: 0,
- common.OpType.BSDIFF: 0,
common.OpType.SOURCE_COPY: 0,
common.OpType.SOURCE_BSDIFF: 0,
common.OpType.PUFFDIFF: 0,
@@ -1162,8 +1068,6 @@
common.OpType.REPLACE: 0,
common.OpType.REPLACE_BZ: 0,
common.OpType.REPLACE_XZ: 0,
- # MOVE operations don't have blobs.
- common.OpType.BSDIFF: 0,
# SOURCE_COPY operations don't have blobs.
common.OpType.SOURCE_BSDIFF: 0,
common.OpType.PUFFDIFF: 0,
@@ -1374,19 +1278,10 @@
if part_sizes is not None and part_sizes.get(part, None):
new_fs_usable_size = old_fs_usable_size = part_sizes[part]
- # Infer the usable partition size when validating rootfs operations:
- # - If rootfs partition size was provided, use that.
- # - Otherwise, if this is an older delta (minor version < 2), stick with
- # a known constant size. This is necessary because older deltas may
- # exceed the filesystem size when moving data blocks around.
- # - Otherwise, use the encoded filesystem size.
- elif self.payload_type == _TYPE_DELTA and part == common.ROOTFS and \
- self.minor_version in (None, 1):
- new_fs_usable_size = old_fs_usable_size = _OLD_DELTA_USABLE_PART_SIZE
- # TODO(garnold)(chromium:243559) only default to the filesystem size if
- # no explicit size provided *and* the partition size is not embedded in
- # the payload; see issue for more details.
+ # TODO(chromium:243559) only default to the filesystem size if no
+ # explicit size provided *and* the partition size is not embedded in the
+ # payload; see issue for more details.
total_blob_size += self._CheckOperations(
operations, report, '%s_install_operations' % part,
self.old_fs_sizes[part], self.new_fs_sizes[part],
diff --git a/scripts/update_payload/checker_unittest.py b/scripts/update_payload/checker_unittest.py
index 7e52233..b5f2f3e 100755
--- a/scripts/update_payload/checker_unittest.py
+++ b/scripts/update_payload/checker_unittest.py
@@ -44,8 +44,6 @@
op_name_to_type = {
'REPLACE': common.OpType.REPLACE,
'REPLACE_BZ': common.OpType.REPLACE_BZ,
- 'MOVE': common.OpType.MOVE,
- 'BSDIFF': common.OpType.BSDIFF,
'SOURCE_COPY': common.OpType.SOURCE_COPY,
'SOURCE_BSDIFF': common.OpType.SOURCE_BSDIFF,
'ZERO': common.OpType.ZERO,
@@ -429,10 +427,10 @@
payload_gen.SetBlockSize(test_utils.KiB(4))
# Add some operations.
- payload_gen.AddOperation(False, common.OpType.MOVE,
+ payload_gen.AddOperation(False, common.OpType.SOURCE_COPY,
src_extents=[(0, 16), (16, 497)],
dst_extents=[(16, 496), (0, 16)])
- payload_gen.AddOperation(True, common.OpType.MOVE,
+ payload_gen.AddOperation(True, common.OpType.SOURCE_COPY,
src_extents=[(0, 8), (8, 8)],
dst_extents=[(8, 8), (0, 8)])
@@ -669,132 +667,6 @@
PayloadError, payload_checker._CheckReplaceOperation,
op, data_length, (data_length + block_size - 1) / block_size, 'foo')
- def testCheckMoveOperation_Pass(self):
- """Tests _CheckMoveOperation(); pass case."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 6)))
- self.assertIsNone(
- payload_checker._CheckMoveOperation(op, None, 134, 134, 'foo'))
-
- def testCheckMoveOperation_FailContainsData(self):
- """Tests _CheckMoveOperation(); fails, message contains data."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, 1024, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailInsufficientSrcBlocks(self):
- """Tests _CheckMoveOperation(); fails, not enough actual src blocks."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 127)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailInsufficientDstBlocks(self):
- """Tests _CheckMoveOperation(); fails, not enough actual dst blocks."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 5)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailExcessSrcBlocks(self):
- """Tests _CheckMoveOperation(); fails, too many actual src blocks."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 5)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 129)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailExcessDstBlocks(self):
- """Tests _CheckMoveOperation(); fails, too many actual dst blocks."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((16, 128), (512, 7)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailStagnantBlocks(self):
- """Tests _CheckMoveOperation(); fails, there are blocks that do not move."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((8, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- def testCheckMoveOperation_FailZeroStartBlock(self):
- """Tests _CheckMoveOperation(); fails, has extent with start block 0."""
- payload_checker = checker.PayloadChecker(self.MockPayload())
- op = update_metadata_pb2.InstallOperation()
- op.type = common.OpType.MOVE
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((0, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((8, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
- self.AddToMessage(op.src_extents,
- self.NewExtentList((1, 4), (12, 2), (1024, 128)))
- self.AddToMessage(op.dst_extents,
- self.NewExtentList((0, 128), (512, 6)))
- self.assertRaises(
- PayloadError, payload_checker._CheckMoveOperation,
- op, None, 134, 134, 'foo')
-
def testCheckAnyDiff(self):
"""Tests _CheckAnyDiffOperation()."""
payload_checker = checker.PayloadChecker(self.MockPayload())
@@ -841,7 +713,7 @@
"""Parametric testing of _CheckOperation().
Args:
- op_type_name: 'REPLACE', 'REPLACE_BZ', 'REPLACE_XZ', 'MOVE', 'BSDIFF',
+ op_type_name: 'REPLACE', 'REPLACE_BZ', 'REPLACE_XZ',
'SOURCE_COPY', 'SOURCE_BSDIFF', BROTLI_BSDIFF or 'PUFFDIFF'.
is_last: Whether we're testing the last operation in a sequence.
allow_signature: Whether we're testing a signature-capable operation.
@@ -880,8 +752,7 @@
op.type = op_type
total_src_blocks = 0
- if op_type in (common.OpType.MOVE, common.OpType.BSDIFF,
- common.OpType.SOURCE_COPY, common.OpType.SOURCE_BSDIFF,
+ if op_type in (common.OpType.SOURCE_COPY, common.OpType.SOURCE_BSDIFF,
common.OpType.PUFFDIFF, common.OpType.BROTLI_BSDIFF):
if fail_src_extents:
self.AddToMessage(op.src_extents,
@@ -895,8 +766,6 @@
payload_checker.major_version = common.CHROMEOS_MAJOR_PAYLOAD_VERSION
if op_type in (common.OpType.REPLACE, common.OpType.REPLACE_BZ):
payload_checker.minor_version = 0
- elif op_type in (common.OpType.MOVE, common.OpType.BSDIFF):
- payload_checker.minor_version = 2 if fail_bad_minor_version else 1
elif op_type in (common.OpType.SOURCE_COPY, common.OpType.SOURCE_BSDIFF):
payload_checker.minor_version = 1 if fail_bad_minor_version else 2
if op_type == common.OpType.REPLACE_XZ:
@@ -907,7 +776,7 @@
elif op_type == common.OpType.PUFFDIFF:
payload_checker.minor_version = 4 if fail_bad_minor_version else 5
- if op_type not in (common.OpType.MOVE, common.OpType.SOURCE_COPY):
+ if op_type != common.OpType.SOURCE_COPY:
if not fail_mismatched_data_offset_length:
op.data_length = 16 * block_size - 8
if fail_prev_data_offset:
@@ -944,8 +813,7 @@
if total_src_blocks:
if fail_src_length:
op.src_length = total_src_blocks * block_size + 8
- elif (op_type in (common.OpType.MOVE, common.OpType.BSDIFF,
- common.OpType.SOURCE_BSDIFF) and
+ elif (op_type == common.OpType.SOURCE_BSDIFF and
payload_checker.minor_version <= 3):
op.src_length = total_src_blocks * block_size
elif fail_src_length:
@@ -955,8 +823,7 @@
if total_dst_blocks:
if fail_dst_length:
op.dst_length = total_dst_blocks * block_size + 8
- elif (op_type in (common.OpType.MOVE, common.OpType.BSDIFF,
- common.OpType.SOURCE_BSDIFF) and
+ elif (op_type == common.OpType.SOURCE_BSDIFF and
payload_checker.minor_version <= 3):
op.dst_length = total_dst_blocks * block_size
@@ -1120,7 +987,6 @@
should_succeed = (
(minor_version == 0 and payload_type == checker._TYPE_FULL) or
- (minor_version == 1 and payload_type == checker._TYPE_DELTA) or
(minor_version == 2 and payload_type == checker._TYPE_DELTA) or
(minor_version == 3 and payload_type == checker._TYPE_DELTA) or
(minor_version == 4 and payload_type == checker._TYPE_DELTA) or
@@ -1244,8 +1110,8 @@
fail_bad_minor_version)):
return False
- # MOVE and SOURCE_COPY operations don't carry data.
- if (op_type in (common.OpType.MOVE, common.OpType.SOURCE_COPY) and (
+ # SOURCE_COPY operation does not carry data.
+ if (op_type == common.OpType.SOURCE_COPY and (
fail_mismatched_data_offset_length or fail_data_hash or
fail_prev_data_offset)):
return False
@@ -1328,9 +1194,8 @@
# Add all _CheckOperation() test cases.
AddParametricTests('CheckOperation',
{'op_type_name': ('REPLACE', 'REPLACE_BZ', 'REPLACE_XZ',
- 'MOVE', 'BSDIFF', 'SOURCE_COPY',
- 'SOURCE_BSDIFF', 'PUFFDIFF',
- 'BROTLI_BSDIFF'),
+ 'SOURCE_COPY', 'SOURCE_BSDIFF',
+ 'PUFFDIFF', 'BROTLI_BSDIFF'),
'is_last': (True, False),
'allow_signature': (True, False),
'allow_unhashed': (True, False),
@@ -1360,7 +1225,7 @@
# Add all _CheckManifestMinorVersion() test cases.
AddParametricTests('CheckManifestMinorVersion',
- {'minor_version': (None, 0, 1, 2, 3, 4, 5, 555),
+ {'minor_version': (None, 0, 2, 3, 4, 5, 555),
'payload_type': (checker._TYPE_FULL,
checker._TYPE_DELTA)})
diff --git a/scripts/update_payload/common.py b/scripts/update_payload/common.py
index 9061a75..b7b53dc 100644
--- a/scripts/update_payload/common.py
+++ b/scripts/update_payload/common.py
@@ -36,7 +36,6 @@
CHROMEOS_MAJOR_PAYLOAD_VERSION = 1
BRILLO_MAJOR_PAYLOAD_VERSION = 2
-INPLACE_MINOR_PAYLOAD_VERSION = 1
SOURCE_MINOR_PAYLOAD_VERSION = 2
OPSRCHASH_MINOR_PAYLOAD_VERSION = 3
BROTLI_BSDIFF_MINOR_PAYLOAD_VERSION = 4
@@ -55,8 +54,6 @@
_CLASS = update_metadata_pb2.InstallOperation
REPLACE = _CLASS.REPLACE
REPLACE_BZ = _CLASS.REPLACE_BZ
- MOVE = _CLASS.MOVE
- BSDIFF = _CLASS.BSDIFF
SOURCE_COPY = _CLASS.SOURCE_COPY
SOURCE_BSDIFF = _CLASS.SOURCE_BSDIFF
ZERO = _CLASS.ZERO
@@ -64,13 +61,11 @@
REPLACE_XZ = _CLASS.REPLACE_XZ
PUFFDIFF = _CLASS.PUFFDIFF
BROTLI_BSDIFF = _CLASS.BROTLI_BSDIFF
- ALL = (REPLACE, REPLACE_BZ, MOVE, BSDIFF, SOURCE_COPY, SOURCE_BSDIFF, ZERO,
+ ALL = (REPLACE, REPLACE_BZ, SOURCE_COPY, SOURCE_BSDIFF, ZERO,
DISCARD, REPLACE_XZ, PUFFDIFF, BROTLI_BSDIFF)
NAMES = {
REPLACE: 'REPLACE',
REPLACE_BZ: 'REPLACE_BZ',
- MOVE: 'MOVE',
- BSDIFF: 'BSDIFF',
SOURCE_COPY: 'SOURCE_COPY',
SOURCE_BSDIFF: 'SOURCE_BSDIFF',
ZERO: 'ZERO',
diff --git a/scripts/update_payload/test_utils.py b/scripts/update_payload/test_utils.py
index 1e2259d..f0edad5 100644
--- a/scripts/update_payload/test_utils.py
+++ b/scripts/update_payload/test_utils.py
@@ -288,11 +288,11 @@
Args:
is_kernel: whether this is a kernel (True) or rootfs (False) operation
- op_type: one of REPLACE, REPLACE_BZ, REPLACE_XZ, MOVE or BSDIFF
+ op_type: one of REPLACE, REPLACE_BZ, REPLACE_XZ.
src_extents: list of (start, length) pairs indicating src block ranges
- src_length: size of the src data in bytes (needed for BSDIFF)
+ src_length: size of the src data in bytes (needed for diff operations)
dst_extents: list of (start, length) pairs indicating dst block ranges
- dst_length: size of the dst data in bytes (needed for BSDIFF)
+ dst_length: size of the dst data in bytes (needed for diff operations)
data_blob: a data blob associated with this operation
do_hash_data_blob: whether or not to compute and add a data blob hash
"""
diff --git a/scripts/update_payload/update_metadata_pb2.py b/scripts/update_payload/update_metadata_pb2.py
index 7f1648b..6275642 100644
--- a/scripts/update_payload/update_metadata_pb2.py
+++ b/scripts/update_payload/update_metadata_pb2.py
@@ -1,19 +1,27 @@
+# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: update_metadata.proto
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
-from google.protobuf import descriptor_pb2
+from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
+_sym_db = _symbol_database.Default()
+
DESCRIPTOR = _descriptor.FileDescriptor(
name='update_metadata.proto',
package='chromeos_update_engine',
- serialized_pb='\n\x15update_metadata.proto\x12\x16\x63hromeos_update_engine\"1\n\x06\x45xtent\x12\x13\n\x0bstart_block\x18\x01 \x01(\x04\x12\x12\n\nnum_blocks\x18\x02 \x01(\x04\"z\n\nSignatures\x12@\n\nsignatures\x18\x01 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x1a*\n\tSignature\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\rPartitionInfo\x12\x0c\n\x04size\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"w\n\tImageInfo\x12\r\n\x05\x62oard\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x15\n\rbuild_channel\x18\x05 \x01(\t\x12\x15\n\rbuild_version\x18\x06 \x01(\t\"\xe6\x03\n\x10InstallOperation\x12;\n\x04type\x18\x01 \x02(\x0e\x32-.chromeos_update_engine.InstallOperation.Type\x12\x13\n\x0b\x64\x61ta_offset\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_length\x18\x03 \x01(\x04\x12\x33\n\x0bsrc_extents\x18\x04 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\nsrc_length\x18\x05 \x01(\x04\x12\x33\n\x0b\x64st_extents\x18\x06 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\ndst_length\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_sha256_hash\x18\x08 \x01(\x0c\x12\x17\n\x0fsrc_sha256_hash\x18\t \x01(\x0c\"\xa5\x01\n\x04Type\x12\x0b\n\x07REPLACE\x10\x00\x12\x0e\n\nREPLACE_BZ\x10\x01\x12\x08\n\x04MOVE\x10\x02\x12\n\n\x06\x42SDIFF\x10\x03\x12\x0f\n\x0bSOURCE_COPY\x10\x04\x12\x11\n\rSOURCE_BSDIFF\x10\x05\x12\x0e\n\nREPLACE_XZ\x10\x08\x12\x08\n\x04ZERO\x10\x06\x12\x0b\n\x07\x44ISCARD\x10\x07\x12\x11\n\rBROTLI_BSDIFF\x10\n\x12\x0c\n\x08PUFFDIFF\x10\t\"\xd7\x05\n\x0fPartitionUpdate\x12\x16\n\x0epartition_name\x18\x01 \x02(\t\x12\x17\n\x0frun_postinstall\x18\x02 \x01(\x08\x12\x18\n\x10postinstall_path\x18\x03 \x01(\t\x12\x17\n\x0f\x66ilesystem_type\x18\x04 \x01(\t\x12M\n\x17new_partition_signature\x18\x05 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x12\x41\n\x12old_partition_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x41\n\x12new_partition_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12<\n\noperations\x18\x08 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x1c\n\x14postinstall_optional\x18\t \x01(\x08\x12=\n\x15hash_tree_data_extent\x18\n \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x38\n\x10hash_tree_extent\x18\x0b \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x1b\n\x13hash_tree_algorithm\x18\x0c \x01(\t\x12\x16\n\x0ehash_tree_salt\x18\r \x01(\x0c\x12\x37\n\x0f\x66\x65\x63_data_extent\x18\x0e \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x32\n\nfec_extent\x18\x0f \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x14\n\tfec_roots\x18\x10 \x01(\r:\x01\x32\"L\n\x15\x44ynamicPartitionGroup\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x17\n\x0fpartition_names\x18\x03 \x03(\t\"Y\n\x18\x44ynamicPartitionMetadata\x12=\n\x06groups\x18\x01 \x03(\x0b\x32-.chromeos_update_engine.DynamicPartitionGroup\"\xb1\x06\n\x14\x44\x65ltaArchiveManifest\x12\x44\n\x12install_operations\x18\x01 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12K\n\x19kernel_install_operations\x18\x02 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x18\n\nblock_size\x18\x03 \x01(\r:\x04\x34\x30\x39\x36\x12\x19\n\x11signatures_offset\x18\x04 \x01(\x04\x12\x17\n\x0fsignatures_size\x18\x05 \x01(\x04\x12>\n\x0fold_kernel_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_kernel_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fold_rootfs_info\x18\x08 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_rootfs_info\x18\t \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x39\n\x0eold_image_info\x18\n \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x39\n\x0enew_image_info\x18\x0b \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x18\n\rminor_version\x18\x0c \x01(\r:\x01\x30\x12;\n\npartitions\x18\r \x03(\x0b\x32\'.chromeos_update_engine.PartitionUpdate\x12\x15\n\rmax_timestamp\x18\x0e \x01(\x03\x12T\n\x1a\x64ynamic_partition_metadata\x18\x0f \x01(\x0b\x32\x30.chromeos_update_engine.DynamicPartitionMetadataB\x02H\x03')
+ syntax='proto2',
+ serialized_options=_b('H\003'),
+ serialized_pb=_b('\n\x15update_metadata.proto\x12\x16\x63hromeos_update_engine\"1\n\x06\x45xtent\x12\x13\n\x0bstart_block\x18\x01 \x01(\x04\x12\x12\n\nnum_blocks\x18\x02 \x01(\x04\"z\n\nSignatures\x12@\n\nsignatures\x18\x01 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x1a*\n\tSignature\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\rPartitionInfo\x12\x0c\n\x04size\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"w\n\tImageInfo\x12\r\n\x05\x62oard\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x15\n\rbuild_channel\x18\x05 \x01(\t\x12\x15\n\rbuild_version\x18\x06 \x01(\t\"\xd0\x03\n\x10InstallOperation\x12;\n\x04type\x18\x01 \x02(\x0e\x32-.chromeos_update_engine.InstallOperation.Type\x12\x13\n\x0b\x64\x61ta_offset\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_length\x18\x03 \x01(\x04\x12\x33\n\x0bsrc_extents\x18\x04 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\nsrc_length\x18\x05 \x01(\x04\x12\x33\n\x0b\x64st_extents\x18\x06 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\ndst_length\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_sha256_hash\x18\x08 \x01(\x0c\x12\x17\n\x0fsrc_sha256_hash\x18\t \x01(\x0c\"\x8f\x01\n\x04Type\x12\x0b\n\x07REPLACE\x10\x00\x12\x0e\n\nREPLACE_BZ\x10\x01\x12\x0f\n\x0bSOURCE_COPY\x10\x04\x12\x11\n\rSOURCE_BSDIFF\x10\x05\x12\x0e\n\nREPLACE_XZ\x10\x08\x12\x08\n\x04ZERO\x10\x06\x12\x0b\n\x07\x44ISCARD\x10\x07\x12\x11\n\rBROTLI_BSDIFF\x10\n\x12\x0c\n\x08PUFFDIFF\x10\t\"\xd7\x05\n\x0fPartitionUpdate\x12\x16\n\x0epartition_name\x18\x01 \x02(\t\x12\x17\n\x0frun_postinstall\x18\x02 \x01(\x08\x12\x18\n\x10postinstall_path\x18\x03 \x01(\t\x12\x17\n\x0f\x66ilesystem_type\x18\x04 \x01(\t\x12M\n\x17new_partition_signature\x18\x05 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x12\x41\n\x12old_partition_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x41\n\x12new_partition_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12<\n\noperations\x18\x08 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x1c\n\x14postinstall_optional\x18\t \x01(\x08\x12=\n\x15hash_tree_data_extent\x18\n \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x38\n\x10hash_tree_extent\x18\x0b \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x1b\n\x13hash_tree_algorithm\x18\x0c \x01(\t\x12\x16\n\x0ehash_tree_salt\x18\r \x01(\x0c\x12\x37\n\x0f\x66\x65\x63_data_extent\x18\x0e \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x32\n\nfec_extent\x18\x0f \x01(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x14\n\tfec_roots\x18\x10 \x01(\r:\x01\x32\"L\n\x15\x44ynamicPartitionGroup\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x17\n\x0fpartition_names\x18\x03 \x03(\t\"Y\n\x18\x44ynamicPartitionMetadata\x12=\n\x06groups\x18\x01 \x03(\x0b\x32-.chromeos_update_engine.DynamicPartitionGroup\"\xb1\x06\n\x14\x44\x65ltaArchiveManifest\x12\x44\n\x12install_operations\x18\x01 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12K\n\x19kernel_install_operations\x18\x02 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x18\n\nblock_size\x18\x03 \x01(\r:\x04\x34\x30\x39\x36\x12\x19\n\x11signatures_offset\x18\x04 \x01(\x04\x12\x17\n\x0fsignatures_size\x18\x05 \x01(\x04\x12>\n\x0fold_kernel_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_kernel_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fold_rootfs_info\x18\x08 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_rootfs_info\x18\t \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x39\n\x0eold_image_info\x18\n \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x39\n\x0enew_image_info\x18\x0b \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x18\n\rminor_version\x18\x0c \x01(\r:\x01\x30\x12;\n\npartitions\x18\r \x03(\x0b\x32\'.chromeos_update_engine.PartitionUpdate\x12\x15\n\rmax_timestamp\x18\x0e \x01(\x03\x12T\n\x1a\x64ynamic_partition_metadata\x18\x0f \x01(\x0b\x32\x30.chromeos_update_engine.DynamicPartitionMetadataB\x02H\x03')
+)
@@ -25,54 +33,47 @@
values=[
_descriptor.EnumValueDescriptor(
name='REPLACE', index=0, number=0,
- options=None,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='REPLACE_BZ', index=1, number=1,
- options=None,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='MOVE', index=2, number=2,
- options=None,
+ name='SOURCE_COPY', index=2, number=4,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='BSDIFF', index=3, number=3,
- options=None,
+ name='SOURCE_BSDIFF', index=3, number=5,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='SOURCE_COPY', index=4, number=4,
- options=None,
+ name='REPLACE_XZ', index=4, number=8,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='SOURCE_BSDIFF', index=5, number=5,
- options=None,
+ name='ZERO', index=5, number=6,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='REPLACE_XZ', index=6, number=8,
- options=None,
+ name='DISCARD', index=6, number=7,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='ZERO', index=7, number=6,
- options=None,
+ name='BROTLI_BSDIFF', index=7, number=10,
+ serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='DISCARD', index=8, number=7,
- options=None,
- type=None),
- _descriptor.EnumValueDescriptor(
- name='BROTLI_BSDIFF', index=9, number=10,
- options=None,
- type=None),
- _descriptor.EnumValueDescriptor(
- name='PUFFDIFF', index=10, number=9,
- options=None,
+ name='PUFFDIFF', index=8, number=9,
+ serialized_options=None,
type=None),
],
containing_type=None,
- options=None,
+ serialized_options=None,
serialized_start=712,
- serialized_end=877,
+ serialized_end=855,
)
+_sym_db.RegisterEnumDescriptor(_INSTALLOPERATION_TYPE)
_EXTENT = _descriptor.Descriptor(
@@ -88,23 +89,26 @@
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='num_blocks', full_name='chromeos_update_engine.Extent.num_blocks', index=1,
number=2, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=49,
serialized_end=98,
)
@@ -123,23 +127,26 @@
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='data', full_name='chromeos_update_engine.Signatures.Signature.data', index=1,
number=2, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value="",
+ has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=180,
serialized_end=222,
)
@@ -157,16 +164,19 @@
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_SIGNATURES_SIGNATURE, ],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=100,
serialized_end=222,
)
@@ -185,23 +195,26 @@
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hash', full_name='chromeos_update_engine.PartitionInfo.hash', index=1,
number=2, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value="",
+ has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=224,
serialized_end=267,
)
@@ -217,54 +230,57 @@
_descriptor.FieldDescriptor(
name='board', full_name='chromeos_update_engine.ImageInfo.board', index=0,
number=1, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='key', full_name='chromeos_update_engine.ImageInfo.key', index=1,
number=2, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='channel', full_name='chromeos_update_engine.ImageInfo.channel', index=2,
number=3, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='version', full_name='chromeos_update_engine.ImageInfo.version', index=3,
number=4, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='build_channel', full_name='chromeos_update_engine.ImageInfo.build_channel', index=4,
number=5, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='build_version', full_name='chromeos_update_engine.ImageInfo.build_version', index=5,
number=6, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=269,
serialized_end=388,
)
@@ -283,63 +299,63 @@
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='data_offset', full_name='chromeos_update_engine.InstallOperation.data_offset', index=1,
number=2, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='data_length', full_name='chromeos_update_engine.InstallOperation.data_length', index=2,
number=3, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='src_extents', full_name='chromeos_update_engine.InstallOperation.src_extents', index=3,
number=4, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='src_length', full_name='chromeos_update_engine.InstallOperation.src_length', index=4,
number=5, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='dst_extents', full_name='chromeos_update_engine.InstallOperation.dst_extents', index=5,
number=6, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='dst_length', full_name='chromeos_update_engine.InstallOperation.dst_length', index=6,
number=7, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='data_sha256_hash', full_name='chromeos_update_engine.InstallOperation.data_sha256_hash', index=7,
number=8, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value="",
+ has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='src_sha256_hash', full_name='chromeos_update_engine.InstallOperation.src_sha256_hash', index=8,
number=9, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value="",
+ has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
@@ -347,11 +363,14 @@
enum_types=[
_INSTALLOPERATION_TYPE,
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
+ oneofs=[
+ ],
serialized_start=391,
- serialized_end=877,
+ serialized_end=855,
)
@@ -365,126 +384,129 @@
_descriptor.FieldDescriptor(
name='partition_name', full_name='chromeos_update_engine.PartitionUpdate.partition_name', index=0,
number=1, type=9, cpp_type=9, label=2,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='run_postinstall', full_name='chromeos_update_engine.PartitionUpdate.run_postinstall', index=1,
number=2, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='postinstall_path', full_name='chromeos_update_engine.PartitionUpdate.postinstall_path', index=2,
number=3, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='filesystem_type', full_name='chromeos_update_engine.PartitionUpdate.filesystem_type', index=3,
number=4, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='new_partition_signature', full_name='chromeos_update_engine.PartitionUpdate.new_partition_signature', index=4,
number=5, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='old_partition_info', full_name='chromeos_update_engine.PartitionUpdate.old_partition_info', index=5,
number=6, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='new_partition_info', full_name='chromeos_update_engine.PartitionUpdate.new_partition_info', index=6,
number=7, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='operations', full_name='chromeos_update_engine.PartitionUpdate.operations', index=7,
number=8, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='postinstall_optional', full_name='chromeos_update_engine.PartitionUpdate.postinstall_optional', index=8,
number=9, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hash_tree_data_extent', full_name='chromeos_update_engine.PartitionUpdate.hash_tree_data_extent', index=9,
number=10, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hash_tree_extent', full_name='chromeos_update_engine.PartitionUpdate.hash_tree_extent', index=10,
number=11, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hash_tree_algorithm', full_name='chromeos_update_engine.PartitionUpdate.hash_tree_algorithm', index=11,
number=12, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='hash_tree_salt', full_name='chromeos_update_engine.PartitionUpdate.hash_tree_salt', index=12,
number=13, type=12, cpp_type=9, label=1,
- has_default_value=False, default_value="",
+ has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fec_data_extent', full_name='chromeos_update_engine.PartitionUpdate.fec_data_extent', index=13,
number=14, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fec_extent', full_name='chromeos_update_engine.PartitionUpdate.fec_extent', index=14,
number=15, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fec_roots', full_name='chromeos_update_engine.PartitionUpdate.fec_roots', index=15,
number=16, type=13, cpp_type=3, label=1,
has_default_value=True, default_value=2,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
- serialized_start=880,
- serialized_end=1607,
+ oneofs=[
+ ],
+ serialized_start=858,
+ serialized_end=1585,
)
@@ -498,35 +520,38 @@
_descriptor.FieldDescriptor(
name='name', full_name='chromeos_update_engine.DynamicPartitionGroup.name', index=0,
number=1, type=9, cpp_type=9, label=2,
- has_default_value=False, default_value=unicode("", "utf-8"),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='size', full_name='chromeos_update_engine.DynamicPartitionGroup.size', index=1,
number=2, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='partition_names', full_name='chromeos_update_engine.DynamicPartitionGroup.partition_names', index=2,
number=3, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
- serialized_start=1609,
- serialized_end=1685,
+ oneofs=[
+ ],
+ serialized_start=1587,
+ serialized_end=1663,
)
@@ -543,18 +568,21 @@
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
- serialized_start=1687,
- serialized_end=1776,
+ oneofs=[
+ ],
+ serialized_start=1665,
+ serialized_end=1754,
)
@@ -571,124 +599,127 @@
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='kernel_install_operations', full_name='chromeos_update_engine.DeltaArchiveManifest.kernel_install_operations', index=1,
number=2, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='block_size', full_name='chromeos_update_engine.DeltaArchiveManifest.block_size', index=2,
number=3, type=13, cpp_type=3, label=1,
has_default_value=True, default_value=4096,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='signatures_offset', full_name='chromeos_update_engine.DeltaArchiveManifest.signatures_offset', index=3,
number=4, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='signatures_size', full_name='chromeos_update_engine.DeltaArchiveManifest.signatures_size', index=4,
number=5, type=4, cpp_type=4, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='old_kernel_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_kernel_info', index=5,
number=6, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='new_kernel_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_kernel_info', index=6,
number=7, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='old_rootfs_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_rootfs_info', index=7,
number=8, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='new_rootfs_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_rootfs_info', index=8,
number=9, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='old_image_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_image_info', index=9,
number=10, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='new_image_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_image_info', index=10,
number=11, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='minor_version', full_name='chromeos_update_engine.DeltaArchiveManifest.minor_version', index=11,
number=12, type=13, cpp_type=3, label=1,
has_default_value=True, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='partitions', full_name='chromeos_update_engine.DeltaArchiveManifest.partitions', index=12,
number=13, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='max_timestamp', full_name='chromeos_update_engine.DeltaArchiveManifest.max_timestamp', index=13,
number=14, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='dynamic_partition_metadata', full_name='chromeos_update_engine.DeltaArchiveManifest.dynamic_partition_metadata', index=14,
number=15, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
- options=None),
+ serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
- options=None,
+ serialized_options=None,
is_extendable=False,
+ syntax='proto2',
extension_ranges=[],
- serialized_start=1779,
- serialized_end=2596,
+ oneofs=[
+ ],
+ serialized_start=1757,
+ serialized_end=2574,
)
-_SIGNATURES_SIGNATURE.containing_type = _SIGNATURES;
+_SIGNATURES_SIGNATURE.containing_type = _SIGNATURES
_SIGNATURES.fields_by_name['signatures'].message_type = _SIGNATURES_SIGNATURE
_INSTALLOPERATION.fields_by_name['type'].enum_type = _INSTALLOPERATION_TYPE
_INSTALLOPERATION.fields_by_name['src_extents'].message_type = _EXTENT
_INSTALLOPERATION.fields_by_name['dst_extents'].message_type = _EXTENT
-_INSTALLOPERATION_TYPE.containing_type = _INSTALLOPERATION;
+_INSTALLOPERATION_TYPE.containing_type = _INSTALLOPERATION
_PARTITIONUPDATE.fields_by_name['new_partition_signature'].message_type = _SIGNATURES_SIGNATURE
_PARTITIONUPDATE.fields_by_name['old_partition_info'].message_type = _PARTITIONINFO
_PARTITIONUPDATE.fields_by_name['new_partition_info'].message_type = _PARTITIONINFO
@@ -717,68 +748,79 @@
DESCRIPTOR.message_types_by_name['DynamicPartitionGroup'] = _DYNAMICPARTITIONGROUP
DESCRIPTOR.message_types_by_name['DynamicPartitionMetadata'] = _DYNAMICPARTITIONMETADATA
DESCRIPTOR.message_types_by_name['DeltaArchiveManifest'] = _DELTAARCHIVEMANIFEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-class Extent(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _EXTENT
-
+Extent = _reflection.GeneratedProtocolMessageType('Extent', (_message.Message,), dict(
+ DESCRIPTOR = _EXTENT,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.Extent)
+ ))
+_sym_db.RegisterMessage(Extent)
-class Signatures(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
+Signatures = _reflection.GeneratedProtocolMessageType('Signatures', (_message.Message,), dict(
- class Signature(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _SIGNATURES_SIGNATURE
-
+ Signature = _reflection.GeneratedProtocolMessageType('Signature', (_message.Message,), dict(
+ DESCRIPTOR = _SIGNATURES_SIGNATURE,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.Signatures.Signature)
- DESCRIPTOR = _SIGNATURES
-
+ ))
+ ,
+ DESCRIPTOR = _SIGNATURES,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.Signatures)
+ ))
+_sym_db.RegisterMessage(Signatures)
+_sym_db.RegisterMessage(Signatures.Signature)
-class PartitionInfo(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _PARTITIONINFO
-
+PartitionInfo = _reflection.GeneratedProtocolMessageType('PartitionInfo', (_message.Message,), dict(
+ DESCRIPTOR = _PARTITIONINFO,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.PartitionInfo)
+ ))
+_sym_db.RegisterMessage(PartitionInfo)
-class ImageInfo(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _IMAGEINFO
-
+ImageInfo = _reflection.GeneratedProtocolMessageType('ImageInfo', (_message.Message,), dict(
+ DESCRIPTOR = _IMAGEINFO,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.ImageInfo)
+ ))
+_sym_db.RegisterMessage(ImageInfo)
-class InstallOperation(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _INSTALLOPERATION
-
+InstallOperation = _reflection.GeneratedProtocolMessageType('InstallOperation', (_message.Message,), dict(
+ DESCRIPTOR = _INSTALLOPERATION,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.InstallOperation)
+ ))
+_sym_db.RegisterMessage(InstallOperation)
-class PartitionUpdate(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _PARTITIONUPDATE
-
+PartitionUpdate = _reflection.GeneratedProtocolMessageType('PartitionUpdate', (_message.Message,), dict(
+ DESCRIPTOR = _PARTITIONUPDATE,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.PartitionUpdate)
+ ))
+_sym_db.RegisterMessage(PartitionUpdate)
-class DynamicPartitionGroup(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _DYNAMICPARTITIONGROUP
-
+DynamicPartitionGroup = _reflection.GeneratedProtocolMessageType('DynamicPartitionGroup', (_message.Message,), dict(
+ DESCRIPTOR = _DYNAMICPARTITIONGROUP,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.DynamicPartitionGroup)
+ ))
+_sym_db.RegisterMessage(DynamicPartitionGroup)
-class DynamicPartitionMetadata(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _DYNAMICPARTITIONMETADATA
-
+DynamicPartitionMetadata = _reflection.GeneratedProtocolMessageType('DynamicPartitionMetadata', (_message.Message,), dict(
+ DESCRIPTOR = _DYNAMICPARTITIONMETADATA,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.DynamicPartitionMetadata)
+ ))
+_sym_db.RegisterMessage(DynamicPartitionMetadata)
-class DeltaArchiveManifest(_message.Message):
- __metaclass__ = _reflection.GeneratedProtocolMessageType
- DESCRIPTOR = _DELTAARCHIVEMANIFEST
-
+DeltaArchiveManifest = _reflection.GeneratedProtocolMessageType('DeltaArchiveManifest', (_message.Message,), dict(
+ DESCRIPTOR = _DELTAARCHIVEMANIFEST,
+ __module__ = 'update_metadata_pb2'
# @@protoc_insertion_point(class_scope:chromeos_update_engine.DeltaArchiveManifest)
+ ))
+_sym_db.RegisterMessage(DeltaArchiveManifest)
-DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), 'H\003')
+DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)
diff --git a/update_metadata.proto b/update_metadata.proto
index b0e8154..3382f84 100644
--- a/update_metadata.proto
+++ b/update_metadata.proto
@@ -153,10 +153,10 @@
message InstallOperation {
enum Type {
- REPLACE = 0; // Replace destination extents w/ attached data
- REPLACE_BZ = 1; // Replace destination extents w/ attached bzipped data
- MOVE = 2; // Move source extents to destination extents
- BSDIFF = 3; // The data is a bsdiff binary diff
+ REPLACE = 0; // Replace destination extents w/ attached data.
+ REPLACE_BZ = 1; // Replace destination extents w/ attached bzipped data.
+ MOVE = 2 [deprecated = true]; // Move source extents to target extents.
+ BSDIFF = 3 [deprecated = true]; // The data is a bsdiff binary diff.
// On minor version 2 or newer, these operations are supported:
SOURCE_COPY = 4; // Copy from source to target partition