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 karl 1.43 //
|
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 ProviderName name = _resolveProviderName(
|
119 kumpf 1.73 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 // delete the cimom handle
539 delete cimomHandle;
|
540 marek 1.64
|
541 kumpf 1.72 provider->setProvider(0);
|
542 chip 1.1
|
543 kumpf 1.72 // unload provider module
544 module->unloadModule();
545 }
|
546 chip 1.1
|
547 kumpf 1.72 provider->status.setInitialized(!initializeError);
|
548 chip 1.1
549 PEG_METHOD_EXIT();
|
550 kumpf 1.71 return provider;
|
551 chip 1.1 }
552
|
553 kumpf 1.71 ProviderModule* DefaultProviderManager::_lookupModule(
554 const String& moduleFileName)
|
555 chip 1.1 {
|
556 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
557 "DefaultProviderManager::_lookupModule");
|
558 chip 1.1
|
559 kumpf 1.72 // lock the providerTable mutex
560 AutoMutex lock(_providerTableMutex);
561
|
562 kumpf 1.71 // look up provider module in cache
563 ProviderModule* module = 0;
|
564 chip 1.1
|
565 kumpf 1.71 if (_modules.lookup(moduleFileName, module))
566 {
567 // found provider module in cache
568 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
569 "Found Provider Module " + moduleFileName +
570 " in Provider Manager Cache");
571 }
572 else
|
573 chip 1.1 {
|
574 kumpf 1.71 // provider module not found in cache, create provider module
|
575 chip 1.1 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
576 kumpf 1.71 "Creating Provider Module " + moduleFileName);
|
577 chip 1.1
|
578 kumpf 1.71 module = new ProviderModule(moduleFileName);
|
579 marek 1.64
|
580 kumpf 1.71 // insert provider module in module table
581 _modules.insert(moduleFileName, module);
|
582 chip 1.1 }
583
584 PEG_METHOD_EXIT();
|
585 kumpf 1.71 return module;
|
586 chip 1.1 }
587
|
588 kumpf 1.71 Boolean DefaultProviderManager::hasActiveProviders()
|
589 chip 1.1 {
|
590 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
591 "DefaultProviderManager::hasActiveProviders");
|
592 schuur 1.12
593 try
594 {
|
595 kumpf 1.71 AutoMutex lock(_providerTableMutex);
596 Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
597 "Number of providers in _providers table = %d", _providers.size());
|
598 marek 1.64
|
599 kumpf 1.71 // Iterate through the _providers table looking for an active provider
600 for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
601 {
602 if (i.value()->status.isInitialized())
603 {
604 PEG_METHOD_EXIT();
605 return true;
606 }
607 }
608 }
609 catch (...)
610 {
611 // Unexpected exception; do not assume that no providers are loaded
612 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
613 "Unexpected Exception in hasActiveProviders.");
614 PEG_METHOD_EXIT();
615 return true;
|
616 schuur 1.12 }
|
617 chip 1.1
|
618 kumpf 1.71 // No active providers were found in the _providers table
|
619 chip 1.1 PEG_METHOD_EXIT();
|
620 kumpf 1.71 return false;
|
621 chip 1.1 }
622
|
623 kumpf 1.71 void DefaultProviderManager::unloadIdleProviders()
|
624 chip 1.1 {
|
625 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
626 kumpf 1.72 "DefaultProviderManager::unloadIdleProviders");
|
627 kumpf 1.71
|
628 kumpf 1.72 static struct timeval prevIdleCheckTime = {0, 0};
|
629 chip 1.1
|
630 kumpf 1.72 if (prevIdleCheckTime.tv_sec == 0)
|
631 kumpf 1.71 {
|
632 kumpf 1.72 Time::gettimeofday(&prevIdleCheckTime);
|
633 kumpf 1.71 }
|
634 kumpf 1.72
635 struct timeval now;
|
636 kumpf 1.71 Time::gettimeofday(&now);
|
637 chip 1.1
|
638 kumpf 1.72 if (!((now.tv_sec - prevIdleCheckTime.tv_sec) > IDLE_LIMIT))
|
639 kumpf 1.71 {
640 // It's not time yet to check for idle providers
641 PEG_METHOD_EXIT();
642 return;
643 }
|
644 chip 1.1
|
645 kumpf 1.72 Time::gettimeofday(&prevIdleCheckTime);
|
646 chip 1.1
|
647 kumpf 1.71 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
648 "Checking for Idle providers to unload.");
|
649 chip 1.1
650 try
651 {
|
652 kumpf 1.72 // Make a copy of the table so it is not locked during provider calls
653 Array<ProviderMessageHandler*> providerList;
|
654 kumpf 1.71 {
|
655 kumpf 1.72 AutoMutex lock(_providerTableMutex);
|
656 chip 1.2
|
657 kumpf 1.72 for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
|
658 kumpf 1.71 {
|
659 kumpf 1.72 providerList.append(i.value());
|
660 kumpf 1.71 }
|
661 kumpf 1.72 }
|
662 se.gupta 1.34
|
663 kumpf 1.72 for (Uint32 i = 0; i < providerList.size(); i++)
664 {
665 ProviderMessageHandler* provider = providerList[i];
|
666 marek 1.64
|
667 kumpf 1.72 AutoMutex lock(provider->status.getStatusMutex());
|
668 kumpf 1.66
|
669 kumpf 1.72 if (!provider->status.isInitialized())
|
670 kumpf 1.71 {
671 continue;
672 }
|
673 chip 1.1
|
674 kumpf 1.72 struct timeval providerTime = {0, 0};
675 provider->status.getLastOperationEndTime(&providerTime);
|
676 kumpf 1.71
677 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
678 kumpf 1.72 "provider->status.isIdle() returns: " +
679 CIMValue(provider->status.isIdle()).toString());
|
680 marek 1.64
|
681 kumpf 1.72 if (provider->status.isIdle() &&
682 ((now.tv_sec - providerTime.tv_sec) > ((Sint32)IDLE_LIMIT)))
|
683 kumpf 1.71 {
|
684 kumpf 1.72 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
685 "Unloading idle provider: " + provider->getName());
686 _unloadProvider(provider);
|
687 kumpf 1.71 }
688 }
689 }
690 catch (...)
|
691 chip 1.1 {
|
692 kumpf 1.71 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
693 "Caught unexpected exception in unloadIdleProviders.");
|
694 chip 1.1 }
695
696 PEG_METHOD_EXIT();
697 }
698
|
699 kumpf 1.71 void DefaultProviderManager::_shutdownAllProviders()
|
700 chip 1.1 {
|
701 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
702 "DefaultProviderManager::_shutdownAllProviders");
|
703 chip 1.1
704 try
705 {
|
706 kumpf 1.71 AutoMutex lock(_providerTableMutex);
|
707 schuur 1.19
|
708 kumpf 1.71 Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
709 "providers in cache = %d", _providers.size());
|
710 chip 1.2
|
711 kumpf 1.71 for (ProviderTable::Iterator i = _providers.start(); i != 0; i++)
712 {
713 ProviderMessageHandler* provider = i.value();
714 PEGASUS_ASSERT(provider != 0);
|
715 chip 1.2
|
716 kumpf 1.72 AutoMutex lock(provider->status.getStatusMutex());
717
|
718 kumpf 1.71 if (provider->status.isInitialized())
719 {
720 _unloadProvider(provider);
721 }
722 }
723 }
724 catch (...)
725 {
|
726 chip 1.2 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
727 kumpf 1.71 "Unexpected Exception in _shutdownAllProviders().");
|
728 chip 1.1 }
729
730 PEG_METHOD_EXIT();
731 }
732
|
733 kumpf 1.71 Sint16 DefaultProviderManager::_disableProvider(const String& providerName)
|
734 chip 1.1 {
|
735 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
736 "DefaultProviderManager::_disableProvider");
|
737 chip 1.1
|
738 kumpf 1.71 ProviderMessageHandler* pr = _lookupProvider(providerName);
739 if (!pr->status.isInitialized())
740 {
741 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
742 "Provider " + providerName + " is not loaded");
743 PEG_METHOD_EXIT();
744 return 1;
745 }
|
746 chip 1.1
|
747 kumpf 1.71 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
748 "Disable Provider " + pr->getName());
749 //
750 // Check to see if there are pending requests. If there are pending
751 // requests and the disable timeout has not expired, loop and wait one
752 // second until either there is no pending requests or until timeout
753 // expires.
754 //
755 Uint32 waitTime = PROVIDER_DISABLE_TIMEOUT;
|
756 kumpf 1.72 while ((pr->status.numCurrentOperations() > 0) && (waitTime > 0))
|
757 kumpf 1.71 {
758 Threads::sleep(1000);
759 waitTime = waitTime - 1;
760 }
|
761 chip 1.1
|
762 kumpf 1.71 // There are still pending requests, do not disable
|
763 kumpf 1.72 if (pr->status.numCurrentOperations() > 0)
|
764 kumpf 1.71 {
765 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
766 "Disable failed since there are pending requests.");
767 PEG_METHOD_EXIT();
768 return 0;
769 }
|
770 chip 1.1
771 try
772 {
|
773 kumpf 1.72 AutoMutex lock(pr->status.getStatusMutex());
|
774 chip 1.1
|
775 kumpf 1.71 if (pr->status.isInitialized())
776 {
777 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
778 "Unloading Provider " + pr->getName());
779 _unloadProvider(pr);
780 }
781 }
782 catch (...)
783 {
|
784 chip 1.2 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
785 kumpf 1.71 "Unload provider failed " + pr->getName());
786 PEG_METHOD_EXIT();
787 return -1;
|
788 chip 1.1 }
789
790 PEG_METHOD_EXIT();
|
791 kumpf 1.71 return 1;
|
792 chip 1.1 }
793
|
794 kumpf 1.71 void DefaultProviderManager::_unloadProvider(ProviderMessageHandler* provider)
|
795 chip 1.1 {
|
796 kumpf 1.71 //
|
797 kumpf 1.72 // NOTE: It is the caller's responsibility to make sure that the
798 // provider->status.getStatusMutex() mutex is locked before calling
799 // this method.
|
800 kumpf 1.71 //
|
801 kumpf 1.72
|
802 kumpf 1.71 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
803 "DefaultProviderManager::_unloadProvider");
|
804 chip 1.1
|
805 kumpf 1.72 if (provider->status.numCurrentOperations() > 0)
|
806 chip 1.1 {
807 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
808 kumpf 1.71 "Provider cannot be unloaded due to pending operations: " +
809 provider->getName());
|
810 chip 1.1 }
|
811 kumpf 1.71 else
|
812 chip 1.1 {
|
813 kumpf 1.71 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
814 "Terminating Provider " + provider->getName());
|
815 chip 1.1
|
816 kumpf 1.72 provider->terminate();
|
817 chip 1.1
|
818 kumpf 1.72 // unload provider module
819 PEGASUS_ASSERT(provider->status.getModule() != 0);
820 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
821 "Unloading provider module: " + provider->getName());
822 provider->status.getModule()->unloadModule();
|
823 chip 1.1
|
824 kumpf 1.72 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
825 "DefaultProviderManager: Unloaded provider $0",
826 provider->getName());
|
827 kumpf 1.71
|
828 kumpf 1.72 // NOTE: The "delete provider->status.getCIMOMHandle()" operation
829 // was moved to be called after the unloadModule() call above
|
830 kumpf 1.71 // as part of a fix for bugzilla 3669. For some providers
831 // run out-of-process on Windows platforms (i.e. running
832 // the cimserver with the forceProviderProcesses config option
833 // set to "true"), deleting the provider's CIMOMHandle before
834 // unloading the provider library caused the unload mechanism
835 // to deadlock, making that provider unavailable and preventing
836 // the cimserver from shutting down. It should NOT be moved back
837 // above the unloadModule() call. See bugzilla 3669 for details.
|
838 kumpf 1.72
|
839 kumpf 1.71 // delete the cimom handle
|
840 chip 1.1 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
841 kumpf 1.72 "Destroying provider's CIMOMHandle: " + provider->getName());
842 delete provider->status.getCIMOMHandle();
|
843 marek 1.64
|
844 kumpf 1.71 // set provider status to uninitialized
|
845 kumpf 1.72 provider->status.setInitialized(false);
|
846 chip 1.1 }
847
848 PEG_METHOD_EXIT();
|
849 carolann.graves 1.49 }
850
|
851 mike 1.63 ProviderManager* DefaultProviderManager::createDefaultProviderManagerCallback()
852 {
853 return new DefaultProviderManager();
854 }
855
|
856 kumpf 1.26 PEGASUS_NAMESPACE_END
|
857 kumpf 1.74
858 PEGASUS_USING_PEGASUS;
859
860 // This entry point is not needed because the DefaultProviderManager is created
861 // using DefaultProviderManager::createDefaultProviderManagerCallback().
862 #if 0
863 extern "C" PEGASUS_EXPORT ProviderManager* PegasusCreateProviderManager(
864 const String& providerManagerName)
865 {
866 if (String::equalNoCase(providerManagerName, "Default"))
867 {
868 return new DefaultProviderManager();
869 }
870
871 return 0;
872 }
873 #endif
|