From d2063ad7dd412f2610ac0fc980e551e0f6b6fa8a Mon Sep 17 00:00:00 2001 From: Akilesh Kailash Date: Fri, 10 Feb 2023 14:26:10 -0800 Subject: [PATCH] libsnapshot: Wait for daemon to terminate after snapshot unamp During verification, update-engine will invoke SnapshotMap() and Unmap() for every partition verification. Post Unmap(), update-engine immediately invokes Map() for next partition. This is a narrow window wherein, daemon from previous unmap() is still present and init hasn't terminated it. Thus, when next MapSnapshot() is invoked, Connect() fails as init may end up terminating the service. Wait for the daemon to fully terminate and exit when Detach() is invoked. Bug: 258514587 Test: OTA on Pixel, Map/Unmap in a loop Change-Id: I36b7ce183dfa4c89a873118876d195480e28d48c Signed-off-by: Akilesh Kailash --- .../include/snapuserd/snapuserd_client.h | 2 ++ .../libsnapshot/snapuserd/snapuserd_client.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_client.h b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_client.h index fb2251e2e..010beb3f2 100644 --- a/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_client.h +++ b/fs_mgr/libsnapshot/snapuserd/include/snapuserd/snapuserd_client.h @@ -47,6 +47,8 @@ class SnapuserdClient { bool ValidateConnection(); std::string GetDaemonAliveIndicatorPath(); + void WaitForServiceToTerminate(std::chrono::milliseconds timeout_ms); + public: explicit SnapuserdClient(android::base::unique_fd&& sockfd); SnapuserdClient(){}; diff --git a/fs_mgr/libsnapshot/snapuserd/snapuserd_client.cpp b/fs_mgr/libsnapshot/snapuserd/snapuserd_client.cpp index 695b5817f..3bed3a4a4 100644 --- a/fs_mgr/libsnapshot/snapuserd/snapuserd_client.cpp +++ b/fs_mgr/libsnapshot/snapuserd/snapuserd_client.cpp @@ -94,6 +94,21 @@ std::unique_ptr SnapuserdClient::Connect(const std::string& soc return client; } +void SnapuserdClient::WaitForServiceToTerminate(std::chrono::milliseconds timeout_ms) { + auto start = std::chrono::steady_clock::now(); + while (android::base::GetProperty("init.svc.snapuserd", "") == "running") { + auto now = std::chrono::steady_clock::now(); + auto elapsed = std::chrono::duration_cast(now - start); + if (elapsed >= timeout_ms) { + LOG(ERROR) << "Timed out - Snapuserd service did not stop - Forcefully terminating the " + "service"; + android::base::SetProperty("ctl.stop", "snapuserd"); + return; + } + std::this_thread::sleep_for(100ms); + } +} + bool SnapuserdClient::ValidateConnection() { if (!Sendmsg("query")) { return false; @@ -238,6 +253,8 @@ bool SnapuserdClient::DetachSnapuserd() { LOG(ERROR) << "Failed to detach snapuserd."; return false; } + + WaitForServiceToTerminate(3s); return true; }