Description of problem: It would be nice if there was always set TZ environment variable to avoid unnecessary syscalls. If left unset for example time() and similar syscalls will call stat() everytime instead of using cached value. I do not know if there is some way for setup to auto-magically set it to correct value, however even simple /etc/localtime will work for the most common use case. Additional info: GNU doc for TZ: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
This bug appears to have been reported against 'rawhide' during the Fedora 29 development cycle. Changing version to '29'.
Completely missed that one. I don't know what you mean by "simple /etc/localtime will work for the most common use case". That file is in binary format and I can't guess the default TZ at the time of setup package installation - as setup is one of the first packages to be installed. What I can imagine is profile.d script that will run timedatectl command, parse Time Zone and based on it will set TZ envvar. Not sure if worth effort, though, as this would mean some TZ guess at the start of user session anyway(probably grep + cut). Is this what you expect?
(In reply to Ondrej Vasik from comment #2) > I don't know what you mean by "simple /etc/localtime will work for the most > common use case". That file is in binary format Yes, that is generally true, however "$ cat /etc/localtime | tail -1" seems to produces sufficient output for time-zone setting.
The function that causes the stat() call is localtime() and other time conversion functions in glibc, right? What happens if the admin reconfigures /etc/localtime while the programs are running, or there is a tzdata update? I think that could be an unexpected side effect of this optimization.
(In reply to Miroslav Lichvar from comment #4) > The function that causes the stat() call is localtime() and other time > conversion functions in glibc, right? > Yes > What happens if the admin reconfigures /etc/localtime while the programs are > running, or there is a tzdata update? I think that could be an unexpected > side effect of this optimization. That is unfortunately probable, this optimization would have to be documented so people know to either update the value after updating timezone, however this situation should be quite rare in practice (what are the reasons behind manually changing timezone anyway?).
Created attachment 1527208 [details] proof of concept for the VDSO run it both with TZ set and unset
Hi all, the rationale behind this is that the kernel links every binary with a fake library named VDSO[1], as you can see in the ldd output: $ ldd /bin/cat linux-vdso.so.1 (0x00007ffebcdfa000) libc.so.6 => /lib64/libc.so.6 (0x00007f5a18ab0000) /lib64/ld-linux-x86-64.so.2 (0x00007f5a18cb2000) This library contains a variant of the clock_gettime() and gettimeofday() which gets the time from a readonly shared mem instead of issueing a syscall. The glibc supports this, but if the TZ environment variable is unset, it does a stat("/etc/localtime"), nullifying the advantage of avoiding a call to gettimeofday(). I have attached a proof of concept to show this, this is a run on a Fedora 29 system with TZ unset: $ gcc -Wall -O2 time_vdso.c -o time_vdso $ time ./time_vdso real 0m6,068s user 0m1,233s sys 0m4,835s $ strace -c ./time_vdso % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 100,00 12,664314 2 4999999 stat 0,00 0,000000 0 6 read 0,00 0,000000 0 3 close 0,00 0,000000 0 4 fstat 0,00 0,000000 0 4 lseek 0,00 0,000000 0 7 mmap 0,00 0,000000 0 4 mprotect 0,00 0,000000 0 1 munmap 0,00 0,000000 0 4 brk 0,00 0,000000 0 1 1 access 0,00 0,000000 0 1 execve 0,00 0,000000 0 2 1 arch_prctl 0,00 0,000000 0 3 openat ------ ----------- ----------- --------- --------- ---------------- 100.00 12,664314 5000039 2 total By setting TZ to a good value, the program runs 15x faster: $ export TZ=Europe/Rome $ time ./time_vdso real 0m0,411s user 0m0,411s sys 0m0,000s $ strace -c ./time_vdso % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 17,55 0,000112 16 7 mmap 13,95 0,000089 22 4 brk 11,44 0,000073 18 4 mprotect 10,03 0,000064 64 1 execve 9,56 0,000061 10 6 read 8,93 0,000057 19 3 openat 5,96 0,000038 9 4 fstat 5,64 0,000036 9 4 lseek 4,70 0,000030 30 1 munmap 4,55 0,000029 9 3 close 4,55 0,000029 14 2 1 arch_prctl 3,13 0,000020 20 1 1 access ------ ----------- ----------- --------- --------- ---------------- 100.00 0,000638 40 2 total If the timezone is unknown, it can safely point to a file which describes the time zone, prepended by a colon. For example, this does the same job without having to specify the zone manually: $ export TZ=:/etc/localtime $ time ./time_vdso real 0m0,414s user 0m0,410s sys 0m0,004s [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/entry/vdso
On arm64 the difference is more noticeable: root@macchiatobin:~# uname -a Linux macchiatobin 5.0.0-rc6 #22 SMP Sun Feb 10 23:54:37 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux root@macchiatobin:~# time ./time_vdso real 0m13,849s user 0m6,089s sys 0m7,759s root@macchiatobin:~# export TZ=Europe/Rome root@macchiatobin:~# time ./time_vdso real 0m1,463s user 0m1,463s sys 0m0,000s
This message is a reminder that Fedora 29 is nearing its end of life. Fedora will stop maintaining and issuing updates for Fedora 29 on 2019-11-26. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a Fedora 'version' of '29'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora 29 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior this bug is closed as described in the policy above. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
This bug appears to have been reported against 'rawhide' during the Fedora 32 development cycle. Changing version to 32.
This bug appears to have been reported against 'rawhide' during the Fedora 34 development cycle. Changing version to 34.
This message is a reminder that Fedora Linux 34 is nearing its end of life. Fedora will stop maintaining and issuing updates for Fedora Linux 34 on 2022-06-07. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a 'version' of '34'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, change the 'version' to a later Fedora Linux version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora Linux 34 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora Linux, you are encouraged to change the 'version' to a later version prior to this bug being closed.
I don't think it's a good idea to set a default TZ value globally for all users by setup. No other distro does that (e.g. Suse, Debian). This is not a bug, but a feature. The reason for stat() calls is to allow for timezone changes. If you don't want that, just set the TZ before running the program or before calling the localtime() to the needed value. Some background info: The feature of having /etc/localtime stat() (and if changed also read()) every invocation of localtime() was introduced in REHL6, first attempt to get this behavior appeared in RHEL5: [Bug 452957 - [RHEL5] localtime() does not handle changes to /etc/locatime] https://bugzilla.redhat.com/show_bug.cgi?id=452957#c3 ~~~ I think it is a bad idea to change this in RHEL5.x, I'm afraid many customers would be upset by localtime slowdown in an update release. Just wait for RHEL6. ~~~ Ulrich Drepper explains why it is so and also recommends setting TZ by the user: [Bug 5184 - strftime stats /etc/localtime too much] https://sourceware.org/bugzilla/show_bug.cgi?id=5184#c1 ~~~ No, /etc/localtime is not touched too often. All the time functions are required to check TZ all the time. Missing that envvar, /etc/localtime is used. People who move laptops from one timezone to the other appreciate that. If this is no problem of yours just set TZ to /etc/localtime and all this will stop. ~~~ Another explanation from Jakub Jelinek: [Bug 171351 - strftime is unreasonably slow because of tzset] https://bugzilla.redhat.com/show_bug.cgi?id=171351#c1 ~~~ The reason for the stat is to allow for timezone changes. If you don't want that, you can just use TZ=/etc/localtime or TZ=Europe/Prague or whatever timezone you want to use. ~~~ Given the information above, I am closing this as WONTFIX.