/*
 * Regression test for hrtimer early expiration during and after leap seconds
 *
 * A bug in the hrtimer subsystem caused all TIMER_ABSTIME CLOCK_REALTIME
 * timers to expire one second early during leap second.
 * See http://lwn.net/Articles/504658/.
 *
 * This is a regression test for the bug.
 *
 * Lingzhu Xiang <lxiang@redhat.com> Copyright (c) Red Hat, Inc., 2012.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <sys/types.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include "test.h"
#include "common_timers.h"

#define SECONDS_BEFORE_LEAP 2
#define SECONDS_AFTER_LEAP 2

char *TCID = "leapsec_timer";
int TST_TOTAL = 1;

static inline int in_order(struct timespec a, struct timespec b);
static void adjtimex_status(struct timex *tx, int status);
static const char *strtime(const struct timespec *now);
static void test_hrtimer_early_expiration(void);
static void run_leapsec(void);
static void setup(void);
static void cleanup(void);

int main(int argc, char **argv)
{
	const char *msg;
	int lc;

	msg = parse_opts(argc, argv, NULL, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		run_leapsec();
	}

	cleanup();
	tst_exit();
}

static inline int in_order(struct timespec a, struct timespec b)
{
	if (a.tv_sec < b.tv_sec)
		return 1;
	if (a.tv_sec > b.tv_sec)
		return 0;
	if (a.tv_nsec > b.tv_nsec)
		return 0;
	return 1;
}

static void adjtimex_status(struct timex *tx, int status)
{
	const char *const msgs[6] = {
		"clock synchronized",
		"insert leap second",
		"delete leap second",
		"leap second in progress",
		"leap second has occurred",
		"clock not synchronized",
	};
	int r;
	struct timespec now;

	tx->modes = ADJ_STATUS;
	tx->status = status;
	r = adjtimex(tx);
	now.tv_sec = tx->time.tv_sec;
	now.tv_nsec = tx->time.tv_usec * 1000;

	if ((tx->status & status) != status)
		tst_brkm(TBROK, cleanup, "adjtimex status %d not set", status);
	else if (r < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "adjtimex");
	else if (r < 6)
		tst_resm(TINFO, "%s adjtimex: %s", strtime(&now), msgs[r]);
	else
		tst_resm(TINFO, "%s adjtimex: clock state %d",
			 strtime(&now), r);
}

static const char *strtime(const struct timespec *now)
{
	static char fmt[256], buf[256];

	if (snprintf(fmt, sizeof(fmt), "%%F %%T.%09ld %%z", now->tv_nsec) < 0) {
		buf[0] = '\0';
		return buf;
	}
	if (!strftime(buf, sizeof(buf), fmt, localtime(&now->tv_sec))) {
		buf[0] = '\0';
		return buf;
	}
	return buf;
}

static void test_hrtimer_early_expiration(void)
{
	struct timespec now, target;
	int r, fail;

	clock_gettime(CLOCK_REALTIME, &now);
	tst_resm(TINFO, "now is     %s", strtime(&now));

	target = now;
	target.tv_sec++;
	tst_resm(TINFO, "sleep till %s", strtime(&target));
	r = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &target, NULL);
	if (r < 0) {
		tst_resm(TINFO | TERRNO, "clock_nanosleep");
		return;
	}

	clock_gettime(CLOCK_REALTIME, &now);
	tst_resm(TINFO, "now is     %s", strtime(&now));

	fail = !in_order(target, now);
	tst_resm(fail ? TFAIL : TINFO, "hrtimer early expiration is %s.",
		 fail ? "detected" : "not detected");
}

static void run_leapsec(void)
{
	const struct timespec sleeptime = { 0, NSEC_PER_SEC / 2 };
	struct timespec now, leap, start;
	struct timex tx;

	clock_gettime(CLOCK_REALTIME, &now);
	start = now;
	tst_resm(TINFO, "test start at %s", strtime(&now));

	test_hrtimer_early_expiration();

	/* calculate the next leap second */
	now.tv_sec += 86400 - now.tv_sec % 86400;
	now.tv_nsec = 0;
	leap = now;
	tst_resm(TINFO, "scheduling leap second %s", strtime(&leap));

	/* start before the leap second */
	now.tv_sec -= SECONDS_BEFORE_LEAP;
	if (clock_settime(CLOCK_REALTIME, &now) < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "clock_settime");
	tst_resm(TINFO, "setting time to        %s", strtime(&now));

	/* reset NTP time state */
	adjtimex_status(&tx, STA_PLL);
	adjtimex_status(&tx, 0);

	/* set the leap second insert flag */
	adjtimex_status(&tx, STA_INS);

	/* reliably sleep till after the leap second */
	while (tx.time.tv_sec < leap.tv_sec + SECONDS_AFTER_LEAP) {
		adjtimex_status(&tx, tx.status);
		clock_nanosleep(CLOCK_MONOTONIC, 0, &sleeptime, NULL);
	}

	test_hrtimer_early_expiration();

	adjtimex_status(&tx, STA_PLL);
	adjtimex_status(&tx, 0);

	/* recover from timer expiring state and restore time */
	clock_gettime(CLOCK_REALTIME, &now);
	start.tv_sec += now.tv_sec - (leap.tv_sec - SECONDS_BEFORE_LEAP);
	start.tv_nsec += now.tv_nsec;
	start.tv_sec += start.tv_nsec / NSEC_PER_SEC;
	start.tv_nsec = start.tv_nsec % NSEC_PER_SEC;
	tst_resm(TINFO, "restoring time to %s", strtime(&start));
	/* calls clock_was_set() in kernel to revert inconsistency */
	if (clock_settime(CLOCK_REALTIME, &start) < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "clock_settime");

	test_hrtimer_early_expiration();
}

static void setup(void)
{
	tst_require_root(NULL);
	tst_sig(NOFORK, DEF_HANDLER, CLEANUP);
	TEST_PAUSE;
}

static void cleanup(void)
{
	struct timespec now;
	clock_gettime(CLOCK_REALTIME, &now);
	/* Calls clock_was_set() in kernel to revert inconsistency.
	 * The only possible EPERM doesn't matter here. */
	clock_settime(CLOCK_REALTIME, &now);
}
