1 // Copyright (C) 2020 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include <unistd.h> 18 19 #include <chrono> 20 #include <string> 21 22 #include <android-base/unique_fd.h> 23 24 namespace android { 25 namespace snapshot { 26 27 static constexpr uint32_t PACKET_SIZE = 512; 28 29 static constexpr char kSnapuserdSocket[] = "snapuserd"; 30 static constexpr char kSnapuserdSocketProxy[] = "snapuserd_proxy"; 31 static constexpr char kDaemonAliveIndicator[] = "daemon-alive-indicator"; 32 33 // Ensure that the second-stage daemon for snapuserd is running. 34 bool EnsureSnapuserdStarted(); 35 36 class SnapuserdClient { 37 private: 38 android::base::unique_fd sockfd_; 39 40 bool Sendmsg(const std::string& msg); 41 std::string Receivemsg(); 42 43 bool ValidateConnection(); 44 std::string GetDaemonAliveIndicatorPath(); 45 46 void WaitForServiceToTerminate(std::chrono::milliseconds timeout_ms); 47 48 public: 49 explicit SnapuserdClient(android::base::unique_fd&& sockfd); SnapuserdClient()50 SnapuserdClient(){}; 51 52 // Attempt to connect to snapsuerd, wait for the daemon to start if 53 // connection failed. 54 static std::unique_ptr<SnapuserdClient> Connect(const std::string& socket_name, 55 std::chrono::milliseconds timeout_ms); 56 // Attempt to connect to snapsuerd, but does not wait for the daemon to 57 // start. 58 static std::unique_ptr<SnapuserdClient> TryConnect(const std::string& socket_name, 59 std::chrono::milliseconds timeout_ms); 60 bool StopSnapuserd(); 61 62 // Initializing a snapuserd handler is a three-step process: 63 // 64 // 1. Client invokes InitDmUserCow. This creates the snapuserd handler and validates the 65 // COW. The number of sectors required for the dm-user target is returned. 66 // 2. Client creates the device-mapper device with the dm-user target. 67 // 3. Client calls AttachControlDevice. 68 // 69 // The misc_name must be the "misc_name" given to dm-user in step 2. 70 // 71 uint64_t InitDmUserCow(const std::string& misc_name, const std::string& cow_device, 72 const std::string& backing_device, 73 const std::string& base_path_merge = ""); 74 bool AttachDmUser(const std::string& misc_name); 75 76 // Wait for snapuserd to disassociate with a dm-user control device. This 77 // must ONLY be called if the control device has already been deleted. 78 bool WaitForDeviceDelete(const std::string& control_device); 79 80 // Detach snapuserd. This shuts down the listener socket, and will cause 81 // snapuserd to gracefully exit once all handler threads have terminated. 82 // This should only be used on first-stage instances of snapuserd. 83 bool DetachSnapuserd(); 84 85 // Returns true if the snapuserd instance supports bridging a socket to second-stage init. 86 bool SupportsSecondStageSocketHandoff(); 87 88 // Returns true if the merge is started(or resumed from crash). 89 bool InitiateMerge(const std::string& misc_name); 90 91 // Returns Merge completion percentage 92 double GetMergePercent(); 93 94 // Return the status of the snapshot 95 std::string QuerySnapshotStatus(const std::string& misc_name); 96 97 // Check the update verification status - invoked by update_verifier during 98 // boot 99 bool QueryUpdateVerification(); 100 101 // Check if Snapuser daemon is ready post selinux transition after OTA boot 102 // This is invoked only by init as there is no sockets setup yet during 103 // selinux transition 104 bool IsTransitionedDaemonReady(); 105 106 // Remove the daemon-alive-indicator path post snapshot merge 107 bool RemoveTransitionedDaemonIndicator(); 108 109 // Notify init that snapuserd daemon is ready post selinux transition 110 void NotifyTransitionDaemonIsReady(); 111 }; 112 113 } // namespace snapshot 114 } // namespace android 115