Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: Add option to spawn the init process as a sibling of the calling processes in libcontainer #3011

Closed
jprendes opened this issue Dec 5, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@jprendes
Copy link
Contributor

jprendes commented Dec 5, 2024

Background

In runwasi we use libcontainer as a dependency.
One of the key aspects is that we use a custom executor.
In particular, the executor's exec method doesn't invoke libc::exec but rather continue executing fairly complex code (e.g., it starts a tokio runtime).

Feature Request

Adding an option to spawn the init process as a sibling of the calling process, something like:

 ContainerBuilder::new(id, SyscallType::Linux)
     .with_executor(executor)
     .with_root_path(rootdir)?
     .as_init(bundle)
+    .as_sibling(true)
     .build()?;

Is the request related to some problem running youki?

In general, after cloning the process like we do in libcontainer, there are very few operation that are safe (see #2425). Fox example, not even malloc and free are safe in that context. This is because the libc implementation might be using locks to synchronize access across threads.
There are very few situations where doing this is safe, and we've experienced UB because of this in the past (again, see #2425). In general, libc should be safe to use if the application is single threaded before the clone.

More recently, we've been having another issue, where we use a single threaded (to avoid the previous libc issue) tokio runtime in the parent process, and another tokio runtime in the init process. The init process inherits all the global state of the parent process. This is a problem because tokio does hold global state, and does things like global initializations only once. In particular, it uses the self pipe trick for signal handling. This pipe is inherited (and not reinitialized) in the child process, which means that tokio's signal handling breaks in weird ways.

Unfortunately we can't remove our tokio dependency as we need to to communicate with containerd using gRPC.

Proposed Solution

To avoid further issues, we want to create a very simple and clean process very early on, who's only job is to create containers with libcontainer.
The problem with this approach is that the init process is now a child of this other process, and not of the main process with all the logic, so we can't waitpid for it. Adding an option as described would solve this issue.

Considerations

No response

Additional Context

No response

@jprendes jprendes added the enhancement New feature or request label Dec 5, 2024
@jprendes jprendes self-assigned this Dec 5, 2024
@YJDoc2
Copy link
Collaborator

YJDoc2 commented Dec 9, 2024

@jprendes , I think this is closed with #3012 ?

@jprendes jprendes closed this as completed Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants