Skip to content

Commit a56f5bf

Browse files
chantradanobi
authored andcommitted
init: symlink /dev/fd to /proc/self/fd
For process substitution to work, /dev/fd needs to be symlinked to /proc/self/fd Without the change, the newly added `test_command_process_substitution` test would fail with: ``` ---- test_command_process_substitution stdout ---- Command output=bash: line 1: cd: /tmp/.tmpr2SM0u: No such file or directory Command output=cat: /dev/fd/63: No such file or directory [tests/test.rs:251] get_error(recv, None) = Some( "Command failed with 1", ) thread 'test_command_process_substitution' panicked at 'assertion failed: dbg!(get_error(recv, None)).is_none()', tests/test.rs:251:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failures: test_command_process_substitution test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 11 filtered out; finished in 2.41s error: test failed, to rerun pass `--test test` ``` After the change, the test pass and it is possible to run: ``` $ cargo run -- -k $KERNEL_REPO/arch/x86_64/boot/bzImage "tail <(cat README.md) Finished dev [unoptimized + debuginfo] target(s) in 0.03s Running `target/debug/vmtest -k /home/chantra/devel/bpf-next//arch/x86_64/boot/bzImage 'tail <(cat README.md)'` => bzImage ===> Booting ===> Setting up VM ===> Running command For general architecture notes, see [architecture.md](./docs/architecture.md). Many thanks to [`drgn`'s vmtest](https://github.com/osandov/drgn/tree/main/vmtest) by Omar Sandoval and Andy Lutomirski's most excellent [`virtme`](https://github.com/amluto/virtme) for providing both ideas and technical exploration. ``` Signed-off-by: Manu Bretelle <chantr4@gmail.com>
1 parent 81ae527 commit a56f5bf

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/init/init.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ mount -t cgroup2 -o nosuid,nodev,noexec cgroup2 /sys/fs/cgroup
7575
log "Mounting tmpfs at /mnt"
7676
mount -t tmpfs -o nosuid,nodev tmpfs /mnt
7777

78+
# Symlink /dev/fd to /proc/self/fd so process substitution works.
79+
log "Symlink /dev/fd to /proc/self/fd"
80+
[[ -a /dev/fd ]] || ln -s /proc/self/fd /dev/fd
81+
7882
log "Init done"
7983

8084
# Locate our QGA virtio port

tests/test.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,32 @@ fn test_kernel_target_cwd_preserved() {
230230
assert_no_err!(recv);
231231
}
232232

233+
#[test]
234+
fn test_command_process_substitution() {
235+
let config = Config {
236+
target: vec![Target {
237+
name: "command can run process substitution".to_string(),
238+
kernel: Some(asset("bzImage-v5.15-empty")),
239+
kernel_args: None,
240+
// `$0` is a portable way of getting the name of the shell without relying
241+
// on env vars which may be propagated from the host into the guest.
242+
command: "cat <(echo -n $0) > /mnt/vmtest/result".to_string(),
243+
image: None,
244+
uefi: false,
245+
vm: VMConfig::default(),
246+
}],
247+
};
248+
let (vmtest, dir) = setup(config, &[]);
249+
let (send, recv) = channel();
250+
vmtest.run_one(0, send);
251+
assert_no_err!(recv);
252+
253+
// Check that output file contains the shell
254+
let result_path = dir.path().join("result");
255+
let result = fs::read_to_string(result_path).expect("Failed to read result");
256+
assert_eq!(result, "bash");
257+
}
258+
233259
#[test]
234260
fn test_qemu_error_shown() {
235261
let config = Config {

0 commit comments

Comments
 (0)