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