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