1 karl 1.16 //%2005////////////////////////////////////////////////////////////////////////
|
2 schuur 1.1 //
|
3 karl 1.12 // 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 // IBM Corp.; EMC Corporation, The Open Group.
7 // 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.16 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 schuur 1.1 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
|
18 karl 1.16 //
|
19 schuur 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Chip Vincent (cvincent@us.ibm.com)
31 //
32 // Modified By: Yi Zhou, Hewlett-Packard Company(yi_zhou@hp.com)
33 // Mike Day IBM Corporation (mdday@us.ibm.com)
34 // Adrian Schuur, schuur@de.ibm.com
|
35 dj.gorey 1.6 // Dan Gorey, IBM djgorey@us.ibm.com
|
36 r.kieninger 1.15 // Robert Kieninger, IBM kieningr@de.ibm.com
|
37 schuur 1.1 //
38 //%/////////////////////////////////////////////////////////////////////////////
39
|
40 schuur 1.10 #include "CMPI_Version.h"
41
|
42 schuur 1.1 #include <Pegasus/Common/Constants.h>
43 #include <Pegasus/Common/Tracer.h>
44 #include <Pegasus/Common/PegasusVersion.h>
45
|
46 konrad.r 1.26 #include <Pegasus/Common/MessageLoader.h>
47
|
48 schuur 1.1 #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
49 #include <Pegasus/ProviderManager2/CMPI/CMPIProviderModule.h>
50 #include <Pegasus/ProviderManager2/ProviderManagerService.h>
51
|
52 kumpf 1.9 #include "CMPILocalProviderManager.h"
53
|
54 schuur 1.3 PEGASUS_USING_STD;
|
55 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
|
56 konrad.r 1.27 #define DDD(X) if (_cmpi_trace) X;
57
58 extern int _cmpi_trace;
59
|
60 schuur 1.8 #undef IDLE_LIMIT
61 #define IDLE_LIMIT 50
|
62 konrad.r 1.24 CMPILocalProviderManager::CMPILocalProviderManager (void):
63 _idle_timeout (IDLE_LIMIT)
|
64 r.kieninger 1.14 {
|
65 schuur 1.1 }
66
|
67 konrad.r 1.24 CMPILocalProviderManager::~CMPILocalProviderManager (void)
|
68 r.kieninger 1.14 {
|
69 konrad.r 1.24 Uint32 ccode;
|
70 dj.gorey 1.6
|
71 konrad.r 1.24 _provider_ctrl (UNLOAD_ALL_PROVIDERS, this, &ccode);
72 // Since all of the providers are deleted we can delete the
73 // modules too.
74 for (ModuleTable::Iterator j = _modules.start (); j != 0; j++)
75 {
76 CMPIProviderModule *module = j.value ();
77 delete module;
78 }
|
79 schuur 1.1 }
80
|
81 konrad.r 1.24 Sint32
82 CMPILocalProviderManager::_provider_ctrl (CTRL code, void *parm, void *ret)
|
83 r.kieninger 1.14 {
|
84 r.kieninger 1.13
|
85 konrad.r 1.24 static Uint32 quantum;
86 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_provider_ctrl");
|
87 r.kieninger 1.13
|
88 konrad.r 1.24 Sint32 ccode = 0;
89 CTRL_STRINGS *parms = reinterpret_cast < CTRL_STRINGS * >(parm);
|
90 r.kieninger 1.13
|
91 konrad.r 1.24 switch (code)
|
92 r.kieninger 1.14 {
93
94 case GET_PROVIDER:
|
95 konrad.r 1.24 {
|
96 r.kieninger 1.14
|
97 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
98 "_provider_ctrl::GET_PROVIDER");
|
99 r.kieninger 1.14
|
100 konrad.r 1.24 String providerName = *(parms->providerName);
101 String moduleFileName = *(parms->fileName);
102 String location = *(parms->location);
|
103 r.kieninger 1.14
|
104 konrad.r 1.24 CMPIProvider *pr = 0;
105 CMPIProvider::OpProviderHolder * ph =
106 reinterpret_cast < CMPIProvider::OpProviderHolder * >(ret);
|
107 r.kieninger 1.14
|
108 konrad.r 1.24 pr = _lookupProvider (providerName);
|
109 r.kieninger 1.15
|
110 konrad.r 1.24 if (pr->getStatus () != CMPIProvider::INITIALIZED)
111 {
112 pr->setLocation (location);
113 _initProvider (pr, moduleFileName);
|
114 r.kieninger 1.13
|
115 konrad.r 1.24 if (pr->getStatus () != CMPIProvider::INITIALIZED)
116 {
117 PEG_METHOD_EXIT ();
118 throw PEGASUS_CIM_EXCEPTION (CIM_ERR_FAILED,
119 "provider initialization failed");
120 }
121 }
|
122 r.kieninger 1.13
123
|
124 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
125 "Returning Provider" + providerName);
|
126 schuur 1.1
|
127 r.kieninger 1.15
|
128 konrad.r 1.24 ph->SetProvider (pr);
129 ph->GetProvider ().update_idle_timer ();
130 break;
131 }
|
132 r.kieninger 1.14
133 case UNLOAD_PROVIDER:
|
134 konrad.r 1.24 {
135
136 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
137 "_provider_ctrl::UNLOAD_PROVIDER");
138 CMPIProvider *pr = _lookupProvider (*(parms->providerName));
139 if ((pr->getStatus () == CMPIProvider::INITIALIZED))
140 {
|
141 r.kieninger 1.14
|
142 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
143 konrad.r 1.26 "Unloading CMPIProvider: " + pr->getName());
|
144 r.kieninger 1.14
|
145 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
146 // The provider table must be locked before unloading.
147 _providers.remove (pr->_name);
148 _unloadProvider (pr);
149 delete pr;
|
150 r.kieninger 1.14
|
151 konrad.r 1.24 }
|
152 konrad.r 1.25 else {
153 // No need to have a memory leak.
154 delete pr;
155 }
|
156 konrad.r 1.24 break;
157 }
|
158 schuur 1.1
|
159 r.kieninger 1.14 case LOOKUP_PROVIDER:
|
160 konrad.r 1.24 {
161
162 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
163 "_provider_ctrl::LOOKUP_PROVIDER");
|
164 schuur 1.1
|
165 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
166 schuur 1.1
|
167 konrad.r 1.24 if (true == _providers.lookup (*(parms->providerName),
168 *(reinterpret_cast <
169 CMPIProvider * *>(ret))))
170 {
171 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
172 "Found CMPIProvider in cache: " +
173 *(parms->providerName));
174
175 (*(reinterpret_cast < CMPIProvider * *>(ret)))->
176 update_idle_timer ();
177 }
178 else
179 {
180
181 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
182 "Could not find CMPIProvider in cache: " +
183 *(parms->providerName));
184 ccode = -1;
185 }
|
186 dj.gorey 1.6
|
187 konrad.r 1.24 break;
188 }
|
189 schuur 1.1
|
190 konrad.r 1.24 case LOOKUP_MODULE:
191 {
|
192 schuur 1.1
|
193 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
194 "_provider_ctrl::LOOKUP_MODULE");
|
195 schuur 1.1
|
196 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
197 schuur 1.1
|
198 konrad.r 1.24 if (false == _modules.lookup (*(parms->fileName),
199 *(reinterpret_cast <
200 CMPIProviderModule * *>(ret))))
201 {
202 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
203 "Could not find CMPIProvider Module in cache: "
204 + *(parms->fileName));
205 ccode = -1;
206 }
|
207 schuur 1.1
|
208 konrad.r 1.24 break;
209 }
|
210 schuur 1.1
|
211 konrad.r 1.24 case INSERT_PROVIDER:
212 {
|
213 r.kieninger 1.14
|
214 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
215 "_provider_ctrl::INSERT_PROVIDER");
|
216 schuur 1.1
|
217 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
218 konrad.r 1.26
|
219 konrad.r 1.24 if (false == _providers.insert (*(parms->providerName),
220 *reinterpret_cast <
221 CMPIProvider * *>(parm)))
222 ccode = -1;
223 break;
224 }
225 case INSERT_MODULE:
226 {
227 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
228 "_provider_ctrl::INSERT_MODULE");
229 AutoMutex lock (_providerTableMutex);
230 if (false == _modules.insert (*(parms->fileName),
231 *reinterpret_cast <
232 CMPIProviderModule * *>(parm)))
233 ccode = -1;
234 break;
235 }
|
236 schuur 1.1
|
237 konrad.r 1.24 case UNLOAD_ALL_PROVIDERS:
238 {
239 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
240 "_provider_ctrl::UNLOAD_ALL_PROVIDERS");
241 CMPILocalProviderManager *myself =
242 reinterpret_cast < CMPILocalProviderManager * >(parm);
243 CMPIProvider *provider = 0;
244 // Locked provider mutex.
245 AutoMutex lock (_providerTableMutex);
|
246 dj.gorey 1.6
|
247 konrad.r 1.24 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
248 "providers in cache = %d", myself->_providers.size ());
249 ProviderTable::Iterator i = myself->_providers.start ();
250 try
251 {
252 for (; i != 0; i++)
253 {
|
254 r.kieninger 1.15
|
255 konrad.r 1.24 provider = i.value ();
256 PEGASUS_ASSERT (provider != 0);
257 if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
258 {
259 // Delete the skeleton.
260 delete provider;
261 continue;
262 }
263 else
264 {
265 _unloadProvider (provider);
266 delete provider;
267 }
268 }
269 // All the providers are removed. Clear the hash-table
270 _providers.clear ();
|
271 r.kieninger 1.14 }
|
272 konrad.r 1.24 catch (...)
|
273 r.kieninger 1.14 {
|
274 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
275 "Unexpected Exception in UNLOAD_ALL_PROVIDERS.");
|
276 r.kieninger 1.14 }
|
277 konrad.r 1.24 break;
278 }
279 case UNLOAD_IDLE_PROVIDERS:
280 {
281 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
282 "_provider_ctrl::UNLOAD_IDLE_PROVIDERS");
283 AutoMutex lock (_providerTableMutex);
284
285 quantum++;
286 CMPILocalProviderManager *myself =
287 reinterpret_cast < CMPILocalProviderManager * >(parm);
288 CMPIProvider *provider;
289 Uint32 numProviders = myself->_providers.size ();
290
291 if (numProviders)
292 {
293 // Rather than removing the provider immediately while
294 // iterating through the list we remember all candidates
295 // for unload in a simple array.
296 CMPIProvider **unloadProviderArray =
297 new CMPIProvider *[numProviders];
298 konrad.r 1.24 Uint32 upaIndex = 0;
|
299 r.kieninger 1.15
|
300 r.kieninger 1.14 try
301 {
|
302 konrad.r 1.24 struct timeval now;
303 gettimeofday (&now, NULL);
304 ProviderTable::Iterator i = myself->_providers.start ();
305
306 for (; i != 0; i++)
|
307 r.kieninger 1.14 {
|
308 konrad.r 1.24 provider = i.value ();
309 PEGASUS_ASSERT (provider != 0);
310
311 if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
|
312 r.kieninger 1.14 {
|
313 konrad.r 1.24 continue;
|
314 r.kieninger 1.14 }
|
315 konrad.r 1.24
316 if (provider->_quantum == quantum)
|
317 r.kieninger 1.14 {
|
318 konrad.r 1.24 continue;
|
319 r.kieninger 1.14 }
|
320 r.kieninger 1.15
|
321 konrad.r 1.24 provider->_quantum = quantum;
322
323 if (provider->_current_operations.value ())
324 {
325 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
326 "CMPIProvider has pending operations: "
327 + provider->getName ());
|
328 r.kieninger 1.14
|
329 konrad.r 1.24 continue;
|
330 r.kieninger 1.15 }
|
331 r.kieninger 1.14
|
332 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
333 "Checking timeout data for CMPIProvider: "
334 + provider->getName ());
335 struct timeval timeout = { 0, 0 };
336 provider->get_idle_timer (&timeout);
337
338 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
339 " provider->unload_ok() returns: " +
340 provider->unload_ok ()? "true" : "false");
341
342 if (provider->unload_ok () == true &&
343 (now.tv_sec - timeout.tv_sec) >
344 ((Sint32) myself->_idle_timeout))
345 {
346 // Remember this provider to be unloaded
347 unloadProviderArray[upaIndex] = provider;
348 upaIndex++;
|
349 r.kieninger 1.14 }
|
350 konrad.r 1.24 //else cout<<"--- NOT unloaded: "+ provider->getName()<<endl;
|
351 r.kieninger 1.14 }
|
352 konrad.r 1.24
353 // Now finally we unload all providers that we identified as
354 // candidates above.
355 for (Uint32 index = 0; index < upaIndex; index++)
356 {
357 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
358 "Now trying to unload CMPIProvider " +
359 provider->getName ());
360 CMPIProvider *provider = unloadProviderArray[index];
361
362 // lock the provider mutex
363
364 AutoMutex pr_lock (provider->_statusMutex);
365
366 if (provider->tryTerminate () == false)
367 {
368 // provider not unloaded -- we are respecting this!
369 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
370 "Provider refused to unload: " +
|
371 konrad.r 1.26 unloadProviderArray[index]->getName());
|
372 konrad.r 1.24 continue;
373 }
374
|
375 mark.hamzy 1.28 // delete from _provider table
376 if (!_providers.remove (provider->_name))
377 {
378 PEGASUS_ASSERT (0);
379 }
380
|
381 konrad.r 1.24 // delete the cimom handle
382 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
383 "Destroying CMPIProvider's CIMOM Handle "
|
384 konrad.r 1.26 + provider->getName());
|
385 konrad.r 1.24 delete provider->_cimom_handle;
386
387 PEGASUS_ASSERT (provider->_module != 0);
388
389 // unload provider module
390 provider->_module->unloadModule ();
391 Logger::put (Logger::STANDARD_LOG, System::CIMSERVER,
392 Logger::TRACE,
393 "CMPILocalProviderManager::_provider_crtl - Unload provider $0",
394 provider->getName ());
395
396 // set provider status to UNINITIALIZED
397 provider->reset ();
398
399 delete provider;
|
400 r.kieninger 1.14 }
|
401 konrad.r 1.24 }
402 catch (...)
403 {
404 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
405 "Unexpected Exception in UNLOAD_IDLE_PROVIDERS.");
406 }
|
407 r.kieninger 1.15 delete unloadProviderArray;
|
408 konrad.r 1.24 } // if there are any providers
409 break;
410 }
|
411 r.kieninger 1.14
412 default:
|
413 konrad.r 1.24 ccode = -1;
414 break;
|
415 r.kieninger 1.14 }
|
416 konrad.r 1.24 PEG_METHOD_EXIT ();
417 return (ccode);
|
418 schuur 1.1 }
419
|
420 konrad.r 1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
421 getRemoteProvider (const String & location, const String & providerName)
422 {
423 CMPIProvider::OpProviderHolder ph;
424 CTRL_STRINGS
425 strings;
426 Sint32
427 ccode;
428 const String
429 proxy ("CMPIRProxyProvider");
430
431 String
432 rproviderName ("R");
433 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
434 "ProvidertManager::getRemoteProvider");
435
436 rproviderName.append (providerName);
437
438 strings.fileName = &proxy;
439 strings.providerName = &rproviderName;
440 strings.location = &location;
441 konrad.r 1.24
442 try
443 {
444 ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
445 }
446 catch (const Exception & e)
447 {
|
448 konrad.r 1.27 DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
|
449 konrad.r 1.24 PEG_METHOD_EXIT ();
450 throw;
451 }
452 catch (...)
453 {
454 PEG_METHOD_EXIT ();
455 throw;
456 } CMPIProvider & prov = ph.GetProvider ();
|
457 schuur 1.10
|
458 konrad.r 1.24 PEG_METHOD_EXIT ();
459 return (ph);
|
460 schuur 1.1
461 }
462
|
463 konrad.r 1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
464 getProvider (const String & fileName, const String & providerName)
|
465 r.kieninger 1.14 {
|
466 konrad.r 1.24 CMPIProvider::OpProviderHolder ph;
467 CTRL_STRINGS
468 strings;
469 Sint32
470 ccode;
|
471 r.kieninger 1.15
|
472 konrad.r 1.24 String
473 lproviderName ("L");
474 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::getProvider");
|
475 konrad.r 1.26 if (fileName.size() == 0)
476 {
477 throw Exception(MessageLoaderParms("ProviderManager.CMPI.CMPILocalProviderManager.CANNOT_FIND_LIBRARY",
478 "Provider library $0 was not found.",
479 fileName));
|
480 r.kieninger 1.15
|
481 konrad.r 1.26 }
|
482 konrad.r 1.24 lproviderName.append (providerName);
483 strings.fileName = &fileName;
484 strings.providerName = &lproviderName;
485 strings.location = &String::EMPTY;
|
486 r.kieninger 1.14
|
487 konrad.r 1.24 try
488 {
489 ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
490 }
491 catch (const Exception & e)
492 {
|
493 konrad.r 1.27 DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
|
494 konrad.r 1.24 PEG_METHOD_EXIT ();
495 throw;
496 }
497 catch (...)
498 {
499 PEG_METHOD_EXIT ();
500 throw;
501 }
|
502 schuur 1.1
503
|
504 konrad.r 1.24 PEG_METHOD_EXIT ();
505 return (ph);
|
506 schuur 1.1
507 }
508
|
509 konrad.r 1.24 void
510 CMPILocalProviderManager::unloadProvider (const String & fileName,
511 const String & providerName)
|
512 r.kieninger 1.14 {
|
513 konrad.r 1.24 CTRL_STRINGS strings;
514 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::unloadProvider");
|
515 konrad.r 1.25
516 String lproviderName ("L");
517 String rproviderName ("R");
518 lproviderName.append (providerName);
519 rproviderName.append (providerName);
520
|
521 konrad.r 1.24 strings.fileName = &fileName;
|
522 konrad.r 1.25 strings.providerName = &lproviderName;
523 strings.location = &String::EMPTY;
|
524 konrad.r 1.24 _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
|
525 konrad.r 1.25
526 strings.providerName = &rproviderName;
527
528 _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
529
|
530 konrad.r 1.24 PEG_METHOD_EXIT ();
|
531 r.kieninger 1.14 }
532
|
533 konrad.r 1.24 void
534 CMPILocalProviderManager::shutdownAllProviders (void)
|
535 r.kieninger 1.14 {
536
|
537 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
538 "ProviderManager::shutdownAllProviders");
539 _provider_ctrl (UNLOAD_ALL_PROVIDERS, (void *) this, (void *) 0);
540 PEG_METHOD_EXIT ();
|
541 r.kieninger 1.13 }
542
543
|
544 konrad.r 1.24 Boolean
545 CMPILocalProviderManager::hasActiveProviders ()
|
546 r.kieninger 1.14 {
|
547 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
548 "ProviderManager::hasActiveProviders");
|
549 r.kieninger 1.14
|
550 konrad.r 1.24 try
551 {
552 AutoMutex lock (_providerTableMutex);
553 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
554 "providers in _providers table = %d", _providers.size ());
|
555 r.kieninger 1.14
|
556 konrad.r 1.24 // Iterate through the _providers table looking for an active provider
557 for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
558 {
559 if (i.value ()->getStatus () == CMPIProvider::INITIALIZED)
560 {
561 PEG_METHOD_EXIT ();
562 return true;
563 }
564 }
565 }
566 catch (...)
567 {
568 // Unexpected exception; do not assume that no providers are loaded
569 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
570 "Unexpected Exception in hasActiveProviders.");
571 PEG_METHOD_EXIT ();
572 return true;
573 }
|
574 r.kieninger 1.14
|
575 konrad.r 1.24 // No active providers were found in the _providers table
576 PEG_METHOD_EXIT ();
577 return false;
|
578 r.kieninger 1.14 }
579
|
580 konrad.r 1.24 void
581 CMPILocalProviderManager::unloadIdleProviders (void)
|
582 r.kieninger 1.14 {
|
583 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
584 "ProviderManager::unloadIdleProviders");
|
585 r.kieninger 1.14
|
586 konrad.r 1.24 static struct timeval first = { 0, 0 }, now, last =
587 {
588 0, 0};
|
589 r.kieninger 1.15
|
590 konrad.r 1.24 if (first.tv_sec == 0)
|
591 r.kieninger 1.14 {
|
592 konrad.r 1.24 gettimeofday (&first, NULL);
|
593 r.kieninger 1.14 }
|
594 konrad.r 1.24 gettimeofday (&now, NULL);
|
595 r.kieninger 1.14
|
596 konrad.r 1.24 if (((now.tv_sec - first.tv_sec) > IDLE_LIMIT) &&
597 ((now.tv_sec - last.tv_sec) > IDLE_LIMIT))
|
598 r.kieninger 1.14 {
|
599 konrad.r 1.24 gettimeofday (&last, NULL);
600 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
601 "Checking for Idle providers to unload.");
602 try
603 {
604 _provider_ctrl (UNLOAD_IDLE_PROVIDERS, this, (void *) 0);
605 }
606 catch (...)
607 {
608 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
609 "Caught unexpected exception from UNLOAD_IDLE_PROVIDERS.");
610 }
|
611 r.kieninger 1.14 }
|
612 konrad.r 1.24 PEG_METHOD_EXIT ();
|
613 schuur 1.1 }
614
|
615 konrad.r 1.24 Array <
616 CMPIProvider * >CMPILocalProviderManager::getIndicationProvidersToEnable ()
|
617 carolann.graves 1.17 {
|
618 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
619 "CMPILocalProviderManager::getIndicationProvidersToEnable");
|
620 carolann.graves 1.17
|
621 konrad.r 1.24 Array < CMPIProvider * >enableProviders;
|
622 carolann.graves 1.17
|
623 konrad.r 1.24 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
624 "Number of providers in _providers table = %d",
625 _providers.size ());
|
626 carolann.graves 1.17
|
627 konrad.r 1.24 try
628 {
629 AutoMutex
630 lock (_providerTableMutex);
|
631 carolann.graves 1.17
|
632 konrad.r 1.24 //
633 // Iterate through the _providers table
634 //
635 for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
636 {
|
637 carolann.graves 1.17 //
|
638 konrad.r 1.24 // Enable any indication provider with current subscriptions
|
639 carolann.graves 1.17 //
|
640 konrad.r 1.24 CMPIProvider *
641 provider = i.value ();
642 if (provider->testSubscriptions ())
643 {
644 enableProviders.append (provider);
645 }
646 }
647
648 }
649 catch (const CIMException & e)
650 {
651 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
652 "CIMException: " + e.getMessage ());
653 }
654 catch (const Exception & e)
655 {
656 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
657 "Exception: " + e.getMessage ());
658 }
659 catch (...)
660 {
661 konrad.r 1.24 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
662 "Unexpected error in getIndicationProvidersToEnable");
663 }
664
665 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
666 "Number of indication providers to enable = %d",
667 enableProviders.size ());
668
669 PEG_METHOD_EXIT ();
670 return enableProviders;
671 }
672
673 CMPIProvider *
674 CMPILocalProviderManager::_initProvider (CMPIProvider * provider,
675 const String & moduleFileName)
676 {
677 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_initProvider");
|
678 carolann.graves 1.17
|
679 konrad.r 1.24 CMPIProviderModule *module = 0;
680 ProviderVector base;
|
681 carolann.graves 1.17
|
682 konrad.r 1.24 {
683 // lock the providerTable mutex
684 AutoMutex lock (_providerTableMutex);
|
685 carolann.graves 1.17
|
686 konrad.r 1.24 // lookup provider module
687 module = _lookupModule (moduleFileName);
688 } // unlock the providerTable mutex
|
689 schuur 1.1
|
690 konrad.r 1.24 Boolean deleteProvider = false;
|
691 konrad.r 1.26 String exceptionMsg = moduleFileName;
|
692 konrad.r 1.24 {
693 // lock the provider status mutex
694 AutoMutex lock (provider->_statusMutex);
|
695 r.kieninger 1.14
|
696 konrad.r 1.24 if (provider->_status == CMPIProvider::INITIALIZED)
697 {
698 // Initialization is already complete
699 return provider;
700 }
|
701 r.kieninger 1.14
|
702 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
703 "Loading/Linking Provider Module " + moduleFileName);
|
704 kumpf 1.18
|
705 konrad.r 1.24 // load the provider
706 try
707 {
708 base = module->load (provider->_name);
709 }
|
710 konrad.r 1.26 catch (const Exception &e)
711 {
712 exceptionMsg = e.getMessage();
713 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
714 "Exception caught Loading/Linking Provider Module " +
715 moduleFileName+ " error is: "+exceptionMsg);
716 deleteProvider =true;
717 }
|
718 konrad.r 1.24 catch (...)
|
719 kumpf 1.18 {
|
720 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
721 konrad.r 1.26 "Unknown exception caught Loading/Linking Provider Module " +
|
722 konrad.r 1.24 moduleFileName);
|
723 konrad.r 1.26 exceptionMsg = moduleFileName;
|
724 konrad.r 1.24 }
|
725 konrad.r 1.26 if (!deleteProvider)
726 {
727 // initialize the provider
728 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
729 "Initializing Provider " + provider->getName());
|
730 r.kieninger 1.14
|
731 konrad.r 1.26 CIMOMHandle *cimomHandle = new CIMOMHandle ();
732 provider->set (module, base, cimomHandle);
733 provider->_quantum = 0;
|
734 konrad.r 1.24
|
735 konrad.r 1.26 try
736 {
737 provider->initialize (*(provider->_cimom_handle));
738 }
739 catch (const Exception &e)
740 {
741 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
742 "Problem initializing: " + e.getMessage());
743 deleteProvider = true;
744 exceptionMsg = e.getMessage();
745 }
746 catch (...)
747 {
748 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
749 "Unknown problem initializing " + provider->getName());
750 deleteProvider = true;
751 exceptionMsg = provider->getName();
752 }
753 } // unlock the provider status mutex
754 }
755 /* We wait until this moment to delete the provider b/c we need
756 konrad.r 1.26 be outside the scope for the AutoMutex for the provider. */
757 if (deleteProvider)
758 {
|
759 konrad.r 1.24 // delete the cimom handle
760 delete provider->_cimom_handle;
761 // set provider status to UNINITIALIZED
762 provider->reset ();
763 // unload provider module
764 module->unloadModule ();
|
765 r.kieninger 1.14
|
766 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
767 konrad.r 1.26 _providers.remove (provider->_name);
|
768 konrad.r 1.24 delete provider;
|
769 konrad.r 1.26
770 PEG_METHOD_EXIT ();
771 throw Exception(exceptionMsg);
|
772 r.kieninger 1.14 }
773
|
774 konrad.r 1.24 PEG_METHOD_EXIT ();
775 return (provider);
|
776 r.kieninger 1.14 }
777
778
|
779 konrad.r 1.24 void
780 CMPILocalProviderManager::_unloadProvider (CMPIProvider * provider)
|
781 r.kieninger 1.14 {
|
782 konrad.r 1.24 //
783 // NOTE: It is the caller's responsibility to make sure that
784 // the ProviderTable mutex is locked before calling this method.
785 //
786 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_unloadProvider");
|
787 r.kieninger 1.14
|
788 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
789 konrad.r 1.26 "Unloading Provider " + provider->getName());
|
790 r.kieninger 1.14
|
791 konrad.r 1.24 if (provider->_current_operations.value ())
|
792 r.kieninger 1.14 {
|
793 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
794 "Provider cannot be unloaded due to pending operations: "
|
795 konrad.r 1.26 + provider->getName());
|
796 r.kieninger 1.14 }
|
797 konrad.r 1.24 else
|
798 r.kieninger 1.14 {
|
799 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
800 konrad.r 1.26 "Terminating Provider " + provider->getName());
|
801 konrad.r 1.24
|
802 r.kieninger 1.14
|
803 konrad.r 1.24 // lock the provider mutex
804 AutoMutex pr_lock (provider->_statusMutex);
|
805 r.kieninger 1.14
|
806 konrad.r 1.24 try
807 {
808 provider->terminate ();
809 }
810 catch (...)
811 {
812 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL3,
813 "Error occured terminating CMPI provider " +
|
814 konrad.r 1.26 provider->getName());
|
815 konrad.r 1.24 }
|
816 r.kieninger 1.14
|
817 konrad.r 1.24 // delete the cimom handle
818 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
819 "Destroying CMPIProvider's CIMOM Handle " +
|
820 konrad.r 1.26 provider->getName());
|
821 r.kieninger 1.14
|
822 konrad.r 1.24 delete provider->_cimom_handle;
823 PEGASUS_ASSERT (provider->_module != 0);
|
824 r.kieninger 1.14
|
825 konrad.r 1.24 // unload provider module
826 provider->_module->unloadModule ();
827 Logger::put (Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
828 "CMPILocalProviderManager::_provider_crtl - Unload provider $0",
829 provider->getName ());
|
830 r.kieninger 1.14
|
831 konrad.r 1.24 // set provider status to UNINITIALIZED
832 provider->reset ();
|
833 r.kieninger 1.14
|
834 konrad.r 1.24 // Do not delete the provider. The function calling this function
835 // takes care of that.
|
836 r.kieninger 1.14 }
|
837 r.kieninger 1.13
|
838 konrad.r 1.24 PEG_METHOD_EXIT ();
|
839 dj.gorey 1.6 }
840
|
841 konrad.r 1.24 CMPIProvider *
842 CMPILocalProviderManager::_lookupProvider (const String & providerName)
|
843 r.kieninger 1.14 {
|
844 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupProvider");
845 // lock the providerTable mutex
846 AutoMutex lock (_providerTableMutex);
|
847 r.kieninger 1.14
|
848 konrad.r 1.24 // look up provider in cache
849 CMPIProvider *pr = 0;
850 if (true == _providers.lookup (providerName, pr))
|
851 r.kieninger 1.14 {
|
852 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
853 "Found Provider " + providerName +
854 " in CMPI Provider Manager Cache");
|
855 r.kieninger 1.14 }
|
856 konrad.r 1.24 else
|
857 r.kieninger 1.14 {
|
858 konrad.r 1.24 // create provider
859 pr = new CMPIProvider (providerName, 0, 0);
860 // insert provider in provider table
861 _providers.insert (providerName, pr);
|
862 r.kieninger 1.14
|
863 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
864 "Created provider " + pr->getName ());
|
865 r.kieninger 1.14 }
|
866 dj.gorey 1.6
|
867 konrad.r 1.24 PEG_METHOD_EXIT ();
868 return (pr);
|
869 dj.gorey 1.6 }
870
871
|
872 konrad.r 1.24 CMPIProviderModule *
873 CMPILocalProviderManager::_lookupModule (const String & moduleFileName)
|
874 r.kieninger 1.14 {
|
875 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupModule");
|
876 r.kieninger 1.14
|
877 konrad.r 1.24 // look up provider module in cache
878 CMPIProviderModule *module = 0;
|
879 r.kieninger 1.14
|
880 konrad.r 1.24 if (true == _modules.lookup (moduleFileName, module))
|
881 r.kieninger 1.14 {
|
882 konrad.r 1.24 // found provider module in cache
883 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
884 "Found Provider Module" + moduleFileName +
885 " in Provider Manager Cache");
|
886 dj.gorey 1.6
|
887 konrad.r 1.24 }
888 else
889 {
890 // provider module not found in cache, create provider module
891 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
892 "Creating CMPI Provider Module " + moduleFileName);
|
893 r.kieninger 1.14
|
894 konrad.r 1.24 module = new CMPIProviderModule (moduleFileName);
|
895 r.kieninger 1.14
|
896 konrad.r 1.24 // insert provider module in module table
897 _modules.insert (moduleFileName, module);
|
898 r.kieninger 1.14 }
|
899 dj.gorey 1.6
|
900 konrad.r 1.24 PEG_METHOD_EXIT ();
901 return (module);
|
902 schuur 1.1 }
903
904 PEGASUS_NAMESPACE_END
|