| // 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_ |