/* * Toggle the kernel's watchdog. This routine is used to enable and * disable the watchdog. */ static int watchdog_onoff(int onoff) { int error; /* fake successful watchdog op if a dry run */ if (is_dry_run) return 0; if (onoff) { /* * Call the WDIOC_SETSOFT regardless of softtimeout_set * because we'll need to turn it off if someone had turned * it on. */ error = ioctl(fd, WDIOC_SETSOFT, &softtimeout_set); if (error) { warn("setting WDIOC_SETSOFT %d", softtimeout_set); return (error); } error = watchdog_patpat((timeout|WD_ACTIVE)); if (error) { warn("watchdog_patpat failed"); goto failsafe; } if (softtimeout_act_set) { error = ioctl(fd, WDIOC_SETSOFTTIMEOUTACT, &softtimeout_act); if (error) { warn("setting WDIOC_SETSOFTTIMEOUTACT %d", softtimeout_act); goto failsafe; } } if (pretimeout_set) { error = ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout); if (error) { warn("setting WDIOC_SETPRETIMEOUT %d", pretimeout); goto failsafe; } } if (pretimeout_act_set) { error = ioctl(fd, WDIOC_SETPRETIMEOUTACT, &pretimeout_act); if (error) { warn("setting WDIOC_SETPRETIMEOUTACT %d", pretimeout_act); goto failsafe; } } /* pat one more time for good measure */ return watchdog_patpat((timeout|WD_ACTIVE)); } else { return watchdog_patpat(exit_timeout); } failsafe: watchdog_patpat(exit_timeout); return (error); }
/* * Toggle the kernel's watchdog. This routine is used to enable and * disable the watchdog. */ static int watchdog_onoff(int onoff) { if (onoff) return watchdog_patpat((timeout|WD_ACTIVE)); else return watchdog_patpat(0); }
/* * Main program loop which is iterated every second. */ static void watchdog_loop(void) { struct stat sb; int failed; while (end_program != 2) { failed = 0; if (test_cmd != NULL) failed = system(test_cmd); else failed = stat("/etc", &sb); if (failed == 0) watchdog_patpat(timeout|WD_ACTIVE); sleep(nap); if (end_program != 0) { if (watchdog_onoff(0) == 0) { end_program = 2; } else { warnx("Could not stop the watchdog, not exiting"); end_program = 0; } } } }
/* * Main program loop which is iterated every second. */ static void watchdog_loop(void) { struct timespec ts_start, ts_end; struct stat sb; long waited; int error, failed; while (end_program != 2) { failed = 0; error = watchdog_getuptime(&ts_start); if (error) { end_program = 1; goto try_end; } if (test_cmd != NULL) failed = system(test_cmd); else failed = stat("/etc", &sb); error = watchdog_getuptime(&ts_end); if (error) { end_program = 1; goto try_end; } if (failed == 0) watchdog_patpat(timeout|WD_ACTIVE); waited = watchdog_check_dogfunction_time(&ts_start, &ts_end); if (nap - waited > 0) sleep(nap - waited); try_end: if (end_program != 0) { if (watchdog_onoff(0) == 0) { end_program = 2; } else { warnx("Could not stop the watchdog, not exiting"); end_program = 0; } } } }
/* * Periodically pat the watchdog, preventing it from firing. */ int main(int argc, char *argv[]) { struct rtprio rtp; struct pidfh *pfh; pid_t otherpid; if (getuid() != 0) errx(EX_SOFTWARE, "not super user"); parseargs(argc, argv); if (do_syslog) openlog("watchdogd", LOG_CONS|LOG_NDELAY|LOG_PERROR, LOG_DAEMON); rtp.type = RTP_PRIO_REALTIME; rtp.prio = 0; if (rtprio(RTP_SET, 0, &rtp) == -1) err(EX_OSERR, "rtprio"); if (!is_dry_run && watchdog_init() == -1) errx(EX_SOFTWARE, "unable to initialize watchdog"); if (is_daemon) { if (watchdog_onoff(1) == -1) err(EX_OSERR, "patting the dog"); pfh = pidfile_open(pidfile, 0600, &otherpid); if (pfh == NULL) { if (errno == EEXIST) { watchdog_onoff(0); errx(EX_SOFTWARE, "%s already running, pid: %d", getprogname(), otherpid); } warn("Cannot open or create pidfile"); } if (debugging == 0 && daemon(0, 0) == -1) { watchdog_onoff(0); pidfile_remove(pfh); err(EX_OSERR, "daemon"); } signal(SIGHUP, SIG_IGN); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); pidfile_write(pfh); if (madvise(0, 0, MADV_PROTECT) != 0) warn("madvise failed"); if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) warn("mlockall failed"); watchdog_loop(); /* exiting */ pidfile_remove(pfh); return (EX_OK); } else { if (passive) timeout |= WD_PASSIVE; else timeout |= WD_ACTIVE; if (watchdog_patpat(timeout) < 0) err(EX_OSERR, "patting the dog"); return (EX_OK); } }