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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2