On 1/13/19 8:57 PM, Brian Dolbec wrote: > On Sun, 13 Jan 2019 16:27:21 -0800 > Zac Medico <zmed...@gentoo.org> wrote: > >> Execute pid-ns-init as the first fork after unshare, as >> required for it to have pid 1 and become the default reaper >> of orphaned descendant processes. In _exec, exec a separate >> pid-ns-init process to behave as a supervisor which will >> forward signals to init and forward exit status to the parent >> process. >> >> Fixes: a75d5546e3a4 ("Introduce a tiny init replacement for inside >> pid namespace") Bug: https://bugs.gentoo.org/670484 >> --- >> bin/pid-ns-init | 44 >> ++++++++++++++++++++++++++++++++++++++---- lib/portage/process.py | >> 26 ++++++++++++++++++------- 2 files changed, 59 insertions(+), 11 >> deletions(-) >> >> diff --git a/bin/pid-ns-init b/bin/pid-ns-init >> index 843257b70..3792eeaa4 100644 >> --- a/bin/pid-ns-init >> +++ b/bin/pid-ns-init >> @@ -1,23 +1,59 @@ >> #!/usr/bin/env python >> -# Copyright 2018 Gentoo Authors >> +# Copyright 2018-2019 Gentoo Authors >> # Distributed under the terms of the GNU General Public License v2 >> >> +import functools >> import os >> +import signal >> import sys >> >> >> +KILL_SIGNALS = ( >> + signal.SIGINT, >> + signal.SIGTERM, >> + signal.SIGHUP, >> +) >> + >> +def forward_kill_signal(main_child_pid, signum, frame): >> + os.kill(main_child_pid, signum) >> + >> + >> def main(argv): >> if len(argv) < 2: >> - return 'Usage: {} <main-child-pid>'.format(argv[0]) >> - main_child_pid = int(argv[1]) >> + return 'Usage: {} <main-child-pid> or <binary> >> argv0..'.format(argv[0]) + >> + if len(argv) == 2: >> + # The child process is init (pid 1) in a child pid >> namespace, and >> + # the current process supervises from within the >> global pid namespace >> + # (forwarding signals to init and forwarding exit >> status to the parent >> + # process). >> + main_child_pid = int(argv[1]) >> + else: >> + # The current process is init (pid 1) in a child pid >> namespace. >> + binary = argv[1] >> + args = argv[2:] >> + >> + main_child_pid = os.fork() >> + if main_child_pid == 0: >> + os.execv(binary, args) >> + >> + sig_handler = functools.partial(forward_kill_signal, >> main_child_pid) >> + for signum in KILL_SIGNALS: >> + signal.signal(signum, sig_handler) >> >> # wait for child processes >> while True: >> - pid, status = os.wait() >> + try: >> + pid, status = os.wait() >> + except OSError as e: >> + if e.errno == errno.EINTR: >> + continue >> + raise >> if pid == main_child_pid: >> if os.WIFEXITED(status): >> return os.WEXITSTATUS(status) >> elif os.WIFSIGNALED(status): >> + signal.signal(os.WTERMSIG(status), >> signal.SIG_DFL) os.kill(os.getpid(), os.WTERMSIG(status)) >> # go to the unreachable place >> break >> diff --git a/lib/portage/process.py b/lib/portage/process.py >> index 7103b6b31..3e07f806c 100644 >> --- a/lib/portage/process.py >> +++ b/lib/portage/process.py >> @@ -564,15 +564,27 @@ def _exec(binary, mycommand, opt_name, fd_pipes, >> noiselevel=-1) >> else: >> if unshare_pid: >> - # pid >> namespace requires us to become init >> - fork_ret = >> os.fork() >> - if >> fork_ret != 0: >> - >> os.execv(portage._python_interpreter, [ >> + >> main_child_pid = os.fork() >> + if >> main_child_pid == 0: >> + # >> pid namespace requires us to become init >> + >> binary, myargs = portage._python_interpreter, [ >> + >> portage._python_interpreter, >> + >> os.path.join(portage._bin_path, >> + >> 'pid-ns-init')] >> + [binary] + myargs >> + else: >> + # >> Execute a supervisor process which will forward >> + # >> signals to init and forward exit status to the >> + # >> parent process. The supervisor process runs in >> + # >> the global pid namespace, so skip /proc remount >> + # >> and other setup that's intended only for the >> + # >> init process. >> + >> binary, myargs = portage._python_interpreter, >> [ portage._python_interpreter, os.path.join(portage._bin_path, >> - >> 'pid-ns-init'), >> - '%s' >> % fork_ret, >> - ]) >> + >> 'pid-ns-init'), >> str(main_child_pid)] + >> + >> os.execve(binary, myargs, env) + >> if unshare_mount: >> # mark the >> whole filesystem as slave to avoid # mounts escaping the namespace > > Looks fine,
Thanks, merged: https://gitweb.gentoo.org/proj/portage.git/commit/?id=fb406579b1d13c1ba23b28e0bb794c22878a58c0 > but I defer to floppym, mgorny since this affects systemd I not experiencing any problems with systemd here. We've got this patch to solve the systemd pkg_postinst thing: https://gitweb.gentoo.org/proj/portage.git/commit/?id=bbfc36befdeed60f29c17d80d7766fd0da402d61 -- Thanks, Zac
signature.asc
Description: OpenPGP digital signature