Page MenuHomeFreeBSD

D57532.id179579.diff
No OneTemporary

D57532.id179579.diff

diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c
--- a/sys/kern/subr_rtc.c
+++ b/sys/kern/subr_rtc.c
@@ -317,54 +317,80 @@
/*
* Initialize the system time. Must be called from a context which does not
- * restrict any locking or sleeping that clock drivers may need to do.
+ * restrict any locking or sleeping that clock drivers may need to do. The
+ * caller should finish it with an inittodr_post() using the same cookie and
+ * a reasonable fake time if possible, just in case.
*
* First attempt to get the time from a registered realtime clock. The clocks
- * are queried in order of resolution until one provides the time. If no clock
- * can provide the current time, use the 'base' time provided by the caller, if
- * non-zero. The 'base' time is potentially highly inaccurate, such as the last
- * known good value of the system clock, or even a filesystem last-updated
- * timestamp. It is used to prevent system time from appearing to move
- * backwards in logs.
+ * are queried in order of resolution until one provides the time. This is done
+ * early enough that we won't report errors just yet, the caller will need to
+ * call inittodr_late() anyways.
*/
void
-inittodr(time_t base)
+inittodr_early(inittodr_cookie_t *cookiep)
{
struct timespec ts;
int error;
- error = read_clocks(&ts, false);
-
/*
* Do not report errors from each clock; it is expected that some clocks
* cannot provide results in some situations. Only report problems when
* no clocks could provide the time.
*/
- if (error != 0) {
- switch (error) {
- case ENXIO:
- printf("Warning: no time-of-day clock registered, ");
- break;
- case EINVAL:
- printf("Warning: bad time from time-of-day clock, ");
- break;
- default:
- printf("Error reading time-of-day clock (%d), ", error);
- break;
- }
- printf("system time will not be set accurately\n");
- ts.tv_sec = (base > 0) ? base : -1;
- ts.tv_nsec = 0;
- }
+ error = read_clocks(&ts, false);
+ *cookiep = error;
+ if (error != 0)
+ return;
- if (ts.tv_sec >= 0) {
- tc_setclock(&ts);
+ MPASS(ts.tv_sec >= 0);
+ tc_setclock(&ts);
#ifdef FFCLOCK
- ffclock_reset_clock(&ts);
+ ffclock_reset_clock(&ts);
#endif
+}
+
+void
+inittodr_late(inittodr_cookie_t cookie, time_t base)
+{
+ struct timespec basets = { .tv_sec = base };
+ int error;
+
+ error = cookie;
+ if (error == 0)
+ return; /* Clock was set, nothing to do here. */
+
+ switch (error) {
+ case ENXIO:
+ printf("Warning: no time-of-day clock registered, ");
+ break;
+ case EINVAL:
+ printf("Warning: bad time from time-of-day clock, ");
+ break;
+ default:
+ printf("Error reading time-of-day clock (%d), ", error);
+ break;
}
+ printf("system time will not be set accurately\n");
+ if (base <= 0)
+ return;
+
+ tc_setclock(&basets);
+#ifdef FFCLOCK
+ ffclock_reset_clock(&basets);
+#endif
+}
+
+/* Simple wrapper around inittodr_early + inittodr_late, see the former above.*/
+void
+inittodr(time_t base)
+{
+ inittodr_cookie_t cookie;
+
+ inittodr_early(&cookie);
+ inittodr_late(cookie, base);
}
+
/*
* Write system time back to all registered clocks, unless disabled by admin.
* This can be called from a context that restricts locking and/or sleeping; the
diff --git a/sys/sys/time.h b/sys/sys/time.h
--- a/sys/sys/time.h
+++ b/sys/sys/time.h
@@ -531,6 +531,14 @@
/*
* Kernel to clock driver interface.
*/
+/*
+ * The _early and _late variants are meant to be chained such that work is
+ * done between them that will use the RTC if it's available, and the caller
+ * passes the cookie on from _early to _late.
+ */
+typedef uintptr_t inittodr_cookie_t;
+void inittodr_early(inittodr_cookie_t *cookiep);
+void inittodr_late(inittodr_cookie_t cookie, time_t base);
void inittodr(time_t base);
void resettodr(void);

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 6, 7:27 AM (9 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34743666
Default Alt Text
D57532.id179579.diff (3 KB)

Event Timeline