]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
sys: add null driver
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 9 Mar 2017 17:16:56 +0000 (18:16 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 10 Mar 2017 15:51:03 +0000 (16:51 +0100)
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.

Makefile.in
doc/chronyd.adoc
main.c
sys.c
sys.h
sys_null.c [new file with mode: 0644]
sys_null.h [new file with mode: 0644]

index 6f67b92135785d104f421719cfb070340c421d69..732d4b9d50cfbaefb8da098b375e1fba95d83acb 100644 (file)
@@ -37,7 +37,7 @@ HASH_OBJ = @HASH_OBJ@
 
 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@
 
index 9cb8effadbf81a9f80ada0edaca6dbe45ce99ef1..2ae5b17604f7f935c4aac4a1cb410e529be3befe 100644 (file)
@@ -151,6 +151,13 @@ support this option.
 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.
 
diff --git a/main.c b/main.c
index 21c89be08468f2e63be22dad20eb1789125a84d8..be99f0d5c831414ed6bf3d4bc28d67ede4f7697a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -376,7 +376,7 @@ int main
   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();
@@ -435,6 +435,8 @@ int main
       ++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)) {
@@ -499,7 +501,7 @@ int main
   PRV_Initialise();
   LCL_Initialise();
   SCH_Initialise();
-  SYS_Initialise();
+  SYS_Initialise(clock_control);
   RTC_Initialise(do_init_rtc);
   SRC_Initialise();
   RCL_Initialise();
diff --git a/sys.c b/sys.c
index f27170d2e9e1b9f9e5d48386e6643754d9bd4e80..5b56aae5c3d651191a71a8f744c5f88beee59742 100644 (file)
--- a/sys.c
+++ b/sys.c
@@ -30,6 +30,7 @@
 #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)
@@ -65,6 +75,10 @@ SYS_Initialise(void)
 void
 SYS_Finalise(void)
 {
+  if (null_driver) {
+    SYS_Null_Finalise();
+    return;
+  }
 #if defined(LINUX)
   SYS_Linux_Finalise();
 #elif defined(SOLARIS)
diff --git a/sys.h b/sys.h
index bd990e2af22c5e611366a23e5601c6b77fcf760c..cb726f27cc68e23744401dea49e0cab4ecdc260c 100644 (file)
--- a/sys.h
+++ b/sys.h
@@ -30,7 +30,7 @@
 #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);
diff --git a/sys_null.c b/sys_null.c
new file mode 100644 (file)
index 0000000..3a0d5f6
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+  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)
+{
+}
diff --git a/sys_null.h b/sys_null.h
new file mode 100644 (file)
index 0000000..0fbf077
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+  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