-
Notifications
You must be signed in to change notification settings - Fork 329
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
Draft: Add support for tapered, precise, absolute faketime start time #456
base: master
Are you sure you want to change the base?
Draft: Add support for tapered, precise, absolute faketime start time #456
Conversation
Sorry if this isn't exactly idiomatic or clean (in particular I'd like to have some way of "starting" rewrites at a given time for a whole process tree, not an individual process, which seems to be a limitation in |
44215b6
to
934c66a
Compare
I keep finding more problems with this approach this PR is not solving. |
Yes, The other aspect is getting everything to nanosecond resolution. Certainly doable, but probably needs changes in several places. |
@wolfcw, thanks for the quick response and for your suggestions, and sorry for a storm of increasingly ad-hoc patches. I think tapering will be highly desired for us, after all, since without it programs are more likely to notice the weird time jump, even if it happens before process startup. (programs notice it if they run Should I open a separate issue to discuss what's the best way to support tapered start? As a quick introduction of what tapering is, unless that's already clear: it's when the time mapping instead of a jump transition uses a gradual transition, see code below. The point being that such mapping is reversible (up to some loss of precision), so you need really pedantic tests to run into issues.
In the branch of this PR I seem to have a working prototype, but there are probably many reasons you don't want to take that code as-is. |
FAKETIME_KEEP_BEFORE_NSEC_SINCE_EPOCH
Adding two variables, specifying the beginning and the end of a tapered start interval, measured in nanoseconds since epoch: ``` FAKETIME_TAPER_BEGIN_NSEC_SINCE_EPOCH FAKETIME_TAPER_END_NSEC_SINCE_EPOCH ``` The behavior these implement is similar to what `FAKETIME_START_AFTER_SECONDS` does, with a few key differences: * timestamp is absolute, instead of being relative to process startup * timestamp is specified in nanoseconds * conversion interacts correctly with `utimes` family of functions * conversion is tapered (see below), which makes mapping reversible (up to loss of precision) The reason we want this feature is the following use case. We run a large test suite under faketime. That test suite has access to filesystem artifacts that were created prior to test start up. Among those artifacts are some caches which are considered up to date iff the timestamps of the files match what's recorded in a data structure. This means that for those caches to be considered valid we need their timestamps to not be fake. The reason we can't use `FAKETIME_START_AFTER_SECONDS` directly is that the test suite consists of multiple processes, for those processes to correctly interact with each other they need a consistent timestamp mapping that is shared between them. In fact the simplest bash script already behaves incorrectly because the commands use different process start times. ``` touch old LD_PRELOAD=... FAKETIME=+100d FAKETIME_START_AFTER_SECONDS=0 bash -c 'touch new; stat old new' ``` The expected behavior is that the timestamp of `old` is not rewritten, while the timestamp of `new` is rewritten. That is in fact achievable now: ``` FAKETIME_TAPER_BEGIN_NSEC_SINCE_EPOCH=$(date +%s%N) sleep 0.1 FAKETIME_TAPER_END_NSEC_SINCE_EPOCH=$(date +%s%N) FAKETIME=+100d FAKETIME_KEEP_BEFORE_NSEC_SINCE_EPOCH="$now_ns" bash -c 'touch new; stat old new' ``` What is tapering and why do we need it? The idea is to make the time transition smooth instead of abrupt, gradually increasing the offset amount from the start to the end of the tapering interval. The reason we want this is to make the time mapping reversible (up to some loss of precision). This means some programs that interact with the file system will no longer be confused. For example, if you do the equivalent of `touch -d "3 days ago"` and then read back the timestamp, you'll get approximately the expected timestamp, instead of something completely off.
3343efd
to
1beb455
Compare
FAKETIME_KEEP_BEFORE_NSEC_SINCE_EPOCH
behaves similar toFAKETIME_START_AFTER_SECONDS
, with two main differences:The reason we want this feature is the following use case.
We run a large test suite under faketime. That test suite has access to filesystem artifacts that were created prior to test start up. Among those artifacts are some caches which are considered up to date iff the timestamps of the files match what's recorded in a data structure.
This means that to access those caches to be considered valid we need their timestamps to not be rewritten.
The reason we can't use
FAKETIME_START_AFTER_SECONDS
directly is that the test suite consists of multiple processes, for those processes to correctly interact with each other they need a consistent timestamp mapping that is shared between them. In fact the simplest bash script already behaves incorrectly because the commands use different process start times.The expected behavior is that the timestamp of
old
is not rewritten, while the timestamp ofnew
is rewritten.That is in fact achievable now: