1 h.sterling 1.1 //%2005////////////////////////////////////////////////////////////////////////
2 //
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 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // 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 // 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 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // 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 h.sterling 1.1 // 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 // 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 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
33 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
34 // Marek Szermutzky, IBM (ddt6szer@de.ibm.com)
35 //%/////////////////////////////////////////////////////////////////////////////
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #if defined(PEGASUS_OS_HPUX)
39 #include <sys/pstat.h>
40 #endif
41 #include <fcntl.h>
42 #include <unistd.h>
43 h.sterling 1.1 #include <Pegasus/Common/Signal.h>
44 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
45 #include <sys/ps.h>
46 #endif
47 #define MAX_WAIT_TIME 25
48 #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
56 PEGASUS_USING_PEGASUS;
57 PEGASUS_USING_STD;
58
59 Boolean handleSigUsr1 = false;
60 Boolean graveError = false;
61
62 pid_t server_pid;
63
64 h.sterling 1.1 void sigUsr1Handler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
65 {
66 handleSigUsr1 = true;
67 }
68
69 void sigTermHandler(int s_n, PEGASUS_SIGINFO_T * s_info, void * sig)
70 {
71 graveError= handleSigUsr1=true;
72 }
73
74
75 //constructor
76 ServerProcess::ServerProcess() {}
77
78 //destructor
79 ServerProcess::~ServerProcess() {}
80
81 // no-ops
82 void ServerProcess::cimserver_set_process(void* p) {}
83 void ServerProcess::cimserver_exitRC(int rc) {}
84 int ServerProcess::cimserver_initialize(void) { return 1; }
85 h.sterling 1.1 int ServerProcess::cimserver_wait(void) { return 1; }
86 String ServerProcess::getHome(void) { return String::EMPTY; }
87
88 // daemon_init , RW Stevens, "Advance UNIX Programming"
89
90 int ServerProcess::cimserver_fork(void)
91 {
92 getSigHandle()->registerHandler(PEGASUS_SIGUSR1, sigUsr1Handler);
93 getSigHandle()->activate(PEGASUS_SIGUSR1);
94 getSigHandle()->registerHandler(SIGTERM, sigTermHandler);
95 getSigHandle()->activate(SIGTERM);
96
97 pid_t pid;
98 if( (pid = fork() ) < 0)
99 {
100 getSigHandle()->deactivate(PEGASUS_SIGUSR1);
101 getSigHandle()->deactivate(SIGTERM);
102 return(-1);
103 }
104 else if (pid != 0)
105 {
106 h.sterling 1.1 //
107 // parent wait for child
108 // if there is a problem with signal, parent process terminates
109 // when waitTime expires
110 //
111 Uint32 waitTime = MAX_WAIT_TIME;
112
113 while(!handleSigUsr1 && waitTime > 0)
114 {
115 sleep(1);
116 waitTime--;
117 }
118 exit(graveError);
119 }
120
121 setsid();
122 umask(0);
123
124 // get the pid of the cimserver process
125 server_pid = getpid();
126 return(0);
127 h.sterling 1.1 }
128
129 long ServerProcess::get_server_pid()
130 {
131 return server_pid;
132 }
133
134 #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
135
136 //===========================================================================
137 // NAME : verify_process_name
138 // DESCRIPTION : Opens the 'stat' file in the /proc/<pid> directory to
139 // verify that the process name is that of the cimserver.
140 //===========================================================================
141 int verify_process_name(char *directory, const char* server_process_name)
142 {
143 static char filename[80];
144 static char buffer[512];
145 int fd, bytesRead;
146
147 // generate the name of the stat file in the process's /proc directory,
148 h.sterling 1.1 // and open it
149 sprintf(filename, "%s/%s", directory, "stat");
150 if ( (fd = open(filename, O_RDONLY, 0)) == -1 )
151 {
152 return -1;
153 }
154
155 // read the contents
156 if ( (bytesRead = read( fd, buffer, (sizeof buffer) - 1 )) <= 0 )
157 {
158 close(fd);
159 return -1;
160 }
161
162 // null terminate the file contents
163 buffer[bytesRead] = 0;
164
165 close(fd);
166
167 // the process name is the second element of the file contents and
168 // is surrounded by parentheses.
169 h.sterling 1.1 //
170 // find the positions of the parentheses in the file contents
171 char * open_paren;
172 char * close_paren;
173
174 open_paren = strchr (buffer, '(');
175 close_paren = strchr (buffer, ')');
176 if (open_paren == NULL || close_paren == NULL || close_paren < open_paren)
177 {
178 return -1;
179 }
180
181 // allocate memory for the result
182 char * process_name;
183 process_name = (char*) malloc(close_paren - open_paren - 1);
184
185 // copy the process name into the result
186 strncpy (process_name, open_paren + 1, close_paren - open_paren -1);
187
188 // strncpy doesn't NULL-terminate the result, so do it here
189 process_name[close_paren - open_paren -1] = '\0';
190 h.sterling 1.1
191 if (strcmp(process_name, server_process_name) != 0)
192 {
193 return -1;
194 }
195
196 return 0;
197 }
198
199 //=============================================================================
200 // NAME : get_proc
201 // DESCRIPTION : get_proc() makes a stat() system call on the directory in
202 // /proc with a name that matches the pid of the cimserver.
203 // It returns 0 if it successfully located the process dir
204 // and verified that the process name matches that of the
205 // cimserver. It returns -1 if it fails to open /proc, or
206 // the cimserver process does not exist.
207 //=============================================================================
208 int ServerProcess::get_proc(int pid)
209 {
210 static char path[32];
211 h.sterling 1.1 static struct stat stat_buff;
212
213 sprintf(path, "/proc/%d", pid);
214 if (stat(path, &stat_buff) == -1) // process stopped running
215 {
216 return -1;
217 }
218
219 // get the process name to make sure it is the cimserver process
220 // ATTN: skip verify for Solaris
221 #if !defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
222 if ((verify_process_name(path, getProcessName())) == -1)
223 {
224 return -1;
225 }
226 #endif
227
228 //
229 // Check to see if this command process has the same pid as the cimserver
230 // daemon process pid stored in the cimserver_start.conf file. Since the
231 // command has the same name as the cimserver daemon process, this could
232 h.sterling 1.1 // happen after a system reboot. If the pids are the same, cimserver
233 // isn't really running.
234 //
235 Uint32 mypid = System::getPID();
236 if ((mypid == (unsigned)pid) || ((unsigned)parentPid == (unsigned)pid))
237 {
238 return -1;
239 }
240 return 0;
241 }
242 #endif
243
244 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
245 Boolean isProcRunning(pid_t pid)
246 {
247 W_PSPROC buf;
248 int token = 0;
249 memset(&buf, 0x00, sizeof(buf));
250 buf.ps_conttyptr =(char *) malloc(buf.ps_conttylen =PS_CONTTYBLEN);
251 buf.ps_pathptr =(char *) malloc(buf.ps_pathlen =PS_PATHBLEN);
252 buf.ps_cmdptr =(char *) malloc(buf.ps_cmdlen =PS_CMDBLEN);
253 h.sterling 1.1
254 token = w_getpsent(token, &buf, sizeof(buf));
255 do {
256 token = w_getpsent(token, &buf, sizeof(buf));
257 if (buf.ps_pid==pid) {
258 free(buf.ps_conttyptr);
259 free(buf.ps_pathptr);
260 free(buf.ps_cmdptr);
261 return true;
262 }
263 } while(token>0);
264
265 free(buf.ps_conttyptr);
266 free(buf.ps_pathptr);
267 free(buf.ps_cmdptr);
268 return false;
269 }
270 #endif
271
272 #if defined(PEGASUS_OS_AIX)
273
274 h.sterling 1.1 /////////////////////////////////////////////////////////////////////////////
275 // NAME : processdata
276 // FUNCTION : it calls subroutine getprocs() to get information
277 // about all processes.
278 /////////////////////////////////////////////////////////////////////////////
279 // ARGUMENTS:
280 // cnt: the number of the processes in the returned table
281 // RETURN VALUES:
282 // when it successfully gets the process table entries,
283 // an array of procsinfo structures filled with process table
284 // entries are returned. Otherewise, a null pointer is
285 // returned.
286 //
287 /////////////////////////////////////////////////////////////////////////////
288 struct procsinfo *processdata(int *cnt)
289 {
290 struct procsinfo *proctable=NULL, *rtnp=NULL;
291 int count=1048576, rtncnt, repeat=1, nextp=0;
292
293 *cnt=0;
294 while ( repeat && (rtncnt=getprocs(rtnp,PROCSIZE,0,0,&nextp, count))>0)
295 h.sterling 1.1 {
296 if (!rtnp)
297 {
298 count=rtncnt;
299 proctable=(struct procsinfo *) malloc((size_t) \
300 PROCSIZE*count);
301 if (!proctable)
302 return NULL;
303 rtnp=proctable;
304 nextp=0;
305 } else
306 {
307 *cnt+=rtncnt;
308 if (rtncnt>=count)
309 {
310 proctable=(struct procsinfo *) realloc(\
311 (void*)proctable, (size_t)\
312 (PROCSIZE*(*cnt+count)));
313 if (!proctable)
314 return NULL;
315 rtnp=proctable+(*cnt);
316 h.sterling 1.1 } else
317 repeat=0;
318 } // end of if(!rtnp)
319 } //end of while
320 return proctable;
321 }
322
323 /////////////////////////////////////////////////////////////////////////////
324 // NAME : aixcimsrvrunning
325 // FUNCTION : it figures out if the cimserver process is running
326 // by checking the process table entries in the array
327 // returned from processdata(). If the cimserver process is
328 // running and its pid is the same as the pid in the file
329 // getPIDFileName(), it will return 0, otherwise it will
330 // return -1.
331 /////////////////////////////////////////////////////////////////////////////
332 // ARGUMENTS:
333 // pid: the process identifier saved in the file
334 // getPIDFileName()
335 // RETURN VALUES:
336 // 0: successful
337 h.sterling 1.1 // -1: errors
338 //
339 /////////////////////////////////////////////////////////////////////////////
340
|