diff options
author | Max Kellermann <max@musicpd.org> | 2020-07-06 18:00:57 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-07-06 18:02:47 +0200 |
commit | d7744d2b8e8219e6f9a9fad7eff63c8e5f3a000d (patch) | |
tree | dd326468aab434f59461aecb54c2cd070da747d9 /src/storage | |
parent | 33ee35ab928fab752aa7f533e6a9a2b46de6528a (diff) |
command/storage: check if storage is already mounted
Mounting one storage URI twice on different mount points can lead to
conflicts with the database cache file, and it doesn't make a lot of
sense.
But most importantly, our udisks storage plugin will unmount the disk
from the kernel VFS, and if two exist, they will compete with each
others. We could (and should) fix this in the udisks storage plugin,
but for now, this workaround is good enough (and useful).
Diffstat (limited to 'src/storage')
-rw-r--r-- | src/storage/CompositeStorage.hxx | 25 | ||||
-rw-r--r-- | src/storage/StorageState.cxx | 5 |
2 files changed, 30 insertions, 0 deletions
diff --git a/src/storage/CompositeStorage.hxx b/src/storage/CompositeStorage.hxx index d6c424d54..c06240403 100644 --- a/src/storage/CompositeStorage.hxx +++ b/src/storage/CompositeStorage.hxx @@ -121,6 +121,15 @@ public: VisitMounts(uri, root, t); } + /** + * Is a storage with the given URI already mounted? + */ + gcc_pure gcc_nonnull_all + bool IsMounted(const char *storage_uri) const noexcept { + const std::lock_guard<Mutex> protect(mutex); + return IsMounted(root, storage_uri); + } + void Mount(const char *uri, std::unique_ptr<Storage> storage); bool Unmount(const char *uri); @@ -155,6 +164,22 @@ private: } } + gcc_pure gcc_nonnull_all + static bool IsMounted(const Directory &directory, + const char *storage_uri) noexcept { + if (directory.storage) { + const auto uri = directory.storage->MapUTF8(""); + if (uri == storage_uri) + return true; + } + + for (const auto &i : directory.children) + if (IsMounted(i.second, storage_uri)) + return true; + + return false; + } + /** * Follow the given URI path, and find the outermost directory * which is a #Storage mount point. If there are no mounts, diff --git a/src/storage/StorageState.cxx b/src/storage/StorageState.cxx index 34e669787..404dfeeb3 100644 --- a/src/storage/StorageState.cxx +++ b/src/storage/StorageState.cxx @@ -112,6 +112,11 @@ storage_state_restore(const char *line, TextFile &file, Instance &instance) return true; } + if (composite_storage.IsMounted(url.c_str())) { + LogError(storage_domain, "This storage is already mounted"); + return true; + } + auto &event_loop = instance.io_thread.GetEventLoop(); auto storage = CreateStorageURI(event_loop, url.c_str()); if (storage == nullptr) { |