(file) Return to DefaultProviderManager.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / Default

  1 karl  1.59 //%2006////////////////////////////////////////////////////////////////////////
  2 chip  1.1  //
  3 karl  1.43 // 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.7  // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.43 // 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.47 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.59 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 chip  1.1  //
 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 ms.aruran 1.76.2.1 //
 21 chip      1.1      // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22                    // 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 "DefaultProviderManager.h"
 35                    
 36                    #include <Pegasus/Common/CIMMessage.h>
 37                    #include <Pegasus/Common/OperationContext.h>
 38 kumpf     1.71     #include <Pegasus/Common/Time.h>
 39 chip      1.1      #include <Pegasus/Common/Tracer.h>
 40                    #include <Pegasus/Common/StatisticalData.h>
 41                    #include <Pegasus/Common/Logger.h>
 42 kumpf     1.71     #include <Pegasus/Common/MessageLoader.h>
 43                    #include <Pegasus/Common/PegasusVersion.h>
 44 kumpf     1.38     #include <Pegasus/Common/Constants.h>
 45 chip      1.1      
 46 chuck     1.44     #include <Pegasus/Query/QueryExpression/QueryExpression.h>
 47 schuur    1.12     #include <Pegasus/ProviderManager2/QueryExpressionFactory.h>
 48                    
 49 schuur    1.21     #include <Pegasus/ProviderManager2/OperationResponseHandler.h>
 50 chip      1.1      
 51 kumpf     1.71     PEGASUS_NAMESPACE_BEGIN
 52                    
 53                    //
 54                    // Default Provider Manager
 55                    //
 56                    DefaultProviderManager::DefaultProviderManager()
 57                    {
 58                        _subscriptionInitComplete = false;
 59 kumpf     1.66     }
 60 a.dunfey  1.58     
 61 kumpf     1.71     DefaultProviderManager::~DefaultProviderManager()
 62                    {
 63                        PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
 64                            "DefaultProviderManager::~DefaultProviderManager");
 65 a.dunfey  1.58     
 66 kumpf     1.71         _shutdownAllProviders();
 67 chip      1.1      
 68 kumpf     1.71         for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
 69 chip      1.1          {
 70 kumpf     1.71             ProviderMessageHandler* provider = i.value();
 71                            delete provider;
 72 chip      1.1          }
 73                    
 74 kumpf     1.71         for (ModuleTable::Iterator j = _modules.start(); j != 0; j++)
 75 chip      1.1          {
 76 kumpf     1.71             ProviderModule* module = j.value();
 77                            delete module;
 78 chip      1.1          }
 79                    
 80 kumpf     1.71         PEG_METHOD_EXIT();
 81 chip      1.1      }
 82                    
 83 kumpf     1.73     Message* DefaultProviderManager::processMessage(Message* message)
 84 chip      1.1      {
 85                        PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
 86                            "DefaultProviderManager::processMessage()");
 87                    
 88 kumpf     1.73         CIMRequestMessage* request = dynamic_cast<CIMRequestMessage*>(message);
 89                        PEGASUS_ASSERT(request != 0);
 90                    
 91                        CIMResponseMessage* response = 0;
 92 chip      1.1      
 93 kumpf     1.73         try
 94 chip      1.1          {
 95 kumpf     1.73             // pass the request message to a handler method based on message type
 96                            switch(request->getType())
 97                            {
 98                            case CIM_GET_INSTANCE_REQUEST_MESSAGE:
 99                            case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
100                            case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
101                            case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
102                            case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
103                            case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
104                            case CIM_EXEC_QUERY_REQUEST_MESSAGE:
105                            case CIM_ASSOCIATORS_REQUEST_MESSAGE:
106                            case CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE:
107                            case CIM_REFERENCES_REQUEST_MESSAGE:
108                            case CIM_REFERENCE_NAMES_REQUEST_MESSAGE:
109                            case CIM_GET_PROPERTY_REQUEST_MESSAGE:
110                            case CIM_SET_PROPERTY_REQUEST_MESSAGE:
111                            case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
112                            case CIM_CREATE_SUBSCRIPTION_REQUEST_MESSAGE:
113                            case CIM_MODIFY_SUBSCRIPTION_REQUEST_MESSAGE:
114                            case CIM_DELETE_SUBSCRIPTION_REQUEST_MESSAGE:
115                            case CIM_EXPORT_INDICATION_REQUEST_MESSAGE:
116 kumpf     1.71             {
117 ms.aruran 1.76.2.1             ProviderIdContainer pidc = (ProviderIdContainer)
118                                request->operationContext.get(ProviderIdContainer::NAME);
119                    
120                                Array<Uint16> requestedOperationContextContainers;
121                                Uint32 pos1 = pidc.getProvider().findProperty(PEGASUS_PROPERTYNAME_PROVIDERCERTINFO);
122                    
123                                if (pos1 != PEG_NOT_FOUND)
124                                {
125                                    pidc.getProvider().getProperty(pos1).getValue().get(requestedOperationContextContainers);
126                                }
127                    
128                                for (Uint32 i=0; i<requestedOperationContextContainers.size(); i++)
129                                {
130                                    if (requestedOperationContextContainers[i] != 0)
131                                    {
132                                        /**
133                                            remove the SSL client certificate container unless the provider
134                                            explicitly registered for it
135                                        */
136                                        request->operationContext.remove(SSLCertificateChainContainer::NAME);
137                                    }
138 ms.aruran 1.76.2.1             }
139                    
140 kumpf     1.71                 // resolve provider name
141 ms.aruran 1.76.2.1             ProviderName name = _resolveProviderName(pidc);
142                                    //request->operationContext.get(ProviderIdContainer::NAME));
143 kumpf     1.71     
144                                // get cached or load new provider module
145                                ProviderOperationCounter poc(
146                                    _getProvider(name.getPhysicalName(), name.getLogicalName()));
147 chip      1.1      
148 kumpf     1.73                 response = poc.GetProvider().processMessage(request);
149 kumpf     1.71                 break;
150                            }
151 schuur    1.14     
152 kumpf     1.73             case CIM_DISABLE_MODULE_REQUEST_MESSAGE:
153                                response = _handleDisableModuleRequest(request);
154                                break;
155                    
156                            case CIM_ENABLE_MODULE_REQUEST_MESSAGE:
157                                response = _handleEnableModuleRequest(request);
158                                break;
159 chip      1.1      
160 kumpf     1.73             case CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE:
161                                // tell the provider manager to shutdown all the providers
162                                _shutdownAllProviders();
163                                response = request->buildResponse();
164                                break;
165 chip      1.1      
166 kumpf     1.73             case CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE:
167                                response = _handleSubscriptionInitCompleteRequest(request);
168                                break;
169 chip      1.1      
170 kumpf     1.73     // Note: The PG_Provider AutoStart property is not yet supported
171                    #if 0
172                            case CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE:
173                            {
174                                // resolve provider name
175                                ProviderName name = _resolveProviderName(
176                                    request->operationContext.get(ProviderIdContainer::NAME));
177 kumpf     1.30     
178 kumpf     1.73                 // get cached or load new provider module
179                                ProviderOperationCounter poc(
180                                    _getProvider(name.getPhysicalName(), name.getLogicalName()));
181 kumpf     1.30     
182 kumpf     1.73                 break;
183                            }
184                    #endif
185 kumpf     1.30     
186 kumpf     1.73             default:
187                                PEGASUS_ASSERT(0);
188                                break;
189                            }
190 kumpf     1.30         }
191 kumpf     1.71         catch (CIMException& e)
192 kumpf     1.30         {
193 kumpf     1.73             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
194 kumpf     1.30                 "CIMException: " + e.getMessage());
195 kumpf     1.73             response = request->buildResponse();
196 kumpf     1.71             response->cimException = PEGASUS_CIM_EXCEPTION_LANG(
197                                e.getContentLanguages(), e.getCode(), e.getMessage());
198 kumpf     1.30         }
199 kumpf     1.71         catch (Exception& e)
200 kumpf     1.30         {
201 kumpf     1.73             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
202 kumpf     1.30                 "Exception: " + e.getMessage());
203 kumpf     1.73             response = request->buildResponse();
204 kumpf     1.71             response->cimException = PEGASUS_CIM_EXCEPTION_LANG(
205                                e.getContentLanguages(), CIM_ERR_FAILED, e.getMessage());
206 kumpf     1.30         }
207 kumpf     1.71         catch (...)
208 kumpf     1.30         {
209 kumpf     1.73             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
210 kumpf     1.30                 "Exception: Unknown");
211 kumpf     1.73             response = request->buildResponse();
212 kumpf     1.71             response->cimException = PEGASUS_CIM_EXCEPTION(
213                                CIM_ERR_FAILED, "Unknown error.");
214 kumpf     1.30         }
215                    
216                        PEG_METHOD_EXIT();
217 kumpf     1.71         return response;
218 kumpf     1.30     }
219                    
220 kumpf     1.73     CIMResponseMessage* DefaultProviderManager::_handleDisableModuleRequest(
221                        CIMRequestMessage* message)
222 chip      1.1      {
223 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
224                            "DefaultProviderManager::_handleDisableModuleRequest");
225 chip      1.1      
226 kumpf     1.71         CIMDisableModuleRequestMessage* request =
227                            dynamic_cast<CIMDisableModuleRequestMessage*>(message);
228 chip      1.1          PEGASUS_ASSERT(request != 0);
229                    
230 kumpf     1.71         Array<Uint16> operationalStatus;
231                        CIMException cimException;
232 chip      1.1      
233                        try
234                        {
235 kumpf     1.71             // get provider module name
236                            String moduleName;
237                            CIMInstance mInstance = request->providerModule;
238                            Uint32 pos = mInstance.findProperty(CIMName("Name"));
239                            PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
240                            mInstance.getProperty(pos).getValue().get(moduleName);
241 chip      1.1      
242 kumpf     1.71             //
243                            // Unload providers
244                            //
245                            Array<CIMInstance> providerInstances = request->providers;
246 chip      1.1      
247 kumpf     1.71             String physicalName = _resolvePhysicalName(
248                                mInstance.getProperty(
249                                    mInstance.findProperty("Location")).getValue().toString());
250 chip      1.1      
251 kumpf     1.71             for (Uint32 i = 0, n = providerInstances.size(); i < n; i++)
252                            {
253                                String pName;
254                                providerInstances[i].getProperty(
255                                    providerInstances[i].findProperty("Name")).
256                                        getValue().get(pName);
257 chip      1.1      
258 kumpf     1.71                 Sint16 ret_value = _disableProvider(pName);
259 chip      1.1      
260 kumpf     1.71                 if (ret_value == 0)
261                                {
262                                    // disable failed since there are pending requests,
263                                    // stop trying to disable other providers in this module.
264                                    operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_OK);
265                                    break;
266                                }
267                                else if (ret_value != 1)  // Not success
268                                {
269                                    // disable failed for other reason, throw exception
270                                    throw PEGASUS_CIM_EXCEPTION_L(
271                                        CIM_ERR_FAILED,
272                                        MessageLoaderParms(
273                                            "ProviderManager.ProviderManagerService."
274                                                "DISABLE_PROVIDER_FAILED",
275                                            "Failed to disable the provider."));
276                                }
277                            }
278                        }
279                        catch (CIMException & e)
280                        {
281 kumpf     1.71             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
282                                             "Exception: " + e.getMessage());
283                            cimException = e;
284                        }
285                        catch (Exception & e)
286                        {
287                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
288                                "Exception: " + e.getMessage());
289                            cimException = CIMException(CIM_ERR_FAILED, e.getMessage());
290                        }
291                        catch (...)
292                        {
293 chip      1.1              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
294 kumpf     1.71                 "Exception: Unknown");
295                            cimException = PEGASUS_CIM_EXCEPTION_L(
296                                CIM_ERR_FAILED,
297                                MessageLoaderParms(
298                                    "ProviderManager.ProviderManagerService.UNKNOWN_ERROR",
299                                    "Unknown Error"));
300                        }
301 chip      1.1      
302 kumpf     1.71         if (cimException.getCode() == CIM_ERR_SUCCESS)
303                        {
304                            // Status is set to OK if a provider was busy
305                            if (operationalStatus.size() == 0)
306                            {
307                                operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_STOPPED);
308                            }
309                        }
310                        else
311                        {
312                            // If exception occurs, module is not stopped
313                            operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_OK);
314                        }
315 marek     1.64     
316 kumpf     1.71         CIMDisableModuleResponseMessage* response =
317                            dynamic_cast<CIMDisableModuleResponseMessage*>(
318                                request->buildResponse());
319                        PEGASUS_ASSERT(response != 0);
320 chip      1.1      
321 kumpf     1.71         response->operationalStatus = operationalStatus;
322 chip      1.1      
323 kumpf     1.71         PEG_METHOD_EXIT();
324 chip      1.1      
325 kumpf     1.71         return response;
326 chip      1.1      }
327                    
328 kumpf     1.73     CIMResponseMessage* DefaultProviderManager::_handleEnableModuleRequest(
329                        CIMRequestMessage* message)
330 chip      1.1      {
331 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
332                            "DefaultProviderManager::_handleEnableModuleRequest");
333 chip      1.1      
334 kumpf     1.71         CIMEnableModuleRequestMessage* request =
335                            dynamic_cast<CIMEnableModuleRequestMessage*>(message);
336                        PEGASUS_ASSERT(request != 0);
337 chip      1.1      
338 kumpf     1.71         Array<Uint16> operationalStatus;
339                        operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_OK);
340 chip      1.1      
341 kumpf     1.71         CIMEnableModuleResponseMessage* response =
342                            dynamic_cast<CIMEnableModuleResponseMessage*>(
343 kumpf     1.54                 request->buildResponse());
344 chip      1.1          PEGASUS_ASSERT(response != 0);
345                    
346 kumpf     1.71         response->operationalStatus = operationalStatus;
347 chip      1.1      
348 kumpf     1.71         PEG_METHOD_EXIT();
349                        return response;
350                    }
351 chip      1.1      
352 kumpf     1.73     CIMResponseMessage*
353                    DefaultProviderManager::_handleSubscriptionInitCompleteRequest(
354                        CIMRequestMessage* message)
355 kumpf     1.71     {
356                        PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
357                            "DefaultProviderManager::_handleSubscriptionInitCompleteRequest");
358 chip      1.1      
359 kumpf     1.71         CIMSubscriptionInitCompleteRequestMessage* request =
360                            dynamic_cast<CIMSubscriptionInitCompleteRequestMessage*>(message);
361 chip      1.1          PEGASUS_ASSERT(request != 0);
362                    
363 kumpf     1.71         CIMSubscriptionInitCompleteResponseMessage* response =
364                            dynamic_cast<CIMSubscriptionInitCompleteResponseMessage*>(
365 kumpf     1.54                 request->buildResponse());
366 chip      1.1          PEGASUS_ASSERT(response != 0);
367                    
368 kumpf     1.71         _subscriptionInitComplete = true;
369 chip      1.1      
370 kumpf     1.71         // Make a copy of the table so it is not locked during the provider calls
371                        Array<ProviderMessageHandler*> providerList;
372 chip      1.1          {
373 kumpf     1.71             AutoMutex lock(_providerTableMutex);
374 chip      1.1      
375 kumpf     1.71             for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
376                            {
377                                providerList.append(i.value());
378                            }
379                        }
380 chip      1.1      
381 kumpf     1.71         //
382                        // Notify all providers that subscription initialization is complete
383                        //
384                        for (Uint32 j = 0; j < providerList.size(); j++)
385                        {
386 kumpf     1.72             AutoMutex lock(providerList[j]->status.getStatusMutex());
387                    
388                            if (providerList[j]->status.isInitialized())
389                            {
390                                providerList[j]->subscriptionInitComplete();
391                            }
392 kumpf     1.71         }
393 chip      1.1      
394 kumpf     1.71         PEG_METHOD_EXIT();
395                        return response;
396                    }
397 chip      1.1      
398 kumpf     1.71     ProviderName DefaultProviderManager::_resolveProviderName(
399                        const ProviderIdContainer & providerId)
400                    {
401                        String providerName;
402                        String fileName;
403                        String interfaceName;
404                        CIMValue genericValue;
405 se.gupta  1.34     
406 kumpf     1.71         genericValue = providerId.getProvider().getProperty(
407                            providerId.getProvider().findProperty("Name")).getValue();
408                        genericValue.get(providerName);
409 chip      1.1      
410 kumpf     1.71         genericValue = providerId.getModule().getProperty(
411                            providerId.getModule().findProperty("Location")).getValue();
412                        genericValue.get(fileName);
413                        fileName = _resolvePhysicalName(fileName);
414 marek     1.64     
415 kumpf     1.71         // ATTN: This attribute is probably not required
416                        genericValue = providerId.getModule().getProperty(
417                            providerId.getModule().findProperty("InterfaceType")).getValue();
418                        genericValue.get(interfaceName);
419 chip      1.1      
420 kumpf     1.71         return ProviderName(providerName, fileName, interfaceName, 0);
421 chip      1.1      }
422                    
423 kumpf     1.71     ProviderOperationCounter DefaultProviderManager::_getProvider(
424                        const String& moduleFileName,
425                        const String& providerName)
426 chip      1.1      {
427 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
428                            "DefaultProviderManager::_getProvider");
429 chip      1.1      
430 kumpf     1.71         ProviderMessageHandler* pr = _lookupProvider(providerName);
431 chip      1.1      
432 kumpf     1.71         if (!pr->status.isInitialized())
433                        {
434                            _initProvider(pr, moduleFileName);
435 kumpf     1.72         }
436                    
437                        AutoMutex lock(pr->status.getStatusMutex());
438 chip      1.1      
439 kumpf     1.72         if (!pr->status.isInitialized())
440                        {
441                            PEG_METHOD_EXIT();
442                            throw PEGASUS_CIM_EXCEPTION(
443                                CIM_ERR_FAILED, "provider initialization failed");
444 kumpf     1.71         }
445 chip      1.1      
446 kumpf     1.71         ProviderOperationCounter poc(pr);
447 chip      1.1      
448 kumpf     1.71         PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
449                            "Returning Provider " + providerName);
450 chip      1.1      
451 kumpf     1.71         PEG_METHOD_EXIT();
452                        return poc;
453                    }
454 chip      1.1      
455 kumpf     1.71     ProviderMessageHandler* DefaultProviderManager::_lookupProvider(
456                        const String& providerName)
457                    {
458                        PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
459                            "DefaultProviderManager::_lookupProvider");
460 chip      1.1      
461 kumpf     1.71         // lock the providerTable mutex
462                        AutoMutex lock(_providerTableMutex);
463 chip      1.1      
464 kumpf     1.71         // look up provider in cache
465                        ProviderMessageHandler* pr = 0;
466                        if (_providers.lookup(providerName, pr))
467                        {
468 chip      1.1              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
469 kumpf     1.71                 "Found Provider " + providerName + " in Provider Manager Cache");
470                        }
471                        else
472                        {
473                            // create provider
474                            pr = new ProviderMessageHandler(
475                                providerName, 0, _indicationCallback, _responseChunkCallback,
476                                _subscriptionInitComplete);
477 chip      1.1      
478 kumpf     1.71             // insert provider in provider table
479                            _providers.insert(providerName, pr);
480 marek     1.64     
481 kumpf     1.71             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
482                                "Created provider " + pr->getName());
483 chip      1.1          }
484                    
485                        PEG_METHOD_EXIT();
486 kumpf     1.71         return pr;
487 chip      1.1      }
488                    
489 kumpf     1.71     ProviderMessageHandler* DefaultProviderManager::_initProvider(
490                        ProviderMessageHandler* provider,
491                        const String& moduleFileName)
492 chip      1.1      {
493 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
494                            "DefaultProviderManager::_initProvider");
495 chip      1.1      
496 kumpf     1.71         ProviderModule* module = 0;
497                        CIMProvider* base;
498 chip      1.1      
499 kumpf     1.72         // lookup provider module
500                        module = _lookupModule(moduleFileName);
501 chip      1.1      
502 kumpf     1.72         // lock the provider status mutex
503                        AutoMutex lock(provider->status.getStatusMutex());
504 chip      1.1      
505 kumpf     1.72         if (provider->status.isInitialized())
506 kumpf     1.71         {
507 kumpf     1.72             // Initialization is already complete
508                            return provider;
509                        }
510 chip      1.1      
511 kumpf     1.72         PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
512                            "Loading/Linking Provider Module " + moduleFileName);
513 chip      1.1      
514 kumpf     1.72         // load the provider
515                        try
516                        {
517                            base = module->load(provider->getName());
518                        }
519                        catch (...)
520                        {
521 kumpf     1.71             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
522 kumpf     1.72                 "Exception caught Loading/Linking Provider Module " +
523                                moduleFileName);
524                            PEG_METHOD_EXIT();
525                            throw;
526                        }
527 chip      1.1      
528 kumpf     1.72         // initialize the provider
529                        PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
530                            "Initializing Provider " + provider->getName());
531 chip      1.1      
532 kumpf     1.72         CIMOMHandle *cimomHandle = new CIMOMHandle();
533                        provider->status.setCIMOMHandle(cimomHandle);
534                        provider->status.setModule(module);
535                        provider->setProvider(base);
536 chip      1.1      
537 kumpf     1.72         Boolean initializeError = false;
538 chip      1.1      
539 kumpf     1.72         try
540                        {
541                            provider->initialize(*cimomHandle);
542                        }
543                        catch (...)
544                        {
545                            initializeError = true;
546                        }
547 chip      1.1      
548 kumpf     1.72         // The cleanup code executed when an exception occurs was previously
549                        // included in the catch block above. Unloading the provider module
550                        // from inside the catch block resulted in a crash when an exception
551                        // was thrown from a provider's initialize() method. The issue is that
552                        // when an exception is thrown, the program maintains internal
553                        // pointers related to the code that threw the exception. In the case
554                        // of an exception thrown from a provider during the initialize()
555                        // method, those pointers point into the provider library, so when
556                        // the DefaultProviderManager unloads the library, the pointers into
557                        // the library that the program was holding are invalid.
558 chip      1.1      
559 kumpf     1.72         if (initializeError == true)
560                        {
561 kumpf     1.76             // Allow the provider to clean up
562                            provider->terminate();
563                    
564 kumpf     1.72             // delete the cimom handle
565                            delete cimomHandle;
566 marek     1.64     
567 kumpf     1.72             provider->setProvider(0);
568 chip      1.1      
569 kumpf     1.72             // unload provider module
570                            module->unloadModule();
571                        }
572 chip      1.1      
573 kumpf     1.72         provider->status.setInitialized(!initializeError);
574 chip      1.1      
575                        PEG_METHOD_EXIT();
576 kumpf     1.71         return provider;
577 chip      1.1      }
578                    
579 kumpf     1.71     ProviderModule* DefaultProviderManager::_lookupModule(
580                        const String& moduleFileName)
581 chip      1.1      {
582 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
583                            "DefaultProviderManager::_lookupModule");
584 chip      1.1      
585 kumpf     1.72         // lock the providerTable mutex
586                        AutoMutex lock(_providerTableMutex);
587                    
588 kumpf     1.71         // look up provider module in cache
589                        ProviderModule* module = 0;
590 chip      1.1      
591 kumpf     1.71         if (_modules.lookup(moduleFileName, module))
592                        {
593                            // found provider module in cache
594                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
595                                "Found Provider Module " + moduleFileName +
596                                " in Provider Manager Cache");
597                        }
598                        else
599 chip      1.1          {
600 kumpf     1.71             // provider module not found in cache, create provider module
601 chip      1.1              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
602 kumpf     1.71                 "Creating Provider Module " + moduleFileName);
603 chip      1.1      
604 kumpf     1.71             module = new ProviderModule(moduleFileName);
605 marek     1.64     
606 kumpf     1.71             // insert provider module in module table
607                            _modules.insert(moduleFileName, module);
608 chip      1.1          }
609                    
610                        PEG_METHOD_EXIT();
611 kumpf     1.71         return module;
612 chip      1.1      }
613                    
614 kumpf     1.71     Boolean DefaultProviderManager::hasActiveProviders()
615 chip      1.1      {
616 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
617                            "DefaultProviderManager::hasActiveProviders");
618 schuur    1.12     
619                        try
620                        {
621 kumpf     1.71             AutoMutex lock(_providerTableMutex);
622                            Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
623                                "Number of providers in _providers table = %d", _providers.size());
624 marek     1.64     
625 kumpf     1.71             // Iterate through the _providers table looking for an active provider
626                            for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
627                            {
628                                if (i.value()->status.isInitialized())
629                                {
630                                    PEG_METHOD_EXIT();
631                                    return true;
632                                }
633                            }
634                        }
635                        catch (...)
636                        {
637                            // Unexpected exception; do not assume that no providers are loaded
638                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
639                                "Unexpected Exception in hasActiveProviders.");
640                            PEG_METHOD_EXIT();
641                            return true;
642 schuur    1.12         }
643 chip      1.1      
644 kumpf     1.71         // No active providers were found in the _providers table
645 chip      1.1          PEG_METHOD_EXIT();
646 kumpf     1.71         return false;
647 chip      1.1      }
648                    
649 kumpf     1.71     void DefaultProviderManager::unloadIdleProviders()
650 chip      1.1      {
651 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
652 kumpf     1.72             "DefaultProviderManager::unloadIdleProviders");
653 kumpf     1.71     
654 kumpf     1.75         try
655 kumpf     1.71         {
656 kumpf     1.75             struct timeval now;
657                            Time::gettimeofday(&now);
658 chip      1.1      
659 kumpf     1.72             // Make a copy of the table so it is not locked during provider calls
660                            Array<ProviderMessageHandler*> providerList;
661 kumpf     1.71             {
662 kumpf     1.72                 AutoMutex lock(_providerTableMutex);
663 chip      1.2      
664 kumpf     1.72                 for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
665 kumpf     1.71                 {
666 kumpf     1.72                     providerList.append(i.value());
667 kumpf     1.71                 }
668 kumpf     1.72             }
669 se.gupta  1.34     
670 kumpf     1.72             for (Uint32 i = 0; i < providerList.size(); i++)
671                            {
672                                ProviderMessageHandler* provider = providerList[i];
673 marek     1.64     
674 kumpf     1.72                 AutoMutex lock(provider->status.getStatusMutex());
675 kumpf     1.66     
676 kumpf     1.72                 if (!provider->status.isInitialized())
677 kumpf     1.71                 {
678                                    continue;
679                                }
680 chip      1.1      
681 kumpf     1.72                 struct timeval providerTime = {0, 0};
682                                provider->status.getLastOperationEndTime(&providerTime);
683 kumpf     1.71     
684                                PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
685 kumpf     1.72                     "provider->status.isIdle() returns: " +
686                                    CIMValue(provider->status.isIdle()).toString());
687 marek     1.64     
688 kumpf     1.72                 if (provider->status.isIdle() &&
689                                    ((now.tv_sec - providerTime.tv_sec) > ((Sint32)IDLE_LIMIT)))
690 kumpf     1.71                 {
691 kumpf     1.72                     PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
692                                        "Unloading idle provider: " + provider->getName());
693                                    _unloadProvider(provider);
694 kumpf     1.71                 }
695                            }
696                        }
697                        catch (...)
698 chip      1.1          {
699 kumpf     1.71             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
700                                "Caught unexpected exception in unloadIdleProviders.");
701 chip      1.1          }
702                    
703                        PEG_METHOD_EXIT();
704                    }
705                    
706 kumpf     1.71     void DefaultProviderManager::_shutdownAllProviders()
707 chip      1.1      {
708 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
709                            "DefaultProviderManager::_shutdownAllProviders");
710 chip      1.1      
711                        try
712                        {
713 kumpf     1.71             AutoMutex lock(_providerTableMutex);
714 schuur    1.19     
715 kumpf     1.71             Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
716                                "providers in cache = %d", _providers.size());
717 chip      1.2      
718 kumpf     1.71             for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
719                            {
720                                ProviderMessageHandler* provider = i.value();
721                                PEGASUS_ASSERT(provider != 0);
722 chip      1.2      
723 kumpf     1.72                 AutoMutex lock(provider->status.getStatusMutex());
724                    
725 kumpf     1.71                 if (provider->status.isInitialized())
726                                {
727                                    _unloadProvider(provider);
728                                }
729                            }
730                        }
731                        catch (...)
732                        {
733 chip      1.2              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
734 kumpf     1.71                 "Unexpected Exception in _shutdownAllProviders().");
735 chip      1.1          }
736                    
737                        PEG_METHOD_EXIT();
738                    }
739                    
740 kumpf     1.71     Sint16 DefaultProviderManager::_disableProvider(const String& providerName)
741 chip      1.1      {
742 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
743                            "DefaultProviderManager::_disableProvider");
744 chip      1.1      
745 kumpf     1.71         ProviderMessageHandler* pr = _lookupProvider(providerName);
746                        if (!pr->status.isInitialized())
747                        {
748                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
749                                "Provider " + providerName + " is not loaded");
750                            PEG_METHOD_EXIT();
751                            return 1;
752                        }
753 chip      1.1      
754 kumpf     1.71         PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
755                            "Disable Provider " + pr->getName());
756                        //
757                        // Check to see if there are pending requests. If there are pending
758                        // requests and the disable timeout has not expired, loop and wait one
759                        // second until either there is no pending requests or until timeout
760                        // expires.
761                        //
762                        Uint32 waitTime = PROVIDER_DISABLE_TIMEOUT;
763 kumpf     1.72         while ((pr->status.numCurrentOperations() > 0) && (waitTime > 0))
764 kumpf     1.71         {
765                            Threads::sleep(1000);
766                            waitTime = waitTime - 1;
767                        }
768 chip      1.1      
769 kumpf     1.71         // There are still pending requests, do not disable
770 kumpf     1.72         if (pr->status.numCurrentOperations() > 0)
771 kumpf     1.71         {
772                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
773                                "Disable failed since there are pending requests.");
774                            PEG_METHOD_EXIT();
775                            return 0;
776                        }
777 chip      1.1      
778                        try
779                        {
780 kumpf     1.72             AutoMutex lock(pr->status.getStatusMutex());
781 chip      1.1      
782 kumpf     1.71             if (pr->status.isInitialized())
783                            {
784                                PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
785                                    "Unloading Provider " + pr->getName());
786                                _unloadProvider(pr);
787                            }
788                        }
789                        catch (...)
790                        {
791 chip      1.2              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
792 kumpf     1.71                 "Unload provider failed " + pr->getName());
793                            PEG_METHOD_EXIT();
794                            return -1;
795 chip      1.1          }
796                    
797                        PEG_METHOD_EXIT();
798 kumpf     1.71         return 1;
799 chip      1.1      }
800                    
801 kumpf     1.71     void DefaultProviderManager::_unloadProvider(ProviderMessageHandler* provider)
802 chip      1.1      {
803 kumpf     1.71         //
804 kumpf     1.72         // NOTE:  It is the caller's responsibility to make sure that the
805                        // provider->status.getStatusMutex() mutex is locked before calling
806                        // this method.
807 kumpf     1.71         //
808 kumpf     1.72     
809 kumpf     1.71         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
810                            "DefaultProviderManager::_unloadProvider");
811 chip      1.1      
812 kumpf     1.72         if (provider->status.numCurrentOperations() > 0)
813 chip      1.1          {
814                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
815 kumpf     1.71                 "Provider cannot be unloaded due to pending operations: " +
816                                provider->getName());
817 chip      1.1          }
818 kumpf     1.71         else
819 chip      1.1          {
820 kumpf     1.71             PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
821                                "Terminating Provider " + provider->getName());
822 chip      1.1      
823 kumpf     1.72             provider->terminate();
824 chip      1.1      
825 kumpf     1.72             // unload provider module
826                            PEGASUS_ASSERT(provider->status.getModule() != 0);
827                            PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
828                                "Unloading provider module: " + provider->getName());
829                            provider->status.getModule()->unloadModule();
830 chip      1.1      
831 kumpf     1.72             Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
832                                "DefaultProviderManager:  Unloaded provider $0",
833                                provider->getName());
834 kumpf     1.71     
835 kumpf     1.72             // NOTE: The "delete provider->status.getCIMOMHandle()" operation
836                            //   was moved to be called after the unloadModule() call above
837 kumpf     1.71             //   as part of a fix for bugzilla 3669. For some providers
838                            //   run out-of-process on Windows platforms (i.e. running
839                            //   the cimserver with the forceProviderProcesses config option
840                            //   set to "true"), deleting the provider's CIMOMHandle before
841                            //   unloading the provider library caused the unload mechanism
842                            //   to deadlock, making that provider unavailable and preventing
843                            //   the cimserver from shutting down. It should NOT be moved back
844                            //   above the unloadModule() call. See bugzilla 3669 for details.
845 kumpf     1.72     
846 kumpf     1.71             // delete the cimom handle
847 chip      1.1              PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
848 kumpf     1.72                 "Destroying provider's CIMOMHandle: " + provider->getName());
849                            delete provider->status.getCIMOMHandle();
850 marek     1.64     
851 kumpf     1.71             // set provider status to uninitialized
852 kumpf     1.72             provider->status.setInitialized(false);
853 chip      1.1          }
854                    
855                        PEG_METHOD_EXIT();
856 carolann.graves 1.49     }
857                          
858 mike            1.63     ProviderManager* DefaultProviderManager::createDefaultProviderManagerCallback()
859                          {
860                              return new DefaultProviderManager();
861                          }
862                          
863 kumpf           1.26     PEGASUS_NAMESPACE_END
864 kumpf           1.74     
865                          PEGASUS_USING_PEGASUS;
866                          
867                          // This entry point is not needed because the DefaultProviderManager is created
868                          // using DefaultProviderManager::createDefaultProviderManagerCallback().
869                          #if 0
870                          extern "C" PEGASUS_EXPORT ProviderManager* PegasusCreateProviderManager(
871                              const String& providerManagerName)
872                          {
873                              if (String::equalNoCase(providerManagerName, "Default"))
874                              {
875                                  return new DefaultProviderManager();
876                              }
877                          
878                              return 0;
879                          }
880                          #endif

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2