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