1 karl 1.33 //%2006////////////////////////////////////////////////////////////////////////
|
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 karl 1.33 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 schuur 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.16 //
|
21 schuur 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 schuur 1.10 #include "CMPI_Version.h"
35
|
36 schuur 1.1 #include <Pegasus/Common/Constants.h>
|
37 mike 1.38 #include <Pegasus/Common/Time.h>
|
38 schuur 1.1 #include <Pegasus/Common/Tracer.h>
39 #include <Pegasus/Common/PegasusVersion.h>
40
|
41 konrad.r 1.26 #include <Pegasus/Common/MessageLoader.h>
42
|
43 schuur 1.1 #include <Pegasus/ProviderManager2/CMPI/CMPIProvider.h>
44 #include <Pegasus/ProviderManager2/CMPI/CMPIProviderModule.h>
|
45 konrad.r 1.30 #include <Pegasus/ProviderManager2/CMPI/CMPILocalProviderManager.h>
|
46 kumpf 1.9
|
47 schuur 1.3 PEGASUS_USING_STD;
|
48 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
|
49 konrad.r 1.27 #define DDD(X) if (_cmpi_trace) X;
50
51 extern int _cmpi_trace;
52
|
53 schuur 1.8 #undef IDLE_LIMIT
54 #define IDLE_LIMIT 50
|
55 konrad.r 1.30
56 /* Thread deletion specific */
57 Semaphore CMPILocalProviderManager::_pollingSem(0);
58 AtomicInt CMPILocalProviderManager::_stopPolling(0);
59 Thread *CMPILocalProviderManager::_reaperThread = 0;
|
60 mike 1.38 List<CMPILocalProviderManager::cleanupThreadRecord,Mutex> CMPILocalProviderManager::_finishedThreadList;
61 Mutex CMPILocalProviderManager::_reaperMutex;
|
62 konrad.r 1.30
|
63 konrad.r 1.24 CMPILocalProviderManager::CMPILocalProviderManager (void):
64 _idle_timeout (IDLE_LIMIT)
|
65 r.kieninger 1.14 {
|
66 schuur 1.1 }
67
|
68 konrad.r 1.24 CMPILocalProviderManager::~CMPILocalProviderManager (void)
|
69 r.kieninger 1.14 {
|
70 konrad.r 1.24 Uint32 ccode;
|
71 dj.gorey 1.6
|
72 konrad.r 1.24 _provider_ctrl (UNLOAD_ALL_PROVIDERS, this, &ccode);
73 // Since all of the providers are deleted we can delete the
74 // modules too.
75 for (ModuleTable::Iterator j = _modules.start (); j != 0; j++)
76 {
77 CMPIProviderModule *module = j.value ();
78 delete module;
79 }
|
80 konrad.r 1.30
81 if (_reaperThread)
82 {
83 AutoMutex lock(_reaperMutex);
84 _stopPolling++;
85 _pollingSem.signal();
86 // Wait until it finishes itself.
87 _reaperThread->join();
88 delete _reaperThread;
89 _reaperThread = 0;
90 }
91 PEGASUS_ASSERT(_finishedThreadList.size() == 0);
92
|
93 schuur 1.1 }
94
|
95 konrad.r 1.24 Sint32
96 CMPILocalProviderManager::_provider_ctrl (CTRL code, void *parm, void *ret)
|
97 r.kieninger 1.14 {
|
98 r.kieninger 1.13
|
99 konrad.r 1.24 static Uint32 quantum;
100 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_provider_ctrl");
|
101 r.kieninger 1.13
|
102 konrad.r 1.24 Sint32 ccode = 0;
103 CTRL_STRINGS *parms = reinterpret_cast < CTRL_STRINGS * >(parm);
|
104 r.kieninger 1.13
|
105 konrad.r 1.24 switch (code)
|
106 r.kieninger 1.14 {
107
108 case GET_PROVIDER:
|
109 konrad.r 1.24 {
|
110 r.kieninger 1.14
|
111 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
112 "_provider_ctrl::GET_PROVIDER");
|
113 r.kieninger 1.14
|
114 konrad.r 1.24 String providerName = *(parms->providerName);
115 String moduleFileName = *(parms->fileName);
116 String location = *(parms->location);
|
117 r.kieninger 1.14
|
118 konrad.r 1.24 CMPIProvider *pr = 0;
119 CMPIProvider::OpProviderHolder * ph =
120 reinterpret_cast < CMPIProvider::OpProviderHolder * >(ret);
|
121 r.kieninger 1.14
|
122 konrad.r 1.24 pr = _lookupProvider (providerName);
|
123 r.kieninger 1.15
|
124 konrad.r 1.24 if (pr->getStatus () != CMPIProvider::INITIALIZED)
125 {
126 pr->setLocation (location);
127 _initProvider (pr, moduleFileName);
|
128 r.kieninger 1.13
|
129 konrad.r 1.24 if (pr->getStatus () != CMPIProvider::INITIALIZED)
130 {
131 PEG_METHOD_EXIT ();
132 throw PEGASUS_CIM_EXCEPTION (CIM_ERR_FAILED,
133 "provider initialization failed");
134 }
135 }
|
136 r.kieninger 1.13
137
|
138 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
139 "Returning Provider" + providerName);
|
140 schuur 1.1
|
141 r.kieninger 1.15
|
142 konrad.r 1.24 ph->SetProvider (pr);
143 ph->GetProvider ().update_idle_timer ();
144 break;
145 }
|
146 r.kieninger 1.14
147 case UNLOAD_PROVIDER:
|
148 konrad.r 1.24 {
149
150 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
151 "_provider_ctrl::UNLOAD_PROVIDER");
|
152 konrad.r 1.30 CMPIProvider *pr = 0;
153 pr = _lookupProvider (*(parms->providerName));
|
154 konrad.r 1.24 if ((pr->getStatus () == CMPIProvider::INITIALIZED))
155 {
|
156 r.kieninger 1.14
|
157 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
158 konrad.r 1.26 "Unloading CMPIProvider: " + pr->getName());
|
159 r.kieninger 1.14
|
160 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
161 // The provider table must be locked before unloading.
162 _providers.remove (pr->_name);
163 _unloadProvider (pr);
164 delete pr;
|
165 r.kieninger 1.14
|
166 konrad.r 1.24 }
|
167 konrad.r 1.25 else {
168 // No need to have a memory leak.
|
169 konrad.r 1.29 _providers.remove(pr->_name);
|
170 konrad.r 1.25 delete pr;
171 }
|
172 konrad.r 1.24 break;
173 }
|
174 schuur 1.1
|
175 r.kieninger 1.14 case LOOKUP_PROVIDER:
|
176 konrad.r 1.24 {
177
178 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
179 "_provider_ctrl::LOOKUP_PROVIDER");
|
180 schuur 1.1
|
181 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
182 schuur 1.1
|
183 konrad.r 1.24 if (true == _providers.lookup (*(parms->providerName),
184 *(reinterpret_cast <
185 CMPIProvider * *>(ret))))
186 {
187 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
188 "Found CMPIProvider in cache: " +
189 *(parms->providerName));
190
191 (*(reinterpret_cast < CMPIProvider * *>(ret)))->
192 update_idle_timer ();
193 }
194 else
195 {
196
197 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
198 "Could not find CMPIProvider in cache: " +
199 *(parms->providerName));
200 ccode = -1;
201 }
|
202 dj.gorey 1.6
|
203 konrad.r 1.24 break;
204 }
|
205 schuur 1.1
|
206 konrad.r 1.24 case LOOKUP_MODULE:
207 {
|
208 schuur 1.1
|
209 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
210 "_provider_ctrl::LOOKUP_MODULE");
|
211 schuur 1.1
|
212 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
213 schuur 1.1
|
214 konrad.r 1.24 if (false == _modules.lookup (*(parms->fileName),
215 *(reinterpret_cast <
216 CMPIProviderModule * *>(ret))))
217 {
218 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
219 "Could not find CMPIProvider Module in cache: "
220 + *(parms->fileName));
221 ccode = -1;
222 }
|
223 schuur 1.1
|
224 konrad.r 1.24 break;
225 }
|
226 schuur 1.1
|
227 konrad.r 1.24 case INSERT_PROVIDER:
228 {
|
229 r.kieninger 1.14
|
230 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
231 "_provider_ctrl::INSERT_PROVIDER");
|
232 schuur 1.1
|
233 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
234 konrad.r 1.26
|
235 konrad.r 1.24 if (false == _providers.insert (*(parms->providerName),
236 *reinterpret_cast <
237 CMPIProvider * *>(parm)))
238 ccode = -1;
239 break;
240 }
241 case INSERT_MODULE:
242 {
243 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
244 "_provider_ctrl::INSERT_MODULE");
245 AutoMutex lock (_providerTableMutex);
246 if (false == _modules.insert (*(parms->fileName),
247 *reinterpret_cast <
248 CMPIProviderModule * *>(parm)))
249 ccode = -1;
250 break;
251 }
|
252 schuur 1.1
|
253 konrad.r 1.24 case UNLOAD_ALL_PROVIDERS:
254 {
255 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
256 "_provider_ctrl::UNLOAD_ALL_PROVIDERS");
257 CMPILocalProviderManager *myself =
258 reinterpret_cast < CMPILocalProviderManager * >(parm);
259 CMPIProvider *provider = 0;
260 // Locked provider mutex.
261 AutoMutex lock (_providerTableMutex);
|
262 dj.gorey 1.6
|
263 konrad.r 1.24 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
264 "providers in cache = %d", myself->_providers.size ());
265 ProviderTable::Iterator i = myself->_providers.start ();
266 try
267 {
268 for (; i != 0; i++)
269 {
|
270 r.kieninger 1.15
|
271 konrad.r 1.24 provider = i.value ();
272 PEGASUS_ASSERT (provider != 0);
273 if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
274 {
275 // Delete the skeleton.
|
276 konrad.r 1.30 delete provider;
|
277 konrad.r 1.24 continue;
278 }
279 else
280 {
281 _unloadProvider (provider);
282 delete provider;
283 }
284 }
285 // All the providers are removed. Clear the hash-table
286 _providers.clear ();
|
287 r.kieninger 1.14 }
|
288 konrad.r 1.24 catch (...)
|
289 r.kieninger 1.14 {
|
290 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
291 "Unexpected Exception in UNLOAD_ALL_PROVIDERS.");
|
292 r.kieninger 1.14 }
|
293 konrad.r 1.24 break;
294 }
295 case UNLOAD_IDLE_PROVIDERS:
296 {
297 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
298 "_provider_ctrl::UNLOAD_IDLE_PROVIDERS");
299 AutoMutex lock (_providerTableMutex);
300
301 quantum++;
302 CMPILocalProviderManager *myself =
303 reinterpret_cast < CMPILocalProviderManager * >(parm);
|
304 kumpf 1.32 CMPIProvider *provider = 0;
|
305 konrad.r 1.24 Uint32 numProviders = myself->_providers.size ();
306
307 if (numProviders)
308 {
309 // Rather than removing the provider immediately while
310 // iterating through the list we remember all candidates
311 // for unload in a simple array.
312 CMPIProvider **unloadProviderArray =
313 new CMPIProvider *[numProviders];
314 Uint32 upaIndex = 0;
|
315 r.kieninger 1.15
|
316 r.kieninger 1.14 try
317 {
|
318 konrad.r 1.24 struct timeval now;
|
319 mike 1.38 Time::gettimeofday (&now);
|
320 konrad.r 1.24 ProviderTable::Iterator i = myself->_providers.start ();
321
322 for (; i != 0; i++)
|
323 r.kieninger 1.14 {
|
324 konrad.r 1.24 provider = i.value ();
325 PEGASUS_ASSERT (provider != 0);
326
327 if (provider->getStatus () == CMPIProvider::UNINITIALIZED)
|
328 r.kieninger 1.14 {
|
329 konrad.r 1.24 continue;
|
330 r.kieninger 1.14 }
|
331 konrad.r 1.24
332 if (provider->_quantum == quantum)
|
333 r.kieninger 1.14 {
|
334 konrad.r 1.24 continue;
|
335 r.kieninger 1.14 }
|
336 r.kieninger 1.15
|
337 konrad.r 1.24 provider->_quantum = quantum;
338
|
339 mike 1.31 if (provider->_current_operations.get ())
|
340 konrad.r 1.24 {
341 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
342 "CMPIProvider has pending operations: "
343 + provider->getName ());
|
344 r.kieninger 1.14
|
345 konrad.r 1.24 continue;
|
346 r.kieninger 1.15 }
|
347 r.kieninger 1.14
|
348 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
349 "Checking timeout data for CMPIProvider: "
350 + provider->getName ());
351 struct timeval timeout = { 0, 0 };
352 provider->get_idle_timer (&timeout);
353
354 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
355 " provider->unload_ok() returns: " +
356 provider->unload_ok ()? "true" : "false");
357
358 if (provider->unload_ok () == true &&
359 (now.tv_sec - timeout.tv_sec) >
360 ((Sint32) myself->_idle_timeout))
361 {
362 // Remember this provider to be unloaded
363 unloadProviderArray[upaIndex] = provider;
364 upaIndex++;
|
365 r.kieninger 1.14 }
|
366 konrad.r 1.24 //else cout<<"--- NOT unloaded: "+ provider->getName()<<endl;
|
367 r.kieninger 1.14 }
|
368 konrad.r 1.24
369 // Now finally we unload all providers that we identified as
370 // candidates above.
371 for (Uint32 index = 0; index < upaIndex; index++)
372 {
373 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
374 "Now trying to unload CMPIProvider " +
375 provider->getName ());
376 CMPIProvider *provider = unloadProviderArray[index];
377
|
378 dave.sudlik 1.39 {
379 // lock the provider mutex
380
381 AutoMutex pr_lock (provider->_statusMutex);
|
382 konrad.r 1.24
|
383 dave.sudlik 1.39 if (provider->tryTerminate () == false)
384 {
385 // provider not unloaded -- we are respecting this!
386 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
387 "Provider refused to unload: " +
388 unloadProviderArray[index]->getName());
389 continue;
390 }
391
392 // delete from _provider table
393 if (!_providers.remove (provider->_name))
394 {
395 PEGASUS_ASSERT (0);
396 }
|
397 konrad.r 1.24
|
398 dave.sudlik 1.39 // delete the cimom handle
|
399 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
400 dave.sudlik 1.39 "Destroying CMPIProvider's CIMOM Handle "
401 + provider->getName());
402 delete provider->_cimom_handle;
403
404 PEGASUS_ASSERT (provider->_module != 0);
405
406 // unload provider module
407 provider->_module->unloadModule ();
408 Logger::put (Logger::STANDARD_LOG, System::CIMSERVER,
409 Logger::TRACE,
410 "CMPILocalProviderManager::_provider_crtl - Unload provider $0",
411 provider->getName ());
|
412 konrad.r 1.24
|
413 dave.sudlik 1.39 // set provider status to UNINITIALIZED
414 provider->reset ();
|
415 mark.hamzy 1.28 }
|
416 dave.sudlik 1.39 // We need to delete the provider instance outside of the scope
417 // of the provider mutex.
|
418 konrad.r 1.24 delete provider;
|
419 r.kieninger 1.14 }
|
420 konrad.r 1.24 }
421 catch (...)
422 {
423 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
424 "Unexpected Exception in UNLOAD_IDLE_PROVIDERS.");
425 }
|
426 r.kieninger 1.15 delete unloadProviderArray;
|
427 konrad.r 1.24 } // if there are any providers
428 break;
429 }
|
430 r.kieninger 1.14
431 default:
|
432 konrad.r 1.24 ccode = -1;
433 break;
|
434 r.kieninger 1.14 }
|
435 konrad.r 1.24 PEG_METHOD_EXIT ();
436 return (ccode);
|
437 schuur 1.1 }
438
|
439 konrad.r 1.30
440
441 /*
442 * The reaper function polls out the threads from the global list (_finishedThreadList),
443 * joins them deletes them, and removes them from the CMPIProvider specific list.
444 */
|
445 mike 1.38 ThreadReturnType PEGASUS_THREAD_CDECL CMPILocalProviderManager::_reaper(void *parm)
|
446 konrad.r 1.30 {
447 Thread *myself = reinterpret_cast<Thread *>(parm);
448 do {
449 _pollingSem.wait();
450 // All of the threads are finished working. We just need to reap 'em
451 cleanupThreadRecord *rec = 0;
452
453 while (_finishedThreadList.size() >0 )
454 {
455 // Pull of the the threads from the global list.
|
456 mike 1.35 rec = _finishedThreadList.remove_front();
|
457 konrad.r 1.30 DDD(cerr << "Reaping the thread " << rec->thread << " from " << rec->provider->getName() << endl);
458 rec->thread->join();
|
459 mike 1.35
460 // Remove the thread for the CMPIProvider.
|
461 dave.sudlik 1.34 rec->provider->threadDelete(rec->thread);
|
462 mike 1.35
463 // Delete the thread.
|
464 konrad.r 1.30 delete rec->thread;
465 delete rec;
466 }
467 }
|
468 mike 1.31 while (_stopPolling.get() == 0);
|
469 mike 1.38 myself->exit_self( (ThreadReturnType) 0);
|
470 konrad.r 1.30 return (0);
471 }
472 /*
473 // Cleanup the thread and upon deletion of it, call the CMPIProvider' "threadDeleted".
474 // to not, all the CMPIProvider '
475 // Note that this function is called from the thread that finished with
476 // running the providers function, and returns immediately while scheduling the
477 // a cleanup procedure. If you want to wait until the thread is truly deleted,
478 // call 'waitUntilThreadsDone' - but DO NOT do it in the the thread that
479 // the Thread owns - you will wait forever.
480 //
481 // @argument t Thread that is not NULL and finished with running the provider function.
482 // @argument p CMPIProvider in which the 't' Thread was running.
483 */
484 void
485 CMPILocalProviderManager::cleanupThread(Thread *t, CMPIProvider *p)
486 {
487 PEGASUS_ASSERT( t != 0 && p != 0 );
488
489 PEGASUS_ASSERT ( p->isThreadOwner(t) );
490 // The mutex guards against a race condition for _reaperThread creation.
491 konrad.r 1.30 AutoMutex lock(_reaperMutex);
492
493 // Put the Thread and the CMPIProvider on the global list.
494 cleanupThreadRecord *record = new cleanupThreadRecord(t, p);
|
495 mike 1.35 _finishedThreadList.insert_back(record);
|
496 konrad.r 1.30
497 if (_reaperThread == 0)
498 {
499 _reaperThread = new Thread(_reaper, NULL, false);
500 ThreadStatus rtn = PEGASUS_THREAD_OK;
501 while ( (rtn = _reaperThread->run()) != PEGASUS_THREAD_OK)
502 {
503 if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
|
504 mike 1.38 Threads::yield();
|
505 konrad.r 1.30 else
506 {
507 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, \
508 "Could not allocate thread to take care of deleting user threads. ");
509 delete _reaperThread; _reaperThread = 0;
510 return;
511 }
512 }
513 }/*
514 Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, \
515 "Cleaning up provider thread (%p) from provider %s.",
516 t, (const char *)p->getName().getCString());*/
517 // Wake up the reaper.
518 _pollingSem.signal();
519
520 }
521
|
522 konrad.r 1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
523 getRemoteProvider (const String & location, const String & providerName)
524 {
525 CMPIProvider::OpProviderHolder ph;
526 CTRL_STRINGS
527 strings;
528 Sint32
529 ccode;
530 const String
531 proxy ("CMPIRProxyProvider");
532
533 String
534 rproviderName ("R");
535 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
536 "ProvidertManager::getRemoteProvider");
537
538 rproviderName.append (providerName);
539
540 strings.fileName = &proxy;
541 strings.providerName = &rproviderName;
542 strings.location = &location;
543 konrad.r 1.24
544 try
545 {
546 ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
547 }
548 catch (const Exception & e)
549 {
|
550 konrad.r 1.27 DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
|
551 konrad.r 1.24 PEG_METHOD_EXIT ();
552 throw;
553 }
554 catch (...)
555 {
556 PEG_METHOD_EXIT ();
557 throw;
558 } CMPIProvider & prov = ph.GetProvider ();
|
559 schuur 1.10
|
560 konrad.r 1.24 PEG_METHOD_EXIT ();
561 return (ph);
|
562 schuur 1.1
563 }
564
|
565 konrad.r 1.24 CMPIProvider::OpProviderHolder CMPILocalProviderManager::
566 getProvider (const String & fileName, const String & providerName)
|
567 r.kieninger 1.14 {
|
568 konrad.r 1.24 CMPIProvider::OpProviderHolder ph;
569 CTRL_STRINGS
570 strings;
571 Sint32
572 ccode;
|
573 r.kieninger 1.15
|
574 konrad.r 1.24 String
575 lproviderName ("L");
576 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::getProvider");
|
577 konrad.r 1.26 if (fileName.size() == 0)
578 {
|
579 thilo.boehm 1.36 throw Exception(MessageLoaderParms(
580 "ProviderManager.CMPI.CMPILocalProviderManager.CANNOT_FIND_LIBRARY",
581 "For provider $0 the library name was empty. Check provider registered location.",
582 providerName));
|
583 r.kieninger 1.15
|
584 konrad.r 1.26 }
|
585 konrad.r 1.24 lproviderName.append (providerName);
586 strings.fileName = &fileName;
587 strings.providerName = &lproviderName;
588 strings.location = &String::EMPTY;
|
589 r.kieninger 1.14
|
590 konrad.r 1.24 try
591 {
592 ccode = _provider_ctrl (GET_PROVIDER, &strings, &ph);
593 }
594 catch (const Exception & e)
595 {
|
596 konrad.r 1.27 DDD(cerr << "--- loading proxy: " << e.getMessage () << endl);
|
597 konrad.r 1.24 PEG_METHOD_EXIT ();
598 throw;
599 }
600 catch (...)
601 {
602 PEG_METHOD_EXIT ();
603 throw;
604 }
|
605 schuur 1.1
606
|
607 konrad.r 1.24 PEG_METHOD_EXIT ();
608 return (ph);
|
609 schuur 1.1
610 }
611
|
612 konrad.r 1.24 void
613 CMPILocalProviderManager::unloadProvider (const String & fileName,
614 const String & providerName)
|
615 r.kieninger 1.14 {
|
616 konrad.r 1.24 CTRL_STRINGS strings;
617 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "ProviderManager::unloadProvider");
|
618 konrad.r 1.25
619 String lproviderName ("L");
620 String rproviderName ("R");
621 lproviderName.append (providerName);
622 rproviderName.append (providerName);
623
|
624 konrad.r 1.24 strings.fileName = &fileName;
|
625 konrad.r 1.25 strings.providerName = &lproviderName;
626 strings.location = &String::EMPTY;
|
627 konrad.r 1.24 _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
|
628 konrad.r 1.25
629 strings.providerName = &rproviderName;
630
631 _provider_ctrl (UNLOAD_PROVIDER, &strings, (void *) 0);
632
|
633 konrad.r 1.24 PEG_METHOD_EXIT ();
|
634 r.kieninger 1.14 }
635
|
636 konrad.r 1.24 void
637 CMPILocalProviderManager::shutdownAllProviders (void)
|
638 r.kieninger 1.14 {
639
|
640 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
641 "ProviderManager::shutdownAllProviders");
642 _provider_ctrl (UNLOAD_ALL_PROVIDERS, (void *) this, (void *) 0);
643 PEG_METHOD_EXIT ();
|
644 r.kieninger 1.13 }
645
646
|
647 konrad.r 1.24 Boolean
648 CMPILocalProviderManager::hasActiveProviders ()
|
649 r.kieninger 1.14 {
|
650 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
651 "ProviderManager::hasActiveProviders");
|
652 r.kieninger 1.14
|
653 konrad.r 1.24 try
654 {
655 AutoMutex lock (_providerTableMutex);
656 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
657 "providers in _providers table = %d", _providers.size ());
|
658 r.kieninger 1.14
|
659 konrad.r 1.24 // Iterate through the _providers table looking for an active provider
660 for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
661 {
662 if (i.value ()->getStatus () == CMPIProvider::INITIALIZED)
663 {
664 PEG_METHOD_EXIT ();
665 return true;
666 }
667 }
668 }
669 catch (...)
670 {
671 // Unexpected exception; do not assume that no providers are loaded
672 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
673 "Unexpected Exception in hasActiveProviders.");
674 PEG_METHOD_EXIT ();
675 return true;
676 }
|
677 r.kieninger 1.14
|
678 konrad.r 1.24 // No active providers were found in the _providers table
679 PEG_METHOD_EXIT ();
680 return false;
|
681 r.kieninger 1.14 }
682
|
683 konrad.r 1.24 void
684 CMPILocalProviderManager::unloadIdleProviders (void)
|
685 r.kieninger 1.14 {
|
686 kumpf 1.41 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
687 "ProviderManager::unloadIdleProviders");
|
688 r.kieninger 1.14
|
689 kumpf 1.41 try
|
690 r.kieninger 1.14 {
|
691 kumpf 1.41 _provider_ctrl (UNLOAD_IDLE_PROVIDERS, this, (void *) 0);
|
692 r.kieninger 1.14 }
|
693 kumpf 1.41 catch (...)
|
694 r.kieninger 1.14 {
|
695 kumpf 1.41 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
696 "Caught unexpected exception from UNLOAD_IDLE_PROVIDERS.");
|
697 r.kieninger 1.14 }
|
698 kumpf 1.41
699 PEG_METHOD_EXIT ();
|
700 schuur 1.1 }
701
|
702 konrad.r 1.24 Array <
703 CMPIProvider * >CMPILocalProviderManager::getIndicationProvidersToEnable ()
|
704 carolann.graves 1.17 {
|
705 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
706 "CMPILocalProviderManager::getIndicationProvidersToEnable");
|
707 carolann.graves 1.17
|
708 konrad.r 1.24 Array < CMPIProvider * >enableProviders;
|
709 carolann.graves 1.17
|
710 konrad.r 1.24 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
711 "Number of providers in _providers table = %d",
712 _providers.size ());
|
713 carolann.graves 1.17
|
714 konrad.r 1.24 try
715 {
716 AutoMutex
717 lock (_providerTableMutex);
|
718 carolann.graves 1.17
|
719 konrad.r 1.24 //
720 // Iterate through the _providers table
721 //
722 for (ProviderTable::Iterator i = _providers.start (); i != 0; i++)
723 {
|
724 carolann.graves 1.17 //
|
725 konrad.r 1.24 // Enable any indication provider with current subscriptions
|
726 carolann.graves 1.17 //
|
727 konrad.r 1.24 CMPIProvider *
728 provider = i.value ();
729 if (provider->testSubscriptions ())
730 {
731 enableProviders.append (provider);
732 }
733 }
734
735 }
736 catch (const CIMException & e)
737 {
738 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
739 "CIMException: " + e.getMessage ());
740 }
741 catch (const Exception & e)
742 {
743 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
744 "Exception: " + e.getMessage ());
745 }
746 catch (...)
747 {
748 konrad.r 1.24 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
749 "Unexpected error in getIndicationProvidersToEnable");
750 }
751
752 Tracer::trace (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
753 "Number of indication providers to enable = %d",
754 enableProviders.size ());
755
756 PEG_METHOD_EXIT ();
757 return enableProviders;
758 }
759
760 CMPIProvider *
761 CMPILocalProviderManager::_initProvider (CMPIProvider * provider,
762 const String & moduleFileName)
763 {
764 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_initProvider");
|
765 carolann.graves 1.17
|
766 konrad.r 1.24 CMPIProviderModule *module = 0;
767 ProviderVector base;
|
768 carolann.graves 1.17
|
769 konrad.r 1.24 {
770 // lock the providerTable mutex
771 AutoMutex lock (_providerTableMutex);
|
772 carolann.graves 1.17
|
773 konrad.r 1.24 // lookup provider module
774 module = _lookupModule (moduleFileName);
775 } // unlock the providerTable mutex
|
776 schuur 1.1
|
777 kumpf 1.37 Boolean moduleLoaded = false;
|
778 konrad.r 1.24 Boolean deleteProvider = false;
|
779 konrad.r 1.26 String exceptionMsg = moduleFileName;
|
780 konrad.r 1.24 {
781 // lock the provider status mutex
782 AutoMutex lock (provider->_statusMutex);
|
783 r.kieninger 1.14
|
784 konrad.r 1.24 if (provider->_status == CMPIProvider::INITIALIZED)
785 {
786 // Initialization is already complete
787 return provider;
788 }
|
789 r.kieninger 1.14
|
790 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
791 "Loading/Linking Provider Module " + moduleFileName);
|
792 kumpf 1.18
|
793 konrad.r 1.24 // load the provider
794 try
795 {
796 base = module->load (provider->_name);
|
797 kumpf 1.37 moduleLoaded = true;
|
798 konrad.r 1.24 }
|
799 konrad.r 1.26 catch (const Exception &e)
800 {
801 exceptionMsg = e.getMessage();
802 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
803 "Exception caught Loading/Linking Provider Module " +
804 moduleFileName+ " error is: "+exceptionMsg);
805 deleteProvider =true;
806 }
|
807 konrad.r 1.24 catch (...)
|
808 kumpf 1.18 {
|
809 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
810 konrad.r 1.26 "Unknown exception caught Loading/Linking Provider Module " +
|
811 konrad.r 1.24 moduleFileName);
|
812 konrad.r 1.26 exceptionMsg = moduleFileName;
|
813 kumpf 1.37 deleteProvider = true;
|
814 konrad.r 1.24 }
|
815 kumpf 1.37
|
816 konrad.r 1.26 if (!deleteProvider)
817 {
818 // initialize the provider
819 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
820 "Initializing Provider " + provider->getName());
|
821 r.kieninger 1.14
|
822 konrad.r 1.26 CIMOMHandle *cimomHandle = new CIMOMHandle ();
823 provider->set (module, base, cimomHandle);
824 provider->_quantum = 0;
|
825 konrad.r 1.24
|
826 konrad.r 1.26 try
827 {
828 provider->initialize (*(provider->_cimom_handle));
829 }
830 catch (const Exception &e)
831 {
832 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
833 "Problem initializing: " + e.getMessage());
834 deleteProvider = true;
835 exceptionMsg = e.getMessage();
836 }
837 catch (...)
838 {
839 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL2,
840 "Unknown problem initializing " + provider->getName());
841 deleteProvider = true;
842 exceptionMsg = provider->getName();
843 }
844 } // unlock the provider status mutex
845 }
846 /* We wait until this moment to delete the provider b/c we need
847 konrad.r 1.26 be outside the scope for the AutoMutex for the provider. */
848 if (deleteProvider)
849 {
|
850 konrad.r 1.24 // delete the cimom handle
851 delete provider->_cimom_handle;
852 // set provider status to UNINITIALIZED
853 provider->reset ();
|
854 kumpf 1.37
|
855 konrad.r 1.24 // unload provider module
|
856 kumpf 1.37 if (moduleLoaded)
857 {
858 module->unloadModule();
859 }
|
860 r.kieninger 1.14
|
861 konrad.r 1.24 AutoMutex lock (_providerTableMutex);
|
862 konrad.r 1.26 _providers.remove (provider->_name);
|
863 konrad.r 1.24 delete provider;
|
864 konrad.r 1.26
865 PEG_METHOD_EXIT ();
866 throw Exception(exceptionMsg);
|
867 r.kieninger 1.14 }
868
|
869 konrad.r 1.24 PEG_METHOD_EXIT ();
870 return (provider);
|
871 r.kieninger 1.14 }
872
873
|
874 konrad.r 1.24 void
875 CMPILocalProviderManager::_unloadProvider (CMPIProvider * provider)
|
876 r.kieninger 1.14 {
|
877 konrad.r 1.24 //
878 // NOTE: It is the caller's responsibility to make sure that
879 // the ProviderTable mutex is locked before calling this method.
880 //
881 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_unloadProvider");
|
882 r.kieninger 1.14
|
883 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
884 konrad.r 1.26 "Unloading Provider " + provider->getName());
|
885 r.kieninger 1.14
|
886 mike 1.31 if (provider->_current_operations.get ())
|
887 r.kieninger 1.14 {
|
888 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
889 "Provider cannot be unloaded due to pending operations: "
|
890 konrad.r 1.26 + provider->getName());
|
891 r.kieninger 1.14 }
|
892 konrad.r 1.24 else
|
893 r.kieninger 1.14 {
|
894 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
895 konrad.r 1.26 "Terminating Provider " + provider->getName());
|
896 konrad.r 1.24
|
897 r.kieninger 1.14
|
898 konrad.r 1.24 // lock the provider mutex
899 AutoMutex pr_lock (provider->_statusMutex);
|
900 r.kieninger 1.14
|
901 konrad.r 1.24 try
902 {
903 provider->terminate ();
904 }
905 catch (...)
906 {
907 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL3,
908 "Error occured terminating CMPI provider " +
|
909 konrad.r 1.26 provider->getName());
|
910 konrad.r 1.24 }
|
911 r.kieninger 1.14
|
912 konrad.r 1.24 // delete the cimom handle
913 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
914 "Destroying CMPIProvider's CIMOM Handle " +
|
915 konrad.r 1.26 provider->getName());
|
916 r.kieninger 1.14
|
917 konrad.r 1.24 delete provider->_cimom_handle;
918 PEGASUS_ASSERT (provider->_module != 0);
|
919 r.kieninger 1.14
|
920 konrad.r 1.24 // unload provider module
921 provider->_module->unloadModule ();
922 Logger::put (Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
923 "CMPILocalProviderManager::_provider_crtl - Unload provider $0",
924 provider->getName ());
|
925 r.kieninger 1.14
|
926 konrad.r 1.24 // set provider status to UNINITIALIZED
927 provider->reset ();
|
928 r.kieninger 1.14
|
929 konrad.r 1.24 // Do not delete the provider. The function calling this function
930 // takes care of that.
|
931 r.kieninger 1.14 }
|
932 r.kieninger 1.13
|
933 konrad.r 1.24 PEG_METHOD_EXIT ();
|
934 dj.gorey 1.6 }
935
|
936 konrad.r 1.24 CMPIProvider *
937 CMPILocalProviderManager::_lookupProvider (const String & providerName)
|
938 r.kieninger 1.14 {
|
939 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupProvider");
940 // lock the providerTable mutex
941 AutoMutex lock (_providerTableMutex);
942 // look up provider in cache
943 CMPIProvider *pr = 0;
944 if (true == _providers.lookup (providerName, pr))
|
945 r.kieninger 1.14 {
|
946 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
947 "Found Provider " + providerName +
948 " in CMPI Provider Manager Cache");
|
949 r.kieninger 1.14 }
|
950 konrad.r 1.24 else
|
951 r.kieninger 1.14 {
|
952 konrad.r 1.24 // create provider
953 pr = new CMPIProvider (providerName, 0, 0);
954 // insert provider in provider table
955 _providers.insert (providerName, pr);
|
956 r.kieninger 1.14
|
957 konrad.r 1.24 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
958 "Created provider " + pr->getName ());
|
959 r.kieninger 1.14 }
|
960 dj.gorey 1.6
|
961 konrad.r 1.24 PEG_METHOD_EXIT ();
962 return (pr);
|
963 dj.gorey 1.6 }
964
965
|
966 konrad.r 1.24 CMPIProviderModule *
967 CMPILocalProviderManager::_lookupModule (const String & moduleFileName)
|
968 r.kieninger 1.14 {
|
969 konrad.r 1.24 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER, "_lookupModule");
|
970 r.kieninger 1.14
|
971 konrad.r 1.24 // look up provider module in cache
972 CMPIProviderModule *module = 0;
|
973 r.kieninger 1.14
|
974 konrad.r 1.24 if (true == _modules.lookup (moduleFileName, module))
|
975 r.kieninger 1.14 {
|
976 konrad.r 1.24 // found provider module in cache
977 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
978 "Found Provider Module" + moduleFileName +
979 " in Provider Manager Cache");
|
980 dj.gorey 1.6
|
981 konrad.r 1.24 }
982 else
983 {
984 // provider module not found in cache, create provider module
985 PEG_TRACE_STRING (TRC_PROVIDERMANAGER, Tracer::LEVEL4,
986 "Creating CMPI Provider Module " + moduleFileName);
|
987 r.kieninger 1.14
|
988 konrad.r 1.24 module = new CMPIProviderModule (moduleFileName);
|
989 r.kieninger 1.14
|
990 konrad.r 1.24 // insert provider module in module table
991 _modules.insert (moduleFileName, module);
|
992 r.kieninger 1.14 }
|
993 dj.gorey 1.6
|
994 konrad.r 1.24 PEG_METHOD_EXIT ();
995 return (module);
|
996 schuur 1.1 }
997
998 PEGASUS_NAMESPACE_END
|