Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147415
  • 博文数量: 17
  • 博客积分: 2146
  • 博客等级: 大尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-07 23:26
文章分类

全部博文(17)

文章存档

2011年(1)

2009年(5)

2008年(11)

分类: LINUX

2008-05-30 17:05:02

设想:读取/proc下相关进程status状态,根据自定义的配置文件(mon_task_list)对进程做相应的操作。
1.遍历pid目录,找到status下name段,匹配配置文件(mon_task_list)中设定的进程名。
2.如果没有找到,根据配置中的action设定,决定是否产生这个进程。
3.找到后,读取status下state段,找出当前状态,然后根据配置文件(mon_task_list)中设定的action和当前状态做相应的操作。
配置文件结构:
processname1(char*),cmdline1(char*),path1(char*),action1(int)
processname2(char*),cmdline2(char*),path2(char*),action2(int)
..
processnameN(char*),cmdlineN(char*),pathN(char*),actionN(int)
eg:
bash,bash,./,0               //意味着允许bash自由操作
a.out,/usr/a.out &,/usr,2    //意味着阻止a.out运行
 
//mon_task_list文件
 
procmon,./procmon,./,0
bash,bash,.,0
test1,/mnt/hgfs/share/test/test1 &,/mnt/hgfs/share/test/test1,1
 
 
//procmon.c文件
 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
 
#define MAX_THREAD_NUM 1024
#define MON_IDLE_TIME 2
 
//action
#define CONFIG_ACTION_ALLOW         0x0
#define CONFIG_ACTION_RESTART       0x1
#define CONFIG_ACTION_FORBIDDEN     0x2
#define CONFIG_ACTION_KILL_ZOMBIE   0x4
 
//process state
#define TASK_STATUS_NOT_RUN         0x0
#define TASK_STATUS_SLEEPING        0x1
#define TASK_STATUS_RUNNING         0x2
#define TASK_STATUS_ZOMBIE          0x3
#define CONFIG_STRING_DELIMITER     ","

typedef struct mon_proc_thread
{
 pthread_t tid;
 int taskid; 
 int threadstatus;
 int taskstatus;
 int action;
 char procname[128];
 char cmdline[512];
 char path[255]; 
 
}mon_proc_thread_t;

int displayver();
int displayhlp(char* pszAppname);
int create_mon_task_list(char* filename);
int getprocstatus(mon_proc_thread_t* pmon_proc_thread);
void getprocname(char* src,char*dst);
void handleproc(mon_proc_thread_t* pmon_proc_thread);
void* pthread_fn(void* arg);
pthread_mutex_t g_mutex;
mon_proc_thread_t mon_proc_thread[MAX_THREAD_NUM];
 
int displayver()
{
          printf("******************************\n");
          printf("*   Application  : APP       *\n");
          printf("*   module       : procmon   *\n");
          printf("*   version      : 1.0.0     *\n");
          printf("*   company      : company   *\n");
          printf("******************************\n");
          return(0);
}
void getprocname(char* src,char*dst)
{
  int i;
  int endstart = 0;
  printf("%s\n",src);
  for(i = strlen(src) -1 ; i >=0; i--)
  {
   if(endstart > 0)
   {
      dst[i] = src[i];
   }
   else
   {
    if(endstart == 0 &&(src[i] == ' ' || src[i] == '\n' || src[i] == '\r'))
    {
      continue;
    }
    else if(endstart == 0)
    {
       endstart = i;
       dst[i] = src[i];
    }
   }
  }
}
void handleproc(mon_proc_thread_t* pmon_proc_thread)

 int ret ;  
 if(pmon_proc_thread->taskid <= -1)
 {
  return;
 }  
 switch(pmon_proc_thread->action)
 {
  case CONFIG_ACTION_ALLOW:
   printf("%s are allowed to run\n",pmon_proc_thread->procname);
   break;
  case CONFIG_ACTION_RESTART:
   printf("%s are allowed to run and restart automaticly\n",pmon_proc_thread->procname);
   break;
  case CONFIG_ACTION_FORBIDDEN:
   printf("%s are forbidden to run\n",pmon_proc_thread->procname);
   break;
  case CONFIG_ACTION_KILL_ZOMBIE:
   printf("%s are allowed to run and will be killed when zombie\n",pmon_proc_thread->procname);
   break;
  default:
   printf("%s are forbidden to run\n",pmon_proc_thread->procname);
   break;
 }
 switch(pmon_proc_thread->taskstatus)
 {  
  
    case TASK_STATUS_NOT_RUN: 
     if(pmon_proc_thread->action == CONFIG_ACTION_RESTART)    
     {      
      ret = system(pmon_proc_thread->cmdline);          
  }
     break;
    case TASK_STATUS_SLEEPING:     
     if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN)    
     {      
      printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
      kill(pmon_proc_thread->taskid,SIGTERM);      
  }
     break;
    case TASK_STATUS_RUNNING:     
     if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN)    
     {      
      printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
      kill(pmon_proc_thread->taskid,SIGTERM);      
  }
     break;
    case TASK_STATUS_ZOMBIE:     
     if(pmon_proc_thread->action == CONFIG_ACTION_FORBIDDEN || pmon_proc_thread->action == CONFIG_ACTION_KILL_ZOMBIE)    
     {      
      printf("killing name=%s pid=%d\n",pmon_proc_thread->procname,pmon_proc_thread->taskid);
      kill(pmon_proc_thread->taskid,SIGTERM);      
  }
  else if(pmon_proc_thread->action == CONFIG_ACTION_RESTART)    
     {      
      ret = system(pmon_proc_thread->cmdline);          
  }
     break;   
    default:
     break;
 }
 
}
 
 
int create_mon_task_list(char* filename)
{
 int i;
 int index;
        int ret;       
 FILE* fd;               
        char err[255] = {0};
        char buf[128] = {0};                        
        char* delim = CONFIG_STRING_DELIMITER;
       
        if ((fd = fopen(filename, "r")) < 0) {
         sprintf(err,"open %s",filename);
                perror(err);
                exit(-1);
        }          
        index = 0;               
        ret = pthread_mutex_init(&g_mutex,NULL);    
        while(fgets(buf, sizeof(buf),fd)!= NULL)
        {           
         bzero(&mon_proc_thread[index],sizeof(mon_proc_thread[index]));
         if(buf[strlen(buf) -1] == '\n')
         {
          buf[strlen(buf) -1] = '\0';
         }         
          strcpy(mon_proc_thread[index].procname,strtok(buf,delim));    //name     
          strcpy(mon_proc_thread[index].cmdline,strtok(NULL,delim));    //cmdline     
          strcpy(mon_proc_thread[index].path,strtok(NULL,delim));       //path            
          mon_proc_thread[index].action = atoi(strtok(NULL,delim));     //action 
            
   ret = pthread_create(&mon_proc_thread[index].tid,NULL,pthread_fn,&mon_proc_thread[index]);
   if(ret != 0)
   {
      perror("create thread");
   }     
   while(mon_proc_thread[index].threadstatus == 0)
   {
    //printf("waitting for...\n");
    usleep(100);
   }    
   bzero(buf,sizeof(buf));  
   index ++;
        }
        fclose(fd);
        return 1;   
}
int getprocstatus(mon_proc_thread_t* pmon_proc_thread)
{
 struct dirent * ptr;
 DIR * dd;  
 int i;
 FILE* fd;
 int len;
 int namestart ;
 char buf[128]; 
 char name[128]; 
 char status[20];
 char* procName = pmon_proc_thread->procname; 
 if ((dd = opendir("/proc")) == NULL) {
                perror("open");
                exit(1);
        }
        while((ptr=readdir(dd))!=NULL)
        {         
         if(atoi(ptr->d_name)) 
         {
          
          buf[0] = '\0';
          sprintf(buf,"%s%s%s","/proc/",ptr->d_name,"/status");          
          if((fd = fopen(buf,"r")) < 0)
          {
                 perror("open");
                  continue;
          }
          buf[0] = '\0';
          if (fgets(buf, sizeof(buf),fd) == NULL)
          {
           closedir(dd);
                  return -1;
          }                      
          buf[strlen(buf) -1] = '\0';  /*remove ctrl*/             
          namestart = 0;
          for(i = 0; i< strlen(buf); i++)
          {
           if(buf[i] == ':')
           {         
            namestart = i;
            continue;
           }            
           else if(namestart == 0)
           {
            continue;
           }           
           else if(isgraph(buf[i]) && namestart > 0)
           {
            namestart = i;
            break;
           }
           
          }
          strcpy(name,buf + namestart);
          for(i = namestart ; i>0; i--)
          {
           if(isgraph(buf[i]))
           {
            break;
           }
          }
          buf[i] = '\0';                
          if(strcmp(name ,procName))
          {
               fclose(fd) ;              
               continue;   
          }
          else
          {      
           pmon_proc_thread->taskid = atoi(ptr->d_name);           
           printf("Name : %s\n",name);                
           buf[0] = '\0';           
           if (fgets(buf, sizeof(buf),fd) == NULL)
           {
            printf("read status failed\n");
            fclose(fd);
            closedir(dd);
                   return -1;
           }
           else
           {            
            buf[strlen(buf)] = '\0';
            char* pleft = strtok(buf,"(");     
            char left[20] ;
            strcpy(left,pleft);
            char* pstatus = strtok(left,":");            
            strcpy(status,strtok(NULL,":") + 1);
            status[strlen(status) -1] = '\0';                        
            if(strcmp("R",status) == 0)
            {
             pmon_proc_thread->taskstatus = TASK_STATUS_RUNNING;
            }
            else if(strcmp("S",status) == 0)
            {             
             pmon_proc_thread->taskstatus = TASK_STATUS_SLEEPING;
            }      
            printf("%s\n",buf);
            fclose(fd);          
            break;
           }
           
          }
           
         }
        }       
        closedir(dd);       
        handleproc(pmon_proc_thread);
        pmon_proc_thread->taskstatus = TASK_STATUS_NOT_RUN;
        return 1;
}
int displayhlp(char* pszAppname)
{
    printf("用法:%s [ver|help]\n",pszAppname);
    return(0);
}
void* pthread_fn(void* arg)
{  
   int ret;
   char buf[128] = {0};
   mon_proc_thread_t* pmon_proc_thread =(mon_proc_thread_t*)arg;
   strcpy(buf,pmon_proc_thread->procname);  
   pmon_proc_thread->threadstatus = 0;  
   while(1)
   {
    pthread_mutex_lock(&g_mutex);
    ret = getprocstatus(pmon_proc_thread);
    pmon_proc_thread->threadstatus = 1;
    pthread_mutex_unlock(&g_mutex);
    sleep(MON_IDLE_TIME);
   }  
   return ((void *)0);
}
int main(int argc, char** argv)
{
        int ret ;
        if(argc >= 2)
        {
           if(strcmp(argv[1],"help")==0)
          {
           displayhlp(argv[0]);
           return 0;
          }
          else if(strcmp(argv[1],"ver")==0)
          {
           displayver();
           return 0;
          }
          else
          {
             displayhlp(argv[0]);
             return 0;
          }
        }       
        ret = create_mon_task_list("mon_task_list");
        while(1)
        {           
            sleep(10);
        }       
        return 0;
}
 
阅读(1895) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~