1 mike 1.5 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.8 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.8 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.5 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.8 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.5 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.8 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.5 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Day (mdday@us.ibm.com)
25 //
|
26 kumpf 1.10 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
27 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
|
28 marek 1.19 // Marek Szermutzky, IBM (ddt6szer@de.ibm.com)
|
29 mike 1.5 //%/////////////////////////////////////////////////////////////////////////////
30 #include <sys/types.h>
31 #include <sys/stat.h>
|
32 kumpf 1.7 #if defined(PEGASUS_OS_HPUX)
|
33 kumpf 1.6 #include <sys/pstat.h>
|
34 kumpf 1.7 #endif
|
35 mike 1.5 #include <fcntl.h>
36 #include <unistd.h>
|
37 kumpf 1.16 #include <Pegasus/Common/Signal.h>
|
38 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
39 #include <sys/ps.h>
40 #endif
|
41 kumpf 1.16 #define MAX_WAIT_TIME 25
|
42 kumpf 1.12
|
43 mike 1.5 PEGASUS_USING_PEGASUS;
44 PEGASUS_USING_STD;
|
45 kumpf 1.10
|
46 kumpf 1.16 Boolean handleSigUsr1 = false;
|
47 konrad.r 1.20 Boolean graveError = false;
|
48 mike 1.5 void cim_server_service(int argc, char **argv ) { return; }
49
|
50 kumpf 1.6 pid_t server_pid;
51
|
52 kumpf 1.16 void sigUsr1Handler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
|
53 kumpf 1.10 {
|
54 kumpf 1.16 handleSigUsr1 = true;
|
55 kumpf 1.10 }
56
|
57 konrad.r 1.20 void sigTermHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
58 {
59 graveError= handleSigUsr1=true;
60 }
|
61 mike 1.5 // daemon_init , RW Stevens, "Advance UNIX Programming"
62
63 int cimserver_fork(void)
64 {
|
65 kumpf 1.16 getSigHandle()->registerHandler(PEGASUS_SIGUSR1, sigUsr1Handler);
66 getSigHandle()->activate(PEGASUS_SIGUSR1);
|
67 konrad.r 1.20 getSigHandle()->registerHandler(SIGTERM, sigTermHandler);
68 getSigHandle()->activate(SIGTERM);
|
69 kumpf 1.10
|
70 mike 1.5 pid_t pid;
71 if( (pid = fork() ) < 0)
|
72 kumpf 1.16 {
73 getSigHandle()->deactivate(PEGASUS_SIGUSR1);
|
74 konrad.r 1.20 getSigHandle()->deactivate(SIGTERM);
|
75 kumpf 1.16 return(-1);
76 }
|
77 mike 1.5 else if (pid != 0)
|
78 kumpf 1.10 {
|
79 kumpf 1.16 //
80 // parent wait for child
81 // if there is a problem with signal, parent process terminates
82 // when waitTime expires
83 //
84 Uint32 waitTime = MAX_WAIT_TIME;
|
85 kumpf 1.12
|
86 kumpf 1.16 while(!handleSigUsr1 && waitTime > 0)
87 {
|
88 kumpf 1.12 sleep(1);
|
89 kumpf 1.16 waitTime--;
90 }
|
91 konrad.r 1.20 exit(graveError);
|
92 kumpf 1.10 }
|
93 mike 1.5
94 setsid();
95 umask(0);
|
96 kumpf 1.6
97 // get the pid of the cimserver process
98 server_pid = getpid();
99 return(0);
|
100 kumpf 1.9 }
101
|
102 kumpf 1.18 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
103
104 //===========================================================================
105 // NAME : verify_process_name
106 // DESCRIPTION : Opens the 'stat' file in the /proc/<pid> directory to
107 // verify that the process name is that of the cimserver.
108 //===========================================================================
109 int verify_process_name(char *directory)
110 {
111 static char filename[80];
112 static char buffer[512];
113 int fd, bytesRead;
114
115 // generate the name of the stat file in the process's /proc directory,
116 // and open it
117 sprintf(filename, "%s/%s", directory, "stat");
118 if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
119 {
120 return -1;
121 }
122
123 kumpf 1.18 // read the contents
124 if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
125 {
126 close(fd);
127 return -1;
128 }
129
130 // null terminate the file contents
131 buffer[bytesRead] = 0;
132
133 close(fd);
134
135 // the process name is the second element of the file contents and
136 // is surrounded by parentheses.
137 //
138 // find the positions of the parentheses in the file contents
139 char * open_paren;
140 char * close_paren;
141
142 open_paren = strchr (buffer, '(');
143 close_paren = strchr (buffer, ')');
144 kumpf 1.18 if (open_paren == NULL || close_paren == NULL || close_paren < open_paren)
145 {
146 return -1;
147 }
148
149 // allocate memory for the result
150 char * process_name;
151 process_name = (char*) malloc(close_paren - open_paren - 1);
152
153 // copy the process name into the result
154 strncpy (process_name, open_paren + 1, close_paren - open_paren -1);
155
156 // strncpy doesn't NULL-terminate the result, so do it here
157 process_name[close_paren - open_paren -1] = '\0';
158
159 if (strcmp(process_name, "cimserver") != 0)
160 {
161 return -1;
162 }
163
164 return 0;
165 kumpf 1.18 }
166
167 //=============================================================================
168 // NAME : get_proc
169 // DESCRIPTION : get_proc() makes a stat() system call on the directory in
170 // /proc with a name that matches the pid of the cimserver.
171 // It returns 0 if it successfully located the process dir
172 // and verified that the process name matches that of the
173 // cimserver. It returns -1 if it fails to open /proc, or
174 // the cimserver process does not exist.
175 //=============================================================================
176 int get_proc(int pid)
177 {
178 static char path[32];
179 static struct stat stat_buff;
180
181 sprintf(path, "/proc/%d", pid);
182 if (stat(path, &stat_buff) == -1) // process stopped running
183 {
184 return -1;
185 }
186 kumpf 1.18
187 // get the process name to make sure it is the cimserver process
188 if ((verify_process_name(path)) == -1)
189 {
190 return -1;
191 }
192
|
193 kumpf 1.21 //
194 // Check to see if this command process has the same pid as the cimserver
195 // daemon process pid stored in the cimserver_start.conf file. Since the
196 // command has the same name as the cimserver daemon process, this could
197 // happen after a system reboot. If the pids are the same, cimserver
198 // isn't really running.
199 //
200 pid_t mypid = getpid();
201 if (mypid == pid)
202 {
203 return -1;
204 }
|
205 kumpf 1.18 return 0;
206 }
207 #endif
208
|
209 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
210 Boolean isProcRunning(pid_t pid)
211 {
212 W_PSPROC buf;
213 int token = 0;
214 memset(&buf, 0x00, sizeof(buf));
215 buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
216 buf.ps_pathptr =(char *) malloc(buf.ps_pathlen =PS_PATHBLEN);
217 buf.ps_cmdptr =(char *) malloc(buf.ps_cmdlen =PS_CMDBLEN);
218
219 token = w_getpsent(token, &buf, sizeof(buf));
220 do {
221 token = w_getpsent(token, &buf, sizeof(buf));
222 if (buf.ps_pid==pid) {
223 free(buf.ps_conttyptr);
224 free(buf.ps_pathptr);
225 free(buf.ps_cmdptr);
226 return true;
227 }
228 } while(token>0);
229
230 marek 1.19 free(buf.ps_conttyptr);
231 free(buf.ps_pathptr);
232 free(buf.ps_cmdptr);
233 return false;
234 }
235 #endif
|
236 kumpf 1.18
|
237 kumpf 1.9 Boolean isCIMServerRunning(void)
238 {
239 FILE *pid_file;
240 pid_t pid = 0;
241
242 // open the file containing the CIMServer process ID
|
243 marek 1.19 pid_file = fopen(CIMSERVER_START_FILE, "r");
|
244 kumpf 1.9 if (!pid_file)
245 {
246 return false;
247 }
248
249 // get the pid from the file
|
250 kumpf 1.17 fscanf(pid_file, "%d\n", &pid);
251
252 fclose(pid_file);
|
253 kumpf 1.9
254 if (pid == 0)
255 {
256 return false;
257 }
258
259 //
260 // check to see if cimserver process is alive
261 //
262 #if defined(PEGASUS_OS_HPUX)
263 struct pst_status pstru;
264
|
265 kumpf 1.17 int ret_code;
266 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
267
268 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
|
269 kumpf 1.9 {
|
270 kumpf 1.21 //
271 // Check to see if this command process has the same pid as the
272 // cimserver daemon process pid stored in the cimserver_start.conf
273 // file. Since the command has the same name as the cimserver daemon
274 // process, this could happen after a system reboot. If the pids are
275 // the same, cimserver isn't really running.
276 //
277 pid_t mypid = getpid();
278 if (mypid != pid)
279 {
280 // cimserver is running
281 return true;
282 }
|
283 kumpf 1.9 }
284 #endif
|
285 kumpf 1.18 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
286 if (get_proc(pid) != -1 )
287 {
288 // cimserver is running
289 return true;
290 }
291 #endif
|
292 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
293 return isProcRunning(pid);
294 #endif
|
295 kumpf 1.9 return false;
|
296 kumpf 1.6 }
297
298 int cimserver_kill(void)
299 {
300 FILE *pid_file;
301 pid_t pid = 0;
302
303 // open the file containing the CIMServer process ID
|
304 kumpf 1.18 pid_file = fopen(CIMSERVER_START_FILE, "r");
|
305 kumpf 1.6 if (!pid_file)
306 {
307 return (-1);
308 }
309
310 // get the pid from the file
|
311 kumpf 1.17 fscanf(pid_file, "%d\n", &pid);
312
313 fclose(pid_file);
|
314 kumpf 1.6
315 if (pid == 0)
316 {
|
317 kumpf 1.18 System::removeFile(CIMSERVER_START_FILE);
|
318 kumpf 1.6 return (-1);
319 }
320
321 //
322 // kill the process if it is still alive
323 //
|
324 kumpf 1.7 #if defined(PEGASUS_OS_HPUX)
|
325 kumpf 1.6 struct pst_status pstru;
326
|
327 kumpf 1.17 int ret_code;
328 ret_code = pstat_getproc(&pstru, sizeof(struct pst_status), (size_t)0, pid);
329
330 if ( (ret_code != -1 ) && (strcmp(pstru.pst_ucomm, "cimserver")) == 0)
|
331 kumpf 1.6 {
|
332 kumpf 1.17 // cimserver is running, kill the process
|
333 kumpf 1.6 kill(pid, SIGKILL);
334 }
|
335 kumpf 1.7 #endif
|
336 kumpf 1.18 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
337 if (get_proc(pid) != -1 )
338 {
339 kill(pid, SIGKILL);
340 }
341 #endif
|
342 marek 1.19 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
343 if (isProcRunning(pid)) {
344 kill(pid, SIGKILL);
345 }
346 #endif
|
347 kumpf 1.6 // remove the file
|
348 kumpf 1.18 System::removeFile(CIMSERVER_START_FILE);
|
349 kumpf 1.6
|
350 mike 1.5 return(0);
351 }
352
|
353 kumpf 1.10 // notify parent process to terminate so user knows that cimserver
354 // is ready to serve CIM requests.
|
355 konrad.r 1.20 void notify_parent(int id)
|
356 kumpf 1.10 {
357 pid_t ppid = getppid();
|
358 konrad.r 1.20 if (id)
359 kill(ppid, SIGTERM);
360 else
361 kill(ppid, PEGASUS_SIGUSR1);
|
362 kumpf 1.10 }
|
363 s.hills 1.22
364
365 // Platform specific run
366 int platform_run( int argc, char** argv, Boolean shutdownOption )
367 {
368 return cimserver_run( argc, argv, shutdownOption );
369 }
370
371 void cimserver_set( CIMServer* s )
372 {
373 }
|