1 karl 1.75 //%2006////////////////////////////////////////////////////////////////////////
|
2 chip 1.1 //
|
3 karl 1.59 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.15 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.59 // 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.63 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.75 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 chip 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.59 //
|
21 chip 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Chip Vincent (cvincent@us.ibm.com)
33 //
34 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
35 // (carolann_graves@hp.com)
36 // Mike Day, IBM (mdday@us.ibm.com)
37 // Karl Schopmeyer(k.schopmeyer@opengroup.org) - Fix associators.
|
38 chip 1.9 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
|
39 schuur 1.19 // Adrian Schuur, IBM (schuur@de.ibm.com)
|
40 a.arora 1.37 // Amit K Arora (amita@in.ibm.com) for PEP-101
|
41 kumpf 1.39 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
|
42 se.gupta 1.41 // Seema Gupta (gseema@in.ibm.com for PEP135)
|
43 jim.wunderlich 1.69 // Jim Wunderlich (Jim_Wunderlich@prodigy.net)
|
44 aruran.ms 1.71 // Aruran, IBM (ashanmug@in.ibm.com)for Bug# 3881
|
45 chip 1.1 //
46 //%/////////////////////////////////////////////////////////////////////////////
47
48 #include "ProviderManagerService.h"
49
50 #include <Pegasus/Common/Config.h>
|
51 kumpf 1.65 #include <Pegasus/Common/PegasusVersion.h>
|
52 chip 1.1 #include <Pegasus/Common/Constants.h>
53 #include <Pegasus/Common/CIMMessage.h>
|
54 kumpf 1.39 #include <Pegasus/Common/Thread.h>
|
55 chip 1.1 #include <Pegasus/Common/Tracer.h>
56 #include <Pegasus/Common/Logger.h>
|
57 a.arora 1.37 #include <Pegasus/Common/AutoPtr.h>
|
58 chip 1.1
|
59 chip 1.6 #include <Pegasus/Config/ConfigManager.h>
60
|
61 kumpf 1.39 #include <Pegasus/ProviderManager2/BasicProviderManagerRouter.h>
|
62 kumpf 1.51 #include <Pegasus/ProviderManager2/OOPProviderManagerRouter.h>
|
63 brian.campbell 1.60 #include <Pegasus/ProviderManager2/OperationResponseHandler.h>
|
64 chip 1.17
|
65 chip 1.1 PEGASUS_NAMESPACE_BEGIN
66
|
67 chip 1.11 inline Boolean _isSupportedRequestType(const Message * message)
68 {
69 // ATTN: needs implementation
70
71 // for now, assume all requests are valid
72
73 return(true);
|
74 chip 1.3 }
75
76 inline Boolean _isSupportedResponseType(const Message * message)
77 {
|
78 chip 1.11 // ATTN: needs implementation
79
80 // for now, assume all responses are invalid
|
81 chip 1.3
|
82 chip 1.11 return(false);
|
83 chip 1.3 }
84
|
85 schuur 1.19 ProviderManagerService* ProviderManagerService::providerManagerService=NULL;
|
86 kumpf 1.39 Uint32 ProviderManagerService::_indicationServiceQueueId = PEG_NOT_FOUND;
|
87 schuur 1.19
|
88 chip 1.1 ProviderManagerService::ProviderManagerService(void)
89 : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
90 {
|
91 schuur 1.19 providerManagerService=this;
|
92 chip 1.1 }
93
|
94 schuur 1.25 ProviderManagerService::ProviderManagerService(
95 ProviderRegistrationManager * providerRegistrationManager,
|
96 mike 1.81 CIMRepository * repository,
|
97 kumpf 1.82 ProviderManager* (*createDefaultProviderManagerCallback)())
|
98 chip 1.1 : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
99 {
|
100 schuur 1.19 providerManagerService=this;
|
101 schuur 1.25 _repository=repository;
|
102 dj.gorey 1.31
|
103 kumpf 1.38 _providerRegistrationManager = providerRegistrationManager;
|
104 kumpf 1.44
105 _unloadIdleProvidersBusy = 0;
106
|
107 kumpf 1.62 _basicProviderManagerRouter = 0;
108 _oopProviderManagerRouter = 0;
109
110 // Determine which ProviderManagerRouter(s) to use
111
|
112 kumpf 1.51 ConfigManager* configManager = ConfigManager::getInstance();
|
113 kumpf 1.62 Boolean forceProviderProcesses = String::equal(
114 configManager->getCurrentValue("forceProviderProcesses"), "true");
115
116 #ifdef PEGASUS_DISABLE_PROV_USERCTXT
117 if (forceProviderProcesses)
|
118 kumpf 1.51 {
|
119 kumpf 1.76 _oopProviderManagerRouter = new OOPProviderManagerRouter(
|
120 carolann.graves 1.79 indicationCallback, responseChunkCallback,
121 providerModuleFailureCallback);
|
122 kumpf 1.51 }
123 else
124 {
|
125 kumpf 1.76 _basicProviderManagerRouter = new BasicProviderManagerRouter(
|
126 mike 1.81 indicationCallback, responseChunkCallback,
|
127 kumpf 1.82 createDefaultProviderManagerCallback);
|
128 kumpf 1.62 }
129 #else
|
130 kumpf 1.76 _oopProviderManagerRouter = new OOPProviderManagerRouter(
|
131 carolann.graves 1.79 indicationCallback, responseChunkCallback,
132 providerModuleFailureCallback);
|
133 kumpf 1.62
134 if (!forceProviderProcesses)
135 {
|
136 kumpf 1.76 _basicProviderManagerRouter = new BasicProviderManagerRouter(
|
137 kumpf 1.82 indicationCallback, responseChunkCallback,
138 createDefaultProviderManagerCallback);
|
139 kumpf 1.51 }
|
140 kumpf 1.62 #endif
|
141 chip 1.1 }
142
143 ProviderManagerService::~ProviderManagerService(void)
144 {
|
145 kumpf 1.62 delete _basicProviderManagerRouter;
146 delete _oopProviderManagerRouter;
|
147 schuur 1.19 providerManagerService=NULL;
|
148 chip 1.1 }
149
150 Boolean ProviderManagerService::messageOK(const Message * message)
151 {
152 PEGASUS_ASSERT(message != 0);
153
|
154 chip 1.3 if(_isSupportedRequestType(message))
|
155 chip 1.1 {
|
156 chip 1.3 return(MessageQueueService::messageOK(message));
|
157 chip 1.1 }
158
|
159 chip 1.3 return(false);
|
160 chip 1.1 }
161
162 void ProviderManagerService::handleEnqueue(void)
163 {
164 Message * message = dequeue();
165
166 handleEnqueue(message);
167 }
168
169 void ProviderManagerService::handleEnqueue(Message * message)
170 {
171 PEGASUS_ASSERT(message != 0);
172
173 AsyncLegacyOperationStart * asyncRequest;
174
175 if(message->_async != NULL)
176 {
177 asyncRequest = static_cast<AsyncLegacyOperationStart *>(message->_async);
178 }
179 else
180 {
181 chip 1.1 asyncRequest = new AsyncLegacyOperationStart(
182 0,
183 this->getQueueId(),
184 message,
185 this->getQueueId());
186 }
187
188 _handle_async_request(asyncRequest);
189 }
190
191 void ProviderManagerService::_handle_async_request(AsyncRequest * request)
192 {
193 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
194 "ProviderManagerService::_handle_async_request");
195
196 PEGASUS_ASSERT((request != 0) && (request->op != 0));
197
198 if(request->getType() == async_messages::ASYNC_LEGACY_OP_START)
199 {
200 request->op->processing();
201
|
202 mike 1.83 _incomingQueue.insert_back(request->op);
|
203 konrad.r 1.68 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
204 kumpf 1.77 while (( rtn =_thread_pool->allocate_and_awaken(
|
205 konrad.r 1.68 (void *)this, ProviderManagerService::handleCimOperation)) != PEGASUS_THREAD_OK)
|
206 kumpf 1.77 {
207 if (rtn==PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
208 pegasus_yield();
209 else
210 {
211 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
212 "Not enough threads to service provider manager." );
213
214 Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
215 "Could not allocate thread for %s.",
216 getQueueName());
217 break;
218 }
|
219 konrad.r 1.68 }
|
220 chip 1.1 }
221 else
222 {
223 // pass all other operations to the default handler
224 MessageQueueService::_handle_async_request(request);
225 }
226
227 PEG_METHOD_EXIT();
228
229 return;
230 }
231
|
232 kumpf 1.57 // Note: This method should not throw an exception. It is used as a thread
233 // entry point, and any exceptions thrown are ignored.
|
234 kumpf 1.39 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
|
235 kumpf 1.77 ProviderManagerService::handleCimOperation(void* arg)
|
236 chip 1.1 {
|
237 kumpf 1.39 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
238 "ProviderManagerService::handleCimOperation");
|
239 chip 1.1
|
240 kumpf 1.67 PEGASUS_ASSERT(arg != 0);
|
241 chip 1.8
|
242 chip 1.1 // get the service from argument
|
243 kumpf 1.67 ProviderManagerService* service =
|
244 kumpf 1.39 reinterpret_cast<ProviderManagerService *>(arg);
|
245 kumpf 1.67 PEGASUS_ASSERT(service != 0);
|
246 chip 1.1
|
247 kumpf 1.67 try
|
248 chip 1.1 {
|
249 kumpf 1.67 if (service->_incomingQueue.size() == 0)
250 {
251 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
252 "ProviderManagerService::handleCimOperation() called with no "
253 "op node in queue");
|
254 chip 1.1
|
255 kumpf 1.67 PEG_METHOD_EXIT();
256 return(PEGASUS_THREAD_RETURN(1));
257 }
|
258 chip 1.1
|
259 mike 1.83 AsyncOpNode* op = service->_incomingQueue.remove_front();
|
260 chip 1.1
|
261 mike 1.83 if ((op == 0) || (op->_request.size() == 0))
|
262 kumpf 1.67 {
263 // ATTN: This may dereference a null pointer!
264 MessageQueue* queue = MessageQueue::lookup(op->_source_queue);
|
265 chip 1.1
|
266 kumpf 1.67 PEGASUS_ASSERT(queue != 0);
|
267 chip 1.1
|
268 kumpf 1.67 PEG_METHOD_EXIT();
|
269 chip 1.1
|
270 kumpf 1.67 // no request in op node
271 return(PEGASUS_THREAD_RETURN(1));
272 }
|
273 chip 1.1
|
274 kumpf 1.67 AsyncRequest* request =
|
275 mike 1.83 static_cast<AsyncRequest*>(op->_request.front());
|
276 chip 1.1
|
277 kumpf 1.67 if ((request == 0) ||
278 (request->getType() != async_messages::ASYNC_LEGACY_OP_START))
279 {
280 // reply with NAK
281 PEG_METHOD_EXIT();
282 return(PEGASUS_THREAD_RETURN(0));
283 }
|
284 chip 1.1
|
285 kumpf 1.39 Message* legacy =
286 static_cast<AsyncLegacyOperationStart *>(request)->get_action();
|
287 chip 1.1
|
288 chip 1.8 if(_isSupportedRequestType(legacy))
|
289 chip 1.1 {
|
290 a.arora 1.37 AutoPtr<Message> xmessage(legacy);
|
291 chip 1.1
|
292 chip 1.8 // Set the client's requested language into this service thread.
293 // This will allow functions in this service to return messages
294 // in the correct language.
|
295 kumpf 1.39 CIMMessage* msg = dynamic_cast<CIMMessage *>(legacy);
|
296 chip 1.8
|
297 kumpf 1.39 if (msg != 0)
|
298 chip 1.8 {
|
299 kumpf 1.74 AcceptLanguageList* langs = new AcceptLanguageList(
|
300 kumpf 1.67 ((AcceptLanguageListContainer)msg->operationContext.get(
301 AcceptLanguageListContainer::NAME)).getLanguages());
|
302 chip 1.8 Thread::setLanguages(langs);
303 }
304 else
305 {
306 Thread::clearLanguages();
307 }
|
308 chip 1.1
309 service->handleCimRequest(op, legacy);
|
310 chip 1.3 }
|
311 chip 1.8 }
|
312 konrad.r 1.66 catch (const Exception& e)
|
313 kumpf 1.67 {
|
314 konrad.r 1.66 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
315 kumpf 1.67 "Unexpected exception in handleCimOperation: " + e.getMessage());
316 }
|
317 konrad.r 1.66 catch (...)
|
318 kumpf 1.67 {
|
319 konrad.r 1.66 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
|
320 kumpf 1.67 "Unexpected exception in handleCimOperation.");
321 }
|
322 chip 1.1
323 PEG_METHOD_EXIT();
324
325 return(PEGASUS_THREAD_RETURN(0));
326 }
327
|
328 kumpf 1.39 void ProviderManagerService::handleCimRequest(
329 AsyncOpNode * op,
330 Message * message)
|
331 chip 1.1 {
|
332 kumpf 1.39 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
333 "ProviderManagerService::handleCimRequest");
|
334 chip 1.1
|
335 kumpf 1.38 CIMRequestMessage * request = dynamic_cast<CIMRequestMessage *>(message);
336 PEGASUS_ASSERT(request != 0);
|
337 chip 1.1
338 // get request from op node
|
339 mike 1.83 AsyncRequest * async = static_cast<AsyncRequest *>(op->_request.front());
|
340 kumpf 1.38 PEGASUS_ASSERT(async != 0);
341
342 Message * response = 0;
|
343 kumpf 1.58 Boolean consumerLookupFailed = false;
|
344 chip 1.1
|
345 kumpf 1.58 if (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE)
346 {
347 //
348 // Get a ProviderIdContainer for ExportIndicationRequestMessage.
349 // Note: This can be removed when the CIMExportRequestDispatcher
350 // is updated to add the ProviderIdContainer to the message.
351 //
352 CIMInstance providerModule;
353 CIMInstance provider;
354 const CIMExportIndicationRequestMessage* expRequest =
355 dynamic_cast<const CIMExportIndicationRequestMessage*>(request);
356 if (_providerRegistrationManager->lookupIndicationConsumer(
357 expRequest->destinationPath, provider, providerModule))
358 {
359 request->operationContext.insert(
360 ProviderIdContainer(providerModule, provider));
361 }
362 else
363 {
364 consumerLookupFailed = true;
365 }
366 kumpf 1.58 }
367
368 if (consumerLookupFailed)
369 {
370 CIMResponseMessage* cimResponse = request->buildResponse();
371 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
372 CIM_ERR_NOT_SUPPORTED, String::EMPTY);
373 response = cimResponse;
374 }
375 else if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
|
376 kumpf 1.46 (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0) ||
|
377 kumpf 1.40 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
|
378 kumpf 1.45 (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
|
379 kumpf 1.38 {
|
380 kumpf 1.45 // Handle CIMOperationRequestMessage, CIMExportIndicationRequestMessage,
|
381 kumpf 1.46 // CIMIndicationRequestMessage, and CIMInitializeProviderRequestMessage.
382 // (These should be blocked when the provider module is disabled.)
|
383 kumpf 1.45
|
384 kumpf 1.46 //
385 // Get the provider module instance to check for a disabled module
386 //
387 CIMInstance providerModule;
|
388 kumpf 1.45
|
389 kumpf 1.58 // The provider ID container is added to the OperationContext
390 // by the CIMOperationRequestDispatcher for all CIM operation
391 // requests to providers, so it does not need to be added again.
392 // CIMInitializeProviderRequestMessage also has a provider ID
393 // container.
394 ProviderIdContainer pidc =
395 request->operationContext.get(ProviderIdContainer::NAME);
396 providerModule = pidc.getModule();
|
397 kumpf 1.38
|
398 kumpf 1.45 //
399 // Check if the target provider is disabled
400 //
401 Boolean moduleDisabled = false;
402 Uint32 pos = providerModule.findProperty(CIMName("OperationalStatus"));
403 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
404 Array<Uint16> operationalStatus;
405 providerModule.getProperty(pos).getValue().get(operationalStatus);
406
407 for(Uint32 i = 0; i < operationalStatus.size(); i++)
408 {
|
409 kumpf 1.50 if ((operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPED) ||
410 (operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPING))
|
411 kumpf 1.45 {
412 moduleDisabled = true;
413 break;
414 }
415 }
416
417 if (moduleDisabled)
418 {
419 //
420 // Send a "provider blocked" response
421 //
422 CIMResponseMessage* cimResponse = request->buildResponse();
423 cimResponse->cimException = PEGASUS_CIM_EXCEPTION_L(
424 CIM_ERR_ACCESS_DENIED,
425 MessageLoaderParms(
426 "ProviderManager.ProviderManagerService.PROVIDER_BLOCKED",
427 "provider blocked."));
428 response = cimResponse;
|
429 w.white 1.70
430 STAT_COPYDISPATCHER
|
431 kumpf 1.45 }
432 else
433 {
434 //
435 // Forward the request to the appropriate ProviderManagerRouter
436 //
|
437 kumpf 1.62 response = _processMessage(request);
|
438 kumpf 1.45 }
|
439 schuur 1.19 }
|
440 kumpf 1.38 else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
441 {
442 // Handle CIMEnableModuleRequestMessage
443 CIMEnableModuleRequestMessage * emReq =
444 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
445
446 CIMInstance providerModule = emReq->providerModule;
|
447 dj.gorey 1.31
|
448 kumpf 1.38 try
449 {
|
450 kumpf 1.39 // Forward the request to the ProviderManager
|
451 kumpf 1.62 response = _processMessage(request);
|
452 kumpf 1.38
453 // If successful, update provider module status to OK
454 // ATTN: Use CIMEnableModuleResponseMessage operationalStatus?
455 CIMEnableModuleResponseMessage * emResp =
456 dynamic_cast<CIMEnableModuleResponseMessage*>(response);
457 if (emResp->cimException.getCode() == CIM_ERR_SUCCESS)
458 {
|
459 carolann.graves 1.80 //
460 // On a successful enable, remove Stopped status and
461 // append OK status
462 //
463 Array<Uint16> removeStatus;
464 Array<Uint16> appendStatus;
465 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPED);
466 appendStatus.append (CIM_MSE_OPSTATUS_VALUE_OK);
|
467 kumpf 1.38 _updateProviderModuleStatus(
|
468 carolann.graves 1.80 providerModule, removeStatus, appendStatus);
|
469 kumpf 1.38 }
470 }
471 catch (Exception& e)
472 {
473 // Get the OperationalStatus property from the provider module
474 Array<Uint16> operationalStatus;
475 CIMValue itValue = emReq->providerModule.getProperty(
476 emReq->providerModule.findProperty("OperationalStatus"))
477 .getValue();
478 itValue.get(operationalStatus);
479
|
480 kumpf 1.78 delete response;
|
481 kumpf 1.38
482 response = new CIMEnableModuleResponseMessage(
483 request->messageId,
484 CIMException(CIM_ERR_FAILED, e.getMessage()),
485 request->queueIds.copyAndPop(),
486 operationalStatus);
487 }
488 }
489 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
490 {
491 // Handle CIMDisableModuleRequestMessage
492 CIMDisableModuleRequestMessage * dmReq =
493 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
494
495 CIMInstance providerModule = dmReq->providerModule;
496 Boolean updateModuleStatus = !dmReq->disableProviderOnly;
497
498 try
499 {
|
500 carolann.graves 1.80 //
501 // On issuing a disable request, append Stopping status
502 // Do not remove existing status
503 //
|
504 kumpf 1.38 if (updateModuleStatus)
505 {
|
506 carolann.graves 1.80 Array<Uint16> removeStatus;
507 Array<Uint16> appendStatus;
508 appendStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
|
509 kumpf 1.38 _updateProviderModuleStatus(
|
510 carolann.graves 1.80 providerModule, removeStatus, appendStatus);
|
511 kumpf 1.38 }
512
|
513 kumpf 1.39 // Forward the request to the ProviderManager
|
514 kumpf 1.62 response = _processMessage(request);
|
515 kumpf 1.38
516 // Update provider module status based on success or failure
517 if (updateModuleStatus)
518 {
519 CIMDisableModuleResponseMessage * dmResp =
520 dynamic_cast<CIMDisableModuleResponseMessage*>(response);
521 if (dmResp->cimException.getCode() != CIM_ERR_SUCCESS)
522 {
|
523 carolann.graves 1.80 //
524 // On an unsuccessful disable, remove Stopping status
525 //
526 Array<Uint16> removeStatus;
527 Array<Uint16> appendStatus;
528 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
|
529 kumpf 1.38 _updateProviderModuleStatus(
|
530 carolann.graves 1.80 providerModule, removeStatus, appendStatus);
|
531 kumpf 1.38 }
532 else
533 {
534 // Disable may or may not have been successful,
535 // depending on whether there are outstanding requests.
|
536 carolann.graves 1.80 // Remove Stopping status
537 // Append status, if any, from disable module response
538 Array<Uint16> removeStatus;
539 Array<Uint16> appendStatus;
540 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
541 if (dmResp->operationalStatus.size() > 0)
542 {
543 //
544 // On a successful disable, remove an OK or a Degraded
545 // status, if present
546 //
547 if (dmResp->operationalStatus[
548 dmResp->operationalStatus.size()-1] ==
549 CIM_MSE_OPSTATUS_VALUE_STOPPED)
550 {
551 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_OK);
552 removeStatus.append
553 (CIM_MSE_OPSTATUS_VALUE_DEGRADED);
554 }
555 appendStatus.append (dmResp->operationalStatus[
556 dmResp->operationalStatus.size()-1]);
557 carolann.graves 1.80 }
|
558 kumpf 1.38 _updateProviderModuleStatus(
|
559 carolann.graves 1.80 providerModule, removeStatus, appendStatus);
|
560 kumpf 1.38 }
561 }
562 }
563 catch (Exception& e)
564 {
565 // Get the OperationalStatus property from the provider module
566 Array<Uint16> operationalStatus;
567 CIMValue itValue = dmReq->providerModule.getProperty(
568 dmReq->providerModule.findProperty("OperationalStatus"))
569 .getValue();
570 itValue.get(operationalStatus);
571
|
572 kumpf 1.78 delete response;
|
573 kumpf 1.38
574 response = new CIMDisableModuleResponseMessage(
575 request->messageId,
576 CIMException(CIM_ERR_FAILED, e.getMessage()),
577 request->queueIds.copyAndPop(),
578 operationalStatus);
579 }
580 }
581 else
582 {
|
583 kumpf 1.62 response = _processMessage(request);
|
584 schuur 1.23 }
|
585 chip 1.13
|
586 schuur 1.19 AsyncLegacyOperationResult * async_result =
587 new AsyncLegacyOperationResult(
588 op,
589 response);
|
590 chip 1.13
|
591 schuur 1.19 _complete_op_node(op, ASYNC_OPSTATE_COMPLETE, 0, 0);
|
592 chip 1.13
|
593 schuur 1.19 PEG_METHOD_EXIT();
594 }
|
595 chip 1.13
|
596 kumpf 1.76 void ProviderManagerService::responseChunkCallback(
597 CIMRequestMessage* request,
598 CIMResponseMessage* response)
|
599 brian.campbell 1.60 {
|
600 kumpf 1.77 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
601 "ProviderManagerService::responseChunkCallback");
|
602 brian.campbell 1.60
|
603 kumpf 1.77 try
604 {
605 // only incomplete messages are processed because the caller ends up
606 // sending the complete() stage
607 PEGASUS_ASSERT(response->isComplete() == false);
608
609 AsyncLegacyOperationStart *requestAsync =
610 dynamic_cast<AsyncLegacyOperationStart *>(request->_async);
611 PEGASUS_ASSERT(requestAsync);
612 AsyncOpNode *op = requestAsync->op;
613 PEGASUS_ASSERT(op);
614 PEGASUS_ASSERT(!response->_async);
615 response->_async = new AsyncLegacyOperationResult(
|
616 kumpf 1.86 op, response);
|
617 kumpf 1.77
618 // set the destination
619 op->_op_dest = op->_callback_response_q;
620
621 MessageQueueService *service =
622 dynamic_cast<MessageQueueService *>(op->_callback_response_q);
623
624 PEGASUS_ASSERT(service);
625
626 // the last chunk MUST be sent last, so use execute the callback
627 // not all chunks are going through the dispatcher's chunk
628 // resequencer, so this must be a synchronous call here
629 // After the call is done, response and asyncResponse are now invalid
630 // as they have been sent and deleted externally
|
631 brian.campbell 1.60
|
632 kumpf 1.77 op->_async_callback(op, service, op->_callback_ptr);
633 }
634 catch(Exception &e)
635 {
636 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
637 "Exception in ProviderManagerService::responseChunkCallback: " +
638 e.getMessage() + ". Chunk not delivered.");
639 }
640 catch(...)
641 {
642 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
643 "Exception in ProviderManagerService::responseChunkCallback. "
644 "Chunk not delivered.");
645 }
646
647 PEG_METHOD_EXIT();
|
648 brian.campbell 1.60 }
649
|
650 kumpf 1.62 Message* ProviderManagerService::_processMessage(CIMRequestMessage* request)
651 {
652 Message* response = 0;
653
654 if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
655 kumpf 1.77 (request->getType() ==
|
656 carolann.graves 1.64 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
|
657 kumpf 1.62 (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
658 {
659 if (_basicProviderManagerRouter)
660 {
661 response = _basicProviderManagerRouter->processMessage(request);
662 }
663
664 if (_oopProviderManagerRouter)
665 {
666 // Note: These responses do not contain interesting data, so just
667 // use the last one.
|
668 kumpf 1.78 delete response;
|
669 kumpf 1.62
670 response = _oopProviderManagerRouter->processMessage(request);
671 }
672 }
673 else
674 {
675 CIMInstance providerModule;
676
677 if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
678 {
679 CIMEnableModuleRequestMessage* emReq =
680 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
681 providerModule = emReq->providerModule;
682 }
683 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
684 {
685 CIMDisableModuleRequestMessage* dmReq =
686 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
687 providerModule = dmReq->providerModule;
688 }
689 else
690 kumpf 1.62 {
691 ProviderIdContainer pidc =
692 request->operationContext.get(ProviderIdContainer::NAME);
693 providerModule = pidc.getModule();
694 }
695
|
696 carolann.graves 1.79 Uint16 userContext = PEGASUS_DEFAULT_PROV_USERCTXT;
|
697 kumpf 1.62 Uint32 pos = providerModule.findProperty(
698 PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT);
699 if (pos != PEG_NOT_FOUND)
700 {
701 providerModule.getProperty(pos).getValue().get(userContext);
702 }
703
704 // Forward the request to the appropriate ProviderManagerRouter, based
705 // on the CIM Server configuration and the UserContext setting.
706
707 ConfigManager* configManager = ConfigManager::getInstance();
708 Boolean forceProviderProcesses = String::equal(
709 configManager->getCurrentValue("forceProviderProcesses"), "true");
710
711 if (forceProviderProcesses
712 #ifndef PEGASUS_DISABLE_PROV_USERCTXT
713 || (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
714 || (userContext == PG_PROVMODULE_USERCTXT_DESIGNATED)
715 || ((userContext == PG_PROVMODULE_USERCTXT_PRIVILEGED) &&
716 !System::isPrivilegedUser(System::getEffectiveUserName()))
717 #endif
718 kumpf 1.62 )
719 {
720 response = _oopProviderManagerRouter->processMessage(request);
721 }
722 else
723 {
724 response = _basicProviderManagerRouter->processMessage(request);
725 }
726 }
727
728 return response;
729 }
730
|
731 kumpf 1.44 void ProviderManagerService::unloadIdleProviders()
732 {
733 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
734 "ProviderManagerService::unloadIdleProviders");
|
735 konrad.r 1.68 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
736 kumpf 1.44 // Ensure that only one _unloadIdleProvidersHandler thread runs at a time
737 _unloadIdleProvidersBusy++;
|
738 mike 1.72 if ((_unloadIdleProvidersBusy.get() == 1) &&
|
739 konrad.r 1.68 ((rtn = _thread_pool->allocate_and_awaken(
740 (void*)this, ProviderManagerService::_unloadIdleProvidersHandler))==PEGASUS_THREAD_OK))
|
741 kumpf 1.44 {
742 // _unloadIdleProvidersBusy is decremented in
743 // _unloadIdleProvidersHandler
744 }
745 else
746 {
747 // If we fail to allocate a thread, don't retry now.
748 _unloadIdleProvidersBusy--;
749 }
|
750 kumpf 1.77 if (rtn != PEGASUS_THREAD_OK)
|
751 konrad.r 1.68 {
|
752 kumpf 1.77 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
753 "Not enough threads to unload idle providers.");
754
755 Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
756 "Could not allocate thread for %s to unload idle providers.",
757 getQueueName());
|
758 konrad.r 1.68 }
|
759 kumpf 1.44 PEG_METHOD_EXIT();
760 }
761
762 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
763 ProviderManagerService::_unloadIdleProvidersHandler(void* arg) throw()
|
764 chip 1.1 {
|
765 kumpf 1.44 try
766 {
767 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
768 "ProviderManagerService::unloadIdleProvidersHandler");
769
770 ProviderManagerService* myself =
771 reinterpret_cast<ProviderManagerService*>(arg);
772
|
773 kumpf 1.62 if (myself->_basicProviderManagerRouter)
|
774 kumpf 1.44 {
|
775 kumpf 1.62 try
776 {
777 myself->_basicProviderManagerRouter->unloadIdleProviders();
778 }
779 catch (...)
780 {
781 // Ignore errors
782 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
783 "Unexpected exception from "
784 "BasicProviderManagerRouter::_unloadIdleProviders");
785 }
|
786 kumpf 1.44 }
|
787 kumpf 1.62
788 if (myself->_oopProviderManagerRouter)
|
789 kumpf 1.44 {
|
790 kumpf 1.62 try
791 {
792 myself->_oopProviderManagerRouter->unloadIdleProviders();
793 }
794 catch (...)
795 {
796 // Ignore errors
797 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
798 "Unexpected exception from "
799 "OOPProviderManagerRouter::_unloadIdleProviders");
800 }
|
801 kumpf 1.44 }
802
803 myself->_unloadIdleProvidersBusy--;
804 PEG_METHOD_EXIT();
805 }
806 catch (...)
807 {
808 // Ignore errors
809 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
810 "Unexpected exception in _unloadIdleProvidersHandler");
811 }
812
813 return(PEGASUS_THREAD_RETURN(0));
|
814 kumpf 1.38 }
815
816 // Updates the providerModule instance and the ProviderRegistrationManager
|
817 carolann.graves 1.79 //
818 // This method is used to update the provider module status when the module is
819 // disabled or enabled. If a Degraded status has been set (appended) to the
820 // OperationalStatus, it is cleared (removed) when the module is disabled or
821 // enabled.
822 //
|
823 kumpf 1.38 void ProviderManagerService::_updateProviderModuleStatus(
824 CIMInstance& providerModule,
|
825 carolann.graves 1.80 const Array<Uint16>& removeStatus,
826 const Array<Uint16>& appendStatus)
|
827 kumpf 1.38 {
828 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
829 "ProviderManagerService::_updateProviderModuleStatus");
830
831 Array<Uint16> operationalStatus;
832 String providerModuleName;
833
834 Uint32 pos = providerModule.findProperty(CIMName("Name"));
835 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
836 providerModule.getProperty(pos).getValue().get(providerModuleName);
837
838 //
839 // get operational status
840 //
841 pos = providerModule.findProperty(CIMName("OperationalStatus"));
842 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
843 CIMProperty operationalStatusProperty = providerModule.getProperty(pos);
844
|
845 carolann.graves 1.80 if (_providerRegistrationManager->updateProviderModuleStatus(
846 providerModuleName, removeStatus, appendStatus, operationalStatus) ==
847 false)
|
848 kumpf 1.38 {
849 throw PEGASUS_CIM_EXCEPTION_L(
850 CIM_ERR_FAILED,
851 MessageLoaderParms(
852 "ProviderManager.ProviderManagerService."
853 "SET_MODULE_STATUS_FAILED",
854 "set module status failed."));
855 }
856
857 operationalStatusProperty.setValue(CIMValue(operationalStatus));
858
859 PEG_METHOD_EXIT();
|
860 kumpf 1.39 }
861
862 void ProviderManagerService::indicationCallback(
863 CIMProcessIndicationRequestMessage* request)
864 {
|
865 a.dunfey 1.85 if(request->operationContext.contains(AcceptLanguageListContainer::NAME))
|
866 kumpf 1.77 {
867 AcceptLanguageListContainer cntr = request->operationContext.get(AcceptLanguageListContainer::NAME);
|
868 a.dunfey 1.85 }
869 else
|
870 kumpf 1.77 {
871 request->operationContext.insert(AcceptLanguageListContainer(AcceptLanguageList()));
872 }
873
874 if (_indicationServiceQueueId == PEG_NOT_FOUND)
|
875 kumpf 1.39 {
876 Array<Uint32> serviceIds;
877
878 providerManagerService->find_services(
879 PEGASUS_QUEUENAME_INDICATIONSERVICE, 0, 0, &serviceIds);
880 PEGASUS_ASSERT(serviceIds.size() != 0);
881
882 _indicationServiceQueueId = serviceIds[0];
883 }
884
885 request->queueIds = QueueIdStack(
886 _indicationServiceQueueId, providerManagerService->getQueueId());
887
888 AsyncLegacyOperationStart * asyncRequest =
889 new AsyncLegacyOperationStart(
890 0,
891 _indicationServiceQueueId,
892 request,
893 _indicationServiceQueueId);
894
895 providerManagerService->SendForget(asyncRequest);
|
896 jim.wunderlich 1.69
897
898
899
900 #ifdef PEGASUS_INDICATIONS_Q_THRESHOLD
901
|
902 kumpf 1.77 // See Comments in config.mak asociated with
|
903 jim.wunderlich 1.69 // PEGASUS_INDICATIONS_Q_THRESHOLD
904 //
905 // if INDICATIONS_Q_STALL THRESHOLD is gt 0
906 // then if there are over INDICATIONS_Q_STALL_THRESHOLD
|
907 kumpf 1.77 // indications in the queue
|
908 jim.wunderlich 1.69 // then force this provider to sleep until the queue count
909 // is lower than INDICATIONS_Q_RESUME_THRESHOLD
910
911 static Mutex indicationThresholdReportedLock;
912 static Boolean indicationThresholdReported = false;
913
914 #define INDICATIONS_Q_STALL_THRESHOLD PEGASUS_INDICATIONS_Q_THRESHOLD
915 #define INDICATIONS_Q_RESUME_THRESHOLD (int)(PEGASUS_INDICATIONS_Q_THRESHOLD*.90)
916 #define INDICATIONS_Q_STALL_DURATION 250 // milli-seconds
917
918 MessageQueue * indicationsQueue = MessageQueue::lookup(_indicationServiceQueueId);
919
920 if (((MessageQueueService *)indicationsQueue)->getIncomingCount() > INDICATIONS_Q_STALL_THRESHOLD)
|
921 kumpf 1.77 {
|
922 jim.wunderlich 1.69 AutoMutex indicationThresholdReportedAutoMutex(indicationThresholdReportedLock);
923 if (!indicationThresholdReported)
|
924 kumpf 1.77 {
|
925 jim.wunderlich 1.69 indicationThresholdReported = true;
926 indicationThresholdReportedAutoMutex.unlock();
927
|
928 kumpf 1.77 // make log entry to record que max exceeded
|
929 jim.wunderlich 1.69
930 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
|
931 kumpf 1.77 "Indication generation stalled: maximum queue count ($0) exceeded.",
|
932 jim.wunderlich 1.69 INDICATIONS_Q_STALL_THRESHOLD);
|
933 kumpf 1.77 }
934 else
935 {
|
936 jim.wunderlich 1.69 indicationThresholdReportedAutoMutex.unlock();
|
937 kumpf 1.77 }
|
938 jim.wunderlich 1.69
939 while (((MessageQueueService *)indicationsQueue)->getIncomingCount() > INDICATIONS_Q_RESUME_THRESHOLD)
|
940 kumpf 1.77 {
|
941 jim.wunderlich 1.69 pegasus_sleep(INDICATIONS_Q_STALL_DURATION);
|
942 kumpf 1.77 }
|
943 jim.wunderlich 1.69
944 AutoMutex indicationThresholdReportedAutoMutex1(indicationThresholdReportedLock);
945 // indicationThresholdReportedLock.lock(pegasus_thread_self());
946 if(indicationThresholdReported)
|
947 kumpf 1.77 {
|
948 jim.wunderlich 1.69 indicationThresholdReported = false;
949 indicationThresholdReportedAutoMutex1.unlock();
|
950 kumpf 1.77
|
951 jim.wunderlich 1.69 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
|
952 kumpf 1.77 "Indication generation resumed: current queue count = $0",
|
953 jim.wunderlich 1.69 ((MessageQueueService *)indicationsQueue)->getIncomingCount() );
954
|
955 kumpf 1.77 }
|
956 jim.wunderlich 1.69 else
|
957 kumpf 1.77 {
|
958 jim.wunderlich 1.69 indicationThresholdReportedAutoMutex1.unlock();
|
959 kumpf 1.77 }
960 }
|
961 jim.wunderlich 1.69 #endif /* INDICATIONS_Q_STALL_THRESHOLD */
962
|
963 chip 1.1 }
964
|
965 carolann.graves 1.79 void ProviderManagerService::providerModuleFailureCallback
966 (const String & moduleName,
967 const String & userName,
968 Uint16 userContext)
969 {
970 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
971 "ProviderManagerService::providerModuleFailureCallback");
972
973 if (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
974 {
975 Logger::put_l (
976 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
977 "ProviderManager.OOPProviderManagerRouter."
978 "OOP_PROVIDER_MODULE_USER_CTXT_FAILURE_DETECTED",
979 "A failure was detected in provider module $0 with"
980 " user context $1.",
981 moduleName, userName);
982 }
983 else // not requestor context
984 {
985 Logger::put_l (
986 carolann.graves 1.79 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
987 "ProviderManager.OOPProviderManagerRouter."
988 "OOP_PROVIDER_MODULE_FAILURE_DETECTED",
989 "A failure was detected in provider module $0.",
990 moduleName);
991 }
992
993 //
994 // Create Notify Provider Fail request message
995 //
996 CIMNotifyProviderFailRequestMessage * request =
997 new CIMNotifyProviderFailRequestMessage
998 (XmlWriter::getNextMessageId (),
999 moduleName,
1000 userName,
1001 QueueIdStack ());
1002
1003 //
1004 // Send Notify Provider Fail request message to Indication Service
1005 //
1006 if (_indicationServiceQueueId == PEG_NOT_FOUND)
1007 carolann.graves 1.79 {
1008 Array <Uint32> serviceIds;
1009
1010 providerManagerService->find_services
1011 (PEGASUS_QUEUENAME_INDICATIONSERVICE, 0, 0, &serviceIds);
1012 PEGASUS_ASSERT (serviceIds.size () != 0);
1013
1014 _indicationServiceQueueId = serviceIds [0];
1015 }
1016
1017 request->queueIds = QueueIdStack
1018 (_indicationServiceQueueId, providerManagerService->getQueueId ());
1019
|
1020 kumpf 1.86 AsyncLegacyOperationStart * asyncRequest = new AsyncLegacyOperationStart(
|
1021 carolann.graves 1.79 0,
1022 _indicationServiceQueueId,
1023 request,
1024 _indicationServiceQueueId);
1025
1026 AutoPtr <AsyncReply> asyncReply
1027 (providerManagerService->SendWait (asyncRequest));
1028
1029 AutoPtr <CIMNotifyProviderFailResponseMessage> response
1030 (reinterpret_cast <CIMNotifyProviderFailResponseMessage *>
1031 ((dynamic_cast <AsyncLegacyOperationResult *>
1032 (asyncReply.get ()))->get_result ()));
1033
1034 if (response->cimException.getCode () != CIM_ERR_SUCCESS)
1035 {
1036 PEG_TRACE_STRING (TRC_DISCARDED_DATA, Tracer::LEVEL2,
1037 "Unexpected exception in providerModuleFailureCallback: " +
1038 response->cimException.getMessage ());
1039 }
1040 else
1041 {
1042 carolann.graves 1.79 //
1043 // Successful response
1044 // Examine result to see if any subscriptions were affected
1045 //
1046 if (response->numSubscriptionsAffected > 0)
1047 {
1048 //
1049 // Subscriptions were affected
1050 // Update the provider module status to Degraded
1051 //
|
1052 carolann.graves 1.80 try
|
1053 carolann.graves 1.79 {
|
1054 carolann.graves 1.80 CIMInstance providerModule;
1055 CIMKeyBinding keyBinding(
1056 _PROPERTY_PROVIDERMODULE_NAME,
1057 moduleName,
1058 CIMKeyBinding::STRING);
1059 Array<CIMKeyBinding> kbArray;
1060 kbArray.append(keyBinding);
1061 CIMObjectPath modulePath("", PEGASUS_NAMESPACENAME_INTEROP,
1062 PEGASUS_CLASSNAME_PROVIDERMODULE, kbArray);
1063 providerModule =
1064 providerManagerService->_providerRegistrationManager->
1065 getInstance(
1066 modulePath, false, false, CIMPropertyList());
1067
1068 Array<Uint16> removeStatus;
1069 Array<Uint16> appendStatus;
1070 removeStatus.append(CIM_MSE_OPSTATUS_VALUE_OK);
1071 appendStatus.append(CIM_MSE_OPSTATUS_VALUE_DEGRADED);
1072 providerManagerService->_updateProviderModuleStatus(
1073 providerModule, removeStatus, appendStatus);
|
1074 carolann.graves 1.79 }
|
1075 carolann.graves 1.80 catch (const Exception & e)
|
1076 carolann.graves 1.79 {
|
1077 carolann.graves 1.80 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
1078 "Failed to update provider module status: " +
1079 e.getMessage());
|
1080 carolann.graves 1.79 }
1081
1082 //
1083 // Log a warning message since subscriptions were affected
1084 //
1085 Logger::put_l (
1086 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
1087 "ProviderManager.OOPProviderManagerRouter."
1088 "OOP_PROVIDER_MODULE_SUBSCRIPTIONS_AFFECTED",
1089 "The generation of indications by providers in module $0 "
1090 "may be affected. To ensure these providers are serving "
1091 "active subscriptions, disable and then re-enable this "
|
1092 carolann.graves 1.80 "module using the cimprovider command.",
1093 moduleName);
|
1094 carolann.graves 1.79 }
1095 }
|
1096 carolann.graves 1.80
1097 PEG_METHOD_EXIT();
|
1098 carolann.graves 1.79 }
1099
|
1100 a.arora 1.37 PEGASUS_NAMESPACE_END
|