Skip to content

RFC: Clarify the role of the processes involved in bwrap - #809

Draft
smcv wants to merge 5 commits into
containers:mainfrom
smcv:wip/smcv/label-processes
Draft

smcv wants to merge 5 commits into
containers:mainfrom
smcv:wip/smcv/label-processes

Conversation

@smcv

@smcv smcv commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator
  • Add a diagram of the processes we will generally have

    Work on several issues and PRs like ctrl+c sends SIGINT to bubblwrap instead of child process #369, Directory at /proc/{PID}/root doesn't match root of the sandbox #589, Pass WINCH signal to child process #573 has been impeded
    by the structure of the process hierarchy not being obvious.
    We can make this better by assigning clear names to the various
    long-running processes that might exist.

    We say that the top-level process (the bwrap process that was run
    by the user), which continues to run outside the sandbox boundary,
    is the monitor. It is responsible for monitoring sandboxed processes
    and passing on their exit status.

    Typically the child of the monitor will be an init process inside
    the sandbox (in some cases this is not present).

    Finally, the sandboxed command is the COMMAND specified after the
    -- divider on bwrap's command-line.

  • Add more debug logging to clarify which process is which

    This uses the terminology from the diagram added in the previous commit.

  • Fix a misleading debug message

    It's misleading to say we're forking for child if we will not, in fact,
    fork. Instead, say that we're forking init parent for command if
    that's the case, or say that init not needed if we won't fork.

    This uses the terminology from the diagram I added previously.

  • Make debug() expand to something non-empty, even if disabled

    This is the standard trick to make a macro always have non-empty contents
    for syntax purposes, even if it ends up compiling to no machine code.

  • Try to set the process name for bwrap's internal processes

    This uses the terminology from the diagram I added previously.


cc @alexlarsson @cgwalters @swick

This will make it easier to talk about what is going on. For example, in #725 we can unambigously say things like "the inherited environment variables from the caller are visible in the bwrap init process's /proc/1/environ, but with --unshare-pid the bwrap monitor process's environment isn't visible".

Work on several issues and PRs like containers#369, containers#589, containers#573 has been impeded
by the structure of the process hierarchy not being obvious.
We can make this better by assigning clear names to the various
long-running processes that might exist.

We say that the top-level process (the `bwrap` process that was run
by the user), which continues to run outside the sandbox boundary,
is the *monitor*. It is responsible for monitoring sandboxed processes
and passing on their exit status.

Typically the child of the monitor will be an *init* process inside
the sandbox (in some cases this is not present).

Finally, the sandboxed *command* is the `COMMAND` specified after the
`--` divider on bwrap's command-line.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This uses the terminology from the diagram added in the previous commit.

Signed-off-by: Simon McVittie <smcv@collabora.com>
It's misleading to say we're `forking for child` if we will not, in fact,
fork. Instead, say that we're `forking init parent for command` if
that's the case, or say that `init not needed` if we won't fork.

This uses the terminology from the diagram I added previously.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This is the standard trick to make a macro always have non-empty contents
for syntax purposes, even if it ends up compiling to no machine code.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This uses the terminology from the diagram I added previously.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Comment thread bubblewrap.c
debug ("monitor[%d] outside sandbox: watching child %d", getpid (), child_pid);

/* This is just nice-to-have, so don't crash out if this fails */
if (prctl (PR_SET_NAME, "bwrap monitor") < 0)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows up in /proc/*/comm and commands like pstree:

  |   |   |-zsh
  |   |   |   |-bwrap monitor --unshare-all --dev-bind / / bash -i
  |   |   |   |   `-bwrap init --unshare-all --dev-bind / / bash -i
  |   |   |   |       `-bash -i

and in ps -o comm, but not in systemd-cgls or plain ps, which continue to show /proc/*/cmdline.

As far as I know, editing /proc/*/cmdline requires arbitrarily overwriting memory similar to #800.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe bwrap(monitor) and bwrap(init), or bwrap:monitor and bwrap:init, would be more obviously not a command that you can type? This is a matter of opinion, I'm not sure what is the best presentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant