On 11/14/18 12:02 AM, Michał Górny wrote: > @@ -531,6 +543,15 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, > gid, groups, uid, umask, > > errno.errorcode.get(ctypes.get_errno(), '?')), > noiselevel=-1) > 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) > if unshare_mount: > # mark the whole > filesystem as private to avoid > # mounts escaping the > namespace > @@ -541,6 +562,18 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, > gid, groups, uid, umask, > # TODO: should > it be fatal maybe? > > writemsg("Unable to mark mounts private: %d\n" % (mount_ret,), > > noiselevel=-1) > + if unshare_pid: > + if mount_ret != 0: > + # can't proceed > without private mounts > + os._exit(1)
For the benefit of anyone not watching https://github.com/gentoo/portage/pull/379, the mount_ret is expected to be non-zero inside a chroot where `mount --make-rprivate /` would fail because / is not a mountpoint, and this is an extremely valuable use case for tools like catalyst that perform builds inside a chroot. Based on /proc/[pid]/mountinfo documentation in the proc(5) manpage, and empirical analysis of /proc/self/mountinfo in various states, it should be reasonable to assume that the current propagation flags are suitable if there is not a shared / or /proc mountpoint found in /proc/self/mountinfo. We can use a function like this to check if the `mount --make-rprivate /` call is needed: def want_make_rprivate(): try: with open('/proc/self/mountinfo', 'rb') as f: if re.match(rb'^\S+ \S+ \S+ \S+ (?P<mountpoint>/|/proc) \S+ (?:\S+:\S+ )*(?P<shared>shared:\S+ )', f.read(), re.MULTILINE) is None: return False except EnvironmentError: pass return True -- Thanks, Zac
signature.asc
Description: OpenPGP digital signature