git: ddedf2a11eb2 - main - tzcode: Implement timezone change detection

Cy Schubert Cy.Schubert at cschubert.com
Tue Sep 14 15:36:21 UTC 2021


In message <202109131442.18DEgDIn043709 at gitrepo.freebsd.org>, Edward Tomasz 
Nap
ierala writes:
> The branch main has been updated by trasz:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=ddedf2a11eb20af1ee52cb3da70a57c2
> 1904af8f
>
> commit ddedf2a11eb20af1ee52cb3da70a57c21904af8f
> Author:     Edward Tomasz Napierala <trasz at FreeBSD.org>
> AuthorDate: 2021-09-12 03:07:26 +0000
> Commit:     Edward Tomasz Napierala <trasz at FreeBSD.org>
> CommitDate: 2021-09-12 03:07:58 +0000
>
>     tzcode: Implement timezone change detection
>     
>     Implement optional timezone change detection for local time libc
>     functions.  This is disabled by default; set WITH_DETECT_TZ_CHANGES
>     to build it.
>     
>     Reviewed By:    imp
>     Sponsored by:   NetApp, Inc.
>     Sponsored by:   Klara, Inc.
>     X-NetApp-PR:    #47
>     Differential Revision:  https://reviews.freebsd.org/D30183
> ---
>  contrib/tzcode/stdtime/localtime.c         | 89 ++++++++++++++++++++++++++++
> +-
>  lib/libc/stdtime/Makefile.inc              |  4 ++
>  share/mk/src.opts.mk                       |  1 +
>  tools/build/options/WITH_DETECT_TZ_CHANGES |  2 +
>  4 files changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/contrib/tzcode/stdtime/localtime.c b/contrib/tzcode/stdtime/loca
> ltime.c
> index e221c1fa3964..926b24470e19 100644
> --- a/contrib/tzcode/stdtime/localtime.c
> +++ b/contrib/tzcode/stdtime/localtime.c
> @@ -354,6 +354,45 @@ settzname(void)
>  	}
>  }
>  
> +#ifdef DETECT_TZ_CHANGES
> +/*
> + * Determine if there's a change in the timezone since the last time we chec
> ked.
> + * Returns: -1 on error
> + * 	     0 if the timezone has not changed
> + *	     1 if the timezone has changed
> + */
> +static int
> +change_in_tz(const char *name)
> +{
> +	static char old_name[PATH_MAX];
> +	static struct stat old_sb;
> +	struct stat sb;
> +	int error;
> +
> +	error = stat(name, &sb);
> +	if (error != 0)
> +		return -1;
> +
> +	if (strcmp(name, old_name) != 0) {
> +		strlcpy(old_name, name, sizeof(old_name));
> +		old_sb = sb;
> +		return 1;
> +	}
> +
> +	if (sb.st_dev != old_sb.st_dev ||
> +	    sb.st_ino != old_sb.st_ino ||
> +	    sb.st_ctime != old_sb.st_ctime ||
> +	    sb.st_mtime != old_sb.st_mtime) {
> +		old_sb = sb;
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +#else /* !DETECT_TZ_CHANGES */
> +#define	change_in_tz(X)	0
> +#endif /* !DETECT_TZ_CHANGES */
> +
>  static int
>  differ_by_repeat(const time_t t1, const time_t t0)
>  {
> @@ -379,6 +418,7 @@ register const int	doextend;
>  	int		stored;
>  	int		nread;
>  	int		res;
> +	int		ret;
>  	union {
>  		struct tzhead	tzhead;
>  		char		buf[2 * sizeof(struct tzhead) +
> @@ -427,6 +467,22 @@ register const int	doextend;
>  			(void) strcat(fullname, name);
>  			name = fullname;
>  		}
> +		if (doextend == TRUE) {
> +			/*
> +			 * Detect if the timezone file has changed.  Check
> +			 * 'doextend' to ignore TZDEFRULES; the change_in_tz()
> +			 * function can only keep state for a single file.
> +			 */
> +			ret = change_in_tz(name);
> +			if (ret <= 0) {
> +				/*
> +				 * Returns -1 if there was an error,
> +				 * and 0 if the timezone had not changed.
> +				 */
> +				free(fullname);
> +				return ret;
> +			}
> +		}
>  		if ((fid = _open(name, OPEN_MODE)) == -1) {
>  			free(fullname);
>  			return -1;
> @@ -1209,12 +1265,43 @@ gmtload(struct state *const sp)
>  		(void) tzparse(gmt, sp, TRUE);
>  }
>  
> +#ifdef DETECT_TZ_CHANGES
> +static int
> +recheck_tzdata()
> +{
> +	static time_t last_checked;
> +	struct timespec now;
> +	time_t current_time;
> +	int error;
> +
> +	/*
> +	 * We want to recheck the timezone file every 61 sec.
> +	 */
> +	error = clock_gettime(CLOCK_MONOTONIC, &now);
> +	if (error <= 0) {
> +		/* XXX: Can we somehow report this? */
> +		return 0;
> +	}
> +
> +	current_time = now.tv_sec;
> +	if ((current_time - last_checked > 61) ||
> +	    (last_checked > current_time)) {
> +		last_checked = current_time;
> +		return 1;
> +	}
> +
> +	return 0;
> +}
> +#else /* !DETECT_TZ_CHANGES */
> +#define	recheck_tzdata()	0
> +#endif /* !DETECT_TZ_CHANGES */
> +
>  static void
>  tzsetwall_basic(int rdlocked)
>  {
>  	if (!rdlocked)
>  		_RWLOCK_RDLOCK(&lcl_rwlock);
> -	if (lcl_is_set < 0) {
> +	if (lcl_is_set < 0 && recheck_tzdata() == 0) {
>  		if (!rdlocked)
>  			_RWLOCK_UNLOCK(&lcl_rwlock);
>  		return;
> diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
> index fb0d2b934148..3d483469bc97 100644
> --- a/lib/libc/stdtime/Makefile.inc
> +++ b/lib/libc/stdtime/Makefile.inc
> @@ -12,6 +12,10 @@ CFLAGS+= -I${SRCTOP}/contrib/tzcode/stdtime -I${LIBC_SRCTO
> P}/stdtime
>  
>  CFLAGS.localtime.c= -fwrapv
>  
> +.if ${MK_DETECT_TZ_CHANGES} != "no"
> +CFLAGS+= -DDETECT_TZ_CHANGES
> +.endif
> +
>  MAN+=	ctime.3 strftime.3 strptime.3 time2posix.3
>  MAN+=	tzfile.5
>  
> diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
> index 28e18260affd..ff894d3b3517 100644
> --- a/share/mk/src.opts.mk
> +++ b/share/mk/src.opts.mk
> @@ -196,6 +196,7 @@ __DEFAULT_NO_OPTIONS = \
>      BHYVE_SNAPSHOT \
>      CLANG_EXTRAS \
>      CLANG_FORMAT \
> +    DETECT_TZ_CHANGES \
>      DTRACE_TESTS \
>      EXPERIMENTAL \
>      HESIOD \
> diff --git a/tools/build/options/WITH_DETECT_TZ_CHANGES b/tools/build/options
> /WITH_DETECT_TZ_CHANGES
> new file mode 100644
> index 000000000000..6a2d18473892
> --- /dev/null
> +++ b/tools/build/options/WITH_DETECT_TZ_CHANGES
> @@ -0,0 +1,2 @@
> +.\" $FreeBSD$
> +Make the time handling code detect changes to the timezone files.
>

Hi,

This patch caused all of the machines on my network to display UTC. After 
reboot everything was ok. However moments ago my screen locked while typing 
on my laptop. The time is now UTC instead of PDT. TZ is still set to 
America/Vancouver. Changing the TZ makes no difference.


-- 
Cheers,
Cy Schubert <Cy.Schubert at cschubert.com>
FreeBSD UNIX:  <cy at FreeBSD.org>   Web:  https://FreeBSD.org
NTP:           <cy at nwtime.org>    Web:  https://nwtime.org

	The need of the many outweighs the greed of the few.




More information about the dev-commits-src-main mailing list