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.
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.
- Support for the
O_CLOEXECflag passed to
open(2). We attempt to work around this in the
os.OpenFilefunction, 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)was introduced in kernel 2.6.28 to allow
O_CLOEXECto be set on newly accepted socket file descriptors. In the case that this syscall is not supported, we fall back to the older
accept(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 uses
clock_gettime(2)via the vDSO in preference to the older
gettimeofday(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.
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
$ 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
$ 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
$ export PATH=$PATH:$HOME/go/bin $ go version go version go1.1.1 linux/amd64
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.
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 188.8.131.528.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.