xref: /aosp_15_r20/system/incremental_delivery/incfs/include/MountRegistry.h (revision 9190c2a8bd3622b7aa9bd7bfe4b3aec77820f478)
1*9190c2a8SAndroid Build Coastguard Worker /*
2*9190c2a8SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*9190c2a8SAndroid Build Coastguard Worker  *
4*9190c2a8SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*9190c2a8SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*9190c2a8SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*9190c2a8SAndroid Build Coastguard Worker  *
8*9190c2a8SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*9190c2a8SAndroid Build Coastguard Worker  *
10*9190c2a8SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*9190c2a8SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*9190c2a8SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*9190c2a8SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*9190c2a8SAndroid Build Coastguard Worker  * limitations under the License.
15*9190c2a8SAndroid Build Coastguard Worker  */
16*9190c2a8SAndroid Build Coastguard Worker 
17*9190c2a8SAndroid Build Coastguard Worker #pragma once
18*9190c2a8SAndroid Build Coastguard Worker 
19*9190c2a8SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
20*9190c2a8SAndroid Build Coastguard Worker 
21*9190c2a8SAndroid Build Coastguard Worker #include <functional>
22*9190c2a8SAndroid Build Coastguard Worker #include <map>
23*9190c2a8SAndroid Build Coastguard Worker #include <mutex>
24*9190c2a8SAndroid Build Coastguard Worker #include <string>
25*9190c2a8SAndroid Build Coastguard Worker #include <string_view>
26*9190c2a8SAndroid Build Coastguard Worker #include <utility>
27*9190c2a8SAndroid Build Coastguard Worker #include <vector>
28*9190c2a8SAndroid Build Coastguard Worker 
29*9190c2a8SAndroid Build Coastguard Worker namespace android::incfs {
30*9190c2a8SAndroid Build Coastguard Worker 
31*9190c2a8SAndroid Build Coastguard Worker //
32*9190c2a8SAndroid Build Coastguard Worker // MountRegistry - a collection of mount points for a particular filesystem, with
33*9190c2a8SAndroid Build Coastguard Worker //      live tracking of binds, mounts and unmounts on it
34*9190c2a8SAndroid Build Coastguard Worker //
35*9190c2a8SAndroid Build Coastguard Worker 
36*9190c2a8SAndroid Build Coastguard Worker class MountRegistry final {
37*9190c2a8SAndroid Build Coastguard Worker public:
38*9190c2a8SAndroid Build Coastguard Worker     struct Bind {
39*9190c2a8SAndroid Build Coastguard Worker         std::string subdir;
40*9190c2a8SAndroid Build Coastguard Worker         int rootIndex;
41*9190c2a8SAndroid Build Coastguard Worker     };
42*9190c2a8SAndroid Build Coastguard Worker     // std::less<> enables heterogeneous lookups, e.g. by a string_view
43*9190c2a8SAndroid Build Coastguard Worker     using BindMap = std::map<std::string, Bind, std::less<>>;
44*9190c2a8SAndroid Build Coastguard Worker 
45*9190c2a8SAndroid Build Coastguard Worker     class Mounts final {
46*9190c2a8SAndroid Build Coastguard Worker         struct Root {
47*9190c2a8SAndroid Build Coastguard Worker             std::string path;
48*9190c2a8SAndroid Build Coastguard Worker             std::string backing;
49*9190c2a8SAndroid Build Coastguard Worker             std::vector<BindMap::const_iterator> binds;
50*9190c2a8SAndroid Build Coastguard Worker 
emptyRoot51*9190c2a8SAndroid Build Coastguard Worker             bool empty() const { return path.empty(); }
clearRoot52*9190c2a8SAndroid Build Coastguard Worker             void clear() {
53*9190c2a8SAndroid Build Coastguard Worker                 decltype(path)().swap(path);
54*9190c2a8SAndroid Build Coastguard Worker                 decltype(binds)().swap(binds);
55*9190c2a8SAndroid Build Coastguard Worker             }
56*9190c2a8SAndroid Build Coastguard Worker         };
57*9190c2a8SAndroid Build Coastguard Worker 
58*9190c2a8SAndroid Build Coastguard Worker     public:
59*9190c2a8SAndroid Build Coastguard Worker         struct Mount final {
Mountfinal60*9190c2a8SAndroid Build Coastguard Worker             Mount(std::vector<Root>::const_iterator base) : mBase(base) {}
61*9190c2a8SAndroid Build Coastguard Worker 
rootfinal62*9190c2a8SAndroid Build Coastguard Worker             std::string_view root() const { return mBase->path; }
backingDirfinal63*9190c2a8SAndroid Build Coastguard Worker             std::string_view backingDir() const { return mBase->backing; }
64*9190c2a8SAndroid Build Coastguard Worker             std::vector<std::pair<std::string_view, std::string_view>> binds() const;
65*9190c2a8SAndroid Build Coastguard Worker 
66*9190c2a8SAndroid Build Coastguard Worker         private:
67*9190c2a8SAndroid Build Coastguard Worker             std::vector<Root>::const_iterator mBase;
68*9190c2a8SAndroid Build Coastguard Worker         };
69*9190c2a8SAndroid Build Coastguard Worker 
70*9190c2a8SAndroid Build Coastguard Worker         struct iterator final : public std::vector<Root>::const_iterator {
71*9190c2a8SAndroid Build Coastguard Worker             using base = std::vector<Root>::const_iterator;
72*9190c2a8SAndroid Build Coastguard Worker             using value_type = Mount;
73*9190c2a8SAndroid Build Coastguard Worker             value_type operator*() const { return Mount(*this); }
74*9190c2a8SAndroid Build Coastguard Worker 
iteratorfinal75*9190c2a8SAndroid Build Coastguard Worker             explicit iterator(base b) : base(b) {}
76*9190c2a8SAndroid Build Coastguard Worker         };
77*9190c2a8SAndroid Build Coastguard Worker 
78*9190c2a8SAndroid Build Coastguard Worker         static Mounts load(base::borrowed_fd fd, std::string_view filesystem);
79*9190c2a8SAndroid Build Coastguard Worker         bool loadFrom(base::borrowed_fd fd, std::string_view filesystem);
80*9190c2a8SAndroid Build Coastguard Worker 
begin()81*9190c2a8SAndroid Build Coastguard Worker         iterator begin() const { return iterator(roots.begin()); }
end()82*9190c2a8SAndroid Build Coastguard Worker         iterator end() const { return iterator(roots.end()); }
size()83*9190c2a8SAndroid Build Coastguard Worker         size_t size() const { return roots.size(); }
empty()84*9190c2a8SAndroid Build Coastguard Worker         bool empty() const { return roots.empty(); }
85*9190c2a8SAndroid Build Coastguard Worker 
86*9190c2a8SAndroid Build Coastguard Worker         std::string_view rootFor(std::string_view path) const;
87*9190c2a8SAndroid Build Coastguard Worker         std::pair<const Root*, std::string> rootAndSubpathFor(std::string_view path) const;
88*9190c2a8SAndroid Build Coastguard Worker 
89*9190c2a8SAndroid Build Coastguard Worker         void swap(Mounts& other);
90*9190c2a8SAndroid Build Coastguard Worker         void clear();
91*9190c2a8SAndroid Build Coastguard Worker 
92*9190c2a8SAndroid Build Coastguard Worker         void addRoot(std::string_view root, std::string_view backingDir);
93*9190c2a8SAndroid Build Coastguard Worker         void removeRoot(std::string_view root);
94*9190c2a8SAndroid Build Coastguard Worker         void addBind(std::string_view what, std::string_view where);
95*9190c2a8SAndroid Build Coastguard Worker         void removeBind(std::string_view what);
96*9190c2a8SAndroid Build Coastguard Worker 
97*9190c2a8SAndroid Build Coastguard Worker     private:
98*9190c2a8SAndroid Build Coastguard Worker         std::pair<int, BindMap::const_iterator> rootIndex(std::string_view path) const;
99*9190c2a8SAndroid Build Coastguard Worker 
100*9190c2a8SAndroid Build Coastguard Worker         std::vector<Root> roots;
101*9190c2a8SAndroid Build Coastguard Worker         BindMap rootByBindPoint;
102*9190c2a8SAndroid Build Coastguard Worker     };
103*9190c2a8SAndroid Build Coastguard Worker 
104*9190c2a8SAndroid Build Coastguard Worker     MountRegistry(std::string_view filesystem = {});
105*9190c2a8SAndroid Build Coastguard Worker     ~MountRegistry();
106*9190c2a8SAndroid Build Coastguard Worker 
107*9190c2a8SAndroid Build Coastguard Worker     std::string rootFor(std::string_view path);
108*9190c2a8SAndroid Build Coastguard Worker     std::pair<std::string, std::string> rootAndSubpathFor(std::string_view path);
109*9190c2a8SAndroid Build Coastguard Worker 
110*9190c2a8SAndroid Build Coastguard Worker     struct Details {
111*9190c2a8SAndroid Build Coastguard Worker         std::string root;
112*9190c2a8SAndroid Build Coastguard Worker         std::string backing;
113*9190c2a8SAndroid Build Coastguard Worker         std::string subpath;
114*9190c2a8SAndroid Build Coastguard Worker     };
115*9190c2a8SAndroid Build Coastguard Worker     Details detailsFor(std::string_view path);
116*9190c2a8SAndroid Build Coastguard Worker 
117*9190c2a8SAndroid Build Coastguard Worker     Mounts copyMounts();
118*9190c2a8SAndroid Build Coastguard Worker 
119*9190c2a8SAndroid Build Coastguard Worker     void reload();
120*9190c2a8SAndroid Build Coastguard Worker 
121*9190c2a8SAndroid Build Coastguard Worker private:
122*9190c2a8SAndroid Build Coastguard Worker     [[nodiscard]] std::unique_lock<std::mutex> ensureUpToDate();
123*9190c2a8SAndroid Build Coastguard Worker 
124*9190c2a8SAndroid Build Coastguard Worker private:
125*9190c2a8SAndroid Build Coastguard Worker     const std::string mFilesystem;
126*9190c2a8SAndroid Build Coastguard Worker     base::unique_fd mMountInfo;
127*9190c2a8SAndroid Build Coastguard Worker     Mounts mMounts;
128*9190c2a8SAndroid Build Coastguard Worker     mutable std::mutex mDataMutex;
129*9190c2a8SAndroid Build Coastguard Worker };
130*9190c2a8SAndroid Build Coastguard Worker 
131*9190c2a8SAndroid Build Coastguard Worker } // namespace android::incfs
132