Skip to content

Calling setns from Go returns EINVAL for mnt namespace #8676

Closed
@gopherbot

Description

@gopherbot

by iain.lowe:

The C code works fine and correctly enters the namespace, but the Go code always seems
to return EINVAL from the `setns` call to enter the `mnt` namespace. I've tried a number
of permutations (including embedded C code with cgo and external `.so`) on Go `1.2`,
`1.3` and the current tip.

Stepping through the code in `gdb` shows that both sequences are calling `setns` in
`libc` the exact same way (or so it appears to me).

I have boiled what seems to be the issue down to the code below. What am I doing wrong?

## Setup

I have a shell alias for starting quick busybox containers:

    alias startbb='docker inspect --format "{{ .State.Pid }}" $(docker run -d busybox sleep 1000000)'

After running this, `startbb` will start a container and output it's PID.

`lxc-checkconfig` outputs:

    Found kernel config file /boot/config-3.8.0-44-generic
    --- Namespaces ---
    Namespaces: enabled
    Utsname namespace: enabled
    Ipc namespace: enabled
    Pid namespace: enabled
    User namespace: missing
    Network namespace: enabled
    Multiple /dev/pts instances: enabled
    
    --- Control groups ---
    Cgroup: enabled
    Cgroup clone_children flag: enabled
    Cgroup device: enabled
    Cgroup sched: enabled
    Cgroup cpu account: enabled
    Cgroup memory controller: missing
    Cgroup cpuset: enabled
    
    --- Misc ---
    Veth pair device: enabled
    Macvlan: enabled
    Vlan: enabled
    File capabilities: enabled

`uname -a` produces:

    Linux gecko 3.8.0-44-generic #66~precise1-Ubuntu SMP Tue Jul 15 04:01:04 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

## Working C code

The attached C code works fine.

After compiling with `gcc -o checkns checkns.c`, the output of `sudo ./checkns
<PID>` is:

    setns on ipc namespace succeeded
    setns on uts namespace succeeded
    setns on net namespace succeeded
    setns on pid namespace succeeded
    setns on mnt namespace succeeded

## Failing Go code

Conversely, the attached Go code (which should be identical) doesn't work quite as well.

Instead, running `sudo go run main.go <PID>` produces:

    setns on ipc namespace succeeded
    setns on uts namespace succeeded
    setns on net namespace succeeded
    setns on pid namespace succeeded
    setns on mnt namespace failed: invalid argument

Attachments:

  1. checkns.c (786 bytes)
  2. checkns.go (730 bytes)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions