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
|