blob: b882c7749ad138e77a1c50bbeffa2debd29cf85d [file] [log] [blame]
// Copyright 2019 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_FS_MANAGER_H_
#define SRC_STORAGE_FSHOST_FS_MANAGER_H_
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/wait.h>
#include <lib/memfs/cpp/vnode.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>
#include <lib/zx/job.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <iterator>
#include <fs/vfs.h>
#include "src/lib/loader_service/loader_service.h"
// Used for fshost signals.
#include "delayed-outdir.h"
#include "fdio.h"
#include "fshost-boot-args.h"
#include "inspect-manager.h"
#include "metrics.h"
#include "registry.h"
namespace devmgr {
class BlockWatcher;
// FsManager owns multiple sub-filesystems, managing them within a top-level
// in-memory filesystem.
class FsManager {
public:
explicit FsManager(std::shared_ptr<FshostBootArgs> boot_args,
std::unique_ptr<FsHostMetrics> metrics);
~FsManager();
zx_status_t Initialize(zx::channel dir_request, zx::channel lifecycle_request,
std::shared_ptr<loader::LoaderServiceBase> loader, BlockWatcher& watcher);
// TODO(fxbug.dev/39588): delete this
// Starts servicing the delayed portion of the outgoing directory, called once
// "/system" has been mounted.
void FuchsiaStart() { delayed_outdir_.Start(); }
// Pins a handle to a remote filesystem on one of the paths specified
// by |kMountPoints|.
zx_status_t InstallFs(const char* path, zx::channel h);
// Serves connection to the root directory ("/") on |server|.
zx_status_t ServeRoot(zx::channel server);
// Serves connection to the fshost directory (exporting the "fuchsia.fshost" services) on
// |server|.
zx_status_t ServeFshostRoot(zx::channel server) { return registry_.ServeRoot(std::move(server)); }
// Triggers unmount when the FSHOST_SIGNAL_EXIT signal is raised on |event_|.
//
// Sets FSHOST_SIGNAL_EXIT_DONE when unmounting is complete.
void WatchExit();
// Signals FSHOST_SIGNAL_EXIT on |event_|, causing filesystems to be shutdown
// and unmounted. Calls |callback| when this is complete.
void Shutdown(fit::function<void(zx_status_t)> callback);
// Returns a pointer to the |FsHostMetrics| instance.
FsHostMetrics* mutable_metrics() { return metrics_.get(); }
// Flushes FsHostMetrics to cobalt.
void FlushMetrics();
std::shared_ptr<FshostBootArgs> boot_args() { return boot_args_; }
zx::event* event() { return &event_; }
// Creates a RemoteDir sub-directory in the fshost diagnostics directory.
// This allows a filesystem to expose its Inspect API to Archivist alongside fshost.
// |diagnostics_dir_name| is the name of the diagnostics subdirectory created for
// this filesystem.
zx_status_t AddFsDiagnosticsDirectory(const char* diagnostics_dir_name,
zx::channel fs_diagnostics_dir_client);
private:
zx_status_t SetupOutgoingDirectory(zx::channel dir_request,
std::shared_ptr<loader::LoaderServiceBase> loader,
BlockWatcher& watcher);
zx_status_t SetupLifecycleServer(zx::channel lifecycle_request);
// Event on which "FSHOST_SIGNAL_XXX" signals are set.
// Communicates state changes internal to FsManager.
zx::event event_;
static constexpr const char* kMountPoints[] = {
"/bin", "/data", "/volume", "/system", "/install", "/blob", "/pkgfs", "/factory", "/durable"};
fbl::RefPtr<fs::Vnode> mount_nodes[std::size(kMountPoints)];
// The Root VFS manages the following filesystems:
// - The global root filesystem (including the mount points)
// - "/tmp"
std::unique_ptr<memfs::Vfs> root_vfs_;
std::unique_ptr<async::Loop> global_loop_;
fs::ManagedVfs outgoing_vfs_;
async::Wait global_shutdown_;
// The base, root directory which serves the rest of the fshost.
fbl::RefPtr<memfs::VnodeDir> global_root_;
// Controls the external fshost vnode, as well as registration of filesystems
// dynamically within the fshost.
fshost::Registry registry_;
// Keeps a collection of metrics being track at the FsHost level.
std::unique_ptr<FsHostMetrics> metrics_;
// Serves inspect data.
InspectManager inspect_;
// Used to lookup configuration options stored in fuchsia.boot.Arguments
std::shared_ptr<devmgr::FshostBootArgs> boot_args_;
// TODO(fxbug.dev/39588): delete this
// A RemoteDir in the outgoing directory that ignores requests until Start is
// called on it.
DelayedOutdir delayed_outdir_;
// The diagnostics directory for the fshost inspect tree.
// Each filesystem gets a subdirectory to host their own inspect tree.
// Archivist will parse all the inspect trees found in this directory tree.
fbl::RefPtr<fs::PseudoDir> diagnostics_dir_;
std::unique_ptr<async::Wait> shutdown_waiter_;
};
} // namespace devmgr
#endif // SRC_STORAGE_FSHOST_FS_MANAGER_H_