Пример #1
0
/*
 * 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");
}
Пример #2
0
/* 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);
}
Пример #3
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;
}
Пример #4
0
/*
 * 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);
	}
}
Пример #5
0
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);
	}
}
Пример #6
0
/*
 * 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");
}
Пример #7
0
/*
 * 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);
}