Year-2038 work in 4.18
If 32-bit systems are to be able to handle times after January 2038, they will need to switch to a 64-bit version of the time_t type; the kernel will obviously need to support applications using that new type. Doing so in a way that doesn't break existing applications is going to require some careful work, though. In particular, the kernel must be able to successfully run a system where applications have been rebuilt to use a 64-bit time_t, but ancient binaries stuck on 32-bit time_t still exist; both applications should continue to work (though the old code may fail to handle times correctly).
The first step is to recognize that most architectures already have support for applications running in both 64-bit and 32-bit modes in the form of the compatibility code used to run 32-bit applications on 64-bit systems. At some point, all systems will be 64-bit systems when it comes to time handling, so it makes sense to use the compatibility calls for older applications even on 32-bit systems. To that end, with 4.18, work has been done to allow both 32-bit and 64-bit versions of the time-related system calls to be built on all architectures. The CONFIG_64BIT_TIME configuration symbol controls the building of the 64-bit versions on 32-bit systems, while CONFIG_COMPAT_32BIT_TIME controls the 32-bit versions.
Internally, some work has been done to keep the handling of time formats as simple as possible. The new __kernel_timespec type describes how 64-bit timespec values will be passed between the kernel and user space; it is designed to be the same for both 64-bit applications and those running under 32-bit emulation.
The long-term plan for many system calls with year-2038 issues is to create new versions, under new system-call numbers, that handle times in the __kernel_timespec format. The old versions, which will not handle 2038 correctly, will retain the old system-call numbers, so they will still be there for applications that expect them. Applications that are built for 64-bit time values will use the new versions and function correctly. For the most part, the patches for this phase of the work exist but have not yet found their way into the mainline.
One set of system calls that have changed are those managing System V interprocess communication. These system calls, providing access to semaphores, shared memory, and message queues, are not universally loved, but they do have users and need to continue to work. They also have interfaces using time_t values. For example, the semctl() system call uses the semid_ds structure, defined as:
struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Last change time */ unsigned long sem_nsems; /* No. of semaphores in set */ };
This structure looks like it would be difficult to extend to 64-bit time values without breaking compatibility, but the reality of the situation is a good illustration of how the view of system calls provided by the C library does not always match the actual interface provided by the kernel. The structure that is actually passed into and out of the kernel is rather different; the C library takes responsibility for converting between the two. The kernel's structure looks like this:
struct semid64_ds { struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ __kernel_time_t sem_otime; /* last semop time */ unsigned long __unused1; __kernel_time_t sem_ctime; /* last change time */ unsigned long __unused2; unsigned long sem_nsems; /* no. of semaphores in array */ unsigned long __unused3; unsigned long __unused4; };
This is the 32-bit version of the structure with some #ifdef lines taken out; the full definition can be found in include/uapi/asm-generic/sembuf.h. What jumps out here is the padding that exists between the time fields. Somebody, years ago (before the beginning of the Git era) decided that the kernel should use the semid64_ds structure on all systems, and to ensure that enough space existed to pass 64-bit time values at some time in the future.
Many years later, that decision is paying off. In 4.18, the kernel will be able to unconditionally return 64-bit times for sem_otime and sem_ctime, with no compatibility issues to worry about. To that end, the structure (on 32-bit systems) now looks like:
struct semid64_ds { struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ unsigned long sem_otime; /* last semop time */ unsigned long sem_otime_high; unsigned long sem_ctime; /* last change time */ unsigned long sem_ctime_high; unsigned long sem_nsems; /* no. of semaphores in array */ unsigned long __unused3; unsigned long __unused4; };
The extra bits in the _high fields will be ignored until the C library is upgraded to use them, but that can happen independently. There are some minor issues to be dealt with (the padding values are in the wrong place on big-endian systems, necessitating a swap operation, for example), but the change is essentially painless.
The one remaining piece, involving a bit more pain, is semtimedop(), which takes a struct timespec parameter. That call will have to be split into old and new versions, as described above — a change that has not found its way into 4.18.
The merging of these changes for 4.18 shows that the work on the year-2038
problem is progressing. There is still quite a bit to do; beyond the new
system calls, there are a bunch of ioctl() operations that will
need to be found and fixed, for example. But, from the kernel point of
view at least, perhaps there is some light visible at the end of the
tunnel. A complete solution will also require a lot of work at the
C-library, distribution, and application levels, though, so we are likely
to be hearing about year-2038 work for a while yet.
Index entries for this article | |
---|---|
Kernel | Year 2038 problem |
(Log in to post comments)
Year-2038 work in 4.18
Posted Jun 12, 2018 3:10 UTC (Tue) by marcH (subscriber, #57642) [Link]
A bit less for applications which handle dates in the future.
Year-2038 work in 4.18
Posted Jun 12, 2018 6:01 UTC (Tue) by k8to (guest, #15413) [Link]
Projections? Business looks maybe a year or so. Maybe other people look further?
Year-2038 work in 4.18
Posted Jun 12, 2018 6:18 UTC (Tue) by gfernandes (subscriber, #119910) [Link]
Year-2038 work in 4.18
Posted Jun 12, 2018 6:24 UTC (Tue) by jem (subscriber, #24231) [Link]
Out of curiosity, I checked the certificates in my Firefox browser. The "Amazon Root CA 1" certificate expires on January 17, 2038, just two days before the 32-bit rollover on January 19, 2038. Coincidence?
Year-2038 work in 4.18
Posted Jun 14, 2018 19:30 UTC (Thu) by flussence (subscriber, #85566) [Link]
Year-2038 work in 4.18
Posted Jun 14, 2018 13:18 UTC (Thu) by jschrod (subscriber, #1646) [Link]
That said, applications for this kind of work typically don't use time_t for such computations.
Well, except if some guys use Excel, then they use some kind of time_t nevertheless; but this doesn't have the Y2038 problem.
Year-2038 work in 4.18
Posted Jun 12, 2018 6:28 UTC (Tue) by anselm (subscriber, #2796) [Link]
Kernel-style time_t values are mostly useful for dealing with system-level stuff such as file access/modification/change times, process ages, and so on.
If you're writing applications that, e.g., handle life insurance calculations, you don't want to do that based on time_t – most programming languages have date/time data types that are way more useful and robust.
Year-2038 work in 4.18
Posted Jun 12, 2018 8:57 UTC (Tue) by eru (subscriber, #2753) [Link]
I wonder what time representation "at" and "cron" use? Of course you probably will not schedule anything with them years ahead, but in principle it is possible. Out of curiosity tried what "at" does given a date in 2040, and it did not complain (on a 64-bit Linux Mint 18.3):
$ at -f at-test.sh 12/12/2040 warning: commands will be executed using /bin/sh job 1 at Wed Dec 12 11:48:00 2040
But I guess it is infeasible to wait until that to see if it really worked.
Year-2038 work in 4.18
Posted Jun 12, 2018 10:11 UTC (Tue) by brooksmoses (guest, #88422) [Link]
Year-2038 work in 4.18
Posted Jun 12, 2018 16:08 UTC (Tue) by arnd (subscriber, #8866) [Link]
Also quite a bit less for people that run older kernels and/or provide long-term support.
Year-2038 work in 4.18
Posted Jun 14, 2018 6:34 UTC (Thu) by lamby (subscriber, #42621) [Link]
Year-2038 work in 4.18
Posted Jun 15, 2018 19:17 UTC (Fri) by fratti (guest, #105722) [Link]