mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-29 12:54:10 +00:00
agent: set stdout/err vsock stream as blocking before passing to child
In passfd io mode, when not using a terminal, the stdout/stderr vsock streams are directly used as the stdout/stderr of the child process. These streams are non-blocking by default. The stdout/stderr of the process should be blocking, otherwise the process may encounter EAGAIN error when writing to stdout/stderr. Fixes: #6714 Signed-off-by: Zixuan Tan <tanzixuan.me@gmail.com>
This commit is contained in:
parent
cfb262d02f
commit
7874ef5fd2
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use libc::pid_t;
|
use libc::pid_t;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd, IntoRawFd};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tokio_vsock::VsockStream;
|
use tokio_vsock::VsockStream;
|
||||||
|
|
||||||
@ -137,6 +137,13 @@ impl ProcessOperations for Process {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_blocking(fd: RawFd) -> Result<()> {
|
||||||
|
let flags = fcntl(fd, FcntlArg::F_GETFL)?;
|
||||||
|
let new_flags = !OFlag::O_NONBLOCK & OFlag::from_bits_truncate(flags);
|
||||||
|
fcntl(fd, FcntlArg::F_SETFL(new_flags))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
impl Process {
|
impl Process {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
logger: &Logger,
|
logger: &Logger,
|
||||||
@ -189,8 +196,11 @@ impl Process {
|
|||||||
p.stdin = Some(stdin);
|
p.stdin = Some(stdin);
|
||||||
|
|
||||||
if let Some(stdout) = p.proc_io.as_mut().map(|io| io.stdout.take()).flatten() {
|
if let Some(stdout) = p.proc_io.as_mut().map(|io| io.stdout.take()).flatten() {
|
||||||
p.stdout = Some(stdout.as_raw_fd());
|
let fd = stdout.into_raw_fd();
|
||||||
std::mem::forget(stdout);
|
// The stdout/stderr of the process should be blocking, otherwise
|
||||||
|
// the process may encounter EAGAIN error when writing to stdout/stderr.
|
||||||
|
set_blocking(fd)?;
|
||||||
|
p.stdout = Some(fd);
|
||||||
} else {
|
} else {
|
||||||
let (pstdout, stdout) = create_extended_pipe(OFlag::O_CLOEXEC, pipe_size)?;
|
let (pstdout, stdout) = create_extended_pipe(OFlag::O_CLOEXEC, pipe_size)?;
|
||||||
p.parent_stdout = Some(pstdout);
|
p.parent_stdout = Some(pstdout);
|
||||||
@ -198,8 +208,9 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stderr) = p.proc_io.as_mut().map(|io| io.stderr.take()).flatten() {
|
if let Some(stderr) = p.proc_io.as_mut().map(|io| io.stderr.take()).flatten() {
|
||||||
p.stderr = Some(stderr.as_raw_fd());
|
let fd = stderr.into_raw_fd();
|
||||||
std::mem::forget(stderr);
|
set_blocking(fd)?;
|
||||||
|
p.stderr = Some(fd);
|
||||||
} else {
|
} else {
|
||||||
let (pstderr, stderr) = create_extended_pipe(OFlag::O_CLOEXEC, pipe_size)?;
|
let (pstderr, stderr) = create_extended_pipe(OFlag::O_CLOEXEC, pipe_size)?;
|
||||||
p.parent_stderr = Some(pstderr);
|
p.parent_stderr = Some(pstderr);
|
||||||
|
Loading…
Reference in New Issue
Block a user