StorageCommands: add command "listmounts"
This commit is contained in:
parent
9e02b13ab3
commit
0935ae330a
@ -107,6 +107,7 @@ static const struct command commands[] = {
|
|||||||
{ "list", PERMISSION_READ, 1, -1, handle_list },
|
{ "list", PERMISSION_READ, 1, -1, handle_list },
|
||||||
{ "listall", PERMISSION_READ, 0, 1, handle_listall },
|
{ "listall", PERMISSION_READ, 0, 1, handle_listall },
|
||||||
{ "listallinfo", PERMISSION_READ, 0, 1, handle_listallinfo },
|
{ "listallinfo", PERMISSION_READ, 0, 1, handle_listallinfo },
|
||||||
|
{ "listmounts", PERMISSION_READ, 0, 0, handle_listmounts },
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_NEIGHBOR_PLUGINS
|
#ifdef ENABLE_NEIGHBOR_PLUGINS
|
||||||
{ "listneighbors", PERMISSION_READ, 0, 0, handle_listneighbors },
|
{ "listneighbors", PERMISSION_READ, 0, 0, handle_listneighbors },
|
||||||
|
@ -21,13 +21,63 @@
|
|||||||
#include "StorageCommands.hxx"
|
#include "StorageCommands.hxx"
|
||||||
#include "CommandError.hxx"
|
#include "CommandError.hxx"
|
||||||
#include "protocol/Result.hxx"
|
#include "protocol/Result.hxx"
|
||||||
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
#include "fs/Traits.hxx"
|
||||||
#include "client/Client.hxx"
|
#include "client/Client.hxx"
|
||||||
#include "Partition.hxx"
|
#include "Partition.hxx"
|
||||||
#include "Instance.hxx"
|
#include "Instance.hxx"
|
||||||
#include "storage/Registry.hxx"
|
#include "storage/Registry.hxx"
|
||||||
#include "storage/CompositeStorage.hxx"
|
#include "storage/CompositeStorage.hxx"
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_storage_uri(Client &client, const Storage &storage)
|
||||||
|
{
|
||||||
|
std::string uri = storage.MapUTF8("");
|
||||||
|
if (uri.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PathTraitsFS::IsAbsolute(uri.c_str())) {
|
||||||
|
/* storage points to local directory */
|
||||||
|
|
||||||
|
if (!client.IsLocal())
|
||||||
|
/* only "local" clients may see local paths
|
||||||
|
(same policy as with the "config"
|
||||||
|
command) */
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
/* hide username/passwords from client */
|
||||||
|
|
||||||
|
std::string allocated = uri_remove_auth(uri.c_str());
|
||||||
|
if (!allocated.empty())
|
||||||
|
uri = std::move(allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
client_printf(client, "storage: %s\n", uri.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandResult
|
||||||
|
handle_listmounts(Client &client, gcc_unused int argc, gcc_unused char *argv[])
|
||||||
|
{
|
||||||
|
Storage *_composite = client.partition.instance.storage;
|
||||||
|
if (_composite == nullptr) {
|
||||||
|
command_error(client, ACK_ERROR_NO_EXIST, "No database");
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeStorage &composite = *(CompositeStorage *)_composite;
|
||||||
|
|
||||||
|
const auto visitor = [&client](const char *mount_uri,
|
||||||
|
const Storage &storage){
|
||||||
|
client_printf(client, "mount: %s\n", mount_uri);
|
||||||
|
print_storage_uri(client, storage);
|
||||||
|
};
|
||||||
|
|
||||||
|
composite.VisitMounts(visitor);
|
||||||
|
|
||||||
|
return CommandResult::OK;
|
||||||
|
}
|
||||||
|
|
||||||
CommandResult
|
CommandResult
|
||||||
handle_mount(Client &client, gcc_unused int argc, char *argv[])
|
handle_mount(Client &client, gcc_unused int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
|
CommandResult
|
||||||
|
handle_listmounts(Client &client, int argc, char *argv[]);
|
||||||
|
|
||||||
CommandResult
|
CommandResult
|
||||||
handle_mount(Client &client, int argc, char *argv[]);
|
handle_mount(Client &client, int argc, char *argv[]);
|
||||||
|
|
||||||
|
@ -95,6 +95,18 @@ public:
|
|||||||
CompositeStorage();
|
CompositeStorage();
|
||||||
virtual ~CompositeStorage();
|
virtual ~CompositeStorage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call the given function for each mounted storage, including
|
||||||
|
* the root storage. Passes mount point URI and the a const
|
||||||
|
* Storage reference to the function.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void VisitMounts(T t) const {
|
||||||
|
const ScopeLock protect(mutex);
|
||||||
|
std::string uri;
|
||||||
|
VisitMounts(uri, root, t);
|
||||||
|
}
|
||||||
|
|
||||||
void Mount(const char *uri, Storage *storage);
|
void Mount(const char *uri, Storage *storage);
|
||||||
bool Unmount(const char *uri);
|
bool Unmount(const char *uri);
|
||||||
|
|
||||||
@ -112,6 +124,26 @@ public:
|
|||||||
virtual const char *MapToRelativeUTF8(const char *uri) const override;
|
virtual const char *MapToRelativeUTF8(const char *uri) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template<typename T>
|
||||||
|
void VisitMounts(std::string &uri, const Directory &directory,
|
||||||
|
T t) const {
|
||||||
|
const Storage *const storage = directory.storage;
|
||||||
|
if (storage != nullptr)
|
||||||
|
t(uri.c_str(), *storage);
|
||||||
|
|
||||||
|
if (!uri.empty())
|
||||||
|
uri.push_back('/');
|
||||||
|
|
||||||
|
const size_t uri_length = uri.length();
|
||||||
|
|
||||||
|
for (const auto &i : directory.children) {
|
||||||
|
uri.resize(uri_length);
|
||||||
|
uri.append(i.first);
|
||||||
|
|
||||||
|
VisitMounts(uri, i.second, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
FindResult FindStorage(const char *uri) const;
|
FindResult FindStorage(const char *uri) const;
|
||||||
FindResult FindStorage(const char *uri, Error &error) const;
|
FindResult FindStorage(const char *uri, Error &error) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user