diff options
-rw-r--r-- | common/dynamic_partition_control_interface.h | 7 | ||||
-rw-r--r-- | common/dynamic_partition_control_stub.cc | 7 | ||||
-rw-r--r-- | common/dynamic_partition_control_stub.h | 5 | ||||
-rw-r--r-- | dynamic_partition_control_android.cc | 57 | ||||
-rw-r--r-- | dynamic_partition_control_android.h | 27 | ||||
-rw-r--r-- | dynamic_partition_control_android_unittest.cc | 8 | ||||
-rw-r--r-- | mock_dynamic_partition_control.h | 4 | ||||
-rw-r--r-- | payload_consumer/delta_performer.cc | 25 | ||||
-rw-r--r-- | payload_consumer/filesystem_verifier_action.cc | 15 | ||||
-rw-r--r-- | payload_consumer/filesystem_verifier_action.h | 12 | ||||
-rw-r--r-- | payload_consumer/filesystem_verifier_action_unittest.cc | 8 | ||||
-rw-r--r-- | payload_consumer/install_plan.h | 4 | ||||
-rw-r--r-- | payload_consumer/partition_update_generator_android.cc | 56 | ||||
-rw-r--r-- | payload_consumer/partition_update_generator_android.h | 3 | ||||
-rw-r--r-- | payload_generator/generate_delta_main.cc | 4 | ||||
-rw-r--r-- | update_attempter.cc | 4 | ||||
-rw-r--r-- | update_attempter_android.cc | 4 | ||||
-rw-r--r-- | update_attempter_unittest.cc | 3 |
18 files changed, 169 insertions, 84 deletions
diff --git a/common/dynamic_partition_control_interface.h b/common/dynamic_partition_control_interface.h index 7289deee..7c2d0b0c 100644 --- a/common/dynamic_partition_control_interface.h +++ b/common/dynamic_partition_control_interface.h @@ -130,6 +130,13 @@ class DynamicPartitionControlInterface { // the result in |path|. Returns true on success. // Sample result: /dev/block/by-name/ virtual bool GetDeviceDir(std::string* path) = 0; + + // Verifies that the untouched dynamic partitions in the target metadata have + // the same extents as the source metadata. + virtual bool VerifyExtentsForUntouchedPartitions( + uint32_t source_slot, + uint32_t target_slot, + const std::vector<std::string>& partitions) = 0; }; } // namespace chromeos_update_engine diff --git a/common/dynamic_partition_control_stub.cc b/common/dynamic_partition_control_stub.cc index cde36afc..5a8ca434 100644 --- a/common/dynamic_partition_control_stub.cc +++ b/common/dynamic_partition_control_stub.cc @@ -76,4 +76,11 @@ bool DynamicPartitionControlStub::GetDeviceDir(std::string* path) { return true; } +bool DynamicPartitionControlStub::VerifyExtentsForUntouchedPartitions( + uint32_t source_slot, + uint32_t target_slot, + const std::vector<std::string>& partitions) { + return true; +} + } // namespace chromeos_update_engine diff --git a/common/dynamic_partition_control_stub.h b/common/dynamic_partition_control_stub.h index 28e3e6a5..94dba1bc 100644 --- a/common/dynamic_partition_control_stub.h +++ b/common/dynamic_partition_control_stub.h @@ -51,6 +51,11 @@ class DynamicPartitionControlStub : public DynamicPartitionControlInterface { bool ListDynamicPartitionsForSlot( uint32_t current_slot, std::vector<std::string>* partitions) override; bool GetDeviceDir(std::string* path) override; + + bool VerifyExtentsForUntouchedPartitions( + uint32_t source_slot, + uint32_t target_slot, + const std::vector<std::string>& partitions) override; }; } // namespace chromeos_update_engine diff --git a/dynamic_partition_control_android.cc b/dynamic_partition_control_android.cc index 6817c21e..ba749d97 100644 --- a/dynamic_partition_control_android.cc +++ b/dynamic_partition_control_android.cc @@ -293,9 +293,16 @@ bool DynamicPartitionControlAndroid::GetDmDevicePathByName( std::unique_ptr<MetadataBuilder> DynamicPartitionControlAndroid::LoadMetadataBuilder( - const std::string& super_device, uint32_t source_slot) { - return LoadMetadataBuilder( - super_device, source_slot, BootControlInterface::kInvalidSlot); + const std::string& super_device, uint32_t slot) { + auto builder = MetadataBuilder::New(PartitionOpener(), super_device, slot); + if (builder == nullptr) { + LOG(WARNING) << "No metadata slot " << BootControlInterface::SlotName(slot) + << " in " << super_device; + return nullptr; + } + LOG(INFO) << "Loaded metadata from slot " + << BootControlInterface::SlotName(slot) << " in " << super_device; + return builder; } std::unique_ptr<MetadataBuilder> @@ -303,26 +310,19 @@ DynamicPartitionControlAndroid::LoadMetadataBuilder( const std::string& super_device, uint32_t source_slot, uint32_t target_slot) { - std::unique_ptr<MetadataBuilder> builder; - if (target_slot == BootControlInterface::kInvalidSlot) { - builder = - MetadataBuilder::New(PartitionOpener(), super_device, source_slot); - } else { - bool always_keep_source_slot = !target_supports_snapshot_; - builder = MetadataBuilder::NewForUpdate(PartitionOpener(), - super_device, - source_slot, - target_slot, - always_keep_source_slot); - } - + bool always_keep_source_slot = !target_supports_snapshot_; + auto builder = MetadataBuilder::NewForUpdate(PartitionOpener(), + super_device, + source_slot, + target_slot, + always_keep_source_slot); if (builder == nullptr) { LOG(WARNING) << "No metadata slot " << BootControlInterface::SlotName(source_slot) << " in " << super_device; return nullptr; } - LOG(INFO) << "Loaded metadata from slot " + LOG(INFO) << "Created metadata for new update from slot " << BootControlInterface::SlotName(source_slot) << " in " << super_device; return builder; @@ -495,6 +495,7 @@ bool DynamicPartitionControlAndroid::PreparePartitionsForUpdate( } } + // TODO(xunchang) support partial update on non VAB enabled devices. TEST_AND_RETURN_FALSE(PrepareDynamicPartitionsForUpdate( source_slot, target_slot, manifest, delete_source)); @@ -1113,6 +1114,28 @@ bool DynamicPartitionControlAndroid::ListDynamicPartitionsForSlot( return true; } +bool DynamicPartitionControlAndroid::VerifyExtentsForUntouchedPartitions( + uint32_t source_slot, + uint32_t target_slot, + const std::vector<std::string>& partitions) { + std::string device_dir_str; + TEST_AND_RETURN_FALSE(GetDeviceDir(&device_dir_str)); + base::FilePath device_dir(device_dir_str); + + auto source_super_device = + device_dir.Append(GetSuperPartitionName(source_slot)).value(); + auto source_builder = LoadMetadataBuilder(source_super_device, source_slot); + TEST_AND_RETURN_FALSE(source_builder != nullptr); + + auto target_super_device = + device_dir.Append(GetSuperPartitionName(target_slot)).value(); + auto target_builder = LoadMetadataBuilder(target_super_device, target_slot); + TEST_AND_RETURN_FALSE(target_builder != nullptr); + + return MetadataBuilder::VerifyExtentsAgainstSourceMetadata( + *source_builder, source_slot, *target_builder, target_slot, partitions); +} + bool DynamicPartitionControlAndroid::ExpectMetadataMounted() { // No need to mount metadata for non-Virtual A/B devices. if (!GetVirtualAbFeatureFlag().IsEnabled()) { diff --git a/dynamic_partition_control_android.h b/dynamic_partition_control_android.h index 69026a40..08656fdc 100644 --- a/dynamic_partition_control_android.h +++ b/dynamic_partition_control_android.h @@ -57,6 +57,11 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { bool ListDynamicPartitionsForSlot( uint32_t current_slot, std::vector<std::string>* partitions) override; + bool VerifyExtentsForUntouchedPartitions( + uint32_t source_slot, + uint32_t target_slot, + const std::vector<std::string>& partitions) override; + bool GetDeviceDir(std::string* path) override; // Return the device for partition |partition_name| at slot |slot|. @@ -85,16 +90,14 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { virtual bool UnmapPartitionOnDeviceMapper( const std::string& target_partition_name); - // Retrieve metadata from |super_device| at slot |source_slot|. - // - // If |target_slot| != kInvalidSlot, before returning the metadata, this - // function modifies the metadata so that during updates, the metadata can be - // written to |target_slot|. In particular, on retrofit devices, the returned - // metadata automatically includes block devices at |target_slot|. - // - // If |target_slot| == kInvalidSlot, this function returns metadata at - // |source_slot| without modifying it. This is the same as - // LoadMetadataBuilder(const std::string&, uint32_t). + // Retrieves metadata from |super_device| at slot |slot|. + virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder( + const std::string& super_device, uint32_t slot); + + // Retrieves metadata from |super_device| at slot |source_slot|. And modifies + // the metadata so that during updates, the metadata can be written to + // |target_slot|. In particular, on retrofit devices, the returned metadata + // automatically includes block devices at |target_slot|. virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder( const std::string& super_device, uint32_t source_slot, @@ -133,10 +136,6 @@ class DynamicPartitionControlAndroid : public DynamicPartitionControlInterface { virtual bool GetDmDevicePathByName(const std::string& name, std::string* path); - // Retrieve metadata from |super_device| at slot |source_slot|. - virtual std::unique_ptr<android::fs_mgr::MetadataBuilder> LoadMetadataBuilder( - const std::string& super_device, uint32_t source_slot); - // Return the name of the super partition (which stores super partition // metadata) for a given slot. virtual std::string GetSuperPartitionName(uint32_t slot); diff --git a/dynamic_partition_control_android_unittest.cc b/dynamic_partition_control_android_unittest.cc index 37381708..4154b36c 100644 --- a/dynamic_partition_control_android_unittest.cc +++ b/dynamic_partition_control_android_unittest.cc @@ -115,6 +115,14 @@ class DynamicPartitionControlAndroidTest : public ::testing::Test { const PartitionSuffixSizes& sizes, uint32_t partition_attr = 0) { EXPECT_CALL(dynamicControl(), + LoadMetadataBuilder(GetSuperDevice(slot), slot)) + .Times(AnyNumber()) + .WillRepeatedly(Invoke([sizes, partition_attr](auto, auto) { + return NewFakeMetadata(PartitionSuffixSizesToManifest(sizes), + partition_attr); + })); + + EXPECT_CALL(dynamicControl(), LoadMetadataBuilder(GetSuperDevice(slot), slot, _)) .Times(AnyNumber()) .WillRepeatedly(Invoke([sizes, partition_attr](auto, auto, auto) { diff --git a/mock_dynamic_partition_control.h b/mock_dynamic_partition_control.h index 1aaebd8b..e85df327 100644 --- a/mock_dynamic_partition_control.h +++ b/mock_dynamic_partition_control.h @@ -52,6 +52,10 @@ class MockDynamicPartitionControlAndroid (override)); MOCK_METHOD(std::unique_ptr<::android::fs_mgr::MetadataBuilder>, LoadMetadataBuilder, + (const std::string&, uint32_t), + (override)); + MOCK_METHOD(std::unique_ptr<::android::fs_mgr::MetadataBuilder>, + LoadMetadataBuilder, (const std::string&, uint32_t, uint32_t), (override)); MOCK_METHOD(bool, diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc index af1baa4a..7d837db4 100644 --- a/payload_consumer/delta_performer.cc +++ b/payload_consumer/delta_performer.cc @@ -806,15 +806,32 @@ bool DeltaPerformer::ParseManifestPartitions(ErrorCode* error) { auto generator = partition_update_generator::Create(boot_control_, manifest_.block_size()); - std::vector<PartitionUpdate> other_partitions; + std::vector<PartitionUpdate> untouched_static_partitions; TEST_AND_RETURN_FALSE( generator->GenerateOperationsForPartitionsNotInPayload( install_plan_->source_slot, install_plan_->target_slot, touched_partitions, - &other_partitions)); - partitions_.insert( - partitions_.end(), other_partitions.begin(), other_partitions.end()); + &untouched_static_partitions)); + partitions_.insert(partitions_.end(), + untouched_static_partitions.begin(), + untouched_static_partitions.end()); + + // Save the untouched dynamic partitions in install plan. + std::vector<std::string> dynamic_partitions; + if (!boot_control_->GetDynamicPartitionControl() + ->ListDynamicPartitionsForSlot(install_plan_->source_slot, + &dynamic_partitions)) { + LOG(ERROR) << "Failed to load dynamic partitions from slot " + << install_plan_->source_slot; + return false; + } + install_plan_->untouched_dynamic_partitions.clear(); + for (const auto& name : dynamic_partitions) { + if (touched_partitions.find(name) == touched_partitions.end()) { + install_plan_->untouched_dynamic_partitions.push_back(name); + } + } } // Fill in the InstallPlan::partitions based on the partitions from the diff --git a/payload_consumer/filesystem_verifier_action.cc b/payload_consumer/filesystem_verifier_action.cc index 5b2b5f43..61917ea5 100644 --- a/payload_consumer/filesystem_verifier_action.cc +++ b/payload_consumer/filesystem_verifier_action.cc @@ -28,6 +28,7 @@ #include <base/bind.h> #include <brillo/data_encoding.h> #include <brillo/streams/file_stream.h> +#include <base/strings/string_util.h> #include "update_engine/common/utils.h" @@ -89,6 +90,20 @@ void FilesystemVerifierAction::UpdateProgress(double progress) { void FilesystemVerifierAction::StartPartitionHashing() { if (partition_index_ == install_plan_.partitions.size()) { + if (!install_plan_.untouched_dynamic_partitions.empty()) { + LOG(INFO) << "Verifying extents of untouched dynamic partitions [" + << base::JoinString(install_plan_.untouched_dynamic_partitions, + ", ") + << "]"; + if (!dynamic_control_->VerifyExtentsForUntouchedPartitions( + install_plan_.source_slot, + install_plan_.target_slot, + install_plan_.untouched_dynamic_partitions)) { + Cleanup(ErrorCode::kFilesystemVerifierError); + return; + } + } + Cleanup(ErrorCode::kSuccess); return; } diff --git a/payload_consumer/filesystem_verifier_action.h b/payload_consumer/filesystem_verifier_action.h index 7d179dfc..6a8823a5 100644 --- a/payload_consumer/filesystem_verifier_action.h +++ b/payload_consumer/filesystem_verifier_action.h @@ -57,8 +57,13 @@ class FilesystemVerifyDelegate { class FilesystemVerifierAction : public InstallPlanAction { public: - FilesystemVerifierAction() - : verity_writer_(verity_writer::CreateVerityWriter()) {} + explicit FilesystemVerifierAction( + DynamicPartitionControlInterface* dynamic_control) + : verity_writer_(verity_writer::CreateVerityWriter()), + dynamic_control_(dynamic_control) { + CHECK(dynamic_control_); + } + ~FilesystemVerifierAction() override = default; void PerformAction() override; @@ -123,6 +128,9 @@ class FilesystemVerifierAction : public InstallPlanAction { // Write verity data of the current partition. std::unique_ptr<VerityWriterInterface> verity_writer_; + // Verifies the untouched dynamic partitions for partial updates. + DynamicPartitionControlInterface* dynamic_control_{nullptr}; + // Reads and hashes this many bytes from the head of the input stream. When // the partition starts to be hashed, this field is initialized from the // corresponding InstallPlan::Partition size which is the total size diff --git a/payload_consumer/filesystem_verifier_action_unittest.cc b/payload_consumer/filesystem_verifier_action_unittest.cc index cb33404d..2971849c 100644 --- a/payload_consumer/filesystem_verifier_action_unittest.cc +++ b/payload_consumer/filesystem_verifier_action_unittest.cc @@ -27,6 +27,7 @@ #include <brillo/secure_blob.h> #include <gtest/gtest.h> +#include "update_engine/common/dynamic_partition_control_stub.h" #include "update_engine/common/hash_calculator.h" #include "update_engine/common/test_utils.h" #include "update_engine/common/utils.h" @@ -51,6 +52,7 @@ class FilesystemVerifierActionTest : public ::testing::Test { brillo::FakeMessageLoop loop_{nullptr}; ActionProcessor processor_; + DynamicPartitionControlStub dynamic_control_stub_; }; class FilesystemVerifierActionTestDelegate : public ActionProcessorDelegate { @@ -188,7 +190,8 @@ bool FilesystemVerifierActionTest::DoTest(bool terminate_early, void FilesystemVerifierActionTest::BuildActions( const InstallPlan& install_plan) { auto feeder_action = std::make_unique<ObjectFeederAction<InstallPlan>>(); - auto verifier_action = std::make_unique<FilesystemVerifierAction>(); + auto verifier_action = + std::make_unique<FilesystemVerifierAction>(&dynamic_control_stub_); auto collector_action = std::make_unique<ObjectCollectorAction<InstallPlan>>(); @@ -217,7 +220,8 @@ class FilesystemVerifierActionTest2Delegate : public ActionProcessorDelegate { }; TEST_F(FilesystemVerifierActionTest, MissingInputObjectTest) { - auto copier_action = std::make_unique<FilesystemVerifierAction>(); + auto copier_action = + std::make_unique<FilesystemVerifierAction>(&dynamic_control_stub_); auto collector_action = std::make_unique<ObjectCollectorAction<InstallPlan>>(); diff --git a/payload_consumer/install_plan.h b/payload_consumer/install_plan.h index 63178bd8..f04c6504 100644 --- a/payload_consumer/install_plan.h +++ b/payload_consumer/install_plan.h @@ -158,6 +158,10 @@ struct InstallPlan { // If not blank, a base-64 encoded representation of the PEM-encoded // public key in the response. std::string public_key_rsa; + + // The name of dynamic partitions not included in the payload. Only used + // for partial updates. + std::vector<std::string> untouched_dynamic_partitions; }; class InstallPlanAction; diff --git a/payload_consumer/partition_update_generator_android.cc b/payload_consumer/partition_update_generator_android.cc index aa3f2e57..5768dd6f 100644 --- a/payload_consumer/partition_update_generator_android.cc +++ b/payload_consumer/partition_update_generator_android.cc @@ -50,25 +50,14 @@ bool PartitionUpdateGeneratorAndroid:: BootControlInterface::Slot target_slot, const std::set<std::string>& partitions_in_payload, std::vector<PartitionUpdate>* update_list) { - auto ret = GetStaticAbPartitionsOnDevice(); - if (!ret.has_value()) { + auto ab_partitions = GetStaticAbPartitionsOnDevice(); + if (!ab_partitions.has_value()) { LOG(ERROR) << "Failed to load static a/b partitions"; return false; } - auto ab_partitions = ret.value(); - - // Add the dynamic partitions. - auto dynamic_control = boot_control_->GetDynamicPartitionControl(); - std::vector<std::string> dynamic_partitions; - if (!dynamic_control->ListDynamicPartitionsForSlot(source_slot, - &dynamic_partitions)) { - LOG(ERROR) << "Failed to load dynamic partitions from slot " << source_slot; - return false; - } - ab_partitions.insert(dynamic_partitions.begin(), dynamic_partitions.end()); std::vector<PartitionUpdate> partition_updates; - for (const auto& partition_name : ab_partitions) { + for (const auto& partition_name : ab_partitions.value()) { if (partitions_in_payload.find(partition_name) != partitions_in_payload.end()) { LOG(INFO) << partition_name << " has included in payload"; @@ -159,13 +148,15 @@ PartitionUpdateGeneratorAndroid::CreatePartitionUpdate( return std::nullopt; } - if (is_source_dynamic != is_target_dynamic) { - LOG(ERROR) << "Source slot " << source_slot << " for partition " - << partition_name << " is " << (is_source_dynamic ? "" : "not") - << " dynamic, but target slot " << target_slot << " is " + if (is_source_dynamic || is_target_dynamic) { + LOG(ERROR) << "Partition " << partition_name << " is expected to be a" + << " static partition. source slot is " + << (is_source_dynamic ? "" : "not") + << " dynamic, and target slot " << target_slot << " is " << (is_target_dynamic ? "" : "not") << " dynamic."; return std::nullopt; } + auto source_size = utils::FileSize(source_device); auto target_size = utils::FileSize(target_device); if (source_size == -1 || target_size == -1 || source_size != target_size || @@ -175,11 +166,8 @@ PartitionUpdateGeneratorAndroid::CreatePartitionUpdate( return std::nullopt; } - return CreatePartitionUpdate(partition_name, - source_device, - target_device, - source_size, - is_source_dynamic); + return CreatePartitionUpdate( + partition_name, source_device, target_device, source_size); } std::optional<PartitionUpdate> @@ -187,8 +175,7 @@ PartitionUpdateGeneratorAndroid::CreatePartitionUpdate( const std::string& partition_name, const std::string& source_device, const std::string& target_device, - int64_t partition_size, - bool is_dynamic) { + int64_t partition_size) { PartitionUpdate partition_update; partition_update.set_partition_name(partition_name); auto old_partition_info = partition_update.mutable_old_partition_info(); @@ -202,18 +189,15 @@ PartitionUpdateGeneratorAndroid::CreatePartitionUpdate( auto new_partition_info = partition_update.mutable_new_partition_info(); new_partition_info->set_size(partition_size); new_partition_info->set_hash(raw_hash->data(), raw_hash->size()); - // TODO(xunchang) TBD, should we skip hashing and verification of the - // dynamic partitions not in payload? - if (!is_dynamic) { - auto copy_operation = partition_update.add_operations(); - copy_operation->set_type(InstallOperation::SOURCE_COPY); - Extent copy_extent; - copy_extent.set_start_block(0); - copy_extent.set_num_blocks(partition_size / block_size_); - *copy_operation->add_src_extents() = copy_extent; - *copy_operation->add_dst_extents() = copy_extent; - } + auto copy_operation = partition_update.add_operations(); + copy_operation->set_type(InstallOperation::SOURCE_COPY); + Extent copy_extent; + copy_extent.set_start_block(0); + copy_extent.set_num_blocks(partition_size / block_size_); + + *copy_operation->add_src_extents() = copy_extent; + *copy_operation->add_dst_extents() = copy_extent; return partition_update; } diff --git a/payload_consumer/partition_update_generator_android.h b/payload_consumer/partition_update_generator_android.h index 8f33077f..97b7d838 100644 --- a/payload_consumer/partition_update_generator_android.h +++ b/payload_consumer/partition_update_generator_android.h @@ -56,8 +56,7 @@ class PartitionUpdateGeneratorAndroid const std::string& partition_name, const std::string& source_device, const std::string& target_device, - int64_t partition_size, - bool is_dynamic); + int64_t partition_size); std::optional<PartitionUpdate> CreatePartitionUpdate( const std::string& partition_name, diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc index f7df2118..eb00333b 100644 --- a/payload_generator/generate_delta_main.cc +++ b/payload_generator/generate_delta_main.cc @@ -252,8 +252,8 @@ bool ApplyPayload(const string& payload_file, nullptr, new FileFetcher(), true /* interactive */); - auto filesystem_verifier_action = - std::make_unique<FilesystemVerifierAction>(); + auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>( + fake_boot_control.GetDynamicPartitionControl()); BondActions(install_plan_action.get(), download_action.get()); BondActions(download_action.get(), filesystem_verifier_action.get()); diff --git a/update_attempter.cc b/update_attempter.cc index 60c2c36c..f37973ef 100644 --- a/update_attempter.cc +++ b/update_attempter.cc @@ -818,8 +818,8 @@ void UpdateAttempter::BuildUpdateActions(bool interactive) { system_state_->hardware()), false, session_id_); - auto filesystem_verifier_action = - std::make_unique<FilesystemVerifierAction>(); + auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>( + system_state_->boot_control()->GetDynamicPartitionControl()); auto update_complete_action = std::make_unique<OmahaRequestAction>( system_state_, new OmahaEvent(OmahaEvent::kTypeUpdateComplete), diff --git a/update_attempter_android.cc b/update_attempter_android.cc index a554d380..7fc13e11 100644 --- a/update_attempter_android.cc +++ b/update_attempter_android.cc @@ -738,8 +738,8 @@ void UpdateAttempterAndroid::BuildUpdateActions(HttpFetcher* fetcher) { true /* interactive */); download_action->set_delegate(this); download_action->set_base_offset(base_offset_); - auto filesystem_verifier_action = - std::make_unique<FilesystemVerifierAction>(); + auto filesystem_verifier_action = std::make_unique<FilesystemVerifierAction>( + boot_control_->GetDynamicPartitionControl()); auto postinstall_runner_action = std::make_unique<PostinstallRunnerAction>(boot_control_, hardware_); filesystem_verifier_action->set_delegate(this); diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc index 0086dd5d..305dbdb9 100644 --- a/update_attempter_unittest.cc +++ b/update_attempter_unittest.cc @@ -663,7 +663,8 @@ TEST_F(UpdateAttempterTest, GetErrorCodeForActionTest) { EXPECT_EQ( ErrorCode::kOmahaResponseHandlerError, GetErrorCodeForAction(&omaha_response_handler_action, ErrorCode::kError)); - FilesystemVerifierAction filesystem_verifier_action; + DynamicPartitionControlStub dynamic_control_stub; + FilesystemVerifierAction filesystem_verifier_action(&dynamic_control_stub); EXPECT_EQ( ErrorCode::kFilesystemVerifierError, GetErrorCodeForAction(&filesystem_verifier_action, ErrorCode::kError)); |