elf_runner/
runtime_dir.rs

1// Copyright 2021 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
5use fidl::endpoints::ServerEnd;
6use fidl_fuchsia_io as fio;
7use std::sync::Arc;
8use vfs::directory::helper::DirectlyMutable;
9use vfs::directory::immutable::simple as pfs;
10use vfs::execution_scope::ExecutionScope;
11use vfs::file::vmo::read_only;
12use vfs::tree_builder::TreeBuilder;
13
14// Simple directory type which is used to implement `ComponentStartInfo.runtime_directory`.
15pub struct RuntimeDirectory(Arc<pfs::Simple>);
16
17impl RuntimeDirectory {
18    pub fn add_process_id(&self, process_id: u64) {
19        self.elf_dir()
20            .add_entry("process_id", read_only(process_id.to_string()))
21            .expect("failed to add process_id");
22    }
23
24    pub fn add_process_start_time(&self, process_start_time: i64) {
25        self.elf_dir()
26            .add_entry("process_start_time", read_only(process_start_time.to_string()))
27            .expect("failed to add process_start_time");
28    }
29
30    pub fn add_process_start_time_utc_estimate(&self, process_start_time_utc_estimate: String) {
31        self.elf_dir()
32            .add_entry(
33                "process_start_time_utc_estimate",
34                read_only(process_start_time_utc_estimate),
35            )
36            .expect("failed to add process_start_time_utc_estimate");
37    }
38
39    // Create an empty runtime directory, for test purpose only.
40    #[cfg(test)]
41    pub fn empty() -> Self {
42        let mut empty = TreeBuilder::empty_dir();
43        empty.add_empty_dir(["elf"]).expect("failed to add elf directory");
44        RuntimeDirectory(empty.build())
45    }
46
47    fn elf_dir(&self) -> Arc<pfs::Simple> {
48        self.0
49            .get_entry("elf")
50            .expect("elf directory should be present")
51            .into_any()
52            .downcast::<pfs::Simple>()
53            .expect("could not downcast elf to a directory")
54    }
55}
56
57pub struct RuntimeDirBuilder {
58    args: Vec<String>,
59    job_id: Option<u64>,
60    server_end: ServerEnd<fio::DirectoryMarker>,
61}
62
63impl RuntimeDirBuilder {
64    pub fn new(server_end: ServerEnd<fio::DirectoryMarker>) -> Self {
65        Self { args: vec![], job_id: None, server_end }
66    }
67
68    pub fn args(mut self, args: Vec<String>) -> Self {
69        self.args = args;
70        self
71    }
72
73    pub fn job_id(mut self, job_id: u64) -> Self {
74        self.job_id = Some(job_id);
75        self
76    }
77
78    pub fn serve(mut self) -> RuntimeDirectory {
79        // Create the runtime tree structure
80        //
81        // runtime
82        // |- args
83        // |  |- 0
84        // |  |- 1
85        // |  \- ...
86        // \- elf
87        //    |- job_id
88        //    \- process_id
89        let mut runtime_tree_builder = TreeBuilder::empty_dir();
90        let mut count: u32 = 0;
91        for arg in self.args.drain(..) {
92            runtime_tree_builder
93                .add_entry(["args", &count.to_string()], read_only(arg))
94                .expect("Failed to add arg to runtime directory");
95            count += 1;
96        }
97
98        // Always add the "elf" directory so we can add process information later.
99        runtime_tree_builder.add_empty_dir(["elf"]).expect("failed to add elf directory");
100
101        if let Some(job_id) = self.job_id {
102            runtime_tree_builder
103                .add_entry(["elf", "job_id"], read_only(job_id.to_string()))
104                .expect("Failed to add job_id to runtime/elf directory");
105        }
106
107        let runtime_directory = runtime_tree_builder.build();
108        // Serve the runtime directory
109        vfs::directory::serve_on(
110            runtime_directory.clone(),
111            fio::PERM_READABLE | fio::PERM_WRITABLE,
112            ExecutionScope::new(),
113            self.server_end,
114        );
115        RuntimeDirectory(runtime_directory)
116    }
117}