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

all: announce end of support for old Linux versions #60792

Open
dmitshur opened this issue Jun 14, 2023 · 5 comments
Open

all: announce end of support for old Linux versions #60792

dmitshur opened this issue Jun 14, 2023 · 5 comments
Labels
Builders x/build issues (builders, bots, dashboards) Documentation NeedsFix The path to resolution is known, but the work has not been done. recurring Issues that should never be closed, but moved to the next milestone once fixed in the current one. release-blocker
Milestone

Comments

@dmitshur
Copy link
Contributor

New Linux versions get released over time, and old ones cannot be supported indefinitely. This is the tracking recurring issue for announcing end of support for very old versions that we decide to drop support for. (The corresponding tracking issues for macOS and Windows, the other two OSes that have first class ports, are #23011 and #52188.)

The most recent change was applied in Go 1.18, where proposal #45964 increased the minimum Linux kernel version requirement from 2.6.23 to 2.6.32. See https://go.dev/doc/go1.18#linux.

CC @golang/release.

@dmitshur dmitshur added Documentation Builders x/build issues (builders, bots, dashboards) NeedsFix The path to resolution is known, but the work has not been done. release-blocker recurring Issues that should never be closed, but moved to the next milestone once fixed in the current one. labels Jun 14, 2023
@dmitshur dmitshur added this to the Go1.22 milestone Jun 14, 2023
@ianlancetaylor
Copy link
Contributor

Just a note that the case for Linux is a bit different than that for macOS and Windows, as Linux does not have a sole vendor. We need to identify organizations that distribute older versions of Linux that are supported and used. For example, I believe that we should continue to support all versions of Linux that are actively supported by commercial organizations, such as RHEL or Suse Linux Enterprise Server, and also all versions of Linux that are actively supported by communities supporting stable versions, such as Rocky Linux. Of course the nature of Linux is such that the set of active organizations changes over time.

@baryluk
Copy link

baryluk commented Nov 4, 2023

3.10 could be a reasonable target.

For reference some facts about distros, and the kernel changes tangential to Go and userland.

Centos 7 - Linux 3.10
Centos 7: Released: 2014-07-07 , Full updates ended: 2020-08-06, Maintenance updates EOL: 2024-06-30
(Centos 8 is in maintenance for about a year now, and Centos 9 is current version)

Debian 9 - Linux 4.9
Debian 9.0 (codename Stretch) was initially released on June 17th, 2017. Last major update was Debian 9.13 was released [July 18th, 2020. Stretch had Long Term Support (LTS) until the end of June 2022.

Current stable Debian is version 12.2. So Debian 9.x is really ancient actually.

Debian 8 (Jessie), from 2015, had Linux 3.16.7-ckt9 in the 8.0

Ubuntu 16.04.7 LTS (initial relase of 16.04 - 2016-04-21; with latest minor bump 16.04.7 - August 13, 2020) - End of standard support: April 2021, EOL: April 2026

OpenSUSE 13.1, released 2013-11-19, end of life 2016-01, Linux 3.11.6

Oracle Linux 7 - initial release, Jul 2014, about same time as RHEL 7/ Centos. Extended support, Jun 2026. But if you pay, they will support you indefinitively (even on older version than 7), and it is likely there are people having such support in various industries. It is unlikely they run Go programs, and if they do, they will likely run older Go version for this anyway.

Also of note is that Oracle Linux 6.x, latest release, 6.10 from July 2018, has updated kernels, including 4.1.12, 2.6.39, and not just 2.6.32 (as RHEL 6).

These are the major ones that might be running and be sometimes hard to upgrade. Other distributions are more desktop and normal user focused, and update way faster, and earlier, and do not have LTS often. So it is close to 0% they would use old system or kernel.

For example, 3.10 would be like 20 major releases ago in world of Fedora, or Ubuntu.

The biggest risk would be probably various mobile and embedded arm devices, like Android, SBCs, routers, etc.

Linux 3.10 was release 30 June 2013, and was 10th LTS release. EOLed November 2017. Red Hat was maintaining own version of 3.10 (with backports from newer kernels, including some syscalls that were not originally in any upstream 3.10 release) until very recently.

Personally, I do not use any of these ancient systems. (Where I work, we migrated from Centos 7, about 2.5 years ago, and almost migrated from Centos 8 to Centos 9 to, already on some parts of our infra, but migrate on demand slowly instead). In other places, I run Debian 12, and still few Debian 11 systems, that could be updated anytime, but just wait their time.

Notable features added between 2.6.32 and 3.10, that might be semi related to userland go runtime

3.10:

  • memory mapped netlink I/O
  • Add new "perf mem" command for memory access profiling
  • POSIX and high-resolution timers support a new clock (CLOCK_TAI) which operates in international atomic time
  • Applications within control groups can now request memory pressure notifications when the system is running low on available memory
  • Make madvise(MADV_WILLNEED) support swap file prefetch

3.9

  • TCP and UDP sockets have a new option, SO_REUSEPORT, that allows multiple sockets listening for new connections or packets (respectively) at the same time
  • The PowerPC architecture supports a new set of transactional memory instructions; at this time, only user-space support is provided

3.8 (2012)

  • Support more page sizes for MAP_HUGETLB/SHM_HUGETLB, as some large applications want to use 1GB huge pages on some mappings
  • tmpfs: support SEEK_DATA and SEEK_HOLE lseek() flags
  • perf: x86: Make hardware event translations available in sysfs /sys/devices/cpu/events/
  • SCTP: support per-association statistics
  • 386 support dropped. Minimum is 486
  • The ptrace() system call has a new option flag, PTRACE_O_EXITKILL, which causes all traced processes to receive a SIGKILL signal if the tracing process exits unexpectedly.

3.7

  • TCP Fast Open (server side) (Client side on Linux 3.6)
  • The epoll_ctl() system call supports a new EPOLL_CTL_DISABLE operation to disable polling on a specific file descriptor.
  • Applications on the s/390 architecture can now make use of the System zEC12 hardware transactional memory feature.
  • perf trace, an alternative to strace
  • Providing protocol type via system.sockprotoname xattr of /proc/PID/fd entries (commit)
  • default loopback interface MTU raised to 64K
  • Add generic netlink support for tcp_metrics

3.6

  • TCP Fast Open (Client side)

3.5

  • Introduce /proc//task//children entry, which provides information about task children
  • Report file/anon bit in /proc/pid/pagemap
  • epoll(): Add a flag, EPOLLWAKEUP, to prevent suspend while epoll events are ready
  • fuse: add fallocate() operation

3.4

  • The pipe2() system call permits a new flag, O_DIRECT, that creates a pipe that operates in "packet" mode. Each write() to the pipe creates a distinct packet, and each read() reads exactly one packet
  • The new PR_SET_CHILD_SUBREAPER prctl() operation allows userspace service managers/supervisors mark itself as a sort of 'sub-init', able to stay as the parent for all orphaned processes created by the started services. All SIGCHLD signals will be delivered to the service manager
  • Mark thread stack correctly in proc//maps
  • Implement IP_UNICAST_IF and IPV6_UNICAST_IF socket options - This is mostly for Wine tho
  • Introduce the SO_PEEK_OFF sock option, implemented for datagram, seqpacket and stream sockets
  • MSG_TRUNC support for dgram sockets
  • Add missing getsockopt for SO_NOFCS

3.3

  • Android merge
  • Add BLKROTATIONAL ioctl, which permits applications to query whether a block device is rotational
  • Add a few /proc entries and prctl() codes to future checkpoint/restart support

3.2

  • sysctl: add support for poll()
  • Cross memory attach
  • ipv4: gc_interval sysctl removed
  • Support for transmission of IPv6 packets as well as the formation of IPv6 link-local addresses and statelessly autoconfigured addresses on top of IEEE 802.15.4 networks
  • crypto: Add userspace configuration API

3.1

  • tcp: Lower the default initRTO from 3secs to 1sec, as per RFC2988bis. It falls back to 3secs if the SYN or SYN-ACK packet has been retransmitted, AND the TCP timestamp option is not on
  • tcp: Compute protocol sequence numbers and fragment IDs using MD5 instead of MD4, as is inline with both RFC1948 and other OS
  • Add SEEK_HOLE and SEEK_DATA flags in lseek()
  • ptrace: implement PTRACE_INTERRUPT PTRACE_LISTEN , PTRACE_SEIZE , TRAP_NOTIFY
  • ipc: introduce shm_rmid_forced sysctl
  • x86: vsyscall emulation rework, and boot options to disable

3.0

  • sendmmsg
  • BPF JIT
  • Unprivileged ICMP_ECHO
  • setns() syscall
  • Alarm timers
  • tmpfs: implement generic xattr support
  • Allow no-cache copy from user on transmit
  • sctp: implement socket option SCTP_GET_ASSOC_ID_LIST, implement event notification SCTP_SENDER_DRY_EVENT
  • cgroups; remove the Namespace cgroup subsystem. It has been replaced by a compatibility flag 'clone_children', where a newly created cgroup will copy the parent cgroup values. The userspace has to manually create a cgroup and add a task to the 'tasks' file; Make 'procs' file writable

2.6.32 - 2.6.39 - Various / A lot / Not listed here.

I also looked at some man pages, and found few bits, for Linux above 2.6.32:

vdso:

   aarch64 functions
       The table below lists the symbols exported by the vDSO.
       symbol                   version
       ──────────────────────────────────────
       __kernel_rt_sigreturn    LINUX_2.6.39
       __kernel_gettimeofday    LINUX_2.6.39
       __kernel_clock_gettime   LINUX_2.6.39
       __kernel_clock_getres    LINUX_2.6.39

syscalls:

       bpf(2)                      3.18
       clone3(2)                   5.3
       close_range(2)              5.9
       copy_file_range(2)          4.5
       epoll_pwait2(2)             5.11
       execveat(2)                 3.19
       faccessat2(2)               5.8
       finit_module(2)             3.8             ireelavant (this is mostly for Android for loading kernel modules)
       fsconfig(2)                 5.2
       fsmount(2)                  5.2
       fsopen(2)                   5.2
       fspick(2)                   5.2
       get_tls(2)                  4.15          ARM OABI only, has __ARM_NR prefix
       getrandom(2)                3.17
       io_pgetevents(2)            4.18
       io_uring_enter(2)           5.1
       io_uring_register(2)        5.1
       io_uring_setup(2)           5.1
       kcmp(2)                     3.5
       kern_features(2)            3.7           SPARC64 only
       kexec_file_load(2)          3.17       irrelevant
       landlock_add_rule(2)        5.13    irrelevant
       landlock_create_ruleset(2)  5.13    irrelevant
       landlock_restrict_self(2)   5.13    irrelevant
       membarrier(2)               3.17
       memfd_create(2)             3.17
       memfd_secret(2)             5.14
       move_mount(2)               5.2
       name_to_handle_at(2)        2.6.39
       open_by_handle_at(2)        2.6.39
       open_tree(2)                5.2
       openat2(2)                  5.6
       or1k_atomic(2)              3.1           OpenRISC 1000 only
       pidfd_getfd(2)              5.6
       pidfd_send_signal(2)        5.1
       pidfd_open(2)               5.3
       pkey_alloc(2)               4.8
       pkey_free(2)                4.8
       pkey_mprotect(2)            4.8
       preadv2(2)                  4.6
       prlimit64(2)                2.6.36
       process_madvise(2)          5.10
       process_vm_readv(2)         3.2
       process_vm_writev(2)        3.2
       pwritev2(2)                 4.6
       quotactl_fd(2)              5.14
       recvmmsg(2)                 2.6.33
       riscv_flush_icache(2)       4.15          RISC-V only
       rseq(2)                     4.18
       s390_runtime_instr(2)       3.7           s390 only
       s390_pci_mmio_read(2)       3.19          s390 only
       s390_pci_mmio_write(2)      3.19          s390 only
       s390_sthyi(2)               4.15          s390 only
       s390_guarded_storage(2)     4.12          s390 only
       sched_getattr(2)            3.14
       sched_setattr(2)            3.14
       seccomp(2)                  3.17
       sendmmsg(2)                 3.0
       setns(2)                    3.0
       statx(2)                    4.11
       switch_endian(2)            4.1           PowerPC64 only
       syncfs(2)                   2.6.39
       userfaultfd(2)              4.3

Extra syscall options:

mmap

       MAP_SHARED_VALIDATE (since Linux 4.15)
       MAP_FIXED_NOREPLACE (since Linux 4.17)
       MAP_HUGE_2MB, MAP_HUGE_1GB (since Linux 3.8)
       MAP_SYNC (since Linux 4.15)
       MAP_UNINITIALIZED (since Linux 2.6.33)            irrelevant, requires special kernel config, for embeded single-user devices
open

       O_PATH (since Linux 2.6.39)
       O_TMPFILE (since Linux 3.11)

Since  Linux  2.6.33,  proper  O_SYNC support is provided.  

Since Linux 6.1, O_DIRECT support and alignment restrictions for a file can be queried using statx(2), using the STATX_DIOALIGN flag.

linkat

       AT_EMPTY_PATH (since Linux 2.6.39)
execve

can no longer fail with EAGAIN error (i.e. due to switching to a different user, and exhausting max number of processes limits).
clone3 options

               u64 set_tid;      /* Pointer to a pid_t array
                                    (since Linux 5.5) */
               u64 set_tid_size; /* Number of elements in set_tid
                                    (since Linux 5.5) */
               u64 cgroup;       /* File descriptor for target cgroup
                                    of child (since Linux 5.7) */

flag masks

       CLONE_CLEAR_SIGHAND (since Linux 5.5)
       CLONE_INTO_CGROUP (since Linux 5.7)
       CLONE_NEWCGROUP (since Linux 4.6)
       CLONE_NEWUSER  semantic fianlized between 2.6.23 and 3.5
       CLONE_PIDFD (since Linux 5.2)

returns:

EINVAL and and some other could be returned, some in relation to new flags, or to previously unhandled wrong combinations of flags.
       epoll_pwait2() was added in Linux 5.11.

epoll_ctl

       EPOLLWAKEUP (since Linux 3.5)
       EPOLLEXCLUSIVE (since Linux 4.5)

epoll_wait

       Before Linux 2.6.37, a timeout value larger than approximately
       LONG_MAX / HZ milliseconds is treated as -1 (i.e., infinity).
       Thus, for example, on a system where sizeof(long) is 4 and the
       kernel HZ value is 1000, this means that timeouts greater than
       35.79 minutes are treated as infinity.
clock_gettime

       CLOCK_REALTIME_ALARM (since Linux 3.0; Linux-specific)
       CLOCK_TAI (since Linux 3.10; Linux-specific)
       CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)
       CLOCK_BOOTTIME_ALARM (since Linux 3.0; Linux-specific)
   preadv2() and pwritev2()  # preadv2() and pwritev2() first appeared in Linux 4.6.
       RWF_DSYNC (since Linux 4.7)
       RWF_HIPRI (since Linux 4.6)
       RWF_SYNC (since Linux 4.7)
       RWF_NOWAIT (since Linux 4.14)
       RWF_APPEND (since Linux 4.16)
sendmsg

       MSG_FASTOPEN (since Linux 3.7)

recvfrom

      MSG_TRUNC (since Linux 2.2)
              For raw (AF_PACKET), Internet datagram (since Linux 2.4.27/2.6.8), netlink (since Linux 2.6.22), and UNIX datagram (since Linux 3.4) sockets: return the real length of the packet or datagram, even when it was longer than the passed buffer.
setsockopt

       TCP_USER_TIMEOUT (since Linux 2.6.37)
       TCP_FASTOPEN (since Linux 3.6)
       TCP_FASTOPEN_CONNECT (since Linux 4.11)

       SO_ATTACH_FILTER (since Linux 2.2), SO_ATTACH_BPF (since Linux 3.19)
       SO_BINDTODEVICE  (can do getsockopt since Linux 3.8)
       SO_DETACH_FILTER (since Linux 2.2), SO_DETACH_BPF (since Linux 3.19)
       SO_ATTACH_REUSEPORT_CBPF, SO_ATTACH_REUSEPORT_EBPF
       SO_INCOMING_NAPI_ID (gettable since Linux 4.12)
       SO_PEEK_OFF (since Linux 3.4)
       SO_REUSEPORT (since Linux 3.9)
       SO_RXQ_OVFL (since Linux 2.6.33)
       SO_SELECT_ERR_QUEUE (since Linux 3.10)
       SO_BUSY_POLL (since Linux 3.11)

       IP_BIND_ADDRESS_NO_PORT (since Linux 4.2)
       IP_NODEFRAG (since Linux 2.6.36)
The prlimit() system call is available since Linux 2.6.36.
mlock2() is available since Linux 4.4

MCL_ONFAULT (since Linux 4.4)

Some limit account bugs fixed in 4.9
pkey_mprotect() first appeared in Linux 4.9
futex

       FUTEX_LOCK_PI2 (since Linux 5.14)

timerfd_create

can use boottime and realtime alarm / clocks

              TFD_IOC_SET_TICKS (since Linux 3.17)

sendfile

       Before Linux 2.6.33, out_fd must refer to a socket.  Since Linux 2.6.33 it can be any file.  If it is a regular file, then sendfile() changes the file offset appropriately.  (Just like in 2.4.x and earlier).
copy_file_range

Since 5.19, can use for cross-filesystems copy, if src and dst file systems are the same and support it

Significantly improved error return codes in 5.3 and 5.19
pipe2

       O_DIRECT (since Linux 3.4)

O_NOTIFICATION_PIPE
              Since Linux 5.8,
fcntl

       F_SETPIPE_SZ (int; since Linux 2.6.35)
       F_GETPIPE_SZ (void; since Linux 2.6.35)

       F_ADD_SEALS (int; since Linux 3.17)
       F_GET_SEALS (void; since Linux 3.17)
       F_SEAL_FUTURE_WRITE (since Linux 5.1)

       F_GET_RW_HINT (uint64_t *; since Linux 4.13)
       F_SET_RW_HINT (uint64_t *; since Linux 4.13)
       F_GET_FILE_RW_HINT (uint64_t *; since Linux 4.13)
       F_SET_FILE_RW_HINT (uint64_t *; since Linux 4.13)
       RWH_WRITE_LIFE_NOT_SET
       RWH_WRITE_LIFE_NONE
       RWH_WRITE_LIFE_SHORT
       RWH_WRITE_LIFE_MEDIUM
       RWH_WRITE_LIFE_LONG
       RWH_WRITE_LIFE_EXTREME

Lost locks on NFSv4 mounts, are correctly detected in 3.12 in all cases, when using default nfs kernel module params.
statfs

       ST_NOSYMFOLLOW (since Linux 5.10)

       From Linux 2.6.38 up to and including Linux 3.1, fstatfs() failed with the error ENOSYS for file descriptors created by pipe(2).

@dmitshur
Copy link
Contributor Author

Thanks for the suggestion above.

We've entered the release freeze for 1.22 and there aren't announcements to make for this release, moving to the next for now.

@dmitshur dmitshur modified the milestones: Go1.22, Go1.23 Nov 29, 2023
@mdempsky
Copy link
Member

FWIW, it looks like Rust bumped their minimum Linux version to 3.2 last year, to align with glibc:

The new baseline requirements were picked as the least common denominator among long-term-support distributions that still have active support. This is currently RHEL 7 with glibc 2.17 and kernel 3.10. The kernel requirement is picked as 3.2 instead, because this is the minimum requirement of glibc itself, and there is little relevant API difference between these versions.

https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html

@rsc
Copy link
Contributor

rsc commented Apr 23, 2024

Filed #67001 for Linux 3.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Builders x/build issues (builders, bots, dashboards) Documentation NeedsFix The path to resolution is known, but the work has not been done. recurring Issues that should never be closed, but moved to the next milestone once fixed in the current one. release-blocker
Projects
Status: Planned
Status: No status
Development

No branches or pull requests

6 participants
@mdempsky @rsc @baryluk @dmitshur @ianlancetaylor and others