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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2