Signed-off-by: Michał Górny <mgo...@gentoo.org> --- bin/pid-ns-init | 25 +++++++++++++++++++++++++ lib/portage/process.py | 11 ++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 bin/pid-ns-init
diff --git a/bin/pid-ns-init b/bin/pid-ns-init new file mode 100644 index 000000000..90660571a --- /dev/null +++ b/bin/pid-ns-init @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# Copyright 2018 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +import os +import sys + + +def main(argv): + if len(argv) < 2: + return 'Usage: {} <main-child-pid>'.format(argv[0]) + main_child_pid = int(argv[1]) + + # wait for child processes + while True: + pid, status = os.wait() + if pid == main_child_pid: + return os.WEXITSTATUS(status) + + # this should never be reached + return 127 + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/lib/portage/process.py b/lib/portage/process.py index beeb09529..4b0d8f7bc 100644 --- a/lib/portage/process.py +++ b/lib/portage/process.py @@ -545,13 +545,14 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, else: if unshare_pid: # pid namespace requires us to become init - # TODO: do init-ty stuff - # therefore, fork() ASAP fork_ret = os.fork() if fork_ret != 0: - pid, status = os.waitpid(fork_ret, 0) - assert pid == fork_ret - os._exit(status) + os.execv(portage._python_interpreter, [ + portage._python_interpreter, + os.path.join(portage._bin_path, + 'pid-ns-init'), + '%s' % fork_ret, + ]) if unshare_mount: # mark the whole filesystem as private to avoid # mounts escaping the namespace -- 2.19.1