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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2