util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: J William Piggott <elseifthen@gmx.com>
To: Karel Zak <kzak@redhat.com>
Cc: util-linux@vger.kernel.org
Subject: [v2 PATCH] hwclock: make glibc 2.31 compatible
Date: Fri, 21 Feb 2020 20:03:47 -0500	[thread overview]
Message-ID: <20200222010347.2743-1-elseifthen@gmx.com> (raw)

______________________________________________________
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-authored-by: Karel Zak <kzak@redhat.com>
Signed-off-by: J William Piggott <elseifthen@gmx.com>
---

Changes from v1:
 Only make one settimeofday(2) call when: rtc_is_utc and tz_is_utc

Karel, your patch implemented the the above mentioned v1 change, so
I put that back. With the glibc change there is no way to avoid a double
call when: rtc_is_utc and tz_is_!zero. See the two tables below. These
compare just the time zone and warp_clock calls, not the clock setting.


Comparison of calls for [v1 PATCH]:
_____________________________________________________
 Number of settimeofday(2) calls to set timezone/warp

           RTC      RTC
Sys TZ  |  UTC  | Localtime |
---------------------------------------------
UTC0    |   1   |    2
--------|-------|------- Karel's   More code  7 calls
EST5    |   2   |    2
--------|-------|----------------------------
UTC0    |   2   |    1     v1
--------|-------|------- Willie's  Less code  6 calls
EST5    |   2   |    1
---------------------------------------------


Comparison of calls for [v2 PATCH]:
_____________________________________________________

 Number of settimeofday(2) calls to set timezone/warp

           RTC      RTC
Sys TZ  |  UTC  | Localtime |
---------------------------------------------
UTC0    |   1   |    2
--------|-------|------- Karel's   More code  7 calls
EST5    |   2   |    2
--------|-------|----------------------------
UTC0    |   1   |    1     v2
--------|-------|------- Willie's  Less code  5 calls
EST5    |   2   |    1
---------------------------------------------

Status: builds, but mostly untested.

 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;

             reply	other threads:[~2020-02-22  1:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-22  1:03 J William Piggott [this message]
2020-02-24 15:48 ` [v2 PATCH] hwclock: make glibc 2.31 compatible Karel Zak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200222010347.2743-1-elseifthen@gmx.com \
    --to=elseifthen@gmx.com \
    --cc=kzak@redhat.com \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).