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).
This commit is contained in:
parent
33ee35ab92
commit
d7744d2b8e
|
@ -203,6 +203,11 @@ handle_mount(Client &client, Request args, Response &r)
|
|||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
if (composite.IsMounted(remote_uri)) {
|
||||
r.Error(ACK_ERROR_ARG, "This storage is already mounted");
|
||||
return CommandResult::ERROR;
|
||||
}
|
||||
|
||||
auto &event_loop = instance.io_thread.GetEventLoop();
|
||||
auto storage = CreateStorageURI(event_loop, remote_uri);
|
||||
if (storage == nullptr) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue