]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3699] Problems handling drift file and restoring previous drifts <perlinger...
authorJuergen Perlinger <perlinger@ntp.org>
Sun, 29 Nov 2020 09:41:07 +0000 (10:41 +0100)
committerJuergen Perlinger <perlinger@ntp.org>
Sun, 29 Nov 2020 09:41:07 +0000 (10:41 +0100)
 - command line options override config statements where applicable
 - make initial frequency settings idempotent and reversible
 - make sure kernel PLL gets a revovered drift componsation

bk: 5fc36cb3F2W6QL8Of1bpmb77G6JTyA

include/ntp.h
ntpd/cmd_args.c
ntpd/ntp_config.c
ntpd/ntp_loopfilter.c
ntpd/ntp_util.c

index 8e0ea2b202a79435a633aa09ada02e4a72f5373c..c037f59860164f9fa4efafb6707c4d500b445aab 100644 (file)
@@ -759,6 +759,7 @@ struct pkt {
 #define LOOP_CODEC             13      /* set audio codec frequency */
 #define        LOOP_LEAP               14      /* insert leap after second 23:59 */
 #define        LOOP_TICK               15      /* sim. low precision clock */
+#define LOOP_NOFREQ            16      /* undo a previos LOOP_FREQ */
 
 /*
  * Configuration items for the stats printer
index adb4a606bb31929835f904a1f5880c9a95ed15e7..aa461cb4dbe6088c15fb60990b9c5af4f60544b7 100644 (file)
@@ -71,7 +71,7 @@ getCmdOpts(
        }
 
        if (HAVE_OPT( DRIFTFILE ))
-           stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ), 0);
+           stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ), 1);
 
        if (HAVE_OPT( PANICGATE ))
                allow_panic = TRUE;
@@ -90,7 +90,7 @@ getCmdOpts(
                getauthkeys(OPT_ARG( KEYFILE ));
 
        if (HAVE_OPT( PIDFILE ))
-           stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ), 0);
+           stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ), 1);
 
        if (HAVE_OPT( QUIT ))
                mode_ntpdate = TRUE;
@@ -110,7 +110,7 @@ getCmdOpts(
                } while (0);
 
        if (HAVE_OPT( STATSDIR ))
-           stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ), 0);
+           stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ), 1);
 
        if (HAVE_OPT( TRUSTEDKEY )) {
                int             ct = STACKCT_OPT(  TRUSTEDKEY );
index cdc391c1b95b05025a2b94aa3ae8618233e2dc13..f5ea35630c41abbeb5d27d6ceda26620baa49327 100644 (file)
@@ -3991,11 +3991,9 @@ config_vars(
                        break;
 
                case T_Driftfile:
-                       if ('\0' == curr_var->value.s[0]) {
-                               stats_drift_file = 0;
+                       if ('\0' == curr_var->value.s[0])
                                msyslog(LOG_INFO, "config: driftfile disabled");
-                       } else
-                           stats_config(STATS_FREQ_FILE, curr_var->value.s, 0);
+                       stats_config(STATS_FREQ_FILE, curr_var->value.s, 0);
                        break;
 
                case T_Dscp:
index b7a742bbd183e7dc633344fb29d6e145ebc6d75b..0499c363393df6648b24d8a6e5ad5228bea30666 100644 (file)
@@ -1117,6 +1117,11 @@ start_kern_loop(void)
         * unconditionally set to sys_poll, whereas elsewhere is is
         * modified depending on nanosecond vs. microsecond kernel?
         */
+       /*[bug 3699] make sure kernel PLL sees our initial drift compensation */
+       if (freq_set) {
+               ntv.modes |= MOD_FREQUENCY;
+               ntv.freq = DTOFREQ(drift_comp);
+       }
 #ifdef SIGSYS
        /*
         * Use sigsetjmp() to save state and then call ntp_adjtime(); if
@@ -1314,7 +1319,12 @@ loop_config(
 
        case LOOP_FREQ:         /* initial frequency (freq) */
                init_drift_comp = freq;
-               freq_set++;
+               freq_set = 1;
+               break;
+
+       case LOOP_NOFREQ:       /* remove any initial drift comp spec */
+               init_drift_comp = 0;
+               freq_set = 0;
                break;
 
        case LOOP_HUFFPUFF:     /* huff-n'-puff length (huffpuff) */
index 11ca620172cd132fe0189d490b6d7055e5a6ccec..8b5755406ef66413361ddc6ef1d5e0822a8b9616 100644 (file)
@@ -64,6 +64,15 @@ static       char *stats_temp_file;          /* temp frequency file name */
 static double wander_resid;            /* last frequency update */
 double wander_threshold = 1e-7;        /* initial frequency threshold */
 
+/* For things where command line has precedence, we have
+ * to remember we've already seen that. These options have to be
+ * applied only once...
+ */
+#define CMDARG_FREQ_FILE       0x01
+#define CMDARG_PID_FILE                0x02
+#define CMDARG_STATSDIR                0x04
+static unsigned int cmdargs_seen = 0;
+
 /*
  * Statistics file stuff
  */
@@ -397,24 +406,47 @@ stats_config(
         * Open and read frequency file.
         */
        case STATS_FREQ_FILE:
+               if (!optflag && (cmdargs_seen & CMDARG_FREQ_FILE))
+                       break;
+               if (optflag)
+                       cmdargs_seen |= CMDARG_FREQ_FILE;
+               
                if (!value || (len = strlen(value)) == 0)
+               {
+                       free(stats_drift_file);
+                       free(stats_temp_file);
+                       stats_drift_file = stats_temp_file = NULL;    
+               }
+               else
+               {
+                       stats_drift_file = erealloc(stats_drift_file, len + 1);
+                       stats_temp_file = erealloc(stats_temp_file,
+                                                  len + sizeof(".TEMP"));
+                       memcpy(stats_drift_file, value, (size_t)(len+1));
+                       memcpy(stats_temp_file, value, (size_t)len);
+                       memcpy(stats_temp_file + len, temp_ext, sizeof(temp_ext));
+               }
+               
+               if (NULL == stats_drift_file) {
+                       loop_config(LOOP_NOFREQ, 0.0);
+                       prev_drift_comp = 0.0;
                        break;
-
-               stats_drift_file = erealloc(stats_drift_file, len + 1);
-               stats_temp_file = erealloc(stats_temp_file,
-                   len + sizeof(".TEMP"));
-               memcpy(stats_drift_file, value, (size_t)(len+1));
-               memcpy(stats_temp_file, value, (size_t)len);
-               memcpy(stats_temp_file + len, temp_ext, sizeof(temp_ext));
+               }
 
                /*
                 * Open drift file and read frequency. If the file is
                 * missing or contains errors, tell the loop to reset.
                 */
-               if ((fp = fopen(stats_drift_file, "r")) == NULL)
-                       break;
+               if ((fp = fopen(stats_drift_file, "r")) == NULL) {
+                       if (errno != ENOENT)
+                               msyslog(LOG_WARNING,
+                                       "cannot read frequency file %s: %s",
+                                       stats_drift_file, strerror(errno));
+                       break;
+               }
 
                if (fscanf(fp, "%lf", &old_drift) != 1) {
+                       
                        msyslog(LOG_ERR,
                                "format error frequency file %s",
                                stats_drift_file);
@@ -425,12 +457,19 @@ stats_config(
                fclose(fp);
                loop_config(LOOP_FREQ, old_drift);
                prev_drift_comp = drift_comp;
+               msyslog(LOG_INFO,
+                       "initial drift restored to %f",
+                       old_drift);
                break;
 
        /*
         * Specify statistics directory.
         */
        case STATS_STATSDIR:
+               if (!optflag && (cmdargs_seen & CMDARG_STATSDIR))
+                       break;
+               if (optflag)
+                       cmdargs_seen |= CMDARG_STATSDIR;
 
                /* - 1 since value may be missing the DIR_SEP. */
                if (strlen(value) >= sizeof(statsdir) - 1) {
@@ -463,6 +502,11 @@ stats_config(
         * Open pid file.
         */
        case STATS_PID_FILE:
+               if (!optflag && (cmdargs_seen & CMDARG_PID_FILE))
+                       break;
+               if (optflag)
+                       cmdargs_seen |= CMDARG_PID_FILE;
+               
                if ((fp = fopen(value, "w")) == NULL) {
                        msyslog(LOG_ERR, "pid file %s: %m",
                            value);