Hi Mike,
Mike Frysinger wrote:
Signed-off-by: Mike Frysinger <[EMAIL PROTECTED]>
Applied, thanks.
Regards
Greg
user/Kconfig | 5 +
user/Makefile | 1 +
user/watchdogd/Makefile | 12 +++
user/watchdogd/watchdogd.c | 200 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 218 insertions(+), 0 deletions(-)
create mode 100644 user/watchdogd/Makefile
create mode 100644 user/watchdogd/watchdogd.c
diff --git a/user/Kconfig b/user/Kconfig
index 688fca6..f78e94d 100644
--- a/user/Kconfig
+++ b/user/Kconfig
@@ -3361,6 +3361,11 @@ config USER_UNZOO_UNZOO
The unzoo archive decompression and extraction program.
Can only extract and view contents of zoo archives.
+config USER_WATCHDOGD
+ bool "watchdogd"
+ help
+ A simple watchdog daemon.
+
config USER_LRZSZ_LRZSZ
bool "zmodem utils"
diff --git a/user/Makefile b/user/Makefile
index d452260..4dfd206 100644
--- a/user/Makefile
+++ b/user/Makefile
@@ -417,6 +417,7 @@ dir_$(CONFIG_USER_VPLAY_MIXER) += vplay
dir_$(CONFIG_USER_VPNLED_VPNLED) += vpnled
dir_$(CONFIG_USER_W3CAM_VIDCAT) += w3cam
dir_$(CONFIG_USER_W3CAM_W3CAMD) += w3cam
+dir_$(CONFIG_USER_WATCHDOGD) += watchdogd
dir_$(CONFIG_USER_WGET) += wget
dir_$(CONFIG_USER_WHETSTONE_WHETSTONE) += whetstone
dir_$(CONFIG_USER_WIRELESS_TOOLS) += wireless_tools
diff --git a/user/watchdogd/Makefile b/user/watchdogd/Makefile
new file mode 100644
index 0000000..d76bd7c
--- /dev/null
+++ b/user/watchdogd/Makefile
@@ -0,0 +1,12 @@
+CFLAGS += -Wall
+
+all: watchdogd
+
+romfs:
+ $(ROMFSINST) -e CONFIG_USER_WATCHDOGD /bin/$(EXEC)
+ $(ROMFSINST) -e CONFIG_USER_WATCHDOGD -a "watchdogd:unknown:/bin/watchdogd
-f -s" /etc/inittab
+
+clean:
+ -rm -f $(EXEC) *.elf *.gdb *.o
+
+.PHONY: all clean romfs
diff --git a/user/watchdogd/watchdogd.c b/user/watchdogd/watchdogd.c
new file mode 100644
index 0000000..d25aa1e
--- /dev/null
+++ b/user/watchdogd/watchdogd.c
@@ -0,0 +1,200 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <signal.h>
+#include <paths.h>
+
+int fd = -1;
+
+/*
+ * This function simply sends an IOCTL to the driver, which in turn ticks
+ * the PC Watchdog card to reset its internal timer so it doesn't trigger
+ * a computer reset.
+ */
+void keep_alive(void)
+{
+ int dummy;
+
+ ioctl(fd, WDIOC_KEEPALIVE, &dummy);
+}
+
+void safe_exit()
+{
+ if (fd != -1) {
+ write(fd, "V", 1);
+ close(fd);
+ }
+ exit(0);
+}
+
+int set_wd_counter(int count)
+{
+ return ioctl(fd, WDIOC_SETTIMEOUT, &count);
+}
+
+int get_wd_counter()
+{
+ int count;
+ int err;
+ if ((err = ioctl(fd, WDIOC_GETTIMEOUT, &count))) {
+ count = err;
+ }
+ return count;
+}
+
+#define FOREGROUND_FLAG "-f"
+
+#define _PATH_DEVNULL "/dev/null"
+
+void vfork_daemon_rexec(int nochdir, int noclose, int argc, char **argv, char
*foreground_opt)
+{
+ int f;
+ char **vfork_args;
+ int a = 0;
+
+ setsid();
+
+ if (!nochdir)
+ chdir("/");
+
+ if (!noclose && (f = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ dup2(f, STDIN_FILENO);
+ dup2(f, STDOUT_FILENO);
+ dup2(f, STDERR_FILENO);
+ if (f > 2)
+ close(f);
+ }
+
+ vfork_args = malloc(sizeof(char *) * (argc + 2));
+ while (*argv) {
+ vfork_args[a++] = *argv;
+ argv++;
+ }
+ vfork_args[a++] = foreground_opt;
+ vfork_args[a++] = NULL;
+ switch (vfork()) {
+ case 0: /* child */
+ /* Make certain we are not a session leader, or else we
+ * might reacquire a controlling terminal */
+ if (vfork())
+ _exit(0);
+ execvp(vfork_args[0], vfork_args);
+ perror("execv");
+ exit(-1);
+ case -1: /* error */
+ perror("vfork");
+ exit(-1);
+ default: /* parent */
+ exit(0);
+ }
+}
+
+static void usage(char *argv[])
+{
+ printf(
+ "%s [-f] [-w <sec>] [-k <sec>] [-s] [-h|--help]\n"
+ "A simple watchdog deamon that send WDIOC_KEEPALIVE ioctl every
some\n"
+ "\"heartbeat of keepalives\" seconds.\n"
+ "Options:\n"
+ "\t-f start in foreground (background is default)\n"
+ "\t-w <sec> set the watchdog counter to <sec> in seconds\n"
+ "\t-k <sec> set the \"heartbeat of keepalives\" to <sec> in
seconds\n"
+ "\t-s safe exit (disable Watchdog) for CTRL-c and kill
-SIGTERM signals\n"
+ "\t--help|-h write this help message and exit\n",
+ argv[0]);
+}
+
+/*
+ * The main program.
+ */
+int main(int argc, char *argv[])
+{
+ int wd_count = 20;
+ int real_wd_count = 0;
+ int wd_keep_alive = wd_count / 2;
+ struct sigaction sa;
+ int background = 1;
+ int ac = argc;
+ char **av = argv;
+
+ memset(&sa, 0, sizeof(sa));
+
+ /* TODO: rewrite this to use getopt() */
+ while (--ac) {
+ ++av;
+ if (strcmp(*av, "-w") == 0) {
+ if (--ac) {
+ wd_count = atoi(*++av);
+ printf("-w switch: set watchdog counter to %d
sec.\n", wd_count);
+ } else {
+ fprintf(stderr, "-w switch must be followed to
seconds of watchdog counter.\n");
+ fflush(stderr);
+ break;
+ }
+ } else if (strcmp(*av, "-k") == 0) {
+ if (--ac) {
+ wd_keep_alive = atoi(*++av);
+ printf("-k switch: set the heartbeat of keepalives
in %d sec.\n", wd_keep_alive);
+ } else {
+ fprintf(stderr, "-k switch must be followed to
seconds of heartbeat of keepalives.\n");
+ fflush(stderr);
+ break;
+ }
+ } else if (strcmp(*av, "-s") == 0) {
+ printf("-s switch: safe exit (CTRL-C and kill).\n");
+ sa.sa_handler = safe_exit;
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ } else if (strcmp(*av, FOREGROUND_FLAG) == 0) {
+ background = 0;
+ printf("Start in foreground mode.\n");
+ } else if ((strcmp(*av, "-h") == 0) || (strcmp(*av, "--help")
== 0)) {
+ usage(argv);
+ exit(0);
+ } else {
+ fprintf(stderr, "Unrecognized option \"%s\".\n", *av);
+ usage(argv);
+ exit(1);
+ }
+ }
+
+ if (background) {
+ printf("Start in deamon mode.\n");
+ vfork_daemon_rexec(1, 0, argc, argv, FOREGROUND_FLAG);
+ }
+
+ fd = open("/dev/watchdog", O_WRONLY);
+
+ if (fd == -1) {
+ perror("Watchdog device not enabled");
+ fflush(stderr);
+ exit(-1);
+ }
+
+ if (set_wd_counter(wd_count)) {
+ fprintf(stderr, "-w switch: wrong value. Please look at kernel log
for more dettails.\n Continue with the old value\n");
+ fflush(stderr);
+ }
+
+ real_wd_count = get_wd_counter();
+ if (real_wd_count < 0) {
+ perror("Error while issue IOCTL WDIOC_GETTIMEOUT");
+ } else {
+ if (real_wd_count <= wd_keep_alive) {
+ fprintf(stderr,
+ "Warning watchdog counter less or equal to the
heartbeat of keepalives: %d <= %d\n",
+ real_wd_count, wd_keep_alive);
+ fflush(stderr);
+ }
+ }
+
+ while (1) {
+ keep_alive();
+ sleep(wd_keep_alive);
+ }
+}
--
------------------------------------------------------------------------
Greg Ungerer -- Chief Software Dude EMAIL: [EMAIL PROTECTED]
Secure Computing Corporation PHONE: +61 7 3435 2888
825 Stanley St, FAX: +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev