Important Go 1.0 or 1.1 has never supported RHEL5 or CentOS5. In fact, I don’t think Go will even compile on RHEL5/CentOS5 after version 1.3. Please do not interpret anything in this article as a statement that Go does support RHEL5 or CentOS5.
Introduction
Go has never supported RedHat 5 or CentOS 5. We’ve been pretty good at getting that message out, but it still catches a few people by surprise. The reason these old releases are not supported is the Linux kernel that ships with them, a derivative of 2.6.18, does not provide three facilities required by the Go runtime.
These are
- Support for the
O_CLOEXEC
flag passed toopen(2)
. We attempt to work around this in theos.OpenFile
function, but not all kernels that do not support this flag return an error telling us they don’t support it. The result on RHEL5/CentOS5 systems is file descriptors can leak into child processes, this isn’t a big problem, but does cause test failures. - Support for
accept4(2)
.accept4(2)
was introduced in kernel 2.6.28 to allowO_CLOEXEC
to be set on newly accepted socket file descriptors. In the case that this syscall is not supported, we fall back to the olderaccept(2)
syscall at a small performance hit. - Support for high resolution vDSO
clock_gettime(2)
. vDSO is a way of projecting a small part of the kernel into your process address space. This means you can call certain syscalls (known as vsyscalls) without the cost of a trap into kernel space or a context switch. Go usesclock_gettime(2)
via the vDSO in preference to the oldergettimeofday(2)
syscall as it is both faster, and higher precision.
Installing Go from source
As RHEL5/CentOS5 are not supported, there are no binary packages available on the golang.org website. To install Go you will need to use the source tarball, in this case we’re using the Go 1.1.1 release. I’m using a CentOS 5.9 amd64 image running in a vm.
Install prerequisites
The packages required to build Go on RedHat platforms are listed on the Go community wiki.
$ sudo yum install gcc glibc-devel
Download and unpack
We’re going to download the Go 1.1.1 source distribution and unpack it to $HOME/go
.
$ curl https://go.googlecode.com/files/go1.1.1.src.tar.gz | tar xz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 8833k 100 8833k 0 0 710k 0 0:00:12 0:00:12 --:--:-- 974k $ ls Desktop go
Build
$ cd go/src $ ./make.bash # Building C bootstrap tool. cmd/dist # Building compilers and Go bootstrap tool for host, linux/amd64. lib9 libbio ... Installed Go for linux/amd64 in /home/dfc/go Installed commands in /home/dfc/go/bin
Add go
to PATH
$ export PATH=$PATH:$HOME/go/bin $ go version go version go1.1.1 linux/amd64
Known issues
As described above, RHEL5/CentOS5 are not supported as their kernel is too old. Here are some of the known issues. As RHEL5/CentOS5 are unsupported, they will not be fixed.
Test failures
You’ll notice above to build Go I ran make.bash
, not the recommended all.bash
, to skip the tests. Due to the lack of working O_CLOEXEC
support, some tests will fail. This is a known issue and will not be fixed.
$ ./run.bash ... --- FAIL: TestExtraFiles (0.05 seconds) exec_test.go:302: Something already leaked - closed fd 3 exec_test.go:359: Run: exit status 1; stdout "leaked parent file. fd = 10; want 9\n", stderr "" FAIL FAIL os/exec 0.489s
Segfaults and crashes due to missing vDSO support
A some point during the RHEL5 release cycle support for vDSO vsyscalls was added to RedHat’s 2.6.18 kernel. However that point appears to differ by point release. For example, for RedHat 5, kernel 2.6.18-238.el5 does not work, whereas 2.6.18-238.19.1.el5 does. Running CentOS 5.9 with kernel 2.6.18.348.el5 does work.
$ ./make.bash ... cmd/go ./make.bash: line 141: 8269 segmentfault "$GOTOOLDIR"/go_bootstrap clean -i std
In summary, if the your Go programs crash or segfault using RHEL5/CentOS5, you should try upgrading to the latest kernel available for your point release. I’ll leave the comments on this article open for a while so people can contribute their known working kernel versions, perhaps I can build a (partial) table of known good configurations.