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 <cstring> 21 #include <iostream> 22 #include <string> 23 #include <thread> 24 #include <vector> 25 26 #include <android-base/unique_fd.h> 27 28 namespace android { 29 namespace snapshot { 30 31 static constexpr uint32_t PACKET_SIZE = 512; 32 33 static constexpr char kSnapuserdSocket[] = "snapuserd"; 34 static constexpr char kSnapuserdSocketProxy[] = "snapuserd_proxy"; 35 static constexpr char kDaemonAliveIndicator[] = "daemon-alive-indicator"; 36 37 // Ensure that the second-stage daemon for snapuserd is running. 38 bool EnsureSnapuserdStarted(); 39 40 class SnapuserdClient { 41 private: 42 android::base::unique_fd sockfd_; 43 44 bool Sendmsg(const std::string& msg); 45 std::string Receivemsg(); 46 47 bool ValidateConnection(); 48 std::string GetDaemonAliveIndicatorPath(); 49 50 void WaitForServiceToTerminate(std::chrono::milliseconds timeout_ms); 51 52 public: 53 explicit SnapuserdClient(android::base::unique_fd&& sockfd); SnapuserdClient()54 SnapuserdClient(){}; 55 56 static std::unique_ptr<SnapuserdClient> Connect(const std::string& socket_name, 57 std::chrono::milliseconds timeout_ms); 58 59 bool StopSnapuserd(); 60 61 // Initializing a snapuserd handler is a three-step process: 62 // 63 // 1. Client invokes InitDmUserCow. This creates the snapuserd handler and validates the 64 // COW. The number of sectors required for the dm-user target is returned. 65 // 2. Client creates the device-mapper device with the dm-user target. 66 // 3. Client calls AttachControlDevice. 67 // 68 // The misc_name must be the "misc_name" given to dm-user in step 2. 69 // 70 uint64_t InitDmUserCow(const std::string& misc_name, const std::string& cow_device, 71 const std::string& backing_device, 72 const std::string& base_path_merge = ""); 73 bool AttachDmUser(const std::string& misc_name); 74 75 // Wait for snapuserd to disassociate with a dm-user control device. This 76 // must ONLY be called if the control device has already been deleted. 77 bool WaitForDeviceDelete(const std::string& control_device); 78 79 // Detach snapuserd. This shuts down the listener socket, and will cause 80 // snapuserd to gracefully exit once all handler threads have terminated. 81 // This should only be used on first-stage instances of snapuserd. 82 bool DetachSnapuserd(); 83 84 // Returns true if the snapuserd instance supports bridging a socket to second-stage init. 85 bool SupportsSecondStageSocketHandoff(); 86 87 // Returns true if the merge is started(or resumed from crash). 88 bool InitiateMerge(const std::string& misc_name); 89 90 // Returns Merge completion percentage 91 double GetMergePercent(); 92 93 // Return the status of the snapshot 94 std::string QuerySnapshotStatus(const std::string& misc_name); 95 96 // Check the update verification status - invoked by update_verifier during 97 // boot 98 bool QueryUpdateVerification(); 99 100 // Check if Snapuser daemon is ready post selinux transition after OTA boot 101 // This is invoked only by init as there is no sockets setup yet during 102 // selinux transition 103 bool IsTransitionedDaemonReady(); 104 105 // Remove the daemon-alive-indicator path post snapshot merge 106 bool RemoveTransitionedDaemonIndicator(); 107 108 // Notify init that snapuserd daemon is ready post selinux transition 109 void NotifyTransitionDaemonIsReady(); 110 }; 111 112 } // namespace snapshot 113 } // namespace android 114