timesync.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <auth.h>
  12. #include <ip.h>
  13. #include <mp.h>
  14. /* nanosecond times */
  15. #define SEC 1000000000LL
  16. #define MIN (60LL*SEC)
  17. #define HOUR (60LL*MIN)
  18. #define DAY (24LL*HOUR)
  19. enum {
  20. Fs,
  21. Rtc,
  22. Ntp,
  23. Utc,
  24. Gps,
  25. HZAvgSecs= 3*60, /* target averaging period for frequency in seconds */
  26. MinSampleSecs= 60, /* minimum sampling time in seconds */
  27. };
  28. char *dir = "/tmp"; /* directory sample files live in */
  29. char *logfile = "timesync";
  30. char *timeserver;
  31. char *Rootid;
  32. int utcfil;
  33. int gpsfil;
  34. int debug;
  35. int impotent;
  36. int logging;
  37. int type;
  38. int gmtdelta; /* rtc+gmtdelta = gmt */
  39. uint64_t avgerr;
  40. /* ntp server info */
  41. int stratum = 14;
  42. int64_t mydisp, rootdisp;
  43. int64_t mydelay, rootdelay;
  44. int64_t avgdelay;
  45. int64_t lastutc;
  46. uint8_t rootid[4];
  47. char *sysid;
  48. int myprec;
  49. /* list of time samples */
  50. typedef struct Sample Sample;
  51. struct Sample
  52. {
  53. Sample *next;
  54. uint64_t ticks;
  55. int64_t ltime;
  56. int64_t stime;
  57. };
  58. /* ntp packet */
  59. typedef struct NTPpkt NTPpkt;
  60. struct NTPpkt
  61. {
  62. uint8_t mode;
  63. uint8_t stratum;
  64. uint8_t poll;
  65. uint8_t precision;
  66. uint8_t rootdelay[4];
  67. uint8_t rootdisp[4];
  68. uint8_t rootid[4];
  69. uint8_t refts[8];
  70. uint8_t origts[8]; /* departed client */
  71. uint8_t recvts[8]; /* arrived at server */
  72. uint8_t xmitts[8]; /* departed server */
  73. uint8_t keyid[4];
  74. uint8_t digest[16];
  75. };
  76. /* ntp server */
  77. typedef struct NTPserver NTPserver;
  78. struct NTPserver
  79. {
  80. NTPserver *next;
  81. char *name;
  82. uint8_t stratum;
  83. uint8_t precision;
  84. int64_t rootdelay;
  85. int64_t rootdisp;
  86. int64_t rtt;
  87. int64_t dt;
  88. };
  89. NTPserver *ntpservers;
  90. enum
  91. {
  92. NTPSIZE= 48, /* basic ntp packet */
  93. NTPDIGESTSIZE= 20, /* key and digest */
  94. };
  95. /* error bound of last sample */
  96. uint32_t etha;
  97. static void addntpserver(char *name);
  98. static int adjustperiod(int64_t diff, int64_t accuracy, int secs);
  99. static void background(void);
  100. static int caperror(int64_t dhz, int tsecs, int64_t taccuracy);
  101. static int32_t fstime(void);
  102. static int gettime(int64_t *nsec, uint64_t *ticks, uint64_t *hz); /* returns time, ticks, hz */
  103. static int getclockprecision(int64_t);
  104. static int64_t gpssample(void);
  105. static void hnputts(void *p, int64_t nsec);
  106. static void hnputts(void *p, int64_t nsec);
  107. static void inittime(void);
  108. static int64_t nhgetts(void *p);
  109. static int64_t nhgetts(void *p);
  110. static void ntpserver(char*);
  111. static int64_t ntpsample(void);
  112. static int ntptimediff(NTPserver *ns);
  113. static int openfreqfile(void);
  114. static int64_t readfreqfile(int fd, int64_t ohz, int64_t minhz,
  115. int64_t maxhz);
  116. static int32_t rtctime(void);
  117. static int64_t sample(int32_t (*get)(void));
  118. static void setpriority(void);
  119. static void setrootid(char *d);
  120. static void settime(int64_t now, uint64_t hz, int64_t delta, int n); /* set time, hz, delta, period */
  121. static int64_t utcsample(void);
  122. static uint64_t vabs(int64_t);
  123. static uint64_t whatisthefrequencykenneth(uint64_t hz, uint64_t minhz,
  124. uint64_t maxhz,
  125. int64_t dt, int64_t ticks, int64_t period);
  126. static void writefreqfile(int fd, int64_t hz, int secs, int64_t diff);
  127. // ((1970-1900)*365 + 17 /*leap days*/)*24*60*60
  128. #define EPOCHDIFF 2208988800UL
  129. static void
  130. usage(void)
  131. {
  132. fprint(2, "usage: %s [-a accuracy][-d dir][-I rootid][-s net]"
  133. "[-S stratum][-DfGilLnrU] timesource ...\n", argv0);
  134. exits("usage");
  135. }
  136. void
  137. main(int argc, char **argv)
  138. {
  139. int i, t, fd, nservenet;
  140. int secs; /* sampling period */
  141. int tsecs; /* temporary sampling period */
  142. uint64_t hz, minhz, maxhz, period, nhz;
  143. int64_t diff, accuracy, taccuracy;
  144. char *servenet[4];
  145. Sample *s, *x, *first, **l;
  146. Tm tl, tg;
  147. type = Fs; /* by default, sync with the file system */
  148. debug = 0;
  149. accuracy = 1000000LL; /* default accuracy is 1 millisecond */
  150. nservenet = 0;
  151. tsecs = secs = MinSampleSecs;
  152. timeserver = "";
  153. ARGBEGIN{
  154. case 'a':
  155. accuracy = strtoll(EARGF(usage()), 0, 0); /* specified in ns */
  156. if(accuracy <= 1)
  157. sysfatal("bad accuracy specified");
  158. break;
  159. case 'd':
  160. dir = EARGF(usage());
  161. break;
  162. case 'D':
  163. debug = 1;
  164. break;
  165. case 'f':
  166. type = Fs;
  167. stratum = 2;
  168. break;
  169. case 'G':
  170. type = Gps;
  171. stratum = 1;
  172. break;
  173. case 'i':
  174. impotent = 1;
  175. break;
  176. case 'I':
  177. Rootid = EARGF(usage());
  178. break;
  179. case 'l':
  180. logging = 1;
  181. break;
  182. case 'L':
  183. /*
  184. * Assume time source in local time rather than GMT.
  185. * Calculate difference so that rtctime can return GMT.
  186. * This is useful with the rtc on PC's that run Windows
  187. * since Windows keeps the local time in the rtc.
  188. */
  189. t = time(0);
  190. tl = *localtime(t);
  191. tg = *gmtime(t);
  192. /*
  193. * if the years are different, we're at most a day off,
  194. * so just rewrite
  195. */
  196. if(tl.year < tg.year){
  197. tg.year--;
  198. tg.yday = tl.yday + 1;
  199. }else if(tl.year > tg.year){
  200. tl.year--;
  201. tl.yday = tg.yday+1;
  202. }
  203. assert(tl.year == tg.year);
  204. tg.sec -= tl.sec;
  205. tg.min -= tl.min;
  206. tg.hour -= tl.hour;
  207. tg.yday -= tl.yday;
  208. gmtdelta = tg.sec+60*(tg.min+60*(tg.hour+tg.yday*24));
  209. assert(abs(gmtdelta) <= 24*60*60);
  210. break;
  211. case 'n':
  212. type = Ntp;
  213. break;
  214. case 'r':
  215. type = Rtc;
  216. stratum = 0;
  217. break;
  218. case 'U':
  219. type = Utc;
  220. stratum = 1;
  221. break;
  222. case 's':
  223. if(nservenet >= nelem(servenet))
  224. sysfatal("too many networks to serve on");
  225. servenet[nservenet++] = EARGF(usage());
  226. break;
  227. case 'S':
  228. stratum = strtoll(EARGF(usage()), 0, 0);
  229. break;
  230. default:
  231. usage();
  232. }ARGEND;
  233. fmtinstall('E', eipfmt);
  234. fmtinstall('I', eipfmt);
  235. fmtinstall('V', eipfmt);
  236. sysid = getenv("sysname");
  237. /* detach from the current namespace */
  238. if(debug)
  239. rfork(RFNAMEG);
  240. switch(type){
  241. case Utc:
  242. if(argc > 0)
  243. timeserver = argv[0];
  244. else
  245. sysfatal("bad time source");
  246. break;
  247. case Gps:
  248. if(argc > 0)
  249. timeserver = argv[0];
  250. else
  251. timeserver = "/mnt/gps/time";
  252. break;
  253. case Fs:
  254. if(argc > 0)
  255. timeserver = argv[0];
  256. else
  257. timeserver = "/srv/boot";
  258. break;
  259. case Ntp:
  260. if(argc > 0)
  261. for(i = 0; i < argc; i++)
  262. addntpserver(argv[i]);
  263. else
  264. addntpserver("$ntp");
  265. break;
  266. }
  267. setpriority();
  268. /* figure out our time interface and initial frequency */
  269. inittime();
  270. gettime(0, 0, &hz);
  271. minhz = hz/10;
  272. maxhz = hz*10;
  273. myprec = getclockprecision(hz);
  274. /* convert the accuracy from nanoseconds to ticks */
  275. taccuracy = hz*accuracy/SEC;
  276. /*
  277. * bind in clocks
  278. */
  279. switch(type){
  280. case Fs:
  281. fd = open(timeserver, ORDWR);
  282. if(fd < 0)
  283. sysfatal("opening %s: %r", timeserver);
  284. if(amount(fd, "/n/boot", MREPL, "") < 0)
  285. sysfatal("mounting %s: %r", timeserver);
  286. close(fd);
  287. break;
  288. case Rtc:
  289. bind("#r", "/dev", MAFTER);
  290. if(access("/dev/rtc", AREAD) < 0)
  291. sysfatal("accessing /dev/rtc: %r");
  292. break;
  293. case Utc:
  294. fd = open(timeserver, OREAD);
  295. if(fd < 0)
  296. sysfatal("opening %s: %r", timeserver);
  297. utcfil = fd;
  298. break;
  299. case Gps:
  300. fd = open(timeserver, OREAD);
  301. if(fd < 0)
  302. sysfatal("opening %s: %r", timeserver);
  303. gpsfil = fd;
  304. break;
  305. }
  306. /*
  307. * start a local ntp server(s)
  308. */
  309. for(i = 0; i < nservenet; i++)
  310. switch(rfork(RFPROC|RFFDG|RFMEM|RFNOWAIT)){
  311. case -1:
  312. sysfatal("forking: %r");
  313. case 0:
  314. ntpserver(servenet[i]);
  315. _exits(0);
  316. }
  317. /* get the last known frequency from the file */
  318. fd = openfreqfile();
  319. hz = readfreqfile(fd, hz, minhz, maxhz);
  320. /*
  321. * this is the main loop. it gets a sample, adjusts the
  322. * clock and computes a sleep period until the next loop.
  323. * we balance frequency drift against the length of the
  324. * period to avoid blowing the accuracy limit.
  325. */
  326. first = nil;
  327. l = &first;
  328. avgerr = accuracy >> 1;
  329. for(;; background(), sleep(tsecs*1000)){
  330. s = mallocz(sizeof *s, 1);
  331. diff = 0;
  332. /* get times for this sample */
  333. etha = ~0;
  334. switch(type){
  335. case Fs:
  336. s->stime = sample(fstime);
  337. break;
  338. case Rtc:
  339. s->stime = sample(rtctime);
  340. break;
  341. case Utc:
  342. s->stime = utcsample();
  343. if(s->stime == 0LL){
  344. if(logging)
  345. syslog(0, logfile, "no sample");
  346. free(s);
  347. if (secs > 60 * 15)
  348. tsecs = 60*15;
  349. continue;
  350. }
  351. break;
  352. case Ntp:
  353. diff = ntpsample();
  354. if(diff == 0LL){
  355. if(logging)
  356. syslog(0, logfile, "no sample");
  357. free(s);
  358. if(secs > 60*15)
  359. tsecs = 60*15;
  360. continue;
  361. }
  362. break;
  363. case Gps:
  364. diff = gpssample();
  365. if(diff == 0LL){
  366. if(logging)
  367. syslog(0, logfile, "no sample");
  368. free(s);
  369. if(secs > 60*15)
  370. tsecs = 60*15;
  371. continue;
  372. }
  373. }
  374. /* use fastest method to read local clock and ticks */
  375. gettime(&s->ltime, &s->ticks, 0);
  376. if(type == Ntp || type == Gps)
  377. s->stime = s->ltime + diff;
  378. /* if the sample was bad, ignore it */
  379. if(s->stime < 0){
  380. free(s);
  381. continue;
  382. }
  383. /* reset local time */
  384. diff = s->stime - s->ltime;
  385. if(diff > 10*SEC || diff < -10*SEC){
  386. /* we're way off, just set the time */
  387. secs = MinSampleSecs;
  388. settime(s->stime, 0, 0, 0);
  389. } else {
  390. /* keep a running average of the error. */
  391. avgerr = (avgerr>>1) + (vabs(diff)>>1);
  392. /*
  393. * the time to next sample depends on how good or
  394. * bad we're doing.
  395. */
  396. tsecs = secs = adjustperiod(diff, accuracy, secs);
  397. /*
  398. * work off the fixed difference. This is done
  399. * by adding a ramp to the clock. Each 100th of a
  400. * second (or so) the kernel will add diff/(4*secs*100)
  401. * to the clock. we only do 1/4 of the difference per
  402. * period to dampen any measurement noise.
  403. *
  404. * any difference greater than etha we work off during the
  405. * sampling period.
  406. */
  407. if(abs(diff) > etha)
  408. if(diff > 0)
  409. settime(-1, 0, diff-((3*etha)/4), secs);
  410. else
  411. settime(-1, 0, diff+((3*etha)/4), secs);
  412. else
  413. settime(-1, 0, diff, 4*secs);
  414. }
  415. if(debug)
  416. fprint(2, "δ %lld avgδ %lld f %lld\n", diff, avgerr, hz);
  417. /* dump old samples (keep at least one) */
  418. while(first != nil){
  419. if(first->next == nil)
  420. break;
  421. if(s->stime - first->next->stime < DAY)
  422. break;
  423. x = first;
  424. first = first->next;
  425. free(x);
  426. }
  427. /*
  428. * The sampling error is limited by the total error. If
  429. * we make sure the sampling period is at least 16 million
  430. * times the average error, we should calculate a frequency
  431. * with on average a 1e-7 error.
  432. *
  433. * So that big hz changes don't blow our accuracy requirement,
  434. * we shorten the period to make sure that δhz*secs will be
  435. * greater than the accuracy limit.
  436. */
  437. period = avgerr << 24;
  438. for(x = first; x != nil; x = x->next)
  439. if(s->stime - x->stime < period ||
  440. x->next == nil || s->stime - x->next->stime < period)
  441. break;
  442. if(x != nil){
  443. nhz = whatisthefrequencykenneth(
  444. hz, minhz, maxhz,
  445. s->stime - x->stime,
  446. s->ticks - x->ticks,
  447. period);
  448. tsecs = caperror(vabs(nhz-hz), tsecs, taccuracy);
  449. hz = nhz;
  450. writefreqfile(fd, hz, (s->stime - x->stime)/SEC, diff);
  451. }
  452. /* add current sample to list. */
  453. *l = s;
  454. l = &s->next;
  455. if(logging)
  456. syslog(0, logfile, "δ %lld avgδ %lld hz %lld",
  457. diff, avgerr, hz);
  458. }
  459. }
  460. /*
  461. * adjust the sampling period with some histeresis
  462. */
  463. static int
  464. adjustperiod(int64_t diff, int64_t accuracy, int secs)
  465. {
  466. uint64_t absdiff;
  467. absdiff = vabs(diff);
  468. if(absdiff < (accuracy>>1))
  469. secs += 60;
  470. else if(absdiff > accuracy)
  471. secs >>= 1;
  472. else
  473. secs -= 60;
  474. if(secs < MinSampleSecs)
  475. secs = MinSampleSecs;
  476. return secs;
  477. }
  478. /*
  479. * adjust the frequency
  480. */
  481. static uint64_t
  482. whatisthefrequencykenneth(uint64_t hz, uint64_t minhz, uint64_t maxhz,
  483. int64_t dt,
  484. int64_t ticks, int64_t period)
  485. {
  486. uint64_t ohz = hz;
  487. static mpint *mpdt, *mpticks, *mphz, *mpbillion;
  488. /* sanity check */
  489. if(dt <= 0 || ticks <= 0)
  490. return hz;
  491. if(mphz == nil){
  492. mphz = mpnew(0);
  493. mpbillion = uvtomp(SEC, nil);
  494. }
  495. /* hz = (ticks*SEC)/dt */
  496. mpdt = vtomp(dt, mpdt);
  497. mpticks = vtomp(ticks, mpticks);
  498. mpmul(mpticks, mpbillion, mpticks);
  499. mpdiv(mpticks, mpdt, mphz, nil);
  500. hz = mptoui(mphz);
  501. /* sanity */
  502. if(hz < minhz || hz > maxhz)
  503. return ohz;
  504. /* damp the change if we're shorter than the target period */
  505. if(period > dt)
  506. hz = (12ULL*ohz + 4ULL*hz)/16ULL;
  507. settime(-1, hz, 0, 0);
  508. return hz;
  509. }
  510. /*
  511. * We may be changing the frequency to match a bad measurement
  512. * or to match a condition no longer in effect. To make sure
  513. * that this doesn't blow our error budget over the next measurement
  514. * period, shorten the period to make sure that δhz*secs will be
  515. * less than the accuracy limit. Here taccuracy is accuracy converted
  516. * from nanoseconds to ticks.
  517. */
  518. static int
  519. caperror(int64_t dhz, int tsecs, int64_t taccuracy)
  520. {
  521. if(dhz*tsecs <= taccuracy)
  522. return tsecs;
  523. if(debug)
  524. fprint(2, "δhz %lld tsecs %d tacc %lld\n", dhz, tsecs, taccuracy);
  525. tsecs = taccuracy/dhz;
  526. if(tsecs < MinSampleSecs)
  527. tsecs = MinSampleSecs;
  528. return tsecs;
  529. }
  530. /*
  531. * kernel interface
  532. */
  533. enum
  534. {
  535. Ibintime,
  536. Insec,
  537. Itiming,
  538. };
  539. int ifc;
  540. int bintimefd = -1;
  541. int timingfd = -1;
  542. int nsecfd = -1;
  543. int fastclockfd = -1;
  544. static void
  545. inittime(void)
  546. {
  547. int mode;
  548. if(impotent)
  549. mode = OREAD;
  550. else
  551. mode = ORDWR;
  552. /* bind in clocks */
  553. if(access("/dev/time", 0) < 0)
  554. bind("#c", "/dev", MAFTER);
  555. if(access("/dev/rtc", 0) < 0)
  556. bind("#r", "/dev", MAFTER);
  557. /* figure out what interface we have */
  558. ifc = Ibintime;
  559. bintimefd = open("/dev/bintime", mode);
  560. if(bintimefd >= 0)
  561. return;
  562. ifc = Insec;
  563. nsecfd = open("/dev/nsec", mode);
  564. if(nsecfd < 0)
  565. sysfatal("opening /dev/nsec");
  566. fastclockfd = open("/dev/fastclock", mode);
  567. if(fastclockfd < 0)
  568. sysfatal("opening /dev/fastclock");
  569. timingfd = open("/dev/timing", OREAD);
  570. if(timingfd < 0)
  571. return;
  572. ifc = Itiming;
  573. }
  574. /*
  575. * convert binary numbers from/to kernel
  576. */
  577. static uint64_t uvorder = 0x0001020304050607ULL;
  578. static uint8_t*
  579. be2int64_t(int64_t *to, uint8_t *f)
  580. {
  581. uint8_t *t, *o;
  582. int i;
  583. t = (uint8_t*)to;
  584. o = (uint8_t*)&uvorder;
  585. for(i = 0; i < sizeof(int64_t); i++)
  586. t[o[i]] = f[i];
  587. return f+sizeof(int64_t);
  588. }
  589. static uint8_t*
  590. int64_t2be(uint8_t *t, int64_t from)
  591. {
  592. uint8_t *f, *o;
  593. int i;
  594. f = (uint8_t*)&from;
  595. o = (uint8_t*)&uvorder;
  596. for(i = 0; i < sizeof(int64_t); i++)
  597. t[i] = f[o[i]];
  598. return t+sizeof(int64_t);
  599. }
  600. static int32_t order = 0x00010203;
  601. static uint8_t*
  602. long2be(uint8_t *t, int32_t from)
  603. {
  604. uint8_t *f, *o;
  605. int i;
  606. f = (uint8_t*)&from;
  607. o = (uint8_t*)&order;
  608. for(i = 0; i < sizeof(int32_t); i++)
  609. t[i] = f[o[i]];
  610. return t+sizeof(int32_t);
  611. }
  612. /*
  613. * read ticks and local time in nanoseconds
  614. */
  615. static int
  616. gettime(int64_t *nsec, uint64_t *ticks, uint64_t *hz)
  617. {
  618. int i, n;
  619. uint8_t ub[3*8], *p;
  620. char b[2*24+1];
  621. switch(ifc){
  622. case Ibintime:
  623. n = sizeof(int64_t);
  624. if(hz != nil)
  625. n = 3*sizeof(int64_t);
  626. if(ticks != nil)
  627. n = 2*sizeof(int64_t);
  628. i = read(bintimefd, ub, n);
  629. if(i != n)
  630. break;
  631. p = ub;
  632. if(nsec != nil)
  633. be2int64_t(nsec, ub);
  634. p += sizeof(int64_t);
  635. if(ticks != nil)
  636. be2int64_t((int64_t*)ticks, p);
  637. p += sizeof(int64_t);
  638. if(hz != nil)
  639. be2int64_t((int64_t*)hz, p);
  640. return 0;
  641. case Itiming:
  642. n = sizeof(int64_t);
  643. if(ticks != nil)
  644. n = 2*sizeof(int64_t);
  645. i = read(timingfd, ub, n);
  646. if(i != n)
  647. break;
  648. p = ub;
  649. if(nsec != nil)
  650. be2int64_t(nsec, ub);
  651. p += sizeof(int64_t);
  652. if(ticks != nil)
  653. be2int64_t((int64_t*)ticks, p);
  654. if(hz != nil){
  655. seek(fastclockfd, 0, 0);
  656. n = read(fastclockfd, b, sizeof(b)-1);
  657. if(n <= 0)
  658. break;
  659. b[n] = 0;
  660. *hz = strtoll(b+24, 0, 0);
  661. }
  662. return 0;
  663. case Insec:
  664. if(nsec != nil){
  665. seek(nsecfd, 0, 0);
  666. n = read(nsecfd, b, sizeof(b)-1);
  667. if(n <= 0)
  668. break;
  669. b[n] = 0;
  670. *nsec = strtoll(b, 0, 0);
  671. }
  672. if(ticks != nil){
  673. seek(fastclockfd, 0, 0);
  674. n = read(fastclockfd, b, sizeof(b)-1);
  675. if(n <= 0)
  676. break;
  677. b[n] = 0;
  678. *ticks = strtoll(b, 0, 0);
  679. }
  680. if(hz != nil){
  681. seek(fastclockfd, 0, 0);
  682. n = read(fastclockfd, b, sizeof(b)-1);
  683. if(n <= 24)
  684. break;
  685. b[n] = 0;
  686. *hz = strtoll(b+24, 0, 0);
  687. }
  688. return 0;
  689. }
  690. return -1;
  691. }
  692. static void
  693. settime(int64_t now, uint64_t hz, int64_t delta, int n)
  694. {
  695. uint8_t b[1+sizeof(int64_t)+sizeof(int32_t)], *p;
  696. if(debug)
  697. fprint(2, "settime(now=%lld, hz=%llu, delta=%lld, period=%d)\n",
  698. now, hz, delta, n);
  699. if(impotent)
  700. return;
  701. switch(ifc){
  702. case Ibintime:
  703. if(now >= 0){
  704. p = b;
  705. *p++ = 'n';
  706. p = int64_t2be(p, now);
  707. if(write(bintimefd, b, p-b) < 0)
  708. sysfatal("writing /dev/bintime: %r");
  709. }
  710. if(delta != 0){
  711. p = b;
  712. *p++ = 'd';
  713. p = int64_t2be(p, delta);
  714. p = long2be(p, n);
  715. if(write(bintimefd, b, p-b) < 0)
  716. sysfatal("writing /dev/bintime: %r");
  717. }
  718. if(hz != 0){
  719. p = b;
  720. *p++ = 'f';
  721. p = int64_t2be(p, hz);
  722. if(write(bintimefd, b, p-b) < 0)
  723. sysfatal("writing /dev/bintime: %r");
  724. }
  725. break;
  726. case Itiming:
  727. case Insec:
  728. seek(nsecfd, 0, 0);
  729. if(now >= 0 || delta != 0){
  730. if(fprint(nsecfd, "%lld %lld %d", now, delta, n) < 0)
  731. sysfatal("writing /dev/nsec: %r");
  732. }
  733. if(hz > 0){
  734. seek(fastclockfd, 0, 0);
  735. if(fprint(fastclockfd, "%lld", hz) < 0)
  736. sysfatal("writing /dev/fastclock: %r");
  737. }
  738. }
  739. }
  740. /*
  741. * set priority high and wire process to a processor
  742. */
  743. static void
  744. setpriority(void)
  745. {
  746. int fd;
  747. char buf[32];
  748. sprint(buf, "/proc/%d/ctl", getpid());
  749. fd = open(buf, ORDWR);
  750. if(fd < 0){
  751. fprint(2, "can't set priority\n");
  752. return;
  753. }
  754. if(fprint(fd, "pri 100") < 0)
  755. fprint(2, "can't set priority\n");
  756. if(fprint(fd, "wired 2") < 0)
  757. fprint(2, "can't wire process\n");
  758. close(fd);
  759. }
  760. /* convert to ntp timestamps */
  761. static void
  762. hnputts(void *p, int64_t nsec)
  763. {
  764. uint8_t *a;
  765. uint32_t tsh, tsl;
  766. a = p;
  767. /* zero is a special case */
  768. if(nsec == 0)
  769. return;
  770. tsh = nsec/SEC;
  771. nsec -= tsh*SEC;
  772. tsl = (nsec<<32)/SEC;
  773. hnputl(a, tsh+EPOCHDIFF);
  774. hnputl(a+4, tsl);
  775. }
  776. /* convert from ntp timestamps */
  777. static int64_t
  778. nhgetts(void *p)
  779. {
  780. uint8_t *a;
  781. uint32_t tsh, tsl;
  782. int64_t nsec;
  783. a = p;
  784. tsh = nhgetl(a);
  785. tsl = nhgetl(a+4);
  786. nsec = tsl*SEC;
  787. nsec >>= 32;
  788. nsec += (tsh - EPOCHDIFF)*SEC;
  789. return nsec;
  790. }
  791. /* convert to ntp 32 bit fixed point */
  792. static void
  793. hnputfp(void *p, int64_t nsec)
  794. {
  795. uint8_t *a;
  796. uint32_t fp;
  797. a = p;
  798. fp = nsec/(SEC/((int64_t)(1<<16)));
  799. hnputl(a, fp);
  800. }
  801. /* convert from ntp fixed point to nanosecs */
  802. static int64_t
  803. nhgetfp(void *p)
  804. {
  805. uint8_t *a;
  806. uint32_t fp;
  807. int64_t nsec;
  808. a = p;
  809. fp = nhgetl(a);
  810. nsec = ((int64_t)fp)*(SEC/((int64_t)(1<<16)));
  811. return nsec;
  812. }
  813. /* get network address of the server */
  814. static void
  815. setrootid(char *d)
  816. {
  817. char buf[128];
  818. int fd, n;
  819. char *p;
  820. snprint(buf, sizeof buf, "%s/remote", d);
  821. fd = open(buf, OREAD);
  822. if(fd < 0)
  823. return;
  824. n = read(fd, buf, sizeof buf);
  825. close(fd);
  826. if(n <= 0)
  827. return;
  828. p = strchr(buf, '!');
  829. if(p != nil)
  830. *p = 0;
  831. v4parseip(rootid, buf);
  832. }
  833. static void
  834. ding(void *v, char *s)
  835. {
  836. if(strstr(s, "alarm") != nil)
  837. noted(NCONT);
  838. noted(NDFLT);
  839. }
  840. static void
  841. addntpserver(char *name)
  842. {
  843. NTPserver *ns, **l;
  844. ns = mallocz(sizeof(NTPserver), 1);
  845. if(ns == nil)
  846. sysfatal("addntpserver: %r");
  847. timeserver = strdup(name);
  848. ns->name = name;
  849. for(l = &ntpservers; *l != nil; l = &(*l)->next)
  850. ;
  851. *l = ns;
  852. }
  853. /*
  854. * sntp client, we keep calling if the delay seems
  855. * unusually high, i.e., 30% longer than avg.
  856. */
  857. static int
  858. ntptimediff(NTPserver *ns)
  859. {
  860. int fd, tries, n;
  861. NTPpkt ntpin, ntpout;
  862. int64_t dt, recvts, origts, xmitts, destts, x;
  863. char dir[64];
  864. static int whined;
  865. notify(ding);
  866. alarm(30*1000); /* don't wait forever if ns->name is unreachable */
  867. fd = dial(netmkaddr(ns->name, "udp", "ntp"), 0, dir, 0);
  868. alarm(0);
  869. if(fd < 0){
  870. if (!whined++)
  871. syslog(0, logfile, "can't reach %s: %r", ns->name);
  872. return -1;
  873. }
  874. setrootid(dir);
  875. memset(&ntpout, 0, sizeof(ntpout));
  876. ntpout.mode = 3 | (3 << 3);
  877. for(tries = 0; tries < 3; tries++){
  878. alarm(2*1000);
  879. gettime(&x, 0, 0);
  880. hnputts(ntpout.xmitts, x);
  881. if(write(fd, &ntpout, NTPSIZE) < 0){
  882. alarm(0);
  883. continue;
  884. }
  885. n = read(fd, &ntpin, sizeof ntpin);
  886. alarm(0);
  887. gettime(&destts, 0, 0);
  888. if(n >= NTPSIZE){
  889. close(fd);
  890. /* we got one, use it */
  891. recvts = nhgetts(ntpin.recvts);
  892. origts = nhgetts(ntpin.origts);
  893. xmitts = nhgetts(ntpin.xmitts);
  894. dt = ((recvts - origts) + (xmitts - destts))/2;
  895. /* save results */
  896. ns->rtt = ((destts - origts) - (xmitts - recvts))/2;
  897. ns->dt = dt;
  898. ns->stratum = ntpin.stratum;
  899. ns->precision = ntpin.precision;
  900. ns->rootdelay = nhgetfp(ntpin.rootdelay);
  901. ns->rootdisp = nhgetfp(ntpin.rootdisp);
  902. if(debug)
  903. fprint(2, "ntp %s stratum %d ntpdelay(%lld)\n",
  904. ns->name, ntpin.stratum, ns->rtt);
  905. return 0;
  906. }
  907. /* try again */
  908. sleep(250);
  909. }
  910. close(fd);
  911. return -1;
  912. }
  913. static int64_t
  914. gpssample(void)
  915. {
  916. int64_t l, g, d;
  917. int i, n;
  918. char *v[4], buf[128];
  919. d = -1000000000000000000LL;
  920. for(i = 0; i < 5; i++){
  921. sleep(1100);
  922. seek(gpsfil, 0, 0);
  923. n = read(gpsfil, buf, sizeof buf - 1);
  924. if (n <= 0)
  925. return 0;
  926. buf[n] = 0;
  927. n = tokenize(buf, v, nelem(v));
  928. if(n != 4 || strcmp(v[3], "A") != 0)
  929. return 0;
  930. g = atoll(v[1]);
  931. l = atoll(v[2]);
  932. if(g-l > d)
  933. d = g-l;
  934. }
  935. return d;
  936. }
  937. static int64_t
  938. ntpsample(void)
  939. {
  940. NTPserver *tns, *ns;
  941. int64_t metric, x;
  942. metric = 1000LL*SEC;
  943. ns = nil;
  944. for(tns = ntpservers; tns != nil; tns = tns->next){
  945. if(ntptimediff(tns) < 0)
  946. continue;
  947. x = vabs(tns->rootdisp) + (vabs(tns->rtt+tns->rootdelay)>>1);
  948. if(debug)
  949. fprint(2, "ntp %s rootdelay %lld rootdisp %lld metric %lld\n",
  950. tns->name, tns->rootdelay, tns->rootdisp, x);
  951. if(x < metric){
  952. metric = x;
  953. ns = tns;
  954. }
  955. }
  956. if(ns == nil)
  957. return 0;
  958. /* save data for our server */
  959. rootdisp = ns->rootdisp;
  960. rootdelay = ns->rootdelay;
  961. mydelay = ns->rtt;
  962. mydisp = avgerr;
  963. if(ns->stratum == 0)
  964. stratum = 0;
  965. else
  966. stratum = ns->stratum + 1;
  967. etha = abs(ns->rtt/2);
  968. return ns->dt;
  969. }
  970. /*
  971. * sample the utc file
  972. */
  973. static int64_t
  974. utcsample(void)
  975. {
  976. int64_t s;
  977. int n;
  978. char *v[2], buf[128];
  979. s = 0;
  980. seek(utcfil, 0, 0);
  981. n = read(utcfil, buf, sizeof buf - 1);
  982. if (n <= 0)
  983. return 0;
  984. buf[n] = 0;
  985. n = tokenize(buf, v, nelem(v));
  986. if (strcmp(v[0], "0") == 0)
  987. return 0;
  988. if (n == 2) {
  989. gettime(&s, nil, nil);
  990. s -= atoll(v[1]);
  991. }
  992. lastutc = atoll(v[0]) + s;
  993. return lastutc;
  994. }
  995. /*
  996. * sntp server
  997. */
  998. static int
  999. openlisten(char *net)
  1000. {
  1001. int fd, cfd;
  1002. char data[128], devdir[40];
  1003. sprint(data, "%s/udp!*!ntp", net);
  1004. cfd = announce(data, devdir);
  1005. if(cfd < 0)
  1006. sysfatal("can't announce");
  1007. if(fprint(cfd, "headers") < 0)
  1008. sysfatal("can't set header mode");
  1009. sprint(data, "%s/data", devdir);
  1010. fd = open(data, ORDWR);
  1011. if(fd < 0)
  1012. sysfatal("open %s: %r", data);
  1013. return fd;
  1014. }
  1015. static void
  1016. ntpserver(char *servenet)
  1017. {
  1018. int fd, n, vers, mode;
  1019. int64_t recvts, x;
  1020. char buf[512];
  1021. NTPpkt *ntp;
  1022. fd = openlisten(servenet);
  1023. if (Rootid == nil)
  1024. switch(type){
  1025. case Fs:
  1026. Rootid = "WWV";
  1027. break;
  1028. case Rtc:
  1029. Rootid = "LOCL";
  1030. break;
  1031. case Utc:
  1032. Rootid = "UTC";
  1033. break;
  1034. case Gps:
  1035. Rootid = "GPS";
  1036. break;
  1037. case Ntp:
  1038. /* set by the ntp client */
  1039. break;
  1040. }
  1041. if (Rootid != nil)
  1042. memmove(rootid, Rootid, strlen(Rootid) > 4? 4: strlen(Rootid));
  1043. for(;;){
  1044. n = read(fd, buf, sizeof buf);
  1045. gettime(&recvts, 0, 0);
  1046. if(n <= 0) {
  1047. /* don't croak on input error, but don't spin either */
  1048. sleep(500);
  1049. continue;
  1050. }
  1051. if(n < Udphdrsize + NTPSIZE)
  1052. continue;
  1053. ntp = (NTPpkt*)(buf + Udphdrsize);
  1054. mode = ntp->mode & 7;
  1055. vers = (ntp->mode>>3) & 7;
  1056. if(mode != 3)
  1057. continue;
  1058. ntp->mode = (vers<<3)|4;
  1059. ntp->stratum = stratum;
  1060. ntp->precision = myprec;
  1061. hnputfp(ntp->rootdelay, rootdelay + mydelay);
  1062. hnputfp(ntp->rootdisp, rootdisp + mydisp);
  1063. hnputts(ntp->refts, lastutc);
  1064. memmove(ntp->origts, ntp->xmitts, sizeof(ntp->origts));
  1065. hnputts(ntp->recvts, recvts);
  1066. memmove(ntp->rootid, rootid, sizeof(ntp->rootid));
  1067. gettime(&x, 0, 0);
  1068. hnputts(ntp->xmitts, x);
  1069. write(fd, buf, NTPSIZE + Udphdrsize);
  1070. }
  1071. }
  1072. /*
  1073. * get the current time from the file system
  1074. */
  1075. static int32_t
  1076. fstime(void)
  1077. {
  1078. Dir *d;
  1079. uint32_t t;
  1080. d = dirstat("/n/boot");
  1081. if(d != nil){
  1082. t = d->atime;
  1083. free(d);
  1084. } else
  1085. t = 0;
  1086. return t;
  1087. }
  1088. /*
  1089. * get the current time from the real time clock
  1090. */
  1091. static int32_t
  1092. rtctime(void)
  1093. {
  1094. char b[20];
  1095. static int f = -1;
  1096. int i, retries;
  1097. memset(b, 0, sizeof(b));
  1098. for(retries = 0; retries < 100; retries++){
  1099. if(f < 0)
  1100. f = open("/dev/rtc", OREAD|OCEXEC);
  1101. if(f < 0)
  1102. break;
  1103. if(seek(f, 0, 0) < 0 || (i = read(f, b, sizeof b)) < 0){
  1104. close(f);
  1105. f = -1;
  1106. } else
  1107. if(i != 0)
  1108. break;
  1109. }
  1110. return strtoul(b, 0, 10)+gmtdelta;
  1111. }
  1112. /*
  1113. * Sample a clock. We wait for the clock to always
  1114. * be at the leading edge of a clock period.
  1115. */
  1116. static int64_t
  1117. sample(int32_t (*get)(void))
  1118. {
  1119. int32_t this, last;
  1120. int64_t start, end;
  1121. /*
  1122. * wait for the second to change
  1123. */
  1124. last = (*get)();
  1125. for(;;){
  1126. gettime(&start, 0, 0);
  1127. this = (*get)();
  1128. gettime(&end, 0, 0);
  1129. if(this != last)
  1130. break;
  1131. last = this;
  1132. }
  1133. return SEC*this - (end-start)/2;
  1134. }
  1135. /*
  1136. * the name of the frequency file has the method and possibly the
  1137. * server name encoded in it.
  1138. */
  1139. static int
  1140. openfreqfile(void)
  1141. {
  1142. char *p;
  1143. int fd;
  1144. if(sysid == nil)
  1145. return -1;
  1146. switch(type){
  1147. case Ntp:
  1148. p = smprint("%s/ts.%s.%d.%s", dir, sysid, type, timeserver);
  1149. break;
  1150. default:
  1151. p = smprint("%s/ts.%s.%d", dir, sysid, type);
  1152. break;
  1153. }
  1154. fd = open(p, ORDWR);
  1155. if(fd < 0)
  1156. fd = create(p, ORDWR, 0666);
  1157. free(p);
  1158. if(fd < 0)
  1159. return -1;
  1160. return fd;
  1161. }
  1162. /*
  1163. * the file contains the last known frequency and the
  1164. * number of seconds it was sampled over
  1165. */
  1166. static int64_t
  1167. readfreqfile(int fd, int64_t ohz, int64_t minhz, int64_t maxhz)
  1168. {
  1169. int n;
  1170. char buf[128];
  1171. int64_t hz;
  1172. n = read(fd, buf, sizeof buf-1);
  1173. if(n <= 0)
  1174. return ohz;
  1175. buf[n] = 0;
  1176. hz = strtoll(buf, nil, 0);
  1177. if(hz > maxhz || hz < minhz)
  1178. return ohz;
  1179. settime(-1, hz, 0, 0);
  1180. return hz;
  1181. }
  1182. /*
  1183. * remember hz and averaging period
  1184. */
  1185. static void
  1186. writefreqfile(int fd, int64_t hz, int secs, int64_t diff)
  1187. {
  1188. int32_t now;
  1189. static int32_t last;
  1190. if(fd < 0)
  1191. return;
  1192. now = time(0);
  1193. if(now - last < 10*60)
  1194. return;
  1195. last = now;
  1196. if(seek(fd, 0, 0) < 0)
  1197. return;
  1198. fprint(fd, "%lld %d %d %lld\n", hz, secs, type, diff);
  1199. }
  1200. static uint64_t
  1201. vabs(int64_t x)
  1202. {
  1203. if(x < 0)
  1204. return -x;
  1205. else
  1206. return x;
  1207. }
  1208. static void
  1209. background(void)
  1210. {
  1211. static int inbackground;
  1212. if(inbackground)
  1213. return;
  1214. if(!debug)
  1215. switch(rfork(RFPROC|RFFDG|RFNAMEG|RFNOTEG|RFNOWAIT)){
  1216. case -1:
  1217. sysfatal("forking: %r");
  1218. break;
  1219. case 0:
  1220. break;
  1221. default:
  1222. exits(0);
  1223. }
  1224. inbackground = 1;
  1225. }
  1226. static int
  1227. getclockprecision(int64_t hz)
  1228. {
  1229. int i;
  1230. i = 8;
  1231. while(hz > 0){
  1232. i--;
  1233. hz >>= 1;
  1234. }
  1235. return i;
  1236. }