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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2