1 |
commit: a75d5546e3a49599280c222a75471981bf2a7837 |
2 |
Author: Michał Górny <mgorny <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Nov 13 21:34:14 2018 +0000 |
4 |
Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Nov 18 12:25:04 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=a75d5546 |
7 |
|
8 |
Introduce a tiny init replacement for inside pid namespace |
9 |
|
10 |
Reviewed-by: Zac Medico <zmedico <AT> gentoo.org> |
11 |
Signed-off-by: Michał Górny <mgorny <AT> gentoo.org> |
12 |
|
13 |
bin/pid-ns-init | 30 ++++++++++++++++++++++++++++++ |
14 |
lib/portage/process.py | 11 ++++++----- |
15 |
2 files changed, 36 insertions(+), 5 deletions(-) |
16 |
|
17 |
diff --git a/bin/pid-ns-init b/bin/pid-ns-init |
18 |
new file mode 100644 |
19 |
index 000000000..843257b70 |
20 |
--- /dev/null |
21 |
+++ b/bin/pid-ns-init |
22 |
@@ -0,0 +1,30 @@ |
23 |
+#!/usr/bin/env python |
24 |
+# Copyright 2018 Gentoo Authors |
25 |
+# Distributed under the terms of the GNU General Public License v2 |
26 |
+ |
27 |
+import os |
28 |
+import sys |
29 |
+ |
30 |
+ |
31 |
+def main(argv): |
32 |
+ if len(argv) < 2: |
33 |
+ return 'Usage: {} <main-child-pid>'.format(argv[0]) |
34 |
+ main_child_pid = int(argv[1]) |
35 |
+ |
36 |
+ # wait for child processes |
37 |
+ while True: |
38 |
+ pid, status = os.wait() |
39 |
+ if pid == main_child_pid: |
40 |
+ if os.WIFEXITED(status): |
41 |
+ return os.WEXITSTATUS(status) |
42 |
+ elif os.WIFSIGNALED(status): |
43 |
+ os.kill(os.getpid(), os.WTERMSIG(status)) |
44 |
+ # go to the unreachable place |
45 |
+ break |
46 |
+ |
47 |
+ # this should never be reached |
48 |
+ return 127 |
49 |
+ |
50 |
+ |
51 |
+if __name__ == '__main__': |
52 |
+ sys.exit(main(sys.argv)) |
53 |
|
54 |
diff --git a/lib/portage/process.py b/lib/portage/process.py |
55 |
index dee126c3c..75ec299f0 100644 |
56 |
--- a/lib/portage/process.py |
57 |
+++ b/lib/portage/process.py |
58 |
@@ -544,13 +544,14 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, |
59 |
else: |
60 |
if unshare_pid: |
61 |
# pid namespace requires us to become init |
62 |
- # TODO: do init-ty stuff |
63 |
- # therefore, fork() ASAP |
64 |
fork_ret = os.fork() |
65 |
if fork_ret != 0: |
66 |
- pid, status = os.waitpid(fork_ret, 0) |
67 |
- assert pid == fork_ret |
68 |
- os._exit(status) |
69 |
+ os.execv(portage._python_interpreter, [ |
70 |
+ portage._python_interpreter, |
71 |
+ os.path.join(portage._bin_path, |
72 |
+ 'pid-ns-init'), |
73 |
+ '%s' % fork_ret, |
74 |
+ ]) |
75 |
if unshare_mount: |
76 |
# mark the whole filesystem as slave to avoid |
77 |
# mounts escaping the namespace |