You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.9 KiB
132 lines
3.9 KiB
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <android-base/unique_fd.h>
|
|
|
|
#include <functional>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace android::incfs {
|
|
|
|
//
|
|
// MountRegistry - a collection of mount points for a particular filesystem, with
|
|
// live tracking of binds, mounts and unmounts on it
|
|
//
|
|
|
|
class MountRegistry final {
|
|
public:
|
|
struct Bind {
|
|
std::string subdir;
|
|
int rootIndex;
|
|
};
|
|
// std::less<> enables heterogeneous lookups, e.g. by a string_view
|
|
using BindMap = std::map<std::string, Bind, std::less<>>;
|
|
|
|
class Mounts final {
|
|
struct Root {
|
|
std::string path;
|
|
std::string backing;
|
|
std::vector<BindMap::const_iterator> binds;
|
|
|
|
bool empty() const { return path.empty(); }
|
|
void clear() {
|
|
decltype(path)().swap(path);
|
|
decltype(binds)().swap(binds);
|
|
}
|
|
};
|
|
|
|
public:
|
|
struct Mount final {
|
|
Mount(std::vector<Root>::const_iterator base) : mBase(base) {}
|
|
|
|
std::string_view root() const { return mBase->path; }
|
|
std::string_view backingDir() const { return mBase->backing; }
|
|
std::vector<std::pair<std::string_view, std::string_view>> binds() const;
|
|
|
|
private:
|
|
std::vector<Root>::const_iterator mBase;
|
|
};
|
|
|
|
struct iterator final : public std::vector<Root>::const_iterator {
|
|
using base = std::vector<Root>::const_iterator;
|
|
using value_type = Mount;
|
|
value_type operator*() const { return Mount(*this); }
|
|
|
|
explicit iterator(base b) : base(b) {}
|
|
};
|
|
|
|
static Mounts load(base::borrowed_fd fd, std::string_view filesystem);
|
|
bool loadFrom(base::borrowed_fd fd, std::string_view filesystem);
|
|
|
|
iterator begin() const { return iterator(roots.begin()); }
|
|
iterator end() const { return iterator(roots.end()); }
|
|
size_t size() const { return roots.size(); }
|
|
bool empty() const { return roots.empty(); }
|
|
|
|
std::string_view rootFor(std::string_view path) const;
|
|
std::pair<const Root*, std::string> rootAndSubpathFor(std::string_view path) const;
|
|
|
|
void swap(Mounts& other);
|
|
void clear();
|
|
|
|
void addRoot(std::string_view root, std::string_view backingDir);
|
|
void removeRoot(std::string_view root);
|
|
void addBind(std::string_view what, std::string_view where);
|
|
void removeBind(std::string_view what);
|
|
|
|
private:
|
|
std::pair<int, BindMap::const_iterator> rootIndex(std::string_view path) const;
|
|
|
|
std::vector<Root> roots;
|
|
BindMap rootByBindPoint;
|
|
};
|
|
|
|
MountRegistry(std::string_view filesystem = {});
|
|
~MountRegistry();
|
|
|
|
std::string rootFor(std::string_view path);
|
|
std::pair<std::string, std::string> rootAndSubpathFor(std::string_view path);
|
|
|
|
struct Details {
|
|
std::string root;
|
|
std::string backing;
|
|
std::string subpath;
|
|
};
|
|
Details detailsFor(std::string_view path);
|
|
|
|
Mounts copyMounts();
|
|
|
|
void reload();
|
|
|
|
private:
|
|
[[nodiscard]] std::unique_lock<std::mutex> ensureUpToDate();
|
|
|
|
private:
|
|
const std::string mFilesystem;
|
|
base::unique_fd mMountInfo;
|
|
Mounts mMounts;
|
|
mutable std::mutex mDataMutex;
|
|
};
|
|
|
|
} // namespace android::incfs
|