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