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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2