/*
- $Id: watchquagga.c,v 1.6 2004/12/23 19:35:56 paul Exp $
+ $Id$
Monitor status of quagga daemons and restart if necessary.
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* System headers: */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-/* Quagga headers: */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
+#include <zebra.h>
#include <thread.h>
#include <log.h>
+#include <network.h>
#include <sigevent.h>
-#include <version.h>
+#include <lib/version.h>
#include <getopt.h>
+#include <sys/un.h>
+#include <sys/wait.h>
#ifndef MIN
#define MIN(X,Y) (((X) <= (Y)) ? (X) : (Y))
}
default:
/* Parent process: we will reap the child later. */
- zlog_err("Forked background command [pid %d]: %s",child,shell_cmd);
+ zlog_err("Forked background command [pid %d]: %s",(int)child,shell_cmd);
return child;
}
}
time_elapsed(&delay,&restart->time);
zlog_warn("Warning: %s %s child process %d still running after "
"%ld seconds, sending signal %d",
- restart->what,restart->name,restart->pid,delay.tv_sec,
+ restart->what,restart->name,(int)restart->pid,delay.tv_sec,
(restart->kills ? SIGKILL : SIGTERM));
kill(-restart->pid,(restart->kills ? SIGKILL : SIGTERM));
restart->kills++;
else
{
zlog_err("waitpid returned status for an unknown child process %d",
- child);
+ (int)child);
name = "(unknown)";
what = "background";
}
if (WIFSTOPPED(status))
zlog_warn("warning: %s %s process %d is stopped",
- what,name,child);
+ what,name,(int)child);
else if (WIFSIGNALED(status))
zlog_warn("%s %s process %d terminated due to signal %d",
- what,name,child,WTERMSIG(status));
+ what,name,(int)child,WTERMSIG(status));
else if (WIFEXITED(status))
{
if (WEXITSTATUS(status) != 0)
zlog_warn("%s %s process %d exited with non-zero status %d",
- what,name,child,WEXITSTATUS(status));
+ what,name,(int)child,WEXITSTATUS(status));
else
- zlog_debug("%s %s process %d exited normally",what,name,child);
+ zlog_debug("%s %s process %d exited normally",what,name,(int)child);
}
else
zlog_err("cannot interpret %s %s process %d wait status 0x%x",
- what,name,child,status);
+ what,name,(int)child,status);
phase_check();
}
{
if (gs.loglevel > LOG_DEBUG+1)
zlog_debug("cannot %s %s, previous pid %d still running",
- cmdtype,restart->name,restart->pid);
+ cmdtype,restart->name,(int)restart->pid);
return -1;
}
- if (!force &&
- (time_elapsed(&delay,&restart->time)->tv_sec < restart->interval))
+ /* Note: time_elapsed test must come before the force test, since we need
+ to make sure that delay is initialized for use below in updating the
+ restart interval. */
+ if ((time_elapsed(&delay,&restart->time)->tv_sec < restart->interval) &&
+ !force)
{
if (gs.loglevel > LOG_DEBUG+1)
zlog_debug("postponing %s %s: "
{
char why[100];
- if ((errno == EINTR) || (errno == EAGAIN))
+ if (ERRNO_IO_RETRY(errno))
{
/* Pretend it never happened. */
SET_READ_HANDLER(dmn);
int sock;
struct sockaddr_un addr;
socklen_t len;
- int flags;
if (gs.loglevel > LOG_DEBUG+1)
zlog_debug("%s: attempting to connect",dmn->name);
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s.vty",
gs.vtydir,dmn->name);
-#ifdef HAVE_SUN_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
len = addr.sun_len = SUN_LEN(&addr);
#else
len = sizeof (addr.sun_family) + strlen (addr.sun_path);
-#endif /* HAVE_SUN_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
/* Quick check to see if we might succeed before we go to the trouble
of creating a socket. */
return -1;
}
- /* Set non-blocking. */
- if ((flags = fcntl(sock, F_GETFL, 0)) < 0)
+ if (set_nonblocking(sock) < 0)
{
- zlog_err("%s(%s): fcntl(F_GETFL) failed: %s",
- __func__,addr.sun_path, safe_strerror(errno));
- close(sock);
- return -1;
- }
- if (fcntl(sock, F_SETFL, (flags|O_NONBLOCK)) < 0)
- {
- zlog_err("%s(%s): fcntl(F_SETFL,O_NONBLOCK) failed: %s",
- __func__,addr.sun_path, safe_strerror(errno));
+ zlog_err("%s(%s): set_nonblocking(%d) failed",
+ __func__, addr.sun_path, sock);
close(sock);
return -1;
}
for (dmn = gs.daemons; dmn; dmn = dmn->next)
{
if (dmn != gs.special)
- run_job(&dmn->restart,"start",gs.start_command,1,1);
+ run_job(&dmn->restart,"start",gs.start_command,1,0);
}
}
gs.phase = PHASE_NONE;
for (dmn = gs.daemons; dmn; dmn = dmn->next)
{
if (dmn != gs.special)
- run_job(&dmn->restart,"stop",gs.stop_command,1,0);
+ run_job(&dmn->restart,"stop",gs.stop_command,1,1);
}
set_phase(PHASE_STOPS_PENDING);
break;