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

  1 martin 1.9 //%LICENSE////////////////////////////////////////////////////////////////
  2            // 
  3            // Licensed to The Open Group (TOG) under one or more contributor license
  4            // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5            // this work for additional information regarding copyright ownership.
  6            // Each contributor licenses this file to you under the OpenPegasus Open
  7            // Source License; you may not use this file except in compliance with the
  8            // License.
  9            // 
 10            // Permission is hereby granted, free of charge, to any person obtaining a
 11            // copy of this software and associated documentation files (the "Software"),
 12            // to deal in the Software without restriction, including without limitation
 13            // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14            // and/or sell copies of the Software, and to permit persons to whom the
 15            // Software is furnished to do so, subject to the following conditions:
 16            // 
 17            // The above copyright notice and this permission notice shall be included
 18            // in all copies or substantial portions of the Software.
 19            // 
 20            // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21            // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 22 martin 1.9 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23            // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24            // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25            // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26            // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 kumpf  1.1 // 
 28 martin 1.9 //////////////////////////////////////////////////////////////////////////
 29 kumpf  1.1 //
 30            //%/////////////////////////////////////////////////////////////////////////////
 31            
 32            #include <Pegasus/Common/System.h>
 33            #include <Pegasus/Common/Signal.h>
 34            #include <Pegasus/Common/AutoPtr.h>
 35            #include <Service/PidFile.h>
 36            #include <Service/ServerRunStatus.h>
 37            
 38            #include <sys/types.h>
 39            #include <sys/stat.h>
 40            
 41            #if defined(PEGASUS_OS_HPUX)
 42            # include <sys/pstat.h>
 43            # include <libgen.h>
 44            #endif
 45            
 46 r.kieninger 1.8 #if defined(PEGASUS_OS_ZOS)
 47 kumpf       1.1 # include <sys/ps.h>
 48                 #endif
 49                 
 50 ouyang.jian 1.6 #if defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
 51 dave.sudlik 1.7 # include <procinfo.h>
 52                 # define PROCSIZE sizeof(struct procsinfo)
 53                 # if PEGASUS_AIX_VERSION <= 5
 54                 // AIX version 5 does not define getprocs() in procinfo.h
 55 kumpf       1.1 extern "C"
 56                 {
 57 dave.sudlik 1.7     extern int getprocs(
 58                         struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
 59 kumpf       1.1 }
 60 dave.sudlik 1.7 # endif
 61 kumpf       1.1 #endif
 62                 
 63                 PEGASUS_NAMESPACE_BEGIN
 64                 
 65                 #ifdef PEGASUS_OS_TYPE_WINDOWS
 66                 
 67                 //////////////////////////////////////
 68                 //
 69                 // Windows implementation
 70                 //
 71                 //////////////////////////////////////
 72                 
 73                 ServerRunStatus::ServerRunStatus(
 74                     const char* serverName,
 75                     const char* pidFilePath)
 76                     : _serverName(serverName),
 77                       _pidFilePath(pidFilePath),
 78 kumpf       1.5       _isRunningServerInstance(false),
 79 kumpf       1.1       _parentPid(0),
 80                       _event(NULL),
 81                       _wasAlreadyRunning(false)
 82                 {
 83                 }
 84                 
 85                 ServerRunStatus::~ServerRunStatus()
 86                 {
 87                     if (_event != NULL)
 88                     {
 89                         CloseHandle(_event);
 90                     }
 91                 }
 92                 
 93                 Boolean ServerRunStatus::isServerRunning()
 94                 {
 95 dave.sudlik 1.3     return _wasAlreadyRunning;
 96 kumpf       1.1 }
 97                 
 98                 void ServerRunStatus::setServerRunning()
 99                 {
100                     if (_event == NULL)
101                     {
102                         _event = CreateEvent(NULL, TRUE, TRUE, _serverName);
103                         if ((_event != NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
104                         {
105                             _wasAlreadyRunning = false;
106                         }
107                     }
108                 }
109                 
110                 void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
111                 {
112                 }
113                 
114                 Boolean ServerRunStatus::kill()
115                 {
116                     return true;
117 kumpf       1.1 }
118                 
119 carson.hovey 1.2 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
120 kumpf        1.1 
121                  //////////////////////////////////////
122                  //
123                  // Unix and OpenVMS implementation
124                  //
125                  //////////////////////////////////////
126                  
127                  ServerRunStatus::ServerRunStatus(
128                      const char* serverName,
129                      const char* pidFilePath)
130                      : _serverName(serverName),
131                        _pidFilePath(pidFilePath),
132 kumpf        1.5       _isRunningServerInstance(false),
133 kumpf        1.1       _parentPid(0)
134                  {
135                  }
136                  
137                  ServerRunStatus::~ServerRunStatus()
138                  {
139 kumpf        1.5     if (_isRunningServerInstance)
140                      {
141                          PidFile pidFile(_pidFilePath);
142                          pidFile.remove();
143                      }
144 kumpf        1.1 }
145                  
146                  Boolean ServerRunStatus::isServerRunning()
147                  {
148                      PidFile pidFile(_pidFilePath);
149                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
150                  
151                      if (pid == 0)
152                      {
153                          return false;
154                      }
155                  
156                      return (pid != (PEGASUS_PID_T) System::getPID()) &&
157                             (pid != _parentPid) &&
158                             _isServerProcess(pid);
159                  }
160                  
161                  void ServerRunStatus::setServerRunning()
162                  {
163                      PidFile pidFile(_pidFilePath);
164                      pidFile.setPid(System::getPID());
165 kumpf        1.5     _isRunningServerInstance = true;
166 kumpf        1.1 }
167                  
168                  void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
169                  {
170                      _parentPid = parentPid;
171                  }
172                  
173                  Boolean ServerRunStatus::kill()
174                  {
175                      PidFile pidFile(_pidFilePath);
176                      PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
177                  
178                      if ((pid == 0) ||
179                          (pid == (PEGASUS_PID_T) System::getPID()) ||
180                          (pid == _parentPid) ||
181                          !_isServerProcess(pid))
182                      {
183                          pidFile.remove();
184                          return false;
185                      }
186                  
187 kumpf        1.1 #if defined(PEGASUS_OS_HPUX) || \
188                      defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
189                      defined(PEGASUS_OS_SOLARIS) || \
190 r.kieninger  1.8     defined(PEGASUS_OS_ZOS) || \
191 ouyang.jian  1.6     defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
192 kumpf        1.1 
193                      ::kill(pid, SIGKILL);
194                  
195                  #endif
196                  
197                      pidFile.remove();
198                      return true;
199                  }
200                  
201 r.kieninger  1.8 # if defined(PEGASUS_OS_ZOS)
202 kumpf        1.1 
203                  ///////////////////////////////////////////////////////
204                  // z/OS implementation of _isServerProcess
205                  ///////////////////////////////////////////////////////
206                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
207                  {
208                      W_PSPROC buf;
209                      int token = 0;
210                      memset(&buf, 0x00, sizeof(buf));
211                      buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
212                      buf.ps_pathptr   =(char *) malloc(buf.ps_pathlen   =PS_PATHBLEN);
213                      buf.ps_cmdptr    =(char *) malloc(buf.ps_cmdlen    =PS_CMDBLEN);
214                      Boolean returnValue = false;
215                  
216                      while ((token = w_getpsent(token, &buf, sizeof(buf))) > 0)
217                      {
218                          if (buf.ps_pid == pid)
219                          {
220                              // If the process id is associated with the server program,
221                              // then a server is still running.
222                              if (strstr(buf.ps_pathptr, _serverName) != NULL)
223 kumpf        1.1             {
224                                  returnValue = true;
225                              }
226                              // else the pid was not associated with the server
227                              break;
228                          }
229                      }
230                  
231                      free(buf.ps_conttyptr);
232                      free(buf.ps_pathptr);
233                      free(buf.ps_cmdptr);
234                      return returnValue;
235                  }
236                  
237                  # elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
238                      defined(PEGASUS_OS_SOLARIS)
239                  
240                  ///////////////////////////////////////////////////////
241                  // Linux and Solaris implementation of _isServerProcess
242                  ///////////////////////////////////////////////////////
243                  /*
244 kumpf        1.1    Opens the 'stat' file in the /proc/<pid> directory to
245                     verify that the process name is that of the server.
246                  */
247                  static Boolean _isServerPidDir(
248                      const char *directory,
249                      const char* serverProcessName)
250                  {
251                      static char filename[80];
252                      static char buffer[512];
253                      int fd, bytesRead;
254                  
255                      // generate the name of the stat file in the process's /proc directory,
256                      // and open it
257                      sprintf(filename, "%s/%s", directory, "stat");
258                      if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
259                      {
260                          return false;
261                      }
262                  
263                      // read the contents
264                      if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
265 kumpf        1.1     {
266                          close(fd);
267                          return false;
268                      }
269                  
270                      // null terminate the file contents
271                      buffer[bytesRead] = 0;
272                  
273                      close(fd);
274                  
275                      // the process name is the second element of the file contents and
276                      // is surrounded by parentheses.
277                      //
278                      // find the positions of the parentheses in the file contents
279                      const char* openParen;
280                      const char* closeParen;
281                  
282                      openParen = strchr(buffer, '(');
283                      closeParen = strchr(buffer, ')');
284                      if (openParen == NULL || closeParen == NULL || closeParen < openParen)
285                      {
286 kumpf        1.1         return false;
287                      }
288                  
289                      // allocate memory for the result
290                      AutoArrayPtr<char> processName(new char[closeParen - openParen]);
291                  
292                      // copy the process name into the result
293                      strncpy(processName.get(), openParen + 1, closeParen - openParen -1);
294                  
295                      // strncpy doesn't NULL-terminate the result, so do it here
296                      processName[closeParen - openParen -1] = '\0';
297                  
298                      return strcmp(processName.get(), serverProcessName) == 0;
299                  }
300                  
301                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
302                  {
303                      // This method makes a stat() system call on the directory in /proc
304                      // with a name that matches the pid of the server.  It returns true
305                      // if it successfully located the process dir and verified that the
306                      // process name matches that of the server.
307 kumpf        1.1 
308                      static char path[32];
309                      static struct stat statBuffer;
310                  
311                      sprintf(path, "/proc/%d", pid);
312                      if (stat(path, &statBuffer) == -1)          // process stopped running
313                      {
314                          return false;
315                      }
316                  
317                      // get the process name to make sure it is the cimserver process
318                  // ATTN: skip verify for Solaris
319                  #  if !defined(PEGASUS_OS_SOLARIS)
320                      if (!_isServerPidDir(path, _serverName))
321                      {
322                          return false;
323                      }
324                  #  endif
325                  
326                      return true;
327                  }
328 kumpf        1.1 
329 ouyang.jian  1.6 # elif defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
330 kumpf        1.1 
331                  ///////////////////////////////////////////////////////
332                  // AIX implementation of _isServerProcess
333                  ///////////////////////////////////////////////////////
334                  /*
335                     Calls subroutine getprocs() to get information about all processes.
336                     If successful, an array of procsinfo structures filled with process table
337                     entries is returned.  Otherwise, a null pointer is returned.
338                     The output parameter cnt specifies the number of the processes in the
339                     returned table.
340                  */
341                  static struct procsinfo* _getProcessData(int& cnt)
342                  {
343                      struct procsinfo* proctable = NULL;
344                      struct procsinfo* rtnp = NULL;
345                      int count = 1048576;
346                      int rtncnt;
347                      int repeat = 1;
348                      int nextp = 0;
349                  
350                      cnt = 0;
351 kumpf        1.1     while (repeat &&
352                             (rtncnt = getprocs(rtnp, PROCSIZE, 0, 0, &nextp, count) > 0))
353                      {
354                          if (!rtnp)
355                          {
356                              count=rtncnt;
357                              proctable = (struct procsinfo*) malloc((size_t) PROCSIZE*count);
358                              if (!proctable)
359                              {
360                                  return NULL;
361                              }
362                              rtnp = proctable;
363                              nextp = 0;
364                          }
365                          else
366                          {
367                              cnt += rtncnt;
368                              if (rtncnt >= count)
369                              {
370                                  proctable=(struct procsinfo *) realloc(
371                                      (void*)proctable, (size_t) (PROCSIZE*(cnt+count)));
372 kumpf        1.1                 if (!proctable)
373                                  {
374                                      return NULL;
375                                  }
376                                  rtnp = proctable+(cnt);
377                              }
378                              else
379                              {
380                                  repeat = 0;
381                              }
382                          } // end of if(!rtnp)
383                      } //end of while
384                      return proctable;
385                  }
386                  
387                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
388                  {
389                      int count;
390                      struct procsinfo* proctable;
391                  
392                      proctable = _getProcessData(count);
393 kumpf        1.1     if (proctable == NULL)
394                      {
395                          return false;
396                      }
397                  
398                      for (int i=0; i < count; i++)
399                      {
400                          if (!strcmp(proctable[i].pi_comm, _serverName) && \
401                              proctable[i].pi_pid == pid)
402                          {
403                              free(proctable);
404                              return true;
405                          }
406                      }
407                  
408                      free(proctable);
409                      return false;
410                  }
411                  
412                  # elif defined(PEGASUS_OS_HPUX)
413                  
414 kumpf        1.1 ///////////////////////////////////////////////////////
415                  // HP-UX implementation of _isServerProcess
416                  ///////////////////////////////////////////////////////
417                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
418                  {
419                      struct pst_status pstru;
420                  
421                      if (pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid) != -1)
422                      {
423                          //
424                          // Gets the command basename disregarding the command parameters
425                          //
426                          char *execName = strchr(pstru.pst_cmd,' ');
427                          if (execName)
428                          {
429                              *execName = '\0';
430                          }
431                          execName = basename(pstru.pst_cmd);
432                  
433                          if (strcmp(execName, _serverName) == 0)
434                          {
435 kumpf        1.1             return true;
436                          }
437                      }
438                  
439                      return false;
440                  }
441                  
442                  # else
443                  
444                  ///////////////////////////////////////////////////////
445                  // Generic implementation of _isServerProcess
446                  ///////////////////////////////////////////////////////
447                  Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
448                  {
449                      return false;
450                  }
451                  
452                  # endif
453                  
454                  #endif
455                  
456 kumpf        1.1 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2