version 1.1, 2004/06/26 03:24:20
|
version 1.12, 2005/02/10 00:45:12
|
|
|
//%2003//////////////////////////////////////////////////////////////////////// |
//%2005//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Development |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L. P., IBM Corp., The Open Group, Tivoli Systems. |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.; | // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.; |
// IBM Corp.; EMC Corporation, The Open Group. | // IBM Corp.; EMC Corporation, The Open Group. |
|
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; VERITAS Software Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// Author: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) | // Author: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) |
// Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com) | // Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com) |
// | // |
// Modified By: |
// Modified By: Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
| |
#if defined (PEGASUS_OS_TYPE_WINDOWS) | #if defined (PEGASUS_OS_TYPE_WINDOWS) |
#include <windows.h> // For CreateProcess() | #include <windows.h> // For CreateProcess() |
#else |
#elif defined (PEGASUS_OS_OS400) |
# if defined (PEGASUS_OS_OS400) |
|
# include <unistd.cleinc> | # include <unistd.cleinc> |
|
#elif defined (PEGASUS_OS_VMS) |
|
# include <perror.h> |
|
# include <climsgdef.h> |
|
# include <stdio.h> |
|
# include <stdlib.h> |
|
# include <string.h> |
|
# include <processes.h> |
|
# include <unixio.h> |
# else | # else |
# include <unistd.h> // For fork(), exec(), and _exit() | # include <unistd.h> // For fork(), exec(), and _exit() |
# endif |
|
#include <errno.h> | #include <errno.h> |
#endif | #endif |
| |
|
|
public: | public: |
ProviderAgentContainer( | ProviderAgentContainer( |
const String & moduleName, | const String & moduleName, |
|
const String & userName, |
PEGASUS_INDICATION_CALLBACK indicationCallback); | PEGASUS_INDICATION_CALLBACK indicationCallback); |
| |
~ProviderAgentContainer(); | ~ProviderAgentContainer(); |
| |
Boolean isInitialized(); | Boolean isInitialized(); |
| |
|
String getModuleName() const; |
|
|
CIMResponseMessage* processMessage(CIMRequestMessage* request); | CIMResponseMessage* processMessage(CIMRequestMessage* request); |
void unloadIdleProviders(); | void unloadIdleProviders(); |
| |
|
|
String _moduleName; | String _moduleName; |
| |
/** | /** |
|
The user context in which this Provider Agent operates. |
|
*/ |
|
String _userName; |
|
|
|
/** |
Callback function to which all generated indications are sent for | Callback function to which all generated indications are sent for |
processing. | processing. |
*/ | */ |
|
|
updating the _outstandingRequestTable. | updating the _outstandingRequestTable. |
*/ | */ |
Mutex _outstandingRequestTableMutex; | Mutex _outstandingRequestTableMutex; |
|
|
|
/** |
|
Holds the last provider module instance sent to the Provider Agent in |
|
a ProviderIdContainer. Since the provider module instance rarely |
|
changes, an optimization is used to send it only when it differs from |
|
the last provider module instance sent. |
|
*/ |
|
CIMInstance _providerModuleCache; |
|
|
|
/** |
|
The number of Provider Agent processes that are currently initialized |
|
(active). |
|
*/ |
|
static Uint32 _numProviderProcesses; |
|
|
|
/** |
|
The _numProviderProcessesMutex must be locked whenever reading or |
|
updating the _numProviderProcesses count. |
|
*/ |
|
static Mutex _numProviderProcessesMutex; |
|
|
|
/** |
|
The maximum number of Provider Agent processes that may be initialized |
|
(active) at one time. |
|
*/ |
|
static Uint32 _maxProviderProcesses; |
}; | }; |
| |
|
Uint32 ProviderAgentContainer::_numProviderProcesses = 0; |
|
Mutex ProviderAgentContainer::_numProviderProcessesMutex; |
|
Uint32 ProviderAgentContainer::_maxProviderProcesses = PEG_NOT_FOUND; |
|
|
ProviderAgentContainer::ProviderAgentContainer( | ProviderAgentContainer::ProviderAgentContainer( |
const String & moduleName, | const String & moduleName, |
|
const String & userName, |
PEGASUS_INDICATION_CALLBACK indicationCallback) | PEGASUS_INDICATION_CALLBACK indicationCallback) |
: _moduleName(moduleName), | : _moduleName(moduleName), |
|
_userName(userName), |
_indicationCallback(indicationCallback), | _indicationCallback(indicationCallback), |
_isInitialized(false) | _isInitialized(false) |
{ | { |
|
|
| |
CloseHandle(piProcInfo.hProcess); | CloseHandle(piProcInfo.hProcess); |
CloseHandle(piProcInfo.hThread); | CloseHandle(piProcInfo.hThread); |
|
|
|
#elif defined (PEGASUS_OS_VMS) |
|
|
|
// |
|
// fork and exec the child process |
|
// |
|
int status; |
|
|
|
status = vfork (); |
|
switch (status) |
|
{ |
|
case 0: |
|
try |
|
{ |
|
// |
|
// Execute the cimprovagt program |
|
// |
|
String agentCommandPath = |
|
ConfigManager::getHomedPath(PEGASUS_PROVIDER_AGENT_PROC_NAME); |
|
CString agentCommandPathCString = agentCommandPath.getCString(); |
|
|
|
char readHandle[32]; |
|
char writeHandle[32]; |
|
pipeToAgent->exportReadHandle(readHandle); |
|
pipeFromAgent->exportWriteHandle(writeHandle); |
|
|
|
if ((status = execl(agentCommandPathCString, agentCommandPathCString, |
|
readHandle, writeHandle, |
|
(const char*)_moduleName.getCString(), (char*)0)) == -1); |
|
{ |
|
// If we're still here, there was an error |
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"execl() failed. errno = %d.", errno); |
|
_exit(1); |
|
} |
|
} |
|
catch (...) |
|
{ |
|
// There's not much we can do here in no man's land |
|
try |
|
{ |
|
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"Caught exception before calling execl()."); |
|
} |
|
catch (...) |
|
{ |
|
} |
|
_exit(1); |
|
} |
|
PEG_METHOD_EXIT(); |
|
return; |
|
break; |
|
|
|
case -1: |
|
Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, |
|
"fork() failed. errno = %d.", errno); |
|
PEG_METHOD_EXIT(); |
|
throw Exception(MessageLoaderParms( |
|
"ProviderManager.OOPProviderManagerRouter.CIMPROVAGT_START_FAILED", |
|
"Failed to start cimprovagt \"$0\".", |
|
_moduleName)); |
|
break; |
|
|
|
default: |
|
// Close our copies of the agent's ends of the pipes |
|
pipeToAgent->closeReadHandle(); |
|
pipeFromAgent->closeWriteHandle(); |
|
|
|
_pipeToAgent.reset(pipeToAgent.release()); |
|
_pipeFromAgent.reset(pipeFromAgent.release()); |
|
|
|
PEG_METHOD_EXIT(); |
|
} |
#else | #else |
pid_t pid = fork(); | pid_t pid = fork(); |
if (pid < 0) | if (pid < 0) |
|
|
pipeToAgent->exportReadHandle(readHandle); | pipeToAgent->exportReadHandle(readHandle); |
pipeFromAgent->exportWriteHandle(writeHandle); | pipeFromAgent->exportWriteHandle(writeHandle); |
| |
|
// Set the user context of the Provider Agent process |
|
if (_userName != System::getEffectiveUserName()) |
|
{ |
|
if (!System::changeUserContext(_userName.getCString())) |
|
{ |
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"System::changeUserContext() failed. userName = %s.", |
|
(const char*)_userName.getCString()); |
|
Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, |
|
Logger::WARNING, |
|
"ProviderManager.OOPProviderManagerRouter." |
|
"USER_CONTEXT_CHANGE_FAILED", |
|
"Unable to change user context to \"$0\".", _userName); |
|
_exit(1); |
|
} |
|
} |
|
|
execl(agentCommandPathCString, agentCommandPathCString, | execl(agentCommandPathCString, agentCommandPathCString, |
readHandle, writeHandle, | readHandle, writeHandle, |
(const char*)_moduleName.getCString(), (char*)0); | (const char*)_moduleName.getCString(), (char*)0); |
|
|
return; | return; |
} | } |
| |
|
if (_maxProviderProcesses == PEG_NOT_FOUND) |
|
{ |
|
String maxProviderProcesses = ConfigManager::getInstance()->getCurrentValue("maxProviderProcesses"); |
|
CString maxProviderProcessesString = maxProviderProcesses.getCString(); |
|
char* end = 0; |
|
_maxProviderProcesses = strtol(maxProviderProcessesString, &end, 10); |
|
} |
|
|
|
{ |
|
AutoMutex lock(_numProviderProcessesMutex); |
|
if ((_maxProviderProcesses != 0) && |
|
(_numProviderProcesses >= _maxProviderProcesses)) |
|
{ |
|
throw PEGASUS_CIM_EXCEPTION( |
|
CIM_ERR_FAILED, |
|
MessageLoaderParms( |
|
"ProviderManager.OOPProviderManagerRouter." |
|
"MAX_PROVIDER_PROCESSES_REACHED", |
|
"The maximum number of cimprovagt processes has been " |
|
"reached.")); |
|
} |
|
else |
|
{ |
|
_numProviderProcesses++; |
|
} |
|
} |
|
|
try | try |
{ | { |
_startAgentProcess(); | _startAgentProcess(); |
|
|
_isInitialized = false; | _isInitialized = false; |
_pipeToAgent.reset(); | _pipeToAgent.reset(); |
_pipeFromAgent.reset(); | _pipeFromAgent.reset(); |
|
|
|
{ |
|
AutoMutex lock(_numProviderProcessesMutex); |
|
_numProviderProcesses--; |
|
} |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
throw; | throw; |
} | } |
|
|
_pipeFromAgent.reset(); | _pipeFromAgent.reset(); |
_pipeToAgent.reset(); | _pipeToAgent.reset(); |
| |
|
_providerModuleCache = CIMInstance(); |
|
|
|
{ |
|
AutoMutex lock(_numProviderProcessesMutex); |
|
_numProviderProcesses--; |
|
} |
|
|
_isInitialized = false; | _isInitialized = false; |
| |
// | // |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
|
String ProviderAgentContainer::getModuleName() const |
|
{ |
|
return _moduleName; |
|
} |
|
|
CIMResponseMessage* ProviderAgentContainer::processMessage( | CIMResponseMessage* ProviderAgentContainer::processMessage( |
CIMRequestMessage* request) | CIMRequestMessage* request) |
{ | { |
|
|
CIMResponseMessage* response; | CIMResponseMessage* response; |
String originalMessageId = request->messageId; | String originalMessageId = request->messageId; |
| |
|
// These three variables are used for the provider module optimization. |
|
// See the _providerModuleCache member description for more information. |
|
AutoPtr<ProviderIdContainer> origProviderId; |
|
Boolean doProviderModuleOptimization = false; |
|
Boolean updateProviderModuleCache = false; |
|
|
try | try |
{ | { |
// The messageId attribute is used to correlate response messages | // The messageId attribute is used to correlate response messages |
|
|
uniqueMessageId, &outstandingRequestEntry); | uniqueMessageId, &outstandingRequestEntry); |
} | } |
| |
|
// Get the provider module from the ProviderIdContainer to see if |
|
// we can optimize out the transmission of this instance to the |
|
// Provider Agent. (See the _providerModuleCache description.) |
|
try |
|
{ |
|
ProviderIdContainer pidc = request->operationContext.get( |
|
ProviderIdContainer::NAME); |
|
origProviderId.reset(new ProviderIdContainer( |
|
pidc.getModule(), pidc.getProvider(), |
|
pidc.isRemoteNameSpace(), pidc.getRemoteInfo())); |
|
if (_providerModuleCache.isUninitialized() || |
|
(!pidc.getModule().identical(_providerModuleCache))) |
|
{ |
|
// We haven't sent this provider module instance to the |
|
// Provider Agent yet. Update our cache after we send it. |
|
updateProviderModuleCache = true; |
|
} |
|
else |
|
{ |
|
// Replace the provider module in the ProviderIdContainer |
|
// with an uninitialized instance. We'll need to put the |
|
// original one back after the message is sent. |
|
request->operationContext.set(ProviderIdContainer( |
|
CIMInstance(), pidc.getProvider(), |
|
pidc.isRemoteNameSpace(), pidc.getRemoteInfo())); |
|
doProviderModuleOptimization = true; |
|
} |
|
} |
|
catch (...) |
|
{ |
|
// No ProviderIdContainer to optimize |
|
} |
|
|
// | // |
// Write the message to the pipe | // Write the message to the pipe |
// | // |
|
|
_pipeToAgent->writeMessage(request); | _pipeToAgent->writeMessage(request); |
request->messageId = originalMessageId; | request->messageId = originalMessageId; |
| |
|
if (doProviderModuleOptimization) |
|
{ |
|
request->operationContext.set(*origProviderId.get()); |
|
} |
|
|
if (writeStatus != AnonymousPipe::STATUS_SUCCESS) | if (writeStatus != AnonymousPipe::STATUS_SUCCESS) |
{ | { |
Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, | Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, |
|
|
"Failed to communicate with cimprovagt \"$0\".", | "Failed to communicate with cimprovagt \"$0\".", |
_moduleName)); | _moduleName)); |
} | } |
|
|
|
if (updateProviderModuleCache) |
|
{ |
|
_providerModuleCache = origProviderId->getModule(); |
|
} |
} | } |
catch (...) | catch (...) |
{ | { |
request->messageId = originalMessageId; | request->messageId = originalMessageId; |
|
|
|
if (doProviderModuleOptimization) |
|
{ |
|
request->operationContext.set(*origProviderId.get()); |
|
} |
|
|
Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, | Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, |
"Failed to write message to pipe."); | "Failed to write message to pipe."); |
// Remove the OutstandingRequestTable entry for this request | // Remove the OutstandingRequestTable entry for this request |
|
|
void ProviderAgentContainer::unloadIdleProviders() | void ProviderAgentContainer::unloadIdleProviders() |
{ | { |
PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, | PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, |
"ProviderAgentContainer::processMessage"); |
"ProviderAgentContainer::unloadIdleProviders"); |
| |
AutoMutex lock(_agentMutex); | AutoMutex lock(_agentMutex); |
if (_isInitialized) | if (_isInitialized) |
|
|
// Private, unimplemented constructor | // Private, unimplemented constructor |
OOPProviderManagerRouter::OOPProviderManagerRouter( | OOPProviderManagerRouter::OOPProviderManagerRouter( |
const OOPProviderManagerRouter&) | const OOPProviderManagerRouter&) |
|
: ProviderManagerRouter(*this) |
{ | { |
} | } |
| |
|
|
response.reset(request->buildResponse()); | response.reset(request->buildResponse()); |
} | } |
} | } |
else |
else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) |
{ | { |
|
// Fan out the request to all Provider Agent processes for this module |
|
|
// Retrieve the provider module name | // Retrieve the provider module name |
String moduleName; | String moduleName; |
CIMValue nameValue = providerModule.getProperty( | CIMValue nameValue = providerModule.getProperty( |
providerModule.findProperty("Name")).getValue(); | providerModule.findProperty("Name")).getValue(); |
nameValue.get(moduleName); | nameValue.get(moduleName); |
| |
// Look up the Provider Agent for this module |
// Look up the Provider Agents for this module |
ProviderAgentContainer * pa = _lookupProviderAgent(moduleName); |
Array<ProviderAgentContainer*> paArray = |
PEGASUS_ASSERT(pa != 0); |
_lookupProviderAgents(moduleName); |
|
|
// Determine whether the Provider Agent has been initialized |
|
Boolean paInitialized = pa->isInitialized(); |
|
| |
if ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) && |
for (Uint32 i=0; i<paArray.size(); i++) |
!paInitialized) |
|
{ | { |
// | // |
// Do not start up an agent process just to disable the module | // Do not start up an agent process just to disable the module |
// | // |
|
if (paArray[i]->isInitialized()) |
|
{ |
|
// |
|
// Forward the request to the provider agent |
|
// |
|
response.reset(paArray[i]->processMessage(request)); |
|
|
|
// Note: Do not uninitialize the ProviderAgentContainer here |
|
// when a disable module operation is successful. Just let the |
|
// selecting thread notice when the agent connection is closed. |
|
|
|
// Determine the success of the disable module operation |
|
CIMDisableModuleResponseMessage* dmResponse = |
|
dynamic_cast<CIMDisableModuleResponseMessage*>( |
|
response.get()); |
|
PEGASUS_ASSERT(dmResponse != 0); |
|
|
|
Boolean isStopped = false; |
|
for (Uint32 i=0; i < dmResponse->operationalStatus.size(); i++) |
|
{ |
|
if (dmResponse->operationalStatus[i] == |
|
CIM_MSE_OPSTATUS_VALUE_STOPPED) |
|
{ |
|
isStopped = true; |
|
break; |
|
} |
|
} |
|
|
|
// If the operation is unsuccessful, stop and return the error |
|
if ((dmResponse->cimException.getCode() != CIM_ERR_SUCCESS) || |
|
!isStopped) |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Use a default response if no Provider Agents were called |
|
if (!response.get()) |
|
{ |
response.reset(request->buildResponse()); | response.reset(request->buildResponse()); |
| |
CIMDisableModuleResponseMessage* dmResponse = | CIMDisableModuleResponseMessage* dmResponse = |
|
|
operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_STOPPED); | operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_STOPPED); |
dmResponse->operationalStatus = operationalStatus; | dmResponse->operationalStatus = operationalStatus; |
} | } |
else if ((request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE) && |
} |
!paInitialized) |
else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE) |
|
{ |
|
// Fan out the request to all Provider Agent processes for this module |
|
|
|
// Retrieve the provider module name |
|
String moduleName; |
|
CIMValue nameValue = providerModule.getProperty( |
|
providerModule.findProperty("Name")).getValue(); |
|
nameValue.get(moduleName); |
|
|
|
// Look up the Provider Agents for this module |
|
Array<ProviderAgentContainer*> paArray = |
|
_lookupProviderAgents(moduleName); |
|
|
|
for (Uint32 i=0; i<paArray.size(); i++) |
{ | { |
// | // |
// Do not start up an agent process just to enable the module | // Do not start up an agent process just to enable the module |
// | // |
|
if (paArray[i]->isInitialized()) |
|
{ |
|
// |
|
// Forward the request to the provider agent |
|
// |
|
response.reset(paArray[i]->processMessage(request)); |
|
|
|
// Determine the success of the enable module operation |
|
CIMEnableModuleResponseMessage* emResponse = |
|
dynamic_cast<CIMEnableModuleResponseMessage*>( |
|
response.get()); |
|
PEGASUS_ASSERT(emResponse != 0); |
|
|
|
Boolean isOk = false; |
|
for (Uint32 i=0; i < emResponse->operationalStatus.size(); i++) |
|
{ |
|
if (emResponse->operationalStatus[i] == |
|
CIM_MSE_OPSTATUS_VALUE_OK) |
|
{ |
|
isOk = true; |
|
break; |
|
} |
|
} |
|
|
|
// If the operation is unsuccessful, stop and return the error |
|
if ((emResponse->cimException.getCode() != CIM_ERR_SUCCESS) || |
|
!isOk) |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Use a default response if no Provider Agents were called |
|
if (!response.get()) |
|
{ |
response.reset(request->buildResponse()); | response.reset(request->buildResponse()); |
| |
CIMEnableModuleResponseMessage* emResponse = | CIMEnableModuleResponseMessage* emResponse = |
|
|
operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_OK); | operationalStatus.append(CIM_MSE_OPSTATUS_VALUE_OK); |
emResponse->operationalStatus = operationalStatus; | emResponse->operationalStatus = operationalStatus; |
} | } |
|
} |
else | else |
{ | { |
|
// Retrieve the provider module name |
|
String moduleName; |
|
CIMValue nameValue = providerModule.getProperty( |
|
providerModule.findProperty("Name")).getValue(); |
|
nameValue.get(moduleName); |
|
|
|
// Retrieve the provider user context configuration |
|
Uint16 userContext = 0; |
|
Uint32 pos = providerModule.findProperty( |
|
PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT); |
|
if (pos != PEG_NOT_FOUND) |
|
{ |
|
CIMValue userContextValue = |
|
providerModule.getProperty(pos).getValue(); |
|
if (!userContextValue.isNull()) |
|
{ |
|
userContextValue.get(userContext); |
|
} |
|
} |
|
|
|
if (userContext == 0) |
|
{ |
|
userContext = PG_PROVMODULE_USERCTXT_PRIVILEGED; |
|
} |
|
|
|
String userName; |
|
|
|
if (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR) |
|
{ |
|
try |
|
{ |
|
// User Name is in the OperationContext |
|
IdentityContainer ic = (IdentityContainer) |
|
request->operationContext.get(IdentityContainer::NAME); |
|
userName = ic.getUserName(); |
|
} |
|
catch (Exception& e) |
|
{ |
|
// If no IdentityContainer is present, default to the CIM |
|
// Server's user context |
|
} |
|
|
|
// If authentication is disabled, use the CIM Server's user context |
|
if (!userName.size()) |
|
{ |
|
userName = System::getEffectiveUserName(); |
|
} |
|
} |
|
else if (userContext == PG_PROVMODULE_USERCTXT_DESIGNATED) |
|
{ |
|
// Retrieve the provider module name |
|
providerModule.getProperty(providerModule.findProperty( |
|
PEGASUS_PROPERTYNAME_MODULE_DESIGNATEDUSER)).getValue(). |
|
get(userName); |
|
} |
|
else if (userContext == PG_PROVMODULE_USERCTXT_CIMSERVER) |
|
{ |
|
userName = System::getEffectiveUserName(); |
|
} |
|
else // Privileged User |
|
{ |
|
PEGASUS_ASSERT(userContext == PG_PROVMODULE_USERCTXT_PRIVILEGED); |
|
userName = System::getPrivilegedUserName(); |
|
} |
|
|
|
PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, |
|
"Module name = " + moduleName); |
|
Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL4, |
|
"User context = %hd.", userContext); |
|
PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4, |
|
"User name = " + userName); |
|
|
|
// Look up the Provider Agent for this module and user |
|
ProviderAgentContainer* pa = _lookupProviderAgent(moduleName, userName); |
|
PEGASUS_ASSERT(pa != 0); |
|
|
// | // |
// Forward the request to the provider agent | // Forward the request to the provider agent |
// | // |
response.reset(pa->processMessage(request)); | response.reset(pa->processMessage(request)); |
|
|
// Note: Do not uninitialize the ProviderAgentContainer here when |
|
// a disable module operation is successful.) Just let the |
|
// selecting thread notice when the agent connection is closed. |
|
} |
|
} | } |
| |
response->syncAttributes(request); | response->syncAttributes(request); |
|
|
} | } |
| |
ProviderAgentContainer* OOPProviderManagerRouter::_lookupProviderAgent( | ProviderAgentContainer* OOPProviderManagerRouter::_lookupProviderAgent( |
const String& moduleName) |
const String& moduleName, |
|
const String& userName) |
{ | { |
ProviderAgentContainer* pa = 0; | ProviderAgentContainer* pa = 0; |
|
String key = moduleName + ":" + userName; |
| |
AutoMutex lock(_providerAgentTableMutex); | AutoMutex lock(_providerAgentTableMutex); |
if (!_providerAgentTable.lookup(moduleName, pa)) |
if (!_providerAgentTable.lookup(key, pa)) |
{ | { |
pa = new ProviderAgentContainer(moduleName, _indicationCallback); |
pa = new ProviderAgentContainer( |
_providerAgentTable.insert(moduleName, pa); |
moduleName, userName, _indicationCallback); |
|
_providerAgentTable.insert(key, pa); |
} | } |
return pa; | return pa; |
} | } |
| |
|
Array<ProviderAgentContainer*> OOPProviderManagerRouter::_lookupProviderAgents( |
|
const String& moduleName) |
|
{ |
|
Array<ProviderAgentContainer*> paArray; |
|
|
|
AutoMutex lock(_providerAgentTableMutex); |
|
for (ProviderAgentTable::Iterator i = _providerAgentTable.start(); i; i++) |
|
{ |
|
if (i.value()->getModuleName() == moduleName) |
|
{ |
|
paArray.append(i.value()); |
|
} |
|
} |
|
return paArray; |
|
} |
|
|
CIMResponseMessage* OOPProviderManagerRouter::_forwardRequestToAllAgents( | CIMResponseMessage* OOPProviderManagerRouter::_forwardRequestToAllAgents( |
CIMRequestMessage* request) | CIMRequestMessage* request) |
{ | { |