--- ntpd.c
+++ ntpd.c
@@ -153,6 +153,9 @@
 	chld_pid = ntp_main(pipe_chld, &conf);
 
 	setproctitle("[priv]");
+#ifdef USE_ADJTIMEX
+	readfreq();
+#endif
 
 	signal(SIGTERM, sighdlr);
 	signal(SIGINT, sighdlr);
--- ntpd.h
+++ ntpd.h
@@ -34,6 +34,9 @@
 #define	NTPD_USER	"_ntp"
 #endif
 #define	CONFFILE	SYSCONFDIR "/ntpd.conf"
+#ifdef USE_ADJTIMEX
+#define	DRIFTFILE	"/var/db/ntpd.drift"
+#endif
 
 #define	READ_BUF_SIZE		4096
 
--- openbsd-compat/openbsd-compat.h
+++ openbsd-compat/openbsd-compat.h
@@ -49,6 +49,8 @@
 #ifdef USE_ADJTIMEX
 # include <sys/time.h>
 int _compat_adjtime(const struct timeval *, struct timeval *);
+void writefreq(double d);
+void readfreq(void);
 #endif
 
 #ifndef HAVE_INET_PTON
--- openbsd-compat/port-linux.c
+++ openbsd-compat/port-linux.c
@@ -33,6 +33,49 @@
 /* maximum change to skew per adjustment, in PPM */
 #define MAX_SKEW_DELTA 5.0
 
+void
+writefreq(double d)
+{
+	int r;
+	FILE *fp;
+
+	fp = fopen(DRIFTFILE, "w");
+	if (fp == NULL)
+	{
+		log_warn("opening drift file for writing failed");
+		return;
+	}
+
+	fprintf(fp, "%e\n", d);
+	r = ferror(fp);
+	if (fclose(fp) != 0 || r != 0)
+	{
+		unlink(DRIFTFILE);
+		log_warn("saving freq drift failed");
+	}
+}
+
+void
+readfreq(void)
+{
+	FILE *fp;
+	double d;
+	struct timex tmx;
+
+	fp = fopen(DRIFTFILE, "r");
+	if (fp == NULL)
+		return;
+
+	if (fscanf(fp, "%le", &d) == 1)
+	{
+		tmx.freq = (long)(d * ADJTIMEX_FREQ_SCALE);
+		tmx.modes = ADJ_FREQUENCY;
+		if (adjtimex(&tmx) == -1)
+			log_warn("adjtimex set freq failed");
+	}
+	fclose(fp);
+}
+
 int
 _compat_adjtime(const struct timeval *delta, struct timeval *olddelta)
 {
@@ -93,6 +136,8 @@
 		tmx.modes = ADJ_FREQUENCY;
 		if (adjtimex(&tmx) == -1)
 			log_warn("adjtimex set freq failed");
+
+		writefreq( tskew );
 	}
 
 	log_debug("interval %0.3lf skew %0.3lf total skew %0.3lf", interval,
