(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 dl.meetei   1.74             Tracer::LEVEL4,
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 ashok.pathak 1.73         waitUntilNoMoreRequests(requestPending);
152 david        1.19 
153 kumpf        1.8          //
154 kumpf        1.65         // Send a shutdown signal to the CIMServer. CIMServer itself will take
155                           // care of shutting down the CimomServices and deleting them. In other
156                           // words, _DO_ _NOT_ call 'shutdownCimomServices' from a provider.
157 kumpf        1.8          //
158 kumpf        1.65         _cimserver->shutdown();
159                   
160 dl.meetei    1.74         PEG_TRACE_CSTRING(TRC_SHUTDOWN, Tracer::LEVEL4,
161 kumpf        1.65             "ShutdownService::shutdown - CIMServer instructed to shut down.");
162 mike         1.2      }
163 kumpf        1.50     catch (Exception& e)
164 mike         1.2      {
165 thilo.boehm  1.58         PEG_TRACE((TRC_SHUTDOWN, Tracer::LEVEL2,
166                               "Error occurred during CIMServer shutdown: %s",
167                               (const char*)e.getMessage().getCString()));
168 mike         1.2      }
169 kumpf        1.50     catch (...)
170 kumpf        1.9      {
171 marek        1.56         PEG_TRACE_CSTRING(TRC_SHUTDOWN, Tracer::LEVEL2,
172 carolann.graves 1.42             "Unexpected error occurred during CIMServer shutdown. ");
173 kumpf           1.9      }
174                      
175 kumpf           1.12     PEG_METHOD_EXIT();
176 mike            1.2  }
177                      
178                      /**********************************************************/
179                      /*  private methods                                       */
180                      /**********************************************************/
181                      
182 konrad.r        1.39 void ShutdownService::shutdownCimomServices()
183 mike            1.2  {
184 carolann.graves 1.42     PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::shutdownCimomServices");
185 kumpf           1.12 
186 chip            1.4      //
187 kumpf           1.8      // Shutdown the Indication Service
188                          //
189                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDICATIONSERVICE);
190                      
191                          // Shutdown the Indication Handler Service
192                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_INDHANDLERMANAGER);
193                      
194 konrad.r        1.39     // PEGASUS_QUEUENAME_EXPORTRESPENCODER
195                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTRESPENCODER);
196 kumpf           1.50 
197 kumpf           1.8      //
198                          // shutdown  CIM Export Request Dispatcher Service
199                          //
200                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER);
201                      
202 kumpf           1.50     //
203 mday            1.24     // shutdown  CIM Operation Request Dispatcher Service
204                          //
205                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_OPREQDISPATCHER);
206                      
207 konrad.r        1.39     // shutdown CIM Provider Manager
208                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
209                      
210                          // shutdown ModuleController also called ControlService.
211                          _sendShutdownRequestToService(PEGASUS_QUEUENAME_CONTROLSERVICE);
212 mday            1.20 
213 kumpf           1.12     PEG_METHOD_EXIT();
214 kumpf           1.8  }
215                      
216 kumpf           1.50 void ShutdownService::_sendShutdownRequestToService(const char* serviceName)
217 kumpf           1.8  {
218 venkat.puvvada  1.60     MessageQueue *queue = MessageQueue::lookup(serviceName);
219 kumpf           1.50     Uint32 _queueId;
220 venkat.puvvada  1.60     if (queue)
221                          {
222                              _queueId =  queue->getQueueId();
223                          }
224                          else
225 kumpf           1.50     {
226                              // service not found, just return
227                              return;
228                          }
229                          // send a Stop (this is a legacy message that in some of the MQS does
230                          // termination of its internal stuff. Then follow it with a Stop (to
231 venkat.puvvada  1.62     // open up its incoming queue), and then with a AsyncIoClose
232 kumpf           1.50     // which closes the incoming queue.
233                      
234                          // All of these messages MUST be sequential. Do not use SendForget or
235                          // SendAsync as those are asynchronous and their receipt is guaranteed
236                          // to be undeterministic and possibly out of sequence (which is something
237                          // we do not want).
238 konrad.r        1.39 
239 kumpf           1.46     CimServiceStop stop_message(
240 kumpf           1.50         NULL,
241 venkat.puvvada  1.68         _queueId);
242 kumpf           1.50 
243 kumpf           1.47     AutoPtr<AsyncReply> StopAsyncReply(
244                              _controller->ClientSendWait(_queueId, &stop_message));
245 mday            1.26 
246 kumpf           1.46     CimServiceStart start_message(
247 kumpf           1.50         NULL,
248 venkat.puvvada  1.68         _queueId);
249 mday            1.26 
250 kumpf           1.47     AutoPtr <AsyncReply> StartAsyncReply(
251                              _controller->ClientSendWait(_queueId, &start_message));
252 kumpf           1.8  
253 venkat.puvvada  1.62     AsyncIoClose close_request(
254 kumpf           1.50         NULL,
255 venkat.puvvada  1.68         _queueId);
256 kumpf           1.8  
257 kumpf           1.47     AutoPtr <AsyncReply> CloseAsyncReply(
258                              _controller->ClientSendWait(_queueId, &close_request));
259 mike            1.2  }
260                      
261 kumpf           1.65 void ShutdownService::shutdownProviders()
262 mike            1.2  {
263 venkat.puvvada  1.71     _shutdownProviders(true);
264                          _shutdownProviders(false);
265                      }
266                      
267                      void ShutdownService::_shutdownProviders(Boolean controlProviders)
268                      {
269                          PEG_METHOD_ENTER(TRC_SHUTDOWN, "ShutdownService::_shutdownProviders");
270 kumpf           1.12 
271 kumpf           1.8      //
272 venkat.puvvada  1.71     // get provider manager service or control service
273 kumpf           1.8      //
274 kumpf           1.50     MessageQueue* queue =
275 venkat.puvvada  1.71         controlProviders ?
276                                  MessageQueue::lookup(PEGASUS_QUEUENAME_CONTROLSERVICE) :
277                                  MessageQueue::lookup(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
278 kumpf           1.8  
279                          if (queue == 0)
280 kumpf           1.12     {
281                              PEG_METHOD_EXIT();
282 kumpf           1.8          return;
283 kumpf           1.12     }
284 kumpf           1.8  
285 kumpf           1.50     MessageQueueService* _service = dynamic_cast<MessageQueueService*>(queue);
286 kumpf           1.52     PEGASUS_ASSERT(_service != 0);
287 kumpf           1.8      Uint32 _queueId = _service->getQueueId();
288                      
289 kumpf           1.50     //
290 kumpf           1.8      // create stop all providers request
291                          //
292 kumpf           1.50     CIMStopAllProvidersRequestMessage* stopRequest =
293                              new CIMStopAllProvidersRequestMessage(
294                                  XmlWriter::getNextMessageId(),
295 venkat.puvvada  1.70             QueueIdStack(_queueId),
296                                  _shutdownTimeout);
297 mike            1.2  
298                          //
299 kumpf           1.8      // create async request message
300 mike            1.2      //
301 venkat.puvvada  1.71     AsyncRequest *asyncRequest;
302                      
303                          if (controlProviders)
304                          {
305                              asyncRequest = new AsyncModuleOperationStart(
306                                 0,
307                                 _queueId,
308                                 String(),
309                                 stopRequest);
310                          }
311                          else
312                          {
313                              asyncRequest = new AsyncLegacyOperationStart(
314                                  0,
315 kumpf           1.8              _queueId,
316 venkat.puvvada  1.59             stopRequest);
317 venkat.puvvada  1.71     }
318                      
319 kumpf           1.8  
320 kumpf           1.50     // Use SendWait, which is serialized and waits. Do not use asynchronous
321                          // callback as the response might be received _after_ the provider or
322                          // this service has been deleted.
323                      
324                          AsyncReply* asyncReply =
325                              _controller->ClientSendWait(_queueId, asyncRequest);
326 venkat.puvvada  1.71 
327                      
328                          MessageType msgType = asyncReply->getType();
329                          PEGASUS_ASSERT((msgType == ASYNC_ASYNC_LEGACY_OP_RESULT) ||
330                              (msgType == ASYNC_ASYNC_MODULE_OP_RESULT));
331                      
332                          CIMStopAllProvidersResponseMessage *response;
333                      
334                          if (msgType == ASYNC_ASYNC_LEGACY_OP_RESULT)
335                          {
336                              response = reinterpret_cast<CIMStopAllProvidersResponseMessage *>(
337                                  (static_cast<AsyncLegacyOperationResult *>(
338                                      asyncReply))->get_result());
339                          }
340                          else
341                          {
342                              response = reinterpret_cast<CIMStopAllProvidersResponseMessage*>(
343                                  (static_cast<AsyncModuleOperationResult *>(
344                                      asyncReply))->get_result());
345                          }
346 kumpf           1.8  
347                          if (response->cimException.getCode() != CIM_ERR_SUCCESS)
348                          {
349 kumpf           1.50         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
350 kumpf           1.57             MessageLoaderParms(
351                                      "Server.ShutdownService.CIM_PROVIDER_SHUTDOWN",
352 kumpf           1.66                 "A provider shutdown exception has occurred: $0",
353                                      response->cimException.getMessage()));
354 kumpf           1.8      }
355                      
356                          delete asyncRequest;
357                          delete asyncReply;
358                          delete response;
359                      
360 kumpf           1.12     PEG_METHOD_EXIT();
361 kumpf           1.8  }
362                      
363 ashok.pathak    1.73 void ShutdownService::waitUntilNoMoreRequests(Boolean requestPending)
364 kumpf           1.8  {
365 kumpf           1.54     Uint32 waitTime = _shutdownTimeout;    // maximum wait time in seconds
366                          const Uint32 waitInterval = 1;         // one second wait interval
367                          Uint32 requestCount;
368 kumpf           1.8  
369                          //
370                          // Loop and wait one second until either there is no more requests
371                          // or until timeout expires.
372                          //
373 kumpf           1.54     while (waitTime > 0)
374 kumpf           1.8      {
375 kumpf           1.54         requestCount = _cimserver->getOutstandingRequestCount();
376                              if (requestCount <= (requestPending ? 1 : 0))
377                              {
378 ashok.pathak    1.73             break;
379 kumpf           1.54         }
380                      
381 marek           1.55         PEG_TRACE((
382                                  TRC_SHUTDOWN,
383                                  Tracer::LEVEL4,
384 kumpf           1.54             "ShutdownService waiting for outstanding CIM operations to "
385 marek           1.55                 "complete.  Request count: %d",
386                                  requestCount));
387 kumpf           1.50         Threads::sleep(waitInterval * 1000);
388 kumpf           1.54         waitTime -= waitInterval;
389 kumpf           1.50     }
390 kumpf           1.8  
391 ashok.pathak    1.73     PEG_TRACE((
392                              TRC_SHUTDOWN,
393                              Tracer::LEVEL4,
394                              "ShutdownService::shutdown - All outstanding CIM operations "
395                                  "complete = %s",
396                              ((_cimserver->getOutstandingRequestCount()) <=
397                               (requestPending ? 1 : 0)) ? "true" : "false"));
398 mike            1.2  }
399                      
400                      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2