Browse Source

the cloexec logic of the watchdog was broken

Signed-off-by: John Crispin <blogic@openwrt.org>
John Crispin 10 years ago
parent
commit
36d79a90c2
4 changed files with 13 additions and 10 deletions
  1. 1 1
      main.c
  2. 3 4
      state.c
  3. 8 4
      watchdog.c
  4. 1 1
      watchdog.h

+ 1 - 1
main.c

@@ -40,7 +40,7 @@ static int main_procd_init(int argc, char **argv)
 	procd_signal_preinit();
 	procd_early();
 	debug_init();
-	watchdog_init();
+	watchdog_init(1);
 	system("/sbin/kmodloader /etc/modules-boot.d/");
 	uloop_init();
 	hotplug("/etc/hotplug-preinit.json");

+ 3 - 4
state.c

@@ -40,15 +40,14 @@ static void state_enter(void)
 	switch (state) {
 	case STATE_EARLY:
 		LOG("- early -\n");
-		watchdog_init();
+		watchdog_init(0);
 		hotplug("/etc/hotplug.json");
 		procd_coldplug();
 		break;
 
 	case STATE_INIT:
-		// check if the wdt appeared during coldplug
-		if (!watchdog_fd())
-			watchdog_init();
+		// try to reopen incase the wdt was not available before coldplug
+		watchdog_init(0);
 		LOG("- init -\n");
 		log_init();
 		procd_connect_ubus();

+ 8 - 4
watchdog.c

@@ -91,24 +91,28 @@ char* watchdog_fd(void)
 	return fd_buf;
 }
 
-void watchdog_init(void)
+void watchdog_init(int preinit)
 {
 	char *env = getenv("WDTFD");
 
+	if (wdt_fd >= 0)
+		return;
 
 	wdt_timeout.cb = watchdog_timeout_cb;
 	if (env) {
 		DEBUG(1, "Watchdog handover: fd=%s\n", env);
 		wdt_fd = atoi(env);
 		unsetenv("WDTFD");
-		fcntl(wdt_fd, F_SETFD, fcntl(wdt_fd, F_GETFD) | FD_CLOEXEC);
 	} else {
 		wdt_fd = open("/dev/watchdog", O_WRONLY);
-		if ((getpid() != 1) && (wdt_fd >= 0))
-			fcntl(wdt_fd, F_SETFD, fcntl(wdt_fd, F_GETFD) | FD_CLOEXEC);
 	}
+
 	if (wdt_fd < 0)
 		return;
+
+	if (!preinit)
+		fcntl(wdt_fd, F_SETFD, fcntl(wdt_fd, F_GETFD) | FD_CLOEXEC);
+
 	LOG("- watchdog -\n");
 	watchdog_timeout(30);
 	watchdog_timeout_cb(&wdt_timeout);

+ 1 - 1
watchdog.h

@@ -15,7 +15,7 @@
 #ifndef __PROCD_WATCHDOG_H
 #define __PROCD_WATCHDOG_H
 
-void watchdog_init(void);
+void watchdog_init(int preinit);
 char* watchdog_fd(void);
 int watchdog_timeout(int timeout);
 int watchdog_frequency(int frequency);