|This article brought to you by LWN subscribers
Subscribers to LWN.net made this article — and everything that
By Jonathan Corbet
January 11, 2019
In January 2038, the 32-bit
value used on many Unix-like
systems will run out of bits and be unable to represent the current time.
This may seem like a distant problem, but, as Tom Scott recently
the year-2038 apocalypse is now closer to the present than the year-2000
problem. The fact that systems being deployed now will still be operating
in 2038 adds urgency to the issue as well.
The good news is that work has been underway for years to prepare
Linux for this date, so there should be no need to call developers out of
retirement in 2037 in a last-minute panic. Some of the final steps in this
transition for the core kernel have been posted, and seem likely to be
merged for 5.1.
There have been numerous phases to this work, which has been carried out
primarily by Arnd Bergmann and Deepa Dinamani. Timekeeping within the
kernel has been reworked to use 64-bit values throughout, even on 32-bit
systems, for example. A lot of work was required to get there, but that
was, in some sense, the easy part; since the changes were all internal to
the kernel, the developers involved were free to change interfaces when
needed. Life becomes more difficult when it comes to the system-call
interface, since that cannot be changed at whim without breaking user-space
The approach that has been taken here, for many of the relevant system
calls, is to recognize that most systems already have a 64-bit solution for
32-bit applications. Most 64-bit kernels are able to run 32-bit processes;
to do so, they provide a set of compatibility (or “compat”) system calls to
perform impedance matching. Typically, these compat calls simply reformat
32-bit types into their 64-bit equivalent, then pass the result to the
native 64-bit implementations. In other words, the compat calls do exactly
what is needed to connect a user space process using 32-bit times to a
kernel that uses 64-bit times throughout.
Much of the work that has been done to this point, thus, has been promoting
these compat system calls to become the native 32-bit system calls. User
space sees no changes, but the kernel is able to leave 32-bit times behind
entirely. To that end, one of the key changes in this patch
set posted by Bergmann is to take the compat calls and define them as
proper system calls for 32-bit systems. In the process, these calls are
renamed; futex() becomes futex_time32(), for example.
Then, 32-bit architectures are switched
over to use the new _time32() calls.
The only remaining problem, of course, is that user space is still using
32-bit times, so things will still explode on schedule in 2038. Fixing
that problem is not something that the kernel can do on its own, but it can
provide the infrastructure to make the transition possible. In particular,
for all of the _time32() calls described above, the patch set also
the 64-bit versions with _time64() suffixes. So, once this
patch is applied, both the (broken)
32-bit and (fixed) 64-bit interfaces are available in 32-bit systems.
At this point, the ball moves into the court of the C library and
distribution developers. A new C library release can define the
system-call interfaces with 64-bit time values, and implement those
interfaces with calls to the _time64() versions. Older binaries,
instead, will continue to use the 32-bit versions. For many applications,
all that will be needed at this point is a rebuild and they will be
prepared to survive the 2038 transition. Others, of course, will require
more work. Distributors have the option of rebuilding everything they ship
for 64-bit time, then disabling 32-bit times entirely by turning off the
COMPAT_32BIT_TIME configuration variable. Most distributors,
though, are likely to support both modes for some time yet.
For the curious, the system calls affected are:
utimensat(). The plan for
the GNU C Library transition has been posted in great detail as well.
These changes fix the core kernel system-call interfaces, but that is not
the end of the story. There are many other places in the kernel’s
user-space API where time values appear, and many of them need to be fixed
as well. Those are slowly being addressed. Consider, for example,
the SO_TIMESTAMP socket option (described in this man
page); it enables the reception of control messages with network
timestamp values. Those values are specified using struct
timeval, which is not year-2038 safe.
patch set from Dinamani addresses that problem by adding a new set of
options that are year-2038 safe. An application can request
SO_TIMESTAMP_NEW to get a new control-message format with 64-bit
times; the SO_TIMESTAMPNS and SO_TIMESTAMPING options
have seen a similar treatment. Socket timeout values also have a year-2038
patch series adds SO_RCVTIMEOU_NEW and
SO_SNDTIMEO_NEW to address it. Once again, libraries and
(possibly) applications will need to be changed to be able to make use of
these new options.
Once this work gets in, the kernel community, at least, can begin to think
that there is some light at the end of the tunnel. Problems will remain,
mostly in filesystem timestamps and time values that are passed to
ioctl() calls, but the work as a whole can be seen as entering the
clean-up phase. For library developers and distributors, though, the real
work is just beginning. The good news is that they still have some time to
get their piece of the work done so that systems deployed in the near
future will be ready for the not-so-near (but approaching rapidly) 2038
to post comments)