]> git.ipfire.org Git - thirdparty/chrony.git/blame - refclock_shm.c
conf: rework allow/deny parser
[thirdparty/chrony.git] / refclock_shm.c
CommitLineData
75330fdf
ML
1/*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
f7e08d0c 5 * Copyright (C) Miroslav Lichvar 2009
75330fdf
ML
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
8e23110a 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
75330fdf
ML
19 *
20 **********************************************************************
21
22 =======================================================================
23
24 SHM refclock driver.
25
26 */
27
da2c8d90
ML
28#include "config.h"
29
6ca73bf6
ML
30#include "sysincl.h"
31
75330fdf
ML
32#include "refclock.h"
33#include "logging.h"
34#include "util.h"
35
75330fdf
ML
36#define SHMKEY 0x4e545030
37
38struct shmTime {
39 int mode; /* 0 - if valid set
40 * use values,
41 * clear valid
42 * 1 - if valid set
43 * if count before and after read of values is equal,
44 * use values
45 * clear valid
46 */
bbbb3633 47 volatile int count;
75330fdf
ML
48 time_t clockTimeStampSec;
49 int clockTimeStampUSec;
50 time_t receiveTimeStampSec;
51 int receiveTimeStampUSec;
52 int leap;
53 int precision;
54 int nsamples;
bbbb3633
ML
55 volatile int valid;
56 int clockTimeStampNSec;
57 int receiveTimeStampNSec;
58 int dummy[8];
75330fdf
ML
59};
60
61static int shm_initialise(RCL_Instance instance) {
a78031ce 62 const char *options[] = {"perm", NULL};
f261251a
ML
63 int id, param, perm;
64 char *s;
75330fdf
ML
65 struct shmTime *shm;
66
a78031ce
ML
67 RCL_CheckDriverOptions(instance, options);
68
67c0f1c0 69 param = atoi(RCL_GetDriverParameter(instance));
f261251a 70 s = RCL_GetDriverOption(instance, "perm");
a123a12f 71 perm = s ? strtol(s, NULL, 8) & 0777 : 0600;
75330fdf 72
f261251a 73 id = shmget(SHMKEY + param, sizeof (struct shmTime), IPC_CREAT | perm);
75330fdf 74 if (id == -1) {
eea343b9 75 LOG_FATAL("shmget() failed : %s", strerror(errno));
75330fdf
ML
76 return 0;
77 }
78
79 shm = (struct shmTime *)shmat(id, 0, 0);
80 if ((long)shm == -1) {
eea343b9 81 LOG_FATAL("shmat() failed : %s", strerror(errno));
75330fdf
ML
82 return 0;
83 }
84
85 RCL_SetDriverData(instance, shm);
86 return 1;
87}
88
89static void shm_finalise(RCL_Instance instance)
90{
91 shmdt(RCL_GetDriverData(instance));
92}
93
94static int shm_poll(RCL_Instance instance)
95{
d0dfa1de 96 struct timespec receive_ts, clock_ts;
75330fdf
ML
97 struct shmTime t, *shm;
98 double offset;
99
100 shm = (struct shmTime *)RCL_GetDriverData(instance);
101
102 t = *shm;
103
104 if ((t.mode == 1 && t.count != shm->count) ||
105 !(t.mode == 0 || t.mode == 1) || !t.valid) {
f282856c 106 DEBUG_LOG("SHM sample ignored mode=%d count=%d valid=%d",
c00d93a8 107 t.mode, t.count, t.valid);
75330fdf
ML
108 return 0;
109 }
110
111 shm->valid = 0;
112
d0dfa1de
ML
113 receive_ts.tv_sec = t.receiveTimeStampSec;
114 clock_ts.tv_sec = t.clockTimeStampSec;
75330fdf 115
bbbb3633 116 if (t.clockTimeStampNSec / 1000 == t.clockTimeStampUSec &&
d0dfa1de
ML
117 t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec) {
118 receive_ts.tv_nsec = t.receiveTimeStampNSec;
119 clock_ts.tv_nsec = t.clockTimeStampNSec;
120 } else {
121 receive_ts.tv_nsec = 1000 * t.receiveTimeStampUSec;
122 clock_ts.tv_nsec = 1000 * t.clockTimeStampUSec;
123 }
124
125 UTI_NormaliseTimespec(&clock_ts);
126 UTI_NormaliseTimespec(&receive_ts);
cfe706f0 127 offset = UTI_DiffTimespecsToDouble(&clock_ts, &receive_ts);
bbbb3633 128
d0dfa1de 129 return RCL_AddSample(instance, &receive_ts, offset, t.leap);
75330fdf
ML
130}
131
132RefclockDriver RCL_SHM_driver = {
133 shm_initialise,
134 shm_finalise,
135 shm_poll
136};