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
|