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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2