Index: /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.c
===================================================================
--- /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.c	(revision 4509)
+++ /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.c	(revision 4511)
@@ -19,4 +19,32 @@
 #include "watchdog.h"
 
+/* Global watchdog fd, required by signal handler */
+int wdfd = -1;
+
+/* Watchdog shutdown helper */
+static void shutdown_watchdog(int sig)
+{
+	static int wdelay = 3600;
+	static const char wshutdown = WATCH_SHUTDOWN;
+
+	if( wdfd > -1 )
+	{
+		syslog(LOG_INFO, "Stopping watchdog timer");
+		write(wdfd, &wshutdown, 1);
+
+		/* Older Kamikaze versions are compiled with
+		 * CONFIG_WATCHDOG_NOWAYOUT=y, this can be
+		 * harmful if we're in the middle of an upgrade.
+		 * Increase the watchdog timeout to 3600 seconds
+		 * here to avoid unplanned reboots. */
+		ioctl(wdfd, WDIOC_SETTIMEOUT, &wdelay);
+
+		close(wdfd);
+		wdfd = -1;
+	}
+
+	exit(0);
+}
+
 /* Get BSSID of given interface */
 static int iw_get_bssid(int iwfd, const char *ifname, char *bssid)
@@ -258,9 +286,12 @@
 static int do_daemon(void)
 {
+	static int wdtrigger = 1;
+	static int wdtimeout = INTERVAL * 2;
+	static const char wdkeepalive = WATCH_KEEPALIVE;
+
 	int iwfd;
-	int wdfd;
-	int wdtrigger = 1;
 	int channel;
 	char bssid[18];
+	struct sigaction sa;
 
 	wifi_tuple_t *ifs = NULL, *curif;
@@ -285,6 +316,19 @@
 	if( (wdfd = open(WATCH_DEVICE, O_WRONLY)) > -1 )
 	{
-		syslog(LOG_INFO, "Opened %s - polling each %i seconds",
+		syslog(LOG_INFO, "Opened %s - polling every %i seconds",
 			WATCH_DEVICE, INTERVAL);
+
+		/* Install signal handler to halt watchdog on shutdown */
+		sa.sa_handler = shutdown_watchdog;
+		sa.sa_flags = SA_NOCLDWAIT | SA_RESTART;
+		sigaction(SIGHUP,  &sa, NULL);
+		sigaction(SIGINT,  &sa, NULL);
+		sigaction(SIGPIPE, &sa, NULL);
+		sigaction(SIGTERM, &sa, NULL);
+		sigaction(SIGUSR1, &sa, NULL);
+		sigaction(SIGUSR2, &sa, NULL);
+
+		/* Set watchdog timeout to twice the interval */
+		ioctl(wdfd, WDIOC_SETTIMEOUT, &wdtimeout);
 	}
 
@@ -376,17 +420,12 @@
 		/* Reset watchdog timer */
 		if( wdfd > -1 )
-			write(wdfd, '\0', 1);
+			write(wdfd, &wdkeepalive, 1);
 
 		sleep(INTERVAL);
 	}
 
-	if( wdfd > -1 )
-	{
-		syslog(LOG_INFO, "Stopping watchdog timer");
-		write(wdfd, WATCH_SHUTDOWN, 1);
-		close(wdfd);
-	}
-
+	shutdown_watchdog(0);
 	closelog();
+
 	return 0;
 }
Index: /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.h
===================================================================
--- /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.h	(revision 4509)
+++ /luci/branches/luci-0.8/contrib/package/freifunk-watchdog/src/watchdog.h	(revision 4511)
@@ -29,4 +29,5 @@
 #include <math.h>
 #include <time.h>
+#include <signal.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -60,4 +61,5 @@
 #define WATCH_DEVICE	"/dev/watchdog"
 #define WATCH_SHUTDOWN	'V'
+#define WATCH_KEEPALIVE	'\0'
 
 /* System load error action and treshold */
