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

  1 karl  1.43 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.2  //
  3 karl  1.35 // 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 karl  1.29 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.35 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.37 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.43 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.2  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15 chip  1.4  // 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 mike  1.2  // 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 kumpf 1.11 // 
 21 chip  1.4  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 mike  1.2  // 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 chip  1.4  // 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 mike  1.2  // 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 kumpf 1.11 //==============================================================================
 31 mike  1.2  //
 32            //%////////////////////////////////////////////////////////////////////////////
 33            
 34            
 35            /////////////////////////////////////////////////////////////////////////////
 36 chip  1.4  //  ShutdownService
 37 mike  1.2  /////////////////////////////////////////////////////////////////////////////
 38            
 39            #include <Pegasus/Common/Config.h>
 40            #include <Pegasus/Server/ShutdownExceptions.h>
 41            #include <Pegasus/Server/CIMServerState.h>
 42            #include <Pegasus/Server/ShutdownService.h>
 43 kumpf 1.8  #include <Pegasus/Common/XmlWriter.h>
 44            #include <Pegasus/Common/Message.h>
 45            #include <Pegasus/Common/CimomMessage.h>
 46            #include <Pegasus/Common/CIMMessage.h>
 47            #include <Pegasus/Common/MessageQueueService.h>
 48 kumpf 1.12 #include <Pegasus/Common/Tracer.h>
 49 kumpf 1.50 
 50 mday  1.20 #if defined(PEGASUS_OS_TYPE_UNIX)
 51 kumpf 1.50 # include <sys/types.h>
 52 mday  1.20 #endif
 53 humberto 1.22 
 54 mike     1.2  PEGASUS_USING_STD;
 55               
 56               PEGASUS_NAMESPACE_BEGIN
 57               
 58               /**
 59 kumpf    1.8      The constant representing the shutdown timeout property name
 60 mike     1.2  */
 61               static String SHUTDOWN_TIMEOUT_PROPERTY = "shutdownTimeout";
 62               
 63 chip     1.4  /**
 64 kumpf    1.50     Initialize ShutdownService instance
 65 mike     1.2  */
 66               ShutdownService* ShutdownService::_instance = 0;
 67               
 68 chip     1.4  /**
 69 kumpf    1.50     Initialize all other class variables
 70 kumpf    1.3  */
 71 kumpf    1.50 CIMServer* ShutdownService::_cimserver = 0;
 72               Uint32 ShutdownService::_shutdownTimeout = 0;
 73               ModuleController* ShutdownService::_controller = 0;
 74 kumpf    1.3  
 75 mike     1.2  /** Constructor. */
 76 kumpf    1.5  ShutdownService::ShutdownService(CIMServer* cimserver)
 77 mike     1.2  {
 78 kumpf    1.5      _cimserver = cimserver;
 79 kumpf    1.8  
 80                   //
 81                   // get module controller
 82                   //
 83 kumpf    1.47     _controller = ModuleController::getModuleController();
 84 mike     1.2  }
 85 kumpf    1.50 
 86 konrad.r 1.40 /**
 87 kumpf    1.50     Terminates the shutdown service
 88 konrad.r 1.40 */
 89 kumpf    1.50 void ShutdownService::destroy()
 90 konrad.r 1.40 {
 91 kumpf    1.45     delete _instance;
 92                   _instance = 0;
 93 konrad.r 1.40 }
 94 kumpf    1.50 
 95 mike     1.2  /** Destructor. */
 96               ShutdownService::~ShutdownService()
 97               {
 98               }
 99               
100 chip     1.4  /**
101 kumpf    1.50    return a pointer to the ShutdownService instance.
102 mike     1.2  */
103 kumpf    1.5  ShutdownService* ShutdownService::getInstance(CIMServer* cimserver)
104 mike     1.2  {
105 chip     1.4      if (!_instance)
106 mike     1.2      {
107 kumpf    1.5          _instance = new ShutdownService(cimserver);
108 mike     1.2      }
109                   return _instance;
110               }
111               
112 chip     1.4  /**
113                   The shutdown method to be called by the ShutdownProvider to
114 thilo.boehm 1.51     process a shutdown request from the cimcli client.
115 mike        1.2  */
116 kumpf       1.18 void ShutdownService::shutdown(
117                      Boolean force,
118                      Uint32 timeout,
119                      Boolean requestPending)
120 mike        1.2  {
121 kumpf       1.23     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdown");
122 kumpf       1.12 
123 mike        1.2      //
124                      // Initialize variables
125                      //
126                      Boolean timeoutExpired = false;
127                      Boolean noMoreRequests = false;
128                  
129 kumpf       1.12     _shutdownTimeout = timeout;
130                  
131 kumpf       1.8      try
132 mike        1.2      {
133 kumpf       1.8          //
134                          // set CIMServer state to TERMINATING
135                          //
136                          _cimserver->setState(CIMServerState::TERMINATING);
137                  
138 kumpf       1.50         Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
139                              "ShutdownService::shutdown - CIM server state set to "
140                                  "CIMServerState::TERMINATING");
141 david       1.19 
142 kumpf       1.8          //
143                          // Tell the CIMServer to stop accepting new client connection requests.
144                          //
145                          _cimserver->stopClientConnection();
146                  
147 david       1.19 
148 kumpf       1.50         Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
149                              "ShutdownService::shutdown - No longer accepting new client "
150                                  "connection requests.");
151 david       1.19 
152 kumpf       1.8          //
153                          // Determine if there are any outstanding CIM operation requests
154                          // (take into account that one of the request is the shutdown request).
155                          //
156                          Uint32 requestCount = _cimserver->getOutstandingRequestCount();
157 kumpf       1.18         if (requestCount > (requestPending ? 1 : 0))
158 kumpf       1.8          {
159 david       1.19 
160 kumpf       1.50             Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
161                                  "ShutdownService::shutdown - Waiting for outstanding CIM "
162                                      "operations to complete.  Request count: $0",
163                                  requestCount);
164 konrad.r    1.39             noMoreRequests = waitUntilNoMoreRequests(requestPending);
165 kumpf       1.8          }
166                          else
167                          {
168                              noMoreRequests = true;
169                          }
170                  
171 kumpf       1.50         Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
172                              "ShutdownService::shutdown - All outstanding CIM operations "
173                                  "complete");
174 david       1.19 
175 kumpf       1.8          //
176                          // proceed to shutdown the CIMServer
177                          //
178                          _shutdownCIMServer();
179 mike        1.2      }
180 kumpf       1.50     catch (CIMException& e)
181 mike        1.2      {
182 kumpf       1.23         PEG_TRACE_STRING(TRC_SHUTDOWN, Tracer::LEVEL4,
183 kumpf       1.12             "Error occurred during CIMServer shutdown: " + e.getMessage());
184 mike        1.2      }
185 kumpf       1.50     catch (Exception& e)
186 mike        1.2      {
187 kumpf       1.23         PEG_TRACE_STRING(TRC_SHUTDOWN, Tracer::LEVEL4,
188 kumpf       1.12             "Error occurred during CIMServer shutdown: " + e.getMessage());
189 mike        1.2      }
190 kumpf       1.50     catch (...)
191 kumpf       1.9      {
192 marek       1.53         PEG_TRACE_CSTRING(TRC_SHUTDOWN, Tracer::LEVEL4,
193 carolann.graves 1.42             "Unexpected error occurred during CIMServer shutdown. ");
194 kumpf           1.9      }
195                      
196 mike            1.2      //
197                          // All done
198                          //
199 kumpf           1.12     PEG_METHOD_EXIT();
200 mike            1.2  }
201                      
202                      /**********************************************************/
203                      /*  private methods                                       */
204                      /**********************************************************/
205                      
206 kumpf           1.12 void ShutdownService::_shutdownCIMServer()
207 mike            1.2  {
208 kumpf           1.23     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::_shutdownCIMServer");
209 mike            1.2  
210 chip            1.4      //
211 kumpf           1.9      // Shutdown the providers
212 mike            1.2      //
213 mday            1.24 
214 kumpf           1.9      _shutdownProviders();
215 mike            1.2  
216 david           1.19     Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
217 kumpf           1.50         "ShutdownService::_shutdownCIMServer - CIM server provider shutdown "
218                                  "complete");
219 david           1.19 
220 chip            1.4      //
221 kumpf           1.50     // Send a shutdown signal to the CIMServer. CIMServer itself will take
222                          // care of shutting down the CimomServices and deleting them. In other
223                          // words, _DO_ _NOT_ call 'shutdownCimomServices' from a provider.
224 mike            1.2      //
225 konrad.r        1.39     _cimserver->shutdown();
226 chip            1.4  
227 david           1.19     Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
228 kumpf           1.50         "ShutdownService::_shutdownCIMServer - Cimom services shutdown "
229                                  "complete");
230 david           1.19 
231 kumpf           1.12     PEG_METHOD_EXIT();
232 mike            1.2  }
233                      
234 konrad.r        1.39 void ShutdownService::shutdownCimomServices()
235 mike            1.2  {
236 carolann.graves 1.42     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdownCimomServices");
237 kumpf           1.12 
238 chip            1.4      //
239 kumpf           1.8      // Shutdown the Indication Service
240                          //
241                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDICATIONSERVICE);
242                      
243                          // Shutdown the Indication Handler Service
244                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDHANDLERMANAGER);
245                      
246 konrad.r        1.39     // PEGASUS_QUEUENAME_OPRESPENCODER
247                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPRESPENCODER);
248                      
249                          // PEGASUS_QUEUENAME_EXPORTRESPENCODER
250                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTRESPENCODER);
251 kumpf           1.50 
252 kumpf           1.8      //
253                          // shutdown  Authenticator Delegator Service
254                          //
255                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_HTTPAUTHDELEGATOR);
256                      
257                          //
258                          // shutdown  CIM Operation Request Authorizer Service
259                          //
260                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPREQAUTHORIZER);
261                      
262                          //
263                          // shutdown  CIM Operation Request Decoder Service
264                          //
265                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPREQDECODER);
266                      
267                      
268                          //
269                          // shutdown  CIM Export Request Decoder Service
270                          //
271                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTREQDECODER);
272                      
273 mike            1.2      //
274 kumpf           1.8      // shutdown  CIM Export Request Dispatcher Service
275                          //
276                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER);
277                      
278 kumpf           1.50     //
279                          // shutdown binary message handler
280 mday            1.20     //
281                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_BINARY_HANDLER);
282 kumpf           1.50 
283 mday            1.24     //
284                          // shutdown  CIM Operation Request Dispatcher Service
285                          //
286                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPREQDISPATCHER);
287                      
288 konrad.r        1.39     // shutdown CIM Provider Manager
289                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
290                      
291                          // shutdown ModuleController also called ControlService.
292                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_CONTROLSERVICE);
293 mday            1.20 
294 kumpf           1.12     PEG_METHOD_EXIT();
295 kumpf           1.8  }
296                      
297 kumpf           1.50 void ShutdownService::_sendShutdownRequestToService(const char* serviceName)
298 kumpf           1.8  {
299 kumpf           1.50     MessageQueueService* _mqs = static_cast<MessageQueueService*>(_controller);
300                      
301                          Array<Uint32> _services;
302                          Uint32 _queueId;
303 kumpf           1.8  
304 kumpf           1.50     _mqs->find_services(String(serviceName), 0, 0, &_services);
305                      
306                          if (_services.size() == 0 )
307                          {
308                              // service not found, just return
309                              return;
310                          }
311                          _queueId = _services[0];
312                      
313                          // send a Stop (this is a legacy message that in some of the MQS does
314                          // termination of its internal stuff. Then follow it with a Stop (to
315                          // open up its incoming queue), and then with a AsyncIoctl::IO_CLOSE
316                          // which closes the incoming queue.
317                      
318                          // All of these messages MUST be sequential. Do not use SendForget or
319                          // SendAsync as those are asynchronous and their receipt is guaranteed
320                          // to be undeterministic and possibly out of sequence (which is something
321                          // we do not want).
322 konrad.r        1.39 
323 kumpf           1.46     CimServiceStop stop_message(
324 kumpf           1.50         NULL,
325                              _queueId,
326                              _controller->getQueueId(),
327                              true);
328                      
329 kumpf           1.47     AutoPtr<AsyncReply> StopAsyncReply(
330                              _controller->ClientSendWait(_queueId, &stop_message));
331 mday            1.26 
332 kumpf           1.46     CimServiceStart start_message(
333 kumpf           1.50         NULL,
334                              _queueId,
335                              _controller->getQueueId(),
336                              true);
337 mday            1.26 
338 kumpf           1.47     AutoPtr <AsyncReply> StartAsyncReply(
339                              _controller->ClientSendWait(_queueId, &start_message));
340 kumpf           1.8  
341 kumpf           1.46     AsyncIoctl close_request(
342 kumpf           1.50         NULL,
343                              _queueId,
344                              _controller->getQueueId(),
345                              false,
346                              AsyncIoctl::IO_CLOSE,
347                              0,
348                              0);
349 kumpf           1.8  
350 kumpf           1.47     AutoPtr <AsyncReply> CloseAsyncReply(
351                              _controller->ClientSendWait(_queueId, &close_request));
352 mike            1.2  }
353                      
354                      void ShutdownService::_shutdownProviders()
355                      {
356 kumpf           1.23     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::_shutdownProviders");
357 kumpf           1.12 
358 kumpf           1.8      //
359                          // get provider manager service
360                          //
361 kumpf           1.50     MessageQueue* queue =
362 kumpf           1.8          MessageQueue::lookup(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
363                      
364                          if (queue == 0)
365 kumpf           1.12     {
366                              PEG_METHOD_EXIT();
367 kumpf           1.8          return;
368 kumpf           1.12     }
369 kumpf           1.8  
370 kumpf           1.50     MessageQueueService* _service = dynamic_cast<MessageQueueService*>(queue);
371 kumpf           1.52     PEGASUS_ASSERT(_service != 0);
372 kumpf           1.8      Uint32 _queueId = _service->getQueueId();
373                      
374 kumpf           1.50     //
375 kumpf           1.8      // create stop all providers request
376                          //
377 kumpf           1.50     CIMStopAllProvidersRequestMessage* stopRequest =
378                              new CIMStopAllProvidersRequestMessage(
379                                  XmlWriter::getNextMessageId(),
380                                  QueueIdStack(_queueId));
381 mike            1.2  
382                          //
383 kumpf           1.8      // create async request message
384 mike            1.2      //
385 kumpf           1.50     AsyncLegacyOperationStart* asyncRequest =
386                              new AsyncLegacyOperationStart(
387 kumpf           1.8              NULL,
388                                  _queueId,
389                                  stopRequest,
390                                  _queueId);
391                      
392 kumpf           1.50     // Use SendWait, which is serialized and waits. Do not use asynchronous
393                          // callback as the response might be received _after_ the provider or
394                          // this service has been deleted.
395                      
396                          AsyncReply* asyncReply =
397                              _controller->ClientSendWait(_queueId, asyncRequest);
398                          CIMStopAllProvidersResponseMessage* response =
399                             reinterpret_cast<CIMStopAllProvidersResponseMessage*>(
400                               (static_cast<AsyncLegacyOperationResult*>(asyncReply))->get_result());
401 kumpf           1.8  
402                          if (response->cimException.getCode() != CIM_ERR_SUCCESS)
403                          {
404 kumpf           1.50         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
405                                  "Server.ShutdownService.CIM_PROVIDER_SHUTDOWN",
406                                  "$0 - CIM provider shutdown exception has occurred.",
407                                  "ShutdownService::_shutdownProviders");
408 humberto        1.22 
409 kumpf           1.8          CIMException e = response->cimException;
410                              delete asyncRequest;
411                              delete asyncReply;
412                              delete response;
413 kumpf           1.12         PEG_METHOD_EXIT();
414 kumpf           1.50         throw e;
415 kumpf           1.8      }
416                      
417                          delete asyncRequest;
418                          delete asyncReply;
419                          delete response;
420                      
421 kumpf           1.12     PEG_METHOD_EXIT();
422 kumpf           1.8  }
423                      
424 konrad.r        1.39 Boolean ShutdownService::waitUntilNoMoreRequests(Boolean requestPending)
425 kumpf           1.8  {
426                          Uint32 maxWaitTime = _shutdownTimeout;  // maximum wait time in seconds
427                          Uint32 waitInterval = 1;                // one second wait interval
428                      
429                          Uint32 requestCount = _cimserver->getOutstandingRequestCount();
430                      
431                          //
432                          // Loop and wait one second until either there is no more requests
433                          // or until timeout expires.
434                          //
435 kumpf           1.50     while (requestCount > (requestPending ? 1 : 0) && maxWaitTime > 0)
436 kumpf           1.8      {
437 kumpf           1.50         Threads::sleep(waitInterval * 1000);
438                              maxWaitTime -= waitInterval;
439                              requestCount = _cimserver->getOutstandingRequestCount();
440                          }
441 kumpf           1.8  
442                          if (requestCount > 1)
443                              return false;
444                          else
445                              return true;
446 mike            1.2  }
447                      
448                      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2