/* * inittodr: * * Initialize time from the time-of-day register. */ #define MINYEAR 2003 /* minimum plausible year */ void inittodr(time_t base) { time_t deltat; struct timeval rtctime; struct timespec ts; int badbase; if (base < (MINYEAR - 1970) * SECYR) { printf("WARNING: preposterous time in file system\n"); /* read the system clock anyway */ base = (MINYEAR - 1970) * SECYR; badbase = 1; } else badbase = 0; if (todr_handle == NULL || todr_gettime(todr_handle, &rtctime) != 0 || rtctime.tv_sec == 0) { /* * Believe the time in the file system for lack of * anything better, resetting the TODR. */ rtctime.tv_sec = base; rtctime.tv_usec = 0; if (todr_handle != NULL && !badbase) { printf("WARNING: preposterous clock chip time\n"); resettodr(); } ts.tv_sec = rtctime.tv_sec; ts.tv_nsec = rtctime.tv_usec * 1000; tc_setclock(&ts); goto bad; } else { ts.tv_sec = rtctime.tv_sec; ts.tv_nsec = rtctime.tv_usec * 1000; tc_setclock(&ts); } if (!badbase) { /* * See if we gained/lost two or more days; if * so, assume something is amiss. */ deltat = rtctime.tv_sec - base; if (deltat < 0) deltat = -deltat; if (deltat < 2 * SECDAY) return; /* all is well */ printf("WARNING: clock %s %ld days\n", rtctime.tv_sec < base ? "lost" : "gained", (long)deltat / SECDAY); } bad: printf("WARNING: CHECK AND RESET THE DATE!\n"); }
/* This function is used by clock_settime and settimeofday */ static int settime1(struct proc *p, const struct timespec *ts, bool check_kauth) { struct timespec delta, now; int s; /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ s = splclock(); nanotime(&now); timespecsub(ts, &now, &delta); if (check_kauth && kauth_authorize_system(kauth_cred_get(), KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, __UNCONST(ts), &delta, KAUTH_ARG(check_kauth ? false : true)) != 0) { splx(s); return (EPERM); } #ifdef notyet if ((delta.tv_sec < 86400) && securelevel > 0) { /* XXX elad - notyet */ splx(s); return (EPERM); } #endif tc_setclock(ts); timespecadd(&boottime, &delta, &boottime); resettodr(); splx(s); return (0); }
void inittodr(time_t base) { struct clock_ymdhms dt; struct timespec ts; time_t rtc; if (!sh_clock.rtc_initialized) sh_clock.rtc_initialized = 1; sh_clock.rtc.get(sh_clock.rtc._cookie, base, &dt); rtc = clock_ymdhms_to_secs(&dt); #ifdef DEBUG printf("inittodr: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec, dt.dt_wday); #endif if (!(sh_clock.flags & SH_CLOCK_NOINITTODR) && (rtc < base || dt.dt_year < MINYEAR || dt.dt_year > 2037 || dt.dt_mon < 1 || dt.dt_mon > 12 || dt.dt_wday > 6 || dt.dt_day < 1 || dt.dt_day > 31 || dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59)) { /* * Believe the time in the file system for lack of * anything better, resetting the RTC. */ ts.tv_sec = base; ts.tv_nsec = 0; tc_setclock(&ts); printf("WARNING: preposterous clock chip time\n"); resettodr(); printf(" -- CHECK AND RESET THE DATE!\n"); return; } ts.tv_sec = rtc; ts.tv_nsec = 0; tc_setclock(&ts); return; }
/* * Initialize the time of day register, based on the time base which is, e.g. * from a filesystem. */ void inittodr(time_t base) { struct timespec ts; int error; if (clock_dev == NULL) { printf("warning: no time-of-day clock registered, system time " "will not be set accurately\n"); goto wrong_time; } /* XXX: We should poll all registered RTCs in case of failure */ mtx_lock(&resettodr_lock); error = CLOCK_GETTIME(clock_dev, &ts); mtx_unlock(&resettodr_lock); if (error != 0 && error != EINVAL) { printf("warning: clock_gettime failed (%d), the system time " "will not be set accurately\n", error); goto wrong_time; } if (error == EINVAL || ts.tv_sec < 0) { printf("Invalid time in real time clock.\n" "Check and reset the date immediately!\n"); goto wrong_time; } ts.tv_sec += utc_offset(); timespecadd(&ts, &clock_adj); tc_setclock(&ts); #ifdef FFCLOCK ffclock_reset_clock(&ts); #endif return; wrong_time: if (base > 0) { ts.tv_sec = base; ts.tv_nsec = 0; tc_setclock(&ts); } }
static void vmt_sync_guest_clock(struct vmt_softc *sc) { struct vm_backdoor frame; struct timespec ts; memset(&frame, 0, sizeof(frame)); frame.eax.word = VM_MAGIC; frame.ecx.part.low = VM_CMD_GET_TIME_FULL; frame.edx.part.low = VM_PORT_CMD; vm_cmd(&frame); if (frame.eax.word != 0xffffffff) { ts.tv_sec = ((uint64_t)frame.esi.word << 32) | frame.edx.word; ts.tv_nsec = frame.ebx.word * 1000; tc_setclock(&ts); } }
/* * Set up the system's time, given a `reasonable' time value. */ void inittodr(time_t base) { bool badbase = false; bool waszero = (base == 0); bool goodtime = false; bool badrtc = false; int s; struct timespec ts; struct timeval tv; rnd_add_data(NULL, &base, sizeof(base), 0); if (base < 5 * SECS_PER_COMMON_YEAR) { struct clock_ymdhms basedate; /* * If base is 0, assume filesystem time is just unknown * instead of preposterous. Don't bark. */ if (base != 0) printf("WARNING: preposterous time in file system\n"); /* not going to use it anyway, if the chip is readable */ basedate.dt_year = 2010; basedate.dt_mon = 1; basedate.dt_day = 1; basedate.dt_hour = 12; basedate.dt_min = 0; basedate.dt_sec = 0; base = clock_ymdhms_to_secs(&basedate); badbase = true; } /* * Some ports need to be supplied base in order to fabricate a time_t. */ if (todr_handle) todr_handle->base_time = base; if ((todr_handle == NULL) || (todr_gettime(todr_handle, &tv) != 0) || (tv.tv_sec < (25 * SECS_PER_COMMON_YEAR))) { if (todr_handle != NULL) printf("WARNING: preposterous TOD clock time\n"); else printf("WARNING: no TOD clock present\n"); badrtc = true; } else { time_t deltat = tv.tv_sec - base; if (deltat < 0) deltat = -deltat; if (!badbase && deltat >= 2 * SECS_PER_DAY) { if (tv.tv_sec < base) { /* * The clock should never go backwards * relative to filesystem time. If it * does by more than the threshold, * believe the filesystem. */ printf("WARNING: clock lost %" PRId64 " days\n", deltat / SECS_PER_DAY); badrtc = true; } else { aprint_verbose("WARNING: clock gained %" PRId64 " days\n", deltat / SECS_PER_DAY); goodtime = true; } } else { goodtime = true; } rnd_add_data(NULL, &tv, sizeof(tv), 0); } /* if the rtc time is bad, use the filesystem time */ if (badrtc) { if (badbase) { printf("WARNING: using default initial time\n"); } else { printf("WARNING: using filesystem time\n"); } tv.tv_sec = base; tv.tv_usec = 0; } timeset = true; ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; s = splclock(); tc_setclock(&ts); splx(s); if (waszero || goodtime) return; printf("WARNING: CHECK AND RESET THE DATE!\n"); }
/* * Mount a remote root fs via. NFS. It goes like this: * - Call nfs_boot_init() to fill in the nfs_diskless struct * - build the rootfs mount point and call mountnfs() to do the rest. */ int nfs_mountroot(void) { struct timespec ts; struct nfs_diskless *nd; struct vattr attr; struct mount *mp; struct vnode *vp; struct lwp *l; long n; int error; l = curlwp; /* XXX */ if (device_class(root_device) != DV_IFNET) return (ENODEV); /* * XXX time must be non-zero when we init the interface or else * the arp code will wedge. [Fixed now in if_ether.c] * However, the NFS attribute cache gives false "hits" when the * current time < nfs_attrtimeo(nmp, np) so keep this in for now. */ if (time_second < NFS_MAXATTRTIMO) { ts.tv_sec = NFS_MAXATTRTIMO; ts.tv_nsec = 0; tc_setclock(&ts); } /* * Call nfs_boot_init() to fill in the nfs_diskless struct. * Side effect: Finds and configures a network interface. */ nd = kmem_zalloc(sizeof(*nd), KM_SLEEP); error = nfs_boot_init(nd, l); if (error) { kmem_free(nd, sizeof(*nd)); return (error); } /* * Create the root mount point. */ error = nfs_mount_diskless(&nd->nd_root, "/", &mp, &vp, l); if (error) goto out; printf("root on %s\n", nd->nd_root.ndm_host); /* * Link it into the mount list. */ mountlist_append(mp); rootvp = vp; mp->mnt_vnodecovered = NULLVP; vfs_unbusy(mp, false, NULL); /* Get root attributes (for the time). */ vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, &attr, l->l_cred); VOP_UNLOCK(vp); if (error) panic("nfs_mountroot: getattr for root"); n = attr.va_atime.tv_sec; #ifdef DEBUG printf("root time: 0x%lx\n", n); #endif setrootfstime(n); out: if (error) nfs_boot_cleanup(nd, l); kmem_free(nd, sizeof(*nd)); return (error); }