summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianjie <xunchang@google.com>2020-06-30 12:26:25 -0700
committerTianjie Xu <xunchang@google.com>2020-07-09 20:15:08 +0000
commit24f960986b1337f14eb8e86382cb62aed5d1153c (patch)
treeea47bdb983a0b692fc02fe2b5e84029d7d6002f7
parentd2da7b1990e0fee1c99bf64aa562cef572aaa061 (diff)
Verify the extents for untouched dynamic partitions during partial update
For partial updates, the metadata for untouched dynamic partitions are just copied over to the target slot. So, verifying the extents of these partitions in the target metadata should be sufficient for correctness. This saves the work to read & hash the bytes on these partitions for each resumed update. Bug: 151088567 Test: unit tests pass, apply a partial update Change-Id: I9d40ed2643e145a1546ea17b146fcdcfb91f213f
-rw-r--r--common/dynamic_partition_control_interface.h7
-rw-r--r--common/dynamic_partition_control_stub.cc7
-rw-r--r--common/dynamic_partition_control_stub.h5
-rw-r--r--dynamic_partition_control_android.cc57
-rw-r--r--dynamic_partition_control_android.h27
-rw-r--r--dynamic_partition_control_android_unittest.cc8
-rw-r--r--mock_dynamic_partition_control.h4
-rw-r--r--payload_consumer/delta_performer.cc25
-rw-r--r--payload_consumer/filesystem_verifier_action.cc15
-rw-r--r--payload_consumer/filesystem_verifier_action.h12
-rw-r--r--payload_consumer/filesystem_verifier_action_unittest.cc8
-rw-r--r--payload_consumer/install_plan.h4
-rw-r--r--payload_consumer/partition_update_generator_android.cc56
-rw-r--r--payload_consumer/partition_update_generator_android.h3
-rw-r--r--payload_generator/generate_delta_main.cc4
-rw-r--r--update_attempter.cc4
-rw-r--r--update_attempter_android.cc4
-rw-r--r--update_attempter_unittest.cc3
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));