]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
ntpq mrulist shows intermediate counts every five seconds while
authorDave Hart <hart@ntp.org>
Thu, 13 Oct 2011 18:13:58 +0000 (18:13 +0000)
committerDave Hart <hart@ntp.org>
Thu, 13 Oct 2011 18:13:58 +0000 (18:13 +0000)
  retrieving list, and allows Ctrl-C interruption of the retrieval,
  showing the incomplete list as retrieved.  Reduce delay between
  successive mrulist retrieval queries from 30 to 5 msec.  Do not
  give up mrulist retrieval when a single query times out.

bk: 4e972a66ne0ahGB5OMdVfV3THZDFlQ

ChangeLog
include/ntp_stdlib.h
libntp/syssignal.c
ntpq/ntpq-subs.c
ntpq/ntpq.h

index 7d9142452053ccc2e10277ef82110b2cc72ee80b..2ee41b2e0ef4d1954852a29dda547a14d197c2b2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+* ntpq mrulist shows intermediate counts every five seconds while
+  retrieving list, and allows Ctrl-C interruption of the retrieval,
+  showing the incomplete list as retrieved.  Reduce delay between
+  successive mrulist retrieval queries from 30 to 5 msec.  Do not
+  give up mrulist retrieval when a single query times out.
 (4.2.7p223) 2011/10/12 Released by Harlan Stenn <stenn@ntp.org>
 * Documentation updates from Dave Mills.
 (4.2.7p222) 2011/10/11 Released by Harlan Stenn <stenn@ntp.org>
index 7669e298f20c20d8daf811f833140a00b93bdeeb..0a4a32f88a7d17a4077be4809ff17bf50977adb5 100644 (file)
@@ -77,6 +77,8 @@ extern        void    errno_to_str(int, char *, size_t);
                errno = preserved_errno;                \
        }
 
+typedef void (*ctrl_c_fn)(void);
+
 /* authkeys.c */
 extern void    auth_delkeys    (void);
 extern int     auth_havekey    (keyid_t);
@@ -175,6 +177,7 @@ extern      int     decodenetnum    (const char *, sockaddr_u *);
 extern const char * FindConfig (const char *);
 
 extern void    signal_no_reset (int, RETSIGTYPE (*func)(int));
+extern void    set_ctrl_c_hook (ctrl_c_fn);
 
 extern void    getauthkeys     (const char *);
 extern void    auth_agekeys    (void);
index 3f1848135be846689e1af3af210e01c50dc76cbf..5e496a95f26db16b3b2e18f516e0b7ed156636c5 100644 (file)
@@ -9,6 +9,13 @@
 #include "ntp_syslog.h"
 #include "ntp_stdlib.h"
 
+static ctrl_c_fn       ctrl_c_hook;
+#ifndef SYS_WINNT
+RETSIGTYPE sigint_handler(int);
+#else
+BOOL WINAPI console_event_handler(DWORD);
+#endif
+
 
 #ifdef HAVE_SIGACTION
 
@@ -107,3 +114,75 @@ signal_no_reset(
 }
 
 #endif
+
+#ifndef SYS_WINNT
+/*
+ * POSIX implementation of set_ctrl_c_hook()
+ */
+RETSIGTYPE
+sigint_handler(
+       int     signum
+       )
+{
+       UNUSED_ARG(signum);
+       if (ctrl_c_hook != NULL)
+               (*ctrl_c_hook)();
+}
+
+void
+set_ctrl_c_hook(
+       ctrl_c_fn       c_hook
+       )
+{
+       RETSIGTYPE (*handler)(int);
+
+       if (NULL == c_hook) {
+               handler = SIG_DFL;
+               ctrl_c_hook = NULL;
+       } else {
+               handler = &sigint_handler;
+               ctrl_c_hook = c_hook;
+       }
+       signal_no_reset(SIGINT, handler);
+}
+#else  /* SYS_WINNT follows */
+/*
+ * Windows implementation of set_ctrl_c_hook()
+ */
+BOOL WINAPI 
+console_event_handler(  
+       DWORD   dwCtrlType
+       )
+{
+       BOOL handled;
+
+       if (CTRL_C_EVENT == dwCtrlType && ctrl_c_hook != NULL) {
+               (*ctrl_c_hook)();
+               handled = TRUE;
+       } else {
+               handled = FALSE;
+       }
+
+       return handled;
+}
+void
+set_ctrl_c_hook(
+       ctrl_c_fn       c_hook
+       )
+{
+       BOOL install;
+
+       if (NULL == c_hook) {
+               ctrl_c_hook = NULL;
+               install = FALSE;
+       } else {
+               ctrl_c_hook = c_hook;
+               install = TRUE;
+       }
+       if (!SetConsoleCtrlHandler(&console_event_handler, install))
+               msyslog(LOG_ERR, "Can't %s console control handler: %m",
+                       (install)
+                           ? "add"
+                           : "remove");
+}
+#endif /* SYS_WINNT */
index 1bc8b13e1ecfa0cdf0671f6261bee81ac9bfdbad..d5e4035843b5432705f8a15e2aea43f63168df42 100644 (file)
@@ -319,8 +319,9 @@ typedef struct var_display_collection_tag {
 } vdc;
 
 /*
- * other static function prototypes
+ * other local function prototypes
  */
+void           mrulist_ctrl_c_hook(void);
 static mru *   add_mru(mru *);
 static int     collect_mru_list(const char *, l_fp *);
 static int     fetch_nonce(char *, size_t);
@@ -339,6 +340,8 @@ static void collect_display_vdc(associd_t as, vdc *table,
  * static globals
  */
 static u_int   mru_count;
+static u_int   mru_dupes;
+volatile int   mrulist_interrupted;
 static mru     mru_list;               /* listhead */
 static mru **  hash_table;
 
@@ -2175,11 +2178,11 @@ add_mru(
                                add->last.l_uf, mon->last.l_ui,
                                mon->last.l_uf);
                        exit(1);
-
                }
                UNLINK_DLIST(mon, mlink);
                UNLINK_SLIST(unlinked, hash_table[hash], mon, hlink, mru);
                NTP_INSIST(unlinked == mon);
+               mru_dupes++;
                if (debug)
                        fprintf(stderr, "(updated from %08x.%08x) ",
                                mon->last.l_ui, mon->last.l_uf);
@@ -2216,16 +2219,24 @@ add_mru(
        } while (0)
 
 
+void
+mrulist_ctrl_c_hook(void)
+{
+       mrulist_interrupted = TRUE;
+}
+
+
 static int
 collect_mru_list(
-       const char *parms,
-       l_fp *  pnow
+       const char *    parms,
+       l_fp *          pnow
        )
 {
-       const u_int sleep_msecs = 30;
+       const u_int sleep_msecs = 5;
        static int ntpd_row_limit = MRU_ROW_LIMIT;
        int c_mru_l_rc;         /* this function's return code */
        u_char got;             /* MRU_GOT_* bits */
+       time_t next_report;
        size_t cb;
        mru *mon;
        mru *head;
@@ -2279,6 +2290,12 @@ collect_mru_list(
        mon = emalloc_zero(cb);
        ZERO(*pnow);
        ZERO(last_older);
+       mrulist_interrupted = FALSE;
+       set_ctrl_c_hook(&mrulist_ctrl_c_hook);
+       fprintf(stderr,
+               "Ctrl-C will stop MRU retrieval and display partial results.\n");
+       fflush(stderr);
+       next_report = time(NULL) + MRU_REPORT_SECS;
 
        limit = min(3 * MAXFRAGS, ntpd_row_limit);
        snprintf(req_buf, sizeof(req_buf), "nonce=%s, limit=%d%s",
@@ -2343,7 +2360,8 @@ collect_mru_list(
                                fprintf(stderr,
                                        "Row limit reduced to %d following CERR_BADVALUE.\n",
                                        limit);
-               } else if (ERR_INCOMPLETE == qres) {
+               } else if (ERR_INCOMPLETE == qres ||
+                          ERR_TIMEOUT == qres) {
                        /*
                         * Reduce the number of rows to minimize effect
                         * of single lost packets.
@@ -2466,10 +2484,18 @@ collect_mru_list(
                                } else if (1 != sscanf(tag, "last.%d", &si) ||
                                           si != ci || '0' != val[0] ||
                                           'x' != val[1] ||
-                                          !hextolfp(val + 2, &mon->last))
+                                          !hextolfp(val + 2, &mon->last)) {
                                        goto nomatch;
-                               else
+                               } else {
                                        MGOT(MRU_GOT_LAST);
+                                       /*
+                                        * allow interrupted retrieval,
+                                        * using most recent retrieved
+                                        * entry's last seen timestamp
+                                        * as the end of operation.
+                                        */
+                                       *pnow = mon->last;
+                               }
                                break;
 
                        case 'f':
@@ -2531,8 +2557,26 @@ collect_mru_list(
                        list_complete = TRUE;
                if (list_complete) {
                        NTP_INSIST(0 == ri || have_addr_older);
+               }
+               if (mrulist_interrupted) {
+                       printf("mrulist retrieval interrupted by operator.\n"
+                              "Displaying partial client list.\n");
+                       fflush(stdout);
+               }
+               if (list_complete || mrulist_interrupted) {
+                       fprintf(stderr,
+                               "\rRetrieved %u unique MRU entries and %u updates.\n",
+                               mru_count, mru_dupes);
+                       fflush(stderr);
                        break;
                }
+               if (time(NULL) >= next_report) {
+                       next_report += MRU_REPORT_SECS;
+                       fprintf(stderr, "\r%u (%u updates) ", mru_count,
+                               mru_dupes);
+                       fflush(stderr);
+               }
+
                /*
                 * Snooze for a bit between queries to let ntpd catch
                 * up with other duties.
@@ -2592,6 +2636,7 @@ collect_mru_list(
                }
        }
 
+       set_ctrl_c_hook(NULL);
        c_mru_l_rc = TRUE;
        goto retain_hash_table;
 
index 6398ec6ceeabc9368d719859f40bff04b86f8e02..243a54afe7a8b83731c5fcad9070cdc2f29dca8f 100644 (file)
@@ -104,6 +104,11 @@ struct association {
 
 #define        MAXASSOC        1024
 
+/*
+ * mrulist terminal status interval
+ */
+#define        MRU_REPORT_SECS 5
+
 /*
  * var_format is used to override cooked formatting for selected vars.
  */