[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