(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 karl         1.11.6.2 #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 karl         1.11.6.1     setServerNotRunning();
 90 kumpf        1.1      }
 91                       
 92                       Boolean ServerRunStatus::isServerRunning()
 93                       {
 94 dave.sudlik  1.3          return _wasAlreadyRunning;
 95 kumpf        1.1      }
 96                       
 97 karl         1.11.6.1 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                                   _wasAlreadyRunning = false;
121                               }
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 karl         1.11.6.1     setServerNotRunning();
155                       }
156                       
157                       void ServerRunStatus::setServerNotRunning()
158                       {
159 kumpf        1.5          if (_isRunningServerInstance)
160                           {
161                               PidFile pidFile(_pidFilePath);
162                               pidFile.remove();
163 karl         1.11.6.1         _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 karl         1.11.6.2                 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