⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watchdog.c

📁 watchdog source watchdog source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /cvsroot/watchdog/watchdog/src/watchdog.c,v 1.4 2007/08/17 09:24:54 meskes Exp $ *//*************************************************************//* Original version was an example in the kernel source tree *//*                                                           *//* Most of the rest was written by me, Michael Meskes        *//* meskes@debian.org                                         *//*                                                           *//*************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "extern.h"#include <errno.h>#include <fcntl.h>#include <getopt.h>#include <netdb.h>#include <sched.h>#include <signal.h>#include <stdlib.h>#include <arpa/inet.h>#include <sys/mman.h>#include <sys/wait.h>#define __USE_GNU#include <string.h>#if !defined(__GLIBC__)		/* __GLIBC__ */extern char *basename(const char *);#endif				/* __GLIBC__ */#include <unistd.h>#include "watch_err.h"#if USE_SYSLOG#include <syslog.h>#endif				/* USE_SYSLOG */static int no_act = FALSE;#if USE_SYSLOGint verbose = FALSE;#endif				/* USE_SYSLOG */#define ADMIN		"admin"#define CHANGE		"change"#define DEVICE		"watchdog-device"#define	FILENAME	"file"#define INTERFACE	"interface"#define INTERVAL	"interval"#define LOGTICK		"logtick"#define MAXLOAD1	"max-load-1"#define MAXLOAD5	"max-load-5"#define MAXLOAD15	"max-load-15"#define MAXTEMP		"max-temperature"#define MINMEM		"min-memory"#define SERVERPIDFILE	"pidfile"#define PING		"ping"#define PINGCOUNT	"ping-count"#define PRIORITY	"priority"#define REALTIME	"realtime"#define REPAIRBIN	"repair-binary"#define TEMP		"temperature-device"#define TESTBIN		"test-binary"#define TESTTIMEOUT	"test-timeout"#define HEARTBEAT	"heartbeat-file"#define HBSTAMPS	"heartbeat-stamps"pid_t pid;int softboot = FALSE, watchdog = -1, load = -1, mem = -1, temp = -1;int tint = 10, logtick = 1, ticker = 1, schedprio = 1;int maxload1 = 0, maxload5 = 0, maxload15 = 0, minpages = 0;int maxtemp = 120, hbstamps = 300, lastts, nrts;int pingcount = 3;char *tempname = NULL, *devname = NULL, *admin = "root", *progname;char *timestamps, *heartbeat;time_t timeout = 0;FILE *hb;#if defined(_POSIX_MEMLOCK)int mlocked = FALSE, realtime = FALSE;#endifstatic void usage(void){    fprintf(stderr, "%s version %d.%d, usage:\n", progname, MAJOR_VERSION, MINOR_VERSION);#if USE_SYSLOG    fprintf(stderr, "%s [-i <interval> [-f]] [-l <max load avg>] [-v] [-s] [-b] [-m <max temperature>]\n", progname);#else				/* USE_SYSLOG */    fprintf(stderr, "%s [-i <interval> [-f]] [-l <max load avg>] [-v] [-b] [-m <max temperature>]\n", progname);#endif				/* USE_SYSLOG */    exit(1);}/* Try to sync */static int sync_system(int sync_it){    if (sync_it) {	sync();	sync();    }    return (0);}/* execute repair binary */static int repair(char *rbinary, int result){    pid_t child_pid;    char parm[5];    int ret;    /* no binary given, we have to reboot */    if (rbinary == NULL)	return (result);    sprintf(parm, "%d", result);    child_pid = fork();    if (!child_pid) {	/* Don't want the stdin and stdout of our test program	 * to cause trouble	 * So make stdout and stderr go to their respective files */        if (!freopen("/var/log/watchdog/repair-bin.stdout", "a+", stdout))        	exit (errno);        if (!freopen("/var/log/watchdog/repair-bin.stderr", "a+", stderr))        	exit (errno);        /* else start binary */	execl(rbinary, rbinary, parm, NULL);	/* execl should only return in case of an error */	/* so we return the reboot code */	return (errno);    } else if (child_pid < 0) {	/* fork failed */	int err = errno;	if (errno == EAGAIN) {	/* process table full */#if USE_SYSLOG	    syslog(LOG_ERR, "process table is full!");#endif				/* USE_SYSLOG */	    return (EREBOOT);	} else if (softboot)	    return (err);	else	    return (ENOERR);    }    if (waitpid(child_pid, &result, 0) != child_pid) {	int err = errno;#if USE_SYSLOG	syslog(LOG_ERR, "child %d does not exist (errno = %d = '%m')", child_pid, err);#else				/* USE_SYSLOG */	perror(progname);#endif				/* USE_SYSLOG */	if (softboot)	    return (err);    }        /* check result */    ret = WEXITSTATUS(result);    if (ret != 0) {#if USE_SYSLOG	syslog(LOG_ERR, "repair binary returned %d", ret);#endif				/* USE_SYSLOG */	if (ret == ERESET) /* repair script says force hard reset, we give it a try */		sleep(TIMER_MARGIN * 4);		/* for all other errors or if we still live, we let shutdown handle it */	return (ret);    }        return (ENOERR);}static void wd_action(int result, char *rbinary){    /* if no-action flag set, do nothing */    /* no error, keep on working */    if (result == ENOERR || no_act == TRUE)	return;    /* error that might be repairable */    if (result != EREBOOT)	result = repair(rbinary, result);    /* if still error, reboot */    if (result != ENOERR)	do_shutdown(result);}static void do_check(int res, char *rbinary){    wd_action(res, rbinary);    wd_action(keep_alive(), rbinary);}struct list *file = NULL, *target = NULL, *pidfile = NULL, *iface = NULL;char *tbinary, *rbinary, *admin;static void add_list(struct list **list, char *name){    struct list *new, *act;    if ((new = (struct list *) calloc(1, sizeof(struct list))) == NULL) {	fprintf(stderr, "%s: out of memory\n", progname);	exit(1);    }    new->name = name;    memset((char *) (&(new->parameter)), '\0', sizeof(union wdog_options));    if (*list == NULL)	*list = new;    else {	for (act = *list; act->next != NULL; act = act->next);	act->next = new;    }}static int spool(char *line, int *i, int offset){    for ((*i) += offset; line[*i] == ' ' || line[*i] == '\t'; (*i)++);    if (line[*i] == '=')	(*i)++;    for (; line[*i] == ' ' || line[*i] == '\t'; (*i)++);    if (line[*i] == '\0')    	return(1);    else    	return(0);}static void read_config(char *filename, char *progname){    FILE *wc;    int gotload5 = FALSE, gotload15 = FALSE;    if ((wc = fopen(filename, "r")) == NULL) {	perror(progname);	exit(1);    }    while (!feof(wc)) {	char line[CONFIG_LINE_LEN];	if (fgets(line, CONFIG_LINE_LEN, wc) == NULL) {	    if (!ferror(wc))		break;	    else {		perror(progname);		exit(1);	    }	} else {	    int i, j;	    /* scan the actual line for an option */	    /* first remove the leading blanks */	    for (i = 0; line[i] == ' ' || line[i] == '\t'; i++);	    /* if the next sign is a '#' we have a comment */	    if (line[i] == '#')		continue;	    /* also remove the trailing blanks and the \n */	    for (j = strlen(line) - 1; line[j] == ' ' || line[j] == '\t' || line[j] == '\n'; j--);	    line[j + 1] = '\0';	    /* if the line is empty now, we don't have to parse it */	    if (strlen(line + i) == 0)		continue;	    /* now check for an option */	    if (strncmp(line + i, FILENAME, strlen(FILENAME)) == 0) {		if (spool(line, &i, strlen(FILENAME)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    add_list(&file, strdup(line + i));	    } else if (strncmp(line + i, CHANGE, strlen(CHANGE)) == 0) {		struct list *ptr;		if (spool(line, &i, strlen(CHANGE)))		    continue;		if (!file) {	/* no file entered yet */		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		    continue;		}		for (ptr = file; ptr->next != NULL; ptr = ptr->next);		if (ptr->parameter.file.mtime != 0)		    fprintf(stderr, "Duplicate change interval option in config file. Ignoring first entry.\n");		ptr->parameter.file.mtime = atoi(line + i);	    } else if (strncmp(line + i, SERVERPIDFILE, strlen(SERVERPIDFILE)) == 0) {		if (spool(line, &i, strlen(SERVERPIDFILE)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    add_list(&pidfile, strdup(line + i));	    } else if (strncmp(line + i, PINGCOUNT, strlen(PINGCOUNT)) == 0) {		if (spool(line, &i, strlen(PINGCOUNT)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    pingcount = atol(line + i);	    } else if (strncmp(line + i, PING, strlen(PING)) == 0) {		if (spool(line, &i, strlen(PING)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    add_list(&target, strdup(line + i));	    } else if (strncmp(line + i, INTERFACE, strlen(INTERFACE)) == 0) {		if (spool(line, &i, strlen(INTERFACE)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    add_list(&iface, strdup(line + i));	    } else if (strncmp(line + i, REALTIME, strlen(REALTIME)) == 0) {		(void)spool(line, &i, strlen(REALTIME));		realtime = (strncmp(line + i, "yes", 3) == 0) ? TRUE : FALSE;	    } else if (strncmp(line + i, PRIORITY, strlen(PRIORITY)) == 0) {		if (spool(line, &i, strlen(PRIORITY)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    schedprio = atol(line + i);	    } else if (strncmp(line + i, REPAIRBIN, strlen(REPAIRBIN)) == 0) {		if (spool(line, &i, strlen(REPAIRBIN)))			rbinary = NULL;		else			rbinary = strdup(line + i);	    } else if (strncmp(line + i, TESTBIN, strlen(TESTBIN)) == 0) {		if (spool(line, &i, strlen(TESTBIN)))			tbinary = NULL;		else			tbinary = strdup(line + i);	    } else if (strncmp(line + i, TESTTIMEOUT, strlen(TESTTIMEOUT)) == 0) {		if (spool(line, &i, strlen(TESTTIMEOUT)))			timeout = 0;		else			timeout = atol(line + i);	    } else if (strncmp(line + i, HEARTBEAT, strlen(HEARTBEAT)) == 0) {		if (spool(line, &i, strlen(HEARTBEAT)))			heartbeat = NULL;		else			heartbeat = strdup(line + i);	    } else if (strncmp(line + i, HBSTAMPS, strlen(HBSTAMPS)) == 0) {		if (spool(line, &i, strlen(HBSTAMPS)))		        fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else			hbstamps = atol(line + i);	    } else if (strncmp(line + i, ADMIN, strlen(ADMIN)) == 0) {		if (spool(line, &i, strlen(ADMIN)))			admin = NULL;		else			admin = strdup(line + i);	    } else if (strncmp(line + i, INTERVAL, strlen(INTERVAL)) == 0) {		if (spool(line, &i, strlen(INTERVAL)))		    fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else		    tint = atol(line + i);	    } else if (strncmp(line + i, LOGTICK, strlen(LOGTICK)) == 0) {		if (spool(line, &i, strlen(LOGTICK)))		    logtick = ticker = 1;		else		    logtick = ticker = atol(line + i);	    } else if (strncmp(line + i, DEVICE, strlen(DEVICE)) == 0) {		if (spool(line, &i, strlen(DEVICE)))			devname = NULL;		else			devname = strdup(line + i);	    } else if (strncmp(line + i, TEMP, strlen(TEMP)) == 0) {		if (spool(line, &i, strlen(TEMP)))			tempname = NULL;		else			tempname = strdup(line + i);	    } else if (strncmp(line + i, MAXTEMP, strlen(MAXTEMP)) == 0) {		if (spool(line, &i, strlen(MAXTEMP)))			fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else			maxtemp = atol(line + i);	    } else if (strncmp(line + i, MAXLOAD15, strlen(MAXLOAD15)) == 0) {		if (spool(line, &i, strlen(MAXLOAD15)))			fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else {			maxload15 = atol(line + i);			gotload15 = TRUE;		}	    } else if (strncmp(line + i, MAXLOAD1, strlen(MAXLOAD1)) == 0) {		if (spool(line, &i, strlen(MAXLOAD1)))			fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else {			maxload1 = atol(line + i);			if (!gotload5)			    maxload5 = maxload1 * 3 / 4;			if (!gotload15)			    maxload15 = maxload1 / 2;		}	    } else if (strncmp(line + i, MAXLOAD5, strlen(MAXLOAD5)) == 0) {		if (spool(line, &i, strlen(MAXLOAD5)))			fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else {			maxload5 = atol(line + i);			gotload5 = TRUE;		}	    } else if (strncmp(line + i, MINMEM, strlen(MINMEM)) == 0) {		if (spool(line, &i, strlen(MINMEM)))			fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);		else {			minpages = atol(line + i);		}	    } else {		fprintf(stderr, "Ignoring invalid line in config file:\n%s\n", line);	    }	}    }    if (fclose(wc) != 0) {	perror(progname);	exit(1);    }}static void old_option(int c, char *filename){    fprintf(stderr, "Option -%c is no longer valid, please specify it in %s.\n", c, filename);    usage();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -