(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.11.4.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 venkat.puvvada 1.11.4.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 venkat.puvvada 1.11.4.1     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.11.4.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