16319: Use high precision clock for file timestamps.
authorTom Clegg <tom@tomclegg.ca>
Wed, 20 May 2020 03:35:33 +0000 (23:35 -0400)
committerTom Clegg <tom@tomclegg.ca>
Wed, 20 May 2020 03:35:33 +0000 (23:35 -0400)
Fixes occasional test failures caused by artificially old file
timestamps.

Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@tomclegg.ca>

services/keepstore/unix_volume.go

index ceccd11c92172a0f018ec87f25a95bfdada2bf33..9dbb0c3f38865ef4f9d74f5743df5af0bafe6839 100644 (file)
@@ -298,6 +298,17 @@ func (v *UnixVolume) WriteBlock(ctx context.Context, loc string, rdr io.Reader)
                v.os.Remove(tmpfile.Name())
                return err
        }
+       // ext4 uses a low-precision clock and effectively backdates
+       // files by up to 10 ms, sometimes across a 1-second boundary,
+       // which produces confusing results in logs and tests.  We
+       // avoid this by setting the output file's timestamps
+       // explicitly, using a higher resolution clock.
+       ts := syscall.NsecToTimespec(time.Now().UnixNano())
+       if err = syscall.UtimesNano(tmpfile.Name(), []syscall.Timespec{ts, ts}); err != nil {
+               err = fmt.Errorf("error setting timestamps on %s: %s", tmpfile.Name(), err)
+               v.os.Remove(tmpfile.Name())
+               return err
+       }
        if err := v.os.Rename(tmpfile.Name(), bpath); err != nil {
                err = fmt.Errorf("error renaming %s to %s: %s", tmpfile.Name(), bpath, err)
                v.os.Remove(tmpfile.Name())