(file) Return to cimserver_unix.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Server

  1 karl  1.27 //%2004////////////////////////////////////////////////////////////////////////
  2 mike  1.5  //
  3 karl  1.27 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.23 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.27 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 mike  1.5  //
 10            // Permission is hereby granted, free of charge, to any person obtaining a copy
 11 kumpf 1.8  // of this software and associated documentation files (the "Software"), to
 12            // deal in the Software without restriction, including without limitation the
 13            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 14 mike  1.5  // sell copies of the Software, and to permit persons to whom the Software is
 15            // furnished to do so, subject to the following conditions:
 16            // 
 17 kumpf 1.8  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 18 mike  1.5  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 19            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 20 kumpf 1.8  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 21            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 22            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 23 mike  1.5  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 24            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 25            //
 26            //==============================================================================
 27            //
 28            // Author: Mike Day (mdday@us.ibm.com)
 29            //
 30 kumpf 1.10 // Modified By:  Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
 31            //		 Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
 32 marek 1.19 //       Marek Szermutzky, IBM (ddt6szer@de.ibm.com)
 33 mike  1.5  //%/////////////////////////////////////////////////////////////////////////////
 34            #include <sys/types.h>
 35            #include <sys/stat.h>
 36 kumpf 1.7  #if defined(PEGASUS_OS_HPUX)
 37 kumpf 1.6  #include <sys/pstat.h>
 38 kumpf 1.7  #endif
 39 mike  1.5  #include <fcntl.h>
 40            #include <unistd.h>
 41 kumpf 1.16 #include <Pegasus/Common/Signal.h>
 42 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
 43            #include <sys/ps.h>
 44            #endif
 45 kumpf 1.16 #define MAX_WAIT_TIME 25
 46 kv.le 1.24 #if defined(PEGASUS_OS_AIX)
 47            extern "C" {
 48            #include <procinfo.h>
 49            extern int getprocs(struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
 50            #define PROCSIZE sizeof(struct procsinfo)
 51            }
 52            #endif
 53 kumpf 1.12 
 54 mike  1.5  PEGASUS_USING_PEGASUS;
 55            PEGASUS_USING_STD;
 56 kumpf 1.10 
 57 kumpf 1.16 Boolean handleSigUsr1 = false;
 58 konrad.r 1.20 Boolean graveError = false;
 59 mike     1.5  void cim_server_service(int argc, char **argv ) { return; }  
 60               
 61 kumpf    1.6  pid_t server_pid;
 62               
 63 kumpf    1.16 void sigUsr1Handler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
 64 kumpf    1.10 {
 65 kumpf    1.16     handleSigUsr1 = true;
 66 kumpf    1.10 }
 67               
 68 konrad.r 1.20 void sigTermHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
 69               {
 70                   graveError= handleSigUsr1=true;
 71               } 
 72 mike     1.5  // daemon_init , RW Stevens, "Advance UNIX Programming"
 73               
 74               int cimserver_fork(void) 
 75               { 
 76 kumpf    1.16 getSigHandle()->registerHandler(PEGASUS_SIGUSR1, sigUsr1Handler);
 77               getSigHandle()->activate(PEGASUS_SIGUSR1);
 78 konrad.r 1.20 getSigHandle()->registerHandler(SIGTERM, sigTermHandler);
 79               getSigHandle()->activate(SIGTERM);
 80 kumpf    1.10  
 81 mike     1.5    pid_t pid;
 82                 if( (pid = fork() ) < 0) 
 83 kumpf    1.16   {
 84                     getSigHandle()->deactivate(PEGASUS_SIGUSR1);
 85 konrad.r 1.20       getSigHandle()->deactivate(SIGTERM);
 86 kumpf    1.16       return(-1);
 87                 }
 88 mike     1.5    else if (pid != 0)
 89 kumpf    1.10   {
 90 kumpf    1.16       //
 91                     // parent wait for child
 92                     // if there is a problem with signal, parent process terminates
 93                     // when waitTime expires
 94                     //
 95                     Uint32 waitTime = MAX_WAIT_TIME;
 96 kumpf    1.12 
 97 kumpf    1.16       while(!handleSigUsr1 && waitTime > 0)
 98                     {
 99 kumpf    1.12 	    sleep(1);
100 kumpf    1.16 	    waitTime--;
101                     }
102 konrad.r 1.20       exit(graveError);
103 kumpf    1.10   }
104 mike     1.5    
105                 setsid();
106                 umask(0);
107 kumpf    1.6  
108                 // get the pid of the cimserver process
109                 server_pid = getpid();
110                 return(0);
111 kumpf    1.9  }
112               
113 tony     1.25 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
114 kumpf    1.18 
115               //===========================================================================
116               //  NAME          : verify_process_name
117               //  DESCRIPTION   : Opens the 'stat' file in the /proc/<pid> directory to 
118               //                  verify that the process name is that of the cimserver.
119               //===========================================================================
120               int verify_process_name(char *directory) 
121               {
122                   static char filename[80];
123                   static char buffer[512];
124                   int fd, bytesRead;
125               
126                   // generate the name of the stat file in the process's /proc directory,
127                   // and open it
128                   sprintf(filename, "%s/%s", directory, "stat");
129                   if ( (fd = open(filename, O_RDONLY, 0)) == -1 ) 
130                   {
131                       return -1;
132                   }
133               
134                   // read the contents
135 kumpf    1.18     if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 ) 
136                   {
137                       close(fd);
138                       return -1;
139                   }
140               
141                   // null terminate the file contents
142                   buffer[bytesRead] = 0;
143               
144                   close(fd);
145               
146                   // the process name is the second element of the file contents and
147                   // is surrounded by parentheses. 
148                   //
149                   // find the positions of the parentheses in the file contents
150                   char * open_paren;
151                   char * close_paren;
152                   
153                   open_paren = strchr (buffer, '(');
154                   close_paren = strchr (buffer, ')');
155                   if (open_paren == NULL || close_paren == NULL || close_paren < open_paren)
156 kumpf    1.18     {
157                       return -1;
158                   }
159               
160                   // allocate memory for the result
161                   char * process_name;
162                   process_name = (char*) malloc(close_paren - open_paren - 1);
163               
164                   // copy the process name into the result  
165                   strncpy (process_name, open_paren + 1, close_paren - open_paren -1);
166               
167                   // strncpy doesn't NULL-terminate the result, so do it here
168                   process_name[close_paren - open_paren -1] = '\0';
169               
170                   if (strcmp(process_name, "cimserver") != 0)
171                   {
172                       return -1;
173                   }
174               
175                   return 0;
176               }
177 kumpf    1.18 
178               //=============================================================================
179               // NAME           : get_proc
180               // DESCRIPTION    : get_proc() makes a stat() system call on the directory in
181               //                  /proc with a name that matches the pid of the cimserver.
182               //                  It returns 0 if it successfully located the process dir
183               //                  and verified that the process name matches that of the
184               //                  cimserver.  It returns -1 if it fails to open /proc, or
185               //                  the cimserver process does not exist.
186               //=============================================================================
187               int get_proc(int pid)
188               {
189                 static char path[32];
190                 static struct stat stat_buff;
191               
192                 sprintf(path, "/proc/%d", pid);
193                 if (stat(path, &stat_buff) == -1)          // process stopped running
194                 {
195                   return -1;
196                 }
197               
198 tony     1.25  // get the process name to make sure it is the cimserver process
199               // ATTN: skip verify for Solaris
200               #if !defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
201 kumpf    1.18   if ((verify_process_name(path)) == -1)
202                 {
203                   return -1;
204                 }
205 tony     1.25 #endif
206 kumpf    1.18 
207 kumpf    1.21   //
208                 // Check to see if this command process has the same pid as the cimserver
209                 // daemon process pid stored in the cimserver_start.conf file.  Since the
210                 // command has the same name as the cimserver daemon process, this could
211                 // happen after a system reboot.  If the pids are the same, cimserver 
212                 // isn't really running.
213                 //
214 kumpf    1.26   Uint32 mypid = System::getPID();
215 w.otsuka 1.27.2.1   if ((mypid == (unsigned)pid) || ((unsigned)parentPid == (unsigned)pid))
216 kumpf    1.21       {
217                         return -1;
218                     }
219 kumpf    1.18       return 0;
220                   }
221                   #endif
222                   
223 marek    1.19     #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
224                   Boolean isProcRunning(pid_t pid)
225                   {
226                       W_PSPROC buf;                                                              
227                       int token = 0;
228                       memset(&buf, 0x00, sizeof(buf));                                           
229                       buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);        
230                       buf.ps_pathptr   =(char *) malloc(buf.ps_pathlen   =PS_PATHBLEN);          
231                       buf.ps_cmdptr    =(char *) malloc(buf.ps_cmdlen    =PS_CMDBLEN);
232                   
233                       token = w_getpsent(token, &buf, sizeof(buf));                              
234                       do {                                                                       
235                           token = w_getpsent(token, &buf, sizeof(buf));                          
236                           if (buf.ps_pid==pid) {
237                               free(buf.ps_conttyptr);                                                    
238                               free(buf.ps_pathptr);                                                      
239                               free(buf.ps_cmdptr);
240                               return true;
241                           }
242                       } while(token>0);
243                   
244 marek    1.19         free(buf.ps_conttyptr);                                                    
245                       free(buf.ps_pathptr);                                                      
246                       free(buf.ps_cmdptr);
247                       return false;
248                   }
249                   #endif
250 kumpf    1.18     
251 kv.le    1.24     #if defined(PEGASUS_OS_AIX)
252                   
253                   /////////////////////////////////////////////////////////////////////////////
254                   // NAME           : processdata
255                   // FUNCTION       : it calls subroutine getprocs() to get information
256                   //                  about all processes.
257                   /////////////////////////////////////////////////////////////////////////////
258                   // ARGUMENTS:
259                   //              cnt: the number of the processes in the returned table
260                   // RETURN VALUES:
261                   //              when it successfully gets the process table entries,
262                   //              an array of procsinfo structures filled with process table
263                   //              entries are returned. Otherewise, a null pointer is
264                   //              returned.
265                   //  
266                   /////////////////////////////////////////////////////////////////////////////
267                   struct procsinfo *processdata(int *cnt)
268                   {
269                           struct procsinfo *proctable=NULL, *rtnp=NULL;
270                           int count=1048576, rtncnt, repeat=1, nextp=0;
271                   
272 kv.le    1.24             *cnt=0;
273                           while ( repeat && (rtncnt=getprocs(rtnp,PROCSIZE,0,0,&nextp, count))>0)
274                           {
275                                   if (!rtnp)
276                                   {
277                                           count=rtncnt;
278                                           proctable=(struct procsinfo *) malloc((size_t) \
279                                                           PROCSIZE*count);
280                                           if (!proctable)
281                                                   return NULL;
282                                           rtnp=proctable;
283                                           nextp=0;
284                                   } else
285                                   {
286                                           *cnt+=rtncnt;
287                                           if (rtncnt>=count)
288                                           {
289                                                   proctable=(struct procsinfo *) realloc(\
290                                                           (void*)proctable, (size_t)\
291                                                           (PROCSIZE*(*cnt+count)));
292                                                   if (!proctable)
293 kv.le    1.24                                             return NULL;
294                                                   rtnp=proctable+(*cnt);
295                                           } else
296                                                   repeat=0;
297                                   } // end of if(!rtnp)
298                           } //end of while
299                           return proctable;
300                   }
301                   
302                   /////////////////////////////////////////////////////////////////////////////
303                   // NAME           : aixcimsrvrunning
304                   // FUNCTION       : it figures out if the cimserver process is running
305                   //                  by checking the process table entries in the array
306                   //                  returned from processdata(). If the cimserver process is
307                   //                  running and its pid is the same as the pid in the file
308                   //                  CIMSERVER_START_FILE, it will return 0, otherwise it will
309                   //                  return -1.
310                   /////////////////////////////////////////////////////////////////////////////
311                   // ARGUMENTS:
312                   //              pid: the process identifier saved in the file
313                   //                   CIMSERVER_START_FILE
314 kv.le    1.24     // RETURN VALUES:
315                   //              0: successful
316                   //              -1: errors
317                   //  
318                   /////////////////////////////////////////////////////////////////////////////
319                          
320                   int aixcimsrvrunning(pid_t pid)
321                   {
322                           int i,count;
323                           struct procsinfo *proctable;
324                   
325                           proctable=processdata(&count);
326                           if (proctable==NULL)
327                                   return -1;
328                           for (i=0;i<count;i++)
329                                   if (!strcmp(proctable[i].pi_comm,"cimserver") && \
330                                       proctable[i].pi_pid==pid)
331                                   {
332                                           free(proctable);
333                                           return 0;
334                                   }
335 kv.le    1.24     
336                           free(proctable);
337                           return -1;
338                   }
339                   #endif
340                   
341 kumpf    1.9      Boolean isCIMServerRunning(void)
342                   {
343                     FILE *pid_file;
344                     pid_t pid = 0;
345                   
346                     // open the file containing the CIMServer process ID
347 marek    1.19       pid_file = fopen(CIMSERVER_START_FILE, "r");
348 kumpf    1.9        if (!pid_file)
349                     {
350                         return false;
351                     }
352                   
353                     // get the pid from the file
354 kumpf    1.17       fscanf(pid_file, "%d\n", &pid);
355                   
356                     fclose(pid_file);
357 kumpf    1.9      
358                     if (pid == 0)
359                     {
360                        return false;
361                     }
362                   
363                     //
364                     // check to see if cimserver process is alive
365                     //
366                   #if defined(PEGASUS_OS_HPUX)
367                     struct pst_status pstru;
368                   
369 kumpf    1.17       int ret_code;
370                     ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
371                   
372                     if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
373 kumpf    1.9        {
374 kumpf    1.21           //
375                         // Check to see if this command process has the same pid as the 
376                         // cimserver daemon process pid stored in the cimserver_start.conf 
377                         // file.  Since the command has the same name as the cimserver daemon
378                         // process, this could happen after a system reboot.  If the pids are
379                         // the same, cimserver isn't really running.
380                         //
381 kumpf    1.26           Uint32 mypid = System::getPID();
382                         if ((mypid != pid) && (parentPid != pid))
383 kumpf    1.21           {
384                             // cimserver is running
385                             return true;
386                         }
387 kumpf    1.9        }
388                   #endif
389 tony     1.25     #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
390 kumpf    1.18       if (get_proc(pid) != -1 )
391                     {
392                         // cimserver is running
393                         return true;
394                     }
395                   #endif
396 marek    1.19     #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
397                       return isProcRunning(pid);
398                   #endif
399 kv.le    1.24     #if defined(PEGASUS_OS_AIX)
400                       if (aixcimsrvrunning(pid)!=-1)
401                           return true;
402                   #endif
403 kumpf    1.9        return false;
404 kumpf    1.6      }
405                   
406                   int cimserver_kill(void) 
407                   { 
408                     FILE *pid_file;
409                     pid_t pid = 0;
410                     
411                     // open the file containing the CIMServer process ID
412 kumpf    1.18       pid_file = fopen(CIMSERVER_START_FILE, "r");
413 kumpf    1.6        if (!pid_file) 
414                     {
415                         return (-1);
416                     }
417                   
418                     // get the pid from the file
419 kumpf    1.17       fscanf(pid_file, "%d\n", &pid);
420                   
421                     fclose(pid_file);
422 kumpf    1.6      
423                     if (pid == 0)
424                     {
425 kumpf    1.18          System::removeFile(CIMSERVER_START_FILE);
426 kumpf    1.6           return (-1);
427                     }
428                   
429                     //
430                     // kill the process if it is still alive
431                     //
432 kumpf    1.7      #if defined(PEGASUS_OS_HPUX)
433 kumpf    1.6        struct pst_status pstru;
434                   
435 kumpf    1.17       int ret_code;
436                     ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
437                   
438                     if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
439 kumpf    1.6        {
440 kumpf    1.17           // cimserver is running, kill the process
441 kumpf    1.6            kill(pid, SIGKILL);
442                     }
443 kumpf    1.7      #endif
444 tony     1.25     #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
445 kumpf    1.18       if (get_proc(pid) != -1 )
446                     {
447                         kill(pid, SIGKILL);
448                     }
449                   #endif
450 marek    1.19     #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
451                     if (isProcRunning(pid)) {
452                         kill(pid, SIGKILL);
453                     }
454 kv.le    1.24     #endif
455                   #if defined(PEGASUS_OS_AIX)
456                     if (!aixcimsrvrunning(pid))
457                           kill(pid,SIGKILL);
458 marek    1.19     #endif
459 kumpf    1.6        // remove the file
460 kumpf    1.18       System::removeFile(CIMSERVER_START_FILE);
461 kumpf    1.6        
462 mike     1.5        return(0);
463                   }
464                   
465 kumpf    1.10     // notify parent process to terminate so user knows that cimserver
466                   // is ready to serve CIM requests.
467 konrad.r 1.20     void notify_parent(int id)
468 kumpf    1.10     {
469                     pid_t ppid = getppid();
470 konrad.r 1.20       if (id)
471                      kill(ppid, SIGTERM);
472                     else
473                      kill(ppid, PEGASUS_SIGUSR1); 
474 kumpf    1.10     }
475 s.hills  1.22     
476                   
477                   // Platform specific run
478                   int platform_run( int argc, char** argv, Boolean shutdownOption )
479                   {
480                   	return cimserver_run( argc, argv, shutdownOption );
481                   }
482                   
483                   void cimserver_set( CIMServer* s )
484                   {
485                   }
486 tony     1.25     
487                   
488                   
489                   
490                   

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2