aboutsummaryrefslogtreecommitdiffstats
path: root/wd/wdd.c
diff options
context:
space:
mode:
Diffstat (limited to 'wd/wdd.c')
-rw-r--r--wd/wdd.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/wd/wdd.c b/wd/wdd.c
index 3ee0af8..d521881 100644
--- a/wd/wdd.c
+++ b/wd/wdd.c
@@ -1,5 +1,5 @@
/*
- * wdd - simple watchdog daemon - 2003 - willy tarreau
+ * wdd - simple watchdog daemon - 2003-2004 - willy tarreau
*/
#include <stdio.h>
@@ -10,6 +10,57 @@
const char dev_wd_str[] = "/dev/watchdog";
const char root_str[] = "/";
+/*
+ * This function checks if the system can allocate memory
+ * In case of failure, we exit so that the watchdog device
+ * notices it and can reboot.
+ */
+static inline void try_malloc() {
+ void *heap;
+
+ heap = (void*)sbrk(NULL);
+ if (brk(heap + 4096))
+ exit(1);
+ memset(heap, 0, 4096);
+ if (brk(heap))
+ exit(1);
+}
+
+/*
+ * This function checks if the system can fork
+ * In case of failure, we exit so that the watchdog device
+ * notices it and can reboot.
+ */
+static inline void try_fork() {
+ int pid;
+ pid = fork();
+ if (pid < 0) /* exit on error */
+ exit(1);
+ else if (pid == 0) /* child returns cleanly */
+ exit(0);
+ if (waitpid(pid, NULL, 0) != pid) /* father checks child */
+ exit(1);
+}
+
+
+/*
+ * This function checks if the system can access its root FS
+ * In case of failure, we exit so that the watchdog device
+ * notices it and can reboot.
+ */
+static inline void try_stat() {
+ void *heap;
+
+ heap = (void*)sbrk(NULL);
+ if (brk(heap + sizeof (struct stat)))
+ exit(1);
+ memset(heap, 0, sizeof (struct stat));
+ if (stat(root_str, heap) == -1)
+ exit(1);
+ if (brk(heap))
+ exit(1);
+}
+
int main (void) {
int dev;
@@ -29,6 +80,9 @@ int main (void) {
close(dev);
dev = -1;
}
+ try_malloc();
+ try_fork();
+ try_stat();
/* avoid a fast loop */
sleep(1);
}