How to install Go 1.1 on CentOS 5.9

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

  1. Support for the O_CLOEXEC flag passed to open(2). We attempt to work around this in the os.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.
  2. Support for accept4(2). accept4(2) was introduced in kernel 2.6.28 to allow O_CLOEXEC to 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.
  3. 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.

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.