|
Packit |
9c3e7e |
Clock and Network Simulator (clknetsim)
|
|
Packit |
9c3e7e |
=======================================
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
clknetsim is a tool designed to test programs which synchronize the system
|
|
Packit |
9c3e7e |
clock, either over network or from a hardware reference clock. It simulates a
|
|
Packit |
9c3e7e |
system or a number of systems connected to each other in a network and the
|
|
Packit |
9c3e7e |
tested programs discipline the simulated system clocks. It can be used to
|
|
Packit |
9c3e7e |
quickly test how well the programs control the system clocks in various
|
|
Packit |
9c3e7e |
conditions or to test the network protocols.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The tested programs are not modified in order to be included in the simulation,
|
|
Packit |
9c3e7e |
but they have some system calls redirected by a clknetsim library, which is
|
|
Packit |
9c3e7e |
loaded by the LD_PRELOAD feature of the dynamic linker, to a clknetsim server,
|
|
Packit |
9c3e7e |
which runs the simulation and collects several statistics about each client.
|
|
Packit |
9c3e7e |
The server and the clients run on a single host, they communicate via a UNIX
|
|
Packit |
9c3e7e |
domain socket. The simulation runs as fast as the host system is capable of,
|
|
Packit |
9c3e7e |
with two simulated systems it is usually three or four orders of magnitude
|
|
Packit |
9c3e7e |
faster than real time.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Supported programs:
|
|
Packit |
9c3e7e |
- chronyd and chronyc from chrony (http://chrony.tuxfamily.org/)
|
|
Packit |
9c3e7e |
- ntpd, ntpdate, sntp and ntpq from ntp (http://www.ntp.org/)
|
|
Packit |
9c3e7e |
- ntpd from busybox (http://www.busybox.net/)
|
|
Packit |
9c3e7e |
- ptp4l, phc2sys, pmc and nsm from linuxptp (http://linuxptp.sourceforge.net/)
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Limitations:
|
|
Packit |
9c3e7e |
- only Linux is supported
|
|
Packit |
9c3e7e |
- the fake system calls implement only a minimal functionality required to
|
|
Packit |
9c3e7e |
keep the supported clients working
|
|
Packit |
9c3e7e |
- the simulated system clock advances only on select(), poll() or usleep()
|
|
Packit |
9c3e7e |
calls, this means the client sees the CPU as infinitely fast
|
|
Packit |
9c3e7e |
- adjtimex() frequency and tick changes happen immediately, the kernel has
|
|
Packit |
9c3e7e |
infinite HZ
|
|
Packit |
9c3e7e |
- adjtime() and PLL updates happen in one second intervals in the simulated
|
|
Packit |
9c3e7e |
time instead of the uncorrected simulated system time, all clocks are updated
|
|
Packit |
9c3e7e |
at the same time
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Usage
|
|
Packit |
9c3e7e |
-----
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The clknetsim server is started with two required arguments, the first one is
|
|
Packit |
9c3e7e |
path to a configuration file describing the network and clocks and the second
|
|
Packit |
9c3e7e |
argument is the number of simulated nodes. The simulation is started when all
|
|
Packit |
9c3e7e |
clients are connected.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The clients are started under a non-root user, with preloaded clknetsim.so and
|
|
Packit |
9c3e7e |
the environment variable CLKNETSIM_NODE set to the number of the client.
|
|
Packit |
9c3e7e |
Optionally, the environment variable CLKNETSIM_SOCKET can be set to the path of
|
|
Packit |
9c3e7e |
the UNIX domain socket which is used to connect to the server, clknetsim.sock
|
|
Packit |
9c3e7e |
in current directory is used by default. The CLKNETSIM_START_DATE variable can
|
|
Packit |
9c3e7e |
be used to specify in seconds since 1970 when should the simulated time start,
|
|
Packit |
9c3e7e |
1262304000 by default (2010-01-01 0:00 UTC). The CLKNETSIM_CONNECT_TIMEOUT
|
|
Packit |
9c3e7e |
variable sets the server connection timeout, 10 seconds by default.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The simulated network is available to the clients as one or more Ethernet
|
|
Packit |
9c3e7e |
networks with IPv4 addressing. All nodes have interfaces to all networks.
|
|
Packit |
9c3e7e |
Their addresses are 192.168.122+s.n, where n is the number of the node
|
|
Packit |
9c3e7e |
(starting at 1) and s is the number of the network (starting at 1). The
|
|
Packit |
9c3e7e |
broadcast addresses are 192.168.122+s.255.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
At the end of the simulation clock and network statistics are printed.
|
|
Packit |
9c3e7e |
clknetsim has options which can be used to control for how long the
|
|
Packit |
9c3e7e |
simulation should run, or if the frequency, offset or network log should be
|
|
Packit |
9c3e7e |
written. clknetsim -h prints a complete list of available options.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
A minimal example how to start a simulation:
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
$ LD_PRELOAD=./clknetsim.so CLKNETSIM_NODE=1 chronyd -d -f chrony.conf &
|
|
Packit |
9c3e7e |
$ LD_PRELOAD=./clknetsim.so CLKNETSIM_NODE=2 ntpd -n -c ntp.conf &
|
|
Packit |
9c3e7e |
$ ./clknetsim -o log.offset -l 100000 clknetsim.conf 2
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
clknetsim.conf:
|
|
Packit |
9c3e7e |
node2_freq = (sum (* 1e-8 (normal)))
|
|
Packit |
9c3e7e |
node1_delay2 = (+ 1e-1 (* 1e-3 (exponential)))
|
|
Packit |
9c3e7e |
node2_delay1 = (+ 1e-1 (* 1e-3 (exponential)))
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
chrony.conf:
|
|
Packit |
9c3e7e |
pidfile chronyd.pid
|
|
Packit |
9c3e7e |
local stratum 1
|
|
Packit |
9c3e7e |
allow
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
ntp.conf:
|
|
Packit |
9c3e7e |
pidfile ntpd.pid
|
|
Packit |
9c3e7e |
server 192.168.123.1
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The clknetsim.bash file contains bash functions which can create the
|
|
Packit |
9c3e7e |
configuration in several network settings, start the simulation, stop the
|
|
Packit |
9c3e7e |
clients and process the results. The examples subdirectory contains an example
|
|
Packit |
9c3e7e |
script for each supported client. The above example can be written in a bash
|
|
Packit |
9c3e7e |
script as:
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
CLKNETSIM_PATH=.
|
|
Packit |
9c3e7e |
. ./clknetsim.bash
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
generate_config1 2 0.0 "(sum (* 1e-8 (normal)))" "(+ 1e-1 (* 1e-3 (exponential)))"
|
|
Packit |
9c3e7e |
start_client 1 chrony "local stratum 1"
|
|
Packit |
9c3e7e |
start_client 2 ntp "server 192.168.123.1"
|
|
Packit |
9c3e7e |
start_server 2 -o log.offset -l 100000
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
cat tmp/stats
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Configuration file
|
|
Packit |
9c3e7e |
------------------
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
The configuration file is a text file containing a list of assignments, each
|
|
Packit |
9c3e7e |
specified on a separate line, and comments using # as delimiter. Each node has
|
|
Packit |
9c3e7e |
several variables, which configure the system clock, the reference clock and
|
|
Packit |
9c3e7e |
the network delays to other nodes in the network. They can be set either to an
|
|
Packit |
9c3e7e |
integer value, a floating-point value or a number generating expression written
|
|
Packit |
9c3e7e |
in a Lisp-style syntax.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Variables:
|
|
Packit |
9c3e7e |
- nodeX_freq = float | expr
|
|
Packit |
9c3e7e |
the system clock frequency error in terms of gained seconds per second of
|
|
Packit |
9c3e7e |
simulated time, if an expression is specified, the expression is evaluated and
|
|
Packit |
9c3e7e |
frequency updated once per simulated second (or at the rate specified with
|
|
Packit |
9c3e7e |
the -R option), the allowed range is (-0.2, 0.2), the default is 0
|
|
Packit |
9c3e7e |
- nodeX_delayY = expr
|
|
Packit |
9c3e7e |
the network delay for packets sent from node X to node Y in seconds, the
|
|
Packit |
9c3e7e |
expression is evaluated for each sent packet, a negative value means the
|
|
Packit |
9c3e7e |
packet will be dropped, there is no default (packets are dropped)
|
|
Packit |
9c3e7e |
- nodeX_offset = float
|
|
Packit |
9c3e7e |
the initial time error of the system clock in seconds, the default is 0
|
|
Packit |
9c3e7e |
- nodeX_start = float
|
|
Packit |
9c3e7e |
the time in seconds when will be the node started, the default is 0
|
|
Packit |
9c3e7e |
- nodeX_refclock = expr
|
|
Packit |
9c3e7e |
the reference clock time error in seconds, the clock can be accessed by the
|
|
Packit |
9c3e7e |
client via shared memory (NTP SHM protocol) or as a PTP hardware clock (PHC)
|
|
Packit |
9c3e7e |
via the clock_gettime() function, there is no default (the clock is disabled)
|
|
Packit |
9c3e7e |
- nodeX_step = expr
|
|
Packit |
9c3e7e |
the extra time step applied once per second (or at the rate specified with
|
|
Packit |
9c3e7e |
the -R option) in seconds, there is no default (no extra steps are applied)
|
|
Packit |
9c3e7e |
- nodeX_shift_pll = integer
|
|
Packit |
9c3e7e |
kernel PLL parameter, the default is 2
|
|
Packit |
9c3e7e |
- nodeX_pll_clamp = 1 | 0
|
|
Packit |
9c3e7e |
kernel PLL parameter, the default is 0
|
|
Packit |
9c3e7e |
- nodeX_fll_mode2 = 1 | 0
|
|
Packit |
9c3e7e |
kernel FLL parameter, the default is 0
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Functions and their parameters supported in the expressions:
|
|
Packit |
9c3e7e |
(* [expr | float] ...) - multiplication
|
|
Packit |
9c3e7e |
(+ [expr | float] ...) - addition
|
|
Packit |
9c3e7e |
(% [expr | float] ...) - modulo
|
|
Packit |
9c3e7e |
(sum [expr | float] ...)
|
|
Packit |
9c3e7e |
- summation over consecutive evaluation of parameters
|
|
Packit |
9c3e7e |
(uniform) - random number generator with standard uniform
|
|
Packit |
9c3e7e |
distribution
|
|
Packit |
9c3e7e |
(normal) - random number generator with standard normal
|
|
Packit |
9c3e7e |
distribution
|
|
Packit |
9c3e7e |
(exponential) - random number generator with exponential distribution
|
|
Packit |
9c3e7e |
(lambda = 1)
|
|
Packit |
9c3e7e |
(poisson lambda) - random number generator with poisson distribution
|
|
Packit |
9c3e7e |
(file "datafile") - number generator reading floating-point values from
|
|
Packit |
9c3e7e |
the specified file in an inifinite loop
|
|
Packit |
9c3e7e |
(pulse high low) - pulse wave generator
|
|
Packit |
9c3e7e |
(sine period) - sine wave generator
|
|
Packit |
9c3e7e |
(cosine period) - cosine wave generator
|
|
Packit |
9c3e7e |
(triangle period) - triangle wave generator
|
|
Packit |
9c3e7e |
(equal epsilon [expr | float] ...)
|
|
Packit |
9c3e7e |
- returns 1.0 if the values of all parameters are
|
|
Packit |
9c3e7e |
equal within epsilon, 0.0 otherwise
|
|
Packit |
9c3e7e |
(max [expr | float] ...)
|
|
Packit |
9c3e7e |
- returns maximum value
|
|
Packit |
9c3e7e |
(min [expr | float] ...)
|
|
Packit |
9c3e7e |
- returns minimum value
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Variables available in network delay expressions:
|
|
Packit |
9c3e7e |
time - current network time
|
|
Packit |
9c3e7e |
from - number of the sending node
|
|
Packit |
9c3e7e |
to - number of the receiving node
|
|
Packit |
9c3e7e |
port - receiving port number
|
|
Packit |
9c3e7e |
length - length of the packet
|
|
Packit |
9c3e7e |
subnet - number of the Ethernet network in which
|
|
Packit |
9c3e7e |
the packet was sent
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
An example:
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
# node1 is an NTP server, it has an accurate and absolutely stable clock
|
|
Packit |
9c3e7e |
node1_offset = 0
|
|
Packit |
9c3e7e |
node1_freq = 0
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
# node2 is an NTP client, it starts with 0.1s offset and has
|
|
Packit |
9c3e7e |
# 0.01ppm/s frequency wander
|
|
Packit |
9c3e7e |
node2_offset = 0.1
|
|
Packit |
9c3e7e |
node2_freq = (sum (* 1e-8 (normal)))
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
# network delays between the two nodes have 10ms mean and 100us
|
|
Packit |
9c3e7e |
# jitter in both directions
|
|
Packit |
9c3e7e |
node1_delay2 = (+ 9.9e-3 (* 100e-6 (exponential)))
|
|
Packit |
9c3e7e |
node2_delay1 = (+ 9.9e-3 (* 100e-6 (exponential)))
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Author
|
|
Packit |
9c3e7e |
------
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Miroslav Lichvar <mlichvar@redhat.com>
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
License
|
|
Packit |
9c3e7e |
-------
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
Copyright (C) 2010, 2011, 2012 Miroslav Lichvar <mlichvar@redhat.com>
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
9c3e7e |
it under the terms of the GNU General Public License as published by
|
|
Packit |
9c3e7e |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
9c3e7e |
(at your option) any later version.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
This program is distributed in the hope that it will be useful,
|
|
Packit |
9c3e7e |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
9c3e7e |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
9c3e7e |
GNU General Public License for more details.
|
|
Packit |
9c3e7e |
|
|
Packit |
9c3e7e |
You should have received a copy of the GNU General Public License
|
|
Packit |
9c3e7e |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|