blob: 8b79a962920752a58da6dbea259e0dd41e7d5bee [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_STORAGE_FSHOST_INSPECT_MANAGER_H_
#define SRC_STORAGE_FSHOST_INSPECT_MANAGER_H_
#include <lib/inspect/cpp/inspector.h>
#include <map>
#include <optional>
#include <queue>
#include "src/lib/storage/fs_management/cpp/format.h"
#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
namespace fshost {
// Utility to open a directory at the given `path` under `root`. The resulting channel handle will
// be in `result`. The returned `status` indicates whether the operation was successful or not.
zx_status_t OpenNode(fidl::UnownedClientEnd<fuchsia_io::Directory> root, const std::string& path,
uint32_t mode, fidl::ClientEnd<fuchsia_io::Node>* result);
// Management of fshost inspect data.
class FshostInspectManager {
public:
FshostInspectManager() = default;
~FshostInspectManager() = default;
// Returns the diagnostics directory where inspect data is contained.
fbl::RefPtr<fs::PseudoDir> Initialize(async_dispatcher* dispatcher);
// Creates a lazy node which serves stats about the given |root|.
void ServeStats(std::string name, fidl::ClientEnd<fuchsia_io::Directory> root);
const inspect::Inspector& inspector() const { return inspector_; }
void LogCorruption(fs_management::DiskFormat format);
private:
inspect::Inspector inspector_;
// Node which contains counters for all filesystem corruption events. Will be lazily created
// when the first corruption is reported via |LogCorruption|.
std::optional<inspect::Node> corruption_node_;
// Mapping of filesystem type to the Inspect properties keeping track of the corruption counts.
std::map<fs_management::DiskFormat, inspect::UintProperty> corruption_events_;
// Fills information about the size of files and directories under the given `root` under the
// given `node` and emplaces it in the given `inspector`. Returns the total size of `root`.
void FillFileTreeSizes(fidl::ClientEnd<fuchsia_io::Directory> root, inspect::Node node,
inspect::Inspector* inspector);
// Queries the filesystem about stats of the given `root` and stores them in the given `inspector`
void FillStats(fidl::UnownedClientEnd<fuchsia_io::Directory> root, inspect::Inspector* inspector);
};
// A directory entry returned by `DirectoryEntriesIterator`
struct DirectoryEntry {
// The name of the entry.
std::string name;
// A handle to the node this entry represents.
fidl::ClientEnd<fuchsia_io::Node> node;
// If the entry its a file, this contains the content size. If the entry is a directory, this will
// be zero.
size_t size = 0;
// Whether the entry is a directory or not.
bool is_dir = false;
};
// Utility to lazily iterate over the entries of a directory.
class DirectoryEntriesIterator {
public:
// Create a new lazy iterator.
explicit DirectoryEntriesIterator(fidl::ClientEnd<fuchsia_io::Directory> directory);
// Get the next entry. If there's no more entries left (it finished), returns std::nullopt
// forever.
std::optional<DirectoryEntry> GetNext();
bool finished() const { return finished_; }
private:
// The directory which entries will be retrieved.
fidl::ClientEnd<fuchsia_io::Directory> directory_;
// Pending entries to return.
std::queue<std::string> pending_entries_;
// Whether or not the iterator has finished.
bool finished_ = false;
// Creates a `DirectoryEntry`. If it fails to retrieve the entry `entry_name` attributes,
// returns `std::nullopt`.
std::optional<DirectoryEntry> MaybeMakeEntry(const std::string& entry_name);
// Reads the next set of dirents and loads them into `pending_entries_`.
void RefreshPendingEntries();
};
} // namespace fshost
#endif // SRC_STORAGE_FSHOST_INSPECT_MANAGER_H_