Skip to content

Commit fd4869c

Browse files
committed
feat: add stdio redirection example
1 parent 30163dc commit fd4869c

File tree

11 files changed

+141
-15
lines changed

11 files changed

+141
-15
lines changed

.github/workflows/rust.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
- ping
1919
- dev_random
2020
- ping_queue
21+
- redirect_stdio
2122
env:
2223
DURATION: 10s
2324
RUST_LOG: trace

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
/target
22
.direnv/
33
.vscode/
4-
result
4+
result
5+
6+
# For the redirect_stdio example
7+
stdin
8+
stdout
9+
stderr

Cargo.lock

Lines changed: 13 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ members = [
1515
"examples/ping/client",
1616
"examples/ping/server",
1717

18-
"examples/dev_random",
19-
2018
"examples/ping_queue/client",
2119
"examples/ping_queue/server",
20+
21+
"examples/dev_random",
22+
23+
"examples/redirect_stdio"
2224
]
2325

2426
[workspace.package]
@@ -38,6 +40,7 @@ repository = "https://github.com/DLR-FT/a653rs-linux/"
3840
a653rs = "0.6"
3941
a653rs-linux = { version = "0.2", path = "partition" }
4042
a653rs-linux-core = { version = "0.2", path = "core" }
43+
anyhow = "1.0"
4144
log = "0"
4245
nix = { version = "0.29", features = ["socket", "process", "fs", "uio", "signal", "user", "mount", "event", "sched"] }
4346
memmap2 = "0.9"

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ memmap2.workspace = true
1919
procfs.workspace = true
2020
polling.workspace = true
2121
itertools.workspace = true
22+
anyhow.workspace = true
2223

23-
anyhow = "1.0"
2424
log = "0"
2525
walkdir = "2.3"
2626
serde = { version = "1.0", features = ["derive"] }

examples/redirect_stdio/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "redirect_stdio"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
a653rs = { workspace = true, features = ["macros"] }
10+
a653rs-linux.workspace = true
11+
log.workspace = true
12+
nix.workspace = true
13+
anyhow.workspace = true
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
major_frame: 1s
2+
partitions:
3+
- id: 0
4+
name: partition_0
5+
duration: 1s
6+
offset: 0ms
7+
period: 1s
8+
image: ./target/x86_64-unknown-linux-musl/release/redirect_stdio
9+
mounts:
10+
- [ ./stdin, /stdin ]
11+
- [ ./stdout, /stdout ]
12+
- [ ./stderr, /stderr ]
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::fs::OpenOptions;
2+
use std::os::fd::AsRawFd;
3+
use std::path::Path;
4+
5+
use a653rs::partition;
6+
use a653rs::prelude::PartitionExt;
7+
use a653rs_linux::partition::ApexLogger;
8+
use anyhow::Result;
9+
use log::LevelFilter;
10+
11+
fn replace_stdio<T: AsRawFd, U: AsRef<Path>>(stdio: T, new: U, write: bool) -> Result<()> {
12+
let new = OpenOptions::new()
13+
.write(write)
14+
.read(!write)
15+
.truncate(write)
16+
.open(new)?;
17+
nix::unistd::dup2(new.as_raw_fd(), stdio.as_raw_fd())?;
18+
Ok(())
19+
}
20+
21+
fn main() {
22+
replace_stdio(std::io::stdin(), "/stdin", false).unwrap();
23+
replace_stdio(std::io::stdout(), "/stdout", true).unwrap();
24+
replace_stdio(std::io::stderr(), "/stderr", true).unwrap();
25+
26+
ApexLogger::install_panic_hook();
27+
ApexLogger::install_logger(LevelFilter::Trace).unwrap();
28+
29+
redirect_stdio::Partition.run()
30+
}
31+
32+
#[partition(a653rs_linux::partition::ApexLinuxPartition)]
33+
mod redirect_stdio {
34+
use log::info;
35+
use std::io::BufRead;
36+
37+
#[start(cold)]
38+
fn cold_start(mut ctx: start::Context) {
39+
// create and start an aperiodic process
40+
ctx.create_process_0().unwrap().start().unwrap();
41+
}
42+
43+
// do the same as a cold_start
44+
#[start(warm)]
45+
fn warm_start(ctx: start::Context) {
46+
cold_start(ctx);
47+
}
48+
49+
// this aperiodic process opens /dev/random and reads some random bytes from it
50+
#[aperiodic(
51+
time_capacity = "Infinite",
52+
stack_size = "8KB",
53+
base_priority = 1,
54+
deadline = "Soft"
55+
)]
56+
fn process_0(ctx: process_0::Context) {
57+
info!("started process with redirected stdio/stdout/stderr");
58+
59+
info!("Reading stdin to stdout");
60+
println!("Start reading stdin to stdout");
61+
let stdin = std::io::stdin();
62+
for line in stdin.lock().lines() {
63+
println!("{}", line.unwrap())
64+
}
65+
println!("Finished reading stdin to stdout");
66+
67+
info!("Writing messages to stderr");
68+
eprintln!("Error was encountered: None");
69+
eprintln!("But it was printed to stderr");
70+
71+
info!("Terminating partition");
72+
ctx.set_partition_mode(OperatingMode::Idle).unwrap();
73+
}
74+
}

flake.nix

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@
7171
name = "hello_part_no_macros";
7272
partitions = [ "hello_part_no_macros" ];
7373
}
74+
{
75+
name = "redirect_stdio";
76+
partitions = [ "redirect_stdio" ];
77+
preRun = ''
78+
touch $PRJ_ROOT/std{out,err}
79+
echo $'hello\nworld!\n' > $PRJ_ROOT/stdin
80+
'';
81+
}
7482
{
7583
name = "fuel_tank";
7684
partitions = [ "fuel_tank_simulation" "fuel_tank_controller" ];
@@ -103,7 +111,7 @@
103111
cargoTestOptions = x: x ++ [ "--package" pname ];
104112
} // env;
105113
} // (builtins.listToAttrs (builtins.map
106-
({ name, partitions }: {
114+
({ name, partitions, ... }: {
107115
name = "example-${name}";
108116
value = naersk-lib.buildPackage
109117
rec {
@@ -181,7 +189,7 @@
181189
inherit (nixpkgs.lib) flatten;
182190
in
183191
flatten (map
184-
({ name, partitions }: [
192+
({ name, partitions, preRun ? "" }: [
185193
{
186194
name = "run-example-${name}";
187195
command = ''
@@ -192,8 +200,10 @@
192200
# prepend PATH so that partition images can be found
193201
PATH="target/${rust-target}/release:$PATH"
194202
203+
${preRun}
204+
195205
# (build &) run hypervisor
196-
RUST_LOG=''${RUST_LOG:=trace} cargo run --package a653rs-linux-hypervisor --release -- examples/${name}/${name}.yaml $@
206+
RUST_LOG=''${RUST_LOG:=trace} cargo run --package a653rs-linux-hypervisor --release -- "examples/${name}/${name}.yaml" $@
197207
'';
198208
help = "Run the ${name} example, consisting of the partitions: ${concatStringsSep "," partitions}";
199209
category = "example";

hypervisor/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ polling.workspace = true
2121
itertools.workspace = true
2222
once_cell.workspace = true
2323
bytesize.workspace = true
24-
anyhow = "1.0"
24+
anyhow.workspace = true
25+
2526
tempfile = "3.3"
2627
clone3 = "0.2"
2728
serde = { version = "1.0", features = ["derive"] }

0 commit comments

Comments
 (0)