(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                 if ((mypid == pid) || (parentPid == 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