Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File.SetLastAccessTimeUtc on Ubuntu is only up to seconds #26964

Closed
wli3 opened this issue Jul 26, 2018 · 15 comments
Closed

File.SetLastAccessTimeUtc on Ubuntu is only up to seconds #26964

wli3 opened this issue Jul 26, 2018 · 15 comments
Assignees
Milestone

Comments

@wli3
Copy link

wli3 commented Jul 26, 2018

Similar to https://github.com/dotnet/corefx/issues/26024 but for write

This blocks using msbuild incremental build. Especially when using MemoryMappedFile, LastWriteTime will not be set automatically

using System;
using System.IO;

namespace testLastAccess
{
    class Program
    {
        static void Main(string[] args)
        {
            File.WriteAllText("file_reference", "");
            File.WriteAllText("file_change_lastaccess", "");

            File.SetLastAccessTimeUtc("file_change_lastaccess", DateTime.UtcNow);

            Console.WriteLine(File.GetLastWriteTimeUtc("file_reference").Ticks + " file_reference");
            Console.WriteLine(File.GetLastWriteTimeUtc("file_change_lastaccess").Ticks  + " file_change_lastaccess");
        }
    }
}

on Ubuntu

wul@willauzrelinux3:~/test/testSetFileLastAccessTime$ dotnet run
636681614066249674 file_reference
636681614060000000 file_change_lastaccess

file_change_lastaccess has SetLastAccessTimeUtc after file_reference is created. But end up easier than file_reference. And clearly, the ticks are rounded.

on Windows it is correct

λ  dotnet run
636681613739905306 file_reference
636681613739915309 file_change_lastaccess
@danmoseley
Copy link
Member

@Anipik could you please take a look when you free up?

@Anipik
Copy link
Contributor

Anipik commented Jul 27, 2018

yep I will take a look at it sometime next week :)

@danmoseley
Copy link
Member

I'll set the milestone to 2.1.x for now.

@danmoseley
Copy link
Member

Ugh, I see the comment shows the problem -- when fixing, please help check that we don't have anywhere else in CoreFX/CoreCLR that does not set milliseconds. For a start we should not use utime anywhere we can use utimensat or utimes.

        private void SetAccessWriteTimes(string path, long? accessTime, long? writeTime)
        {
            // force a refresh so that we have an up-to-date times for values not being overwritten
            _fileStatusInitialized = -1;
            EnsureStatInitialized(path);
            Interop.Sys.UTimBuf buf;
            // we use utime() not utimensat() so we drop the subsecond part
            buf.AcTime = accessTime ?? _fileStatus.ATime;
            buf.ModTime = writeTime ?? _fileStatus.MTime;
            Interop.CheckIo(Interop.Sys.UTime(path, ref buf), path, InitiallyDirectory);
            _fileStatusInitialized = -1;
        }

@wli3
Copy link
Author

wli3 commented Jul 31, 2018

It looks like this impact large project solution builds. Currently Ubuntu takes 2 times of time to build incrementally than Windows

@Anipik
Copy link
Contributor

Anipik commented Jul 31, 2018

yeah it will be an improvement. I will post the numbers when I put the PR to fix this

@Anipik
Copy link
Contributor

Anipik commented Jul 31, 2018

I am able to make it work using utimes

@wli3 can you confirm that following is the required output ?

  Discovering: System.IO.FileSystem.Tests
  Discovered:  System.IO.FileSystem.Tests
  Starting:    System.IO.FileSystem.Tests
  636686696383220724 file_reference
  636686696383221610 file_change_lastaccess

@wli3
Copy link
Author

wli3 commented Jul 31, 2018

@Anipik yes, this looks good

@Anipik
Copy link
Contributor

Anipik commented Aug 2, 2018

@danmosemsft its fixed in master, do we want it to go for release branch

@danmoseley
Copy link
Member

Thanks @Anipik you're the file timestamp expert now. Yes, please add the template to this issue, create the port PR, and send mail to the usual alias per the procedure in my email and while back.

@Anipik
Copy link
Contributor

Anipik commented Aug 2, 2018

Thanks :) I will do that

@Anipik
Copy link
Contributor

Anipik commented Aug 3, 2018

Shiproom template

Description

Currently, when we set the LastAccessTime or LastModifiedTime of the files on Unix, the millisecond/micrososecond/nanosecond attribute of the timestamp of the file is always set to zero.

Customer Impact

The customers will be able to set Last Access Time or Last Modified Time in Unix to nanosecond granularity.
Incremental build is faster by 2% on unix systems.

Regression?

Not a Regression

Risk

Low risk because this change is already in master.
We are now using utimensat function to set the timestamp, if the utimensat is not available on the machine we are falling back to utimes

@vivmishra
Copy link
Contributor

vivmishra commented Aug 7, 2018

Approved for 2.1.5.
Hold your checkin until further notice about branch availability.

@Anipik
Copy link
Contributor

Anipik commented Aug 9, 2018

Updated the template with performance numbers

@karelz
Copy link
Member

karelz commented Aug 21, 2018

Fixed in 3.0 in PR dotnet/corefx#31522 (setting milestone accordingly & closing).

Note: The 2.1.x port was rejected - see PR dotnet/corefx#31569.

@karelz karelz closed this as completed Aug 21, 2018
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants