📄 oopprovidermanagerrouter.cpp
字号:
} } catch (...) { } PEG_METHOD_EXIT();}void ProviderAgentContainer::_startAgentProcess(){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderAgentContainer::_startAgentProcess"); // // Serialize the starting of agent processes. If two agent processes are // started at the same time, they may get copies of each other's pipe // descriptors. If this happens, the cimserver will not get a pipe read // error when one of the agent processes exits, because the pipe will // still be writable by the other process. This locking control needs to // cover the period from where the pipes are created to where the agent // ends of the pipes are closed by the cimserver. // static Mutex agentStartupMutex; AutoMutex lock(agentStartupMutex); AutoPtr<AnonymousPipe> pipeFromAgent(new AnonymousPipe()); AutoPtr<AnonymousPipe> pipeToAgent(new AnonymousPipe()); // // Start a cimprovagt process for this provider module //#if defined (PEGASUS_OS_TYPE_WINDOWS) // // Set up members of the PROCESS_INFORMATION structure // PROCESS_INFORMATION piProcInfo; ZeroMemory (&piProcInfo, sizeof (PROCESS_INFORMATION)); // // Set up members of the STARTUPINFO structure // STARTUPINFO siStartInfo; ZeroMemory (&siStartInfo, sizeof (STARTUPINFO)); siStartInfo.cb = sizeof (STARTUPINFO); // // Generate the command line // char cmdLine[2048]; char readHandle[32]; char writeHandle[32]; pipeToAgent->exportReadHandle(readHandle); pipeFromAgent->exportWriteHandle(writeHandle); sprintf(cmdLine, "\"%s\" %s %s \"%s\"", (const char*)ConfigManager::getHomedPath( PEGASUS_PROVIDER_AGENT_PROC_NAME).getCString(), readHandle, writeHandle, (const char*)_moduleName.getCString()); // // Create the child process // if (!CreateProcess ( NULL, // cmdLine, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags NULL, // use parent's environment NULL, // use parent's current directory &siStartInfo, // STARTUPINFO &piProcInfo)) // PROCESS_INFORMATION { Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2, "CreateProcess() failed. errno = %d.", GetLastError()); PEG_METHOD_EXIT(); throw Exception(MessageLoaderParms( "ProviderManager.OOPProviderManagerRouter.CIMPROVAGT_START_FAILED", "Failed to start cimprovagt \"$0\".", _moduleName)); } CloseHandle(piProcInfo.hProcess); 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(); }#elif defined (PEGASUS_OS_OS400) //Out of process provider support for OS400 goes here when needed.#else# ifndef PEGASUS_DISABLE_PROV_USERCTXT // Get and save the effective user name and the uid/gid for the user // context of the agent process String effectiveUserName = System::getEffectiveUserName(); PEGASUS_UID_T newUid = (PEGASUS_UID_T) -1; PEGASUS_GID_T newGid = (PEGASUS_GID_T) -1; if (_userName != effectiveUserName) { if (!System::lookupUserId(_userName.getCString(), newUid, newGid)) { throw PEGASUS_CIM_EXCEPTION_L( CIM_ERR_FAILED, MessageLoaderParms( "ProviderManager.OOPProviderManagerRouter." "USER_CONTEXT_CHANGE_FAILED", "Unable to change user context to \"$0\".", _userName)); } }# endif pid_t pid = fork(); if (pid < 0) { 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)); } else if (pid == 0) { // // Child side of the fork // try { // Close our copies of the parent's ends of the pipes pipeToAgent->closeWriteHandle(); pipeFromAgent->closeReadHandle(); // // 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);# ifndef PEGASUS_DISABLE_PROV_USERCTXT // Set the user context of the Provider Agent process if (_userName != effectiveUserName) { if (!System::changeUserContext(newUid, newGid)) { 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); } }# 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, readHandle, writeHandle, (const char*)_moduleName.getCString(), (char*)0); // 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); } }# if defined(PEGASUS_HAS_SIGNALS) _pid = pid;# endif#endif // // CIM Server process // // 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();}// Note: Caller must lock _agentMutexvoid ProviderAgentContainer::_sendInitializationData(){ PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderAgentContainer::_sendInitializationData"); // // Gather config properties to pass to the Provider Agent // ConfigManager* configManager = ConfigManager::getInstance(); Array<Pair<String, String> > configProperties; Array<String> configPropertyNames; configManager->getAllPropertyNames(configPropertyNames, true); for (Uint32 i = 0; i < configPropertyNames.size(); i++) { String configPropertyValue = configManager->getCurrentValue(configPropertyNames[i]); String configPropertyDefaultValue = configManager->getDefaultValue(configPropertyNames[i]); if (configPropertyValue != configPropertyDefaultValue) { configProperties.append(Pair<String, String>( configPropertyNames[i], configPropertyValue)); } } // // Create a Provider Agent initialization message // AutoPtr<CIMInitializeProviderAgentRequestMessage> request( new CIMInitializeProviderAgentRequestMessage( String("0"), // messageId configManager->getPegasusHome(), configProperties, System::bindVerbose, _subscriptionInitComplete, QueueIdStack())); // // Write the initialization message to the pipe // AnonymousPipe::Status writeStatus = _pipeToAgent->writeMessage(request.get()); if (writeStatus != AnonymousPipe::STATUS_SUCCESS) { PEG_METHOD_EXIT(); throw Exception(MessageLoaderParms( "ProviderManager.OOPProviderManagerRouter." "CIMPROVAGT_COMMUNICATION_FAILED", "Failed to communicate with cimprovagt \"$0\".", _moduleName)); } // Wait for a null response from the Provider Agent indicating it has // initialized successfully. CIMMessage* message; AnonymousPipe::Status readStatus; do { readStatus = _pipeFromAgent->readMessage(message); } while (readStatus == AnonymousPipe::STATUS_INTERRUPT); if (readStatus != AnonymousPipe::STATUS_SUCCESS) { PEG_METHOD_EXIT(); throw Exception(MessageLoaderParms( "ProviderManager.OOPProviderManagerRouter." "CIMPROVAGT_COMMUNICATION_FAILED", "Failed to communicate with cimprovagt \"$0\".", _moduleName)); } PEGASUS_ASSERT(message == 0); PEG_METHOD_EXIT();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -