Gentoo Archives: gentoo-portage-dev

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

Replies