| .. | .. |
|---|
| 19 | 19 | |
|---|
| 20 | 20 | int fd; |
|---|
| 21 | 21 | const char v = 'V'; |
|---|
| 22 | | -static const char sopts[] = "bdehp:t:"; |
|---|
| 22 | +static const char sopts[] = "bdehp:t:Tn:NLf:i"; |
|---|
| 23 | 23 | static const struct option lopts[] = { |
|---|
| 24 | 24 | {"bootstatus", no_argument, NULL, 'b'}, |
|---|
| 25 | 25 | {"disable", no_argument, NULL, 'd'}, |
|---|
| .. | .. |
|---|
| 27 | 27 | {"help", no_argument, NULL, 'h'}, |
|---|
| 28 | 28 | {"pingrate", required_argument, NULL, 'p'}, |
|---|
| 29 | 29 | {"timeout", required_argument, NULL, 't'}, |
|---|
| 30 | + {"gettimeout", no_argument, NULL, 'T'}, |
|---|
| 31 | + {"pretimeout", required_argument, NULL, 'n'}, |
|---|
| 32 | + {"getpretimeout", no_argument, NULL, 'N'}, |
|---|
| 33 | + {"gettimeleft", no_argument, NULL, 'L'}, |
|---|
| 34 | + {"file", required_argument, NULL, 'f'}, |
|---|
| 35 | + {"info", no_argument, NULL, 'i'}, |
|---|
| 30 | 36 | {NULL, no_argument, NULL, 0x0} |
|---|
| 31 | 37 | }; |
|---|
| 32 | 38 | |
|---|
| .. | .. |
|---|
| 65 | 71 | static void usage(char *progname) |
|---|
| 66 | 72 | { |
|---|
| 67 | 73 | printf("Usage: %s [options]\n", progname); |
|---|
| 68 | | - printf(" -b, --bootstatus Get last boot status (Watchdog/POR)\n"); |
|---|
| 69 | | - printf(" -d, --disable Turn off the watchdog timer\n"); |
|---|
| 70 | | - printf(" -e, --enable Turn on the watchdog timer\n"); |
|---|
| 71 | | - printf(" -h, --help Print the help message\n"); |
|---|
| 72 | | - printf(" -p, --pingrate=P Set ping rate to P seconds (default %d)\n", DEFAULT_PING_RATE); |
|---|
| 73 | | - printf(" -t, --timeout=T Set timeout to T seconds\n"); |
|---|
| 74 | + printf(" -f, --file\t\tOpen watchdog device file\n"); |
|---|
| 75 | + printf("\t\t\tDefault is /dev/watchdog\n"); |
|---|
| 76 | + printf(" -i, --info\t\tShow watchdog_info\n"); |
|---|
| 77 | + printf(" -b, --bootstatus\tGet last boot status (Watchdog/POR)\n"); |
|---|
| 78 | + printf(" -d, --disable\t\tTurn off the watchdog timer\n"); |
|---|
| 79 | + printf(" -e, --enable\t\tTurn on the watchdog timer\n"); |
|---|
| 80 | + printf(" -h, --help\t\tPrint the help message\n"); |
|---|
| 81 | + printf(" -p, --pingrate=P\tSet ping rate to P seconds (default %d)\n", |
|---|
| 82 | + DEFAULT_PING_RATE); |
|---|
| 83 | + printf(" -t, --timeout=T\tSet timeout to T seconds\n"); |
|---|
| 84 | + printf(" -T, --gettimeout\tGet the timeout\n"); |
|---|
| 85 | + printf(" -n, --pretimeout=T\tSet the pretimeout to T seconds\n"); |
|---|
| 86 | + printf(" -N, --getpretimeout\tGet the pretimeout\n"); |
|---|
| 87 | + printf(" -L, --gettimeleft\tGet the time left until timer expires\n"); |
|---|
| 74 | 88 | printf("\n"); |
|---|
| 75 | 89 | printf("Parameters are parsed left-to-right in real-time.\n"); |
|---|
| 76 | 90 | printf("Example: %s -d -t 10 -p 5 -e\n", progname); |
|---|
| 91 | + printf("Example: %s -t 12 -T -n 7 -N\n", progname); |
|---|
| 77 | 92 | } |
|---|
| 78 | 93 | |
|---|
| 79 | 94 | int main(int argc, char *argv[]) |
|---|
| .. | .. |
|---|
| 83 | 98 | int ret; |
|---|
| 84 | 99 | int c; |
|---|
| 85 | 100 | int oneshot = 0; |
|---|
| 101 | + char *file = "/dev/watchdog"; |
|---|
| 102 | + struct watchdog_info info; |
|---|
| 86 | 103 | |
|---|
| 87 | 104 | setbuf(stdout, NULL); |
|---|
| 88 | 105 | |
|---|
| 89 | | - fd = open("/dev/watchdog", O_WRONLY); |
|---|
| 106 | + while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { |
|---|
| 107 | + if (c == 'f') |
|---|
| 108 | + file = optarg; |
|---|
| 109 | + } |
|---|
| 110 | + |
|---|
| 111 | + fd = open(file, O_WRONLY); |
|---|
| 90 | 112 | |
|---|
| 91 | 113 | if (fd == -1) { |
|---|
| 92 | 114 | if (errno == ENOENT) |
|---|
| 93 | | - printf("Watchdog device not enabled.\n"); |
|---|
| 115 | + printf("Watchdog device (%s) not found.\n", file); |
|---|
| 94 | 116 | else if (errno == EACCES) |
|---|
| 95 | 117 | printf("Run watchdog as root.\n"); |
|---|
| 96 | 118 | else |
|---|
| .. | .. |
|---|
| 98 | 120 | strerror(errno)); |
|---|
| 99 | 121 | exit(-1); |
|---|
| 100 | 122 | } |
|---|
| 123 | + |
|---|
| 124 | + /* |
|---|
| 125 | + * Validate that `file` is a watchdog device |
|---|
| 126 | + */ |
|---|
| 127 | + ret = ioctl(fd, WDIOC_GETSUPPORT, &info); |
|---|
| 128 | + if (ret) { |
|---|
| 129 | + printf("WDIOC_GETSUPPORT error '%s'\n", strerror(errno)); |
|---|
| 130 | + close(fd); |
|---|
| 131 | + exit(ret); |
|---|
| 132 | + } |
|---|
| 133 | + |
|---|
| 134 | + optind = 0; |
|---|
| 101 | 135 | |
|---|
| 102 | 136 | while ((c = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { |
|---|
| 103 | 137 | switch (c) { |
|---|
| .. | .. |
|---|
| 116 | 150 | ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); |
|---|
| 117 | 151 | if (!ret) |
|---|
| 118 | 152 | printf("Watchdog card disabled.\n"); |
|---|
| 119 | | - else |
|---|
| 153 | + else { |
|---|
| 120 | 154 | printf("WDIOS_DISABLECARD error '%s'\n", strerror(errno)); |
|---|
| 155 | + oneshot = 1; |
|---|
| 156 | + } |
|---|
| 121 | 157 | break; |
|---|
| 122 | 158 | case 'e': |
|---|
| 123 | 159 | flags = WDIOS_ENABLECARD; |
|---|
| 124 | 160 | ret = ioctl(fd, WDIOC_SETOPTIONS, &flags); |
|---|
| 125 | 161 | if (!ret) |
|---|
| 126 | 162 | printf("Watchdog card enabled.\n"); |
|---|
| 127 | | - else |
|---|
| 163 | + else { |
|---|
| 128 | 164 | printf("WDIOS_ENABLECARD error '%s'\n", strerror(errno)); |
|---|
| 165 | + oneshot = 1; |
|---|
| 166 | + } |
|---|
| 129 | 167 | break; |
|---|
| 130 | 168 | case 'p': |
|---|
| 131 | 169 | ping_rate = strtoul(optarg, NULL, 0); |
|---|
| .. | .. |
|---|
| 138 | 176 | ret = ioctl(fd, WDIOC_SETTIMEOUT, &flags); |
|---|
| 139 | 177 | if (!ret) |
|---|
| 140 | 178 | printf("Watchdog timeout set to %u seconds.\n", flags); |
|---|
| 141 | | - else |
|---|
| 179 | + else { |
|---|
| 142 | 180 | printf("WDIOC_SETTIMEOUT error '%s'\n", strerror(errno)); |
|---|
| 181 | + oneshot = 1; |
|---|
| 182 | + } |
|---|
| 143 | 183 | break; |
|---|
| 184 | + case 'T': |
|---|
| 185 | + oneshot = 1; |
|---|
| 186 | + ret = ioctl(fd, WDIOC_GETTIMEOUT, &flags); |
|---|
| 187 | + if (!ret) |
|---|
| 188 | + printf("WDIOC_GETTIMEOUT returns %u seconds.\n", flags); |
|---|
| 189 | + else |
|---|
| 190 | + printf("WDIOC_GETTIMEOUT error '%s'\n", strerror(errno)); |
|---|
| 191 | + break; |
|---|
| 192 | + case 'n': |
|---|
| 193 | + flags = strtoul(optarg, NULL, 0); |
|---|
| 194 | + ret = ioctl(fd, WDIOC_SETPRETIMEOUT, &flags); |
|---|
| 195 | + if (!ret) |
|---|
| 196 | + printf("Watchdog pretimeout set to %u seconds.\n", flags); |
|---|
| 197 | + else { |
|---|
| 198 | + printf("WDIOC_SETPRETIMEOUT error '%s'\n", strerror(errno)); |
|---|
| 199 | + oneshot = 1; |
|---|
| 200 | + } |
|---|
| 201 | + break; |
|---|
| 202 | + case 'N': |
|---|
| 203 | + oneshot = 1; |
|---|
| 204 | + ret = ioctl(fd, WDIOC_GETPRETIMEOUT, &flags); |
|---|
| 205 | + if (!ret) |
|---|
| 206 | + printf("WDIOC_GETPRETIMEOUT returns %u seconds.\n", flags); |
|---|
| 207 | + else |
|---|
| 208 | + printf("WDIOC_GETPRETIMEOUT error '%s'\n", strerror(errno)); |
|---|
| 209 | + break; |
|---|
| 210 | + case 'L': |
|---|
| 211 | + oneshot = 1; |
|---|
| 212 | + ret = ioctl(fd, WDIOC_GETTIMELEFT, &flags); |
|---|
| 213 | + if (!ret) |
|---|
| 214 | + printf("WDIOC_GETTIMELEFT returns %u seconds.\n", flags); |
|---|
| 215 | + else |
|---|
| 216 | + printf("WDIOC_GETTIMELEFT error '%s'\n", strerror(errno)); |
|---|
| 217 | + break; |
|---|
| 218 | + case 'f': |
|---|
| 219 | + /* Handled above */ |
|---|
| 220 | + break; |
|---|
| 221 | + case 'i': |
|---|
| 222 | + /* |
|---|
| 223 | + * watchdog_info was obtained as part of file open |
|---|
| 224 | + * validation. So we just show it here. |
|---|
| 225 | + */ |
|---|
| 226 | + oneshot = 1; |
|---|
| 227 | + printf("watchdog_info:\n"); |
|---|
| 228 | + printf(" identity:\t\t%s\n", info.identity); |
|---|
| 229 | + printf(" firmware_version:\t%u\n", |
|---|
| 230 | + info.firmware_version); |
|---|
| 231 | + printf(" options:\t\t%08x\n", info.options); |
|---|
| 232 | + break; |
|---|
| 233 | + |
|---|
| 144 | 234 | default: |
|---|
| 145 | 235 | usage(argv[0]); |
|---|
| 146 | 236 | goto end; |
|---|