1 // Copyright 2016 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <lib/async-loop/cpp/loop.h> 8 #include <lib/async/cpp/wait.h> 9 #include <lib/fdio/io.h> 10 #include <lib/fdio/vfs.h> 11 #include <lib/memfs/cpp/vnode.h> 12 #include <lib/zx/channel.h> 13 #include <lib/zx/event.h> 14 #include <lib/zx/job.h> 15 #include <zircon/compiler.h> 16 #include <zircon/thread_annotations.h> 17 #include <zircon/types.h> 18 19 #include "../shared/env.h" 20 #include "../shared/fdio.h" 21 22 namespace devmgr { 23 24 // FshostConnections represents the link from fshost to external 25 // sources outside fshost, such as the devmgr. 26 class FshostConnections { 27 public: 28 FshostConnections(zx::channel devfs_root, zx::channel svc_root, zx::channel fs_root, 29 zx::event event); 30 31 // Synchronously opens a connection on the requested path. 32 // 33 // TODO: Return an error code, instead of "invalid handle", on error. 34 zx::channel Open(const char* path) const; 35 36 // Create and install the namespace for the current process, using 37 // the owned channels as connections. 38 zx_status_t CreateNamespace(); 39 Event()40 const zx::event& Event() const { 41 return event_; 42 } 43 44 private: 45 zx::channel devfs_root_; 46 zx::channel svc_root_; 47 zx::channel fs_root_; 48 zx::event event_; 49 }; 50 51 // FsManager owns multiple sub-filesystems, managing them within a top-level 52 // in-memory filesystem. 53 class FsManager { 54 public: 55 FsManager(); 56 GetConnections()57 const FshostConnections& GetConnections() const { 58 return *connections_.get(); 59 } 60 61 // Created a named VmoFile in "/system". Ownership of |vmo| assumed global. 62 zx_status_t SystemfsAddFile(const char* path, zx_handle_t vmo, zx_off_t off, size_t len); 63 64 // Signal that "/system" has been mounted. FuchsiaStart()65 void FuchsiaStart() const { 66 connections_->Event().signal(0, FSHOST_SIGNAL_READY); 67 } 68 69 // Create "/system", and mount it within the global root. 70 zx_status_t MountSystem(); 71 72 // Identifies if "/system" has already been mounted. IsSystemMounted()73 bool IsSystemMounted() const { 74 return systemfs_root_ != nullptr; 75 } 76 77 // Set the "/system" VFS filesystem to become readonly. 78 void SystemfsSetReadonly(bool value); 79 80 // Pins a handle to a remote filesystem on one of the paths specified 81 // by |kMountPoints|. 82 zx_status_t InstallFs(const char* path, zx::channel h); 83 84 // Initialize connections to external service managers, and begin 85 // monitoring |event| for a termination event. 86 zx_status_t InitializeConnections(zx::channel root, zx::channel devfs_root, 87 zx::channel svc_root, zx::event event); 88 89 private: 90 // Triggers unmount when the FSHOST_SIGNAL_EXIT signal is raised on an 91 // event contained within |connections_|. 92 // 93 // Sets FSHOST_SIGNAL_EXIT_DONE when unmounting is complete. 94 void WatchExit(); 95 96 // Give a channel to a root directory, where it will begin serving requests. 97 zx_status_t ConnectRoot(zx::channel server); 98 99 // Create a new channel, and connect to the root directory. 100 // Invokes |ConnectRoot| internally. 101 zx_status_t ServeRoot(zx::channel* out); 102 103 zx_status_t ServeVnode(fbl::RefPtr<memfs::VnodeDir>& vn, zx::channel server); 104 zx_status_t LocalMount(memfs::VnodeDir* parent, const char* name, 105 fbl::RefPtr<memfs::VnodeDir>& subtree); 106 107 static constexpr const char* kMountPoints[] = { 108 "/bin", "/data", "/volume", "/system", "/install", "/blob", "/pkgfs" 109 }; 110 fbl::RefPtr<fs::Vnode> mount_nodes[fbl::count_of(kMountPoints)]; 111 112 // The Root VFS manages the following filesystems: 113 // - The global root filesystem (including the mount points) 114 // - "/tmp" 115 memfs::Vfs root_vfs_; 116 117 // The System VFS manages exclusively the system filesystem. 118 memfs::Vfs system_vfs_; 119 fbl::unique_ptr<async::Loop> global_loop_; 120 async::Wait global_shutdown_; 121 122 // The base, root directory which serves the rest of the fshost. 123 fbl::RefPtr<memfs::VnodeDir> global_root_; 124 // The globally accessible "/tmp", in-memory filesystem directory. 125 fbl::RefPtr<memfs::VnodeDir> memfs_root_; 126 127 // The location of an optional system image filesystem. 128 fbl::RefPtr<memfs::VnodeDir> systemfs_root_; 129 130 // Allows access and signals to external resources. 131 fbl::unique_ptr<FshostConnections> connections_; 132 }; 133 134 // Function which mounts a handle on behalf of the block watcher. 135 void block_device_watcher(fbl::unique_ptr<FsManager> fshost, zx::unowned_job job, bool netboot); 136 137 } // namespace devmgr 138