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