Forking is not safe in Go either. On Fri, Jul 1, 2016 at 11:34 AM Alex Bligh <a...@alex.org.uk> wrote:
> > > On 30 Jun 2016, at 14:10, Martynas Pumputis <martyn...@gmail.com> wrote: > > > > I see :-/ > > > > One very fragile workaround I've had in mind is to replace any > > occurrence of syscall.Syscall by syscall.Rawsyscall within call graph > > of doSomeStuff(). However, the Go scheduler is not truly cooperative, > > so unexpected preemption can happen during the execution (e.g. due to > > a stack growth) which might result in creation of a new OS thread (M). > > I've done this in C by creating a new thread and using the method > you describe. Would an alternative approach be to fork() in go > (look at github.com/sevlyar/go-daemon for instance), having previously > set up some IPC, and have your forked process (also in go, and in > the same source code) perform the things that need to be done in > the separate namespace? If you are always using the same alternate > namespace, you then only have IPC overhead, and if you are using > different namespaces each time, it costs a fork() but not an exec(). > > Alex > > > > > > On Thu, Jun 30, 2016 at 3:41 AM, Ian Lance Taylor <i...@golang.org> > wrote: > >> On Tue, Jun 28, 2016 at 2:50 PM, Martynas Pumputis <martyn...@gmail.com> > wrote: > >>> > >>> Recently I've bumped into a problem when using the Linux network > >>> namespaces in Go. > >>> > >>> In my program I have the following function: > >>> > >>> func do() { > >>> runtime.LockOSThread() > >>> defer runtime.UnlockOSThread() > >>> netns.Set(containerNs) > >>> defer netns.Set(hostNs) > >>> doSomeStuff() > >>> } > >>> > >>> where netns.Set [1] changes the network namespace (does the setns(2) > >>> syscall via syscall.Syscall). The problem with this function is that > >>> during the execution of doSomeStuff() or defer netns.Set(hostNs) the > >>> Go runtime might create a new OS thread (e.g. due to blocking) which > >>> will reside in the same namespace as parent (CLONE_NEWNET is not set > >>> when doing clone(2)). The newly created thread might be used for > >>> scheduling other go-routines which will end up running in the "wrong" > >>> namespace. As a consequence, the go-routines might not be able to > >>> access some netdevs available within the host network namespace or > >>> previously created sockets. > >>> > >>> One workaround to this problem is to shell out a process (e.g. via > >>> exec.Command) which would set the namespace and do doSomeStuff(). > >>> However, this approach is sort of ugly, because a) we create > >>> unnecessary process; b) doSomeStuff() cannot be implemented in Go > >>> without special hacks [2]. > >>> > >>> Considering a vast adoption of Go within containers software, it's a > >>> bit odd that the runtime does not provide any means to address the > >>> problem. Maybe I'm missing something? > >> > >> You aren't missing anything. Doing this correctly requires runtime > >> support, and that support does not exist. It's not even obvious how > >> to write it, at least not to me. > >> > >> Ian > > > > -- > > You received this message because you are subscribed to the Google > Groups "golang-nuts" group. > > To unsubscribe from this group and stop receiving emails from it, send > an email to golang-nuts+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/d/optout. > > > > -- > Alex Bligh > > > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.