(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 venkat.puvvada 1.12     setServerNotRunning();
 89 kumpf          1.1  }
 90                     
 91                     Boolean ServerRunStatus::isServerRunning()
 92                     {
 93 dave.sudlik    1.3      return _wasAlreadyRunning;
 94 kumpf          1.1  }
 95                     
 96 venkat.puvvada 1.12 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 dev.meetei     1.14             _wasAlreadyRunning = false;
120 kumpf          1.1          }
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 venkat.puvvada 1.12     setServerNotRunning();
154                     }
155                     
156                     void ServerRunStatus::setServerNotRunning()
157                     {
158 kumpf          1.5      if (_isRunningServerInstance)
159                         {
160                             PidFile pidFile(_pidFilePath);
161                             pidFile.remove();
162 venkat.puvvada 1.12         _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