diff options
author | roberto <roberto@FreeBSD.org> | 2000-01-28 14:55:50 +0000 |
---|---|---|
committer | roberto <roberto@FreeBSD.org> | 2000-01-28 14:55:50 +0000 |
commit | b5b40f9e420899251189775800d9f74092925299 (patch) | |
tree | 98efdf1b74d6ecb7828bb502a0350116eeb2fd3c /contrib/ntp/scripts | |
parent | ef64b99e8412f2273dd2e8b3291c2f78ffc4667f (diff) | |
download | FreeBSD-src-b5b40f9e420899251189775800d9f74092925299.zip FreeBSD-src-b5b40f9e420899251189775800d9f74092925299.tar.gz |
Virgin import of ntpd 4.0.99b
Diffstat (limited to 'contrib/ntp/scripts')
-rw-r--r-- | contrib/ntp/scripts/Makefile.in | 14 | ||||
-rw-r--r-- | contrib/ntp/scripts/README | 7 | ||||
-rwxr-xr-x | contrib/ntp/scripts/freq_adj | 97 | ||||
-rwxr-xr-x | contrib/ntp/scripts/ntp-status | 45 | ||||
-rwxr-xr-x | contrib/ntp/scripts/ntpsweep | 301 | ||||
-rwxr-xr-x | contrib/ntp/scripts/plot_summary.pl | 36 | ||||
-rw-r--r-- | contrib/ntp/scripts/summary.pl | 74 |
7 files changed, 522 insertions, 52 deletions
diff --git a/contrib/ntp/scripts/Makefile.in b/contrib/ntp/scripts/Makefile.in index 008640b..bc662fb 100644 --- a/contrib/ntp/scripts/Makefile.in +++ b/contrib/ntp/scripts/Makefile.in @@ -63,15 +63,18 @@ host_alias = @host_alias@ host_triplet = @host@ target_alias = @target_alias@ target_triplet = @target@ +AMDEP = @AMDEP@ AMTAR = @AMTAR@ -AMTARFLAGS = @AMTARFLAGS@ AWK = @AWK@ CC = @CC@ CFLAGS = @CFLAGS@ CHUTEST = @CHUTEST@ CLKTEST = @CLKTEST@ CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ DCFD = @DCFD@ +DEPDIR = @DEPDIR@ LDFLAGS = @LDFLAGS@ LIBPARSE = @LIBPARSE@ LIBRSAREF = @LIBRSAREF@ @@ -93,6 +96,7 @@ RSAREF = @RSAREF@ TESTDCF = @TESTDCF@ U = @U@ VERSION = @VERSION@ +install_sh = @install_sh@ noinst_SCRIPTS = mkver ntpver @@ -129,15 +133,10 @@ TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu scripts/Makefile @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ + cp -pR $$d/$$file $(distdir); \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ @@ -179,6 +178,7 @@ distclean-generic: -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: + -rm -f Makefile.in mostlyclean-am: mostlyclean-generic mostlyclean: mostlyclean-am diff --git a/contrib/ntp/scripts/README b/contrib/ntp/scripts/README index 37442f1..9e29467 100644 --- a/contrib/ntp/scripts/README +++ b/contrib/ntp/scripts/README @@ -6,6 +6,9 @@ files in the parent directory for directions on how to use these files. calc_tickadj Calculates "optimal" value for tick given ntp.drift file +freq_adj Calculates and optionally sets the clock frequency + based on ntp.drift . For FreeBSD systems. + mkver.in script to create new version numbers for all sources monitoring directory containing perl scripts useful for monitoring @@ -20,6 +23,10 @@ ntp-groper script useful for reaching out and rattling the cages of ntp-restart script useful for killing and restarting the NTP daemon +ntpsweep prints per host given in <file> the NTP stratum level, the + clock offset in seconds, the daemon version, the operating + system and the processor. + ntpver What version of the NTP daemon is running? stats directory containing awk and shell scripts useful for diff --git a/contrib/ntp/scripts/freq_adj b/contrib/ntp/scripts/freq_adj new file mode 100755 index 0000000..4af4316 --- /dev/null +++ b/contrib/ntp/scripts/freq_adj @@ -0,0 +1,97 @@ +#! /usr/bin/perl -w + +die "perl5 needed\n" unless ($] > 5); + +use Getopt::Std; +use vars qw($opt_n); + +getopts('d:nt:'); + +#chop($ncpu = `sysctl -n hw.ncpu`); +#die "Found $ncpu CPUs; can only be run on systems with 1 CPU.\n" if ($ncpu > 1); + +$driftfile = "/etc/ntp.drift"; +$driftfile = $opt_d if defined($opt_d); + +chop($timer = `sysctl -n kern.timecounter.hardware 2> /dev/null`); + +$timer =~ tr/\U/\L/; + +if ($timer eq '') { + open(DM, "/var/run/dmesg.boot"); + while(<DM>) { + # Timecounter "i8254" frequency 1193182 Hz + if (/^Timecounter "(\w+)"\s+/) { + $timer = $1; + last; + } + } + close(DM); +} + +$opt_t = $timer if !defined($opt_t); + +if ($timer ne '') { # $timer found... + if ($opt_t ne '') { # - and $opt_t found + if ($timer ne $opt_t) { # - - and they differ + warn "You specified a $opt_t timer but I detected a $timer timer.\n"; + usage(); + exit 1; + } else { # - - and they are the same + ; + } + } else { # - but no $opt_t specified; this is OK + ; + } +} else { # No $timer found... + if ($opt_t ne '') { # - but $opt_t was specified + $timer = $opt_t; # - - so use it. + } else { # - and neither was $opt_t + warn "I can't tell what timer you have. Please specify one.\n"; + usage(); + exit 1; + } +} + +open(DF, $driftfile) || die "Can't open driftfile ($driftfile): $!\n"; +while(<DF>) { + chop; + if (/^(-?\d+\.\d+)(\s\d)?$/) { + $drift = $1; + } else { + die "Bogus value in driftfile $driftfile: <$_>\n"; + } +} +close(DF); + +print "NTP drift is <$drift>\n"; + +# Convert from NTP's idea of PPM to a decimal equivalent +$freq_adj = int ( $drift * ( 10 ** 6 / 2 ** 20) ); +print "normalized freq_adj is <$freq_adj>\n"; + +$freq_adj = int ( ( $freq_adj - 1 ) / 2 ); +print "Applying freq_adj of <".-$freq_adj.">\n"; + +$sysctl = "machdep.".$timer."_freq"; + +chop($mach_freq = `sysctl -n $sysctl`); + +print "$sysctl is <$mach_freq>\n"; + +$n_mach_freq = $mach_freq - $freq_adj; + +if (defined($opt_n)) { + print "$sysctl $mach_freq -> $n_mach_freq\n"; +} else { + print "i8254: ".`sysctl -w $sysctl=$n_mach_freq`; +} + +sub usage { + print STDERR <<EOUsage +Usage: $0 [-d drift_file] [-n] [-t timer] +where "drift_file" defaults to /etc/ntp.drift +and "timer" is usually "tsc" or "i8254" +and "-n" says "don't really change anything, just say what would happen". +EOUsage +} diff --git a/contrib/ntp/scripts/ntp-status b/contrib/ntp/scripts/ntp-status new file mode 100755 index 0000000..4109124 --- /dev/null +++ b/contrib/ntp/scripts/ntp-status @@ -0,0 +1,45 @@ +#!/bin/sh + +# From: Marc Brett <Marc.Brett@westgeo.com> + +# Here's a quick hack which can give you the stratum, delay, offset +# for any number of ntp servers. + +NTPDATE=/usr/local/bin/ntpdate +NSLOOKUP=/usr/sbin/nslookup +EGREP=/bin/egrep +AWK=/bin/awk +RM=/bin/rm +FILE=/tmp/ntp.$$ + +USAGE="Usage: $0 hostname [hostname ...]" + +if [ $# -le 0 ] +then + echo $USAGE 2>&1 + exit 1 +fi + +trap '$RM -f $FILE; exit' 1 2 3 4 13 15 + +for HOST in $* +do + HOSTNAME=`$NSLOOKUP $HOST | $EGREP "Name:" | $AWK '{print $2}'` + if [ -n "$HOSTNAME" ] + then + $NTPDATE -d $HOST 2>/dev/null | $EGREP '^stratum|^delay|^offset|^originate' > $FILE + STRATUM=`$EGREP '^stratum' $FILE | $AWK '{print $2}'` + OFFSET=`$EGREP '^offset' $FILE | $AWK '{print $2}'` + DELAY=`$EGREP '^delay' $FILE | $AWK '{print $2}'` + TIMESTAMP=`$EGREP '^originate' $FILE | $AWK '{print $4 " " $5 " " $6 " " $7 " " $8}'` + if [ "$STRATUM" -ne 0 ] + then + echo "$HOSTNAME: stratum:$STRATUM delay:$DELAY offset:$OFFSET $TIMESTAMP" + else + echo $HOSTNAME: Not running NTP + fi + fi + +done + +$RM -f $FILE diff --git a/contrib/ntp/scripts/ntpsweep b/contrib/ntp/scripts/ntpsweep new file mode 100755 index 0000000..ab2e884 --- /dev/null +++ b/contrib/ntp/scripts/ntpsweep @@ -0,0 +1,301 @@ +#!/usr/local/bin/perl -w +# +# $Id: ntpsweep,v 1.3 2000/01/15 07:37:52 stenn Exp $ +# +# DISCLAIMER +# +# Copyright (C) 1999,2000 Hans Lambermont and Origin B.V. +# +# Permission to use, copy, modify and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appears in all copies and +# that both the copyright notice and this permission notice appear in +# supporting documentation. This software is supported as is and without +# any express or implied warranties, including, without limitation, the +# implied warranties of merchantability and fitness for a particular +# purpose. The name Origin B.V. must not be used to endorse or promote +# products derived from this software without prior written permission. +# +# Hans Lambermont <Hans.Lambermont@nl.origin-it.com>/<H.Lambermont@chello.nl> +# 14 Jan 2000 + +require 5.0; # But actually tested on 5.004 ;) +use Getopt::Long; # GetOptions() +use strict; + +my $version = 1.3; +(my $program = $0) =~ s%.*/(.+?)(.pl)?$%$1%; + +# Hardcoded paths/program names +my $ntpdate = "ntpdate"; +my $ntpq = "ntpq"; + +# no STDOUT buffering +$| = 1; + +my ($help, $single_host, $showpeers, $maxlevel, $strip, $askversion); +my $res = GetOptions("help!" => \$help, + "host=s" => \$single_host, + "peers!" => \$showpeers, + "maxlevel=s" => \$maxlevel, + "strip=s" => \$strip, + "version!" => \$askversion); + +if ($askversion) { + print("$version\n"); + exit 0; +} + +if ($help || ((@ARGV != 1) && !$single_host)) { + warn <<EOF; +This is $program, version $version +Copyright (C) 1999,2000 Hans Lambermont and Origin B.V. Disclaimer inside. + +Usage: + $program [--help|--peers|--strip <string>|--maxlevel <level>|--version] \\ + <file>|[--host <hostname>] + +Description: + $program prints per host given in <file> the NTP stratum level, the + clock offset in seconds, the daemon version, the operating system and + the processor. Optionally recursing through all peers. + +Options: +--help + Print this short help text and exit. +--version + Print version ($version) and exit. +<file> + Specify hosts file. File format is one hostname or ip number per line. + Lines beginning with # are considered as comment. +--host <hostname> + Speficy a single host, bypassing the need for a hosts file. +--peers + Recursively list all peers a host synchronizes to. + An '= ' before a peer means a loop. Recursion stops here. +--maxlevel <level> + Traverse peers up to this level (4 is a reasonable number). +--strip <string> + Strip <string> from hostnames. + +Examples: + $program myhosts.txt --strip .foo.com + $program --host some.host --peers --maxlevel 4 +EOF + exit 1; +} + +my $hostsfile = shift; +my (@hosts, @known_hosts); +my (%known_host_info, %known_host_peers); + +sub read_hosts() +{ + local *HOSTS; + open (HOSTS, $hostsfile) || + die "$program: FATAL: unable to read $hostsfile: $!\n"; + while (<HOSTS>) { + next if /^\s*(#|$)/; # comment/empty + chomp; + push(@hosts, $_); + } + close(HOSTS); +} + +# translate IP to hostname if possible +sub ip2name { + my($ip) = @_; + my($addr, $name, $aliases, $addrtype, $length, @addrs); + $addr = pack('C4', split(/\./, $ip)); + ($name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($addr, 2); + if ($name) { + # return lower case name + return("\L$name"); + } else { + return($ip); + } +} + +# item_in_list($item, @list): returns 1 if $item is in @list, 0 if not +sub item_in_list { + my($item, @list) = @_; + my($i); + foreach $i (@list) { + return 1 if ($item eq $i); + } + return 0; +} + +sub scan_host($;$;$) { + my($host, $level, @trace) = @_; + my $stratum = 0; + my $offset = 0; + my $daemonversion = ""; + my $system = ""; + my $processor = ""; + my @peers; + my $known_host = 0; + + if (&item_in_list($host, @known_hosts)) { + $known_host = 1; + } else { + # ntpdate part + open(NTPDATE, "$ntpdate -bd $host 2>/dev/null |") || + die "Cannot open ntpdate pipe: $!\n"; + while (<NTPDATE>) { + /^stratum\s+(\d+).*$/ && do { + $stratum = $1; + }; + /^offset\s+([0-9.-]+)$/ && do { + $offset = $1; + }; + } + close(NTPDATE); + + # got answers ? If so, go on. + if ($stratum) { + # ntpq part + my $ntpqparams = "-c 'rv 0 processor,system,daemon_version'"; + open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") || + die "Cannot open ntpq pipe: $!\n"; + while (<NTPQ>) { + /daemon_version="(.*)"/ && do { + $daemonversion = $1; + }; + /system="([^"]*)"/ && do { + $system = $1; + }; + /processor="([^"]*)"/ && do { + $processor = $1; + }; + } + close(NTPQ); + + # Shorten daemon_version string. + $daemonversion =~ s/(;|Mon|Tue|Wed|Thu|Fri|Sat|Sun).*$//; + $daemonversion =~ s/version=//; + $daemonversion =~ s/(x|)ntpd //; + $daemonversion =~ s/(\(|\))//g; + $daemonversion =~ s/beta/b/; + $daemonversion =~ s/multicast/mc/; + + # Shorten system string + $system =~ s/UNIX\///; + $system =~ s/RELEASE/r/; + $system =~ s/CURRENT/c/; + + # Shorten processor string + $processor =~ s/unknown//; + } + + # got answers ? If so, go on. + if ($daemonversion) { + # ntpq again, find out the peers this time + if ($showpeers) { + my $ntpqparams = "-pn"; + open(NTPQ, "$ntpq $ntpqparams $host 2>/dev/null |") || + die "Cannot open ntpq pipe: $!\n"; + while (<NTPQ>) { + /^No association ID's returned$/ && do { + last; + }; + /^ remote/ && do { + next; + }; + /^==/ && do { + next; + }; + /^( |x|\.|-|\+|#|\*|o)([^ ]+)/ && do { + push(@peers, ip2name($2)); + next; + }; + print "ERROR: $_"; + } + close(NTPQ); + } + } + + # Add scanned host to known_hosts array + push(@known_hosts, $host); + if ($stratum) { + $known_host_info{$host} = sprintf("%2d %9.3f %-11s %-12s %s", + $stratum, $offset, substr($daemonversion,0,11), + substr($system,0,12), substr($processor,0,9)); + } else { + # Stratum level 0 is consider invalid + $known_host_info{$host} = sprintf(" ?"); + } + $known_host_peers{$host} = [@peers]; + } + + if ($stratum || $known_host) { # Valid or known host + my $printhost = ' ' x $level . $host; + # Shorten host string + if ($strip) { + $printhost =~ s/$strip//; + } + # append number of peers in brackets if requested and valid + if ($showpeers && ($known_host_info{$host} ne " ?")) { + $printhost .= " (" . @{$known_host_peers{$host}} . ")"; + } + # Finally print complete host line + printf("%-32s %s\n", + substr($printhost,0,32), $known_host_info{$host}); + if ($showpeers && (eval($maxlevel ? $level < $maxlevel : 1))) { + my $peer; + push(@trace, $host); + # Loop through peers + foreach $peer (@{$known_host_peers{$host}}) { + if (&item_in_list($peer, @trace)) { + # we've detected a loop ! + $printhost = ' ' x ($level + 1) . "= " . $peer; + # Shorten host string + if ($strip) { + $printhost =~ s/$strip//; + } + printf("%-32s %s\n", + substr($printhost,0,32)); + } else { + if (substr($peer,0,3) ne "127") { + &scan_host($peer, $level + 1, @trace); + } + } + } + } + } else { # We did not get answers from this host + my $printhost = ' ' x $level . $host; + # Shorten host string + if ($strip) { + $printhost =~ s/$strip//; + } + printf("%-32s ?\n", substr($printhost,0,32)); + } +} + +sub scan_hosts() +{ + my $host; + for $host (@hosts) { + my @trace; + push(@trace, $host); + scan_host($host, 0, @trace); + } +} + +# Main program + +if ($single_host) { + push(@hosts, $single_host); +} else { + &read_hosts($hostsfile); +} + +# Print header +print <<EOF; +Host st offset(s) version system processor +--------------------------------+--+---------+-----------+------------+--------- +EOF + +&scan_hosts(); + +exit 0; diff --git a/contrib/ntp/scripts/plot_summary.pl b/contrib/ntp/scripts/plot_summary.pl index 5be0182..b0e9a4a 100755 --- a/contrib/ntp/scripts/plot_summary.pl +++ b/contrib/ntp/scripts/plot_summary.pl @@ -1,10 +1,10 @@ #!/usr/bin/perl -w -# $Id: plot_summary.pl,v 1.1.1.1 1999/05/26 00:48:25 stenn Exp $ +# $Id: plot_summary.pl,v 1.2 1999/12/02 01:59:05 stenn Exp $ # # Use Gnuplot to display data in summary files produced by summary.pl. -# This script requires GNUPLOT 3.6 (pre 3.6 beta 319)! +# This script requires GNUPLOT 3.7! # -# Copyright (c) 1997, Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> +# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ use Getopt::Long; # parse command line my $summary_dir = "/tmp"; -my $identifier = `hostname`; # origin of these data +my $identifier = "host " . `hostname`; # origin of these data chomp $identifier; # remove newline my $offset_limit = 0.128; # limit of absolute offset my $output_file = ""; # output file defaults to stdout @@ -37,24 +37,27 @@ my $gnuplot_terminal = $ENV{DISPLAY} ? "x11" : "dumb"; my $wait_after_plot = 1; my @peer_list = (); -my %options = ("directory=s" => \$summary_dir, +my %options = ("directory|input-directory=s" => \$summary_dir, "identifier=s" => \$identifier, "offset-limit=f" => \$offset_limit, "output-file=s" => \$output_file, "peer=s@" => \@peer_list, - "plot-term=s" => \$gnuplot_terminal, + "plot-term|gnuplot-term=s" => \$gnuplot_terminal, "wait-after-plot!" => \$wait_after_plot, ); -if ( !GetOptions(%options) ) { - print STDERR "usage: $0\n"; + +if ( !GetOptions(%options) ) +{ + print STDERR "valid options for $0 are:\n"; my $opt; foreach $opt (sort(keys %options)) { - print STDERR "\t--$opt "; + print STDERR "\t--$opt\t(default is "; if ( ref($options{$opt}) eq "ARRAY" ) { - print STDERR "(" . join (" ", @{$options{$opt}}) . ")\n"; + print STDERR join(", ", map { "'$_'" } @{$options{$opt}}); } else { - print STDERR "(${$options{$opt}})\n"; - } + print STDERR "'${$options{$opt}}'"; + } + print STDERR ")\n"; } print STDERR "\n"; die; @@ -120,7 +123,7 @@ sub do_loop # loops.19960405 $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/; m/(\d{4})(\d{2})(\d{2})/; - $line = timegm (59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0); + $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0); $line = int $line / 86400; # days relative to 1970 $first_day = "$1-$2-$3 ($line)" unless $day_out; next; @@ -163,6 +166,7 @@ sub do_loop } else { $ylimit = "[] $ylimit]"; } +# build command file for GNUplot open OUTPUT, "> $cmd_file" or die "$cmd_file: $!"; my $oldfh = select OUTPUT; print "set term $gnuplot_terminal\n"; @@ -199,7 +203,7 @@ sub do_loop print "set nomultiplot\n"; maybe_add_pause; - my $ylimit = "["; + $ylimit = "["; if ($min_rms < -$offset_limit) { $ylimit .= "-$offset_limit"; } @@ -208,7 +212,7 @@ sub do_loop $ylimit .= "$offset_limit"; } if ( $ylimit eq "[:" ) { - $ylimit = ""; + $ylimit =""; } else { $ylimit = "[] $ylimit]"; } @@ -261,7 +265,7 @@ sub do_peer # peers.19960405 $_ = $Fld[0]; s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/; m/(\d{4})(\d{2})(\d{2})/ or next; - $line = timegm (59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0); + $line = timegm(59, 59, 23, $3, $2 - 1, $1 - 1900, 0, 0, 0); $line = int $line / 86400; # days relative to 1970 $first_day = "$1-$2-$3 ($line)" unless $day_out; next; diff --git a/contrib/ntp/scripts/summary.pl b/contrib/ntp/scripts/summary.pl index c9deda9..7145579 100644 --- a/contrib/ntp/scripts/summary.pl +++ b/contrib/ntp/scripts/summary.pl @@ -1,9 +1,9 @@ #!/usr/bin/perl -w -# $Id: summary.pl,v 1.1.1.1 1999/05/26 00:48:25 stenn Exp $ +# $Id: summary.pl,v 1.2 1999/12/02 01:59:07 stenn Exp $ # Perl version of (summary.sh, loop.awk, peer.awk): # Create summaries from xntpd's loop and peer statistics. # -# Copyright (c) 1997, Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> +# Copyright (c) 1997, 1999 by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,13 +24,16 @@ use strict; use Getopt::Long; -my $statsdir = "."; +my $log_date_pattern = '[12]\d{3}[01]\d[0-3]\d'; +my $statsdir = "/var/log/ntp"; # directory with input files +my $outputdir = "/tmp"; # directory for output files my $skip_time_steps = 3600.0; # ignore time offsets larger that this -my $startdate = "19700101"; # first data file to use +my $startdate = "19700101"; # first data file to use (YYYYMMDD) my $enddate=`date -u +%Y%m%d`; chomp $enddate; --$enddate; my $peer_dist_limit = 400.0; -my %options = ("directory=s" => \$statsdir, +my %options = ("directory|input-directory=s" => \$statsdir, + "output-directory=s" => \$outputdir, "skip-time-steps:f" => \$skip_time_steps, "start-date=s" => \$startdate, "end-date=s" => \$enddate, @@ -41,24 +44,27 @@ if ( !GetOptions(%options) ) print STDERR "valid options for $0 are:\n"; my $opt; foreach $opt (sort(keys %options)) { - print STDERR "\t--$opt "; + print STDERR "\t--$opt\t(default is "; if ( ref($options{$opt}) eq "ARRAY" ) { - print STDERR "(" . join (" ", @{$options{$opt}}) . ")\n"; + print STDERR join(", ", map { "'$_'" } @{$options{$opt}}); } else { - print STDERR "(${$options{$opt}})\n"; - } + print STDERR "'${$options{$opt}}'"; + } + print STDERR ")\n"; } print STDERR "\n"; die; } +# check possibly current values of options die "$statsdir: no such directory" unless (-d $statsdir); +die "$outputdir: no such directory" unless (-d $outputdir); die "$skip_time_steps: skip-time-steps must be positive" unless ($skip_time_steps >= 0.0); -die "$startdate: invalid start date" - unless ($startdate =~ m/.*([12]\d{3}[01]\d[0-3]\d)$/); +die "$startdate: invalid start date|$`|$&|$'" + unless ($startdate =~ m/.*$log_date_pattern$/); die "$enddate: invalid end date" - unless ($enddate =~ m/.*([12]\d{3}[01]\d[0-3]\d)$/); + unless ($enddate =~ m/.*$log_date_pattern$/); $skip_time_steps = 0.128 if ($skip_time_steps == 0); @@ -81,7 +87,7 @@ sub do_loop { my ($directory, $fname, $out_file) = @_; print "$directory/$fname\n"; - open INPUT, "$directory/$fname"; + open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!"; open OUTPUT, ">>$out_file" or die "can't open $out_file: $!"; print OUTPUT "$fname\n"; my ($loop_tmax, $loop_fmax) = (-1e9, -1e9); @@ -96,7 +102,10 @@ sub do_loop chop; # strip record separator @Fld = split; next if ($#Fld < 4); -# 50529 74356.259 -0.000112 16.1230 8 +#NTPv3: 50529 74356.259 -0.000112 16.1230 8 +#NTPv3: day, sec.msec, offset, drift_comp, sys_poll +#NTPv4: 51333 54734.582 0.000001648 16.981964 0.000001094 0.020938 6 +#NTPv4: day, sec.msec, offset, drift_comp, sys_error, clock_stabil, sys_poll if ($Fld[2] > $skip_time_steps || $Fld[2] < -$skip_time_steps) { warn "ignoring loop offset $Fld[2] (file $fname, line $.)\n"; next @@ -147,7 +156,7 @@ sub do_peer { my ($directory, $fname, $out_file) = @_; print "$directory/$fname\n"; - open INPUT, "$directory/$fname"; + open INPUT, "$directory/$fname" or warn "can't open $directory/$fname: $!"; open OUTPUT, ">>$out_file" or die "can't open $out_file: $!"; print OUTPUT "$fname\n"; # we toss out all distances greater than one second on the assumption the @@ -169,7 +178,11 @@ sub do_peer chop; # strip record separator @Fld = split; next if ($#Fld < 6); -# 50529 83316.249 127.127.8.1 9674 0.008628 0.00000 0.00700 +#NTPv3: 50529 83316.249 127.127.8.1 9674 0.008628 0.00000 0.00700 +#NTPv3: day, sec.msec, addr, status, offset, delay, dispersion +#NTPv4: 51333 56042.037 127.127.8.1 94f5 -0.000014657 0.000000000 0.000000000 0.000013214 +#NTPv4: day, sec.msec, addr, status, offset, delay, dispersion, skew + $dist = $Fld[6] + $Fld[5] / 2; next if ($dist > $MAXDISTANCE); $offs = $Fld[4]; @@ -211,8 +224,9 @@ sub do_peer for ($i = 0; $i < $n; $i++) { next if $peer_count{$i} < 2; $peer_time{$i} /= $peer_count{$i}; - $peer_time_rms{$i} = sqrt($peer_time_rms{$i} / $peer_count{$i} - - $peer_time{$i} * $peer_time{$i}); + eval { $peer_time_rms{$i} = sqrt($peer_time_rms{$i} / $peer_count{$i} - + $peer_time{$i} * $peer_time{$i}); }; + $peer_time_rms{$i} = 0, warn $@ if $@; $peer_delay{$i} /= $peer_count{$i}; $peer_disp{$i} /= $peer_count{$i}; $peer_tmax{$i} = $peer_tmax{$i} - $peer_time{$i}; @@ -303,8 +317,9 @@ sub peer_summary for ($i = 0; $i < $n; $i++) { next if ($peer_count{$i} < 2); $peer_mean{$i} /= $peer_count{$i}; - $peer_var{$i} = sqrt($peer_var{$i} / $peer_count{$i} - - $peer_mean{$i} * $peer_mean{$i}); + eval { $peer_var{$i} = sqrt($peer_var{$i} / $peer_count{$i} - + $peer_mean{$i} * $peer_mean{$i}); }; + $peer_var{$i} = 0, warn $@ if $@; push @lines, sprintf "%-15s %3d %9.3f% 9.3f %9.3f %3d %3d %3d %3d\n", $peer_ident{$i}, $peer_count{$i}, $peer_mean{$i}, $peer_var{$i}, @@ -313,41 +328,42 @@ sub peer_summary print sort @lines; } -my $loop_summary="/tmp/loop_summary"; -my $peer_summary="/tmp/peer_summary"; -my $clock_summary="/tmp/clock_summary"; +my $loop_summary="$outputdir/loop_summary"; +my $peer_summary="$outputdir/peer_summary"; +my $clock_summary="$outputdir/clock_summary"; my (@loopfiles, @peerfiles, @clockfiles); print STDERR "Creating summaries from $statsdir ($startdate to $enddate)\n"; opendir SDIR, $statsdir or die "directory ${statsdir}: $!"; rewinddir SDIR; -@loopfiles=sort grep /loop.*[12]\d{3}[01]\d[0-3]\d/, readdir SDIR; +@loopfiles=sort grep /loop.*$log_date_pattern/, readdir SDIR; rewinddir SDIR; -@peerfiles=sort grep /peer.*[12]\d{3}[01]\d[0-3]\d/, readdir SDIR; +@peerfiles=sort grep /peer.*$log_date_pattern/, readdir SDIR; rewinddir SDIR; -@clockfiles=sort grep /clock.*[12]\d{3}[01]\d[0-3]\d/, readdir SDIR; +@clockfiles=sort grep /clock.*$log_date_pattern/, readdir SDIR; closedir SDIR; +# remove old summary files map { unlink $_ if -f $_ } ($loop_summary, $peer_summary, $clock_summary); my $date; map { - $date = $_; $date =~ s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/; + $date = $_; $date =~ s/.*($log_date_pattern)$/$1/; if ($date ge $startdate && $date le $enddate) { do_loop $statsdir, $_, $loop_summary; } } @loopfiles; map { - $date = $_; $date =~ s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/; + $date = $_; $date =~ s/.*($log_date_pattern)$/$1/; if ($date ge $startdate && $date le $enddate) { do_peer $statsdir, $_, $peer_summary; } } @peerfiles; map { - $date = $_; $date =~ s/.*([12]\d{3}[01]\d[0-3]\d)$/$1/; + $date = $_; $date =~ s/.*($log_date_pattern)$/$1/; if ($date ge $startdate && $date le $enddate) { do_clock $statsdir, $_, $clock_summary; } |