[Git][NTPsec/ntpsec][master] 3 commits: First pass a direct output mode for mrulist
Hal Murray
gitlab at mg.gitlab.com
Thu Dec 22 02:07:39 UTC 2016
Hal Murray pushed to branch master at NTPsec / ntpsec
Commits:
4322cb4d by Hal Murray at 2016-12-21T18:06:39-08:00
First pass a direct output mode for mrulist
- - - - -
c7d4a78d by Hal Murray at 2016-12-21T18:06:39-08:00
repair mru sort=avgint
- - - - -
29b69e26 by Hal Murray at 2016-12-21T18:06:39-08:00
Fix sort order within batch for direct mru
- - - - -
3 changed files:
- ntpclients/ntpq
- pylib/packet.py
- pylib/util.py
Changes:
=====================================
ntpclients/ntpq
=====================================
--- a/ntpclients/ntpq
+++ b/ntpclients/ntpq
@@ -11,7 +11,7 @@
# SPDX-License-Identifier: BSD-2-clause
from __future__ import print_function, division
-import os, sys, getopt, cmd, re
+import os, sys, getopt, cmd, re, time
import socket, hashlib
try:
@@ -147,6 +147,7 @@ class Ntpq(cmd.Cmd):
#self.auth_keytype = "NID_md5" # MD5 (FIXME: string value is a dummy)
#self.auth_hashlen = 16 # MD5
self.rawmode = False # Flag which indicates raw mode output.
+ self.directmode = False # Flag for direct MRU output.
self.showhostnames = True # If false, display numeric IPs
self.auth_delay = 20 # delay time (default 20msec)
self.wideremote = False # show wide remote names?
@@ -664,6 +665,14 @@ function: print version number
usage: version
""")
+ def do_direct(self, line):
+ "toggle direct mode output"
+ self.directmode = not self.directmode
+ if self.directmode:
+ print("Direct mode is on")
+ else:
+ print("Direct mode is off")
+
def do_raw(self, line):
"do raw mode variable output"
self.rawmode = True
@@ -1160,6 +1169,10 @@ function: configure ntpd using the configuration filename
usage: config_from_file <configuration filename>
""")
+ def printdirect(self, entries):
+ for entry in entries:
+ self.say(self.formatter.summary(entry) + "\n")
+
def do_mrulist(self, line):
"display the list of most recently seen source addresses, tags mincount=... resall=0x... resany=0x..."
cmdvars = {}
@@ -1190,23 +1203,36 @@ usage: config_from_file <configuration filename>
else:
mruhook = None
try:
- span = self.session.mrulist(variables=cmdvars, rawhook=mruhook)
- if not self.rawmode:
+ formatter = ntp.util.MRUSummary(interpreter.showhostnames)
+ if self.directmode:
+ formatter.now = None
+ self.formatter = formatter
+ if session.debug:
+ formatter.logfp = session.logfp
+ formatter.debug = session.debug
+ self.session.slots = 0
+ self.session.start = time.time()
+ direct = self.printdirect if self.directmode else None
+ span = self.session.mrulist(variables=cmdvars, \
+ rawhook=mruhook, direct=direct)
+ if not self.directmode and not self.rawmode:
if not span.is_complete():
self.say("mrulist retrieval interrupted by operator.\n"
- "Displaying partial client list.\n")
+ "Displaying partial client list.\n")
try:
- formatter = ntp.util.MRUSummary(interpreter.showhostnames)
- if session.debug:
- formatter.logfp = session.logfp
- formatter.debug = session.debug
+ delta1 = time.time() - self.session.start
self.say(ntp.util.MRUSummary.header + "\n")
self.say(("=" * ntp.util.MRUSummary.width) + "\n")
# reversed to put most recent entries at the top.
for entry in reversed(span.entries):
self.say(formatter.summary(entry) + "\n")
+ self.say("# Collected %d slots in %.3f seconds\n" \
+ % (self.session.slots, delta1) )
except KeyboardInterrupt:
pass
+ delta2 = time.time() - self.session.start
+ self.say("# Processed %d slots in %.3f seconds\n" \
+ % (self.session.slots, delta2) )
except ntp.packet.ControlException as e:
# Giving up after 8 restarts from the beginning.
# With high-traffic NTP servers, this can occur if the
=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -671,7 +671,9 @@ class MRUEntry:
self.mv = None # mode and version
self.rs = None # restriction mask (RES_* bits)
def avgint(self):
- return (self.last - self.first) / self.ct
+ last = ntp.ntpc.lfptofloat(self.last)
+ first = ntp.ntpc.lfptofloat(self.first)
+ return (last - first) / self.ct
def __repr__(self):
return "<MRUentry: " + repr(self.__dict__)[1:-1] + ">"
@@ -845,7 +847,8 @@ class ControlSession:
while len(xdata) % 4:
xdata += b"\x00"
if self.debug >= 3:
- self.logfp.write("Sending %d octets.\n" % len(xdata))
+ self.logfp.write("Sending %d octets. seq=%d\n" % \
+ ( len(xdata), self.sequence) )
try:
self.sock.sendall(polybytes(xdata))
except socket.error:
@@ -1199,16 +1202,18 @@ class ControlSession:
self.doquery(opcode=ntp.control.CTL_OP_REQ_NONCE)
self.nonce_xmit = time.time()
if not self.response.startswith(polybytes("nonce=")):
+ print("## Nonce expected: %s" % self.response)
raise ControlException(SERR_BADNONCE)
return polystr(self.response.strip())
- def mrulist(self, variables=None, rawhook=None, recent=None):
+ def mrulist(self, variables=None, rawhook=None, direct=None):
"Retrieve MRU list data"
restarted_count = 0
cap_frags = True
warn = self.logfp.write
sorter = None
frags = MAXFRAGS
+ self.slots = 0
if variables is None:
variables = {}
@@ -1217,6 +1222,9 @@ class ControlSession:
sortkey = variables["sort"]
del variables["sort"]
# FIXME: implement sorting by address, in case anyone cares
+ # Slots are printed in reverse order so this is backwards.
+ # That avoids a sort in the normal case.
+ # Note lstint is backwards since we really sort on now-last
sortdict = {
"lstint" : lambda e: e.last, # lstint ascending
"-lstint" : lambda e: -e.last, # lstint descending
@@ -1227,7 +1235,7 @@ class ControlSession:
"count" : lambda e: -e.ct, # hit count ascending
"-count": lambda e: e.ct, # hit count descending
}
- if sortkey == "listint":
+ if sortkey == "lstint":
sortkey = None
if sortkey is not None:
sorter = sortdict.get(sortkey)
@@ -1336,11 +1344,11 @@ class ControlSession:
elif tag == "addr.older":
continue
if tag == "now":
- # Don't see this in debug output, Hal, 2016-Dec-19
+ # finished marker
span.now = ntp.ntpc.lfptofloat(val)
continue
elif tag == "last.newest":
- # Don't see this in debug output, Hal, 2016-Dec-19
+ # more finished
continue
for prefix in ("addr", "last", "first", "ct", "mv", "rs"):
if tag.startswith(prefix + "."):
@@ -1354,7 +1362,10 @@ class ControlSession:
curidx = idx
mru = MRUEntry()
span.entries.append(mru)
+ self.slots += 1
setattr(mru, prefix, val)
+ if direct != None:
+ direct(span.entries)
# If we've seen the end sentinel on the span, break out
if span.is_complete():
@@ -1362,7 +1373,7 @@ class ControlSession:
# Snooze for a bit between queries to let ntpd catch
# up with other duties.
- time.sleep(0.05)
+ ## time.sleep(0.05)
# If there were no errors, increase the number of rows
# to a maximum of 3 * MAXFRAGS (the most packets ntpq
@@ -1395,6 +1406,8 @@ class ControlSession:
break
else:
req_buf += incr
+ if direct != None:
+ span.entries = []
except KeyboardInterrupt:
pass # We can test for interruption with is_complete()
=====================================
pylib/util.py
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py
@@ -485,7 +485,14 @@ class MRUSummary:
def summary(self, entry):
last = ntp.ntpc.lfptofloat(entry.last)
- lstint = int(self.now - last + 0.5)
+ if self.now:
+ lstint = int(self.now - last + 0.5)
+ else:
+ # direct mode doesn't have a reference time
+ # use seconds this day
+ days = int(last) / 86400
+ seconds = last - days*86400
+ lstint = int(seconds)
first = ntp.ntpc.lfptofloat(entry.first)
active = float(last - first)
favgint = active / entry.ct # FIXME should be ct-1
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/ae4152b84887f0027eb34acf8241aac7bad9f6f6...29b69e26e04287a3c8716e1381e5f70e150582a2
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20161222/c139d403/attachment.html>
More information about the vc
mailing list