(file) Return to OOPProviderManagerRouter.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManagerService / Attic

Diff for /pegasus/src/Pegasus/ProviderManagerService/Attic/OOPProviderManagerRouter.cpp between version 1.9 and 1.10

version 1.9, 2007/03/16 17:16:57 version 1.10, 2007/05/25 18:35:17
Line 47 
Line 47 
 #include <Pegasus/Common/Thread.h> #include <Pegasus/Common/Thread.h>
 #include <Pegasus/Common/MessageQueueService.h> #include <Pegasus/Common/MessageQueueService.h>
 #include <Pegasus/Config/ConfigManager.h> #include <Pegasus/Config/ConfigManager.h>
   #include <Pegasus/Common/Executor.h>
  
 #if defined (PEGASUS_OS_TYPE_WINDOWS) #if defined (PEGASUS_OS_TYPE_WINDOWS)
 # include <windows.h>  // For CreateProcess() # include <windows.h>  // For CreateProcess()
Line 344 
Line 345 
     PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,     PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
     PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback,     PEGASUS_PROVIDERMODULEFAIL_CALLBACK_T providerModuleFailCallback,
     Boolean subscriptionInitComplete)     Boolean subscriptionInitComplete)
     : _moduleName(moduleName),      :
         _moduleName(moduleName),
       _userName(userName),       _userName(userName),
       _userContext(userContext),       _userContext(userContext),
       _indicationCallback(indicationCallback),       _indicationCallback(indicationCallback),
Line 353 
Line 355 
       _isInitialized(false),       _isInitialized(false),
       _subscriptionInitComplete(subscriptionInitComplete)       _subscriptionInitComplete(subscriptionInitComplete)
 { {
   
     PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,     PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
         "ProviderAgentContainer::ProviderAgentContainer");         "ProviderAgentContainer::ProviderAgentContainer");
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
Line 387 
Line 390 
  
 void ProviderAgentContainer::_startAgentProcess() void ProviderAgentContainer::_startAgentProcess()
 { {
     PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,      PEG_METHOD_ENTER(
         "ProviderAgentContainer::_startAgentProcess");          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  
     {  
         PEG_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)      PEGASUS_UID_T newUid = (PEGASUS_UID_T)-1;
       PEGASUS_GID_T newGid = (PEGASUS_GID_T)-1;
     //  
     //  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  
             PEG_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_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                 "Caught exception before calling execl().");  
           }  
           catch (...)  
           {  
           }  
          _exit(1);  
         }  
         PEG_METHOD_EXIT();  
         return;  
         break;  
   
       case -1:  
         PEG_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.  # ifndef PEGASUS_DISABLE_PROV_USERCTXT
  
 #else      newUid = getuid();
       newGid = getgid();
  
 # ifndef PEGASUS_DISABLE_PROV_USERCTXT  
     // Get and save the effective user name and the uid/gid for the user     // Get and save the effective user name and the uid/gid for the user
     // context of the agent process     // context of the agent process
  
     String effectiveUserName = System::getEffectiveUserName();     String effectiveUserName = System::getEffectiveUserName();
     PEGASUS_UID_T newUid = (PEGASUS_UID_T) -1;  
     PEGASUS_GID_T newGid = (PEGASUS_GID_T) -1;  
     if (_userName != effectiveUserName)     if (_userName != effectiveUserName)
     {     {
         if (!System::lookupUserId(_userName.getCString(), newUid, newGid))         if (!System::lookupUserId(_userName.getCString(), newUid, newGid))
Line 561 
Line 418 
                     "Unable to change user context to \"$0\".", _userName));                     "Unable to change user context to \"$0\".", _userName));
         }         }
     }     }
 # endif  
  
     pid_t pid = fork();  # endif /* PEGASUS_DISABLE_PROV_USERCTXT */
     if (pid < 0)  
       // Start the provider agent.
   
       int pid;
       AnonymousPipe* readPipe;
       AnonymousPipe* writePipe;
   
       int status = Executor::startProviderAgent(
           (const char*)_moduleName.getCString(),
           ConfigManager::getPegasusHome(),
           _userName,
           newUid,
           newGid,
           pid,
           readPipe,
           writePipe);
   
       if (status != 0)
     {     {
         PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL2,         PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL2,
             "fork() failed.  errno = %d.", errno));              "Executor::startProviderAgent() failed"));
         PEG_METHOD_EXIT();         PEG_METHOD_EXIT();
         throw Exception(MessageLoaderParms(         throw Exception(MessageLoaderParms(
             "ProviderManager.OOPProviderManagerRouter.CIMPROVAGT_START_FAILED",             "ProviderManager.OOPProviderManagerRouter.CIMPROVAGT_START_FAILED",
             "Failed to start cimprovagt \"$0\".",             "Failed to start cimprovagt \"$0\".",
             _moduleName));             _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))  
                 {  
                     PEG_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,      // Set the session key to be used for requests emanating from this read
                 readHandle, writeHandle,      // pipe (i.e., the provider agent). Examples include requests made by the
                 (const char*)_moduleName.getCString(), (char*)0);      // provider with the CIMOMHandle or indications delivered by the provider.
  
             // If we're still here, there was an error  
             PEG_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_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,  
                     "Caught exception before calling execl().");  
             }  
             catch (...) {}  
             _exit(1);  
         }  
     }  
 # if defined(PEGASUS_HAS_SIGNALS) # if defined(PEGASUS_HAS_SIGNALS)
     _pid = pid;     _pid = pid;
 # endif # endif
 #endif  
  
     //      _pipeFromAgent.reset(readPipe);
     // CIM Server process      _pipeToAgent.reset(writePipe);
     //  
   
     // 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();     PEG_METHOD_EXIT();
 } }
Line 739 
Line 525 
     do     do
     {     {
         readStatus = _pipeFromAgent->readMessage(message);         readStatus = _pipeFromAgent->readMessage(message);
   
     } while (readStatus == AnonymousPipe::STATUS_INTERRUPT);     } while (readStatus == AnonymousPipe::STATUS_INTERRUPT);
  
     if (readStatus != AnonymousPipe::STATUS_SUCCESS)     if (readStatus != AnonymousPipe::STATUS_SUCCESS)
Line 800 
Line 587 
     try     try
     {     {
         _startAgentProcess();         _startAgentProcess();
   
         _isInitialized = true;         _isInitialized = true;
   
         _sendInitializationData();         _sendInitializationData();
  
         // Start a thread to read and process responses from the Provider Agent         // Start a thread to read and process responses from the Provider Agent
Line 844 
Line 629 
         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;              int status = Executor::reapProviderAgent(_pid);
             do  
             {  
                 status = waitpid(_pid, 0, 0);  
             } while ((status == -1) && (errno == EINTR));  
  
             if (status == -1)             if (status == -1)
             {             {
                 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,                 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     "ProviderAgentContainer::_initialize(): "                     "ProviderAgentContainer::_initialize(): "
                         "waitpid failed; errno = %d.", errno));                          "Executor::reapProviderAgent() failed"));
             }             }
         }         }
 #endif #endif
Line 959 
Line 740 
 #if defined(PEGASUS_HAS_SIGNALS) #if defined(PEGASUS_HAS_SIGNALS)
     // Harvest the status of the agent process to prevent a zombie.  Do not     // Harvest the status of the agent process to prevent a zombie.  Do not
     // hold the _agentMutex during this operation.     // hold the _agentMutex during this operation.
     pid_t status = 0;      int status = Executor::reapProviderAgent(_pid);
     do  
     {  
         status = waitpid(pid, 0, 0);  
     } while ((status == -1) && (errno == EINTR));  
  
     if (status == -1)     if (status == -1)
     {     {
         PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,         PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
             "ProviderAgentContainer::_uninitialize(): "             "ProviderAgentContainer::_uninitialize(): "
                 "waitpid failed; errno = %d.", errno));                  "Executor::reapProviderAgent() failed."));
     }     }
 #endif #endif
  
Line 1331 
Line 1108 
  
             if (message->getType() == CIM_PROCESS_INDICATION_REQUEST_MESSAGE)             if (message->getType() == CIM_PROCESS_INDICATION_REQUEST_MESSAGE)
             {             {
                 // Forward indications to the indication callback                  // Process an indication message
   
                 _indicationCallback(                 _indicationCallback(
                     reinterpret_cast<CIMProcessIndicationRequestMessage*>(                     reinterpret_cast<CIMProcessIndicationRequestMessage*>(
                         message));                         message));
             }             }
             else if (!message->isComplete())             else if (!message->isComplete())
             {             {
                   // Process an incomplete response chunk
   
                 CIMResponseMessage* response;                 CIMResponseMessage* response;
                 response = dynamic_cast<CIMResponseMessage*>(message);                 response = dynamic_cast<CIMResponseMessage*>(message);
                 PEGASUS_ASSERT(response != 0);                 PEGASUS_ASSERT(response != 0);
Line 1361 
Line 1141 
             }             }
             else             else
             {             {
                   // Process a completed response
   
                 CIMResponseMessage* response;                 CIMResponseMessage* response;
                 response = dynamic_cast<CIMResponseMessage*>(message);                 response = dynamic_cast<CIMResponseMessage*>(message);
                 PEGASUS_ASSERT(response != 0);                 PEGASUS_ASSERT(response != 0);


Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2