19c2daa00SOllivier Robert<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 29c2daa00SOllivier Robert 39c2daa00SOllivier Robert<html> 49c2daa00SOllivier Robert 59c2daa00SOllivier Robert <head> 69c2daa00SOllivier Robert <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 79c2daa00SOllivier Robert <meta name="GENERATOR" content="Mozilla/4.01 [en] (Win95; I) [Netscape]"> 8*2b15cb3dSCy Schubert <title>Shared Memory Driver</title> 9ea906c41SOllivier Robert <link href="scripts/style.css" type="text/css" rel="stylesheet"> 10*2b15cb3dSCy Schubert <style type="text/css"> 11*2b15cb3dSCy Schubert table.dlstable { font-size:85%; } 12*2b15cb3dSCy Schubert td.ttf{ font-family:Courier; font-weight:bold; } 13*2b15cb3dSCy Schubert </style> 149c2daa00SOllivier Robert </head> 159c2daa00SOllivier Robert 169c2daa00SOllivier Robert <body> 179c2daa00SOllivier Robert <h3>Shared Memory Driver</h3> 18*2b15cb3dSCy Schubert<p>Last update: 19*2b15cb3dSCy Schubert <!-- #BeginDate format:En2m -->8-Aug-2014 19:17<!-- #EndDate --> 20*2b15cb3dSCy Schubert UTC</p> 219c2daa00SOllivier Robert <hr> 229c2daa00SOllivier Robert <h4>Synopsis</h4> 239c2daa00SOllivier Robert <p>Address: 127.127.28.<i>u</i><br> 249c2daa00SOllivier Robert Reference ID: <tt>SHM</tt><br> 259c2daa00SOllivier Robert Driver ID: <tt>SHM</tt></p> 26*2b15cb3dSCy Schubert 279c2daa00SOllivier Robert <h4>Description</h4> 28*2b15cb3dSCy Schubert <p>This driver receives its reference clock info from a shared 29*2b15cb3dSCy Schubert memory-segment. The shared memory-segment is created with owner-only 30*2b15cb3dSCy Schubert access by default, unless otherwise requested by the mode word for units 31*2b15cb3dSCy Schubert ≥2. Units 0 and 1 are always created with owner-only access for 32*2b15cb3dSCy Schubert backward compatibility. 33*2b15cb3dSCy Schubert </p> 34*2b15cb3dSCy Schubert 35*2b15cb3dSCy Schubert 369c2daa00SOllivier Robert <h4>Structure of shared memory-segment</h4> 379c2daa00SOllivier Robert <pre>struct shmTime { 38*2b15cb3dSCy Schubert int mode; /* 0 - if valid is set: 39*2b15cb3dSCy Schubert * use values, 40*2b15cb3dSCy Schubert * clear valid 41*2b15cb3dSCy Schubert * 1 - if valid is set: 42*2b15cb3dSCy Schubert * if count before and after read of data is equal: 43*2b15cb3dSCy Schubert * use values 44*2b15cb3dSCy Schubert * clear valid 45*2b15cb3dSCy Schubert */ 46*2b15cb3dSCy Schubert volatile int count; 47*2b15cb3dSCy Schubert time_t clockTimeStampSec; 48*2b15cb3dSCy Schubert int clockTimeStampUSec; 49*2b15cb3dSCy Schubert time_t receiveTimeStampSec; 50*2b15cb3dSCy Schubert int receiveTimeStampUSec; 51*2b15cb3dSCy Schubert int leap; 52*2b15cb3dSCy Schubert int precision; 53*2b15cb3dSCy Schubert int nsamples; 54*2b15cb3dSCy Schubert volatile int valid; 55*2b15cb3dSCy Schubert unsigned clockTimeStampNSec; /* Unsigned ns timestamps */ 56*2b15cb3dSCy Schubert unsigned receiveTimeStampNSec; /* Unsigned ns timestamps */ 57*2b15cb3dSCy Schubert int dummy[8]; 589c2daa00SOllivier Robert};</pre> 59*2b15cb3dSCy Schubert 609c2daa00SOllivier Robert <h4>Operation mode=0</h4> 61*2b15cb3dSCy Schubert <p>Each second, the value of <code>valid</code> of the shared memory-segment is checked:</p> 62*2b15cb3dSCy Schubert <p>If set, the values in the record (clockTimeStampSec, clockTimeStampUSec, receiveTimeStampSec, receiveTimeStampUSec, leap, precision) are passed to <i>NTPD</i>, and <code>valid</code> is cleared and <code>count</code> is bumped.</p> 63*2b15cb3dSCy Schubert <p>If not set, <code>count</code> is bumped.</p> 649c2daa00SOllivier Robert <h4>Operation mode=1</h4> 65*2b15cb3dSCy Schubert <p>Each second, <code>valid</code> in the shared memory-segment is checked:</p> 66*2b15cb3dSCy Schubert <p>If set, the <code>count</code> field of the record is remembered, and the values in the record (clockTimeStampSec, clockTimeStampUSec, receiveTimeStampSec, receiveTimeStampUSec, leap, precision) are read. Then, the remembered <code>count</code> is compared to current value of <code>count</code> now in the record. If both are equal, the values read from the record are passed to <i>NTPD</i>. If they differ, another process has modified the record while it was read out (was not able to produce this case), and failure is reported to <i>NTPD</i>. The <code>valid</code> flag is cleared and <code>count</code> is bumped.</p> 67*2b15cb3dSCy Schubert <p>If not set, <code>count</code> is bumped</p> 68*2b15cb3dSCy Schubert 69*2b15cb3dSCy Schubert<h4>Mode-independent post-processing</h4> 70*2b15cb3dSCy SchubertAfter the time stamps have been successfully plucked from the SHM 71*2b15cb3dSCy Schubertsegment, some sanity checks take place: 72*2b15cb3dSCy Schubert<ul> 73*2b15cb3dSCy Schubert <li>The receive time stamp of the SHM data must be in the last 5 74*2b15cb3dSCy Schubert seconds before the time the data is processed. This helps in weeding 75*2b15cb3dSCy Schubert out stale data. 76*2b15cb3dSCy Schubert <li>If the absolute difference between remote and local clock 77*2b15cb3dSCy Schubert exceeds the limit (either <i>time2</i> or the default of 4hrs), then 78*2b15cb3dSCy Schubert the sample is discarded. This check is disabled when <i>flag1</i> is 79*2b15cb3dSCy Schubert set to 1. 80*2b15cb3dSCy Schubert</ul> 81*2b15cb3dSCy Schubert 82*2b15cb3dSCy Schubert<h4>GPSD</h4> 83*2b15cb3dSCy Schubert 84*2b15cb3dSCy Schubert<a href="http://gpsd.berlios.de/"><i>GPSD</i></a> 85*2b15cb3dSCy Schubertknows how to talk to many GPS devices. 86*2b15cb3dSCy SchubertIt can work with <i>NTPD</i> through the SHM driver. 87*2b15cb3dSCy Schubert<P> 88*2b15cb3dSCy SchubertThe <i>GPSD</i> man page suggests setting minpoll and maxpoll to 4. 89*2b15cb3dSCy SchubertThat was an attempt to reduce jitter. 90*2b15cb3dSCy SchubertThe SHM driver was fixed (ntp-4.2.5p138) to collect data each second rather than 91*2b15cb3dSCy Schubertonce per polling interval so that suggestion is no longer reasonable. 92*2b15cb3dSCy Schubert<P> 93*2b15cb3dSCy Schubert <b>Note:</b> The <i>GPSD</i> client driver (type 46) uses the <i>GPSD</i> 94*2b15cb3dSCy Schubert client protocol to connect and talk to <i>GPSD</i>, but using the 95*2b15cb3dSCy Schubert SHM driver is the ancient way to have <i>GPSD</i> talk to <i>NTPD</i>. There 96*2b15cb3dSCy Schubert are some tricky points when using the SHM interface to interface 97*2b15cb3dSCy Schubert with <i>GPSD</i>, because <i>GPSD</i> will use two SHM clocks, one for the 98*2b15cb3dSCy Schubert serial data stream and one for the PPS information when 99*2b15cb3dSCy Schubert available. Receivers with a loose/sloppy timing between PPS and serial data 100*2b15cb3dSCy Schubert can easily cause trouble here because <i>NTPD</i> has no way to join the two 101*2b15cb3dSCy Schubert data streams and correlate the serial data with the PPS events. 102*2b15cb3dSCy Schubert</p> 103*2b15cb3dSCy Schubert<p> 104*2b15cb3dSCy Schubert 105*2b15cb3dSCy Schubert<h4>Clockstats</h4> 106*2b15cb3dSCy SchubertIf flag4 is set when the driver is polled, a clockstats record is written. 107*2b15cb3dSCy SchubertThe first 3 fields are the normal date, time, and IP address common to all clockstats records. 108*2b15cb3dSCy Schubert<P> 109*2b15cb3dSCy SchubertThe 4th field is the number of second ticks since the last poll. 110*2b15cb3dSCy SchubertThe 5th field is the number of good data samples found. The last 64 will be used by <i>NTPD</i>. 111*2b15cb3dSCy SchubertThe 6th field is the number of sample that didn't have valid data ready. 112*2b15cb3dSCy SchubertThe 7th field is the number of bad samples. 113*2b15cb3dSCy SchubertThe 8th field is the number of times the the mode 1 info was update while <i>NTPD</i> was trying to grab a sample. 114*2b15cb3dSCy Schubert<P> 115*2b15cb3dSCy Schubert 116*2b15cb3dSCy SchubertHere is a sample showing the GPS reception fading out: 117*2b15cb3dSCy Schubert<pre> 118*2b15cb3dSCy Schubert54364 84927.157 127.127.28.0 66 65 1 0 0 119*2b15cb3dSCy Schubert54364 84990.161 127.127.28.0 63 63 0 0 0 120*2b15cb3dSCy Schubert54364 85053.160 127.127.28.0 63 63 0 0 0 121*2b15cb3dSCy Schubert54364 85116.159 127.127.28.0 63 62 1 0 0 122*2b15cb3dSCy Schubert54364 85180.158 127.127.28.0 64 63 1 0 0 123*2b15cb3dSCy Schubert54364 85246.161 127.127.28.0 66 66 0 0 0 124*2b15cb3dSCy Schubert54364 85312.157 127.127.28.0 66 50 16 0 0 125*2b15cb3dSCy Schubert54364 85375.160 127.127.28.0 63 41 22 0 0 126*2b15cb3dSCy Schubert54364 85439.155 127.127.28.0 64 64 0 0 0 127*2b15cb3dSCy Schubert54364 85505.158 127.127.28.0 66 36 30 0 0 128*2b15cb3dSCy Schubert54364 85569.157 127.127.28.0 64 0 64 0 0 129*2b15cb3dSCy Schubert54364 85635.157 127.127.28.0 66 0 66 0 0 130*2b15cb3dSCy Schubert54364 85700.160 127.127.28.0 65 0 65 0 0 131*2b15cb3dSCy Schubert</pre> 132*2b15cb3dSCy Schubert 133*2b15cb3dSCy Schubert <h4>The 'mode' word</h4> 134*2b15cb3dSCy Schubert 135*2b15cb3dSCy Schubert <p> 136*2b15cb3dSCy Schubert Some aspects of the driver behavior can be adjusted by setting bits of 137*2b15cb3dSCy Schubert the 'mode' word in the server configuration line:<br> 138*2b15cb3dSCy Schubert <tt>server 127.127.28.</tt><i>x</i><tt> mode </tt><i>Y</i> 139*2b15cb3dSCy Schubert </p> 140*2b15cb3dSCy Schubert 141*2b15cb3dSCy Schubert <table border="1" width="100%"> 142*2b15cb3dSCy Schubert <caption>mode word bits and bit groups</caption> 143*2b15cb3dSCy Schubert <tbody><tr> 144*2b15cb3dSCy Schubert <th align="center">Bit</th> 145*2b15cb3dSCy Schubert <th align="center">Dec</th> 146*2b15cb3dSCy Schubert <th align="center">Hex</th> 147*2b15cb3dSCy Schubert <th align="left">Meaning</th> 148*2b15cb3dSCy Schubert </tr> 149*2b15cb3dSCy Schubert 150*2b15cb3dSCy Schubert <tr> 151*2b15cb3dSCy Schubert <td align="center">0</td> 152*2b15cb3dSCy Schubert <td align="center">1</td> 153*2b15cb3dSCy Schubert <td align="center">1</td> 154*2b15cb3dSCy Schubert <td>The SHM segment is private (mode 0600). This is the fixed 155*2b15cb3dSCy Schubert default for clock units 0 and 1; clock units >1 are mode 156*2b15cb3dSCy Schubert 0666 unless this bit is set for the specific unit.</td> 157*2b15cb3dSCy Schubert </tr><tr> 158*2b15cb3dSCy Schubert <td align="center">1-31</td> 159*2b15cb3dSCy Schubert <td align="center">-</td> 160*2b15cb3dSCy Schubert <td align="center">-</td> 161*2b15cb3dSCy Schubert <td><i>reserved -- do not use</i></td> 162*2b15cb3dSCy Schubert </tr> 163*2b15cb3dSCy Schubert </tbody> 164*2b15cb3dSCy Schubert </table> 165*2b15cb3dSCy Schubert 1669c2daa00SOllivier Robert <h4>Fudge Factors</h4> 1679c2daa00SOllivier Robert <dl> 1689c2daa00SOllivier Robert <dt><tt>time1 <i>time</i></tt> 1699c2daa00SOllivier Robert <dd>Specifies the time offset calibration factor, in seconds and fraction, with default 0.0. 1709c2daa00SOllivier Robert <dt><tt>time2 <i>time</i></tt> 171*2b15cb3dSCy Schubert <dd>Maximum allowed difference between remote and local 172*2b15cb3dSCy Schubert clock, in seconds. Values <1.0 or >86400.0 are ignored, and the 173*2b15cb3dSCy Schubert default value of 4hrs (14400s) is used instead. See also flag 1. 1749c2daa00SOllivier Robert <dt><tt>stratum <i>number</i></tt> 1759c2daa00SOllivier Robert <dd>Specifies the driver stratum, in decimal from 0 to 15, with default 0. 1769c2daa00SOllivier Robert <dt><tt>refid <i>string</i></tt> 1779c2daa00SOllivier Robert <dd>Specifies the driver reference identifier, an ASCII string from one to four characters, with default <tt>SHM</tt>. 1789c2daa00SOllivier Robert <dt><tt>flag1 0 | 1</tt> 179*2b15cb3dSCy Schubert <dd><i>Skip</i> the difference limit check if set. Useful 180*2b15cb3dSCy Schubert for systems where the RTC backup cannot keep the time over 181*2b15cb3dSCy Schubert long periods without power and the SHM clock must be able 182*2b15cb3dSCy Schubert to force long-distance initial jumps. <i>Check</i> the 183*2b15cb3dSCy Schubert difference limit if cleared (default). 1849c2daa00SOllivier Robert <dt><tt>flag2 0 | 1</tt> 1859c2daa00SOllivier Robert <dd>Not used by this driver. 1869c2daa00SOllivier Robert <dt><tt>flag3 0 | 1</tt> 1879c2daa00SOllivier Robert <dd>Not used by this driver. 1889c2daa00SOllivier Robert <dt><tt>flag4 0 | 1</tt> 189*2b15cb3dSCy Schubert <dd>If flag4 is set, clockstats records will be written when the driver is polled. 190*2b15cb3dSCy Schubert </dl> 191*2b15cb3dSCy Schubert 192*2b15cb3dSCy Schubert <h4>Public vs. Private SHM segments</h4> 193*2b15cb3dSCy Schubert 194*2b15cb3dSCy Schubert <p>The driver attempts to create a shared memory segment with an 195*2b15cb3dSCy Schubert identifier depending on the unit number. This identifier (which can be 196*2b15cb3dSCy Schubert a numeric value or a string) clearly depends on the method used, which 197*2b15cb3dSCy Schubert in turn depends on the host operating system:</p> 198*2b15cb3dSCy Schubert 199*2b15cb3dSCy Schubert <ul> 200*2b15cb3dSCy Schubert <li><p> 201*2b15cb3dSCy Schubert <tt>Windows</tt> uses a file mapping to the page file with the 202*2b15cb3dSCy Schubert name '<tt>Global\NTP</tt><i>u</i>' for public accessible 203*2b15cb3dSCy Schubert mappings, where <i>u</i> is the clock unit. Private / 204*2b15cb3dSCy Schubert non-public mappings are created as 205*2b15cb3dSCy Schubert '<tt>Local\NTP</tt><i>u</i>'. 206*2b15cb3dSCy Schubert </p><p> 207*2b15cb3dSCy Schubert Public access assigns a NULL DACL to the memory mapping, while 208*2b15cb3dSCy Schubert private access just uses the default DACL of the process creating 209*2b15cb3dSCy Schubert the mapping. 210*2b15cb3dSCy Schubert </p> 211*2b15cb3dSCy Schubert </li> 212*2b15cb3dSCy Schubert <li><p> 213*2b15cb3dSCy Schubert <tt>SYSV IPC</tt> creates a shared memory segment with a key value 214*2b15cb3dSCy Schubert of <tt>0x4E545030</tt> + <i>u</i>, where <i>u</i> is again 215*2b15cb3dSCy Schubert the clock unit. (This value could be hex-decoded as 'NTP0', 216*2b15cb3dSCy Schubert 'NTP1',..., with funny characters for units > 9.) 217*2b15cb3dSCy Schubert </p><p> 218*2b15cb3dSCy Schubert Public access means a permission set of 0666, while private access 219*2b15cb3dSCy Schubert creates the mapping with a permission set of 0600. 220*2b15cb3dSCy Schubert </p> 221*2b15cb3dSCy Schubert </li> 222*2b15cb3dSCy Schubert </ul> 223*2b15cb3dSCy Schubert 224*2b15cb3dSCy Schubert <p>There's no support for POSIX shared memory yet.</p> 225*2b15cb3dSCy Schubert 226*2b15cb3dSCy Schubert <p><i>NTPD</i> is started as root on most POSIX-like operating systems 227*2b15cb3dSCy Schubert and uses the setuid/setgid system API to run under reduced rights once 228*2b15cb3dSCy Schubert the initial setup of the process is done. One consequence out of this 229*2b15cb3dSCy Schubert is that the allocation of SHM segments must be done early during the 230*2b15cb3dSCy Schubert clock setup. The actual polling of the clock is done as the run-time 231*2b15cb3dSCy Schubert user; deferring the creation of the SHM segment to this point will 232*2b15cb3dSCy Schubert create a SHM segment owned by the runtime-user account. The internal 233*2b15cb3dSCy Schubert structure of <i>NTPD</i> does not permit the use of a fudge flag if 234*2b15cb3dSCy Schubert this is to be avoided; this is the reason why a mode bit is used for 235*2b15cb3dSCy Schubert the configuration of a public segment. 236*2b15cb3dSCy Schubert </p> 237*2b15cb3dSCy Schubert 238*2b15cb3dSCy Schubert <p>When running under Windows, the chosen user account must be able to 239*2b15cb3dSCy Schubert create a SHM segment in the global object name space for SHM clocks with 240*2b15cb3dSCy Schubert public access. Otherwise the session isolation used by Windows kernels 241*2b15cb3dSCy Schubert after WinXP will get into the way if the client program does not run in 242*2b15cb3dSCy Schubert the same session. 243*2b15cb3dSCy Schubert </p> 244*2b15cb3dSCy Schubert 2459c2daa00SOllivier Robert <h4>Additional Information</h4> 2469c2daa00SOllivier Robert <p><a href="../refclock.html">Reference Clock Drivers</a></p> 247*2b15cb3dSCy Schubert 2489c2daa00SOllivier Robert <hr> 249ea906c41SOllivier Robert <script type="text/javascript" language="javascript" src="scripts/footer.txt"></script> 2509c2daa00SOllivier Robert </body> 2519c2daa00SOllivier Robert 2529c2daa00SOllivier Robert</html> 253*2b15cb3dSCy Schubert 254