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