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