/[monit]/monit/spawn.c
ViewVC logotype

Diff of /monit/spawn.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21 by hauk, Mon Jun 16 22:06:15 2003 UTC revision 1.22 by hauk, Wed Jun 18 02:03:56 2003 UTC
# Line 69  Line 69 
69  /* -------------------------------------------------------------- Prototypes */  /* -------------------------------------------------------------- Prototypes */
70    
71    
72  static void do_free();  static void exec_alert_mail(Service_T s, Command_T c);
73  static Command_T copy_command(Command_T);  static void set_monit_environment(Service_T s, Command_T c);
 static Mail_T create_exec_alert_list(Service_T, Command_T);  
74    
75    
76  /* ------------------------------------------------------------------ Public */  /* ------------------------------------------------------------------ Public */
# Line 91  void  spawn(Service_T S, Command_T C) { Line 90  void  spawn(Service_T S, Command_T C) {
90    
91    ASSERT(S);    ASSERT(S);
92    ASSERT(C);    ASSERT(C);
93      
94    /*    /*
95     * Block SIGCHLD     * Block SIGCHLD
96     */     */
# Line 119  void  spawn(Service_T S, Command_T C) { Line 118  void  spawn(Service_T S, Command_T C) {
118                
119      } else  {      } else  {
120    
       Command_T c= copy_command(C);  
       Mail_T alert_list= create_exec_alert_list(S, C);  
121                
122        /*        /*
123         * Reset all signals, so the child process is         * Reset all signals, so the child process is
# Line 134  void  spawn(Service_T S, Command_T C) { Line 131  void  spawn(Service_T S, Command_T C) {
131        signal(SIGUSR1, SIG_DFL);        signal(SIGUSR1, SIG_DFL);
132        signal(SIGPIPE, SIG_DFL);        signal(SIGPIPE, SIG_DFL);
133    
       /* Garbage collect */  
       do_free();  
   
134        /*        /*
135         * Reset to the original umask so programs will inherit the         * Reset to the original umask so programs will inherit the
136         * same file creation mask monit was started with         * same file creation mask monit was started with
# Line 151  void  spawn(Service_T S, Command_T C) { Line 145  void  spawn(Service_T S, Command_T C) {
145        /*        /*
146         * Switch uid and gid if requested         * Switch uid and gid if requested
147         */         */
148        if(c->has_gid) {        if(C->has_gid) {
149          if(0 != setgid(c->gid)) {          if(0 != setgid(C->gid)) {
150            log("Failed to change gid to '%d' for '%s'\n",            log("Failed to change gid to '%d' for '%s'\n",
151                c->gid, c->arg[0]);                C->gid, C->arg[0]);
152          }          }
153        }        }
154        if(c->has_uid) {        if(C->has_uid) {
155          if(0 != setuid(c->uid)) {          if(0 != setuid(C->uid)) {
156            log("Failed to change uid to '%d' for '%s'\n",            log("Failed to change uid to '%d' for '%s'\n",
157                c->uid, c->arg[0]);                C->uid, C->arg[0]);
158          }          }
159        }        }
160            
161          /*
162           * Set the MONIT_xxx environment variables
163           */
164          set_monit_environment(S, C);
165          
166        /*        /*
167         * The exec statement done by the second child         * The exec statement done by the second child
168         */         */
169        (void) execv(c->arg[0], c->arg);        (void) execv(C->arg[0], C->arg);
170        sendmail(alert_list);        exec_alert_mail(S, C);
171        log("Could not execute %s\n", c->arg[0]);        log("Could not execute %s\n", C->arg[0]);
       gc_mail_list(&alert_list);  
172        _exit(1);        _exit(1);
173                
174      }      }
# Line 201  void  spawn(Service_T S, Command_T C) { Line 199  void  spawn(Service_T S, Command_T C) {
199    
200    
201  /*  /*
202   * Free memory for the child process   * Send an exec failed alert mail to those mail objects that has
203     * registred interest for restart notification.
204   */   */
205  static void do_free() {  static void exec_alert_mail(Service_T s, Command_T c) {
     
   gc();  
   destroy_hosts_allow();  
   free(Run.controlfile);  
   free(Run.pidfile);  
   free(Run.statefile);  
   free(Run.logfile);  
   free(Run.localhostname);  
   free(Run.Env.user);  
   free(Run.Env.home);  
   free(Run.Env.cwd);  
   free(Run.Auth.uname);  
   free(Run.Auth.passwd);  
   free(Run.MailFormat.from);  
   free(Run.MailFormat.subject);  
   free(Run.MailFormat.message);  
   free(Run.bind_addr);  
   /* Run.mailserver is not freed since it's used in exec alert */  
206    
207      Mail_T a= s->maillist;
208    
209      for(; a; a= a->next)
210          if(a->alert_on_restart) {
211            struct mymail m;
212            char message[STRLEN];
213            
214            m.to= a->to;
215            m.from= "monit@localhost";
216            m.subject= "monit alert -- exec error";
217            snprintf(message, STRLEN,
218                     "Could not execute program '%s' for service %s\n\n"
219                     "Your faithful employee,\nmonit",
220                     c->arg[0]?c->arg[0]:"null", s->name);
221            m.message= message;
222            sendmail(&m);
223          }
224      
225  }  }
226    
227    
228  /*  /*
229   * Return a deep copy of the given command object   * Setup the environment with special MONIT_xxx variables. The program
230     * executed may use such variable for various purposes.
231   */   */
232  static Command_T copy_command(Command_T C) {  static void set_monit_environment(Service_T s, Command_T c) {
233    
234    int i;    int i;
235    Command_T P= NEW(P);    char buf[10][STRLEN];
236    
237    for(i= 0; C->arg[i]; i++)    snprintf(buf[0], STRLEN, "MONIT_PROGRAM_PID=%d", is_process_running(s));
238        P->arg[i]= xstrdup(C->arg[i]);    snprintf(buf[1], STRLEN, "MONIT_PROGRAM=%s", c->arg[0]);
239    P->arg[i]= NULL;    snprintf(buf[2], STRLEN, "MONIT_DATE=%s", get_RFC822date(NULL));
240      snprintf(buf[3], STRLEN, "MONIT_HOST=%s", Run.localhostname);
241    P->uid= C->uid;    snprintf(buf[4], STRLEN, "MONIT_PROGRAM_MEMORY=%ld", s->procinfo->mem_kbyte);
242    P->gid= C->gid;    snprintf(buf[5], STRLEN, "MONIT_PROGRAM_CHILDREN=%d", s->procinfo->children);
243    P->has_uid= C->has_uid;    snprintf(buf[6], STRLEN, "MONIT_PROGRAM_CPU_PERCENT=%d",
244    P->has_gid= C->has_gid;             s->procinfo->cpu_percent);
   
   return P;  
245        
246  }    buf[7][0]= 0;
   
   
 /*  
  * Create a list of mail addresses to send mail to in case the exec  
  * fails. Only mail objects that has registred interest for restart  
  * notification is used.  
  */  
 static Mail_T create_exec_alert_list(Service_T s, Command_T c) {  
247    
248    Mail_T l= NULL;    for(i= 0; *buf[i]; i++)
249    Mail_T h= s->maillist;        putenv(buf[i]);
   
   for(; h; h= h->next)  
       if(h->alert_on_restart) {  
           
         Mail_T n= NEW(n);  
         char *message= xmalloc(STRLEN);  
           
         n->to= xstrdup(h->to);  
         n->from= xstrdup("monit@localhost");  
         n->subject= xstrdup("monit alert -- exec error");  
         snprintf(message, STRLEN,  
          "NOTE, THIS EMAIL TAKES PRECEDENCE OVER SUBSEQUENT RESTART ALERTS\n\n"  
                  "Could not execute program '%s' for service %s\n\n"  
                  "Your faithful employee,\nmonit",  
                  c->arg[0]?c->arg[0]:"null", s->name);  
         n->message= message;  
         n->next= l;  
         l= n;  
           
       }  
250    
   return l;  
     
251  }  }

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26