diff options
| author | John Stultz <john.stultz@linaro.org> | 2015-03-11 20:40:12 -0400 |
|---|---|---|
| committer | Shuah Khan <shuahkh@osg.samsung.com> | 2015-03-12 15:22:16 -0400 |
| commit | d7b2902c1541f8e65186c4e9dd1bf054b45d49e5 (patch) | |
| tree | baee0731be59fcaead0b26c221fb5198a1dcfbca /tools/testing | |
| parent | 5bccfe41532f4b80fc70cd8f78fd965666a46c15 (diff) | |
selftests/timers: Add leapcrash test from the timetest suite
This change adds the leapcrash test which tests to see if a
leapsecond deadlock which was observed from 2.6.26 to 3.3
is present on this system.
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Tested-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Diffstat (limited to 'tools/testing')
| -rw-r--r-- | tools/testing/selftests/timers/Makefile | 3 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/leapcrash.c | 120 |
2 files changed, 122 insertions, 1 deletions
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index da35dddaa985..d73332495c2e 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile | |||
| @@ -5,7 +5,7 @@ LDFLAGS += -lrt -lpthread | |||
| 5 | bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ | 5 | bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \ |
| 6 | set-timer-lat threadtest mqueue-lat valid-adjtimex \ | 6 | set-timer-lat threadtest mqueue-lat valid-adjtimex \ |
| 7 | alarmtimer-suspend change_skew skew_consistency clocksource-switch \ | 7 | alarmtimer-suspend change_skew skew_consistency clocksource-switch \ |
| 8 | leap-a-day | 8 | leap-a-day leapcrash |
| 9 | 9 | ||
| 10 | all: ${bins} | 10 | all: ${bins} |
| 11 | 11 | ||
| @@ -31,6 +31,7 @@ run_destructive_tests: run_tests | |||
| 31 | ./skew_consistency | 31 | ./skew_consistency |
| 32 | ./clocksource-switch | 32 | ./clocksource-switch |
| 33 | ./leap-a-day -s -i 10 | 33 | ./leap-a-day -s -i 10 |
| 34 | ./leapcrash | ||
| 34 | 35 | ||
| 35 | clean: | 36 | clean: |
| 36 | rm -f ${bins} | 37 | rm -f ${bins} |
diff --git a/tools/testing/selftests/timers/leapcrash.c b/tools/testing/selftests/timers/leapcrash.c new file mode 100644 index 000000000000..a1071bdbdeb7 --- /dev/null +++ b/tools/testing/selftests/timers/leapcrash.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* Demo leapsecond deadlock | ||
| 2 | * by: John Stultz (john.stultz@linaro.org) | ||
| 3 | * (C) Copyright IBM 2012 | ||
| 4 | * (C) Copyright 2013, 2015 Linaro Limited | ||
| 5 | * Licensed under the GPL | ||
| 6 | * | ||
| 7 | * This test demonstrates leapsecond deadlock that is possibe | ||
| 8 | * on kernels from 2.6.26 to 3.3. | ||
| 9 | * | ||
| 10 | * WARNING: THIS WILL LIKELY HARDHANG SYSTEMS AND MAY LOSE DATA | ||
| 11 | * RUN AT YOUR OWN RISK! | ||
| 12 | * To build: | ||
| 13 | * $ gcc leapcrash.c -o leapcrash -lrt | ||
| 14 | */ | ||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | #include <stdio.h> | ||
| 19 | #include <stdlib.h> | ||
| 20 | #include <time.h> | ||
| 21 | #include <sys/time.h> | ||
| 22 | #include <sys/timex.h> | ||
| 23 | #include <string.h> | ||
| 24 | #include <signal.h> | ||
| 25 | #ifdef KTEST | ||
| 26 | #include "../kselftest.h" | ||
| 27 | #else | ||
| 28 | static inline int ksft_exit_pass(void) | ||
| 29 | { | ||
| 30 | exit(0); | ||
| 31 | } | ||
| 32 | static inline int ksft_exit_fail(void) | ||
| 33 | { | ||
| 34 | exit(1); | ||
| 35 | } | ||
| 36 | #endif | ||
| 37 | |||
| 38 | |||
| 39 | |||
| 40 | /* clear NTP time_status & time_state */ | ||
| 41 | int clear_time_state(void) | ||
| 42 | { | ||
| 43 | struct timex tx; | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | /* | ||
| 47 | * We have to call adjtime twice here, as kernels | ||
| 48 | * prior to 6b1859dba01c7 (included in 3.5 and | ||
| 49 | * -stable), had an issue with the state machine | ||
| 50 | * and wouldn't clear the STA_INS/DEL flag directly. | ||
| 51 | */ | ||
| 52 | tx.modes = ADJ_STATUS; | ||
| 53 | tx.status = STA_PLL; | ||
| 54 | ret = adjtimex(&tx); | ||
| 55 | |||
| 56 | tx.modes = ADJ_STATUS; | ||
| 57 | tx.status = 0; | ||
| 58 | ret = adjtimex(&tx); | ||
| 59 | |||
| 60 | return ret; | ||
| 61 | } | ||
| 62 | |||
| 63 | /* Make sure we cleanup on ctrl-c */ | ||
| 64 | void handler(int unused) | ||
| 65 | { | ||
| 66 | clear_time_state(); | ||
| 67 | exit(0); | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | int main(void) | ||
| 72 | { | ||
| 73 | struct timex tx; | ||
| 74 | struct timespec ts; | ||
| 75 | time_t next_leap; | ||
| 76 | int count = 0; | ||
| 77 | |||
| 78 | setbuf(stdout, NULL); | ||
| 79 | |||
| 80 | signal(SIGINT, handler); | ||
| 81 | signal(SIGKILL, handler); | ||
| 82 | printf("This runs for a few minutes. Press ctrl-c to stop\n"); | ||
| 83 | |||
| 84 | clear_time_state(); | ||
| 85 | |||
| 86 | |||
| 87 | /* Get the current time */ | ||
| 88 | clock_gettime(CLOCK_REALTIME, &ts); | ||
| 89 | |||
| 90 | /* Calculate the next possible leap second 23:59:60 GMT */ | ||
| 91 | next_leap = ts.tv_sec; | ||
| 92 | next_leap += 86400 - (next_leap % 86400); | ||
| 93 | |||
| 94 | for (count = 0; count < 20; count++) { | ||
| 95 | struct timeval tv; | ||
| 96 | |||
| 97 | |||
| 98 | /* set the time to 2 seconds before the leap */ | ||
| 99 | tv.tv_sec = next_leap - 2; | ||
| 100 | tv.tv_usec = 0; | ||
| 101 | if (settimeofday(&tv, NULL)) { | ||
| 102 | printf("Error: You're likely not running with proper (ie: root) permissions\n"); | ||
| 103 | return ksft_exit_fail(); | ||
| 104 | } | ||
| 105 | tx.modes = 0; | ||
| 106 | adjtimex(&tx); | ||
| 107 | |||
| 108 | /* hammer on adjtime w/ STA_INS */ | ||
| 109 | while (tx.time.tv_sec < next_leap + 1) { | ||
| 110 | /* Set the leap second insert flag */ | ||
| 111 | tx.modes = ADJ_STATUS; | ||
| 112 | tx.status = STA_INS; | ||
| 113 | adjtimex(&tx); | ||
| 114 | } | ||
| 115 | clear_time_state(); | ||
| 116 | printf("."); | ||
| 117 | } | ||
| 118 | printf("[OK]\n"); | ||
| 119 | return ksft_exit_pass(); | ||
| 120 | } | ||
