[packages/util-linux] - rel 2; fixes hwclock: settimeofday() failed: Invalid argument with glibc 2.31

arekm arekm at pld-linux.org
Wed Apr 1 22:59:15 CEST 2020


commit 67a912cd50464cae095fbdb7b3cf90daf495fb90
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Wed Apr 1 22:59:06 2020 +0200

    - rel 2; fixes hwclock: settimeofday() failed: Invalid argument with glibc 2.31

 glibc.patch     | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 util-linux.spec |   4 +-
 2 files changed, 165 insertions(+), 1 deletion(-)
---
diff --git a/util-linux.spec b/util-linux.spec
index 07a7bbe..feb5d06 100644
--- a/util-linux.spec
+++ b/util-linux.spec
@@ -39,7 +39,7 @@ Summary(tr.UTF-8):	Temel sistem araçları
 Summary(uk.UTF-8):	Набір базових системних утиліт для Linux
 Name:		util-linux
 Version:	2.35.1
-Release:	1
+Release:	2
 License:	GPL v2+, GPL v3 (hwclock)
 Group:		Applications/System
 # https://github.com/karelzak/util-linux (GitHub backup)
@@ -67,6 +67,7 @@ Patch5:		%{name}-ac.patch
 Patch6:		%{name}-diet.patch
 Patch7:		%{name}-pl.po.patch
 Patch8:		%{name}-completion-gawk.patch
+Patch9:		glibc.patch
 URL:		https://github.com/karelzak/util-linux
 BuildRequires:	audit-libs-devel >= 1.0.6
 BuildRequires:	autoconf >= 2.60
@@ -758,6 +759,7 @@ Bashowe dopełnianie parametrów dla poleceń z pakietu util-linux.
 %{?with_initrd:%patch6 -p1}
 #%patch7 -p1
 %patch8 -p1
+%patch9 -p1
 
 cp -p %{SOURCE10} nologin.c
 
diff --git a/glibc.patch b/glibc.patch
new file mode 100644
index 0000000..e839d81
--- /dev/null
+++ b/glibc.patch
@@ -0,0 +1,162 @@
+From cd781c405be82540484da3bfe3d3f17a39b8eb5c Mon Sep 17 00:00:00 2001
+From: J William Piggott <elseifthen at gmx.com>
+Date: Fri, 21 Feb 2020 20:03:47 -0500
+Subject: [PATCH] hwclock: make glibc 2.31 compatible
+
+______________________________________________________
+GNU C Library NEWS -- history of user-visible changes.
+Version 2.31
+Deprecated and removed features, and other changes affecting compatibility:
+
+* The settimeofday function can still be used to set a system-wide time
+  zone when the operating system supports it.  This is because the Linux
+  kernel reused the API, on some architectures, to describe a system-wide
+  time-zone-like offset between the software clock maintained by the kernel,
+  and the "RTC" clock that keeps time when the system is shut down.
+
+  However, to reduce the odds of this offset being set by accident,
+  settimeofday can no longer be used to set the time and the offset
+  simultaneously.  If both of its two arguments are non-null, the call
+  will fail (setting errno to EINVAL).
+
+  Callers attempting to set this offset should also be prepared for the call
+  to fail and set errno to ENOSYS; this already happens on the Hurd and on
+  some Linux architectures.  The Linux kernel maintainers are discussing a
+  more principled replacement for the reused API.  After a replacement
+  becomes available, we will change settimeofday to fail with ENOSYS on all
+  platforms when its 'tzp' argument is not a null pointer.
+
+  settimeofday itself is obsolescent according to POSIX.  Programs that set
+  the system time should use clock_settime and/or the adjtime family of
+  functions instead.  We may cease to make settimeofday available to newly
+  linked binaries after there is a replacement for Linux's time-zone-like
+  offset API.
+______________________________________________________
+
+hwclock(8) had one settimeofday(2) call where both args were set for
+--hctosys when the RTC was ticking UTC. This allowed setting the system
+time, timezone, and locking the warp_clock function with a single call.
+That operation now takes 3 calls of settimeofday(2).
+
+Although this common operation now takes three calls, the overall logic
+for the set_system_clock() function was simplified.
+
+Co-Author: Karel Zak <kzak at redhat.com>
+Signed-off-by: J William Piggott <elseifthen at gmx.com>
+---
+ sys-utils/hwclock.c | 71 +++++++++++++++++++++++----------------------
+ 1 file changed, 37 insertions(+), 34 deletions(-)
+
+diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
+index e736da717..1191a8571 100644
+--- a/sys-utils/hwclock.c
++++ b/sys-utils/hwclock.c
+@@ -643,28 +643,28 @@ display_time(struct timeval hwctime)
+  * tz.tz_minuteswest argument and sets PCIL (see below). At boot settimeofday(2)
+  * has one-shot access to this function as shown in the table below.
+  *
+- * +-------------------------------------------------------------------+
+- * |                       settimeofday(tv, tz)                        |
+- * |-------------------------------------------------------------------|
+- * |     Arguments     |  System Time  | PCIL |           | warp_clock |
+- * |   tv    |   tz    | set  | warped | set  | firsttime |   locked   |
+- * |---------|---------|---------------|------|-----------|------------|
+- * | pointer | NULL    |  yes |   no   |  no  |     1     |    no      |
+- * | pointer | pointer |  yes |   no   |  no  |     0     |    yes     |
+- * | NULL    | ptr2utc |  no  |   no   |  no  |     0     |    yes     |
+- * | NULL    | pointer |  no  |   yes  |  yes |     0     |    yes     |
+- * +-------------------------------------------------------------------+
++ * +-------------------------------------------------------------------------+
++ * |                           settimeofday(tv, tz)                          |
++ * |-------------------------------------------------------------------------|
++ * |     Arguments     |  System Time  | TZ  | PCIL |           | warp_clock |
++ * |   tv    |   tz    | set  | warped | set | set  | firsttime |   locked   |
++ * |---------|---------|---------------|-----|------|-----------|------------|
++ * | pointer | NULL    |  yes |   no   | no  |  no  |     1     |    no      |
++ * | NULL    | ptr2utc |  no  |   no   | yes |  no  |     0     |    yes     |
++ * | NULL    | pointer |  no  |   yes  | yes |  yes |     0     |    yes     |
++ * +-------------------------------------------------------------------------+
+  * ptr2utc: tz.tz_minuteswest is zero (UTC).
+  * PCIL: persistent_clock_is_local, sets the "11 minute mode" timescale.
+  * firsttime: locks the warp_clock function (initialized to 1 at boot).
++ * Since glibc v2.31 settimeofday() will fail if both args are non NULL
+  *
+  * +---------------------------------------------------------------------------+
+  * |  op     | RTC scale | settimeofday calls                                  |
+  * |---------|-----------|-----------------------------------------------------|
+  * | systz   |   Local   | 1) warps system time*, sets PCIL* and kernel tz     |
+  * | systz   |   UTC     | 1st) locks warp_clock* 2nd) sets kernel tz          |
+- * | hctosys |   Local   | 1st) sets PCIL* 2nd) sets system time and kernel tz |
+- * | hctosys |   UTC     | 1) sets system time and kernel tz                   |
++ * | hctosys |   Local   | 1st) sets PCIL* & kernel tz   2nd) sets system time |
++ * | hctosys |   UTC     | 1st) locks warp* 2nd) sets tz 3rd) sets system time |
+  * +---------------------------------------------------------------------------+
+  *                         * only on first call after boot
+  */
+@@ -675,42 +675,45 @@ set_system_clock(const struct hwclock_control *ctl,
+ 	struct tm broken;
+ 	int minuteswest;
+ 	int rc = 0;
+-	const struct timezone tz_utc = { 0 };
+ 
+ 	localtime_r(&newtime.tv_sec, &broken);
+ 	minuteswest = -get_gmtoff(&broken) / 60;
+ 
+ 	if (ctl->verbose) {
+-		if (ctl->hctosys && !ctl->universal)
+-			printf(_("Calling settimeofday(NULL, %d) to set "
+-				 "persistent_clock_is_local.\n"), minuteswest);
+-		if (ctl->systz && ctl->universal)
++		if (ctl->universal) {
+ 			puts(_("Calling settimeofday(NULL, 0) "
+-				"to lock the warp function."));
++			       "to lock the warp_clock function."));
++			if (!( ctl->universal && !minuteswest ))
++				printf(_("Calling settimeofday(NULL, %d) "
++					 "to set the kernel timezone.\n"),
++				       minuteswest);
++		} else
++			printf(_("Calling settimeofday(NULL, %d) to warp "
++				 "System time, set PCIL and the kernel tz.\n"),
++			       minuteswest);
++
+ 		if (ctl->hctosys)
+-			printf(_("Calling settimeofday(%ld.%06ld, %d)\n"),
+-			       newtime.tv_sec, newtime.tv_usec, minuteswest);
+-		else {
+-			printf(_("Calling settimeofday(NULL, %d) "), minuteswest);
+-			if (ctl->universal)
+-				 puts(_("to set the kernel timezone."));
+-			else
+-				 puts(_("to warp System time."));
+-		}
++			printf(_("Calling settimeofday(%ld.%06ld, NULL) "
++				 "to set the System time.\n"),
++			       newtime.tv_sec, newtime.tv_usec);
+ 	}
+ 
+ 	if (!ctl->testing) {
++		const struct timezone tz_utc = { 0 };
+ 		const struct timezone tz = { minuteswest };
+ 
+-		if (ctl->hctosys && !ctl->universal)	/* set PCIL */
+-			rc = settimeofday(NULL, &tz);
+-		if (ctl->systz && ctl->universal)	/* lock warp_clock */
++		/* If UTC RTC: lock warp_clock and PCIL */
++		if (ctl->universal)
+ 			rc = settimeofday(NULL, &tz_utc);
+-		if (!rc && ctl->hctosys)
+-			rc = settimeofday(&newtime, &tz);
+-		else if (!rc)
++
++		/* Set kernel tz; if localtime RTC: warp_clock and set PCIL */
++		if (!rc && !( ctl->universal && !minuteswest ))
+ 			rc = settimeofday(NULL, &tz);
+ 
++		/* Set the System Clock */
++		if ((!rc || errno == ENOSYS) && ctl->hctosys)
++			rc = settimeofday(&newtime, NULL);
++
+ 		if (rc) {
+ 			warn(_("settimeofday() failed"));
+ 			return  EXIT_FAILURE;
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/util-linux.git/commitdiff/67a912cd50464cae095fbdb7b3cf90daf495fb90



More information about the pld-cvs-commit mailing list