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

  1 martin 1.63 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.64 //
  3 martin 1.63 // Licensed to The Open Group (TOG) under one or more contributor license
  4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5             // this work for additional information regarding copyright ownership.
  6             // Each contributor licenses this file to you under the OpenPegasus Open
  7             // Source License; you may not use this file except in compliance with the
  8             // License.
  9 martin 1.64 //
 10 martin 1.63 // Permission is hereby granted, free of charge, to any person obtaining a
 11             // copy of this software and associated documentation files (the "Software"),
 12             // to deal in the Software without restriction, including without limitation
 13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14             // and/or sell copies of the Software, and to permit persons to whom the
 15             // Software is furnished to do so, subject to the following conditions:
 16 martin 1.64 //
 17 martin 1.63 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.64 //
 20 martin 1.63 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.64 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.63 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 martin 1.64 //
 28 martin 1.63 //////////////////////////////////////////////////////////////////////////
 29 mike   1.2  //
 30             //%////////////////////////////////////////////////////////////////////////////
 31             
 32             
 33             /////////////////////////////////////////////////////////////////////////////
 34 chip   1.4  //  ShutdownService
 35 mike   1.2  /////////////////////////////////////////////////////////////////////////////
 36             
 37             #include <Pegasus/Common/Config.h>
 38             #include <Pegasus/Server/ShutdownExceptions.h>
 39             #include <Pegasus/Server/CIMServerState.h>
 40             #include <Pegasus/Server/ShutdownService.h>
 41 kumpf  1.8  #include <Pegasus/Common/XmlWriter.h>
 42             #include <Pegasus/Common/Message.h>
 43             #include <Pegasus/Common/CimomMessage.h>
 44             #include <Pegasus/Common/CIMMessage.h>
 45             #include <Pegasus/Common/MessageQueueService.h>
 46 kumpf  1.12 #include <Pegasus/Common/Tracer.h>
 47 kumpf  1.50 
 48 mday   1.20 #if defined(PEGASUS_OS_TYPE_UNIX)
 49 kumpf  1.50 # include <sys/types.h>
 50 mday   1.20 #endif
 51 humberto 1.22 
 52 mike     1.2  PEGASUS_USING_STD;
 53               
 54               PEGASUS_NAMESPACE_BEGIN
 55               
 56               /**
 57 kumpf    1.8      The constant representing the shutdown timeout property name
 58 mike     1.2  */
 59               static String SHUTDOWN_TIMEOUT_PROPERTY = "shutdownTimeout";
 60               
 61 chip     1.4  /**
 62 kumpf    1.50     Initialize ShutdownService instance
 63 mike     1.2  */
 64               ShutdownService* ShutdownService::_instance = 0;
 65               
 66 chip     1.4  /**
 67 kumpf    1.50     Initialize all other class variables
 68 kumpf    1.3  */
 69 kumpf    1.50 CIMServer* ShutdownService::_cimserver = 0;
 70               Uint32 ShutdownService::_shutdownTimeout = 0;
 71               ModuleController* ShutdownService::_controller = 0;
 72 kumpf    1.3  
 73 mike     1.2  /** Constructor. */
 74 kumpf    1.5  ShutdownService::ShutdownService(CIMServer* cimserver)
 75 mike     1.2  {
 76 kumpf    1.5      _cimserver = cimserver;
 77 kumpf    1.8  
 78                   //
 79                   // get module controller
 80                   //
 81 kumpf    1.47     _controller = ModuleController::getModuleController();
 82 mike     1.2  }
 83 kumpf    1.50 
 84 konrad.r 1.40 /**
 85 kumpf    1.50     Terminates the shutdown service
 86 konrad.r 1.40 */
 87 kumpf    1.50 void ShutdownService::destroy()
 88 konrad.r 1.40 {
 89 kumpf    1.45     delete _instance;
 90                   _instance = 0;
 91 konrad.r 1.40 }
 92 kumpf    1.50 
 93 mike     1.2  /** Destructor. */
 94               ShutdownService::~ShutdownService()
 95               {
 96               }
 97               
 98 chip     1.4  /**
 99 kumpf    1.50    return a pointer to the ShutdownService instance.
100 mike     1.2  */
101 kumpf    1.5  ShutdownService* ShutdownService::getInstance(CIMServer* cimserver)
102 mike     1.2  {
103 chip     1.4      if (!_instance)
104 mike     1.2      {
105 kumpf    1.5          _instance = new ShutdownService(cimserver);
106 mike     1.2      }
107                   return _instance;
108               }
109               
110 chip     1.4  /**
111                   The shutdown method to be called by the ShutdownProvider to
112 thilo.boehm 1.51     process a shutdown request from the cimcli client.
113 mike        1.2  */
114 kumpf       1.18 void ShutdownService::shutdown(
115                      Boolean force,
116                      Uint32 timeout,
117                      Boolean requestPending)
118 mike        1.2  {
119 kumpf       1.23     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdown");
120 kumpf       1.12 
121                      _shutdownTimeout = timeout;
122                  
123 kumpf       1.8      try
124 mike        1.2      {
125 kumpf       1.8          //
126                          // set CIMServer state to TERMINATING
127                          //
128                          _cimserver->setState(CIMServerState::TERMINATING);
129                  
130 marek       1.55         PEG_TRACE_CSTRING(
131                              TRC_SHUTDOWN,
132 marek       1.56             Tracer::LEVEL4,
133 kumpf       1.50             "ShutdownService::shutdown - CIM server state set to "
134                                  "CIMServerState::TERMINATING");
135 david       1.19 
136 kumpf       1.8          //
137                          // Tell the CIMServer to stop accepting new client connection requests.
138                          //
139                          _cimserver->stopClientConnection();
140                  
141 marek       1.55         PEG_TRACE_CSTRING(
142                              TRC_SHUTDOWN,
143                              Tracer::LEVEL3,
144 kumpf       1.50             "ShutdownService::shutdown - No longer accepting new client "
145                                  "connection requests.");
146 david       1.19 
147 kumpf       1.8          //
148                          // Determine if there are any outstanding CIM operation requests
149                          // (take into account that one of the request is the shutdown request).
150                          //
151 kumpf       1.54         Boolean noMoreRequests = waitUntilNoMoreRequests(requestPending);
152 kumpf       1.8  
153 marek       1.55         PEG_TRACE((
154                              TRC_SHUTDOWN,
155 marek       1.56             Tracer::LEVEL4,
156 kumpf       1.50             "ShutdownService::shutdown - All outstanding CIM operations "
157 marek       1.55                 "complete = %s",
158                              (noMoreRequests) ? "true" : "false"));
159 david       1.19 
160 kumpf       1.8          //
161 kumpf       1.65         // Send a shutdown signal to the CIMServer. CIMServer itself will take
162                          // care of shutting down the CimomServices and deleting them. In other
163                          // words, _DO_ _NOT_ call 'shutdownCimomServices' from a provider.
164 kumpf       1.8          //
165 kumpf       1.65         _cimserver->shutdown();
166                  
167                          PEG_TRACE_CSTRING(TRC_SHUTDOWN, Tracer::LEVEL3,
168                              "ShutdownService::shutdown - CIMServer instructed to shut down.");
169 mike        1.2      }
170 kumpf       1.50     catch (Exception& e)
171 mike        1.2      {
172 thilo.boehm 1.58         PEG_TRACE((TRC_SHUTDOWN, Tracer::LEVEL2,
173                              "Error occurred during CIMServer shutdown: %s",
174                              (const char*)e.getMessage().getCString()));
175 mike        1.2      }
176 kumpf       1.50     catch (...)
177 kumpf       1.9      {
178 marek       1.56         PEG_TRACE_CSTRING(TRC_SHUTDOWN, Tracer::LEVEL2,
179 carolann.graves 1.42             "Unexpected error occurred during CIMServer shutdown. ");
180 kumpf           1.9      }
181                      
182 kumpf           1.12     PEG_METHOD_EXIT();
183 mike            1.2  }
184                      
185                      /**********************************************************/
186                      /*  private methods                                       */
187                      /**********************************************************/
188                      
189 konrad.r        1.39 void ShutdownService::shutdownCimomServices()
190 mike            1.2  {
191 carolann.graves 1.42     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdownCimomServices");
192 kumpf           1.12 
193 chip            1.4      //
194 kumpf           1.8      // Shutdown the Indication Service
195                          //
196                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDICATIONSERVICE);
197                      
198                          // Shutdown the Indication Handler Service
199                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDHANDLERMANAGER);
200                      
201 konrad.r        1.39     // PEGASUS_QUEUENAME_EXPORTRESPENCODER
202                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTRESPENCODER);
203 kumpf           1.50 
204 kumpf           1.8      //
205                          // shutdown  CIM Export Request Dispatcher Service
206                          //
207                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER);
208                      
209 kumpf           1.50     //
210 mday            1.24     // shutdown  CIM Operation Request Dispatcher Service
211                          //
212                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPREQDISPATCHER);
213                      
214 konrad.r        1.39     // shutdown CIM Provider Manager
215                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
216                      
217                          // shutdown ModuleController also called ControlService.
218                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_CONTROLSERVICE);
219 mday            1.20 
220 kumpf           1.12     PEG_METHOD_EXIT();
221 kumpf           1.8  }
222                      
223 kumpf           1.50 void ShutdownService::_sendShutdownRequestToService(const char* serviceName)
224 kumpf           1.8  {
225 kumpf           1.50     MessageQueueService* _mqs = static_cast<MessageQueueService*>(_controller);
226                      
227 venkat.puvvada  1.60     MessageQueue *queue = MessageQueue::lookup(serviceName);
228 kumpf           1.50     Uint32 _queueId;
229 venkat.puvvada  1.60     if (queue)
230                          {
231                              _queueId =  queue->getQueueId();
232                          }
233                          else
234 kumpf           1.50     {
235                              // service not found, just return
236                              return;
237                          }
238                          // send a Stop (this is a legacy message that in some of the MQS does
239                          // termination of its internal stuff. Then follow it with a Stop (to
240 venkat.puvvada  1.62     // open up its incoming queue), and then with a AsyncIoClose
241 kumpf           1.50     // which closes the incoming queue.
242                      
243                          // All of these messages MUST be sequential. Do not use SendForget or
244                          // SendAsync as those are asynchronous and their receipt is guaranteed
245                          // to be undeterministic and possibly out of sequence (which is something
246                          // we do not want).
247 konrad.r        1.39 
248 kumpf           1.46     CimServiceStop stop_message(
249 kumpf           1.50         NULL,
250 venkat.puvvada  1.68         _queueId);
251 kumpf           1.50 
252 kumpf           1.47     AutoPtr<AsyncReply> StopAsyncReply(
253                              _controller->ClientSendWait(_queueId, &stop_message));
254 mday            1.26 
255 kumpf           1.46     CimServiceStart start_message(
256 kumpf           1.50         NULL,
257 venkat.puvvada  1.68         _queueId);
258 mday            1.26 
259 kumpf           1.47     AutoPtr <AsyncReply> StartAsyncReply(
260                              _controller->ClientSendWait(_queueId, &start_message));
261 kumpf           1.8  
262 venkat.puvvada  1.62     AsyncIoClose close_request(
263 kumpf           1.50         NULL,
264 venkat.puvvada  1.68         _queueId);
265 kumpf           1.8  
266 kumpf           1.47     AutoPtr <AsyncReply> CloseAsyncReply(
267                              _controller->ClientSendWait(_queueId, &close_request));
268 mike            1.2  }
269                      
270 kumpf           1.65 void ShutdownService::shutdownProviders()
271 mike            1.2  {
272 kumpf           1.65     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdownProviders");
273 kumpf           1.12 
274 kumpf           1.8      //
275                          // get provider manager service
276                          //
277 kumpf           1.50     MessageQueue* queue =
278 kumpf           1.8          MessageQueue::lookup(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
279                      
280                          if (queue == 0)
281 kumpf           1.12     {
282                              PEG_METHOD_EXIT();
283 kumpf           1.8          return;
284 kumpf           1.12     }
285 kumpf           1.8  
286 kumpf           1.50     MessageQueueService* _service = dynamic_cast<MessageQueueService*>(queue);
287 kumpf           1.52     PEGASUS_ASSERT(_service != 0);
288 kumpf           1.8      Uint32 _queueId = _service->getQueueId();
289                      
290 kumpf           1.50     //
291 kumpf           1.8      // create stop all providers request
292                          //
293 kumpf           1.50     CIMStopAllProvidersRequestMessage* stopRequest =
294                              new CIMStopAllProvidersRequestMessage(
295                                  XmlWriter::getNextMessageId(),
296 venkat.puvvada  1.68.8.1             QueueIdStack(_queueId),
297                                      _shutdownTimeout);
298 mike            1.2      
299                              //
300 kumpf           1.8          // create async request message
301 mike            1.2          //
302 kumpf           1.50         AsyncLegacyOperationStart* asyncRequest =
303                                  new AsyncLegacyOperationStart(
304 kumpf           1.8                  NULL,
305                                      _queueId,
306 venkat.puvvada  1.59                 stopRequest);
307 kumpf           1.8      
308 kumpf           1.50         // Use SendWait, which is serialized and waits. Do not use asynchronous
309                              // callback as the response might be received _after_ the provider or
310                              // this service has been deleted.
311                          
312                              AsyncReply* asyncReply =
313                                  _controller->ClientSendWait(_queueId, asyncRequest);
314                              CIMStopAllProvidersResponseMessage* response =
315                                 reinterpret_cast<CIMStopAllProvidersResponseMessage*>(
316                                   (static_cast<AsyncLegacyOperationResult*>(asyncReply))->get_result());
317 kumpf           1.8      
318                              if (response->cimException.getCode() != CIM_ERR_SUCCESS)
319                              {
320 kumpf           1.50             Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
321 kumpf           1.57                 MessageLoaderParms(
322                                          "Server.ShutdownService.CIM_PROVIDER_SHUTDOWN",
323 kumpf           1.66                     "A provider shutdown exception has occurred: $0",
324                                          response->cimException.getMessage()));
325 kumpf           1.8          }
326                          
327                              delete asyncRequest;
328                              delete asyncReply;
329                              delete response;
330                          
331 kumpf           1.12         PEG_METHOD_EXIT();
332 kumpf           1.8      }
333                          
334 konrad.r        1.39     Boolean ShutdownService::waitUntilNoMoreRequests(Boolean requestPending)
335 kumpf           1.8      {
336 kumpf           1.54         Uint32 waitTime = _shutdownTimeout;    // maximum wait time in seconds
337                              const Uint32 waitInterval = 1;         // one second wait interval
338                              Uint32 requestCount;
339 kumpf           1.8      
340                              //
341                              // Loop and wait one second until either there is no more requests
342                              // or until timeout expires.
343                              //
344 kumpf           1.54         while (waitTime > 0)
345 kumpf           1.8          {
346 kumpf           1.54             requestCount = _cimserver->getOutstandingRequestCount();
347                                  if (requestCount <= (requestPending ? 1 : 0))
348                                  {
349                                      return true;
350                                  }
351                          
352 marek           1.55             PEG_TRACE((
353                                      TRC_SHUTDOWN,
354                                      Tracer::LEVEL4,
355 kumpf           1.54                 "ShutdownService waiting for outstanding CIM operations to "
356 marek           1.55                     "complete.  Request count: %d",
357                                      requestCount));
358 kumpf           1.50             Threads::sleep(waitInterval * 1000);
359 kumpf           1.54             waitTime -= waitInterval;
360 kumpf           1.50         }
361 kumpf           1.8      
362 kumpf           1.54         return _cimserver->getOutstandingRequestCount() <= (requestPending ? 1 : 0);
363 mike            1.2      }
364                          
365                          PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2