Linux and other Unix-like OSes that use 32 bit values to
represent the number of seconds since 1970 will, on its present course,
encounter a "Year 2000-like" problem in early 2038, when,
approximately two billion seconds after 1970, timet
counters roll around.
The following article describes a preliminary analysis that has been done...
From: bgiles@dimensional.com (Bear Giles) Newsgroups: comp.os.linux.development.system Subject: Y2038: Problems exist; fix by kernel 3.0.x? Organization: Dimensional Communications Lines: 142 Message-ID: <6r374h$scr@flatland.dimensional.com> Date: Sat, 15 Aug 1998 05:42:51 GMT NNTP-Posting-Host: 208.206.176.24 NNTP-Posting-Date: Fri, 14 Aug 1998 23:42:51 MDT Path: blue.hex.net!news.planetc.com!leto.ou.edu!hammer.uoregon.edu!newsxfer3.itd.umich.edu!news.maxwell.syr.edu!chippy.visi.com!news-out.visi.com!pulsar.dimensional.com!dimensional.com!wormhole.dimensional.com!not-for-mail Xref: blue.hex.net comp.os.linux.development.system:55396Some people (including many who should know better) have been claiming that Y2038 "isn't a problem" since it's trivial to change the definition of timet to a 64-bit entity and recompile everything.
Sorry, but that's a load of bovine byproduct.
Here are a list of Y2038 problems in the Linux kernel today in the 2.0.35 and 2.1.115 kernels:
2.0.35.
asm_i386/posix_types.h typedef long long __kernel_time_t; linux/time.h struct timeval { long long tv_sec; long tv_usec; }; struct timespec { long long tv_sec; long tv_usec; }; Status: LINK FAILED. undefined reference __moddi3. Cause: do_gettimeofday(); secs = tv.tv_sec % 86400; (long long % long -> undefined reference in kernel).2.0.35.
Status: LINK SUCCESSED; KERNEL NON-Y2038 COMPLIANT
asm_i386/posix_types.h typedef long long __kernel_time_t; linux/time.h struct timeval { int tv_sec; long tv_usec; }; struct timespec { long long tv_sec; long tv_usec; };("timet" is not the only Y2038 time in the kernel. We must also ensure that "struct timeval" will handle dates past the end of the Unix-32 epoch.)
2.1.115
EXT2 FILESYSTEM
filesystem times (iatime, ictime, imtime, idtime) are all defined as u32 fields. Maybe the code will work in 2039, maybe it won't. But it's still not Y2106 compliant.
Bottom line: we need to allocation additional storage for date fields. Perhaps ext3fs is the same, except for u64 fields. Alternately, use the same 8 bytes as
struct { i16 year; u8 mon, u8 day, u8 hour, u8 min, u8 sec, u8 tzcode };
Speaking only for myself, I don't mind a Y32000 problem. :-)
Most (all?) other Linux filesystems have the same problem.
LIBC
typedef long long __kernel_time_t;
Consider the following code snippet:
what does
*tm
contain?We may need to modify the time routines something like:
... if (sizeof (time_t) <= 4 && ((unsigned long) t & (1ul << 31))) treat as invalid time; else if ((long long) t == -1ll) treat as old invalid time else treat as valid time in Y2038 or beyond(Well, maybe it works if I could compile a Y2038 kernel, then Y2038 compilers, libraries, etc., and then wrote and compiled a simple test case. I'll get back to you after winning the next big Powerball drawing.)
This is far from an exhaustive list; I've identified these problems in just a few hours of free time.
Clearly, Linux (i386) is not Y2038 ready. However I think it's reasonable that a requirement for kernel 3.0 is Y2038 compliance defined as:
The kernel will actually compile and link on all platforms with 64-bit timet and struct timeval.tvsec. (duh)
At least one first-tier file system (e.g., ext2) contains 64-bit time fields. These fields should contain either timet values, a split field with (at least) 16-bit years, or 48 bits of Julian Day Number (and 16 bits of seconds-since- midnight.] As today, something like u64 must appear in the structure definition, not timet.
The kernel configuration menu will include a "Y2038-ready" option under "General Setup." If the flag is set, kerneltimet is a 64 bit entity. If the flag is not set, kerneltimet is a 32 bit entity. Most people will use 32-bit timet for many years to come, but still allows 64-bit timet work to proceed.
It would be nice if libc is patched to handle 64-bit timet in a reasonable manner, but that's independent of kernel 3.0.
If we go straight from 2.2 to 3.0, the Linux community has 2-3 years to make these changes. Piece-o-cake, since many of us will be running 64-bit i386 systems by then. :-)
If we go from 2.2 to 2.4 and thence to 3.0, we have around 5 years for these changes. It's almost harder to justify not making these changes than making them, over such a long time frame.
Finally, there's something to be said for having some rich symbolism in the criteria for 3.0. I suspect that many people will be very pissed off at properietary software in mid-2000, and the Open Software community demonstrating awareness and action to avoid a problem a generation away will be a shocking display of... dare I say it... maturity.
Comments?
As an aside, many file systems distinuish between a file creation date and a logical creation date. The US Declaration of Independence, for instance, has a LCD of 1776-07-04. Some documents have LCDs with negative years. Fortunately JDN (modified so the day number doesn't change at local noon) is apparently sufficient to ensure that the numbers will never be negative, while the computational costs to convert to/from timet are modest.]