#include #include #include #include #include #include #include #include "process.h" #include "monitortasks.m" static void usage() { fprintf (stderr,MSG_U(I_USAGE ,"taskmon %s\n" "\n" "taskmon [ --cycle seconds ] [ --config config_file ]\n" " [ --signum signal ] [ --mail email ]\n" "\n" "signum: signal number used to kill the processes (default SIGTERM)\n" "email: Process termination acknoledge will be sent there\n" " They are registered in syslog as well\n" "seconds: wakes up every \"seconds\" time\n" "\n" "config_file: path of the config file\n" " It contains lines in the following format:\n" " process_name percent\n" " ...\n" "percent represent the maximum cpu time fraction of a cycle.\n" "Any offending process will be killed.\n") ,PACKAGE_REV); exit (-1); } class PMON: public ARRAY_OBJ{ public: SSTRING name; int pid; long accum; // Accumulated time since process start bool mark; // To clean up old process int signaled; /*~PROTOBEG~ PMON */ public: PMON (const char *_name, int _pid); /*~PROTOEND~ PMON */ }; PUBLIC PMON::PMON(const char *_name, int _pid) { pid = _pid; name.setfrom (_name); mark = false; accum = 0; signaled = 0; } class PMONS: public ARRAY{ /*~PROTOBEG~ PMONS */ public: PMON *getitem (int no)const; PMON *locatepid (int pid)const; /*~PROTOEND~ PMONS */ }; PUBLIC PMON *PMONS::getitem(int no) const { return (PMON*)ARRAY::getitem(no); } PUBLIC PMON *PMONS::locatepid(int pid) const { PMON *ret = NULL; for (int i=0; ipid == pid){ ret = m; break; } } return ret; } class CONFPROC: public ARRAY_OBJ{ public: SSTRING name; int maxaccum; // Maximum allowed process time in one // pass /*~PROTOBEG~ CONFPROC */ public: CONFPROC (const char *_name, int _maxaccum); /*~PROTOEND~ CONFPROC */ }; PUBLIC CONFPROC::CONFPROC(const char *_name, int _maxaccum) { name.setfrom (_name); maxaccum = _maxaccum; } class CONFPROCS: public ARRAY{ /*~PROTOBEG~ CONFPROCS */ public: CONFPROCS (const char *config, int cycle); CONFPROC *getitem (int no)const; CONFPROC *lookup (const char *name)const; /*~PROTOEND~ CONFPROCS */ }; PUBLIC CONFPROC *CONFPROCS::getitem (int no) const { return (CONFPROC*)ARRAY::getitem(no); } PUBLIC CONFPROC *CONFPROCS::lookup(const char *name) const { CONFPROC *ret = NULL; int n = getnb(); for (int i=0; iname.cmp(name)==0){ ret = c; break; } } return ret; } PUBLIC CONFPROCS::CONFPROCS(const char *config, int cycle) { CONFIG_FILE ff (config,help_nil,CONFIGF_NONE); FILE_CFG *fin = ff.fopen ("r"); if (fin != NULL){ char buf[1000]; while (fgets_strip (buf,sizeof(buf)-1,fin,NULL)!=NULL){ if (buf[0] != '\0'){ char name[1000]; char *pt = str_copyword (name,buf,sizeof(name)-1); pt = str_skip(pt); int percent = atoi(pt); if (percent <= 0) percent = 75; percent = percent * cycle / 100; add (new CONFPROC (name,percent)); } } fclose (fin); } } int main (int argc, char *argv[]) { linuxconf_loadlibmsg("linuxconf"); linuxconf_loadmsg ("monitortasks",PACKAGE_REV); const char *config = "/etc/monitortasks.conf"; int cycle = 60; int signum = SIGTERM; const char *mail = "root"; for (int i=1; imark = false; } PROC *pt = process_getfirst(); while (pt != NULL){ // const char *ppath = pt->getpath(); const char *pname = pt->getname(); CONFPROC *cp = confs.lookup(pname); if (cp != NULL){ int pid = pt->getpid(); PMON *m = pmons.locatepid(pid); long accum = pt->getcputime(); if (m == NULL){ m = new PMON(pname,pid); pmons.add (m); }else{ int diff = accum - m->accum; if (diff >= cp->maxaccum){ // printf ("pid %d accum %d >= %d\n",pid,diff,cp->maxaccum); pt->kill(signum); m->signaled++; if (m->signaled == 1){ char msg[1000]; snprintf (msg,sizeof(msg)-1 ,MSG_U(I_MAIL,"Process %s have been terminated") ,pname); char cmd[1000]; snprintf (cmd,sizeof(cmd)-1 ,"echo %s | mail -s \"taskmon: %s\" %s" ,msg,pname,mail); system (cmd); } syslog (LOG_ERR,MSG_U(E_KILLING ,"Terminating process %s(%d)"),pname,pid); } } m->accum = accum; m->mark = true; } pt = pt->getnext(); } n = pmons.getnb(); for (int i=0; imark){ pmons.remove_del (i); i--; n--; } } #if 0 for (int i=0; iname.get(),m->pid,m->accum); } #endif sleep (cycle); } return 0; }