(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.6 and 1.6.2.13

version 1.6, 2006/11/14 18:34:57 version 1.6.2.13, 2007/01/12 06:31:04
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 128 
Line 129 
 { {
 public: public:
     ProviderAgentContainer(     ProviderAgentContainer(
           const SessionKey& sessionKey,
         const String & moduleName,         const String & moduleName,
         const String & userName,         const String & userName,
         Uint16 userContext,         Uint16 userContext,
Line 219 
Line 221 
     Mutex _agentMutex;     Mutex _agentMutex;
  
     /**     /**
           Session key of the user on whose behalf this provider agent was loaded.
       */
       SessionKey _sessionKey;
   
       /**
         Name of the provider module served by this Provider Agent.         Name of the provider module served by this Provider Agent.
      */      */
     String _moduleName;     String _moduleName;
Line 328 
Line 335 
         ProviderManagerRouter::_subscriptionInitComplete member variable.         ProviderManagerRouter::_subscriptionInitComplete member variable.
      */      */
     Boolean _subscriptionInitComplete;     Boolean _subscriptionInitComplete;
   
       /**
           This SessionKey is used for processing upcalls from the out-of-process
           provider module received from _pipeFromAgent. This session key was
           assigned by Executor::startProviderAgent() as the
           providerAgentSessionKey output argument.
       */
       SessionKey _providerAgentSessionKey;
 }; };
  
 Uint32 ProviderAgentContainer::_numProviderProcesses = 0; Uint32 ProviderAgentContainer::_numProviderProcesses = 0;
Line 339 
Line 354 
     reinterpret_cast<CIMResponseMessage*>(&_REQUEST_NOT_PROCESSED);     reinterpret_cast<CIMResponseMessage*>(&_REQUEST_NOT_PROCESSED);
  
 ProviderAgentContainer::ProviderAgentContainer( ProviderAgentContainer::ProviderAgentContainer(
       const SessionKey& sessionKey,
     const String & moduleName,     const String & moduleName,
     const String & userName,     const String & userName,
     Uint16 userContext,     Uint16 userContext,
Line 346 
Line 362 
     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),      :
         _sessionKey(sessionKey),
         _moduleName(moduleName),
       _userName(userName),       _userName(userName),
       _userContext(userContext),       _userContext(userContext),
       _indicationCallback(indicationCallback),       _indicationCallback(indicationCallback),
Line 355 
Line 373 
       _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 389 
Line 408 
  
 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  
     {  
         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();      PEGASUS_UID_T newUid = (PEGASUS_UID_T)-1;
     }      PEGASUS_GID_T newGid = (PEGASUS_UID_T)-1;
 #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 563 
Line 436 
                     "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;
       SessionKey providerAgentSessionKey;
       AnonymousPipe* readPipe;
       AnonymousPipe* writePipe;
   
       int status = Executor::startProviderAgent(
           _sessionKey,
           (const char*)_moduleName.getCString(),
           newUid,
           newGid,
           pid,
           _providerAgentSessionKey,
           readPipe,
           writePipe);
   
       if (status != 0)
     {     {
         Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,         Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
             "fork() failed.  errno = %d.", errno);              "Executor::createProviderAgent() 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))  
                 {  
                     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,      // 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  
             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) # if defined(PEGASUS_HAS_SIGNALS)
     _pid = pid;     _pid = pid;
 # endif # endif
 #endif  
   
     //  
     // CIM Server process  
     //  
  
     // Close our copies of the agent's ends of the pipes      _pipeFromAgent.reset(readPipe);
     pipeToAgent->closeReadHandle();      _pipeToAgent.reset(writePipe);
     pipeFromAgent->closeWriteHandle();  
  
     _pipeToAgent.reset(pipeToAgent.release());  
     _pipeFromAgent.reset(pipeFromAgent.release());  
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
Line 741 
Line 545 
     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 755 
Line 560 
  
     PEGASUS_ASSERT(message == 0);     PEGASUS_ASSERT(message == 0);
  
       // Request messages must bear the session key of the originating pipe.
       {
           CIMRequestMessage* m = dynamic_cast<CIMRequestMessage*>(message);
   
           if (m)
               m->sessionKey = _providerAgentSessionKey;
       }
   
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
 } }
  
Line 802 
Line 615 
     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 838 
Line 649 
     }     }
     catch (...)     catch (...)
     {     {
           SessionKey sessionKey = _providerAgentSessionKey;
   
         // Closing the connection causes the agent process to exit         // Closing the connection causes the agent process to exit
         _pipeToAgent.reset();         _pipeToAgent.reset();
         _pipeFromAgent.reset();         _pipeFromAgent.reset();
Line 846 
Line 659 
         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;              pid_t status = Executor::reapProviderAgent(sessionKey, _pid);
             do  
             {  
                 status = waitpid(_pid, 0, 0);  
             } while ((status == -1) && (errno == EINTR));  
  
             if (status == -1)             if (status == -1)
             {             {
                 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,                 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                     "ProviderAgentContainer::_initialize(): "                     "ProviderAgentContainer::_initialize(): "
                         "waitpid failed; errno = %d.", errno);                      "Executor::reapProviderAgent() failed");
             }             }
         }         }
 #endif #endif
Line 896 
Line 705 
  
     try     try
     {     {
           SessionKey sessionKey = _providerAgentSessionKey;
   
         // Close the connection with the Provider Agent         // Close the connection with the Provider Agent
         _pipeFromAgent.reset();         _pipeFromAgent.reset();
         _pipeToAgent.reset();         _pipeToAgent.reset();
Line 909 
Line 720 
  
 #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;          pid_t status = Executor::reapProviderAgent(sessionKey, _pid);
         do  
         {  
             status = waitpid(_pid, 0, 0);  
         } while ((status == -1) && (errno == EINTR));  
  
         if (status == -1)         if (status == -1)
         {         {
             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,             Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
                 "ProviderAgentContainer::_uninitialize(): "                 "ProviderAgentContainer::_uninitialize(): "
                     "waitpid failed; errno = %d.", errno);                      "Executor::reapProviderAgent() failed.");
         }         }
 #endif #endif
  
Line 1327 
Line 1134 
                 return;                 return;
             }             }
  
               // Request messages must bear the session key of the
               // originating pipe.
               {
                   CIMRequestMessage* m =
                       dynamic_cast<CIMRequestMessage*>(message);
   
                   if (m)
                       m->sessionKey = _providerAgentSessionKey;
               }
   
               // It is a CIM_PROCESS_INDICATION_REQUEST_MESSAGE?
   
             if (message->getType() == CIM_PROCESS_INDICATION_REQUEST_MESSAGE)             if (message->getType() == CIM_PROCESS_INDICATION_REQUEST_MESSAGE)
             {             {
                 // Forward indications to the indication callback                 // Forward indications to the indication callback
Line 1781 
Line 1600 
     if (!_providerAgentTable.lookup(key, pa))     if (!_providerAgentTable.lookup(key, pa))
     {     {
         pa = new ProviderAgentContainer(         pa = new ProviderAgentContainer(
             moduleName, userName, userContext,              request->sessionKey, moduleName, userName, userContext,
             _indicationCallback, _responseChunkCallback,             _indicationCallback, _responseChunkCallback,
             _providerModuleFailCallback,             _providerModuleFailCallback,
             _subscriptionInitComplete);             _subscriptionInitComplete);


Legend:
Removed from v.1.6  
changed lines
  Added in v.1.6.2.13

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2