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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2