Skip to content

Commit

Permalink
Named process for debugging. (#1846)
Browse files Browse the repository at this point in the history
Signed-off-by: utam0k <[email protected]>
  • Loading branch information
utam0k authored Apr 24, 2023
1 parent 9d6fdab commit 75718d7
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub fn container_intermediate_process(
// configuration. The youki main process can decide what to do with the init
// process and the intermediate process can just exit safely after the job
// is done.
let pid = fork::container_clone_sibling(|| {
let pid = fork::container_clone_sibling("youki:[2:INIT]", || {
// We are inside the forked process here. The first thing we have to do
// is to close any unused senders, since fork will make a dup for all
// the socket.
Expand Down
2 changes: 1 addition & 1 deletion crates/libcontainer/src/process/container_main_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn container_main_process(container_args: &ContainerArgs) -> Result<Pid> {
let inter_chan = &mut channel::intermediate_channel()?;
let init_chan = &mut channel::init_channel()?;

let intermediate_pid = fork::container_fork(|| {
let intermediate_pid = fork::container_fork("youki:[1:INTER]", || {
container_intermediate_process::container_intermediate_process(
container_args,
inter_chan,
Expand Down
17 changes: 10 additions & 7 deletions crates/libcontainer/src/process/fork.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::{Context, Result};
use libc::SIGCHLD;
use nix::unistd::Pid;
use prctl;

// Fork/Clone a sibling process that shares the same parent as the calling
// process. This is used to launch the container init process so the parent
Expand All @@ -9,22 +10,23 @@ use nix::unistd::Pid;
// youki main process) will exit and the init process will be re-parented to the
// process 1 (system init process), which is not the right behavior of what we
// look for.
pub fn container_clone_sibling<F: FnOnce() -> Result<i32>>(cb: F) -> Result<Pid> {
pub fn container_clone_sibling<F: FnOnce() -> Result<i32>>(child_name: &str, cb: F) -> Result<Pid> {
let mut clone = clone3::Clone3::default();
// Note: normally, an exit signal is required, but when using
// `CLONE_PARENT`, the `clone3` will return EINVAL if an exit signal is set.
// The older `clone` will not return EINVAL in this case. Instead it ignores
// the exit signal bits in the glibc wrapper.
clone.flag_parent();

container_clone(cb, clone).with_context(|| "failed to clone sibling process")
container_clone(child_name, cb, clone).with_context(|| "failed to clone sibling process")
}

// A simple clone wrapper to clone3 so we can share this logic in different
// fork/clone situations. We decided to minimally support kernel version >= 5.4,
// and `clone3` requires only kernel version >= 5.3. Therefore, we don't need to
// fall back to `clone` or `fork`.
fn container_clone<F: FnOnce() -> Result<i32>>(
child_name: &str,
cb: F,
mut clone_cmd: clone3::Clone3,
) -> Result<Pid> {
Expand All @@ -34,6 +36,7 @@ fn container_clone<F: FnOnce() -> Result<i32>>(
// callback, exit with -1
match unsafe { clone_cmd.call().with_context(|| "failed to run clone3")? } {
0 => {
prctl::set_name(child_name).expect("failed to set name");
// Inside the cloned process
let ret = match cb() {
Err(error) => {
Expand All @@ -54,12 +57,12 @@ fn container_clone<F: FnOnce() -> Result<i32>>(
// using clone, we would have to manually make sure all the variables are
// correctly send to the new process, especially Rust borrow checker will be a
// lot of hassel to deal with every details.
pub fn container_fork<F: FnOnce() -> Result<i32>>(cb: F) -> Result<Pid> {
pub fn container_fork<F: FnOnce() -> Result<i32>>(child_name: &str, cb: F) -> Result<Pid> {
// Using `clone3` to mimic the effect of `fork`.
let mut clone = clone3::Clone3::default();
clone.exit_signal(SIGCHLD as u64);

container_clone(cb, clone).with_context(|| "failed to fork process")
container_clone(child_name, cb, clone).with_context(|| "failed to fork process")
}

#[cfg(test)]
Expand All @@ -73,7 +76,7 @@ mod test {

#[test]
fn test_container_fork() -> Result<()> {
let pid = container_fork(|| Ok(0))?;
let pid = container_fork("test:child", || Ok(0))?;
match waitpid(pid, None).expect("wait pid failed.") {
WaitStatus::Exited(p, status) => {
assert_eq!(pid, p);
Expand All @@ -86,7 +89,7 @@ mod test {

#[test]
fn test_container_err_fork() -> Result<()> {
let pid = container_fork(|| bail!(""))?;
let pid = container_fork("test:child", || bail!(""))?;
match waitpid(pid, None).expect("wait pid failed.") {
WaitStatus::Exited(p, status) => {
assert_eq!(pid, p);
Expand Down Expand Up @@ -138,7 +141,7 @@ mod test {
unistd::ForkResult::Child => {
// Inside the forked process. We call `container_clone` and pass
// the pid to the parent process.
let pid = container_clone_sibling(|| Ok(0))?;
let pid = container_clone_sibling("test:child", || Ok(0))?;
sender.send(pid.as_raw())?;
sender.close()?;
std::process::exit(0);
Expand Down
14 changes: 7 additions & 7 deletions hack/debug.bt
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
BEGIN
{
printf("Tracing Youki syscalls... Hit Ctrl-C to end.\n");
printf("%-12s %-10s %-8s %-9s %s\n", "TIME", "COMMAND", "PID", "EVENT", "CONTENT");
printf("%-12s %15s %-8s %-9s %s\n", "TIME", "COMMAND", "PID", "EVENT", "CONTENT");
}

tracepoint:syscalls:sys_enter_write
/comm == "4"|| comm == "youki*"/
/comm == "4"|| comm == "youki" || comm == "youki:[1:INTER]" || comm == "youki:[2:INIT]"/
{

$s = str(args->buf, args->count);
if ($s != "\n") {
printf("%-12ld %-10s %-8d %-9s ", elapsed , comm, pid, "write");
printf("%-12ld %15s %-8d %-9s ", elapsed , comm, pid, "write");
printf("fd=%d, %s\n", args->fd, $s);
}
}

tracepoint:syscalls:sys_enter_open,
tracepoint:syscalls:sys_enter_openat
/comm == "4"|| comm == "youki"/
/comm == "4"|| comm == "youki" || comm == "youki:[1:INTER]" || comm == "youki:[2:INIT]"/
{
@filename[tid] = args->filename;
}
Expand All @@ -33,15 +33,15 @@ tracepoint:syscalls:sys_exit_openat
$fd = $ret >= 0 ? $ret : -1;
$errno = $ret >= 0 ? 0 : - $ret;

printf("%-12ld %-10s %-8d %-9s ", elapsed , comm, pid, "open");
printf("%-12ld %15s %-8d %-9s ", elapsed , comm, pid, "open");
printf("errno=%d, fd=%d, file=%s\n", $errno, $fd, str(@filename[tid]));
delete(@filename[tid]);
}

tracepoint:syscalls:sys_enter_clone3
/comm == "4"|| comm == "youki"/
/comm == "4"|| comm == "youki" || comm == "youki:[1:INTER]" || comm == "youki:[2:INIT]"/
{
printf("%-12ld %-10s %-8d %-9s ", elapsed , comm, pid, "clone3");
printf("%-12ld %15s %-8d %-9s ", elapsed , comm, pid, "clone3");
}

END
Expand Down

0 comments on commit 75718d7

Please sign in to comment.