Add a new clock driver that doesn't actually try to adjust the clock.
It allows chronyd to run without the capability to adjust/set the system
clock, e.g. in some containers. It can be enabled by the -x option.
OBJS = array.o cmdparse.o conf.o local.o logging.o main.o memory.o \
reference.o regress.o rtc.o sched.o sources.o sourcestats.o stubs.o \
- sys.o smooth.o tempcomp.o util.o $(HASH_OBJ)
+ smooth.o sys.o sys_null.o tempcomp.o util.o $(HASH_OBJ)
EXTRA_OBJS=@EXTRA_OBJECTS@
This option will lock *chronyd* into RAM so that it will never be paged out.
This mode is only supported on Linux.
+*-x*::
+This option disables the control of the system clock. *chronyd* will not make
+any adjustments of the clock, but it will still track its offset and frequency
+relative to the estimated true time, and be able to operate as an NTP server.
+This allows *chronyd* to run without the capability to adjust or set the system
+clock (e.g. in some containers).
+
*-v*::
With this option *chronyd* will print version number to the terminal and exit.
int do_init_rtc = 0, restarted = 0, timeout = 0;
int other_pid;
int scfilter_level = 0, lock_memory = 0, sched_priority = 0;
- int system_log = 1;
+ int clock_control = 1, system_log = 1;
int config_args = 0;
do_platform_checks();
++argv, --argc;
if (argc == 0 || sscanf(*argv, "%d", &timeout) != 1 || timeout <= 0)
LOG_FATAL("Bad timeout");
+ } else if (!strcmp("-x", *argv)) {
+ clock_control = 0;
} else if (!strcmp("-4", *argv)) {
address_family = IPADDR_INET4;
} else if (!strcmp("-6", *argv)) {
PRV_Initialise();
LCL_Initialise();
SCH_Initialise();
- SYS_Initialise();
+ SYS_Initialise(clock_control);
RTC_Initialise(do_init_rtc);
SRC_Initialise();
RCL_Initialise();
#include "sysincl.h"
#include "sys.h"
+#include "sys_null.h"
#include "logging.h"
#if defined(LINUX)
/* ================================================== */
+static int null_driver;
+
+/* ================================================== */
+
void
-SYS_Initialise(void)
+SYS_Initialise(int clock_control)
{
+ null_driver = !clock_control;
+ if (null_driver) {
+ SYS_Null_Initialise();
+ return;
+ }
#if defined(LINUX)
SYS_Linux_Initialise();
#elif defined(SOLARIS)
void
SYS_Finalise(void)
{
+ if (null_driver) {
+ SYS_Null_Finalise();
+ return;
+ }
#if defined(LINUX)
SYS_Linux_Finalise();
#elif defined(SOLARIS)
#define GOT_SYS_H
/* Called at the start of the run to do initialisation */
-extern void SYS_Initialise(void);
+extern void SYS_Initialise(int clock_control);
/* Called at the end of the run to do final clean-up */
extern void SYS_Finalise(void);
--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ Null clock driver for operation with no clock control.
+ */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include "sys_null.h"
+
+#include "local.h"
+#include "localp.h"
+#include "logging.h"
+#include "util.h"
+
+/* Current frequency offset of the system clock (in ppm) */
+static double freq;
+
+/* Offset of the system clock at the last update */
+static double offset_register;
+
+/* Time of the last update */
+static struct timespec last_update;
+
+/* Minimum interval between updates when frequency is constant */
+#define MIN_UPDATE_INTERVAL 1000.0
+
+/* ================================================== */
+
+static void
+update_offset(void)
+{
+ struct timespec now;
+ double duration;
+
+ LCL_ReadRawTime(&now);
+ duration = UTI_DiffTimespecsToDouble(&now, &last_update);
+ offset_register += 1.0e-6 * freq * duration;
+ last_update = now;
+
+ DEBUG_LOG("System clock offset=%e freq=%f", offset_register, freq);
+}
+
+/* ================================================== */
+
+static double
+read_frequency(void)
+{
+ return freq;
+}
+
+/* ================================================== */
+
+static double
+set_frequency(double freq_ppm)
+{
+ update_offset();
+ freq = freq_ppm;
+
+ return freq;
+}
+
+/* ================================================== */
+
+static void
+accrue_offset(double offset, double corr_rate)
+{
+ offset_register += offset;
+}
+
+/* ================================================== */
+
+static int
+apply_step_offset(double offset)
+{
+ return 0;
+}
+
+/* ================================================== */
+
+static void
+offset_convert(struct timespec *raw, double *corr, double *err)
+{
+ double duration;
+
+ duration = UTI_DiffTimespecsToDouble(raw, &last_update);
+
+ if (duration > MIN_UPDATE_INTERVAL) {
+ update_offset();
+ duration = 0.0;
+ }
+
+ *corr = -1.0e-6 * freq * duration - offset_register;
+
+ if (err)
+ *err = 0.0;
+}
+
+/* ================================================== */
+
+void
+SYS_Null_Initialise(void)
+{
+ offset_register = 0.0;
+ LCL_ReadRawTime(&last_update);
+
+ lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset,
+ apply_step_offset, offset_convert, NULL, NULL);
+
+ LOG(LOGS_INFO, "Disabled control of system clock");
+}
+
+/* ================================================== */
+
+void
+SYS_Null_Finalise(void)
+{
+}
--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ Header file for null clock driver
+ */
+
+#ifndef GOT_SYS_NULL_H
+#define GOT_SYS_NULL_H
+
+extern void SYS_Null_Initialise(void);
+
+extern void SYS_Null_Finalise(void);
+
+#endif