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