d4e63053a3d32640f33a35592d336e2ea9df80cd
[watchdog-test-framework.git] / watchdog-test.c
1 /* watchdog-test framework
2  * Copyright (C) 2014 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <time.h>
24 #include <fcntl.h>
25 #include <sys/ioctl.h>
26 #include <linux/watchdog.h>
27
28 #define WATCHDOG_DEVICE "/dev/watchdog"
29 #define WATCHDOG_TIMEOUT 30
30
31 int
32 main ()
33 {
34   int fd;
35   int timeout;
36   char input[256];
37   time_t start_t, t;
38
39   setvbuf (stdout, NULL, _IONBF, 0);
40
41   printf ("\n");
42   printf ("Welcome to the watchdog test framework.\n");
43   printf ("You should read the README file and run this in the guest.\n");
44   printf ("DO NOT RUN IT IN THE HOST!\n");
45   printf ("\n");
46   printf ("The test is as follows:\n");
47   printf ("(1) I will set up the watchdog with a %d second timeout.\n",
48           WATCHDOG_TIMEOUT);
49   printf ("(2) I will ping the watchdog for %d seconds.  During this time\n"
50           "    the guest should run normally.\n",
51           WATCHDOG_TIMEOUT * 2);
52   printf ("(3) I will stop pinging the watchdog and just count up.  If the\n"
53           "    virtual watchdog device is set correctly, then the watchdog\n"
54           "    action (eg. reboot) should happen around the %d second mark.\n",
55           WATCHDOG_TIMEOUT);
56   printf ("\n");
57   printf ("Do you want to start the test?  Type \"yes\" without quotes:\n");
58
59   if (fgets (input, sizeof input, stdin) == NULL ||
60       strncmp (input, "yes", 3) != 0) {
61     printf ("Exiting the program.\n");
62     exit (EXIT_SUCCESS);
63   }
64
65   printf ("\n");
66   printf ("Setting up the watchdog (%s) with a %d second timeout.\n",
67           WATCHDOG_DEVICE, WATCHDOG_TIMEOUT);
68
69   sync ();
70   fd = open (WATCHDOG_DEVICE, O_WRONLY);
71   if (fd == -1) {
72     perror (WATCHDOG_DEVICE);
73     exit (EXIT_FAILURE);
74   }
75
76   timeout = WATCHDOG_TIMEOUT;
77   if (ioctl (fd, WDIOC_SETTIMEOUT, &timeout) == -1) {
78     perror ("ioctl: WDIOC_SETTIMEOUT: error setting timeout");
79     exit (EXIT_FAILURE);
80   }
81
82   if (ioctl (fd, WDIOC_GETTIMEOUT, &timeout) == -1)
83     perror ("ioctl: WDIOC_GETTIMEOUT");
84   else {
85     printf ("Timeout is set to %d seconds.\n", timeout);
86     if (timeout != WATCHDOG_TIMEOUT)
87       printf ("Note: some watchdog devices don't support setting exact timeout values.\n");
88   }
89
90   printf ("\n");
91   printf ("Pinging the watchdog for %d seconds ...\n", WATCHDOG_TIMEOUT*2);
92   printf ("\n");
93
94   time (&start_t);
95   for (;;) {
96     time (&t);
97     if (t - start_t > WATCHDOG_TIMEOUT * 2)
98       break;
99     printf ("%d... ", (int) (t - start_t));
100
101     sync ();
102
103     sleep (3);
104
105     printf ("ping ");
106     if (ioctl (fd, WDIOC_KEEPALIVE, 0) == -1)
107       perror ("\nioctl: WDIOC_KEEPALIVE");
108   }
109
110   printf ("\n");
111   printf ("\n");
112   printf ("Stopping pings.\n");
113   printf ("The watchdog action should happen at approximately %d second mark.\n",
114           WATCHDOG_TIMEOUT);
115   printf ("\n");
116
117   time (&start_t);
118   for (;;) {
119     time (&t);
120     printf ("%d... ", (int) (t - start_t));
121     sync ();
122     sleep (3);
123   }
124
125   /*NOTREACHED*/
126   exit (EXIT_SUCCESS);
127 }