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 // std::less<> enables heterogeneous lookups, e.g. by a string_view 39 using BindMap = std::map<std::string, std::pair<std::string, int>, std::less<>>; 40 41 class Mounts final { 42 struct Root { 43 std::string path; 44 std::string backing; 45 std::vector<BindMap::const_iterator> binds; 46 emptyRoot47 bool empty() const { return path.empty(); } clearRoot48 void clear() { 49 decltype(path)().swap(path); 50 decltype(binds)().swap(binds); 51 } 52 }; 53 54 public: 55 struct Mount final { Mountfinal56 Mount(std::vector<Root>::const_iterator base) : mBase(base) {} 57 rootfinal58 std::string_view root() const { return mBase->path; } backingDirfinal59 std::string_view backingDir() const { return mBase->backing; } 60 std::vector<std::pair<std::string_view, std::string_view>> binds() const; 61 62 private: 63 std::vector<Root>::const_iterator mBase; 64 }; 65 66 struct iterator final : public std::vector<Root>::const_iterator { 67 using base = std::vector<Root>::const_iterator; 68 using value_type = Mount; 69 value_type operator*() const { return Mount(*this); } 70 iteratorfinal71 explicit iterator(base b) : base(b) {} 72 }; 73 74 static Mounts load(base::borrowed_fd fd, std::string_view filesystem); 75 bool loadFrom(base::borrowed_fd fd, std::string_view filesystem); 76 begin()77 iterator begin() const { return iterator(roots.begin()); } end()78 iterator end() const { return iterator(roots.end()); } size()79 size_t size() const { return roots.size(); } empty()80 bool empty() const { return roots.empty(); } 81 82 std::string_view rootFor(std::string_view path) const; 83 std::pair<std::string_view, std::string> rootAndSubpathFor(std::string_view path) const; 84 85 void swap(Mounts& other); 86 void clear(); 87 88 void addRoot(std::string_view root, std::string_view backingDir); 89 void removeRoot(std::string_view root); 90 void addBind(std::string_view what, std::string_view where); 91 void moveBind(std::string_view src, std::string_view dest); 92 void removeBind(std::string_view what); 93 94 private: 95 std::pair<int, BindMap::const_iterator> rootIndex(std::string_view path) const; 96 97 std::vector<Root> roots; 98 BindMap rootByBindPoint; 99 }; 100 101 MountRegistry(std::string_view filesystem = {}); 102 ~MountRegistry(); 103 104 std::string rootFor(std::string_view path); 105 std::pair<std::string, std::string> rootAndSubpathFor(std::string_view path); 106 Mounts copyMounts(); 107 108 void reload(); 109 110 private: 111 [[nodiscard]] std::unique_lock<std::mutex> ensureUpToDate(); 112 113 private: 114 const std::string mFilesystem; 115 base::unique_fd mMountInfo; 116 Mounts mMounts; 117 mutable std::mutex mDataMutex; 118 }; 119 120 } // namespace android::incfs 121