Fix error with multiply 'adjkerntz -a' copies running.
Manage adjkerntz kernel variable even for UTC clocks. Code cleanup.
This commit is contained in:
parent
fe0d5f43c5
commit
9243a8f346
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15046
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 1993, 1994, 1995 by Andrey A. Chernov, Moscow, Russia.
|
* Copyright (C) 1993-1996 by Andrey A. Chernov, Moscow, Russia.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
char copyright[] =
|
char copyright[] =
|
||||||
"@(#)Copyright (C) 1993, 1994, 1995 by Andrey A. Chernov, Moscow, Russia.\n\
|
"@(#)Copyright (C) 1993-1996 by Andrey A. Chernov, Moscow, Russia.\n\
|
||||||
All rights reserved.\n";
|
All rights reserved.\n";
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -54,6 +54,11 @@ char copyright[] =
|
|||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
|
|
||||||
/*#define DEBUG*/
|
/*#define DEBUG*/
|
||||||
|
|
||||||
|
#define True (1)
|
||||||
|
#define False (0)
|
||||||
|
#define Unknown (-1)
|
||||||
|
|
||||||
#define REPORT_PERIOD (30*60)
|
#define REPORT_PERIOD (30*60)
|
||||||
|
|
||||||
void fake() {}
|
void fake() {}
|
||||||
@ -65,41 +70,44 @@ int main(argc, argv)
|
|||||||
struct tm local, utc;
|
struct tm local, utc;
|
||||||
struct timeval tv, *stv;
|
struct timeval tv, *stv;
|
||||||
struct timezone tz, *stz;
|
struct timezone tz, *stz;
|
||||||
int kern_offset;
|
int kern_offset, wall_clock, disrtcset;
|
||||||
size_t len;
|
size_t len;
|
||||||
int mib[2];
|
int mib[2];
|
||||||
/* Avoid time_t here, can be unsigned long or worse */
|
/* Avoid time_t here, can be unsigned long or worse */
|
||||||
long offset, utcsec, localsec, diff;
|
long offset, utcsec, localsec, diff;
|
||||||
time_t initial_sec, final_sec;
|
time_t initial_sec, final_sec;
|
||||||
int ch, init = -1;
|
int ch;
|
||||||
int initial_isdst = -1, final_isdst, looping;
|
int initial_isdst = -1, final_isdst;
|
||||||
int disrtcset, need_restore = 0;
|
int need_restore = False, sleep_mode = False, looping,
|
||||||
|
init = Unknown;
|
||||||
sigset_t mask, emask;
|
sigset_t mask, emask;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "ai")) != EOF)
|
while ((ch = getopt(argc, argv, "ais")) != EOF)
|
||||||
switch((char)ch) {
|
switch((char)ch) {
|
||||||
case 'i': /* initial call, save offset */
|
case 'i': /* initial call, save offset */
|
||||||
if (init != -1)
|
if (init != Unknown)
|
||||||
goto usage;
|
goto usage;
|
||||||
init = 1;
|
init = True;
|
||||||
break;
|
break;
|
||||||
case 'a': /* adjustment call, use saved offset */
|
case 'a': /* adjustment call, use saved offset */
|
||||||
if (init != -1)
|
if (init != Unknown)
|
||||||
goto usage;
|
goto usage;
|
||||||
init = 0;
|
init = False;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sleep_mode = True;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage:
|
usage:
|
||||||
fprintf(stderr, "Usage:\n\
|
fprintf(stderr, "Usage:\n\
|
||||||
\tadjkerntz -i\t(initial call from /etc/rc)\n\
|
\tadjkerntz -i\t\t(initial call from /etc/rc)\n\
|
||||||
\tadjkerntz -a\t(adjustment call from crontab)\n");
|
\tadjkerntz -a [-s]\t(adjustment call, -s for sleep/retry mode)\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (init == -1)
|
if (init == Unknown)
|
||||||
goto usage;
|
goto usage;
|
||||||
|
if (init)
|
||||||
if (access(_PATH_CLOCK, F_OK))
|
sleep_mode = True;
|
||||||
return 0;
|
|
||||||
|
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
sigemptyset(&emask);
|
sigemptyset(&emask);
|
||||||
@ -114,15 +122,26 @@ int main(argc, argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
if (init)
|
||||||
|
wall_clock = (access(_PATH_CLOCK, F_OK) == 0);
|
||||||
|
else {
|
||||||
|
mib[0] = CTL_MACHDEP;
|
||||||
|
mib[1] = CPU_WALLCLOCK;
|
||||||
|
len = sizeof(wall_clock);
|
||||||
|
if (sysctl(mib, 2, &wall_clock, &len, NULL, 0) == -1) {
|
||||||
|
syslog(LOG_ERR, "sysctl(get_wallclock): %m");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
(void) sigprocmask(SIG_BLOCK, &mask, NULL);
|
(void) sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||||
(void) signal(SIGTERM, fake);
|
(void) signal(SIGTERM, fake);
|
||||||
|
|
||||||
diff = 0;
|
diff = 0;
|
||||||
stv = NULL;
|
stv = NULL;
|
||||||
stz = NULL;
|
stz = NULL;
|
||||||
looping = 0;
|
looping = False;
|
||||||
|
|
||||||
mib[0] = CTL_MACHDEP;
|
mib[0] = CTL_MACHDEP;
|
||||||
mib[1] = CPU_ADJKERNTZ;
|
mib[1] = CPU_ADJKERNTZ;
|
||||||
@ -161,7 +180,15 @@ int main(argc, argv)
|
|||||||
* middle of the nonexistent hour means 3:30 am.
|
* middle of the nonexistent hour means 3:30 am.
|
||||||
*/
|
*/
|
||||||
syslog(LOG_WARNING,
|
syslog(LOG_WARNING,
|
||||||
"Nonexistent local time -- will retry after %d secs", REPORT_PERIOD);
|
"Warning: nonexistent %s time.",
|
||||||
|
utcsec == -1 && localsec == -1 ? "UTC time and local" :
|
||||||
|
utcsec == -1 ? "UTC" : "local");
|
||||||
|
if (!sleep_mode) {
|
||||||
|
syslog(LOG_WARNING, "Giving up.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
syslog(LOG_WARNING, "Will retry after %d minutes.",
|
||||||
|
REPORT_PERIOD / 60);
|
||||||
(void) signal(SIGTERM, SIG_DFL);
|
(void) signal(SIGTERM, SIG_DFL);
|
||||||
(void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
(void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||||
(void) sleep(REPORT_PERIOD);
|
(void) sleep(REPORT_PERIOD);
|
||||||
@ -191,7 +218,7 @@ int main(argc, argv)
|
|||||||
if (diff > 0 && initial_isdst != final_isdst) {
|
if (diff > 0 && initial_isdst != final_isdst) {
|
||||||
if (looping)
|
if (looping)
|
||||||
goto bad_final;
|
goto bad_final;
|
||||||
looping++;
|
looping = True;
|
||||||
initial_isdst = final_isdst;
|
initial_isdst = final_isdst;
|
||||||
goto recalculate;
|
goto recalculate;
|
||||||
}
|
}
|
||||||
@ -207,7 +234,15 @@ int main(argc, argv)
|
|||||||
* but perhaps we never get here.
|
* but perhaps we never get here.
|
||||||
*/
|
*/
|
||||||
syslog(LOG_WARNING,
|
syslog(LOG_WARNING,
|
||||||
"Nonexistent (final) local time -- will retry after %d secs", REPORT_PERIOD);
|
"Warning: nonexistent final %s time.",
|
||||||
|
utcsec == -1 && localsec == -1 ? "UTC time and local" :
|
||||||
|
utcsec == -1 ? "UTC" : "local");
|
||||||
|
if (!sleep_mode) {
|
||||||
|
syslog(LOG_WARNING, "Giving up.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
syslog(LOG_WARNING, "Will retry after %d minutes.",
|
||||||
|
REPORT_PERIOD / 60);
|
||||||
(void) signal(SIGTERM, SIG_DFL);
|
(void) signal(SIGTERM, SIG_DFL);
|
||||||
(void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
(void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||||
(void) sleep(REPORT_PERIOD);
|
(void) sleep(REPORT_PERIOD);
|
||||||
@ -237,9 +272,15 @@ int main(argc, argv)
|
|||||||
tz.tz_dsttime = tz.tz_minuteswest = 0; /* zone info is garbage */
|
tz.tz_dsttime = tz.tz_minuteswest = 0; /* zone info is garbage */
|
||||||
stz = &tz;
|
stz = &tz;
|
||||||
}
|
}
|
||||||
|
if (!wall_clock && stz == NULL)
|
||||||
|
stv = NULL;
|
||||||
|
|
||||||
/* if init and something will be changed, don't touch RTC at all */
|
/* if init or UTC clock and offset/date will be changed, */
|
||||||
if (init && (stv != NULL || kern_offset != offset)) {
|
/* disable RTC modification for a while. */
|
||||||
|
|
||||||
|
if ( (init && stv != NULL)
|
||||||
|
|| ((init || !wall_clock) && kern_offset != offset)
|
||||||
|
) {
|
||||||
mib[0] = CTL_MACHDEP;
|
mib[0] = CTL_MACHDEP;
|
||||||
mib[1] = CPU_DISRTCSET;
|
mib[1] = CPU_DISRTCSET;
|
||||||
len = sizeof(disrtcset);
|
len = sizeof(disrtcset);
|
||||||
@ -249,7 +290,7 @@ int main(argc, argv)
|
|||||||
}
|
}
|
||||||
if (disrtcset == 0) {
|
if (disrtcset == 0) {
|
||||||
disrtcset = 1;
|
disrtcset = 1;
|
||||||
need_restore = 1;
|
need_restore = True;
|
||||||
if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) {
|
if (sysctl(mib, 2, NULL, NULL, &disrtcset, len) == -1) {
|
||||||
syslog(LOG_ERR, "sysctl(set_disrtcset): %m");
|
syslog(LOG_ERR, "sysctl(set_disrtcset): %m");
|
||||||
return 1;
|
return 1;
|
||||||
@ -257,16 +298,19 @@ int main(argc, argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (( (init && (stv != NULL || stz != NULL))
|
if ( ( (init && (stv != NULL || stz != NULL))
|
||||||
|| (stz != NULL && stv == NULL)
|
|| (stz != NULL && stv == NULL)
|
||||||
)
|
)
|
||||||
&& settimeofday(stv, stz)
|
&& settimeofday(stv, stz)
|
||||||
) {
|
) {
|
||||||
syslog(LOG_ERR, "settimeofday: %m");
|
syslog(LOG_ERR, "settimeofday: %m");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init: don't write RTC, !init: write RTC */
|
/* setting CPU_ADJKERNTZ have a side effect: resettodr(), which */
|
||||||
|
/* can be disabled by CPU_DISRTCSET, so if init or UTC clock */
|
||||||
|
/* -- don't write RTC, else write RTC. */
|
||||||
|
|
||||||
if (kern_offset != offset) {
|
if (kern_offset != offset) {
|
||||||
kern_offset = offset;
|
kern_offset = offset;
|
||||||
mib[0] = CTL_MACHDEP;
|
mib[0] = CTL_MACHDEP;
|
||||||
@ -278,8 +322,18 @@ int main(argc, argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
mib[0] = CTL_MACHDEP;
|
||||||
|
mib[1] = CPU_WALLCLOCK;
|
||||||
|
len = sizeof(wall_clock);
|
||||||
|
if (sysctl(mib, 2, NULL, NULL, &wall_clock, len) == -1) {
|
||||||
|
syslog(LOG_ERR, "sysctl(put_wallclock): %m");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (need_restore) {
|
if (need_restore) {
|
||||||
need_restore = 0;
|
need_restore = False;
|
||||||
mib[0] = CTL_MACHDEP;
|
mib[0] = CTL_MACHDEP;
|
||||||
mib[1] = CPU_DISRTCSET;
|
mib[1] = CPU_DISRTCSET;
|
||||||
disrtcset = 0;
|
disrtcset = 0;
|
||||||
@ -292,8 +346,8 @@ int main(argc, argv)
|
|||||||
|
|
||||||
/****** End of critical section ******/
|
/****** End of critical section ******/
|
||||||
|
|
||||||
if (init) {
|
if (init && wall_clock) {
|
||||||
init = 0;
|
init = False;
|
||||||
/* wait for signals and acts like -a */
|
/* wait for signals and acts like -a */
|
||||||
(void) sigsuspend(&emask);
|
(void) sigsuspend(&emask);
|
||||||
goto again;
|
goto again;
|
||||||
|
Loading…
Reference in New Issue
Block a user