Commit 75057916 authored by Kirk Webb's avatar Kirk Webb

healthd code updated to handle select return codes properly. The old code

assumed that the fdesc set was correctly reported when select was interrupted
by a signal.  In the new Linux kernels, this is not the case, and is certainly
not safe to assume in the first place.  Did some cleanups of the daemon loop
as well.
parent c78d9503
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: healthd.c,v 1.3 2002-07-10 00:37:51 kwebb Exp $ * $Id: healthd.c,v 1.4 2003-04-04 21:35:29 kwebb Exp $
*/ */
/* /*
* *
...@@ -58,11 +58,6 @@ ...@@ -58,11 +58,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <signal.h> #include <signal.h>
#include <netdb.h> #include <netdb.h>
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
int allow_severity = LOG_INFO;
int deny_severity = LOG_WARNING;
#endif /* HAVE_LIBWRAP */
#include "parameters.h" #include "parameters.h"
#include "healthd.h" #include "healthd.h"
#include "VERSION.h" #include "VERSION.h"
...@@ -245,6 +240,7 @@ struct OptionInfo { ...@@ -245,6 +240,7 @@ struct OptionInfo {
void void
SIGHUP_handler(int sig) { SIGHUP_handler(int sig) {
ReReadConfigFile = 1; ReReadConfigFile = 1;
signal(SIGHUP, SIGHUP_handler);
} }
void void
...@@ -262,7 +258,7 @@ SIGALRM_handler(int sig) { ...@@ -262,7 +258,7 @@ SIGALRM_handler(int sig) {
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
int n, sec; int n;
int ch; int ch;
int method='I'; int method='I';
int ConfigRead; int ConfigRead;
...@@ -275,27 +271,21 @@ main(int argc, char *argv[]) { ...@@ -275,27 +271,21 @@ main(int argc, char *argv[]) {
int sock; int sock;
int sock6; int sock6;
int length; int length;
#ifdef INET6
int ipv6_enable=1;
struct sockaddr_in6 server6;
#endif /* INET6 */
int ipv4_enable=1; int ipv4_enable=1;
struct sockaddr_in server; struct sockaddr_in server;
int msgsock; int msgsock;
char buf[1024]; char buf[1024];
char outbuf[1024]; char outbuf[1024];
int rval; int rval;
int selretval;
int syserr;
fd_set ready; fd_set ready;
struct servent *sp; struct servent *sp;
struct timeval to;
unsigned long port; unsigned long port;
int psd = -1; int psd = -1;
struct sockaddr_in paddr; struct sockaddr_in paddr;
struct hostent *hent; struct hostent *hent;
time_t now;
time_t tloc;
struct itimerval tmo = {{0,0},{0,0}}; struct itimerval tmo = {{0,0},{0,0}};
struct itimerval tmooff = {{0,0},{0,0}}; struct itimerval tmooff = {{0,0},{0,0}};
...@@ -349,11 +339,7 @@ main(int argc, char *argv[]) { ...@@ -349,11 +339,7 @@ main(int argc, char *argv[]) {
local = 0; local = 0;
LocalOnly = 0; LocalOnly = 0;
#ifdef INET6
while((ch=getopt(argc, argv, "1246BDILSP:Vc:df:t:p:q")) != -1) {
#else /* !INET6 */
while((ch=getopt(argc, argv, "12BDILSP:Vc:df:t:p:q")) != -1) { while((ch=getopt(argc, argv, "12BDILSP:Vc:df:t:p:q")) != -1) {
#endif /* !INET6 */
switch(ch){ switch(ch){
case '1': case '1':
MonitorType = W83781D; MonitorType = W83781D;
...@@ -363,15 +349,6 @@ main(int argc, char *argv[]) { ...@@ -363,15 +349,6 @@ main(int argc, char *argv[]) {
MonitorType = W83782D; MonitorType = W83782D;
break; break;
#ifdef INET6
case '4':
ipv4_enable = 0;
break;
case '6':
ipv6_enable = 0;
break;
#endif /* INET6 */
case 'B': case 'B':
UseVbat = 1; UseVbat = 1;
...@@ -455,13 +432,8 @@ main(int argc, char *argv[]) { ...@@ -455,13 +432,8 @@ main(int argc, char *argv[]) {
break; break;
default: default:
#ifdef INET6
fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV46] [-f configfile] [-c|t count] <seconds for sleep>"\
" (default %d sec)\n", DaemonName, DEFAULT_SEC);
#else /* !INET6 */
fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\ fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\
" (default %d sec)\n", DaemonName, DEFAULT_SEC); " (default %d sec)\n", DaemonName, DEFAULT_SEC);
#endif /* !INET6 */
exit(1); exit(1);
} }
} }
...@@ -475,13 +447,8 @@ main(int argc, char *argv[]) { ...@@ -475,13 +447,8 @@ main(int argc, char *argv[]) {
if((n = atoi(argv[optind])) > 0) { if((n = atoi(argv[optind])) > 0) {
tmo.it_value.tv_sec = n; tmo.it_value.tv_sec = n;
} else { } else {
#ifdef INET6
fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV46] [-f configfile] [-c|t count] <seconds for sleep>"\
" (default %d sec)\n", DaemonName, DEFAULT_SEC);
#else /* !INET6 */
fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\ fprintf(stderr, "Usage: %s -[1|2] -[I|S] [-dLV] [-f configfile] [-c|t count] <seconds for sleep>"\
" (default %d sec)\n", DaemonName, DEFAULT_SEC); " (default %d sec)\n", DaemonName, DEFAULT_SEC);
#endif /* !INET6 */
exit(1); exit(1);
} }
} else { } else {
...@@ -599,37 +566,6 @@ main(int argc, char *argv[]) { ...@@ -599,37 +566,6 @@ main(int argc, char *argv[]) {
} }
if (LocalOnly == 0) { if (LocalOnly == 0) {
/* Create name with wildcards. */ /* Create name with wildcards. */
#ifdef INET6
if ((ipv4_enable == 0) && (ipv6_enable == 0)) {
ipv4_enable = 1;
}
if (ipv6_enable) {
/* Create socket from which to read. */
sock6 = socket(AF_INET6, SOCK_STREAM, 0);
if (sock6 < 0) {
syslog(hdALERT, "opening IPV6 datagram socket: %m");
syslog(hdALERT, "Aborting");
exit(1);
}
server6.sin6_family = AF_INET6;
server6.sin6_addr = in6addr_any;
server6.sin6_port = htons(port);
if (bind(sock6, (struct sockaddr *)&server6, sizeof(struct sockaddr_in6))) {
close(sock6);
syslog(hdALERT, "binding IPv6 datagram socket: %m");
syslog(hdALERT, "Aborting");
exit(1);
}
/* Find assigned port value and print it out. */
length = sizeof(server6);
if (getsockname(sock6, (struct sockaddr *)&server6, &length)) {
close(sock6);
syslog(hdALERT, "getting socket IPv6 name: %m");
syslog(hdALERT, "Aborting");
exit(1);
}
}
#endif /* INET6 */
if (ipv4_enable) { if (ipv4_enable) {
/* Create socket from which to read. */ /* Create socket from which to read. */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
...@@ -660,114 +596,74 @@ main(int argc, char *argv[]) { ...@@ -660,114 +596,74 @@ main(int argc, char *argv[]) {
ReadCurrentValues(); ReadCurrentValues();
if (LocalOnly == 0) { if (LocalOnly == 0) {
/* Start accepting connections */ /* Start accepting connections */
#ifdef INET6
if (sock6 != 0) {
listen(sock6, 32);
}
#endif /* INET6 */
if (sock != 0) { if (sock != 0) {
listen(sock, 32); listen(sock, 32);
} }
} }
/* Main daemon loop */
while ((iter<count) || (count==0)) { while ((iter<count) || (count==0)) {
FD_ZERO(&ready); FD_ZERO(&ready);
if (LocalOnly == 0) { if (LocalOnly == 0) {
#ifdef INET6
if (sock6 != 0) {
FD_SET(sock6, &ready);
}
#endif /* INET6 */
if (sock != 0) { if (sock != 0) {
FD_SET(sock, &ready); FD_SET(sock, &ready);
} }
} }
/* Replace all this goofy shit with setitimer */ /* Wait for connection, or timeout */
#ifdef COMMENT
to.tv_sec = 0;
if (sec <= 3) {
/* For quick reading we need quicker timeouts */
to.tv_usec = 100;
} else if (sec <= 10) {
/* Still want reasonable accuracy */
to.tv_usec = 500;
} else {
/* Let us reduce CPU ussage */
to.tv_usec = 1000;
}
#endif /* COMMENT */
setitimer(ITIMER_REAL,&tmo,0); setitimer(ITIMER_REAL,&tmo,0);
select(getdtablesize(), &ready, 0, 0, 0); selretval = select(getdtablesize(), &ready, 0, 0, 0);
syserr = errno;
setitimer(ITIMER_REAL,&tmooff,0); setitimer(ITIMER_REAL,&tmooff,0);
if ( ExitProgram ) { if ( ExitProgram ) {
break; break;
} }
if (ReReadConfigFile) {
/*
* If we are updating the config file
* then we should clear the error counts.
*/
for (n=0; n<MAX_TYPES; n++) {
active[n] = 0;
fail_count[n] = 0;
warn_level[n] = 2;
warn_sent[n] = 0;
fail_level[n] = 5;
fail_sent[n] = 0;
}
ReadConfigFile (ConfigFile);
ReReadConfigFile = 0;
syslog(hdNOTICE, "Restarted");
continue;
}
if (LocalOnly == 0) {
if (FD_ISSET(sock, &ready)) {
msgsock = accept(sock, 0, 0);
if (msgsock == -1) { switch (selretval) {
/* Add error handling here */ case -1:
} else { if (syserr && syserr != EINTR) {
#ifdef HAVE_LIBWRAP syslog(hdCRITICAL, "OOPS! select returned a weird error, bailing out: %m");
struct request_info req; exit(1);
}
request_init(&req, RQ_DAEMON, DaemonName, RQ_FILE, msgsock, NULL);
fromhost(&req);
if (hosts_access(&req)) { if (ReReadConfigFile) {
#endif /* LIBWRAP */ /*
do { * If we are updating the config file
bzero(buf, sizeof(buf)); * then we should clear the error counts.
bzero(outbuf, sizeof(outbuf)); */
if ((rval = read(msgsock, buf, 1024)) > 0) { for (n=0; n<MAX_TYPES; n++) {
rval = GetAnswer(buf, outbuf); active[n] = 0;
write(msgsock, outbuf, strlen(outbuf)); fail_count[n] = 0;
} warn_level[n] = 2;
else if (rval < 0) { warn_sent[n] = 0;
break; fail_level[n] = 5;
} fail_sent[n] = 0;
} while (rval != 0); }
#ifdef HAVE_LIBWRAP ReadConfigFile (ConfigFile);
} ReReadConfigFile = 0;
#endif /* HAVE_LIBWRAP */ syslog(hdWARNING, "Restarted");
close(msgsock); break;
}
} }
#ifdef INET6
if (FD_ISSET(sock6, &ready)) {
msgsock = accept(sock6, 0, 0);
if (msgsock == -1) { if (count > 0) {
/* Add error handling here */ iter++;
} else { }
#ifdef HAVE_LIBWRAP
struct request_info req; ReadCurrentValues();
if (pushit) {
push_stat(psd);
}
break;
request_init(&req, RQ_DAEMON, DaemonName, RQ_FILE, msgsock, NULL); default:
fromhost(&req); if (LocalOnly == 0) {
if (FD_ISSET(sock, &ready)) {
msgsock = accept(sock, 0, 0);
if (hosts_access(&req)) { if (msgsock == -1) {
#endif /* HAVE_LIBWRAP */ /* Add error handling here */
} else {
do { do {
bzero(buf, sizeof(buf)); bzero(buf, sizeof(buf));
bzero(outbuf, sizeof(outbuf)); bzero(outbuf, sizeof(outbuf));
...@@ -779,35 +675,26 @@ main(int argc, char *argv[]) { ...@@ -779,35 +675,26 @@ main(int argc, char *argv[]) {
break; break;
} }
} while (rval != 0); } while (rval != 0);
#ifdef HAVE_LIBWRAP close(msgsock);
} }
#endif /* HAVE_LIBWRAP */ }
close(msgsock);
}
} }
#endif /* INET6 */ break;
}
if (count > 0) {
iter++;
}
ReadCurrentValues();
if (pushit) {
push_stat(psd);
} }
if (ExitProgram) { if (ExitProgram) {
break; break;
} }
} }
if (LocalOnly == 0) { if (LocalOnly == 0) {
close(sock); close(sock);
#ifdef INET6
close(sock6);
#endif /* INET6 */
} }
if (debug == 0) { if (debug == 0) {
signal(SIGHUP, SIG_DFL); signal(SIGHUP, SIG_DFL);
signal(SIGTERM, SIG_DFL); signal(SIGTERM, SIG_DFL);
} }
syslog(hdWARNING, "Exiting..");
exit(0); exit(0);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment