1*053f45beSAndroid Build Coastguard Worker /* Demo leapsecond deadlock 2*053f45beSAndroid Build Coastguard Worker * by: John Stultz ([email protected]) 3*053f45beSAndroid Build Coastguard Worker * (C) Copyright IBM 2012 4*053f45beSAndroid Build Coastguard Worker * (C) Copyright 2013, 2015 Linaro Limited 5*053f45beSAndroid Build Coastguard Worker * Licensed under the GPL 6*053f45beSAndroid Build Coastguard Worker * 7*053f45beSAndroid Build Coastguard Worker * This test demonstrates leapsecond deadlock that is possible 8*053f45beSAndroid Build Coastguard Worker * on kernels from 2.6.26 to 3.3. 9*053f45beSAndroid Build Coastguard Worker * 10*053f45beSAndroid Build Coastguard Worker * WARNING: THIS WILL LIKELY HARD HANG SYSTEMS AND MAY LOSE DATA 11*053f45beSAndroid Build Coastguard Worker * RUN AT YOUR OWN RISK! 12*053f45beSAndroid Build Coastguard Worker * To build: 13*053f45beSAndroid Build Coastguard Worker * $ gcc leapcrash.c -o leapcrash -lrt 14*053f45beSAndroid Build Coastguard Worker */ 15*053f45beSAndroid Build Coastguard Worker 16*053f45beSAndroid Build Coastguard Worker 17*053f45beSAndroid Build Coastguard Worker 18*053f45beSAndroid Build Coastguard Worker #include <stdio.h> 19*053f45beSAndroid Build Coastguard Worker #include <stdlib.h> 20*053f45beSAndroid Build Coastguard Worker #include <time.h> 21*053f45beSAndroid Build Coastguard Worker #include <sys/time.h> 22*053f45beSAndroid Build Coastguard Worker #include <sys/timex.h> 23*053f45beSAndroid Build Coastguard Worker #include <string.h> 24*053f45beSAndroid Build Coastguard Worker #include <signal.h> 25*053f45beSAndroid Build Coastguard Worker #include "../kselftest.h" 26*053f45beSAndroid Build Coastguard Worker 27*053f45beSAndroid Build Coastguard Worker /* clear NTP time_status & time_state */ clear_time_state(void)28*053f45beSAndroid Build Coastguard Workerint clear_time_state(void) 29*053f45beSAndroid Build Coastguard Worker { 30*053f45beSAndroid Build Coastguard Worker struct timex tx; 31*053f45beSAndroid Build Coastguard Worker int ret; 32*053f45beSAndroid Build Coastguard Worker 33*053f45beSAndroid Build Coastguard Worker /* 34*053f45beSAndroid Build Coastguard Worker * We have to call adjtime twice here, as kernels 35*053f45beSAndroid Build Coastguard Worker * prior to 6b1859dba01c7 (included in 3.5 and 36*053f45beSAndroid Build Coastguard Worker * -stable), had an issue with the state machine 37*053f45beSAndroid Build Coastguard Worker * and wouldn't clear the STA_INS/DEL flag directly. 38*053f45beSAndroid Build Coastguard Worker */ 39*053f45beSAndroid Build Coastguard Worker tx.modes = ADJ_STATUS; 40*053f45beSAndroid Build Coastguard Worker tx.status = STA_PLL; 41*053f45beSAndroid Build Coastguard Worker ret = adjtimex(&tx); 42*053f45beSAndroid Build Coastguard Worker 43*053f45beSAndroid Build Coastguard Worker tx.modes = ADJ_STATUS; 44*053f45beSAndroid Build Coastguard Worker tx.status = 0; 45*053f45beSAndroid Build Coastguard Worker ret = adjtimex(&tx); 46*053f45beSAndroid Build Coastguard Worker 47*053f45beSAndroid Build Coastguard Worker return ret; 48*053f45beSAndroid Build Coastguard Worker } 49*053f45beSAndroid Build Coastguard Worker 50*053f45beSAndroid Build Coastguard Worker /* Make sure we cleanup on ctrl-c */ handler(int unused)51*053f45beSAndroid Build Coastguard Workervoid handler(int unused) 52*053f45beSAndroid Build Coastguard Worker { 53*053f45beSAndroid Build Coastguard Worker clear_time_state(); 54*053f45beSAndroid Build Coastguard Worker exit(0); 55*053f45beSAndroid Build Coastguard Worker } 56*053f45beSAndroid Build Coastguard Worker 57*053f45beSAndroid Build Coastguard Worker main(void)58*053f45beSAndroid Build Coastguard Workerint main(void) 59*053f45beSAndroid Build Coastguard Worker { 60*053f45beSAndroid Build Coastguard Worker struct timex tx; 61*053f45beSAndroid Build Coastguard Worker struct timespec ts; 62*053f45beSAndroid Build Coastguard Worker time_t next_leap; 63*053f45beSAndroid Build Coastguard Worker int count = 0; 64*053f45beSAndroid Build Coastguard Worker 65*053f45beSAndroid Build Coastguard Worker setbuf(stdout, NULL); 66*053f45beSAndroid Build Coastguard Worker 67*053f45beSAndroid Build Coastguard Worker signal(SIGINT, handler); 68*053f45beSAndroid Build Coastguard Worker signal(SIGKILL, handler); 69*053f45beSAndroid Build Coastguard Worker printf("This runs for a few minutes. Press ctrl-c to stop\n"); 70*053f45beSAndroid Build Coastguard Worker 71*053f45beSAndroid Build Coastguard Worker clear_time_state(); 72*053f45beSAndroid Build Coastguard Worker 73*053f45beSAndroid Build Coastguard Worker 74*053f45beSAndroid Build Coastguard Worker /* Get the current time */ 75*053f45beSAndroid Build Coastguard Worker clock_gettime(CLOCK_REALTIME, &ts); 76*053f45beSAndroid Build Coastguard Worker 77*053f45beSAndroid Build Coastguard Worker /* Calculate the next possible leap second 23:59:60 GMT */ 78*053f45beSAndroid Build Coastguard Worker next_leap = ts.tv_sec; 79*053f45beSAndroid Build Coastguard Worker next_leap += 86400 - (next_leap % 86400); 80*053f45beSAndroid Build Coastguard Worker 81*053f45beSAndroid Build Coastguard Worker for (count = 0; count < 20; count++) { 82*053f45beSAndroid Build Coastguard Worker struct timeval tv; 83*053f45beSAndroid Build Coastguard Worker 84*053f45beSAndroid Build Coastguard Worker 85*053f45beSAndroid Build Coastguard Worker /* set the time to 2 seconds before the leap */ 86*053f45beSAndroid Build Coastguard Worker tv.tv_sec = next_leap - 2; 87*053f45beSAndroid Build Coastguard Worker tv.tv_usec = 0; 88*053f45beSAndroid Build Coastguard Worker if (settimeofday(&tv, NULL)) { 89*053f45beSAndroid Build Coastguard Worker printf("Error: You're likely not running with proper (ie: root) permissions\n"); 90*053f45beSAndroid Build Coastguard Worker return ksft_exit_fail(); 91*053f45beSAndroid Build Coastguard Worker } 92*053f45beSAndroid Build Coastguard Worker tx.modes = 0; 93*053f45beSAndroid Build Coastguard Worker adjtimex(&tx); 94*053f45beSAndroid Build Coastguard Worker 95*053f45beSAndroid Build Coastguard Worker /* hammer on adjtime w/ STA_INS */ 96*053f45beSAndroid Build Coastguard Worker while (tx.time.tv_sec < next_leap + 1) { 97*053f45beSAndroid Build Coastguard Worker /* Set the leap second insert flag */ 98*053f45beSAndroid Build Coastguard Worker tx.modes = ADJ_STATUS; 99*053f45beSAndroid Build Coastguard Worker tx.status = STA_INS; 100*053f45beSAndroid Build Coastguard Worker adjtimex(&tx); 101*053f45beSAndroid Build Coastguard Worker } 102*053f45beSAndroid Build Coastguard Worker clear_time_state(); 103*053f45beSAndroid Build Coastguard Worker printf("."); 104*053f45beSAndroid Build Coastguard Worker fflush(stdout); 105*053f45beSAndroid Build Coastguard Worker } 106*053f45beSAndroid Build Coastguard Worker printf("[OK]\n"); 107*053f45beSAndroid Build Coastguard Worker return ksft_exit_pass(); 108*053f45beSAndroid Build Coastguard Worker } 109