/* This programm is written by G. Caronni in '97 */ #include #include #include #include #include #include #define VERSION "1.1" #define STOP_LOAD 1.6 #define RUN_LOAD 0.6 #define INTERVALL 60 /* seconds */ #define UPTIME "/usr/ucb/uptime" char *subprog[] = { "/home/caronni/desclient", "desclient", "-s", "keymaster.des.sollentuna.se", "-e", "gec@acm.org", "-n", "20", NULL}; int pid=0; int verbose=0; float getload(void) { char buf[1024], *t; float load; FILE *p=popen(UPTIME,"r"); if (!p) { perror("popen"); if (verbose) printf("Collecting load stats failed.\n"); if (verbose) printf("Terminating child...\n"); kill (pid,SIGTERM); exit(2); } fgets(buf,sizeof(buf),p); pclose(p); t=strstr(buf,"load average"); if (t) t=strtok(t,","); if (t) t=strtok(NULL,", "); if (t && sscanf(t,"%f",&load)==1) { if (verbose) printf("Scanned load: %0.2f\n",load); } else { if (verbose) printf("Parsing load stats failed.\n"); if (verbose) printf("Terminating child...\n"); kill (pid,SIGTERM); exit(2); } return load; } int main(int argc, char *argv[], char *envp[]) { extern int optind; extern char *optarg; int c; int errflg = 0; float stop_load, run_load; char **sprog=subprog; *envp=NULL; stop_load=run_load=0.0; while ((c = getopt(argc, argv, "vs:r:")) != EOF) { switch (c) { case 'v': verbose++; break; case 's': if (sscanf(optarg,"%f",&stop_load)!=1) errflg++; break; case 'r': if (sscanf(optarg,"%f",&run_load)!=1) errflg++; break; case '?': errflg++; } } if (!stop_load) { stop_load=STOP_LOAD; if (!run_load) run_load=RUN_LOAD; } else if (!run_load) run_load=stop_load; if (stop_load <= 1.0) errflg++; if (run_load > stop_load) errflg++; if (errflg) { (void)fprintf(stderr, "Usage: %s [-v] [-s stopload] [-r runload] [command to call]\n" " -v verbose\n" " -s stopload process will be stopped if load surpassed\n" " load specified must be higer than 1.0\n" " -r runload process will be restarted at this load\n" " load specified must be lower than stopload\n" ,argv[0]); exit(1); } if (optind < argc) sprog = &(argv[optind]); if (verbose) { int i=0; printf("Load watcher (%s), runload: %0.2f, stopload: %0.2f, " "command to be executed:\n", VERSION, run_load,stop_load); while(sprog[i]) printf("%s ",sprog[i++]); printf("\n"); } signal(SIGCHLD,SIG_IGN); /* ============================================ */ if (!(pid=fork())) { execv(*sprog,sprog); perror("execv"); exit(-1); } /* ============================================ */ if (pid<0) { perror("fork"); exit(-1); } sleep(1); while (1) { if (kill(pid,0)) { if (verbose) { perror("kill(pid,0)"); fprintf(stderr, "Child process unreachable. Terminating...\n"); } break; } if (getload()>stop_load) { if (verbose) printf("Maximum load exceeded. Idling...\n"); if (kill(pid,SIGSTOP)) { if (verbose) { perror("kill(pid,SIGSTOP)"); fprintf(stderr, "Child process unreachable. Terminating...\n"); } break; } while(getload()>run_load) sleep (INTERVALL); if (verbose) printf("Load below threshold. Continuing...\n"); if (kill(pid,SIGCONT)) { if (verbose) { perror("kill(pid,SIGCONT)"); fprintf(stderr, "Child process unreachable. Terminating...\n"); } break; } } sleep(INTERVALL); } return 0; } /* EOT */