You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
=== RUN TestChtimesLinux
chtimes_linux_test.go:87: Expected: 2262-04-11 23:47:16 +0000 UTC, got: 1990-01-27 10:50:44 +0000 UTC
--- FAIL: TestChtimesLinux (0.00s)
=== RUN TestChtimes
chtimes_test.go:92: Expected: 2262-04-11 23:47:16 +0000 UTC, got: 1990-01-27 10:50:44 +0000 UTC
--- FAIL: TestChtimes (0.00s)
The problem explained
And the relevant parts of the code, for reference:
func init() {
// chtimes initialization
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
// This is a 64 bit timespec
// os.Chtimes limits time to the following
maxTime = time.Unix(0, 1<<63-1)
} else {
// This is a 32 bit timespec
maxTime = time.Unix(1<<31-1, 0)
}
}
func TestChtimesLinux(t *testing.T) {
[...]
// Test both aTime and mTime set to Unix max time
Chtimes(file, unixMaxTime, unixMaxTime)
f, err = os.Stat(file)
if err != nil {
t.Fatal(err)
}
stat = f.Sys().(*syscall.Stat_t)
aTime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec)) // nolint: unconvert
if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
}
After some investigation, I can explain the issue. On mips64, the size for Timespec.Nsec and Timespec.Sec is 64 bits. However, and that's the weird thing, the stat struct defines the variables st_atime, st_mtime and st_ctime as unsigned int, ie. 32 bits, in the kernel. See https://github.com/torvalds/linux/blob/master/arch/mips/include/uapi/asm/stat.h#L92
So what happens is that, while it's possible to set the access and modified times to something higher than UINT32_MAX, when one retrieves these values with f.Sys().(*syscall.Stat_t), this value is limited to 32 bit.
In other words, this test will never work on mips64, and that's expected
While building docker on a
mips64
machine, from the Debian infra, we observe that some tests fail. The full trace can be seen at https://buildd.debian.org/status/fetch.php?pkg=docker.io&arch=mips64el&ver=20.10.0%2Bdfsg2-1&stamp=1608299173. The relevant part is:The problem explained
And the relevant parts of the code, for reference:
After some investigation, I can explain the issue. On
mips64
, the size forTimespec.Nsec
andTimespec.Sec
is 64 bits. However, and that's the weird thing, thestat
struct defines the variablesst_atime
,st_mtime
andst_ctime
as unsigned int, ie. 32 bits, in the kernel. See https://github.com/torvalds/linux/blob/master/arch/mips/include/uapi/asm/stat.h#L92So what happens is that, while it's possible to set the access and modified times to something higher than
UINT32_MAX
, when one retrieves these values withf.Sys().(*syscall.Stat_t)
, this value is limited to 32 bit.In other words, this test will never work on mips64, and that's expected
The workarounds
One can simply skip this test on mips64. This is what I did in this patch: https://salsa.debian.org/docker-team/docker/-/blob/master/debian/patches/test--skip-pkg-system-chtimes-mips64.patch.
Maybe a better way would be to split this test in different tests or subtests, so that we can skip the last part properly with
t.Skip
.What approach do you prefer? I can submit a PR.
Thanks
The text was updated successfully, but these errors were encountered: