1 // Copyright (C) 2023 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 <memory> 18 #include <mutex> 19 #include <queue> 20 #include <string> 21 #include <thread> 22 #include <vector> 23 24 #include <android-base/unique_fd.h> 25 #include <snapuserd/block_server.h> 26 27 namespace android { 28 namespace snapshot { 29 30 struct HandlerOptions { 31 int num_worker_threads{}; 32 bool use_iouring{}; 33 bool o_direct{}; 34 bool skip_verification{}; 35 uint32_t cow_op_merge_size{}; 36 uint32_t verify_block_size{}; 37 uint32_t num_verification_threads{}; 38 }; 39 40 class SnapshotHandler; 41 42 class HandlerThread { 43 public: 44 explicit HandlerThread(std::shared_ptr<SnapshotHandler> snapuserd); 45 46 void FreeResources(); snapuserd()47 const std::shared_ptr<SnapshotHandler>& snapuserd() const { return snapuserd_; } thread()48 std::thread& thread() { return thread_; } 49 misc_name()50 const std::string& misc_name() const { return misc_name_; } ThreadTerminated()51 bool ThreadTerminated() { return thread_terminated_; } SetThreadTerminated()52 void SetThreadTerminated() { thread_terminated_ = true; } 53 54 private: 55 std::thread thread_; 56 std::shared_ptr<SnapshotHandler> snapuserd_; 57 std::string misc_name_; 58 bool thread_terminated_ = false; 59 }; 60 61 class ISnapshotHandlerManager { 62 public: ~ISnapshotHandlerManager()63 virtual ~ISnapshotHandlerManager() {} 64 65 // Add a new snapshot handler but do not start serving requests yet. 66 virtual std::shared_ptr<HandlerThread> AddHandler(const std::string& misc_name, 67 const std::string& cow_device_path, 68 const std::string& backing_device, 69 const std::string& base_path_merge, 70 std::shared_ptr<IBlockServerOpener> opener, 71 HandlerOptions options) = 0; 72 73 // Start serving requests on a snapshot handler. 74 virtual bool StartHandler(const std::string& misc_name) = 0; 75 76 // Stop serving requests on a snapshot handler and remove it. 77 virtual bool DeleteHandler(const std::string& misc_name) = 0; 78 79 // Begin merging blocks on the given snapshot handler. 80 virtual bool InitiateMerge(const std::string& misc_name) = 0; 81 82 // Return a string containing a status code indicating the merge status 83 // on the handler. Returns empty on error. 84 virtual std::string GetMergeStatus(const std::string& misc_name) = 0; 85 86 // Wait until all handlers have terminated. 87 virtual void JoinAllThreads() = 0; 88 89 // Stop any in-progress merge threads. 90 virtual void TerminateMergeThreads() = 0; 91 92 // Returns the merge progress across all merging snapshot handlers. 93 virtual double GetMergePercentage() = 0; 94 95 // Returns whether all snapshots have verified. 96 virtual bool GetVerificationStatus() = 0; 97 98 // Disable partition verification 99 virtual void DisableVerification() = 0; 100 101 // Pause Merge threads 102 virtual void PauseMerge() = 0; 103 104 // Resume Merge threads 105 virtual void ResumeMerge() = 0; 106 }; 107 108 class SnapshotHandlerManager final : public ISnapshotHandlerManager { 109 public: 110 SnapshotHandlerManager(); 111 std::shared_ptr<HandlerThread> AddHandler(const std::string& misc_name, 112 const std::string& cow_device_path, 113 const std::string& backing_device, 114 const std::string& base_path_merge, 115 std::shared_ptr<IBlockServerOpener> opener, 116 HandlerOptions options) override; 117 118 bool StartHandler(const std::string& misc_name) override; 119 bool DeleteHandler(const std::string& misc_name) override; 120 bool InitiateMerge(const std::string& misc_name) override; 121 std::string GetMergeStatus(const std::string& misc_name) override; 122 void JoinAllThreads() override; 123 void TerminateMergeThreads() override; 124 double GetMergePercentage() override; 125 bool GetVerificationStatus() override; DisableVerification()126 void DisableVerification() override { perform_verification_ = false; } 127 void PauseMerge() override; 128 void ResumeMerge() override; 129 130 private: 131 bool StartHandler(const std::shared_ptr<HandlerThread>& handler); 132 void RunThread(std::shared_ptr<HandlerThread> handler); 133 bool StartMerge(std::lock_guard<std::mutex>* proof_of_lock, 134 const std::shared_ptr<HandlerThread>& handler); 135 void MonitorMerge(); 136 void WakeupMonitorMergeThread(); 137 bool RemoveAndJoinHandler(const std::string& misc_name); 138 139 // Find a HandlerThread within a lock. 140 using HandlerList = std::vector<std::shared_ptr<HandlerThread>>; 141 HandlerList::iterator FindHandler(std::lock_guard<std::mutex>* proof_of_lock, 142 const std::string& misc_name); 143 144 std::mutex lock_; 145 HandlerList dm_users_; 146 147 bool stop_monitor_merge_thread_ = false; 148 int active_merge_threads_ = 0; 149 std::thread merge_monitor_; 150 int num_partitions_merge_complete_ = 0; 151 std::queue<std::shared_ptr<HandlerThread>> merge_handlers_; 152 android::base::unique_fd monitor_merge_event_fd_; 153 bool perform_verification_ = true; 154 }; 155 156 } // namespace snapshot 157 } // namespace android 158