Back to index

im-sdk  12.3.91
Functions | Variables
watchdog.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include "SharedData.h"

Go to the source code of this file.

Functions

static void clean_up (int)
int main (int argc, char **argv)

Variables

int iiimd_pid = 0

Function Documentation

void clean_up ( int  unused) [static]

Definition at line 461 of file watchdog.c.

                         {
    kill(iiimd_pid, SIGTERM);
    exit(1);
}

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 219 of file watchdog.c.

{
    const char *iiimdpath=IIIMPATHIIIMD ; /* SUNWiiimf Only */
    pid_t pgrp;
    void (*disp)(int);
    char **new_argv, **pp;
    int newargc = 1, i, retry_on_error = 4, retrycount;

#ifdef SunOS
    
#ifdef DELAYED_START
    int hardlimit = HARDLIMIT  ; /* Experimental: 2 minutes */
#endif /* DELAYED_START */
    int interval          ;  /* Experimental: 2 sec */
    int salt = 1 ;         /* salt should reflect perf measurement */
    int loadlowwater = 1 ; /* Experimental */
    int cpulowwater = 20 ; /* 20% */
    static int desktop_is_up ;
    static int confirm = 0 ;
    int use_syslog;
    char * message_locale;

    setlocale(LC_ALL, "");

    use_syslog = 0;
    message_locale = NULL;
    /* not enough */
    for (i = argc - 1, pp = argv + 1; 0 < i; --i, pp++) {
       if (0 == strcmp(*pp, "-syslog")) {
           use_syslog = 1;
       } else if (0 == strcmp(*pp, "-message_locale")) {
           if (1 == i) break;
           --i;
           pp++;
           message_locale = *pp;
       } else if (0 == strcmp(*pp, "-retryonerror")) {
           if (1 == i) break;
           --i;
           pp++;
           retry_on_error = atoi(*pp);
       } else if (0 == strcmp(*pp, "-h") ||
                 0 == strcmp(*pp, "-help") ||
                 0 == strcmp(*pp, "--help")) {
           fprintf(stderr, "Usage: %s [-retryonerror NUM]\n", argv[0]);
           exit(1);
       } else {
           /* unknown options found. stop parsing option for iiimd here */
           break;
       }
    }
    newargc = argc - i;

    openlog("iiimd", LOG_PID, LOG_USER);

    /* BugId : 4281734. No need to have delayed start now.
       iiim_server does not require X connection and will be started only
       in asian locales.
    */
#ifdef DELAYED_START
    if (desktop_is_up = is_desktop_up()){
       /* Must not be from bootup time */
       interval = MININTERVAL ;
    } else {
       interval = INITINTERVAL ;
    }
    
    for(; hardlimit > 0; hardlimit -= interval){ /* delayed start loop */

#ifdef DEBUG
printf("%3d | ", salt*HARDLIMIT - hardlimit);
#endif

       if (is_load_or_cpu_low(loadlowwater, cpulowwater, &interval)){
           confirm++ ;
       } else {
           confirm = 0 ;
       }
        if (confirm > 0)
           break ;

        if(!desktop_is_up){
           if (is_desktop_up()){
              desktop_is_up = 1 ; 
              /* Causes too much delay - 4264139 
              interval += DESKTOPINTERVAL ;
              */
#ifdef DEBUG
printf("Desktop is up now\n");
#endif
           }
       }
        if(interval > MININTERVAL){
           interval=(interval+MININTERVAL)/2;
       }
       sleep(interval);

#ifdef DEBUG
        fflush(stdout);
#endif

    }

#endif  /* DELAYED_START */

#ifdef DEBUG
printf("Go though\n");
#endif

#else
    for (i = argc - 1, pp = argv + 1; 0 < i; --i, pp++) {
       if (0 == strcmp(*pp, "-retryonerror")) {
           if (1 == i) break;
           --i;
           pp++;
           retry_on_error = atoi(*pp);
       } else if (0 == strcmp(*pp, "-h") ||
                 0 == strcmp(*pp, "-help") ||
                 0 == strcmp(*pp, "--help")) {
           fprintf(stderr, "Usage: %s [-retryonerror NUM]\n", argv[0]);
           exit(1);
       } else {
           /* unknown options found. stop parsing option for iiimd here */
           break;
       }
    }
    newargc = argc - i;

    openlog("iiimd", LOG_PID, LOG_USER);

#endif /* SunOS */
#ifdef SunOS
    sigset(SIGTERM, clean_up);
    sigset(SIGINT, clean_up);
#else
    signal(SIGTERM, clean_up);
    signal(SIGINT, clean_up);
#endif

    pgrp = setsid();
    if ((pid_t)(-1) == pgrp)
      fprintf (stderr,"cannot set session id");

    /* Create new argv */
    new_argv = (char**) malloc(sizeof(char*) * (argc + 2));
    if (!new_argv) {
      syslog(LOG_ERR, "malloc failed");
      exit(1);
    }
    new_argv[0]="iiimd";
    new_argv[1] = "-nodaemon";
    if (argc > 0)
      memcpy(new_argv + 2, argv + newargc, sizeof(char*) * argc - newargc);
    else
      new_argv[2]= NULL;

    retrycount = retry_on_error;

    for(;;){
#ifdef DEBUG
        fflush(stdout);
#endif
       if((iiimd_pid = fork()) == 0){
           /* XXX uid should be changed to nobody */
            execv(iiimdpath, new_argv);
           syslog(LOG_ERR, "execv iiimd failed\n");
            exit(17);
       } else if(iiimd_pid < 0) {
           syslog(LOG_WARNING, "iiimd watchdog: fork was failed\n");
           sleep(60);
       } else {
            int status ;
            waitpid(iiimd_pid, &status, 0) ;
           
           if (WIFSIGNALED(status)) {
              switch(WTERMSIG(status)) {
                case SIGTERM :
                case SIGKILL : /* there must be a reason */
                    exit (0);
                    break ;
                case SIGCHLD :
                    kill(iiimd_pid, SIGTERM);
                    exit(1);       
                case SIGSEGV:
                    syslog(LOG_WARNING, "iiimd watchdog: iiimd segfaulted");
                    retrycount--;
                    break;
                case SIGABRT:
                    syslog(LOG_WARNING, "iiimd watchdog: iiimd aborted");
                    retrycount--;
                    break;
                default:
                   /* 
                    * 1999/09/28
                    * SIGTERM seems more appropriate,
                    * but orphan iiimd's do not
                    * stop with SIGTERM.
                    */
#ifdef SunOS
                    disp = sigset(SIGUSR1, SIG_IGN);
                    kill(-pgrp, SIGUSR1);
                    sigset(SIGUSR1, disp);
#else /* !SunOS */
                    disp = signal(SIGUSR1, SIG_IGN);
                    kill(-pgrp, SIGUSR1);
                    signal(SIGUSR1, disp);
#endif /* !SunOS */
                    break ;
              }
              if (retrycount < 0) {
                  syslog(LOG_ERR, "give up trying to run iiimd.\n");
                  kill(iiimd_pid, SIGTERM);
                  exit(1);
              }
              sleep(1);
           } else if (WIFEXITED(status)) {
              switch(WEXITSTATUS(status)) {
                case 100: /* unknown options was given */
                    syslog(LOG_ERR, "unrecognized options was given to iiimd.\n");
                    retrycount = 0;
                case 17 : /* failed to execv() */
                case 255: /* seriously not continued working */
                case NOLEIF_EXITCODE :   /* Kill the server */
                case NORUN_EXITCODE :   /* fix for 4297357 */
                    retrycount--;
                    if (retrycount < 0) {
                       syslog(LOG_ERR, "give up trying to run iiimd.\n");
                       kill(iiimd_pid, SIGTERM);
                       exit(1);    
                    }
                    sleep(1);
                    break;
                default:
                    retrycount = retry_on_error;
                    break ;
              }
           }
       }
    }
}

Here is the call graph for this function:


Variable Documentation

int iiimd_pid = 0

Definition at line 216 of file watchdog.c.