Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: add bind/mount operations to SysProcAttr on Linux #12125

Open
sargun opened this issue Aug 13, 2015 · 5 comments

Comments

@sargun
Copy link

commented Aug 13, 2015

It would be nice to be able to pass a list of bind mounts to ForkAndExec via SysProcAttr, that Go bind mounts after forking (and execing): https://golang.org/pkg/syscall/#SysProcAttr. Alternatively, it would be nice to have the ability to pass a lambda to it that would call some syscalls (or raw syscalls) before it execs.

@ianlancetaylor ianlancetaylor changed the title Bind mounts for mount namespaces on Linux syscall: Bind mounts for mount namespaces on Linux Aug 13, 2015

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Aug 13, 2015

Our basic guideline for SysProcAttr is that we only add operations that must take place between the fork and execve calls. As far as I know bind mounts are not such a call: you could instead exec a small helper program that did the bind mounts, and then execed the real program. Running that small helper program is inconvenient, but better than adding new obscure features to the syscall package.

It's not possible to have a function that runs between fork and exec, because many Go operations are not available during that time. Only very carefully written Go code can happen in that space. Permitting an arbitrary function would be an invitation to bugs and a severe restriction on what we could do going forward.

Is there any reason a bind mount has to happen between fork and execve?

@rsc rsc added this to the Go1.6 milestone Oct 23, 2015

@rsc rsc added the Thinking label Oct 23, 2015

@rsc

This comment has been minimized.

Copy link
Contributor

commented Nov 24, 2015

@sargun, arbitrary func calls won't happen, for the reasons Ian explained. They'll be basically impossible to use correctly.

@ianlancetaylor, the argument you're making also applies to closing file descriptors, yet we do that. So there must be a slightly different line. My guess is that it's based on how common/complex the operations are. New mounts do seem a bit rare.

In Plan 9, rfork(2) let you change the current process; you only got a new process if you included the RFPROC bit. So on a Plan 9 system you could call rfork(RFNAMEG) to put the calling thread in its own name space group, do you bind mounts, and then fork/exec. Translated into Go, it would be something like

go func() {
    runtime.LockOSThread()
    syscall.Rfork(syscall.RFNAMEG)
    ... binds/mounts ...
    result = ForkExec(...)
    c <- result
}()
result := <-c

It would be very nice if there were some equivalent on Linux, but as far as I can tell that functionality (operating on the current thread) was dropped along the way from rfork to clone.

@rsc rsc changed the title syscall: Bind mounts for mount namespaces on Linux syscall: add bind/mount operations to SysProcAttr on Linux Nov 24, 2015

@rsc

This comment has been minimized.

Copy link
Contributor

commented Nov 24, 2015

(Clarifying title, not making a decision.)

@mdempsky

This comment has been minimized.

Copy link
Member

commented Nov 24, 2015

@rsc For what it's worth, Linux has unshare() and setns() system calls that operate on the current process/thread:

@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 5, 2015

@mdempsky Thanks. Those look promising.

@sargun, can you take a look at those system calls and see if that works for you? The pattern would be something like:

runtime.LockOSThread()
unshare(2) to get private name space for thread
do bind/mounts
ForkExec or cmd.Start
setns(2) to reconnect to original name space
runtime.UnlockOSThread()

You can do the sequence in a goroutine if you want to make sure not to affect a possible thread lock in the caller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.