1 mike 1.1.2.1 //%2006////////////////////////////////////////////////////////////////////////
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 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.1.2.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/Constants.h>
36 #include <Pegasus/Common/System.h>
37 #include <Pegasus/Client/CIMClient.h>
|
38 mike 1.1.2.5 #include <Executor/Defines.h>
|
39 mike 1.1.2.1 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/signal.h>
42 #include <unistd.h>
43
|
44 mike 1.1.2.3 #if defined(PEGASUS_OS_HPUX)
45 # include <sys/pstat.h>
46 #endif
47
|
48 mike 1.1.2.1 #define PEGASUS_BUFFER_SIZE 1024
49
50 #ifdef PEGASUS_ENABLE_PRIVILEGE_SEPARATION
51 # define PEGASUS_PROCESS_NAME "cimservermain"
52 #else
53 # define PEGASUS_PROCESS_NAME "cimserver"
54 #endif
55
56 PEGASUS_USING_PEGASUS;
57 PEGASUS_USING_STD;
58
59 const char* arg0;
60
61 //==============================================================================
62 //
63 // _getProcessName()
64 //
65 //==============================================================================
66
67 #if defined(PEGASUS_OS_HPUX)
68
69 mike 1.1.2.1 static int _getProcessName(int pid, char name[PEGASUS_BUFFER_SIZE])
70 {
71 struct pst_status psts;
72
73 if (pstat_getproc(&psts, sizeof(psts), 0, pid) == -1)
74 return -1;
75
76 name[0] = '\0';
|
77 kumpf 1.1.2.8 strncat(name, psts.pst_ucomm, PEGASUS_BUFFER_SIZE);
|
78 mike 1.1.2.1
79 return 0;
80 }
81
82 #elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
83
84 static int _getProcessName(int pid, char name[PEGASUS_BUFFER_SIZE])
85 {
86 // Read the process name from the file.
87
88 static char buffer[1024];
89 sprintf(buffer, "/proc/%d/stat", pid);
90 FILE* is = fopen(buffer, "r");
91
92
93 if (!is)
94 return -1;
95
96 // Read the first line of the file.
97
98 if (fgets(buffer, sizeof(buffer), is) == NULL)
99 mike 1.1.2.1 {
100 fclose(is);
101 return -1;
102 }
103
104 fclose(is);
105
106 // Extract the PID enclosed in parentheses.
107
108 const char* start = strchr(buffer, '(');
109
110 if (!start)
111 return -1;
112
113 start++;
114
115 const char* end = strchr(start, ')');
116
117 if (!end)
118 return -1;
119
120 mike 1.1.2.1 if (start == end)
121 return -1;
122
123 name[0] = '\0';
124 strncat(name, start, end - start);
125
126 return 0;
127 }
128
129 #else
130 # error "not implemented on this platform."
131 #endif /* PEGASUS_PLATFORM_LINUX_GENERIC_GNU */
132
133 //==============================================================================
134 //
135 // _readPidFile()
136 //
137 //==============================================================================
138
139 static int _readPidFile(const char* path, int& pid)
140 {
141 mike 1.1.2.1 FILE* is = fopen(path, "r");
142
143 if (!is)
144 return -1;
145
146 pid = 0;
147
148 fscanf(is, "%d\n", &pid);
149 fclose(is);
150
151 if (pid == 0)
152 return -1;
153
154 return 0;
155 }
156
157 //==============================================================================
158 //
159 // _killCimServer()
160 //
161 // Kill the CIM server. Obtain the PID of the server from the PID file.
162 mike 1.1.2.1 //
163 //==============================================================================
164
|
165 mike 1.1.2.7 static int _killCimServer()
|
166 mike 1.1.2.1 {
167 // Read the PID from the PID file.
168
169 int pid;
170
171 if (_readPidFile(PEGASUS_CIMSERVER_START_FILE, pid) != 0)
172 return -1;
173
174 // Kill the cimserver process:
175
176 char name[PEGASUS_BUFFER_SIZE];
177
178 if (_getProcessName(pid, name) != 0)
179 return -1;
180
181 if (strcmp(name, PEGASUS_PROCESS_NAME) != 0)
182 return -1;
183
184 kill(pid, SIGKILL);
185
186 return 0;
187 mike 1.1.2.1 }
188
189 //==============================================================================
190 //
|
191 mike 1.1.2.2 // _waitForTerminationOrTimeout()
|
192 mike 1.1.2.1 //
193 // Kill the CIM server. Obtain the PID of the server from the PID file.
194 //
195 //==============================================================================
196
197 static void _waitForTerminationOrTimeout(Uint32 timeout)
198 {
199 bool running = true;
200
201 for (; running && timeout; timeout--)
202 {
203 // If PID file disappeared, process no longer running.
204
205 int pid;
206
207 if (_readPidFile(PEGASUS_CIMSERVER_START_FILE, pid) != 0)
208 {
209 running = false;
210 break;
211 }
212
213 mike 1.1.2.1 // If process name changed, process no longer running.
214
215 char name[PEGASUS_BUFFER_SIZE];
216
217 if (_getProcessName(pid, name) != 0 ||
218 strcmp(name, PEGASUS_PROCESS_NAME) != 0)
219 {
220 running = false;
221 break;
222 }
223
224 sleep(1);
225 }
226 while (0);
227
228 if (running)
229 {
230 if (_killCimServer() == 0)
231 {
232 cerr << "Timeout expired forced shutdown initiated" << endl;
233 }
234 mike 1.1.2.1 }
235 }
236
237 //==============================================================================
238 //
|
239 mike 1.1.2.2 // _shutdownCimServer()
|
240 mike 1.1.2.1 //
241 //==============================================================================
242
|
243 mike 1.1.2.2 static void _shutdownCimServer(Uint32 timeout)
|
244 mike 1.1.2.1 {
245 // Connect locally to CIM server.
246
247 CIMClient client;
248
249 try
250 {
251 client.connectLocal();
252 client.setTimeout(2000);
253 }
254 catch(Exception& e)
255 {
256 cerr << "Unable to connect to CIM Server." << endl;
257 cerr << "CIM Server may not be running." << endl;
258 exit(0);
259 }
260
261 // Invoke extrinsic PG_ShutdownService.shutdown() method.
262
263 try
264 {
265 mike 1.1.2.1 String referenceStr = "//";
266 referenceStr.append(System::getHostName());
267 referenceStr.append("/");
268 referenceStr.append(PEGASUS_NAMESPACENAME_SHUTDOWN.getString());
269 referenceStr.append(":");
270 referenceStr.append(PEGASUS_CLASSNAME_SHUTDOWN.getString());
271 CIMObjectPath reference(referenceStr);
272
273 Array<CIMParamValue> inParams;
274 inParams.append(CIMParamValue("force", CIMValue(Boolean(true))));
275
276 inParams.append(CIMParamValue("timeout", CIMValue(Uint32(timeout))));
277 Array<CIMParamValue> outParams;
278
279 CIMValue retValue = client.invokeMethod(
280 PEGASUS_NAMESPACENAME_SHUTDOWN,
281 reference,
282 "shutdown",
283 inParams,
284 outParams);
285 }
286 mike 1.1.2.1 catch(CIMException& e)
287 {
288 cerr << arg0 << "Error in server shutdown: ";
289
290 if (e.getCode() == CIM_ERR_INVALID_NAMESPACE)
291 cerr << "The repository may be empty." << endl;
292 else
293 cerr << e.getMessage() << endl;
294
295 if (_killCimServer() != 0)
296 cerr << arg0 << ": failed to kill CIM server" << endl;
297 }
298 catch(Exception& e)
299 {
300 _waitForTerminationOrTimeout(timeout - 2);
301 }
302
303 _waitForTerminationOrTimeout(timeout);
304
305 cerr << "CIM Server stopped." << endl;
306 }
307 mike 1.1.2.1
308 int main(int argc, char** argv)
309 {
310 arg0 = argv[0];
311
|
312 mike 1.1.2.6 // Check arguments.
313
314 if (argc != 1 && argc != 2)
|
315 mike 1.1.2.4 {
|
316 mike 1.1.2.6 fprintf(stderr, "Usage: %s [shutdown-timeout-in-seconds]\n", argv[0]);
317 fprintf(stderr, "%s is an internal OpenPegasus program. "
318 "Please do not invoke directly.\n", argv[0]);
|
319 mike 1.1.2.4 exit(1);
320 }
321
|
322 mike 1.1.2.6 // Extract timeout argument.
323
324 Uint32 timeout = 5;
325
326 if (argc == 2)
327 {
328 char* end;
329 timeout = (Uint32)strtoul(argv[1], &end, 0);
330
331 if (*end != '\0' || timeout == 0)
332 {
333 fprintf(stderr,
334 "%s: bad timeout argument: \"%s\"\n", argv[0], argv[1]);
335 exit(1);
336 }
337 }
338
339 // Shutdown.
340
341 _shutdownCimServer(timeout);
|
342 mike 1.1.2.1 }
|