(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 # include <procinfo.h>
 54                 # define PROCSIZE sizeof(struct procsinfo)
 55 dave.sudlik 1.6.4.1 # if PEGASUS_AIX_VERSION <= 5
 56                     // AIX version 5 does not define getprocs() in procinfo.h
 57                     extern "C"
 58                     {
 59                         extern int getprocs(
 60                             struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
 61 kumpf       1.1     }
 62                     #endif
 63 dave.sudlik 1.6.4.1 #endif
 64 kumpf       1.1     
 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