commit: a75d5546e3a49599280c222a75471981bf2a7837
Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 13 21:34:14 2018 +0000
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Sun Nov 18 12:25:04 2018 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=a75d5546
Introduce a tiny init replacement for inside pid namespace
Reviewed-by: Zac Medico <zmedico <AT> gentoo.org>
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
bin/pid-ns-init | 30 ++++++++++++++++++++++++++++++
lib/portage/process.py | 11 ++++++-----
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
new file mode 100644
index 000000000..843257b70
--- /dev/null
+++ b/bin/pid-ns-init
@@ -0,0 +1,30 @@
+#!/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:
+ if os.WIFEXITED(status):
+ return os.WEXITSTATUS(status)
+ elif os.WIFSIGNALED(status):
+ os.kill(os.getpid(), os.WTERMSIG(status))
+ # go to the unreachable place
+ break
+
+ # 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 dee126c3c..75ec299f0 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -544,13 +544,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 slave to avoid
# mounts escaping the
namespace