Hi!
On Sun, Aug 11, 2013 at 04:47:08PM -0400, Ted Unangst wrote:
> Nobody seemed to much care about my previous effort to get OpenBSD to
> play nicely inside a suspended VM.
> http://marc.info/?l=openbsd-misc&m=134324835209706&w=2
>
Well, I do care about VMs!
> Instead of the kernel, this time I'm poking ntpd. To review, the
> problem is if the VM host is suspended, the VM guest (OpenBSD) doesn't
> get clock interrupts and therefore doesn't advance the clock. ntpd
> quite futilely attempts to cope with this:
>
> ntpd[15280]: adjusting local clock by 1396998.486806s
> ntpd[15280]: adjusting local clock by 1396997.386122s
>
Bah. I tend to turn ntpd off and rely on the internal clock
synchronization of the hypervisor. But fixing ntpd inside VMs would
probably be a big win.
> I'd like to add an option like -s that will jump the clock forward,
> not just once, but whenever it falls too far behind. I called it -j.
> If the clock is more than five seconds behind, we just set the time
> instead of trying to skew towards it. Note that we never jump
> backwards, that would be bad.
>
I don't like the fact that it would require another button. Couldn't
ntpd just detect this automatically? Maybe by detecting that it is
running inside a VM, or by whatever else?
Reyk
> Index: ntp.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
> retrieving revision 1.117
> diff -u -p -r1.117 ntp.c
> --- ntp.c 21 Sep 2011 15:41:30 -0000 1.117
> +++ ntp.c 11 Aug 2013 16:16:32 -0000
> @@ -580,6 +580,7 @@ priv_adjtime(void)
> int offset_cnt = 0, i = 0, j;
> struct ntp_offset **offsets;
> double offset_median;
> + enum imsg_type msgtype;
>
> TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
> if (p->trustlevel < TRUSTLEVEL_BADPEER)
> @@ -632,7 +633,11 @@ priv_adjtime(void)
> }
> conf->status.leap = offsets[i]->status.leap;
>
> - imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, -1,
> + if (conf->jumptime && offset_median > 5.0)
> + msgtype = IMSG_JUMPTIME;
> + else
> + msgtype = IMSG_ADJTIME;
> + imsg_compose(ibuf_main, msgtype, 0, 0, -1,
> &offset_median, sizeof(offset_median));
>
> priv_adjfreq(offset_median);
> Index: ntpd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ntpd/ntpd.c,v
> retrieving revision 1.69
> diff -u -p -r1.69 ntpd.c
> --- ntpd.c 19 Mar 2011 23:40:11 -0000 1.69
> +++ ntpd.c 11 Aug 2013 16:12:09 -0000
> @@ -73,7 +73,7 @@ usage(void)
> {
> extern char *__progname;
>
> - fprintf(stderr, "usage: %s [-dnSsv] [-f file]\n", __progname);
> + fprintf(stderr, "usage: %s [-djnSsv] [-f file]\n", __progname);
> exit(1);
> }
>
> @@ -97,7 +97,7 @@ main(int argc, char *argv[])
>
> log_init(1); /* log to stderr until daemonized */
>
> - while ((ch = getopt(argc, argv, "df:nsSv")) != -1) {
> + while ((ch = getopt(argc, argv, "df:jnsSv")) != -1) {
> switch (ch) {
> case 'd':
> lconf.debug = 1;
> @@ -105,6 +105,9 @@ main(int argc, char *argv[])
> case 'f':
> conffile = optarg;
> break;
> + case 'j':
> + lconf.jumptime = 1;
> + break;
> case 'n':
> lconf.noaction = 1;
> break;
> @@ -295,6 +298,14 @@ dispatch_imsg(struct ntpd_conf *lconf)
> fatalx("invalid IMSG_ADJFREQ received");
> memcpy(&d, imsg.data, sizeof(d));
> ntpd_adjfreq(d, 1);
> + break;
> + case IMSG_JUMPTIME:
> + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
> + fatalx("invalid IMSG_JUMPTIME received");
> + if (!lconf->jumptime)
> + break;
> + memcpy(&d, imsg.data, sizeof(d));
> + ntpd_settime(d);
> break;
> case IMSG_SETTIME:
> if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
> Index: ntpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ntpd/ntpd.h,v
> retrieving revision 1.107
> diff -u -p -r1.107 ntpd.h
> --- ntpd.h 30 Apr 2013 11:42:56 -0000 1.107
> +++ ntpd.h 11 Aug 2013 16:11:40 -0000
> @@ -178,6 +178,7 @@ struct ntpd_conf {
> struct ntp_freq freq;
> u_int32_t scale;
> u_int8_t listen_all;
> + u_int8_t jumptime;
> u_int8_t settime;
> u_int8_t debug;
> u_int8_t noaction;
> @@ -188,6 +189,7 @@ enum imsg_type {
> IMSG_NONE,
> IMSG_ADJTIME,
> IMSG_ADJFREQ,
> + IMSG_JUMPTIME,
> IMSG_SETTIME,
> IMSG_HOST_DNS
> };
>