]> git.pld-linux.org Git - packages/util-linux.git/blame - glibc.patch
- rel 2; fixes hwclock: settimeofday() failed: Invalid argument with glibc 2.31
[packages/util-linux.git] / glibc.patch
CommitLineData
67a912cd
AM
1From cd781c405be82540484da3bfe3d3f17a39b8eb5c Mon Sep 17 00:00:00 2001
2From: J William Piggott <elseifthen@gmx.com>
3Date: Fri, 21 Feb 2020 20:03:47 -0500
4Subject: [PATCH] hwclock: make glibc 2.31 compatible
5
6______________________________________________________
7GNU C Library NEWS -- history of user-visible changes.
8Version 2.31
9Deprecated and removed features, and other changes affecting compatibility:
10
11* The settimeofday function can still be used to set a system-wide time
12 zone when the operating system supports it. This is because the Linux
13 kernel reused the API, on some architectures, to describe a system-wide
14 time-zone-like offset between the software clock maintained by the kernel,
15 and the "RTC" clock that keeps time when the system is shut down.
16
17 However, to reduce the odds of this offset being set by accident,
18 settimeofday can no longer be used to set the time and the offset
19 simultaneously. If both of its two arguments are non-null, the call
20 will fail (setting errno to EINVAL).
21
22 Callers attempting to set this offset should also be prepared for the call
23 to fail and set errno to ENOSYS; this already happens on the Hurd and on
24 some Linux architectures. The Linux kernel maintainers are discussing a
25 more principled replacement for the reused API. After a replacement
26 becomes available, we will change settimeofday to fail with ENOSYS on all
27 platforms when its 'tzp' argument is not a null pointer.
28
29 settimeofday itself is obsolescent according to POSIX. Programs that set
30 the system time should use clock_settime and/or the adjtime family of
31 functions instead. We may cease to make settimeofday available to newly
32 linked binaries after there is a replacement for Linux's time-zone-like
33 offset API.
34______________________________________________________
35
36hwclock(8) had one settimeofday(2) call where both args were set for
37--hctosys when the RTC was ticking UTC. This allowed setting the system
38time, timezone, and locking the warp_clock function with a single call.
39That operation now takes 3 calls of settimeofday(2).
40
41Although this common operation now takes three calls, the overall logic
42for the set_system_clock() function was simplified.
43
44Co-Author: Karel Zak <kzak@redhat.com>
45Signed-off-by: J William Piggott <elseifthen@gmx.com>
46---
47 sys-utils/hwclock.c | 71 +++++++++++++++++++++++----------------------
48 1 file changed, 37 insertions(+), 34 deletions(-)
49
50diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
51index e736da717..1191a8571 100644
52--- a/sys-utils/hwclock.c
53+++ b/sys-utils/hwclock.c
54@@ -643,28 +643,28 @@ display_time(struct timeval hwctime)
55 * tz.tz_minuteswest argument and sets PCIL (see below). At boot settimeofday(2)
56 * has one-shot access to this function as shown in the table below.
57 *
58- * +-------------------------------------------------------------------+
59- * | settimeofday(tv, tz) |
60- * |-------------------------------------------------------------------|
61- * | Arguments | System Time | PCIL | | warp_clock |
62- * | tv | tz | set | warped | set | firsttime | locked |
63- * |---------|---------|---------------|------|-----------|------------|
64- * | pointer | NULL | yes | no | no | 1 | no |
65- * | pointer | pointer | yes | no | no | 0 | yes |
66- * | NULL | ptr2utc | no | no | no | 0 | yes |
67- * | NULL | pointer | no | yes | yes | 0 | yes |
68- * +-------------------------------------------------------------------+
69+ * +-------------------------------------------------------------------------+
70+ * | settimeofday(tv, tz) |
71+ * |-------------------------------------------------------------------------|
72+ * | Arguments | System Time | TZ | PCIL | | warp_clock |
73+ * | tv | tz | set | warped | set | set | firsttime | locked |
74+ * |---------|---------|---------------|-----|------|-----------|------------|
75+ * | pointer | NULL | yes | no | no | no | 1 | no |
76+ * | NULL | ptr2utc | no | no | yes | no | 0 | yes |
77+ * | NULL | pointer | no | yes | yes | yes | 0 | yes |
78+ * +-------------------------------------------------------------------------+
79 * ptr2utc: tz.tz_minuteswest is zero (UTC).
80 * PCIL: persistent_clock_is_local, sets the "11 minute mode" timescale.
81 * firsttime: locks the warp_clock function (initialized to 1 at boot).
82+ * Since glibc v2.31 settimeofday() will fail if both args are non NULL
83 *
84 * +---------------------------------------------------------------------------+
85 * | op | RTC scale | settimeofday calls |
86 * |---------|-----------|-----------------------------------------------------|
87 * | systz | Local | 1) warps system time*, sets PCIL* and kernel tz |
88 * | systz | UTC | 1st) locks warp_clock* 2nd) sets kernel tz |
89- * | hctosys | Local | 1st) sets PCIL* 2nd) sets system time and kernel tz |
90- * | hctosys | UTC | 1) sets system time and kernel tz |
91+ * | hctosys | Local | 1st) sets PCIL* & kernel tz 2nd) sets system time |
92+ * | hctosys | UTC | 1st) locks warp* 2nd) sets tz 3rd) sets system time |
93 * +---------------------------------------------------------------------------+
94 * * only on first call after boot
95 */
96@@ -675,42 +675,45 @@ set_system_clock(const struct hwclock_control *ctl,
97 struct tm broken;
98 int minuteswest;
99 int rc = 0;
100- const struct timezone tz_utc = { 0 };
101
102 localtime_r(&newtime.tv_sec, &broken);
103 minuteswest = -get_gmtoff(&broken) / 60;
104
105 if (ctl->verbose) {
106- if (ctl->hctosys && !ctl->universal)
107- printf(_("Calling settimeofday(NULL, %d) to set "
108- "persistent_clock_is_local.\n"), minuteswest);
109- if (ctl->systz && ctl->universal)
110+ if (ctl->universal) {
111 puts(_("Calling settimeofday(NULL, 0) "
112- "to lock the warp function."));
113+ "to lock the warp_clock function."));
114+ if (!( ctl->universal && !minuteswest ))
115+ printf(_("Calling settimeofday(NULL, %d) "
116+ "to set the kernel timezone.\n"),
117+ minuteswest);
118+ } else
119+ printf(_("Calling settimeofday(NULL, %d) to warp "
120+ "System time, set PCIL and the kernel tz.\n"),
121+ minuteswest);
122+
123 if (ctl->hctosys)
124- printf(_("Calling settimeofday(%ld.%06ld, %d)\n"),
125- newtime.tv_sec, newtime.tv_usec, minuteswest);
126- else {
127- printf(_("Calling settimeofday(NULL, %d) "), minuteswest);
128- if (ctl->universal)
129- puts(_("to set the kernel timezone."));
130- else
131- puts(_("to warp System time."));
132- }
133+ printf(_("Calling settimeofday(%ld.%06ld, NULL) "
134+ "to set the System time.\n"),
135+ newtime.tv_sec, newtime.tv_usec);
136 }
137
138 if (!ctl->testing) {
139+ const struct timezone tz_utc = { 0 };
140 const struct timezone tz = { minuteswest };
141
142- if (ctl->hctosys && !ctl->universal) /* set PCIL */
143- rc = settimeofday(NULL, &tz);
144- if (ctl->systz && ctl->universal) /* lock warp_clock */
145+ /* If UTC RTC: lock warp_clock and PCIL */
146+ if (ctl->universal)
147 rc = settimeofday(NULL, &tz_utc);
148- if (!rc && ctl->hctosys)
149- rc = settimeofday(&newtime, &tz);
150- else if (!rc)
151+
152+ /* Set kernel tz; if localtime RTC: warp_clock and set PCIL */
153+ if (!rc && !( ctl->universal && !minuteswest ))
154 rc = settimeofday(NULL, &tz);
155
156+ /* Set the System Clock */
157+ if ((!rc || errno == ENOSYS) && ctl->hctosys)
158+ rc = settimeofday(&newtime, NULL);
159+
160 if (rc) {
161 warn(_("settimeofday() failed"));
162 return EXIT_FAILURE;
This page took 0.048829 seconds and 4 git commands to generate.