[Git][NTPsec/ntpsec][master] 3 commits: Add minage keyword to ntp.conf

Hal Murray gitlab at mg.gitlab.com
Wed Dec 28 11:16:47 UTC 2016


Hal Murray pushed to branch master at NTPsec / ntpsec


Commits:
dd431856 by Hal Murray at 2016-12-27T23:53:20-08:00
Add minage keyword to ntp.conf

- - - - -
ee767fb5 by Hal Murray at 2016-12-27T23:53:20-08:00
Cleaned up MRU slot allocation (needs doc update)

- - - - -
6d32cc1d by Hal Murray at 2016-12-28T03:15:43-08:00
Doc for new MRU allocation scheme

- - - - -


8 changed files:

- docs/includes/misc-options.txt
- include/ntpd.h
- ntpclients/ntpq
- ntpd/keyword-gen.c
- ntpd/ntp_config.c
- ntpd/ntp_control.c
- ntpd/ntp_monitor.c
- ntpd/ntp_parser.y


Changes:

=====================================
docs/includes/misc-options.txt
=====================================
--- a/docs/includes/misc-options.txt
+++ b/docs/includes/misc-options.txt
@@ -142,7 +142,7 @@ and so on is suppressed.
   same operation as the -l command line option.
 
 [[mru]]
-+mru+ [+maxdepth+ 'count' | +maxmem+ 'kilobytes' | +mindepth+ 'count' | +maxage+ 'seconds' | +initalloc+ 'count' | +initmem+ 'kilobytes' | +incalloc+ 'count' | +incmem+ 'kilobytes']::
++mru+ [+maxdepth+ 'count' | +maxmem+ 'kilobytes' | +mindepth+ 'count' | +maxage+ 'seconds' | +minage+ 'seconds' | +initalloc+ 'count' | +initmem+ 'kilobytes' | +incalloc+ 'count' | +incmem+ 'kilobytes']::
   Controls size limits of the monitoring facility Most Recently Used
   (MRU) list of client addresses, which is also
   used by the rate control facility.
@@ -159,12 +159,18 @@ and so on is suppressed.
     +mindepth+ entries, existing entries are never removed to make room
     for newer ones, regardless of their age. The default is 600 entries.
   +maxage+ 'seconds';;
-    Once the MRU list has +mindepth+ entries and an additional client
-    address is to be added to the list, if the oldest entry was updated
-    more than +maxage+ seconds ago, that entry is removed and its
-    storage reused. If the oldest entry was updated more recently, the
-    MRU list is grown, subject to +maxdepth+/+maxmem+. The default is 64
-    seconds.
+  +minage+ 'seconds';;
+    If an address is not in the list, there are several possible ways
+    to find a slot for it.
+    1. If the list has fewer than +mindepth+ entries, a slot is
+    allocated from the free list.
+    2. If the age of the oldest slot is less than +maxage+, the oldest
+    slot is recycled.
+    3. If the freelist is not empty, a slot is allocated from the
+    free list.
+    4. If the age of the oldest slot is more than +minage+, the oldest
+    slot is recycled.
+    5. Otherwise, no slot is available.
   +initalloc+ 'count';;         
   +initmem+ 'kilobytes';;
     Initial memory allocation at the time the monitoring facility is


=====================================
include/ntpd.h
=====================================
--- a/include/ntpd.h
+++ b/include/ntpd.h
@@ -141,6 +141,7 @@ extern	void	mon_start	(int);
 extern	void	mon_stop	(int);
 extern	u_short	ntp_monitor	(struct recvbuf *, u_short);
 extern	void	mon_clearinterface(endpt *interface);
+extern  int	mon_get_oldest_age(l_fp);
 
 /* ntp_peer.c */
 extern	void	init_peer	(void);
@@ -349,8 +350,14 @@ extern u_int	mru_peakentries;	/* highest mru_entries */
 extern u_int	mru_initalloc;		/* entries to preallocate */
 extern u_int	mru_incalloc;		/* allocation batch factor */
 extern u_int	mru_mindepth;		/* preempt above this */
-extern int	mru_maxage;		/* for entries older than */
+extern int	mru_maxage;		/* recycle if older than this */
+extern int	mru_minage;		/* recycle if older than this & full */
 extern u_int	mru_maxdepth; 		/* MRU size hard limit */
+extern u_long	mru_exists;		/* slot already exists */
+extern u_long	mru_new;		/* allocated new slot */
+extern u_long	mru_recycleold;		/* recycle: age > maxage */
+extern u_long	mru_recyclefull;	/* recycle: full and age > minage */
+extern u_long	mru_none;		/* couldn't allocate slot */
 extern int	mon_age;		/* preemption limit */
 
 /* ntp_peer.c */


=====================================
ntpclients/ntpq
=====================================
--- a/ntpclients/ntpq
+++ b/ntpclients/ntpq
@@ -326,6 +326,8 @@ usage: help [ command ]
 
     def __assoc_valid(self, line, required=False):
         "Process a numeric associd or index."
+        # FIXME: This does a useless call to __dogetassoc() when associd == 0
+        # No big deal most of the time.  Just a useless packet exchange.
         if not line:
             if required:
                 self.warn("An associd argument is required.\n")
@@ -447,8 +449,10 @@ usage: timeout [ msec ]
             queried = self.session.readvar(associd, [v[0] for v in variables])
         except ntp.packet.ControlException as e:
             if ntp.control.CERR_UNKNOWNVAR == e.errorcode:
+                self.warn("Unknown variable.  Trying one at a time.\n")
+                varlist = [v[0] for v in variables]
                 items = []
-                for var in [v[0] for v in variables]:
+                for var in varlist:
                     try:
                         queried = self.session.readvar(associd, [var])
                         for (name, value) in queried.items():
@@ -1216,7 +1220,8 @@ usage: config_from_file <configuration filename>
                             val = val[1:-1]
                 cmdvars[var] = val
 
-        self.say("Ctrl-C will stop MRU retrieval and display partial results.\n")
+        if not self.directmode:
+            self.say("Ctrl-C will stop MRU retrieval and display partial results.\n")
         if self.rawmode:
             mruhook = lambda v: self.printvars(variables=v,
                                                dtype=ntp.ntpc.TYPE_SYS,
@@ -1400,14 +1405,21 @@ usage: sysstats
     def do_monstats(self, _line):
         "display monitor (mrulist) counters and limits"
         monstats = (
-            ("mru_enabled",	"enabled:            ", NTP_INT),
-            ("mru_depth",	"addresses:          ", NTP_INT),
-            ("mru_deepest",	"peak addresses:     ", NTP_INT),
-            ("mru_maxdepth",	"maximum addresses:  ", NTP_INT),
-            ("mru_mindepth",	"reclaim above count:", NTP_INT),
-            ("mru_maxage",	"reclaim older than: ", NTP_INT),
-            ("mru_mem",		"kilobytes:          ", NTP_INT),
-            ("mru_maxmem",	"maximum kilobytes:  ", NTP_INT),
+            ("mru_enabled",	"enabled:              ", NTP_INT),
+            ("mru_depth",	"addresses:            ", NTP_INT),
+            ("mru_deepest",	"peak addresses:       ", NTP_INT),
+            ("mru_maxdepth",	"maximum addresses:    ", NTP_INT),
+            ("mru_mindepth",	"reclaim above count:  ", NTP_INT),
+            ("mru_maxage",	"reclaim maxage:       ", NTP_INT),
+            ("mru_minage",	"reclaim minage:       ", NTP_INT),
+            ("mru_mem",		"kilobytes:            ", NTP_INT),
+            ("mru_maxmem",	"maximum kilobytes:    ", NTP_INT),
+            ("mru_exists", 	"alloc: exists:        ", NTP_INT),
+            ("mru_new", 	"alloc: new:           ", NTP_INT),
+            ("mru_recycleold", 	"alloc: recycle old:   ", NTP_INT),
+            ("mru_recyclefull", "alloc: recycle full:  ", NTP_INT),
+            ("mru_none", 	"alloc: none:          ", NTP_INT),
+            ("mru_oldest_age", 	"age of oldest slot:   ", NTP_INT),
         )
         self.collect_display(associd=0, variables=monstats, decodestatus=False)
 


=====================================
ntpd/keyword-gen.c
=====================================
--- a/ntpd/keyword-gen.c
+++ b/ntpd/keyword-gen.c
@@ -162,8 +162,9 @@ struct key_tok ntp_keywords[] = {
 { "initalloc",		T_Initalloc,		FOLLBY_TOKEN },
 { "initmem",		T_Initmem,		FOLLBY_TOKEN },
 { "mindepth",		T_Mindepth,		FOLLBY_TOKEN },
-{ "maxage",		T_Maxage,		FOLLBY_TOKEN },
 { "maxdepth",		T_Maxdepth,		FOLLBY_TOKEN },
+{ "maxage",		T_Maxage,		FOLLBY_TOKEN },
+{ "minage",		T_Minage,		FOLLBY_TOKEN },
 { "maxmem",		T_Maxmem,		FOLLBY_TOKEN },
 { "mru",		T_Mru,			FOLLBY_TOKEN },
 /* fudge_factor */


=====================================
ntpd/ntp_config.c
=====================================
--- a/ntpd/ntp_config.c
+++ b/ntpd/ntp_config.c
@@ -1592,6 +1592,10 @@ config_access(
 			mru_maxage = my_opt->value.i;
 			break;
 
+		case T_Minage:
+			mru_minage = my_opt->value.i;
+			break;
+
 		case T_Maxdepth:
 			if (0 <= my_opt->value.i)
 				mru_maxdepth = my_opt->value.u;


=====================================
ntpd/ntp_control.c
=====================================
--- a/ntpd/ntp_control.c
+++ b/ntpd/ntp_control.c
@@ -147,24 +147,24 @@ static const struct ctl_proc control_codes[] = {
 #define	CS_MRU_DEEPEST		26
 #define	CS_MRU_MINDEPTH		27
 #define	CS_MRU_MAXAGE		28
-#define	CS_MRU_MAXDEPTH		29
-#define	CS_MRU_MEM		30
-#define	CS_MRU_MAXMEM		31
-#define	CS_SS_UPTIME		32
-#define	CS_SS_RESET		33
-#define	CS_SS_RECEIVED		34
-#define	CS_SS_THISVER		35
-#define	CS_SS_OLDVER		36
-#define	CS_SS_BADFORMAT		37
-#define	CS_SS_BADAUTH		38
-#define	CS_SS_DECLINED		39
-#define	CS_SS_RESTRICTED	40
-#define	CS_SS_LIMITED		41
-#define	CS_SS_KODSENT		42
-#define	CS_SS_PROCESSED		43
-#define	CS_PEERADR		44
-#define	CS_PEERMODE		45
-/* was	CS_BCASTDELAY		46 */
+#define	CS_MRU_MINAGE		29
+#define	CS_MRU_MAXDEPTH		30
+#define	CS_MRU_MEM		31
+#define	CS_MRU_MAXMEM		32
+#define	CS_SS_UPTIME		33
+#define	CS_SS_RESET		34
+#define	CS_SS_RECEIVED		35
+#define	CS_SS_THISVER		36
+#define	CS_SS_OLDVER		37
+#define	CS_SS_BADFORMAT		38
+#define	CS_SS_BADAUTH		39
+#define	CS_SS_DECLINED		40
+#define	CS_SS_RESTRICTED	41
+#define	CS_SS_LIMITED		42
+#define	CS_SS_KODSENT		43
+#define	CS_SS_PROCESSED		44
+#define	CS_PEERADR		45
+#define	CS_PEERMODE		46
 #define	CS_AUTHDELAY		47
 #define	CS_AUTHKEYS		48
 #define	CS_AUTHFREEK		49
@@ -210,8 +210,14 @@ static const struct ctl_proc control_codes[] = {
 #define	CS_TIMER_XMTS		87
 #define	CS_FUZZ			88
 #define	CS_WANDER_THRESH	89
-#define	CS_LEAPSMEARINTV	90
-#define	CS_LEAPSMEAROFFS	91
+#define CS_MRU_EXISTS		90
+#define CS_MRU_NEW		91
+#define CS_MRU_RECYCLEOLD	92
+#define CS_MRU_RECYCLEFULL	93
+#define CS_MRU_NONE		94
+#define CS_MRU_OLDEST_AGE	95
+#define	CS_LEAPSMEARINTV	96
+#define	CS_LEAPSMEAROFFS	97
 #define	CS_MAXCODE		CS_LEAPSMEAROFFS
 
 /*
@@ -321,24 +327,24 @@ static const struct ctl_var sys_var[] = {
 	{ CS_MRU_DEEPEST,	RO, "mru_deepest" },	/* 26 */
 	{ CS_MRU_MINDEPTH,	RO, "mru_mindepth" },	/* 27 */
 	{ CS_MRU_MAXAGE,	RO, "mru_maxage" },	/* 28 */
-	{ CS_MRU_MAXDEPTH,	RO, "mru_maxdepth" },	/* 29 */
-	{ CS_MRU_MEM,		RO, "mru_mem" },	/* 30 */
-	{ CS_MRU_MAXMEM,	RO, "mru_maxmem" },	/* 31 */
-	{ CS_SS_UPTIME,		RO, "ss_uptime" },	/* 32 */
-	{ CS_SS_RESET,		RO, "ss_reset" },	/* 33 */
-	{ CS_SS_RECEIVED,	RO, "ss_received" },	/* 34 */
-	{ CS_SS_THISVER,	RO, "ss_thisver" },	/* 35 */
-	{ CS_SS_OLDVER,		RO, "ss_oldver" },	/* 36 */
-	{ CS_SS_BADFORMAT,	RO, "ss_badformat" },	/* 37 */
-	{ CS_SS_BADAUTH,	RO, "ss_badauth" },	/* 38 */
-	{ CS_SS_DECLINED,	RO, "ss_declined" },	/* 39 */
-	{ CS_SS_RESTRICTED,	RO, "ss_restricted" },	/* 40 */
-	{ CS_SS_LIMITED,	RO, "ss_limited" },	/* 41 */
-	{ CS_SS_KODSENT,	RO, "ss_kodsent" },	/* 42 */
-	{ CS_SS_PROCESSED,	RO, "ss_processed" },	/* 43 */
-	{ CS_PEERADR,		RO, "peeradr" },	/* 44 */
-	{ CS_PEERMODE,		RO, "peermode" },	/* 45 */
-	{ 46,			RO, "was bcastdelay" },	/* 46 */
+	{ CS_MRU_MINAGE,	RO, "mru_minage" },     /* 29 */
+	{ CS_MRU_MAXDEPTH,	RO, "mru_maxdepth" },	/* 30 */
+	{ CS_MRU_MEM,		RO, "mru_mem" },	/* 31 */
+	{ CS_MRU_MAXMEM,	RO, "mru_maxmem" },	/* 32 */
+	{ CS_SS_UPTIME,		RO, "ss_uptime" },	/* 33 */
+	{ CS_SS_RESET,		RO, "ss_reset" },	/* 34 */
+	{ CS_SS_RECEIVED,	RO, "ss_received" },	/* 35 */
+	{ CS_SS_THISVER,	RO, "ss_thisver" },	/* 36 */
+	{ CS_SS_OLDVER,		RO, "ss_oldver" },	/* 37 */
+	{ CS_SS_BADFORMAT,	RO, "ss_badformat" },	/* 38 */
+	{ CS_SS_BADAUTH,	RO, "ss_badauth" },	/* 39 */
+	{ CS_SS_DECLINED,	RO, "ss_declined" },	/* 40 */
+	{ CS_SS_RESTRICTED,	RO, "ss_restricted" },	/* 41 */
+	{ CS_SS_LIMITED,	RO, "ss_limited" },	/* 42 */
+	{ CS_SS_KODSENT,	RO, "ss_kodsent" },	/* 43 */
+	{ CS_SS_PROCESSED,	RO, "ss_processed" },	/* 44 */
+	{ CS_PEERADR,		RO, "peeradr" },	/* 45 */
+	{ CS_PEERMODE,		RO, "peermode" },	/* 46 */
 	{ CS_AUTHDELAY,		RO, "authdelay" },	/* 47 */
 	{ CS_AUTHKEYS,		RO, "authkeys" },	/* 48 */
 	{ CS_AUTHFREEK,		RO, "authfreek" },	/* 49 */
@@ -382,9 +388,15 @@ static const struct ctl_var sys_var[] = {
 	{ CS_TIMER_XMTS,	RO, "timer_xmts" },	/* 87 */
 	{ CS_FUZZ,		RO, "fuzz" },		/* 88 */
 	{ CS_WANDER_THRESH,	RO, "clk_wander_threshold" }, /* 89 */
-	{ CS_LEAPSMEARINTV,	RO, "leapsmearinterval" },    /* 90 */
-	{ CS_LEAPSMEAROFFS,	RO, "leapsmearoffset" },      /* 91 */
-	{ 0,		EOV, "" }		/* 91 */
+	{ CS_MRU_EXISTS,	RO, "mru_exists" },	/* 90 */
+	{ CS_MRU_NEW,		RO, "mru_new" },	/* 91 */
+	{ CS_MRU_RECYCLEOLD,	RO, "mru_recycleold" },	/* 92 */
+	{ CS_MRU_RECYCLEFULL,	RO, "mru_recyclefull" },/* 93 */
+	{ CS_MRU_NONE,		RO, "mru_none" },	/* 94 */
+	{ CS_MRU_OLDEST_AGE,	RO, "mru_oldest_age" },	/* 95 */
+	{ CS_LEAPSMEARINTV,	RO, "leapsmearinterval" },    /* 96 */
+	{ CS_LEAPSMEAROFFS,	RO, "leapsmearoffset" },      /* 97 */
+	{ 0,		EOV, "" }		/* 97 */
 };
 
 static struct ctl_var *ext_sys_var = NULL;
@@ -1652,6 +1664,10 @@ ctl_putsys(
 		ctl_putint(sys_var[varid].text, mru_maxage);
 		break;
 
+	case CS_MRU_MINAGE:
+		ctl_putint(sys_var[varid].text, mru_minage);
+		break;
+
 	case CS_MRU_MAXDEPTH:
 		ctl_putuint(sys_var[varid].text, mru_maxdepth);
 		break;
@@ -1664,6 +1680,33 @@ ctl_putsys(
 		ctl_putuint(sys_var[varid].text, u);
 		break;
 
+	case CS_MRU_EXISTS:
+		ctl_putuint(sys_var[varid].text, mru_exists);
+		break;
+
+	case CS_MRU_NEW:
+		ctl_putuint(sys_var[varid].text, mru_new);
+		break;
+
+	case CS_MRU_RECYCLEOLD:
+		ctl_putuint(sys_var[varid].text, mru_recycleold);
+		break;
+
+	case CS_MRU_RECYCLEFULL:
+		ctl_putuint(sys_var[varid].text, mru_recyclefull);
+		break;
+
+	case CS_MRU_NONE:
+		ctl_putuint(sys_var[varid].text, mru_none);
+		break;
+
+	case CS_MRU_OLDEST_AGE: {
+		l_fp now;
+		get_systime(&now);
+		ctl_putuint(sys_var[varid].text, mon_get_oldest_age(now));
+		break;
+		}
+
 	case CS_SS_UPTIME:
 		ctl_putuint(sys_var[varid].text, current_time);
 		break;


=====================================
ntpd/ntp_monitor.c
=====================================
--- a/ntpd/ntp_monitor.c
+++ b/ntpd/ntp_monitor.c
@@ -78,17 +78,25 @@ uint8_t	ntp_minpoll = NTP_MINPOLL;	/* increment (log 2 s) */
  * Initialization state.  We may be monitoring, we may not.  If
  * we aren't, we may not even have allocated any memory yet.
  */
-u_int	mon_enabled;			/* enable switch */
-u_int	mru_mindepth = 600;		/* preempt above this */
-int	mru_maxage = 64;		/* for entries older than */
+u_int	mon_enabled;		/* enable switch */
+u_int	mru_mindepth = 600;	/* preempt above this */
+int	mru_maxage = 3600;	/* recycle if older than this */
+int	mru_minage = 64;	/* recycle if full and older than this */
 u_int	mru_maxdepth = MRU_MAXDEPTH_DEF;	/* MRU count hard limit */
-int	mon_age = 3000;			/* preemption limit */
+int	mon_age = 3000;		/* preemption limit */
 
 static	void		mon_getmoremem(void);
 static	void		remove_from_hash(mon_entry *);
 static	inline void	mon_free_entry(mon_entry *);
 static	inline void	mon_reclaim_entry(mon_entry *);
 
+/* MRU counters */
+u_long mru_exists = 0;		/* slot already exists */
+u_long mru_new = 0;		/* allocate a new slot (2 cases) */
+u_long mru_recycleold = 0;	/* recycle slot: age > mru_maxage */
+u_long mru_recyclefull = 0;	/* recycle slot: full and age > mru_minage */
+u_long mru_none = 0;		/* couldn't get one */
+
 
 /*
  * init_mon - initialize monitoring global data
@@ -278,7 +286,17 @@ mon_clearinterface(
 	ITER_DLIST_END()
 }
 
-
+int mon_get_oldest_age(l_fp now)
+{
+    mon_entry *	oldest;
+    if (mru_entries == 0)
+	return 0;
+    oldest = TAIL_DLIST(mon_mru_list, mru);
+    L_SUB(&now, &oldest->last);
+    /* add one-half second to round up */
+    L_ADDUF(&now, 0x80000000);
+    return lfpsint(now);
+}
 /*
  * ntp_monitor - record stats about this packet
  *
@@ -333,6 +351,7 @@ ntp_monitor(
 			break;
 
 	if (mon != NULL) {
+		mru_exists++;
 		interval_fp = rbufp->recv_time;
 		L_SUB(&interval_fp, &mon->last);
 		/* add one-half second to round up */
@@ -423,33 +442,27 @@ ntp_monitor(
 	 * initmem", and for "mru incalloc" and "mru incmem".
 	 */
 	if (mru_entries < mru_mindepth) {
+		mru_new++;
 		if (NULL == mon_free)
 			mon_getmoremem();
 		UNLINK_HEAD_SLIST(mon, mon_free, hash_next);
 	} else {
 		oldest = TAIL_DLIST(mon_mru_list, mru);
-		oldest_age = 0;		/* silence uninit warning */
-		if (oldest != NULL) {
-			interval_fp = rbufp->recv_time;
-			L_SUB(&interval_fp, &oldest->last);
-			/* add one-half second to round up */
-			L_ADDUF(&interval_fp, 0x80000000);
-			oldest_age = lfpsint(interval_fp);
-		}
-		/* note -1 is legal for mru_maxage (disables) */
-		if (oldest != NULL && mru_maxage < oldest_age) {
+		oldest_age = mon_get_oldest_age(rbufp->recv_time);
+		if (mru_maxage < oldest_age) {
+			mru_recycleold++;
 			mon_reclaim_entry(oldest);
 			mon = oldest;
-		} else if (mon_free != NULL || mru_alloc <
-			   mru_maxdepth) {
+		} else if (mon_free != NULL || mru_alloc < mru_maxdepth) {
+			mru_new++;
 			if (NULL == mon_free)
 				mon_getmoremem();
 			UNLINK_HEAD_SLIST(mon, mon_free, hash_next);
-		/* preempt from the MRU list if old enough. */
-		} else if (ntp_random() / (2.0 * FRAC) >
-			   (double)oldest_age / mon_age) {
+		} else if (oldest_age < mru_minage) {
+			mru_none++;
 			return ~(RES_LIMITED | RES_KOD) & flags;
 		} else {
+			mru_recyclefull++;
 			/* coverity[var_deref_model] */
 			mon_reclaim_entry(oldest);
 			mon = oldest;


=====================================
ntpd/ntp_parser.y
=====================================
--- a/ntpd/ntp_parser.y
+++ b/ntpd/ntp_parser.y
@@ -136,6 +136,7 @@
 %token	<Integer>	T_Mdnstries
 %token	<Integer>	T_Mem
 %token	<Integer>	T_Memlock
+%token	<Integer>	T_Minage
 %token	<Integer>	T_Minclock
 %token	<Integer>	T_Mindepth
 %token	<Integer>	T_Mindist
@@ -903,6 +904,7 @@ mru_option_keyword
 	|	T_Initalloc
 	|	T_Initmem
 	|	T_Maxage
+	|	T_Minage
 	|	T_Maxdepth
 	|	T_Maxmem
 	|	T_Mindepth



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/93830c8ca49dfef84df99c2a1de7b87e933d2914...6d32cc1d566e8a3a91819e552971aa854b474f7b
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20161228/d34aeb78/attachment.html>


More information about the vc mailing list