Allow ProcessUpdateState to be paused.

Change callback type of ProcessUpdateState to bool() so that, when callback
returns false, immediately returns Merging.

Test: libsnapshot_test
Bug: 147696014

Change-Id: I9dcb8e1658b95216c0f1991e2e4c1ea2e7e7b2e5
This commit is contained in:
Yifan Hong 2020-02-19 13:14:05 -08:00
parent 9aa7bbe161
commit 6187030652
2 changed files with 15 additions and 7 deletions

View file

@ -148,7 +148,11 @@ class SnapshotManager final {
// /data is mounted.
//
// If a merge is in progress, this function will block until the merge is
// completed. If a merge or update was cancelled, this will clean up any
// completed.
// - Callback is called periodically during the merge. If callback()
// returns false during the merge, ProcessUpdateState() will pause
// and returns Merging.
// If a merge or update was cancelled, this will clean up any
// update artifacts and return.
//
// Note that after calling this, GetUpdateState() may still return that a
@ -168,7 +172,7 @@ class SnapshotManager final {
//
// The optional callback allows the caller to periodically check the
// progress with GetUpdateState().
UpdateState ProcessUpdateState(const std::function<void()>& callback = {},
UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
const std::function<bool()>& before_cancel = {});
// Initiate the merge if necessary, then wait for the merge to finish.

View file

@ -794,7 +794,7 @@ bool SnapshotManager::QuerySnapshotStatus(const std::string& dm_name, std::strin
// Note that when a merge fails, we will *always* try again to complete the
// merge each time the device boots. There is no harm in doing so, and if
// the problem was transient, we might manage to get a new outcome.
UpdateState SnapshotManager::ProcessUpdateState(const std::function<void()>& callback,
UpdateState SnapshotManager::ProcessUpdateState(const std::function<bool()>& callback,
const std::function<bool()>& before_cancel) {
while (true) {
UpdateState state = CheckMergeState(before_cancel);
@ -807,8 +807,8 @@ UpdateState SnapshotManager::ProcessUpdateState(const std::function<void()>& cal
return state;
}
if (callback) {
callback();
if (callback && !callback()) {
return state;
}
// This wait is not super time sensitive, so we have a relatively
@ -2413,13 +2413,14 @@ UpdateState SnapshotManager::InitiateMergeAndWait(SnapshotMergeReport* stats_rep
SnapshotMergeStats merge_stats(*this);
unsigned int last_progress = 0;
auto callback = [&]() -> void {
auto callback = [&]() -> bool {
double progress;
GetUpdateState(&progress);
if (last_progress < static_cast<unsigned int>(progress)) {
last_progress = progress;
LOG(INFO) << "Waiting for merge to complete: " << last_progress << "%.";
}
return true; // continue
};
LOG(INFO) << "Waiting for any previous merge request to complete. "
@ -2515,7 +2516,10 @@ bool SnapshotManager::HandleImminentDataWipe(const std::function<void()>& callba
return false;
}
UpdateState state = ProcessUpdateState(callback);
UpdateState state = ProcessUpdateState([&]() -> bool {
callback();
return true;
});
LOG(INFO) << "Update state in recovery: " << state;
switch (state) {
case UpdateState::MergeFailed: