]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: delay initial transmission until first resolving ends
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 29 Apr 2014 09:16:16 +0000 (11:16 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 29 Apr 2014 10:42:45 +0000 (12:42 +0200)
This will be needed to prevent loading of dump files after sources have
already accumulated samples and possibly reference was already updated
when async resolving of sources is implemented.

main.c
ntp_core.c
ntp_core.h
ntp_sources.c
ntp_sources.h

diff --git a/main.c b/main.c
index afdec05b8b43c60adcb6de49261cb9c8a32d1fdb..4de366972afa93e45fbeb5a42b94ff0269d9917a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -147,6 +147,8 @@ post_init_ntp_hook(void *anything)
 
   RTC_StartMeasurements();
   RCL_StartRefclocks();
+  NSR_StartSources();
+  NSR_AutoStartSources();
 
   /* Special modes can end only when sources update their reachability.
      Give up immediatelly if there are no active sources. */
@@ -184,6 +186,7 @@ post_init_rtc_hook(void *anything)
 {
   if (CNF_GetInitSources() > 0) {
     CNF_AddInitSources();
+    NSR_StartSources();
     assert(REF_GetMode() != REF_ModeNormal);
     /* Wait for mode end notification */
   } else {
index 4cb176f92d80e32671cdd153b680c68e82bef007..afc0fc4e80ccd037bcc0804c98b376b52fedd31b 100644 (file)
@@ -73,6 +73,7 @@ struct NCR_Instance_Record {
                                    pending to transmit to the source */
   SCH_TimeoutID timeout_id;     /* Scheduler's timeout ID, if we are
                                    running on a timer. */
+  int tx_suspended;             /* Boolean indicating we can't transmit yet */
 
   int auto_offline;             /* If 1, automatically go offline if server/peer
                                    isn't responding */
@@ -218,6 +219,8 @@ struct NCR_Instance_Record {
 /* Maximum poll interval set by KoD RATE */
 #define MAX_KOD_RATE_POLL SRC_DEFAULT_MAXPOLL
 
+#define INVALID_SOCK_FD -1
+
 /* ================================================== */
 
 static ADF_AuthTable access_auth_table;
@@ -253,20 +256,36 @@ NCR_Finalise(void)
 static void
 start_initial_timeout(NCR_Instance inst)
 {
+  /* Check if we can transmit */
+  if (inst->tx_suspended) {
+    assert(!inst->timer_running);
+    return;
+  }
+
+  /* Stop old timer if running */
+  if (inst->timer_running)
+    SCH_RemoveTimeout(inst->timeout_id);
 
-  /* Start timer for first transmission */
+  /* Start new timer for transmission */
   inst->timeout_id = SCH_AddTimeoutInClass(INITIAL_DELAY, SAMPLING_SEPARATION,
                                            SAMPLING_RANDOMNESS,
                                            SCH_NtpSamplingClass,
                                            transmit_timeout, (void *)inst);
-  inst->timer_running = 1;
 
-  /* Mark source active */
-  SRC_SetActive(inst->source);
+  if (!inst->timer_running) {
+    /* This will be the first transmission after mode change */
+
+    inst->timer_running = 1;
+
+    /* Mark source active */
+    SRC_SetActive(inst->source);
 
-  /* Open client socket */
-  if (inst->mode == MODE_CLIENT)
-    inst->local_addr.sock_fd = NIO_GetClientSocket(&inst->remote_addr);
+    /* Open client socket */
+    if (inst->mode == MODE_CLIENT) {
+      assert(inst->local_addr.sock_fd == INVALID_SOCK_FD);
+      inst->local_addr.sock_fd = NIO_GetClientSocket(&inst->remote_addr);
+    }
+  }
 }
 
 /* ================================================== */
@@ -287,8 +306,10 @@ take_offline(NCR_Instance inst)
   SRC_UnsetActive(inst->source);
 
   /* Close client socket */
-  if (inst->mode == MODE_CLIENT)
+  if (inst->mode == MODE_CLIENT && inst->local_addr.sock_fd != INVALID_SOCK_FD) {
     NIO_CloseClientSocket(inst->local_addr.sock_fd);
+    inst->local_addr.sock_fd = INVALID_SOCK_FD;
+  }
 }
 
 /* ================================================== */
@@ -306,6 +327,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
   switch (type) {
     case NTP_SERVER:
       /* Client socket will be obtained when timer is started */
+      result->local_addr.sock_fd = INVALID_SOCK_FD;
       result->mode = MODE_CLIENT;
       break;
     case NTP_PEER:
@@ -356,14 +378,10 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
   /* Create a source instance for this NTP source */
   result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, params->sel_option, &result->remote_addr.ip_addr);
 
-  if (params->online) {
-    start_initial_timeout(result);
-    result->opmode = MD_ONLINE;
-  } else {
-    result->timer_running = 0;
-    result->timeout_id = 0;
-    result->opmode = MD_OFFLINE;
-  }
+  result->timer_running = 0;
+  result->timeout_id = 0;
+  result->tx_suspended = 1;
+  result->opmode = params->online ? MD_ONLINE : MD_OFFLINE;
   
   if (params->iburst) {
     NCR_InitiateSampleBurst(result, IBURST_GOOD_SAMPLES, IBURST_TOTAL_SAMPLES);
@@ -406,6 +424,16 @@ NCR_DestroyInstance(NCR_Instance instance)
 
 /* ================================================== */
 
+void
+NCR_StartInstance(NCR_Instance instance)
+{
+  instance->tx_suspended = 0;
+  if (instance->opmode != MD_OFFLINE)
+    start_initial_timeout(instance);
+}
+
+/* ================================================== */
+
 static int
 check_packet_auth(NTP_Packet *pkt, unsigned long keyid, int auth_len)
 {
@@ -1309,7 +1337,7 @@ NCR_ProcessKnown
   }
 
   /* Ignore packets from offline sources */
-  if (inst->opmode == MD_OFFLINE) {
+  if (inst->opmode == MD_OFFLINE || inst->tx_suspended) {
     return;
   }
 
@@ -1570,15 +1598,12 @@ NCR_TakeSourceOnline(NCR_Instance inst)
       /* Nothing to do */
       break;
     case MD_OFFLINE:
-      if (!inst->timer_running) {
-        /* We are not already actively polling it */
-        LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToString(&inst->remote_addr.ip_addr));
-        inst->tx_count = 0;
-        inst->local_poll = inst->minpoll;
-        inst->poll_score = 0.5;
-        inst->opmode = MD_ONLINE;
-        start_initial_timeout(inst);
-      }
+      LOG(LOGS_INFO, LOGF_NtpCore, "Source %s online", UTI_IPToString(&inst->remote_addr.ip_addr));
+      inst->tx_count = 0;
+      inst->local_poll = inst->minpoll;
+      inst->poll_score = 0.5;
+      inst->opmode = MD_ONLINE;
+      start_initial_timeout(inst);
       break;
     case MD_BURST_WAS_ONLINE:
       /* Will revert */
@@ -1597,10 +1622,8 @@ NCR_TakeSourceOffline(NCR_Instance inst)
 {
   switch (inst->opmode) {
     case MD_ONLINE:
-      if (inst->timer_running) {
-        LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToString(&inst->remote_addr.ip_addr));
-        take_offline(inst);
-      }
+      LOG(LOGS_INFO, LOGF_NtpCore, "Source %s offline", UTI_IPToString(&inst->remote_addr.ip_addr));
+      take_offline(inst);
       break;
     case MD_OFFLINE:
       break;
@@ -1711,18 +1734,9 @@ NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_sampl
         break;
 
       case MD_ONLINE:
-        inst->opmode = MD_BURST_WAS_ONLINE;
-        inst->burst_good_samples_to_go = n_good_samples;
-        inst->burst_total_samples_to_go = n_total_samples;
-        assert(inst->timer_running);
-        SCH_RemoveTimeout(inst->timeout_id);
-        inst->timeout_id = SCH_AddTimeoutInClass(INITIAL_DELAY, SAMPLING_SEPARATION,
-                                                 SAMPLING_RANDOMNESS,
-                                                 SCH_NtpSamplingClass,
-                                                 transmit_timeout, (void *) inst);
-        break;
       case MD_OFFLINE:
-        inst->opmode = MD_BURST_WAS_OFFLINE;
+        inst->opmode = inst->opmode == MD_ONLINE ?
+          MD_BURST_WAS_ONLINE : MD_BURST_WAS_OFFLINE;
         inst->burst_good_samples_to_go = n_good_samples;
         inst->burst_total_samples_to_go = n_total_samples;
         start_initial_timeout(inst);
index 5af536f859e907d8e49e93dbe0761cba2f88072e..c6c46f8e2c0694ff559e758234cedd6f15e3b7e2 100644 (file)
@@ -52,6 +52,9 @@ extern NCR_Instance NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_
 /* Destroy an instance */
 extern void NCR_DestroyInstance(NCR_Instance instance);
 
+/* Start an instance */
+extern void NCR_StartInstance(NCR_Instance instance);
+
 /* This routine is called when a new packet arrives off the network,
    and it relates to a source we have an ongoing protocol exchange with */
 extern void NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance data, int sock_fd, int length);
index 735ee0ab0844b2c2aa1269e1c5e361ee1a39f733..7836bfa53a2d9218e9874159d3ae94df07059520 100644 (file)
@@ -62,6 +62,9 @@ static int n_sources;
 /* The largest number of sources we want to have stored in the hash table */
 #define MAX_SOURCES 64
 
+/* Flag indicating new sources will be started automatically when added */
+static int auto_start_sources = 0;
+
 /* Source with unknown address (which may be resolved later) */
 struct UnresolvedSource {
   char *name;
@@ -206,6 +209,8 @@ NSR_AddSource(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourceParam
       n_sources++;
       records[slot].data = NCR_GetInstance(remote_addr, type, params); /* Will need params passing through */
       records[slot].remote_addr = NCR_GetRemoteAddress(records[slot].data);
+      if (auto_start_sources)
+        NCR_StartInstance(records[slot].data);
       return NSR_Success;
     }
   }
@@ -293,6 +298,26 @@ NSR_ResolveSources(void)
 
 /* ================================================== */
 
+void NSR_StartSources(void)
+{
+  int i;
+
+  for (i = 0; i < N_RECORDS; i++) {
+    if (!records[i].remote_addr)
+      continue;
+    NCR_StartInstance(records[i].data);
+  }
+}
+
+/* ================================================== */
+
+void NSR_AutoStartSources(void)
+{
+  auto_start_sources = 1;
+}
+
+/* ================================================== */
+
 /* Procedure to remove a source.  We don't bother whether the port
    address is matched - we're only interested in removing a record for
    the right IP address.  Thus the caller can specify the port number
index 43a1cc854325e0f7faea1e9efa8a947c63d33d15..cb25e5f4408d51e2f4ff0f79ba5eed1ff6fb1913 100644 (file)
@@ -57,6 +57,12 @@ extern void NSR_AddUnresolvedSource(char *name, int port, NTP_Source_Type type,
 /* Procedure to try resolve unresolved sources immediately. */
 extern void NSR_ResolveSources(void);
 
+/* Procedure to start all sources */
+extern void NSR_StartSources(void);
+
+/* Start new sources automatically */
+extern void NSR_AutoStartSources(void);
+
 /* Procedure to remove a source */
 extern NSR_Status NSR_RemoveSource(NTP_Remote_Address *remote_addr);