> Date: Sun, 8 Nov 2015 22:57:24 +0100
> From: Christian Weisgerber <na...@mips.inka.de>
> 
> I would like to sync the system time periodically back to the RTC.
> 
> Currently we update the RTC
> (1) when the time is set with clock_settime() or settimeofday(), which
>     never happens for a typical ntpd setup,
> (2) before suspend,
> (3) when the system is properly shut down.
> 
> This means if a machine has been running for a few months and it
> loses power, it may come back up with the time, say, 200 seconds
> off because of RTC drift, and then your SixXS tunnel won't come up
> and you can no longer reach your home network on the last day of
> u2k15.  For example.
> 
> FreeBSD uses a period of 30 minutes.  I have no idea what a good
> number would be so I went with that.  (Maybe a prime number of
> seconds?)  FreeBSD also has a sysctl knob to change the period,
> which is silly.
> 
> The patch below, inspired by FreeBSD, "seems to work for me", but
> I don't really know what I'm doing and if it's okay to just use a
> timeout(9) like that.

No.  Some of the implementattions of resettodr() may sleep.

> Do I need a task?

Probably.

> Any locking?

Kernel lock should be good enough.

> I'm also uncertain where to put the hook to kick off the initial
> timeout_add().

Most logical place would be inittodr() but that's MD code.  Unifying
that code (and therefore unifying the checks for silly times and
falling back to the filesystem time) would be good, but probably too
much to ask from you.  It's a serious can of worms!

You should also delete the timeout and task before rebooting.  And
across suspend/resume.


> Index: kern/init_main.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/init_main.c,v
> retrieving revision 1.246
> diff -u -p -r1.246 init_main.c
> --- kern/init_main.c  8 Nov 2015 20:45:57 -0000       1.246
> +++ kern/init_main.c  8 Nov 2015 21:06:47 -0000
> @@ -118,6 +118,8 @@ struct    sigacts sigacts0;
>  struct       process *initprocess;
>  struct       proc *reaperproc;
>  
> +void start_periodic_resettodr(void);
> +
>  extern       struct user *proc0paddr;
>  
>  struct       vnode *rootvp, *swapdev_vp;
> @@ -550,6 +552,8 @@ main(void *framep)
>  #if !(defined(__m88k__) && defined(MULTIPROCESSOR))  /* XXX */
>       pool_gc_pages(NULL);
>  #endif
> +
> +     start_periodic_resettodr();
>  
>          /*
>           * proc0: nothing to do, back to sleep
> Index: kern/kern_time.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_time.c,v
> retrieving revision 1.95
> diff -u -p -r1.95 kern_time.c
> --- kern/kern_time.c  1 Nov 2015 19:03:33 -0000       1.95
> +++ kern/kern_time.c  8 Nov 2015 16:46:46 -0000
> @@ -41,6 +41,7 @@
>  #include <sys/vnode.h>
>  #include <sys/signalvar.h>
>  #include <sys/pledge.h>
> +#include <sys/timeout.h>
>  #include <sys/timetc.h>
>  
>  #include <sys/mount.h>
> @@ -792,3 +793,21 @@ ppsratecheck(struct timeval *lasttime, i
>       return (rv);
>  }
>  
> +
> +#define RESETTODR_PERIOD     1800
> +
> +void periodic_resettodr(void *);
> +struct timeout resettodr_to = TIMEOUT_INITIALIZER(periodic_resettodr, NULL);
> +
> +void
> +periodic_resettodr(void *arg __unused)
> +{
> +     resettodr();
> +     timeout_add_sec(&resettodr_to, RESETTODR_PERIOD);
> +}
> +
> +void
> +start_periodic_resettodr(void)
> +{
> +     timeout_add_sec(&resettodr_to, RESETTODR_PERIOD);
> +}
> -- 
> Christian "naddy" Weisgerber                          na...@mips.inka.de
> 
> 

Reply via email to