summaryrefslogtreecommitdiffstats
path: root/sbin/adjkerntz
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1994-11-03 03:16:16 +0000
committerache <ache@FreeBSD.org>1994-11-03 03:16:16 +0000
commita3d03a23fcad822c3d64b7ea33797a5c80d8f19f (patch)
treeee3b33c6a00092caa7f33fccfd1eaebe47f1c82b /sbin/adjkerntz
parent807094f81b96ca85a49aafd4bfd9f992510c6c8c (diff)
downloadFreeBSD-src-a3d03a23fcad822c3d64b7ea33797a5c80d8f19f.zip
FreeBSD-src-a3d03a23fcad822c3d64b7ea33797a5c80d8f19f.tar.gz
-i case goes to background pause and acts like -a case on receiving
SIGTERM. This helps to keep CMOS clock updated before reboot. Idea from J.Wunsch.
Diffstat (limited to 'sbin/adjkerntz')
-rw-r--r--sbin/adjkerntz/adjkerntz.815
-rw-r--r--sbin/adjkerntz/adjkerntz.c29
2 files changed, 40 insertions, 4 deletions
diff --git a/sbin/adjkerntz/adjkerntz.8 b/sbin/adjkerntz/adjkerntz.8
index 086f12a..9cb5c8d 100644
--- a/sbin/adjkerntz/adjkerntz.8
+++ b/sbin/adjkerntz/adjkerntz.8
@@ -53,18 +53,24 @@ initialization call from
.Pa /etc/rc
(before any daemons are started).
.Nm Adjkerntz
-makes the first adjustment and the initial time zone offset is stored into
+makes the adjustment of kernel clock (CMOS clock not touched)
+and the initial time zone offset is stored into
.Pa adjkerntz
kernel variable
for following subsequent
-.Nm adjkerntz
-calls.
+.Nm "'adjkerntz -a'"
+calls. Then it goes to background pause which ends with SIGTERM.
+After receiving SIGTERM it acts like
+.Nm "'adjkerntz -a'"
+to be shure to have proper CMOS clock before reboot.
.It Cm Fl a
This form is needed, when time zone changes occur.
.Nm Adjkerntz
uses the previously stored
time zone offset and the changed time zone rule to
-produce the new time zone offset, fix the RTC clock and store the new
+produce the new time zone offset, fix the CMOS clock
+(kernel clock not touched)
+and store the new
offset into
.Pa adjkerntz
kernel variable
@@ -73,6 +79,7 @@ It is recommended to use this form in root's
.Xr crontab 5
every half of a hour from 0am to 4am
since this times matches most modern time zone changes.
+.El
.Pp
.Nm Adjkerntz
clears the kernel timezone structure and makes kernel always run at UTC
diff --git a/sbin/adjkerntz/adjkerntz.c b/sbin/adjkerntz/adjkerntz.c
index 5e7b0b8..444a9df 100644
--- a/sbin/adjkerntz/adjkerntz.c
+++ b/sbin/adjkerntz/adjkerntz.c
@@ -41,6 +41,7 @@ char copyright[] =
*
*/
#include <stdio.h>
+#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
@@ -54,6 +55,8 @@ char copyright[] =
#define REPORT_PERIOD (30*60)
+void fake() {}
+
int main(argc, argv)
int argc;
char **argv;
@@ -69,6 +72,7 @@ int main(argc, argv)
time_t initial_sec, final_sec;
int ch, init = -1;
int disrtcset, need_restore = 0;
+ sigset_t mask, emask;
while ((ch = getopt(argc, argv, "ai")) != EOF)
switch((char)ch) {
@@ -95,10 +99,24 @@ int main(argc, argv)
if (access(_PATH_CLOCK, F_OK))
return 0;
+ sigemptyset(&mask);
+ sigemptyset(&emask);
+ sigaddset(&mask, SIGTERM);
+
openlog("adjkerntz", LOG_PID|LOG_PERROR, LOG_DAEMON);
+ (void) signal(SIGHUP, SIG_IGN);
+
+ if (init && daemon(0, 1)) {
+ syslog(LOG_ERR, "daemon: %m");
+ return 1;
+ }
+
again:
+ (void) sigprocmask(SIG_BLOCK, &mask, NULL);
+ (void) signal(SIGTERM, fake);
+
/****** Critical section, do all things as fast as possible ******/
/* get local CMOS clock and possible kernel offset */
@@ -126,6 +144,8 @@ again:
*/
syslog(LOG_WARNING,
"Nonexistent local time -- will retry after %d secs", REPORT_PERIOD);
+ (void) signal(SIGTERM, SIG_DFL);
+ (void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
(void) sleep(REPORT_PERIOD);
goto again;
}
@@ -165,6 +185,8 @@ again:
*/
syslog(LOG_WARNING,
"Nonexistent (final) local time -- will retry after %d secs", REPORT_PERIOD);
+ (void) signal(SIGTERM, SIG_DFL);
+ (void) sigprocmask(SIG_UNBLOCK, &mask, NULL);
(void) sleep(REPORT_PERIOD);
goto again;
}
@@ -241,5 +263,12 @@ again:
/****** End of critical section ******/
+ if (init) {
+ init = 0;
+ /* wait for signals and acts like -a */
+ (void) sigsuspend(&emask);
+ goto again;
+ }
+
return 0;
}
OpenPOWER on IntegriCloud