(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           PEGASUS_NAMESPACE_BEGIN
 62           
 63           #ifdef PEGASUS_OS_TYPE_WINDOWS
 64 kumpf 1.1 
 65           //////////////////////////////////////
 66           //
 67           // Windows implementation
 68           //
 69           //////////////////////////////////////
 70           
 71           ServerRunStatus::ServerRunStatus(
 72               const char* serverName,
 73               const char* pidFilePath)
 74               : _serverName(serverName),
 75                 _pidFilePath(pidFilePath),
 76                 _parentPid(0),
 77                 _event(NULL),
 78                 _wasAlreadyRunning(false)
 79           {
 80           }
 81           
 82           ServerRunStatus::~ServerRunStatus()
 83           {
 84               if (_event != NULL)
 85 kumpf 1.1     {
 86                   CloseHandle(_event);
 87               }
 88           }
 89           
 90           Boolean ServerRunStatus::isServerRunning()
 91           {
 92 dave.sudlik 1.3     return _wasAlreadyRunning;
 93 kumpf       1.1 }
 94                 
 95                 void ServerRunStatus::setServerRunning()
 96                 {
 97                     if (_event == NULL)
 98                     {
 99                         _event = CreateEvent(NULL, TRUE, TRUE, _serverName);
100                         if ((_event != NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
101                         {
102                             _wasAlreadyRunning = false;
103                         }
104                     }
105                 }
106                 
107                 void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
108                 {
109                 }
110                 
111                 Boolean ServerRunStatus::kill()
112                 {
113                     return true;
114 kumpf       1.1 }
115                 
116 carson.hovey 1.2 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
117 kumpf        1.1 
118                  //////////////////////////////////////
119                  //
120                  // Unix and OpenVMS implementation
121                  //
122                  //////////////////////////////////////
123                  
124                  ServerRunStatus::ServerRunStatus(
125                      const char* serverName,
126                      const char* pidFilePath)
127                      : _serverName(serverName),
128                        _pidFilePath(pidFilePath),
129                        _parentPid(0)
130                  {
131                  }
132                  
133                  ServerRunStatus::~ServerRunStatus()
134                  {
135                  }
136                  
137                  Boolean ServerRunStatus::isServerRunning()
138 kumpf        1.1 {
139                      PidFile pidFile(_pidFilePath);
140                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
141                  
142                      if (pid == 0)
143                      {
144                          return false;
145                      }
146                  
147                      return (pid != (PEGASUS_PID_T) System::getPID()) &&
148                             (pid != _parentPid) &&
149                             _isServerProcess(pid);
150                  }
151                  
152                  void ServerRunStatus::setServerRunning()
153                  {
154                      PidFile pidFile(_pidFilePath);
155                      pidFile.setPid(System::getPID());
156                  }
157                  
158                  void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
159 kumpf        1.1 {
160                      _parentPid = parentPid;
161                  }
162                  
163                  Boolean ServerRunStatus::kill()
164                  {
165                      PidFile pidFile(_pidFilePath);
166                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
167                  
168                      if ((pid == 0) ||
169                          (pid == (PEGASUS_PID_T) System::getPID()) ||
170                          (pid == _parentPid) ||
171                          !_isServerProcess(pid))
172                      {
173                          pidFile.remove();
174                          return false;
175                      }
176                  
177                  #if defined(PEGASUS_OS_HPUX) || \
178                      defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
179                      defined(PEGASUS_OS_SOLARIS) || \
180 kumpf        1.1     defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || \
181                      defined(PEGASUS_OS_AIX)
182                  
183                      ::kill(pid, SIGKILL);
184                  
185                  #endif
186                  
187                      pidFile.remove();
188                      return true;
189                  }
190                  
191                  # if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
192                  
193                  ///////////////////////////////////////////////////////
194                  // z/OS implementation of _isServerProcess
195                  ///////////////////////////////////////////////////////
196                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
197                  {
198                      W_PSPROC buf;
199                      int token = 0;
200                      memset(&buf, 0x00, sizeof(buf));
201 kumpf        1.1     buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
202                      buf.ps_pathptr   =(char *) malloc(buf.ps_pathlen   =PS_PATHBLEN);
203                      buf.ps_cmdptr    =(char *) malloc(buf.ps_cmdlen    =PS_CMDBLEN);
204                      Boolean returnValue = false;
205                  
206                      while ((token = w_getpsent(token, &buf, sizeof(buf))) > 0)
207                      {
208                          if (buf.ps_pid == pid)
209                          {
210                              // If the process id is associated with the server program,
211                              // then a server is still running.
212                              if (strstr(buf.ps_pathptr, _serverName) != NULL)
213                              {
214                                  returnValue = true;
215                              }
216                              // else the pid was not associated with the server
217                              break;
218                          }
219                      }
220                  
221                      free(buf.ps_conttyptr);
222 kumpf        1.1     free(buf.ps_pathptr);
223                      free(buf.ps_cmdptr);
224                      return returnValue;
225                  }
226                  
227                  # elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
228                      defined(PEGASUS_OS_SOLARIS)
229                  
230                  ///////////////////////////////////////////////////////
231                  // Linux and Solaris implementation of _isServerProcess
232                  ///////////////////////////////////////////////////////
233                  /*
234                     Opens the 'stat' file in the /proc/<pid> directory to
235                     verify that the process name is that of the server.
236                  */
237                  static Boolean _isServerPidDir(
238                      const char *directory,
239                      const char* serverProcessName)
240                  {
241                      static char filename[80];
242                      static char buffer[512];
243 kumpf        1.1     int fd, bytesRead;
244                  
245                      // generate the name of the stat file in the process's /proc directory,
246                      // and open it
247                      sprintf(filename, "%s/%s", directory, "stat");
248                      if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
249                      {
250                          return false;
251                      }
252                  
253                      // read the contents
254                      if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
255                      {
256                          close(fd);
257                          return false;
258                      }
259                  
260                      // null terminate the file contents
261                      buffer[bytesRead] = 0;
262                  
263                      close(fd);
264 kumpf        1.1 
265                      // the process name is the second element of the file contents and
266                      // is surrounded by parentheses.
267                      //
268                      // find the positions of the parentheses in the file contents
269                      const char* openParen;
270                      const char* closeParen;
271                  
272                      openParen = strchr(buffer, '(');
273                      closeParen = strchr(buffer, ')');
274                      if (openParen == NULL || closeParen == NULL || closeParen < openParen)
275                      {
276                          return false;
277                      }
278                  
279                      // allocate memory for the result
280                      AutoArrayPtr<char> processName(new char[closeParen - openParen]);
281                  
282                      // copy the process name into the result
283                      strncpy(processName.get(), openParen + 1, closeParen - openParen -1);
284                  
285 kumpf        1.1     // strncpy doesn't NULL-terminate the result, so do it here
286                      processName[closeParen - openParen -1] = '\0';
287                  
288                      return strcmp(processName.get(), serverProcessName) == 0;
289                  }
290                  
291                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
292                  {
293                      // This method makes a stat() system call on the directory in /proc
294                      // with a name that matches the pid of the server.  It returns true
295                      // if it successfully located the process dir and verified that the
296                      // process name matches that of the server.
297                  
298                      static char path[32];
299                      static struct stat statBuffer;
300                  
301                      sprintf(path, "/proc/%d", pid);
302                      if (stat(path, &statBuffer) == -1)          // process stopped running
303                      {
304                          return false;
305                      }
306 kumpf        1.1 
307                      // get the process name to make sure it is the cimserver process
308                  // ATTN: skip verify for Solaris
309                  #  if !defined(PEGASUS_OS_SOLARIS)
310                      if (!_isServerPidDir(path, _serverName))
311                      {
312                          return false;
313                      }
314                  #  endif
315                  
316                      return true;
317                  }
318                  
319                  # elif defined(PEGASUS_OS_AIX)
320                  
321                  ///////////////////////////////////////////////////////
322                  // AIX implementation of _isServerProcess
323                  ///////////////////////////////////////////////////////
324                  /*
325                     Calls subroutine getprocs() to get information about all processes.
326                     If successful, an array of procsinfo structures filled with process table
327 kumpf        1.1    entries is returned.  Otherwise, a null pointer is returned.
328                     The output parameter cnt specifies the number of the processes in the
329                     returned table.
330                  */
331                  static struct procsinfo* _getProcessData(int& cnt)
332                  {
333                      struct procsinfo* proctable = NULL;
334                      struct procsinfo* rtnp = NULL;
335                      int count = 1048576;
336                      int rtncnt;
337                      int repeat = 1;
338                      int nextp = 0;
339                  
340                      cnt = 0;
341                      while (repeat &&
342                             (rtncnt = getprocs(rtnp, PROCSIZE, 0, 0, &nextp, count) > 0))
343                      {
344                          if (!rtnp)
345                          {
346                              count=rtncnt;
347                              proctable = (struct procsinfo*) malloc((size_t) PROCSIZE*count);
348 kumpf        1.1             if (!proctable)
349                              {
350                                  return NULL;
351                              }
352                              rtnp = proctable;
353                              nextp = 0;
354                          }
355                          else
356                          {
357                              cnt += rtncnt;
358                              if (rtncnt >= count)
359                              {
360                                  proctable=(struct procsinfo *) realloc(
361                                      (void*)proctable, (size_t) (PROCSIZE*(cnt+count)));
362                                  if (!proctable)
363                                  {
364                                      return NULL;
365                                  }
366                                  rtnp = proctable+(cnt);
367                              }
368                              else
369 kumpf        1.1             {
370                                  repeat = 0;
371                              }
372                          } // end of if(!rtnp)
373                      } //end of while
374                      return proctable;
375                  }
376                  
377                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
378                  {
379                      int count;
380                      struct procsinfo* proctable;
381                  
382                      proctable = _getProcessData(count);
383                      if (proctable == NULL)
384                      {
385                          return false;
386                      }
387                  
388                      for (int i=0; i < count; i++)
389                      {
390 kumpf        1.1         if (!strcmp(proctable[i].pi_comm, _serverName) && \
391                              proctable[i].pi_pid == pid)
392                          {
393                              free(proctable);
394                              return true;
395                          }
396                      }
397                  
398                      free(proctable);
399                      return false;
400                  }
401                  
402                  # elif defined(PEGASUS_OS_HPUX)
403                  
404                  ///////////////////////////////////////////////////////
405                  // HP-UX implementation of _isServerProcess
406                  ///////////////////////////////////////////////////////
407                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
408                  {
409                      struct pst_status pstru;
410                  
411 kumpf        1.1     if (pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid) != -1)
412                      {
413                          //
414                          // Gets the command basename disregarding the command parameters
415                          //
416                          char *execName = strchr(pstru.pst_cmd,' ');
417                          if (execName)
418                          {
419                              *execName = '\0';
420                          }
421                          execName = basename(pstru.pst_cmd);
422                  
423                          if (strcmp(execName, _serverName) == 0)
424                          {
425                              return true;
426                          }
427                      }
428                  
429                      return false;
430                  }
431                  
432 kumpf        1.1 # else
433                  
434                  ///////////////////////////////////////////////////////
435                  // Generic implementation of _isServerProcess
436                  ///////////////////////////////////////////////////////
437                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
438                  {
439                      return false;
440                  }
441                  
442                  # endif
443                  
444                  #endif
445                  
446                  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2