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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2