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