-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Guard uses of lutimes, for portability #7048
Conversation
src/libfetchers/git.cc
Outdated
struct timeval times[2]; | ||
times[0].tv_sec = touch_time; | ||
times[0].tv_usec = 0; | ||
times[1].tv_sec = touch_time; | ||
times[1].tv_usec = 0; | ||
|
||
return lutimes(path.c_str(), times) == 0; | ||
#else | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nix emits a warning when this returns false
but I have assumed that's acceptable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mh, that's sad (and apologies, at least some of these are my doing).
Dropping these is annoying because it can make things non-reproducible (and in a way that Nix might very much not like). Not sure whether there's a good way around this
src/libutil/filesystem.cc
Outdated
@@ -76,6 +77,7 @@ void createSymlink(const Path & target, const Path & link, | |||
if (lutimes(link.c_str(), times)) | |||
throw SysError("setting time of symlink '%s'", link); | |||
} | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That guard (and the one below which acts on essentially duplicated code :/ ) is a bit annoying because it changes the semantics and affects reproducibility. Do you know whether there's a way to emulate lutimes
if it's absent?
Or maybe we can just ignore setting the time for the symlinks if lutimes
isn't available and pray that it doesn't matter in practice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
futimes() is available since glibc 2.3. lutimes() is available since glibc 2.6, and is implemented using the utimensat(2) system call, which is supported since kernel 2.6.22.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jugendhacker Does termux has the mentioned function ?
Triaged in the Nix team meeting:
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-03-03-nix-team-meeting-minutes-37/25998/1 |
@Ericson2314 and me checked the code, and found #8495 (which you are welcome to implement, it's an almost trivial change). Other than that, we agree with @thufschmitt. For any remaining occurrences of
Making this PR a draft until these changes are implemented. |
#8504 removed the dead code, now there are just two |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-06-12-nix-team-meeting-minutes-62/29315/1 |
This should be good to go, @thufschmitt @Ericson2314 do you want to take another look? |
src/libutil/file-system.hh
Outdated
* Whether or not the path is a symlink is taken from the mode of `st` | ||
* in fallback code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that precision really makes sense without the context of that PR (what's “fallback mode”?)
Besides that, I don't think we should trust st
to tell us whether the file is a symlink or not. Barring possible race conditions (which I think we can't avoid any way), there's no guaranty that st
refers to the path at path
(might have been a totally made up struct just to set the time, or taken from another file). We should rather re-check within the function (std::filesystem::is_symlink being our friend here I guess)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fallback mode is without lutimes
, with just utimes
(yes, this should be reworded)
Besides that, I don't think we should trust
st
to tell us whether the file is a symlink or not.
Note that this is not a new thing. I agree in principle, but how would you update canonicaliseTimestampAndPermissions
in practice? It is, already, very geared about working from a prior stat (in a context that we don't think things would change without them looking.
Unless we want to scope creep and overhaul canonicaliseTimestampAndPermissions
, I think it would be good to just document the race condition on this function and say callers must be confident st
is up to date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is not a new thing. I agree in principle, but how would you update
canonicaliseTimestampAndPermissions
in practice? It is, already, very geared about working from a prior stat (in a context that we don't think things would change without them looking.
That's indeed already the case for canonicaliseTimestampAndPermissions
, but I'd rather not also make it the case here when we can just replace the S_ISLNK(st.st_mode)
calls by std::filesystem::is_symlink(path)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK this is done now. the struct stat
way still exists, but is not forced upon everyone else.
fa1ca2e
to
9642d2d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thufschmitt's request is addressed. All the compat is a bit gnarly, but future improvements are possible.
Fixes #7045