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

  1 kumpf 1.1 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6           // IBM Corp.; EMC Corporation, The Open Group.
  7           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software"), to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 kumpf 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //==============================================================================
 31           //
 32           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34           #include <Pegasus/Common/System.h>
 35           #include <Pegasus/Common/Signal.h>
 36           #include <Pegasus/Common/AutoPtr.h>
 37           #include <Service/PidFile.h>
 38           #include <Service/ServerRunStatus.h>
 39           
 40           #include <sys/types.h>
 41           #include <sys/stat.h>
 42           
 43 kumpf 1.1 #if defined(PEGASUS_OS_HPUX)
 44           # include <sys/pstat.h>
 45           # include <libgen.h>
 46           #endif
 47           
 48           #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
 49           # include <sys/ps.h>
 50           #endif
 51           
 52 ouyang.jian 1.6 #if defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
 53 kumpf       1.1 extern "C"
 54                 {
 55                 # include <procinfo.h>
 56                 extern int getprocs(struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
 57                 # define PROCSIZE sizeof(struct procsinfo)
 58                 }
 59                 #endif
 60                 
 61                 PEGASUS_NAMESPACE_BEGIN
 62                 
 63                 #ifdef PEGASUS_OS_TYPE_WINDOWS
 64                 
 65                 //////////////////////////////////////
 66                 //
 67                 // Windows implementation
 68                 //
 69                 //////////////////////////////////////
 70                 
 71                 ServerRunStatus::ServerRunStatus(
 72                     const char* serverName,
 73                     const char* pidFilePath)
 74 kumpf       1.1     : _serverName(serverName),
 75                       _pidFilePath(pidFilePath),
 76 kumpf       1.5       _isRunningServerInstance(false),
 77 kumpf       1.1       _parentPid(0),
 78                       _event(NULL),
 79                       _wasAlreadyRunning(false)
 80                 {
 81                 }
 82                 
 83                 ServerRunStatus::~ServerRunStatus()
 84                 {
 85                     if (_event != NULL)
 86                     {
 87                         CloseHandle(_event);
 88                     }
 89                 }
 90                 
 91                 Boolean ServerRunStatus::isServerRunning()
 92                 {
 93 dave.sudlik 1.3     return _wasAlreadyRunning;
 94 kumpf       1.1 }
 95                 
 96                 void ServerRunStatus::setServerRunning()
 97                 {
 98                     if (_event == NULL)
 99                     {
100                         _event = CreateEvent(NULL, TRUE, TRUE, _serverName);
101                         if ((_event != NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
102                         {
103                             _wasAlreadyRunning = false;
104                         }
105                     }
106                 }
107                 
108                 void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
109                 {
110                 }
111                 
112                 Boolean ServerRunStatus::kill()
113                 {
114                     return true;
115 kumpf       1.1 }
116                 
117 mike        1.6.2.1 #elif defined(PEGASUS_OS_TYPE_UNIX) || \
118                           defined(PEGASUS_OS_VMS) || \
119                           defined(PEGASUS_OS_VXWORKS)
120 kumpf       1.1     
121                     //////////////////////////////////////
122                     //
123                     // Unix and OpenVMS implementation
124                     //
125                     //////////////////////////////////////
126                     
127                     ServerRunStatus::ServerRunStatus(
128                         const char* serverName,
129                         const char* pidFilePath)
130                         : _serverName(serverName),
131                           _pidFilePath(pidFilePath),
132 kumpf       1.5           _isRunningServerInstance(false),
133 kumpf       1.1           _parentPid(0)
134                     {
135                     }
136                     
137                     ServerRunStatus::~ServerRunStatus()
138                     {
139 kumpf       1.5         if (_isRunningServerInstance)
140                         {
141                             PidFile pidFile(_pidFilePath);
142                             pidFile.remove();
143                         }
144 kumpf       1.1     }
145                     
146                     Boolean ServerRunStatus::isServerRunning()
147                     {
148                         PidFile pidFile(_pidFilePath);
149                         PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
150                     
151                         if (pid == 0)
152                         {
153                             return false;
154                         }
155                     
156                         return (pid != (PEGASUS_PID_T) System::getPID()) &&
157                                (pid != _parentPid) &&
158                                _isServerProcess(pid);
159                     }
160                     
161                     void ServerRunStatus::setServerRunning()
162                     {
163                         PidFile pidFile(_pidFilePath);
164                         pidFile.setPid(System::getPID());
165 kumpf       1.5         _isRunningServerInstance = true;
166 kumpf       1.1     }
167                     
168                     void ServerRunStatus::setParentPid(PEGASUS_PID_T parentPid)
169                     {
170                         _parentPid = parentPid;
171                     }
172                     
173                     Boolean ServerRunStatus::kill()
174                     {
175                         PidFile pidFile(_pidFilePath);
176                         PEGASUS_PID_T pid = (PEGASUS_PID_T) pidFile.getPid();
177                     
178                         if ((pid == 0) ||
179                             (pid == (PEGASUS_PID_T) System::getPID()) ||
180                             (pid == _parentPid) ||
181                             !_isServerProcess(pid))
182                         {
183                             pidFile.remove();
184                             return false;
185                         }
186                     
187 kumpf       1.1     #if defined(PEGASUS_OS_HPUX) || \
188                         defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
189                         defined(PEGASUS_OS_SOLARIS) || \
190                         defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || \
191 ouyang.jian 1.6         defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
192 kumpf       1.1     
193                         ::kill(pid, SIGKILL);
194                     
195                     #endif
196                     
197                         pidFile.remove();
198                         return true;
199                     }
200                     
201                     # if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
202                     
203                     ///////////////////////////////////////////////////////
204                     // z/OS implementation of _isServerProcess
205                     ///////////////////////////////////////////////////////
206                     Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
207                     {
208                         W_PSPROC buf;
209                         int token = 0;
210                         memset(&buf, 0x00, sizeof(buf));
211                         buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
212                         buf.ps_pathptr   =(char *) malloc(buf.ps_pathlen   =PS_PATHBLEN);
213 kumpf       1.1         buf.ps_cmdptr    =(char *) malloc(buf.ps_cmdlen    =PS_CMDBLEN);
214                         Boolean returnValue = false;
215                     
216                         while ((token = w_getpsent(token, &buf, sizeof(buf))) > 0)
217                         {
218                             if (buf.ps_pid == pid)
219                             {
220                                 // If the process id is associated with the server program,
221                                 // then a server is still running.
222                                 if (strstr(buf.ps_pathptr, _serverName) != NULL)
223                                 {
224                                     returnValue = true;
225                                 }
226                                 // else the pid was not associated with the server
227                                 break;
228                             }
229                         }
230                     
231                         free(buf.ps_conttyptr);
232                         free(buf.ps_pathptr);
233                         free(buf.ps_cmdptr);
234 kumpf       1.1         return returnValue;
235                     }
236                     
237                     # elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \
238                         defined(PEGASUS_OS_SOLARIS)
239                     
240                     ///////////////////////////////////////////////////////
241                     // Linux and Solaris implementation of _isServerProcess
242                     ///////////////////////////////////////////////////////
243                     /*
244                        Opens the 'stat' file in the /proc/<pid> directory to
245                        verify that the process name is that of the server.
246                     */
247                     static Boolean _isServerPidDir(
248                         const char *directory,
249                         const char* serverProcessName)
250                     {
251                         static char filename[80];
252                         static char buffer[512];
253                         int fd, bytesRead;
254                     
255 kumpf       1.1         // generate the name of the stat file in the process's /proc directory,
256                         // and open it
257                         sprintf(filename, "%s/%s", directory, "stat");
258                         if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
259                         {
260                             return false;
261                         }
262                     
263                         // read the contents
264                         if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
265                         {
266                             close(fd);
267                             return false;
268                         }
269                     
270                         // null terminate the file contents
271                         buffer[bytesRead] = 0;
272                     
273                         close(fd);
274                     
275                         // the process name is the second element of the file contents and
276 kumpf       1.1         // is surrounded by parentheses.
277                         //
278                         // find the positions of the parentheses in the file contents
279                         const char* openParen;
280                         const char* closeParen;
281                     
282                         openParen = strchr(buffer, '(');
283                         closeParen = strchr(buffer, ')');
284                         if (openParen == NULL || closeParen == NULL || closeParen < openParen)
285                         {
286                             return false;
287                         }
288                     
289                         // allocate memory for the result
290                         AutoArrayPtr<char> processName(new char[closeParen - openParen]);
291                     
292                         // copy the process name into the result
293                         strncpy(processName.get(), openParen + 1, closeParen - openParen -1);
294                     
295                         // strncpy doesn't NULL-terminate the result, so do it here
296                         processName[closeParen - openParen -1] = '\0';
297 kumpf       1.1     
298                         return strcmp(processName.get(), serverProcessName) == 0;
299                     }
300                     
301                     Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
302                     {
303                         // This method makes a stat() system call on the directory in /proc
304                         // with a name that matches the pid of the server.  It returns true
305                         // if it successfully located the process dir and verified that the
306                         // process name matches that of the server.
307                     
308                         static char path[32];
309                         static struct stat statBuffer;
310                     
311                         sprintf(path, "/proc/%d", pid);
312                         if (stat(path, &statBuffer) == -1)          // process stopped running
313                         {
314                             return false;
315                         }
316                     
317                         // get the process name to make sure it is the cimserver process
318 kumpf       1.1     // ATTN: skip verify for Solaris
319                     #  if !defined(PEGASUS_OS_SOLARIS)
320                         if (!_isServerPidDir(path, _serverName))
321                         {
322                             return false;
323                         }
324                     #  endif
325                     
326                         return true;
327                     }
328                     
329 ouyang.jian 1.6     # elif defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_PASE)
330 kumpf       1.1     
331                     ///////////////////////////////////////////////////////
332                     // AIX implementation of _isServerProcess
333                     ///////////////////////////////////////////////////////
334                     /*
335                        Calls subroutine getprocs() to get information about all processes.
336                        If successful, an array of procsinfo structures filled with process table
337                        entries is returned.  Otherwise, a null pointer is returned.
338                        The output parameter cnt specifies the number of the processes in the
339                        returned table.
340                     */
341                     static struct procsinfo* _getProcessData(int& cnt)
342                     {
343                         struct procsinfo* proctable = NULL;
344                         struct procsinfo* rtnp = NULL;
345                         int count = 1048576;
346                         int rtncnt;
347                         int repeat = 1;
348                         int nextp = 0;
349                     
350                         cnt = 0;
351 kumpf       1.1         while (repeat &&
352                                (rtncnt = getprocs(rtnp, PROCSIZE, 0, 0, &nextp, count) > 0))
353                         {
354                             if (!rtnp)
355                             {
356                                 count=rtncnt;
357                                 proctable = (struct procsinfo*) malloc((size_t) PROCSIZE*count);
358                                 if (!proctable)
359                                 {
360                                     return NULL;
361                                 }
362                                 rtnp = proctable;
363                                 nextp = 0;
364                             }
365                             else
366                             {
367                                 cnt += rtncnt;
368                                 if (rtncnt >= count)
369                                 {
370                                     proctable=(struct procsinfo *) realloc(
371                                         (void*)proctable, (size_t) (PROCSIZE*(cnt+count)));
372 kumpf       1.1                     if (!proctable)
373                                     {
374                                         return NULL;
375                                     }
376                                     rtnp = proctable+(cnt);
377                                 }
378                                 else
379                                 {
380                                     repeat = 0;
381                                 }
382                             } // end of if(!rtnp)
383                         } //end of while
384                         return proctable;
385                     }
386                     
387                     Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
388                     {
389                         int count;
390                         struct procsinfo* proctable;
391                     
392                         proctable = _getProcessData(count);
393 kumpf       1.1         if (proctable == NULL)
394                         {
395                             return false;
396                         }
397                     
398                         for (int i=0; i < count; i++)
399                         {
400                             if (!strcmp(proctable[i].pi_comm, _serverName) && \
401                                 proctable[i].pi_pid == pid)
402                             {
403                                 free(proctable);
404                                 return true;
405                             }
406                         }
407                     
408                         free(proctable);
409                         return false;
410                     }
411                     
412                     # elif defined(PEGASUS_OS_HPUX)
413                     
414 kumpf       1.1     ///////////////////////////////////////////////////////
415                     // HP-UX implementation of _isServerProcess
416                     ///////////////////////////////////////////////////////
417                     Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
418                     {
419                         struct pst_status pstru;
420                     
421                         if (pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid) != -1)
422                         {
423                             //
424                             // Gets the command basename disregarding the command parameters
425                             //
426                             char *execName = strchr(pstru.pst_cmd,' ');
427                             if (execName)
428                             {
429                                 *execName = '\0';
430                             }
431                             execName = basename(pstru.pst_cmd);
432                     
433                             if (strcmp(execName, _serverName) == 0)
434                             {
435 kumpf       1.1                 return true;
436                             }
437                         }
438                     
439                         return false;
440                     }
441                     
442                     # else
443                     
444                     ///////////////////////////////////////////////////////
445                     // Generic implementation of _isServerProcess
446                     ///////////////////////////////////////////////////////
447                     Boolean ServerRunStatus::_isServerProcess(PEGASUS_PID_T pid)
448                     {
449                         return false;
450                     }
451                     
452                     # endif
453                     
454                     #endif
455                     
456 kumpf       1.1     PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2