(file) Return to cimshutdown.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Shutdown

  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 }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2