1 |
On 11/18/18 1:21 AM, M. J. Everitt wrote: |
2 |
> On 18/11/18 09:18, Michał Górny wrote: |
3 |
>> On Sun, 2018-11-18 at 09:04 +0000, M. J. Everitt wrote: |
4 |
>>> On 18/11/18 08:53, Michał Górny wrote: |
5 |
>>>> Signed-off-by: Michał Górny <mgorny@g.o> |
6 |
>>>> --- |
7 |
>>>> bin/pid-ns-init | 25 +++++++++++++++++++++++++ |
8 |
>>>> lib/portage/process.py | 11 ++++++----- |
9 |
>>>> 2 files changed, 31 insertions(+), 5 deletions(-) |
10 |
>>>> create mode 100644 bin/pid-ns-init |
11 |
>>>> |
12 |
>>>> diff --git a/bin/pid-ns-init b/bin/pid-ns-init |
13 |
>>>> new file mode 100644 |
14 |
>>>> index 000000000..90660571a |
15 |
>>>> --- /dev/null |
16 |
>>>> +++ b/bin/pid-ns-init |
17 |
>>>> @@ -0,0 +1,25 @@ |
18 |
>>>> +#!/usr/bin/env python |
19 |
>>>> +# Copyright 2018 Gentoo Authors |
20 |
>>>> +# Distributed under the terms of the GNU General Public License v2 |
21 |
>>>> + |
22 |
>>>> +import os |
23 |
>>>> +import sys |
24 |
>>>> + |
25 |
>>>> + |
26 |
>>>> +def main(argv): |
27 |
>>>> + if len(argv) < 2: |
28 |
>>>> + return 'Usage: {} <main-child-pid>'.format(argv[0]) |
29 |
>>>> + main_child_pid = int(argv[1]) |
30 |
>>>> + |
31 |
>>>> + # wait for child processes |
32 |
>>>> + while True: |
33 |
>>>> + pid, status = os.wait() |
34 |
>>>> + if pid == main_child_pid: |
35 |
>>>> + return os.WEXITSTATUS(status) |
36 |
>>>> + |
37 |
>>>> + # this should never be reached |
38 |
>>>> + return 127 |
39 |
>>>> + |
40 |
>>>> + |
41 |
>>>> +if __name__ == '__main__': |
42 |
>>>> + sys.exit(main(sys.argv)) |
43 |
>>>> diff --git a/lib/portage/process.py b/lib/portage/process.py |
44 |
>>>> index dee126c3c..75ec299f0 100644 |
45 |
>>>> --- a/lib/portage/process.py |
46 |
>>>> +++ b/lib/portage/process.py |
47 |
>>>> @@ -544,13 +544,14 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, |
48 |
>>>> else: |
49 |
>>>> if unshare_pid: |
50 |
>>>> # pid namespace requires us to become init |
51 |
>>>> - # TODO: do init-ty stuff |
52 |
>>>> - # therefore, fork() ASAP |
53 |
>>>> fork_ret = os.fork() |
54 |
>>>> if fork_ret != 0: |
55 |
>>>> - pid, status = os.waitpid(fork_ret, 0) |
56 |
>>>> - assert pid == fork_ret |
57 |
>>>> - os._exit(status) |
58 |
>>>> + os.execv(portage._python_interpreter, [ |
59 |
>>>> + portage._python_interpreter, |
60 |
>>>> + os.path.join(portage._bin_path, |
61 |
>>>> + 'pid-ns-init'), |
62 |
>>>> + '%s' % fork_ret, |
63 |
>>>> + ]) |
64 |
>>>> if unshare_mount: |
65 |
>>>> # mark the whole filesystem as slave to avoid |
66 |
>>>> # mounts escaping the namespace |
67 |
>>> Why in python?! Surely a small C app would be significantly more efficient .. |
68 |
>>> |
69 |
>> Surely adding a new build system for C apps would be entirely justified |
70 |
>> by the necessity of premature optimization of program that spends ~100% |
71 |
>> of its time in wait(). |
72 |
>> |
73 |
> Forgive my ignorance then .. what purpose does a process have which simply |
74 |
> wait()s ?! .. no, on second thoughts, don't answer that question, I'm |
75 |
> unlikely to like the answer anyway ... |
76 |
|
77 |
An init process is a fundamental requirement of any pid namespace, which |
78 |
is why dumb-init was created: |
79 |
|
80 |
https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html |
81 |
-- |
82 |
Thanks, |
83 |
Zac |