[aadk-commits] dbailey: uClinux/trunk r101 -
/uClinux/trunk/uClinux-dist/user/procwatch/
aadk-commits at lists.digium.com
aadk-commits at lists.digium.com
Thu Dec 28 08:04:37 MST 2006
Author: dbailey
Date: Thu Dec 28 09:04:36 2006
New Revision: 101
URL: http://svn.digium.com/view/aadk?view=rev&rev=101
Log:
Adding program that monitors a set of processes and hits the watchdog while they are still active
Added:
uClinux/trunk/uClinux-dist/user/procwatch/
uClinux/trunk/uClinux-dist/user/procwatch/Makefile (with props)
uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c (with props)
Added: uClinux/trunk/uClinux-dist/user/procwatch/Makefile
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/user/procwatch/Makefile?view=auto&rev=101
==============================================================================
--- uClinux/trunk/uClinux-dist/user/procwatch/Makefile (added)
+++ uClinux/trunk/uClinux-dist/user/procwatch/Makefile Thu Dec 28 09:04:36 2006
@@ -1,0 +1,15 @@
+
+EXEC = procwatch
+OBJS = procwatch.o
+
+all: $(EXEC)
+
+$(EXEC): $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS$(LDLIBS_$@))
+
+romfs:
+ $(ROMFSINST) /bin/$(EXEC)
+
+clean:
+ -rm -f $(EXEC) *.elf *.gdb *.o
+
Propchange: uClinux/trunk/uClinux-dist/user/procwatch/Makefile
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: uClinux/trunk/uClinux-dist/user/procwatch/Makefile
------------------------------------------------------------------------------
svn:executable = *
Propchange: uClinux/trunk/uClinux-dist/user/procwatch/Makefile
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c?view=auto&rev=101
==============================================================================
--- uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c (added)
+++ uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c Thu Dec 28 09:04:36 2006
@@ -1,0 +1,275 @@
+/*
+ * procwatch - Process monitor using Standard Linux Watchdog API
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Doug Bailey <dbailey at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2.
+ */
+
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <asm/page.h>
+#include <linux/version.h>
+#include <linux/watchdog.h>
+
+#define MAX_PROC_NAME_SIZE 256
+#define MAX_PROCESS 32
+#define DEFAULT_SLEEP_VAL (2000)
+
+#define STATUS_LINE_ARG "Name:"
+
+/*** Local Prototypes ***/
+static void show_usage(void);
+
+
+struct app_monitor {
+ char * name;
+ int valid;
+ int online;
+};
+
+int main(int argc, char ** argv)
+{
+ struct app_monitor proc_monitor[MAX_PROCESS];
+ int num_to_monitor = 0;
+ unsigned long sleep_val = DEFAULT_SLEEP_VAL;
+ unsigned long new_sleep;
+ int watchdog_time = 0;
+ int fd_watchdog;
+ char * dummy;
+ int opt;
+ int daemon = 0;
+ pid_t pid, sid;
+
+ opterr = 0;
+ while ((opt = getopt(argc, argv, "?dp:t:w:")) > 0) {
+ switch (opt) {
+ case 'p':
+ proc_monitor[num_to_monitor].name = optarg;
+ proc_monitor[num_to_monitor].valid = 0;
+ proc_monitor[num_to_monitor].online = 0;
+ num_to_monitor++;
+ break;
+ case 't':
+ new_sleep = strtoul(optarg, &dummy, 10);
+ if(0 < new_sleep) {
+ sleep_val = new_sleep;
+ }
+ break;
+ case 'w':
+ watchdog_time = atoi(optarg);
+ break;
+ case 'd':
+ daemon = 1;
+ break;
+ default:
+ show_usage();
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ if(daemon){ /*NOTE uClinux does not support fork - Save it for later*/
+ /* Fork off process */
+ pid = fork();
+ if (pid < 0) {
+ perror("Cannot Fork child process\n");
+ exit(EXIT_FAILURE);
+ }
+ /* If we got a good PID, then
+ we can exit the parent process. */
+ else if (pid > 0) {
+ exit(EXIT_SUCCESS);
+ }
+
+ /* Change the file mode mask */
+ umask(0);
+
+ /* new SID for the child process */
+ sid = setsid();
+ if (sid < 0) {
+ perror("Cannot set the Wathcdog Monitor child SID \n");
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ fd_watchdog = open("/dev/watchdog", O_RDWR);
+
+ if (fd_watchdog == -1) {
+ printf("Cannot open the watchdog timer\n");
+ _exit(1);
+ }
+
+ if(0 < watchdog_time) {
+ ioctl(fd_watchdog, WDIOC_SETTIMEOUT, &watchdog_time);
+ printf("The watchdog timeout has been set to %d seconds\n", watchdog_time);
+ }
+
+ while(1){
+ if(0 == find_processes(proc_monitor, num_to_monitor)){
+ write(fd_watchdog, "\0", 1);
+ }
+ // Sleep between checking for processes
+ usleep(1000 * sleep_val);
+ }
+
+ return 0;
+}
+
+/* Display command line usage */
+static void show_usage(void)
+{
+ printf("procwatch - Watchdog monitor for one or more processes\n");
+ printf("Usage: \n");
+ printf("procwatch [-t <time in mS>] [-w <watchdog timer value in seconds>] [-p <process name>] [-d] \n");
+ printf("\t\t-t - specified time to sleep between checks (in milliseconds)\n");
+ printf("\t\t-w - specified time for the watchdog to timeout (in seconds)\n");
+ printf("\t\t-p - specific process name to monitor. Program waits for the process to become active.\n");
+ printf("\t\t After the program is active, it must stay alive for the watchdog to be refreshed.\n");
+ printf("\t\t There can be multiple processes monitored by the program.\n");
+ printf("\t\t-d - run the program as a daemon. (Not supported under uClinux.)\n");
+ printf("\t\t-? - See this usage.\n");
+
+}
+
+/*
+ * Finds whether the list of processes passed to the function are currently active.
+ * The function uses the proc file system to find the active processes.
+ *
+ * The it looks at the Name field in the /proc/<id>/status file for the
+ * desired process name.
+ */
+
+int find_processes(struct app_monitor *list, int list_len)
+{
+ int unfound_process;
+ int offline_process;
+
+ DIR *dir;
+ int pid;
+ int valid_line;
+ int x, y, n;
+ struct dirent *entry;
+ FILE *fp;
+ char *proc_id_name;
+ char *cmd_line;
+ char status[128];
+ char buf[128];
+
+ if(0 == list_len) {
+ return 0;
+ } else if( 0 > list_len) {
+ return -1;
+ }
+
+ dir = opendir("/proc");
+ if(!dir)
+ return -1;
+
+ /* Initialize the list to all invalid processes */
+ for(n = 0, unfound_process = 0, offline_process = 0; n < list_len; n++){
+ list[n].valid = 0;
+ if(0 != list[n].online){ /* This process is online, we must find it in proc */
+ unfound_process++;
+ } else {
+ offline_process++;
+ }
+
+ }
+
+/* while I have not accounted for all the processes I need to check */
+ while(0 < unfound_process || 0 < offline_process) {
+ if((entry = readdir(dir)) == NULL) {
+ /* cannot read more entries, time to get out */
+ closedir(dir);
+ dir = NULL;
+ break;
+ }
+ proc_id_name = entry->d_name;
+ if (!(*proc_id_name >= '0' && *proc_id_name <= '9')) {/* look for decimal numeric name */
+ continue;
+ }
+ pid = atoi(proc_id_name);
+ if(0 >= pid) {
+ continue;
+ }
+
+ buf[0] = '\0'; /* Insure termination of string */
+ sprintf(status, "/proc/%d/status", pid);
+ if((fp = fopen(status, "r")) == NULL){
+ continue;
+ }
+
+ /* Find the Name line in the status file */
+ n = 0;
+ valid_line = 0;
+ while(0 != valid_line || !feof(fp)) {
+ /* Append data from the file into the raw buffer */
+ if((x=fread(&buf[n], 1, sizeof(buf)-1-n, fp)) > 0) {
+ n = x+n;
+ }
+ /* extract a terminated line from the buffer */
+ for(valid_line = 0, x = 0; x < n && x < 128; x++) {
+ if(buf[x] == '\n' || buf[x] == '\r' ) {
+ status[x] = '\0';
+ valid_line = 1;
+ x++;
+ for(y = 0; x < n; y++, x++) {
+ buf[y] = buf[x];
+ }
+ n = y;
+ buf[n] = '\0';
+ break;
+ } else if( ' ' > buf[x]) {
+ status[x] = ' ';
+ } else {
+ status[x] = buf[x];
+ }
+ }
+ /* see if this line starts with the desired line header*/
+ if(valid_line) {
+ /* set cmd_line to point to string after header name */
+ if(NULL != (cmd_line= strstr( status, STATUS_LINE_ARG))) {
+ cmd_line += strlen(STATUS_LINE_ARG);
+ break;
+ }
+ } else {
+ cmd_line = NULL;
+ }
+ }
+ fclose(fp);
+
+ /* Is the name in the list of processes to look for */
+ if(cmd_line != NULL) {
+ for(n = 0; n < list_len; n++) {
+ /* If we have found this process */
+ if(NULL != strstr( cmd_line, list[n].name)){
+ /* first test if the process has come online, if so markit as such */
+ if(0 == list[n].online){
+ list[n].online = 1;
+ list[n].valid = 1; /* Mark that I checked this one */
+ offline_process--;
+ /* If it is already online and has not been marked, then mark it */
+ } else if(0 == list[n].valid){
+ unfound_process--;
+ list[n].valid = 1;
+ }
+ }
+ }
+ }
+ }
+ return unfound_process;
+}
+
Propchange: uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: uClinux/trunk/uClinux-dist/user/procwatch/procwatch.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the aadk-commits
mailing list