1 a.dunfey 1.6.2.1 //%2006////////////////////////////////////////////////////////////////////////
|
2 h.sterling 1.1 //
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 a.dunfey 1.6.2.1 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 h.sterling 1.1 //
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 // 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 // Author: Mike Day (mdday@us.ibm.com)
33 //
34 h.sterling 1.1 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
35 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
36 // Marek Szermutzky, IBM (ddt6szer@de.ibm.com)
37 //%/////////////////////////////////////////////////////////////////////////////
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #if defined(PEGASUS_OS_HPUX)
41 #include <sys/pstat.h>
42 #endif
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <Pegasus/Common/Signal.h>
46 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
47 #include <sys/ps.h>
48 #endif
|
49 w.otsuka 1.4 #define MAX_WAIT_TIME 240
|
50 h.sterling 1.1 #if defined(PEGASUS_OS_AIX)
51 extern "C" {
52 #include <procinfo.h>
53 extern int getprocs(struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
54 #define PROCSIZE sizeof(struct procsinfo)
55 }
56 #endif
57
58 PEGASUS_USING_PEGASUS;
59 PEGASUS_USING_STD;
60
61 Boolean handleSigUsr1 = false;
62 Boolean graveError = false;
63
64 pid_t server_pid;
|
65 h.sterling 1.3 Uint32 parentPid = 0;
|
66 h.sterling 1.1
67 void sigUsr1Handler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
68 {
69 handleSigUsr1 = true;
70 }
71
72 void sigTermHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
73 {
74 graveError= handleSigUsr1=true;
75 }
76
77
78 //constructor
79 ServerProcess::ServerProcess() {}
80
81 //destructor
82 ServerProcess::~ServerProcess() {}
83
84 // no-ops
85 void ServerProcess::cimserver_set_process(void* p) {}
86 void ServerProcess::cimserver_exitRC(int rc) {}
87 h.sterling 1.1 int ServerProcess::cimserver_initialize(void) { return 1; }
88 int ServerProcess::cimserver_wait(void) { return 1; }
89 String ServerProcess::getHome(void) { return String::EMPTY; }
90
91 // daemon_init , RW Stevens, "Advance UNIX Programming"
92
93 int ServerProcess::cimserver_fork(void)
94 {
95 getSigHandle()->registerHandler(PEGASUS_SIGUSR1, sigUsr1Handler);
96 getSigHandle()->activate(PEGASUS_SIGUSR1);
97 getSigHandle()->registerHandler(SIGTERM, sigTermHandler);
98 getSigHandle()->activate(SIGTERM);
99
100 pid_t pid;
101 if( (pid = fork() ) < 0)
102 {
103 getSigHandle()->deactivate(PEGASUS_SIGUSR1);
104 getSigHandle()->deactivate(SIGTERM);
105 return(-1);
106 }
107 else if (pid != 0)
108 h.sterling 1.1 {
109 //
110 // parent wait for child
111 // if there is a problem with signal, parent process terminates
112 // when waitTime expires
113 //
114 Uint32 waitTime = MAX_WAIT_TIME;
115
116 while(!handleSigUsr1 && waitTime > 0)
117 {
118 sleep(1);
119 waitTime--;
120 }
|
121 w.otsuka 1.4 if( !handleSigUsr1 )
122 {
123 MessageLoaderParms parms("src.Service.ServerProcessUnix.CIMSERVER_START_TIMEOUT",
124 "The cimserver command timed out waiting for the CIM server to start.");
125 PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) << PEGASUS_STD(endl);
126 }
|
127 h.sterling 1.1 exit(graveError);
128 }
129
130 setsid();
131 umask(0);
132
133 // get the pid of the cimserver process
134 server_pid = getpid();
135 return(0);
136 }
137
138 long ServerProcess::get_server_pid()
139 {
140 return server_pid;
141 }
142
|
143 h.sterling 1.3 void ServerProcess::set_parent_pid(int pid)
144 {
145 parentPid = pid;
146 }
147
148
|
149 jim.wunderlich 1.5 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_OS_SOLARIS)
|
150 h.sterling 1.1
151 //===========================================================================
152 // NAME : verify_process_name
153 // DESCRIPTION : Opens the 'stat' file in the /proc/<pid> directory to
154 // verify that the process name is that of the cimserver.
155 //===========================================================================
156 int verify_process_name(char *directory, const char* server_process_name)
157 {
158 static char filename[80];
159 static char buffer[512];
160 int fd, bytesRead;
161
162 // generate the name of the stat file in the process's /proc directory,
163 // and open it
164 sprintf(filename, "%s/%s", directory, "stat");
165 if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
166 {
167 return -1;
168 }
169
170 // read the contents
171 h.sterling 1.1 if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
172 {
173 close(fd);
174 return -1;
175 }
176
177 // null terminate the file contents
178 buffer[bytesRead] = 0;
179
180 close(fd);
181
182 // the process name is the second element of the file contents and
183 // is surrounded by parentheses.
184 //
185 // find the positions of the parentheses in the file contents
186 char * open_paren;
187 char * close_paren;
188
189 open_paren = strchr (buffer, '(');
190 close_paren = strchr (buffer, ')');
191 if (open_paren == NULL || close_paren == NULL || close_paren < open_paren)
192 h.sterling 1.1 {
193 return -1;
194 }
195
196 // allocate memory for the result
|
197 kumpf 1.6 AutoArrayPtr<char> process_name(new char[close_paren - open_paren]);
|
198 h.sterling 1.1
199 // copy the process name into the result
|
200 kumpf 1.6 strncpy (process_name.get(), open_paren + 1, close_paren - open_paren -1);
|
201 h.sterling 1.1
202 // strncpy doesn't NULL-terminate the result, so do it here
|
203 kumpf 1.6 process_name.get()[close_paren - open_paren -1] = '\0';
|
204 h.sterling 1.1
|
205 kumpf 1.6 if (strcmp(process_name.get(), server_process_name) != 0)
|
206 h.sterling 1.1 {
207 return -1;
208 }
209
210 return 0;
211 }
212
213 //=============================================================================
214 // NAME : get_proc
215 // DESCRIPTION : get_proc() makes a stat() system call on the directory in
216 // /proc with a name that matches the pid of the cimserver.
217 // It returns 0 if it successfully located the process dir
218 // and verified that the process name matches that of the
219 // cimserver. It returns -1 if it fails to open /proc, or
220 // the cimserver process does not exist.
221 //=============================================================================
222 int ServerProcess::get_proc(int pid)
223 {
224 static char path[32];
225 static struct stat stat_buff;
226
227 h.sterling 1.1 sprintf(path, "/proc/%d", pid);
228 if (stat(path, &stat_buff) == -1) // process stopped running
229 {
230 return -1;
231 }
232
233 // get the process name to make sure it is the cimserver process
234 // ATTN: skip verify for Solaris
|
235 jim.wunderlich 1.5 #if !defined(PEGASUS_OS_SOLARIS)
|
236 h.sterling 1.1 if ((verify_process_name(path, getProcessName())) == -1)
237 {
238 return -1;
239 }
240 #endif
241
242 //
243 // Check to see if this command process has the same pid as the cimserver
244 // daemon process pid stored in the cimserver_start.conf file. Since the
245 // command has the same name as the cimserver daemon process, this could
246 // happen after a system reboot. If the pids are the same, cimserver
247 // isn't really running.
248 //
249 Uint32 mypid = System::getPID();
250 if ((mypid == (unsigned)pid) || ((unsigned)parentPid == (unsigned)pid))
251 {
252 return -1;
253 }
254 return 0;
255 }
256 #endif
257 h.sterling 1.1
258 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
259 Boolean isProcRunning(pid_t pid)
260 {
261 W_PSPROC buf;
262 int token = 0;
263 memset(&buf, 0x00, sizeof(buf));
264 buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
265 buf.ps_pathptr =(char *) malloc(buf.ps_pathlen =PS_PATHBLEN);
266 buf.ps_cmdptr =(char *) malloc(buf.ps_cmdlen =PS_CMDBLEN);
267
268 token = w_getpsent(token, &buf, sizeof(buf));
269 do {
270 token = w_getpsent(token, &buf, sizeof(buf));
271 if (buf.ps_pid==pid) {
272 free(buf.ps_conttyptr);
273 free(buf.ps_pathptr);
274 free(buf.ps_cmdptr);
275 return true;
276 }
277 } while(token>0);
278 h.sterling 1.1
279 free(buf.ps_conttyptr);
280 free(buf.ps_pathptr);
281 free(buf.ps_cmdptr);
282 return false;
283 }
284 #endif
285
286 #if defined(PEGASUS_OS_AIX)
287
288 /////////////////////////////////////////////////////////////////////////////
289 // NAME : processdata
290 // FUNCTION : it calls subroutine getprocs() to get information
291 // about all processes.
292 /////////////////////////////////////////////////////////////////////////////
293 // ARGUMENTS:
294 // cnt: the number of the processes in the returned table
295 // RETURN VALUES:
296 // when it successfully gets the process table entries,
297 // an array of procsinfo structures filled with process table
298 // entries are returned. Otherewise, a null pointer is
299 h.sterling 1.1 // returned.
300 //
301 /////////////////////////////////////////////////////////////////////////////
302 struct procsinfo *processdata(int *cnt)
303 {
304 struct procsinfo *proctable=NULL, *rtnp=NULL;
305 int count=1048576, rtncnt, repeat=1, nextp=0;
306
307 *cnt=0;
308 while ( repeat && (rtncnt=getprocs(rtnp,PROCSIZE,0,0,&nextp, count))>0)
309 {
310 if (!rtnp)
311 {
312 count=rtncnt;
313 proctable=(struct procsinfo *) malloc((size_t) \
314 PROCSIZE*count);
315 if (!proctable)
316 return NULL;
317 rtnp=proctable;
318 nextp=0;
319 } else
320 h.sterling 1.1 {
321 *cnt+=rtncnt;
322 if (rtncnt>=count)
323 {
324 proctable=(struct procsinfo *) realloc(\
325 (void*)proctable, (size_t)\
326 (PROCSIZE*(*cnt+count)));
327 if (!proctable)
328 return NULL;
329 rtnp=proctable+(*cnt);
330 } else
331 repeat=0;
332 } // end of if(!rtnp)
333 } //end of while
334 return proctable;
335 }
336
337 /////////////////////////////////////////////////////////////////////////////
338 // NAME : aixcimsrvrunning
339 // FUNCTION : it figures out if the cimserver process is running
340 // by checking the process table entries in the array
341 h.sterling 1.1 // returned from processdata(). If the cimserver process is
342 // running and its pid is the same as the pid in the file
343 // getPIDFileName(), it will return 0, otherwise it will
344 // return -1.
345 /////////////////////////////////////////////////////////////////////////////
346 // ARGUMENTS:
347 // pid: the process identifier saved in the file
348 // getPIDFileName()
349 // RETURN VALUES:
350 // 0: successful
351 // -1: errors
352 //
353 /////////////////////////////////////////////////////////////////////////////
354
|
355 h.sterling 1.2 int aixcimsrvrunning(pid_t pid, const char* processName)
|
356 h.sterling 1.1 {
357 int i,count;
358 struct procsinfo *proctable;
359
360 proctable=processdata(&count);
361 if (proctable==NULL)
362 return -1;
363 for (i=0;i<count;i++)
|
364 h.sterling 1.2 if (!strcmp(proctable[i].pi_comm, processName) && \
|
365 h.sterling 1.1 proctable[i].pi_pid==pid)
366 {
367 free(proctable);
368 return 0;
369 }
370
371 free(proctable);
372 return -1;
373 }
374 #endif
375
376 Boolean ServerProcess::isCIMServerRunning(void)
377 {
378 FILE *pid_file;
379 pid_t pid = 0;
380
381 // open the file containing the CIMServer process ID
382 pid_file = fopen(getPIDFileName(), "r");
383 if (!pid_file)
384 {
385 return false;
386 h.sterling 1.1 }
387
388 // get the pid from the file
389 fscanf(pid_file, "%d\n", &pid);
390
391 fclose(pid_file);
392
393 if (pid == 0)
394 {
395 return false;
396 }
397
398 //
399 // check to see if cimserver process is alive
400 //
401 #if defined(PEGASUS_OS_HPUX)
402 struct pst_status pstru;
403
404 int ret_code;
405 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
406
407 h.sterling 1.1 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, getProcessName())) == 0)
408 {
409 //
410 // Check to see if this command process has the same pid as the
411 // cimserver daemon process pid stored in the cimserver_start.conf
412 // file. Since the command has the same name as the cimserver daemon
413 // process, this could happen after a system reboot. If the pids are
414 // the same, cimserver isn't really running.
415 //
416 Uint32 mypid = System::getPID();
417 if ((mypid != pid) && (parentPid != pid))
418 {
419 // cimserver is running
420 return true;
421 }
422 }
423 #endif
|
424 jim.wunderlich 1.5 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_OS_SOLARIS)
|
425 h.sterling 1.1 if (get_proc(pid) != -1 )
426 {
427 // cimserver is running
428 return true;
429 }
430 #endif
431 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
432 return isProcRunning(pid);
433 #endif
434 #if defined(PEGASUS_OS_AIX)
|
435 h.sterling 1.2 if (aixcimsrvrunning(pid, getProcessName())!=-1)
|
436 h.sterling 1.1 return true;
437 #endif
438 return false;
439 }
440
441 int ServerProcess::cimserver_kill(int id)
442 {
443 FILE *pid_file;
444 pid_t pid = 0;
445
446 // open the file containing the CIMServer process ID
447 pid_file = fopen(getPIDFileName(), "r");
448 if (!pid_file)
449 {
450 return (-1);
451 }
452
453 // get the pid from the file
454 fscanf(pid_file, "%d\n", &pid);
455
456 fclose(pid_file);
457 h.sterling 1.1
458 if (pid == 0)
459 {
460 System::removeFile(getPIDFileName());
461 return (-1);
462 }
463
464 //
465 // kill the process if it is still alive
466 //
467 #if defined(PEGASUS_OS_HPUX)
468 struct pst_status pstru;
469
470 int ret_code;
471 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
472
473 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, getProcessName())) == 0)
474 {
475 // cimserver is running, kill the process
476 kill(pid, SIGKILL);
477 }
478 h.sterling 1.1 #endif
|
479 jim.wunderlich 1.5 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_OS_SOLARIS)
|
480 h.sterling 1.1 if (get_proc(pid) != -1 )
481 {
482 kill(pid, SIGKILL);
483 }
484 #endif
485 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
486 if (isProcRunning(pid)) {
487 kill(pid, SIGKILL);
488 }
489 #endif
490 #if defined(PEGASUS_OS_AIX)
|
491 h.sterling 1.2 if (!aixcimsrvrunning(pid, getProcessName()))
|
492 h.sterling 1.1 kill(pid,SIGKILL);
493 #endif
494 // remove the file
495 System::removeFile(getPIDFileName());
496
497 return(0);
498 }
499
500 // notify parent process to terminate so user knows that cimserver
501 // is ready to serve CIM requests.
502 void ServerProcess::notify_parent(int id)
503 {
504 pid_t ppid = getppid();
505 if (id)
506 kill(ppid, SIGTERM);
507 else
508 kill(ppid, PEGASUS_SIGUSR1);
509 }
510
511
512 // Platform specific run
|
513 a.dunfey 1.6.2.1 int ServerProcess::platform_run(
514 int argc,
515 char** argv,
516 Boolean shutdownOption,
517 Boolean debugOutputOption)
|
518 h.sterling 1.1 {
|
519 a.dunfey 1.6.2.1 return cimserver_run(argc, argv, shutdownOption, debugOutputOption);
|
520 h.sterling 1.1 }
|