Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On 11/18/18 1:21 AM, M. J. Everitt wrote: > On 18/11/18 09:18, Michał Górny wrote: >> On Sun, 2018-11-18 at 09:04 +, M. J. Everitt wrote: >>> On 18/11/18 08:53, Michał Górny wrote: Signed-off-by: Michał Górny --- 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 0..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: {} '.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 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 >>> Why in python?! Surely a small C app would be significantly more efficient >>> .. >>> >> Surely adding a new build system for C apps would be entirely justified >> by the necessity of premature optimization of program that spends ~100% >> of its time in wait(). >> > Forgive my ignorance then .. what purpose does a process have which simply > wait()s ?! .. no, on second thoughts, don't answer that question, I'm > unlikely to like the answer anyway ... An init process is a fundamental requirement of any pid namespace, which is why dumb-init was created: https://engineeringblog.yelp.com/2016/01/dumb-init-an-init-for-docker.html -- Thanks, Zac signature.asc Description: OpenPGP digital signature
Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On 11/18/18 12:53 AM, Michał Górny wrote: > Signed-off-by: Michał Górny > --- > 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 0..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: {} '.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) Technically, is not valid to call WEXITSTATUS unless WIFEXITED called true. If the child process was killed by a signal, we have a couple of options: 1) Kill the current process with the same signal, as suggested in https://www.cons.org/cracauer/sigint.html. 2) Fake it by exiting with 128 + signum (this is what dumb-init does). -- Thanks, Zac signature.asc Description: OpenPGP digital signature
Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On Sun, 2018-11-18 at 09:21 +, M. J. Everitt wrote: > On 18/11/18 09:18, Michał Górny wrote: > > On Sun, 2018-11-18 at 09:04 +, M. J. Everitt wrote: > > > On 18/11/18 08:53, Michał Górny wrote: > > > > Signed-off-by: Michał Górny > > > > --- > > > > 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 0..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: {} '.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 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 > > > > > > Why in python?! Surely a small C app would be significantly more > > > efficient .. > > > > > > > Surely adding a new build system for C apps would be entirely justified > > by the necessity of premature optimization of program that spends ~100% > > of its time in wait(). > > > > Forgive my ignorance then .. what purpose does a process have which simply > wait()s ?! .. no, on second thoughts, don't answer that question, I'm > unlikely to like the answer anyway ... > Well, if you find it useless, then I would suggest you save some space by doing: rm /sbin/init -- Best regards, Michał Górny signature.asc Description: This is a digitally signed message part
Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On 18/11/18 09:18, Michał Górny wrote: > On Sun, 2018-11-18 at 09:04 +, M. J. Everitt wrote: >> On 18/11/18 08:53, Michał Górny wrote: >>> Signed-off-by: Michał Górny >>> --- >>> 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 0..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: {} '.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 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 >> Why in python?! Surely a small C app would be significantly more efficient .. >> > Surely adding a new build system for C apps would be entirely justified > by the necessity of premature optimization of program that spends ~100% > of its time in wait(). > Forgive my ignorance then .. what purpose does a process have which simply wait()s ?! .. no, on second thoughts, don't answer that question, I'm unlikely to like the answer anyway ... signature.asc Description: OpenPGP digital signature
Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On Sun, 2018-11-18 at 09:04 +, M. J. Everitt wrote: > On 18/11/18 08:53, Michał Górny wrote: > > Signed-off-by: Michał Górny > > --- > > 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 0..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: {} '.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 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 > > Why in python?! Surely a small C app would be significantly more efficient .. > Surely adding a new build system for C apps would be entirely justified by the necessity of premature optimization of program that spends ~100% of its time in wait(). -- Best regards, Michał Górny signature.asc Description: This is a digitally signed message part
Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
On 18/11/18 08:53, Michał Górny wrote: > Signed-off-by: Michał Górny > --- > 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 0..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: {} '.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 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 Why in python?! Surely a small C app would be significantly more efficient .. signature.asc Description: OpenPGP digital signature
[gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace
Signed-off-by: Michał Górny --- 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 0..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: {} '.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 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 -- 2.19.1