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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2