diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h index c8cbb1e7a..72f1d91de 100644 --- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h +++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h @@ -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& callback = {}, + UpdateState ProcessUpdateState(const std::function& callback = {}, const std::function& before_cancel = {}); // Initiate the merge if necessary, then wait for the merge to finish. diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 3bf7e310f..aeec17bcd 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -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& callback, +UpdateState SnapshotManager::ProcessUpdateState(const std::function& callback, const std::function& before_cancel) { while (true) { UpdateState state = CheckMergeState(before_cancel); @@ -807,8 +807,8 @@ UpdateState SnapshotManager::ProcessUpdateState(const std::function& 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(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& 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: