bug#40220: date command set linux epoch time failed
On 3/29/20 9:32 PM, Bob Proulx wrote: Both calls from GNU date are returning EINVAL. Those are Linux kernel system calls. Those Linux kernel system calls are using CLOCK_MONOTONIC. OK, I think I understand now. For some reason Linux prohibits you from setting CLOCK_REALTIME to a value less than what CLOCK_MONOTONIC would report. I don't know why Linux has this restriction - it violates POSIX as near as I can tell - but at any rate as you say it's a problem with the Linux kernel, not with GNU 'date'.
bug#40220: date command set linux epoch time failed
Paul Eggert wrote: > Bob Proulx wrote: > > By reading the documentation for CLOCK_MONOTONIC in clock_gettime(2): > > GNU 'date' doesn't use CLOCK_MONOTONIC, so why is CLOCK_MONOTONIC relevant > to this bug report? GNU date uses clock_settime() and settimeofday() on my Debian system. Let me repeat the strace snippet from my previous message which shows this. TZ=UTC strace -o /tmp/out -v date -s "1970-01-01 00:00:00" ... clock_settime(CLOCK_REALTIME, {tv_sec=0, tv_nsec=0}) = -1 EINVAL (Invalid argument) settimeofday({tv_sec=0, tv_usec=0}, NULL) = -1 EINVAL (Invalid argument) ... Both calls from GNU date are returning EINVAL. Those are Linux kernel system calls. Those Linux kernel system calls are using CLOCK_MONOTONIC. Therefore GNU date, on Linux systems, is by association with the Linux kernel, using CLOCK_MONOTONIC. And the Linux kernel is returning EINVAL. And according to the documentation for both clock_settime() and settimeofday() the most likely reason for the EINVAL is the application of CLOCK_MONOTONIC preventing it, because that documentation says that one cannot set the date earlier than the system uptime. Why this is desirable I have no idea as it does not seem desirable to me. But I am just the messenger, having read that in the documentation looking for the reason for the EINVAL return. > Is this some busybox thing? If so, user 'shy' needs to report it to the > busybox people, not to bug-coreutils. No. It is only a busybox thing as much as it is a GNU date thing in that both are making system calls to the Linux kernel and both are failing with EINVAL. The reference to busybox confused me at first too. But in the original report it was simply another case of the same thing. Which is actually a strong indication that it is not a bug in either of the frontend implementations but something common to both. In this case the kernel is the common part. This does not appear to be a bug in the sense that it is explicit behavior. It is working as the Linux kernel has coded it to behave. According to the documentation. If one were to take this anywhere it would be to the Linux kernel mailing list to discover why they implemented this inconvenient behavior. Meanwhile... Since I am writing this in this thread... I might mention to the original poster that if they are testing using old clock times they might be able to get a good result by using libfaketime https://github.com/wolfcw/libfaketime which is a user land strategy for implementing different fake clock times for programs. Very useful in testing. And then there would be no need to set the system time at all. $ faketime '1970-01-01 00:00:00 UTC' date -uR Thu, 01 Jan 1970 00:00:00 + Bob
bug#40220: date command set linux epoch time failed
On 3/28/20 9:12 AM, Bob Proulx wrote: By reading the documentation for CLOCK_MONOTONIC in clock_gettime(2): GNU 'date' doesn't use CLOCK_MONOTONIC, so why is CLOCK_MONOTONIC relevant to this bug report? Is this some busybox thing? If so, user 'shy' needs to report it to the busybox people, not to bug-coreutils.
bug#40220: date command set linux epoch time failed
Paul Eggert wrote: > Bob Proulx wrote: > > I tested this in a victim system and if I was very quick I was able to > > log in and set the time to :10 seconds but no earlier. > > Sounds like some sort of atomic-time thing, since UTC and TAI differed by 10 > seconds when they started up in 1972. Perhaps the clock in question uses TAI > internally? By reading the documentation for CLOCK_MONOTONIC in clock_gettime(2): CLOCK_MONOTONIC Clock that cannot be set and represents monotonic time since--as described by POSIX--"some unspecified point in the past". On Linux, that point corresponds to the number of seconds that the system has been running since it was booted. The CLOCK_MONOTONIC clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP. This clock does not count time that the system is suspended. It's the, "On Linux, that point corresponds to the number of seconds that the system has been running since it was booted." part that seems to apply here just by the reading of it. To test this I can reboot a VM, which boots quickly, and then as soon as I think it is available by watching the console I can ssh into it as root from another terminal. And then in that other terminal logged in as root I try to execute "date -s '1970-01-01 00:00:00 UTC'" as soon as possible. I am never able to do so due to EINVAL. But if I reboot and repeat the experiment trying to set a few seconds in time later then if I am quick I can sometimes catch "date -s '1970-01-01 00:00:10 UTC'" and have it work. Trying again now I was able to be quick and get logged in and set in :07 UTC. But then if I wait and let seconds tick by and try setting to :10 UTC seconds again it will fail. This matches the model described by the documentation that CLOCK_MONOTONIC is the system uptime and the kernel is not allowing the clock set to be before the system uptime. If I wait longer and try setting the date to various times then experimentally the behavior matches that I cannot set the system time earlier than the the system uptime. Personally I can't see an advantage for this behavior. Because if someone is doing an experiment and wants to reset the clock to time zero then I don't see an advantage of blocking that from happening. However doing so might avoid some accidental settings of the system clock to an unintended zero time. Just like rm --preserve-root. But how often does that actually happen? And then I would want to see a way to do it anyway for the experiment possibilities. Here reading the documentation it seems to be a new hard limitation coded into the Linux kernel that is blocking this. Bob