1 karl 1.29 //%2005////////////////////////////////////////////////////////////////////////
|
2 mike 1.5 //
|
3 karl 1.27 // 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 karl 1.23 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.27 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.29 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 mike 1.5 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 kumpf 1.8 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
16 mike 1.5 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
|
19 kumpf 1.8 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
20 mike 1.5 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
22 kumpf 1.8 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
25 mike 1.5 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Mike Day (mdday@us.ibm.com)
31 //
|
32 kumpf 1.10 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
33 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
|
34 marek 1.19 // Marek Szermutzky, IBM (ddt6szer@de.ibm.com)
|
35 mike 1.5 //%/////////////////////////////////////////////////////////////////////////////
36 #include <sys/types.h>
37 #include <sys/stat.h>
|
38 kumpf 1.7 #if defined(PEGASUS_OS_HPUX)
|
39 kumpf 1.6 #include <sys/pstat.h>
|
40 kumpf 1.7 #endif
|
41 mike 1.5 #include <fcntl.h>
42 #include <unistd.h>
|
43 kumpf 1.16 #include <Pegasus/Common/Signal.h>
|
44 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
45 #include <sys/ps.h>
46 #endif
|
47 kumpf 1.16 #define MAX_WAIT_TIME 25
|
48 kv.le 1.24 #if defined(PEGASUS_OS_AIX)
49 extern "C" {
50 #include <procinfo.h>
51 extern int getprocs(struct procsinfo *, int, struct fdsinfo *, int,pid_t *,int);
52 #define PROCSIZE sizeof(struct procsinfo)
53 }
54 #endif
|
55 kumpf 1.12
|
56 mike 1.5 PEGASUS_USING_PEGASUS;
57 PEGASUS_USING_STD;
|
58 kumpf 1.10
|
59 kumpf 1.16 Boolean handleSigUsr1 = false;
|
60 konrad.r 1.20 Boolean graveError = false;
|
61 mike 1.5 void cim_server_service(int argc, char **argv ) { return; }
62
|
63 kumpf 1.6 pid_t server_pid;
64
|
65 kumpf 1.16 void sigUsr1Handler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
|
66 kumpf 1.10 {
|
67 kumpf 1.16 handleSigUsr1 = true;
|
68 kumpf 1.10 }
69
|
70 konrad.r 1.20 void sigTermHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
71 {
72 graveError= handleSigUsr1=true;
73 }
|
74 mike 1.5 // daemon_init , RW Stevens, "Advance UNIX Programming"
75
76 int cimserver_fork(void)
77 {
|
78 kumpf 1.16 getSigHandle()->registerHandler(PEGASUS_SIGUSR1, sigUsr1Handler);
79 getSigHandle()->activate(PEGASUS_SIGUSR1);
|
80 konrad.r 1.20 getSigHandle()->registerHandler(SIGTERM, sigTermHandler);
81 getSigHandle()->activate(SIGTERM);
|
82 kumpf 1.10
|
83 mike 1.5 pid_t pid;
84 if( (pid = fork() ) < 0)
|
85 kumpf 1.16 {
86 getSigHandle()->deactivate(PEGASUS_SIGUSR1);
|
87 konrad.r 1.20 getSigHandle()->deactivate(SIGTERM);
|
88 kumpf 1.16 return(-1);
89 }
|
90 mike 1.5 else if (pid != 0)
|
91 kumpf 1.10 {
|
92 kumpf 1.16 //
93 // parent wait for child
94 // if there is a problem with signal, parent process terminates
95 // when waitTime expires
96 //
97 Uint32 waitTime = MAX_WAIT_TIME;
|
98 kumpf 1.12
|
99 kumpf 1.16 while(!handleSigUsr1 && waitTime > 0)
100 {
|
101 kumpf 1.12 sleep(1);
|
102 kumpf 1.16 waitTime--;
103 }
|
104 konrad.r 1.20 exit(graveError);
|
105 kumpf 1.10 }
|
106 mike 1.5
107 setsid();
108 umask(0);
|
109 kumpf 1.6
110 // get the pid of the cimserver process
111 server_pid = getpid();
112 return(0);
|
113 kumpf 1.9 }
114
|
115 tony 1.25 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
|
116 kumpf 1.18
117 //===========================================================================
118 // NAME : verify_process_name
119 // DESCRIPTION : Opens the 'stat' file in the /proc/<pid> directory to
120 // verify that the process name is that of the cimserver.
121 //===========================================================================
122 int verify_process_name(char *directory)
123 {
124 static char filename[80];
125 static char buffer[512];
126 int fd, bytesRead;
127
128 // generate the name of the stat file in the process's /proc directory,
129 // and open it
130 sprintf(filename, "%s/%s", directory, "stat");
131 if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
132 {
133 return -1;
134 }
135
136 // read the contents
137 kumpf 1.18 if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
138 {
139 close(fd);
140 return -1;
141 }
142
143 // null terminate the file contents
144 buffer[bytesRead] = 0;
145
146 close(fd);
147
148 // the process name is the second element of the file contents and
149 // is surrounded by parentheses.
150 //
151 // find the positions of the parentheses in the file contents
152 char * open_paren;
153 char * close_paren;
154
155 open_paren = strchr (buffer, '(');
156 close_paren = strchr (buffer, ')');
157 if (open_paren == NULL || close_paren == NULL || close_paren < open_paren)
158 kumpf 1.18 {
159 return -1;
160 }
161
162 // allocate memory for the result
163 char * process_name;
164 process_name = (char*) malloc(close_paren - open_paren - 1);
165
166 // copy the process name into the result
167 strncpy (process_name, open_paren + 1, close_paren - open_paren -1);
168
169 // strncpy doesn't NULL-terminate the result, so do it here
170 process_name[close_paren - open_paren -1] = '\0';
171
172 if (strcmp(process_name, "cimserver") != 0)
173 {
174 return -1;
175 }
176
177 return 0;
178 }
179 kumpf 1.18
180 //=============================================================================
181 // NAME : get_proc
182 // DESCRIPTION : get_proc() makes a stat() system call on the directory in
183 // /proc with a name that matches the pid of the cimserver.
184 // It returns 0 if it successfully located the process dir
185 // and verified that the process name matches that of the
186 // cimserver. It returns -1 if it fails to open /proc, or
187 // the cimserver process does not exist.
188 //=============================================================================
189 int get_proc(int pid)
190 {
191 static char path[32];
192 static struct stat stat_buff;
193
194 sprintf(path, "/proc/%d", pid);
195 if (stat(path, &stat_buff) == -1) // process stopped running
196 {
197 return -1;
198 }
199
|
200 tony 1.25 // get the process name to make sure it is the cimserver process
201 // ATTN: skip verify for Solaris
202 #if !defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
|
203 kumpf 1.18 if ((verify_process_name(path)) == -1)
204 {
205 return -1;
206 }
|
207 tony 1.25 #endif
|
208 kumpf 1.18
|
209 kumpf 1.21 //
210 // Check to see if this command process has the same pid as the cimserver
211 // daemon process pid stored in the cimserver_start.conf file. Since the
212 // command has the same name as the cimserver daemon process, this could
213 // happen after a system reboot. If the pids are the same, cimserver
214 // isn't really running.
215 //
|
216 kumpf 1.26 Uint32 mypid = System::getPID();
|
217 w.otsuka 1.28 if ((mypid == (unsigned)pid) || ((unsigned)parentPid == (unsigned)pid))
|
218 kumpf 1.21 {
219 return -1;
220 }
|
221 kumpf 1.18 return 0;
222 }
223 #endif
224
|
225 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
226 Boolean isProcRunning(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
235 token = w_getpsent(token, &buf, sizeof(buf));
236 do {
237 token = w_getpsent(token, &buf, sizeof(buf));
238 if (buf.ps_pid==pid) {
239 free(buf.ps_conttyptr);
240 free(buf.ps_pathptr);
241 free(buf.ps_cmdptr);
242 return true;
243 }
244 } while(token>0);
245
246 marek 1.19 free(buf.ps_conttyptr);
247 free(buf.ps_pathptr);
248 free(buf.ps_cmdptr);
249 return false;
250 }
251 #endif
|
252 kumpf 1.18
|
253 kv.le 1.24 #if defined(PEGASUS_OS_AIX)
254
255 /////////////////////////////////////////////////////////////////////////////
256 // NAME : processdata
257 // FUNCTION : it calls subroutine getprocs() to get information
258 // about all processes.
259 /////////////////////////////////////////////////////////////////////////////
260 // ARGUMENTS:
261 // cnt: the number of the processes in the returned table
262 // RETURN VALUES:
263 // when it successfully gets the process table entries,
264 // an array of procsinfo structures filled with process table
265 // entries are returned. Otherewise, a null pointer is
266 // returned.
267 //
268 /////////////////////////////////////////////////////////////////////////////
269 struct procsinfo *processdata(int *cnt)
270 {
271 struct procsinfo *proctable=NULL, *rtnp=NULL;
272 int count=1048576, rtncnt, repeat=1, nextp=0;
273
274 kv.le 1.24 *cnt=0;
275 while ( repeat && (rtncnt=getprocs(rtnp,PROCSIZE,0,0,&nextp, count))>0)
276 {
277 if (!rtnp)
278 {
279 count=rtncnt;
280 proctable=(struct procsinfo *) malloc((size_t) \
281 PROCSIZE*count);
282 if (!proctable)
283 return NULL;
284 rtnp=proctable;
285 nextp=0;
286 } else
287 {
288 *cnt+=rtncnt;
289 if (rtncnt>=count)
290 {
291 proctable=(struct procsinfo *) realloc(\
292 (void*)proctable, (size_t)\
293 (PROCSIZE*(*cnt+count)));
294 if (!proctable)
295 kv.le 1.24 return NULL;
296 rtnp=proctable+(*cnt);
297 } else
298 repeat=0;
299 } // end of if(!rtnp)
300 } //end of while
301 return proctable;
302 }
303
304 /////////////////////////////////////////////////////////////////////////////
305 // NAME : aixcimsrvrunning
306 // FUNCTION : it figures out if the cimserver process is running
307 // by checking the process table entries in the array
308 // returned from processdata(). If the cimserver process is
309 // running and its pid is the same as the pid in the file
310 // CIMSERVER_START_FILE, it will return 0, otherwise it will
311 // return -1.
312 /////////////////////////////////////////////////////////////////////////////
313 // ARGUMENTS:
314 // pid: the process identifier saved in the file
315 // CIMSERVER_START_FILE
316 kv.le 1.24 // RETURN VALUES:
317 // 0: successful
318 // -1: errors
319 //
320 /////////////////////////////////////////////////////////////////////////////
321
322 int aixcimsrvrunning(pid_t pid)
323 {
324 int i,count;
325 struct procsinfo *proctable;
326
327 proctable=processdata(&count);
328 if (proctable==NULL)
329 return -1;
330 for (i=0;i<count;i++)
331 if (!strcmp(proctable[i].pi_comm,"cimserver") && \
332 proctable[i].pi_pid==pid)
333 {
334 free(proctable);
335 return 0;
336 }
337 kv.le 1.24
338 free(proctable);
339 return -1;
340 }
341 #endif
342
|
343 kumpf 1.9 Boolean isCIMServerRunning(void)
344 {
345 FILE *pid_file;
346 pid_t pid = 0;
347
348 // open the file containing the CIMServer process ID
|
349 marek 1.19 pid_file = fopen(CIMSERVER_START_FILE, "r");
|
350 kumpf 1.9 if (!pid_file)
351 {
352 return false;
353 }
354
355 // get the pid from the file
|
356 kumpf 1.17 fscanf(pid_file, "%d\n", &pid);
357
358 fclose(pid_file);
|
359 kumpf 1.9
360 if (pid == 0)
361 {
362 return false;
363 }
364
365 //
366 // check to see if cimserver process is alive
367 //
368 #if defined(PEGASUS_OS_HPUX)
369 struct pst_status pstru;
370
|
371 kumpf 1.17 int ret_code;
372 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
373
374 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
|
375 kumpf 1.9 {
|
376 kumpf 1.21 //
377 // Check to see if this command process has the same pid as the
378 // cimserver daemon process pid stored in the cimserver_start.conf
379 // file. Since the command has the same name as the cimserver daemon
380 // process, this could happen after a system reboot. If the pids are
381 // the same, cimserver isn't really running.
382 //
|
383 kumpf 1.26 Uint32 mypid = System::getPID();
384 if ((mypid != pid) && (parentPid != pid))
|
385 kumpf 1.21 {
386 // cimserver is running
387 return true;
388 }
|
389 kumpf 1.9 }
390 #endif
|
391 tony 1.25 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
|
392 kumpf 1.18 if (get_proc(pid) != -1 )
393 {
394 // cimserver is running
395 return true;
396 }
397 #endif
|
398 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
399 return isProcRunning(pid);
400 #endif
|
401 kv.le 1.24 #if defined(PEGASUS_OS_AIX)
402 if (aixcimsrvrunning(pid)!=-1)
403 return true;
404 #endif
|
405 kumpf 1.9 return false;
|
406 kumpf 1.6 }
407
408 int cimserver_kill(void)
409 {
410 FILE *pid_file;
411 pid_t pid = 0;
412
413 // open the file containing the CIMServer process ID
|
414 kumpf 1.18 pid_file = fopen(CIMSERVER_START_FILE, "r");
|
415 kumpf 1.6 if (!pid_file)
416 {
417 return (-1);
418 }
419
420 // get the pid from the file
|
421 kumpf 1.17 fscanf(pid_file, "%d\n", &pid);
422
423 fclose(pid_file);
|
424 kumpf 1.6
425 if (pid == 0)
426 {
|
427 kumpf 1.18 System::removeFile(CIMSERVER_START_FILE);
|
428 kumpf 1.6 return (-1);
429 }
430
431 //
432 // kill the process if it is still alive
433 //
|
434 kumpf 1.7 #if defined(PEGASUS_OS_HPUX)
|
435 kumpf 1.6 struct pst_status pstru;
436
|
437 kumpf 1.17 int ret_code;
438 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
439
440 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
|
441 kumpf 1.6 {
|
442 kumpf 1.17 // cimserver is running, kill the process
|
443 kumpf 1.6 kill(pid, SIGKILL);
444 }
|
445 kumpf 1.7 #endif
|
446 tony 1.25 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
|
447 kumpf 1.18 if (get_proc(pid) != -1 )
448 {
449 kill(pid, SIGKILL);
450 }
451 #endif
|
452 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
453 if (isProcRunning(pid)) {
454 kill(pid, SIGKILL);
455 }
|
456 kv.le 1.24 #endif
457 #if defined(PEGASUS_OS_AIX)
458 if (!aixcimsrvrunning(pid))
459 kill(pid,SIGKILL);
|
460 marek 1.19 #endif
|
461 kumpf 1.6 // remove the file
|
462 kumpf 1.18 System::removeFile(CIMSERVER_START_FILE);
|
463 kumpf 1.6
|
464 mike 1.5 return(0);
465 }
466
|
467 kumpf 1.10 // notify parent process to terminate so user knows that cimserver
468 // is ready to serve CIM requests.
|
469 konrad.r 1.20 void notify_parent(int id)
|
470 kumpf 1.10 {
471 pid_t ppid = getppid();
|
472 konrad.r 1.20 if (id)
473 kill(ppid, SIGTERM);
474 else
475 kill(ppid, PEGASUS_SIGUSR1);
|
476 kumpf 1.10 }
|
477 s.hills 1.22
478
479 // Platform specific run
480 int platform_run( int argc, char** argv, Boolean shutdownOption )
481 {
482 return cimserver_run( argc, argv, shutdownOption );
483 }
484
485 void cimserver_set( CIMServer* s )
486 {
487 }
|
488 tony 1.25
489
490
491
492
|