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