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

  1 martin 1.9 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.10 //
  3 martin 1.9  // 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 martin 1.10 //
 10 martin 1.9  // 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 martin 1.10 //
 17 martin 1.9  // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.10 //
 20 martin 1.9  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.10 // 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 martin 1.10 //
 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