1 // Copyright 2013 The Flutter 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 #include "runtime/dart/utils/tempfs.h"
6
7 #include <string>
8 #include <thread>
9
10 #include <lib/async-loop/cpp/loop.h>
11 #include <lib/fdio/namespace.h>
12 #include <lib/memfs/memfs.h>
13 #include <lib/syslog/global.h>
14 #include <zircon/errors.h>
15 #include <zircon/status.h>
16 #include <zircon/syscalls.h>
17
18 #include "runtime/dart/utils/logging.h"
19
20 namespace {
21
22 constexpr char kTmpPath[] = "/tmp";
23 [[maybe_unused]] constexpr size_t kMaxTmpPages = 1024;
24
DispatchTempMemFS()25 void DispatchTempMemFS() {
26 async::Loop loop(&kAsyncLoopConfigAttachToThread);
27 #if defined(DART_PRODUCT)
28 zx_status_t status = memfs_install_at_with_page_limit(loop.dispatcher(),
29 kMaxTmpPages, kTmpPath);
30 #else
31 // Hot reload uses /tmp to hold the updated dills and assets so do not
32 // impose any size limitation in non product runners.
33 zx_status_t status = memfs_install_at(loop.dispatcher(), kTmpPath);
34 #endif
35 if (status != ZX_OK) {
36 FX_LOGF(ERROR, LOG_TAG, "Failed to install a /tmp memfs: %s",
37 zx_status_get_string(status));
38 return;
39 }
40 loop.Run();
41 }
42
43 } // namespace
44
45 namespace dart_utils {
46
47 // Set up a memfs bound to /tmp in the process-wide namespace that has the
48 // lifetime of the process.
SetupRunnerTemp()49 void SetupRunnerTemp() {
50 std::thread thread(DispatchTempMemFS);
51 thread.detach();
52 }
53
SetupComponentTemp(fdio_ns_t * ns)54 void SetupComponentTemp(fdio_ns_t* ns) {
55 // TODO(zra): Should isolates share a /tmp file system within a process, or
56 // should isolates each get their own private memfs for /tmp? For now,
57 // sharing the process-wide /tmp simplifies hot reload since the hot reload
58 // devfs requires sharing between the service isolate and the app isolates.
59 zx_status_t status;
60 fdio_flat_namespace_t* rootns;
61 status = fdio_ns_export_root(&rootns);
62 if (status != ZX_OK) {
63 FX_LOGF(ERROR, LOG_TAG, "Failed to export root ns: %s",
64 zx_status_get_string(status));
65 return;
66 }
67
68 zx_handle_t tmp_dir_handle;
69 for (size_t i = 0; i < rootns->count; i++) {
70 if (strcmp(rootns->path[i], kTmpPath) == 0) {
71 tmp_dir_handle = rootns->handle[i];
72 } else {
73 zx_handle_close(rootns->handle[i]);
74 rootns->handle[i] = ZX_HANDLE_INVALID;
75 }
76 }
77 free(rootns);
78 rootns = nullptr;
79
80 status = fdio_ns_bind(ns, kTmpPath, tmp_dir_handle);
81 if (status != ZX_OK) {
82 zx_handle_close(tmp_dir_handle);
83 FX_LOGF(ERROR, LOG_TAG,
84 "Failed to bind /tmp directory into isolate namespace: %s",
85 zx_status_get_string(status));
86 }
87 }
88
89 } // namespace dart_utils
90