version 1.25.2.8, 2006/10/10 18:10:15
|
version 1.29, 2006/05/09 19:09:36
|
|
|
# include <unistd.h> // For fork(), exec(), and _exit() | # include <unistd.h> // For fork(), exec(), and _exit() |
# include <errno.h> | # include <errno.h> |
# include <sys/types.h> | # include <sys/types.h> |
# include <sys/resource.h> |
|
# if defined(PEGASUS_HAS_SIGNALS) | # if defined(PEGASUS_HAS_SIGNALS) |
# include <sys/wait.h> | # include <sys/wait.h> |
# endif | # endif |
|
|
{ | { |
public: | public: |
OutstandingRequestEntry( | OutstandingRequestEntry( |
String originalMessageId_, |
String messageId_, |
CIMRequestMessage* requestMessage_, | CIMRequestMessage* requestMessage_, |
CIMResponseMessage*& responseMessage_, | CIMResponseMessage*& responseMessage_, |
Semaphore* responseReady_) | Semaphore* responseReady_) |
: originalMessageId(originalMessageId_), |
: messageId(messageId_), |
requestMessage(requestMessage_), | requestMessage(requestMessage_), |
responseMessage(responseMessage_), | responseMessage(responseMessage_), |
responseReady(responseReady_) | responseReady(responseReady_) |
{ | { |
} | } |
| |
/** |
String messageId; |
A unique value is substituted as the request messageId attribute to |
|
allow responses to be definitively correllated with requests. |
|
The original messageId value is stored here to avoid a race condition |
|
between the processing of a response chunk and the resetting of the |
|
original messageId in the request message. |
|
*/ |
|
String originalMessageId; |
|
CIMRequestMessage* requestMessage; | CIMRequestMessage* requestMessage; |
CIMResponseMessage*& responseMessage; | CIMResponseMessage*& responseMessage; |
Semaphore* responseReady; | Semaphore* responseReady; |
|
|
} | } |
# endif | # endif |
| |
// Close all file descriptors except stdin/stdout/stderr |
|
// and the pipe handles needed by the Provider Agent process. |
|
|
|
Uint32 readFd = atoi(readHandle); |
|
Uint32 writeFd = atoi(writeHandle); |
|
struct rlimit fileLimit; |
|
|
|
if (getrlimit(RLIMIT_NOFILE, &fileLimit) == 0) |
|
{ |
|
Uint32 maxFd = (Uint32)fileLimit.rlim_cur; |
|
for (Uint32 i = 3; i < maxFd - 1; i++) |
|
{ |
|
if ((i != readFd) && (i != writeFd)) |
|
{ |
|
close(i); |
|
} |
|
} |
|
} |
|
|
|
execl(agentCommandPathCString, agentCommandPathCString, | execl(agentCommandPathCString, agentCommandPathCString, |
readHandle, writeHandle, | readHandle, writeHandle, |
(const char*)_moduleName.getCString(), (char*)0); | (const char*)_moduleName.getCString(), (char*)0); |
|
|
if (_isInitialized) | if (_isInitialized) |
{ | { |
// Harvest the status of the agent process to prevent a zombie | // Harvest the status of the agent process to prevent a zombie |
pid_t status = 0; |
Boolean keepWaiting = false; |
do | do |
{ | { |
status = waitpid(_pid, 0, 0); |
pid_t status = waitpid(_pid, 0, 0); |
} while ((status == -1) && (errno == EINTR)); |
|
|
|
if (status == -1) | if (status == -1) |
{ | { |
|
if (errno == EINTR) |
|
{ |
|
keepWaiting = true; |
|
} |
|
else |
|
{ |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ProviderAgentContainer::_initialize(): " | "ProviderAgentContainer::_initialize(): " |
"waitpid failed; errno = %d.", errno); | "waitpid failed; errno = %d.", errno); |
} | } |
} | } |
|
} while (keepWaiting); |
|
} |
#endif | #endif |
| |
_isInitialized = false; | _isInitialized = false; |
|
|
| |
#if defined(PEGASUS_HAS_SIGNALS) | #if defined(PEGASUS_HAS_SIGNALS) |
// Harvest the status of the agent process to prevent a zombie | // Harvest the status of the agent process to prevent a zombie |
pid_t status = 0; |
Boolean keepWaiting = false; |
do | do |
{ | { |
status = waitpid(_pid, 0, 0); |
pid_t status = waitpid(_pid, 0, 0); |
} while ((status == -1) && (errno == EINTR)); |
|
|
|
if (status == -1) | if (status == -1) |
{ | { |
|
if (errno == EINTR) |
|
{ |
|
keepWaiting = true; |
|
} |
|
else |
|
{ |
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, | Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"ProviderAgentContainer::_uninitialize(): " | "ProviderAgentContainer::_uninitialize(): " |
"waitpid failed; errno = %d.", errno); | "waitpid failed; errno = %d.", errno); |
} | } |
|
} |
|
} while (keepWaiting); |
#endif | #endif |
| |
_isInitialized = false; | _isInitialized = false; |
|
|
i != 0; i++) | i != 0; i++) |
{ | { |
PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, | PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2, |
String("Completing messageId \"") + i.key() + |
String("Completing messageId \"") + i.value()->messageId + |
"\" with a null response."); | "\" with a null response."); |
i.value()->responseMessage = response; | i.value()->responseMessage = response; |
i.value()->responseReady->signal(); | i.value()->responseReady->signal(); |
|
|
} | } |
} while (response == _REQUEST_NOT_PROCESSED); | } while (response == _REQUEST_NOT_PROCESSED); |
| |
if (request->getType() == CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) |
|
{ |
|
_subscriptionInitComplete = true; |
|
} |
|
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
return response; | return response; |
} | } |
|
|
// | // |
Semaphore waitSemaphore(0); | Semaphore waitSemaphore(0); |
OutstandingRequestEntry outstandingRequestEntry( | OutstandingRequestEntry outstandingRequestEntry( |
originalMessageId, request, response, &waitSemaphore); |
uniqueMessageId, request, response, &waitSemaphore); |
| |
// | // |
// Lock the Provider Agent Container while initializing the | // Lock the Provider Agent Container while initializing the |
|
|
| |
// Put the original message ID into the response | // Put the original message ID into the response |
response->messageId = | response->messageId = |
_outstandingRequestEntry->originalMessageId; |
_outstandingRequestEntry->requestMessage->messageId; |
| |
// Call the response chunk callback to process the chunk | // Call the response chunk callback to process the chunk |
_responseChunkCallback( | _responseChunkCallback( |