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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2