• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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