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

"CGO_ENABLED=0 go build" binary #2566

Closed
zokrezyl opened this issue Aug 24, 2020 · 7 comments
Closed

"CGO_ENABLED=0 go build" binary #2566

zokrezyl opened this issue Aug 24, 2020 · 7 comments

Comments

@zokrezyl
Copy link

I hoped to find something similar in the issues collection, but no luck. Trying to build master/head with

"CGO_ENABLED=0 go build"

unfortunately the executable does not seem to behave as expected:

ERRO[0000] container_linux.go:370: starting container process caused: process_linux.go:346: getting pipe fds for pid 0 caused: readlink /proc/0/fd/0: no such file or directory

Is this a known issue? Is there any workaround?

The intention is to bring RunC into an environment where I don't want to install the libc dependencies. To be more precise I am building an executable on top of runc that contains (packr) other stuff to run some specific containers.

Thanks for your time

@cyphar
Copy link
Member

cyphar commented Aug 25, 2020

runc has C code embedded inside it in order to run (this code is a core part of container setup and can't be disabled) -- so you'll need to have libc enabled when you build runc. However you can always just use our static binaries (see the releases page) which mean you don't need libc dependencies at runtime.

@zokrezyl
Copy link
Author

zokrezyl commented Sep 27, 2020

I understand that you have the container setup part that has C code. Is there any part of the C code that could not be rewritten in Go?

@zokrezyl
Copy link
Author

zokrezyl commented Sep 27, 2020

Just gave it another try. The secret was in the Makefile of runc. Just building the 'static' target, I have an executable that is not depending on the hosts or target hosts libc.

->/g/e/runc/runc --rootless true run test       
->ldd /g/e/runc/runc
        not a dynamic executable

@cyphar
Copy link
Member

cyphar commented Sep 28, 2020

Yes, make static will build runc as a static binary (this is what we distribute in our releases). I thought you were asking about building runc without having glibc-devel installed (which isn't possible).

To answer this part of your question:

Is there any part of the C code that could not be rewritten in Go?

Yes, the namespace setup code cannot be done in Go because the Go runtime is multi-threaded and this simply cannot be disabled (and the namespace interfaces require you to run them as a single-threaded program). Go does have some basic support for namespace setup, but it's woefully inadequate for what we do (not to mention any new kernel feature may require the setup code to be changed -- which means we'd have to wait for a new Go release before we could use it). And historically speaking, features like runtime.LockOSThread() didn't work for a very long time so we couldn't even use the Go built-in support even if we wanted to.

@zokrezyl
Copy link
Author

Well, when I raised the question was not aware or did not think about linking statically. Thus my problem is solved.

Thanks for the clarification related to go and namespace setup. Does this mean that runc will call some external program for namespace manipulation? Linking statically means the C lib will be in the same mult-threaded process.

@cyphar
Copy link
Member

cyphar commented Sep 29, 2020

We don't use an external program, we have a complicated hack using __attribute__((constructor)) to call this function whenever runc is executed. In order to do namespace setup, we simply do execve("/proc/self/exe") to re-execute the current process with the right environment variables set up and the C code does the setup before returning which allows the Go runtime to boot and continue executing the runc init logic. The package has a short explanation of how this works.

@zokrezyl
Copy link
Author

Thanks for the extra explanation. In the meantime I understood the logic, this is how I proposed a potential solution for #1800

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants