elf_runner/
runtime_dir.rs
1use 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
14pub 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 #[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 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 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 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}