]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Add retries and timeout commands
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 4 Oct 2010 13:00:07 +0000 (15:00 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Mon, 4 Oct 2010 13:00:07 +0000 (15:00 +0200)
chrony.texi
client.c

index f20376993a37254f487ebe00b4e49a6c19139493..d1c77b31a339aca7a39b128c92c4fa76ebca8ce5 100644 (file)
@@ -2836,10 +2836,12 @@ interface.
 * online command::              Warn that connectivity to a source has been restored
 * password command::            Provide password needed for most commands
 * quit command::                Exit from chronyc
+* retries command::             Set maximum number of retries
 * rtcdata command::             Display RTC parameters
 * settime command::             Provide a manual input of the current time
 * sources command::             Display information about the current set of sources
 * sourcestats command::         Display the rate & offset estimation performance of sources
+* timeout command::             Set initial response timeout
 * tracking command::            Display system clock performance
 * trimrtc command::             Correct the RTC time to the current system time
 * writertc command::            Write the RTC parameters to file.
@@ -3604,6 +3606,15 @@ directive}).
 The quit command exits from chronyc and returns the user to the shell
 (same as the exit command).
 @c }}}
+@c {{{ retries
+@node retries command
+@subsubsection retries
+The @code{retries} command sets the maximum number of retries for
+@code{chronyc} requests before giving up.  The response timeout is controlled
+by @code{timeout} command (@pxref{timeout command}).
+
+The default is 2.
+@c }}}
 @c {{{ rtcdata
 @node rtcdata command
 @subsubsection rtcdata
@@ -3841,6 +3852,16 @@ This is the estimated sample standard deviation.
 
 @end table
 @c }}}
+@c {{{ timeout
+@node timeout command
+@subsubsection timeout
+The @code{timeout} command sets the initial timeout for @code{chronyc} requests
+in milliseconds.  If no response is received from @code{chronyd}, the timeout is
+doubled and the request is resent.  The maximum number of retries is configured
+with the @code{retries} command (@pxref{retries command}).
+
+The default is 1000 milliseconds.
+@c }}}
 @c {{{ tracking
 @node tracking command
 @subsubsection tracking
index 4874266823aeb6431eebba65dca850976dc44344..64147d1765eb0388c3b3e3be0222831214c43ce0 100644 (file)
--- a/client.c
+++ b/client.c
@@ -1179,6 +1179,8 @@ give_help(void)
   printf("\n");
   printf("dns -n|+n : Disable/enable resolving IP addresses to hostnames\n");
   printf("dns -4|-6|-46 : Resolve hostnames only to IPv4/IPv6/both addresses\n");
+  printf("timeout <milliseconds> : Set initial response timeout\n");
+  printf("retries <n> : Set maximum number of retries\n");
   printf("exit|quit : Leave the program\n");
   printf("help : Generate this help\n");
   printf("\n");
@@ -1190,8 +1192,8 @@ static unsigned long sequence = 0;
 static unsigned long utoken = 0;
 static unsigned long token = 0;
 
-#define MAX_ATTEMPTS 3
-
+static int max_retries = 2;
+static int initial_timeout = 1000;
 
 /* This is the core protocol module.  Complete particular fields in
    the outgoing packet, send it, wait for a response, handle retries,
@@ -1210,8 +1212,8 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
   int read_length;
   int expected_length;
   int command_length;
-  struct timeval timeout;
-  int timeout_seconds;
+  struct timeval tv;
+  int timeout;
   int n_attempts;
   fd_set rdfd, wrfd, exfd;
 
@@ -1225,8 +1227,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
   request->utoken = htonl(utoken);
   request->token = htonl(token);
 
-  timeout_seconds = 1;
-
+  timeout = initial_timeout;
 
   n_attempts = 0;
 
@@ -1262,17 +1263,17 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
     /* Increment this for next time */
     ++ request->attempt;
       
-    timeout.tv_sec = timeout_seconds;
-    timeout.tv_usec = 0;
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = timeout % 1000 * 1000;
+    timeout *= 2;
 
-    timeout_seconds *= 2;
     FD_ZERO(&rdfd);
     FD_ZERO(&wrfd);
     FD_ZERO(&exfd);
 
     FD_SET(sock_fd, &rdfd);
 
-    select_status = select(sock_fd + 1, &rdfd, &wrfd, &exfd, &timeout);
+    select_status = select(sock_fd + 1, &rdfd, &wrfd, &exfd, &tv);
 
     if (select_status < 0) {
 #if 0
@@ -1281,7 +1282,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
     } else if (select_status == 0) {
       /* Timeout must have elapsed, try a resend? */
       n_attempts ++;
-      if (n_attempts == MAX_ATTEMPTS) {
+      if (n_attempts > max_retries) {
         return 0;
       }
 
@@ -1304,7 +1305,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
            going to a dead port - but only if the daemon machine is
            running Linux (Solaris doesn't return anything) */
         n_attempts++;
-        if (n_attempts == MAX_ATTEMPTS) {
+        if (n_attempts > max_retries) {
           return 0;
         }
       } else {
@@ -1333,7 +1334,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
         
         if (bad_length || bad_sender || bad_sequence) {
           n_attempts++;
-          if (n_attempts == MAX_ATTEMPTS) {
+          if (n_attempts > max_retries) {
             return 0;
           }
           continue;
@@ -1349,7 +1350,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
         
         if (bad_header) {
           n_attempts++;
-          if (n_attempts == MAX_ATTEMPTS) {
+          if (n_attempts > max_retries) {
             return 0;
           }
           continue;
@@ -2331,6 +2332,38 @@ process_cmd_dns(const char *line)
 
 /* ================================================== */
 
+static int
+process_cmd_timeout(const char *line)
+{
+  int timeout;
+
+  timeout = atoi(line);
+  if (timeout < 100) {
+    fprintf(stderr, "Timeout %d is too short\n", timeout);
+    return 0;
+  }
+  initial_timeout = timeout;
+  return 1;
+}
+
+/* ================================================== */
+
+static int
+process_cmd_retries(const char *line)
+{
+  int retries;
+
+  retries = atoi(line);
+  if (retries < 0) {
+    fprintf(stderr, "Invalid maximum number of retries\n");
+    return 0;
+  }
+  max_retries = retries;
+  return 1;
+}
+
+/* ================================================== */
+
 static int
 process_line(char *line, int *quit)
 {
@@ -2449,6 +2482,12 @@ process_line(char *line, int *quit)
   } else if (!strncmp(p, "dns ", 4)) {
     ret = process_cmd_dns(p+4);
     do_normal_submit = 0;
+  } else if (!strncmp(p, "timeout", 7)) {
+    ret = process_cmd_timeout(p+7);
+    do_normal_submit = 0;
+  } else if (!strncmp(p, "retries", 7)) {
+    ret = process_cmd_retries(p+7);
+    do_normal_submit = 0;
   } else if (!strncmp(p, "help", 4)) {
     do_normal_submit = 0;
     give_help();