• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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