Re: [gentoo-portage-dev] [PATCH v2 3/3] Introduce a tiny init replacement for inside pid namespace

2018-11-18 Thread Zac Medico
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

2018-11-18 Thread Zac Medico
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

2018-11-18 Thread Michał Górny
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

2018-11-18 Thread M. J. Everitt
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

2018-11-18 Thread Michał Górny
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

2018-11-18 Thread M. J. Everitt
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

2018-11-18 Thread Michał Górny
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