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

  1 kumpf 1.1 //%2006////////////////////////////////////////////////////////////////////////
  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           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 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 kumpf 1.1 // 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           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34           #include <Pegasus/Common/System.h>
 35           #include <Pegasus/Common/Signal.h>
 36           #include <Pegasus/Common/AutoPtr.h>
 37           #include <Service/PidFile.h>
 38           #include <Service/ServerRunStatus.h>
 39           
 40           #include <sys/types.h>
 41           #include <sys/stat.h>
 42           
 43 kumpf 1.1 #if defined(PEGASUS_OS_HPUX)
 44           # include <sys/pstat.h>
 45           # include <libgen.h>
 46           #endif
 47           
 48           #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
 49           # include <sys/ps.h>
 50           #endif
 51           
 52           #if defined(PEGASUS_OS_AIX)
 53           extern "C"
 54           {
 55           # include <procinfo.h>
 56           extern int getprocs(struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
 57           # define PROCSIZE sizeof(struct procsinfo)
 58           }
 59           #endif
 60           
 61           #if defined(PEGASUS_OS_OS400)
 62           # include <Pegasus/Common/Logger.h>
 63           # include "OS400ConvertChar.h"
 64 kumpf 1.1 #endif
 65           
 66           PEGASUS_NAMESPACE_BEGIN
 67           
 68           #ifdef PEGASUS_OS_TYPE_WINDOWS
 69           
 70           //////////////////////////////////////
 71           //
 72           // Windows implementation
 73           //
 74           //////////////////////////////////////
 75           
 76           ServerRunStatus::ServerRunStatus(
 77               const char* serverName,
 78               const char* pidFilePath)
 79               : _serverName(serverName),
 80                 _pidFilePath(pidFilePath),
 81                 _parentPid(0),
 82                 _event(NULL),
 83                 _wasAlreadyRunning(false)
 84           {
 85 kumpf 1.1 }
 86           
 87           ServerRunStatus::~ServerRunStatus()
 88           {
 89               if (_event != NULL)
 90               {
 91                   CloseHandle(_event);
 92               }
 93           }
 94           
 95           Boolean ServerRunStatus::isServerRunning()
 96           {
 97 dave.sudlik 1.3     return _wasAlreadyRunning;
 98 kumpf       1.1 }
 99                 
100                 void ServerRunStatus::setServerRunning()
101                 {
102                     if (_event == NULL)
103                     {
104                         _event = CreateEvent(NULL, TRUE, TRUE, _serverName);
105                         if ((_event != NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
106                         {
107                             _wasAlreadyRunning = false;
108                         }
109                     }
110                 }
111                 
112                 void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
113                 {
114                 }
115                 
116                 Boolean ServerRunStatus::kill()
117                 {
118                     return true;
119 kumpf       1.1 }
120                 
121 carson.hovey 1.2 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
122 kumpf        1.1 
123                  //////////////////////////////////////
124                  //
125                  // Unix and OpenVMS implementation
126                  //
127                  //////////////////////////////////////
128                  
129                  ServerRunStatus::ServerRunStatus(
130                      const char* serverName,
131                      const char* pidFilePath)
132                      : _serverName(serverName),
133                        _pidFilePath(pidFilePath),
134                        _parentPid(0)
135                  {
136                  }
137                  
138                  ServerRunStatus::~ServerRunStatus()
139                  {
140                  }
141                  
142                  Boolean ServerRunStatus::isServerRunning()
143 kumpf        1.1 {
144                      PidFile pidFile(_pidFilePath);
145                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
146                  
147                      if (pid == 0)
148                      {
149                          return false;
150                      }
151                  
152                      return (pid != (PEGASUS_PID_T) System::getPID()) &&
153                             (pid != _parentPid) &&
154                             _isServerProcess(pid);
155                  }
156                  
157                  void ServerRunStatus::setServerRunning()
158                  {
159                      PidFile pidFile(_pidFilePath);
160                      pidFile.setPid(System::getPID());
161                  }
162                  
163                  void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
164 kumpf        1.1 {
165                      _parentPid = parentPid;
166                  }
167                  
168                  Boolean ServerRunStatus::kill()
169                  {
170                      PidFile pidFile(_pidFilePath);
171                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
172                  
173                      if ((pid == 0) ||
174                          (pid == (PEGASUS_PID_T) System::getPID()) ||
175                          (pid == _parentPid) ||
176                          !_isServerProcess(pid))
177                      {
178                          pidFile.remove();
179                          return false;
180                      }
181                  
182                  #if defined(PEGASUS_OS_HPUX) || \
183                      defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
184                      defined(PEGASUS_OS_SOLARIS) || \
185 kumpf        1.1     defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || \
186                      defined(PEGASUS_OS_AIX)
187                  
188                      ::kill(pid, SIGKILL);
189                  
190                  #endif
191                  
192                      pidFile.remove();
193                      return true;
194                  }
195                  
196                  # if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
197                  
198                  ///////////////////////////////////////////////////////
199                  // z/OS implementation of _isServerProcess
200                  ///////////////////////////////////////////////////////
201                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
202                  {
203                      W_PSPROC buf;
204                      int token = 0;
205                      memset(&buf, 0x00, sizeof(buf));
206 kumpf        1.1     buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
207                      buf.ps_pathptr   =(char *) malloc(buf.ps_pathlen   =PS_PATHBLEN);
208                      buf.ps_cmdptr    =(char *) malloc(buf.ps_cmdlen    =PS_CMDBLEN);
209                      Boolean returnValue = false;
210                  
211                      while ((token = w_getpsent(token, &buf, sizeof(buf))) > 0)
212                      {
213                          if (buf.ps_pid == pid)
214                          {
215                              // If the process id is associated with the server program,
216                              // then a server is still running.
217                              if (strstr(buf.ps_pathptr, _serverName) != NULL)
218                              {
219                                  returnValue = true;
220                              }
221                              // else the pid was not associated with the server
222                              break;
223                          }
224                      }
225                  
226                      free(buf.ps_conttyptr);
227 kumpf        1.1     free(buf.ps_pathptr);
228                      free(buf.ps_cmdptr);
229                      return returnValue;
230                  }
231                  
232                  # elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
233                      defined(PEGASUS_OS_SOLARIS)
234                  
235                  ///////////////////////////////////////////////////////
236                  // Linux and Solaris implementation of _isServerProcess
237                  ///////////////////////////////////////////////////////
238                  /*
239                     Opens the 'stat' file in the /proc/<pid> directory to
240                     verify that the process name is that of the server.
241                  */
242                  static Boolean _isServerPidDir(
243                      const char *directory,
244                      const char* serverProcessName)
245                  {
246                      static char filename[80];
247                      static char buffer[512];
248 kumpf        1.1     int fd, bytesRead;
249                  
250                      // generate the name of the stat file in the process's /proc directory,
251                      // and open it
252                      sprintf(filename, "%s/%s", directory, "stat");
253                      if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
254                      {
255                          return false;
256                      }
257                  
258                      // read the contents
259                      if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
260                      {
261                          close(fd);
262                          return false;
263                      }
264                  
265                      // null terminate the file contents
266                      buffer[bytesRead] = 0;
267                  
268                      close(fd);
269 kumpf        1.1 
270                      // the process name is the second element of the file contents and
271                      // is surrounded by parentheses.
272                      //
273                      // find the positions of the parentheses in the file contents
274                      const char* openParen;
275                      const char* closeParen;
276                  
277                      openParen = strchr(buffer, '(');
278                      closeParen = strchr(buffer, ')');
279                      if (openParen == NULL || closeParen == NULL || closeParen < openParen)
280                      {
281                          return false;
282                      }
283                  
284                      // allocate memory for the result
285                      AutoArrayPtr<char> processName(new char[closeParen - openParen]);
286                  
287                      // copy the process name into the result
288                      strncpy(processName.get(), openParen + 1, closeParen - openParen -1);
289                  
290 kumpf        1.1     // strncpy doesn't NULL-terminate the result, so do it here
291                      processName[closeParen - openParen -1] = '\0';
292                  
293                      return strcmp(processName.get(), serverProcessName) == 0;
294                  }
295                  
296                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
297                  {
298                      // This method makes a stat() system call on the directory in /proc
299                      // with a name that matches the pid of the server.  It returns true
300                      // if it successfully located the process dir and verified that the
301                      // process name matches that of the server.
302                  
303                      static char path[32];
304                      static struct stat statBuffer;
305                  
306                      sprintf(path, "/proc/%d", pid);
307                      if (stat(path, &statBuffer) == -1)          // process stopped running
308                      {
309                          return false;
310                      }
311 kumpf        1.1 
312                      // get the process name to make sure it is the cimserver process
313                  // ATTN: skip verify for Solaris
314                  #  if !defined(PEGASUS_OS_SOLARIS)
315                      if (!_isServerPidDir(path, _serverName))
316                      {
317                          return false;
318                      }
319                  #  endif
320                  
321                      return true;
322                  }
323                  
324                  # elif defined(PEGASUS_OS_AIX)
325                  
326                  ///////////////////////////////////////////////////////
327                  // AIX implementation of _isServerProcess
328                  ///////////////////////////////////////////////////////
329                  /*
330                     Calls subroutine getprocs() to get information about all processes.
331                     If successful, an array of procsinfo structures filled with process table
332 kumpf        1.1    entries is returned.  Otherwise, a null pointer is returned.
333                     The output parameter cnt specifies the number of the processes in the
334                     returned table.
335                  */
336                  static struct procsinfo* _getProcessData(int& cnt)
337                  {
338                      struct procsinfo* proctable = NULL;
339                      struct procsinfo* rtnp = NULL;
340                      int count = 1048576;
341                      int rtncnt;
342                      int repeat = 1;
343                      int nextp = 0;
344                  
345                      cnt = 0;
346                      while (repeat &&
347                             (rtncnt = getprocs(rtnp, PROCSIZE, 0, 0, &nextp, count) > 0))
348                      {
349                          if (!rtnp)
350                          {
351                              count=rtncnt;
352                              proctable = (struct procsinfo*) malloc((size_t) PROCSIZE*count);
353 kumpf        1.1             if (!proctable)
354                              {
355                                  return NULL;
356                              }
357                              rtnp = proctable;
358                              nextp = 0;
359                          }
360                          else
361                          {
362                              cnt += rtncnt;
363                              if (rtncnt >= count)
364                              {
365                                  proctable=(struct procsinfo *) realloc(
366                                      (void*)proctable, (size_t) (PROCSIZE*(cnt+count)));
367                                  if (!proctable)
368                                  {
369                                      return NULL;
370                                  }
371                                  rtnp = proctable+(cnt);
372                              }
373                              else
374 kumpf        1.1             {
375                                  repeat = 0;
376                              }
377                          } // end of if(!rtnp)
378                      } //end of while
379                      return proctable;
380                  }
381                  
382                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
383                  {
384                      int count;
385                      struct procsinfo* proctable;
386                  
387                      proctable = _getProcessData(count);
388                      if (proctable == NULL)
389                      {
390                          return false;
391                      }
392                  
393                      for (int i=0; i < count; i++)
394                      {
395 kumpf        1.1         if (!strcmp(proctable[i].pi_comm, _serverName) && \
396                              proctable[i].pi_pid == pid)
397                          {
398                              free(proctable);
399                              return true;
400                          }
401                      }
402                  
403                      free(proctable);
404                      return false;
405                  }
406                  
407                  # elif defined(PEGASUS_OS_HPUX)
408                  
409                  ///////////////////////////////////////////////////////
410                  // HP-UX implementation of _isServerProcess
411                  ///////////////////////////////////////////////////////
412                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
413                  {
414                      struct pst_status pstru;
415                  
416 kumpf        1.1     if (pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid) != -1)
417                      {
418                          //
419                          // Gets the command basename disregarding the command parameters
420                          //
421                          char *execName = strchr(pstru.pst_cmd,' ');
422                          if (execName)
423                          {
424                              *execName = '\0';
425                          }
426                          execName = basename(pstru.pst_cmd);
427                  
428                          if (strcmp(execName, _serverName) == 0)
429                          {
430                              return true;
431                          }
432                      }
433                  
434                      return false;
435                  }
436                  
437 kumpf        1.1 # else
438                  
439                  ///////////////////////////////////////////////////////
440                  // Generic implementation of _isServerProcess
441                  ///////////////////////////////////////////////////////
442                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
443                  {
444                      return false;
445                  }
446                  
447                  # endif
448                  
449                  #elif defined(PEGASUS_OS_OS400)
450                  
451                  //////////////////////////////////////
452                  //
453                  // OS/400 implementation
454                  //
455                  //////////////////////////////////////
456                  
457                  ServerRunStatus::ServerRunStatus(
458 kumpf        1.1     const char* serverName,
459                      const char* pidFilePath)
460                      : _serverName(serverName),
461                        _pidFilePath(pidFilePath),
462                        _parentPid(0)
463                  {
464                  }
465                  
466                  ServerRunStatus::~ServerRunStatus()
467                  {
468                  }
469                  
470                  /*
471                     NOTE: This implementation is specific to the CIM Server.
472                  */
473                  Boolean ServerRunStatus::isServerRunning()
474                  {
475                  #pragma convert(37)
476                      // Construct a ycmJob object
477                      ycmJob cppJob(YCMJOB_SRVNAME_10, YCMJOB_SRVUSER_10);
478                  
479 kumpf        1.1     // Find the QYCMCIMOM job
480                      char cppStatus  = cppJob.find(YCMJOB_ALL_NUMBERS);
481                  
482                      if (cppStatus == YCMJOB_FOUND)       // CIMOM Server is Running
483                      {
484                          return true;
485                      }
486                  
487                      return false;
488                  #pragma convert(0)
489                  }
490                  
491                  void ServerRunStatus::setServerRunning()
492                  {
493                  }
494                  
495                  void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
496                  {
497                  }
498                  
499                  /*
500 kumpf        1.1    The iSeries qycmctlcimCimomServer.C (QYCMCTLCIM program) code has
501                     already checked that the server is already running prior to calling
502                     the CIMOM server (QYCMCIMOM) and telling it to shutdown.
503                     However, a check is still made in this method because we have to
504                     find the job number in order to kill the job.
505                    
506                     For iSeries, this method is called regardless of whether we took
507                     errors trying to connect to the server - if the CIMOM server job
508                     is anywhere on the system, in any state, this method will find it
509                     and kill it dead!!
510                    
511                     NEVER call this method unless the server is unable to be shut down
512                     gracefully.
513                  
514                     NOTE: This implementation is specific to the CIM Server.
515                  */
516                  Boolean ServerRunStatus::kill()
517                  {
518                  #pragma convert(37)
519                      char rc2[3] = "02"; // CIMOM server failed to end
520                      char cppServ[10] = "QYCMCIMOM";
521 kumpf        1.1 
522                      // Construct a ycmJob object
523                      ycmJob cppJob(YCMJOB_SRVNAME_10, YCMJOB_SRVUSER_10);
524                      // Find the QYCMCIMOM job
525                      char cppStatus  = cppJob.find(YCMJOB_ALL_NUMBERS);
526                  
527                      if (cppStatus == YCMJOB_FOUND)       // CIMOM Server is Running
528                      {
529                          if (cppJob.end((char *)cppJob.getNumber().c_str(), 'C', 30) ==
530                                  YCMJOB_END_FAILED)
531                          {
532                              char chData[sizeof(rc2)+sizeof(cppServ)];
533                              strcpy((char *)&chData,rc2);
534                              strcat(chData,cppServ);
535                  
536                              ycmMessage message(
537                                  "CPDDF81",
538                                  chData,
539                                  strlen(chData),
540                                  "cimserver_os400::cimserver_kill()",
541                                  ycmCTLCIMID,
542 kumpf        1.1                 utf8);
543                              message.joblogIt(UserError,ycmMessage::Diagnostic);
544                  
545                  #pragma convert(0)
546                  
547                              Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
548                                  "src.Server.cimserver_os400.FAILED_TO_END_JOB",
549                                  "$0 FAILED to end the $1 job!!",
550                                  "cimserver_os400::cimserver_kill -",
551                                  "QYCMCIMOM");
552                  
553                              return false; // Note: this return code is ignored
554                          }
555                      }
556                  
557                      // The case of the job not found is already handled in QYCMCTLCIM program
558                      return true;
559                  }
560                  
561                  #endif
562                  
563 kumpf        1.1 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2