Example #1
0
/**
 * Destroy and removes the shared memory region from OS.
 * 
 * The timing of which OS removes the memory is OS dependent. However when 
 * you make a call you can considered that you can no longer access the region through
 * the handle. Memory allocated for handle structure is freed as well.
 * 
 * @param[in] portLibrary The port Library
 * @param[in] handle Pointer to a valid shared memory handle
 * 
 * @return 0 on success, -1 on failure.
 */
IDATA VMCALL
hyshmem_destroy (struct HyPortLibrary * portLibrary,
                 struct hyshmem_handle ** handle)
{
  IDATA rc;

  Trc_PRT_shmem_hyshmem_destroy_Entry (*handle);

  if (NULL == *handle)
    {
      Trc_PRT_shmem_hyshmem_destroy_Exit ();
      return SUCCESS;
    }

  portLibrary->shmem_detach (portLibrary, handle);

  rc = portLibrary->file_unlink (portLibrary, (*handle)->baseFileName);
  Trc_PRT_shmem_hyshmem_destroy_Debug1 ((*handle)->baseFileName, rc, errno);

  if (-1 == shmctl ((*handle)->shmid, IPC_RMID, NULL))
    {
      portLibrary->error_set_last_error (portLibrary, errno,
                                         findError_shmctl (errno,
                                                           __errno2 ()));
      Trc_PRT_shmem_hyshmem_destroy_Exit1 ();
      return FAILED;
    }

  portLibrary->shmem_close (portLibrary, handle);
  Trc_PRT_shmem_hyshmem_destroy_Exit ();
  return SUCCESS;
}
void ZOSConsoleManager::startConsoleWatchThread(void)
{
    PEG_METHOD_ENTER(TRC_SERVER,
                     "ZOSConsoleManager::startConsoleWatchThread");

    pthread_t thid;

    if ( pthread_create(&thid,
                        NULL,
                        ZOSConsoleManager::_consoleCommandWatchThread,
                        NULL) != 0 )
    {
        char str_errno2[10];
        sprintf(str_errno2,"%08X",__errno2());
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
                      MessageLoaderParms(
                          "Server.ConsoleManager_zOS.NO_CONSOLE_THREAD.PEGASUS_OS_ZOS",
                          "CIM Server Console command thread cannot be created: "
                          "$0 ( errno $1, reason code 0x$2 ).",
                          strerror(errno),
                          errno,
                          str_errno2));
    }

    PEG_METHOD_EXIT();
}
Example #3
0
/**
 * Attaches the shared memory represented by the handle
 * 
 * @param[in] portLibrary The port Library
 * @param[in] handle A valid shared memory handle
 * 
 * @return: A pointer to the shared memory region, NULL on failure
 */
void *VMCALL
hyshmem_attach (struct HyPortLibrary *portLibrary,
                struct hyshmem_handle *handle)
{
  void *region;
  Trc_PRT_shmem_hyshmem_attach_Entry (handle);

  if (NULL == handle)
    {
      Trc_PRT_shmem_hyshmem_attach_Exit1 ();
      return NULL;
    }

  Trc_PRT_shmem_hyshmem_attach_Debug1 (handle->shmid);

  if (NULL != handle->regionStart)
    {
      Trc_PRT_shmem_hyshmem_attach_Exit (handle->regionStart);
      return handle->regionStart;
    }

  if (handle->shmid > 0)
    {
      region = shmat (handle->shmid, 0, 0);
      /* Do not do shmctl to release on event of ^C or crash */
      if ((void *) -1 != region)
        {
          handle->regionStart = region;
          Trc_PRT_shmem_hyshmem_attach_Exit (region);
          return region;
        }
    }

  portLibrary->error_set_last_error (portLibrary, errno,
                                     findError_shmat (errno, __errno2 ()));
  Trc_PRT_shmem_hyshmem_attach_Exit2 (errno);
  return NULL;
}
Example #4
0
void printError() {
   printf("errno = %d \n", errno);
   printf("_errno2() = %08x  %s", __errno2(), errnojr);
}
Example #5
0
    virtual int startProviderAgent(
        const char* module,
        const String& pegasusHome,
        const String& userName,
        int& pid,
        AnonymousPipe*& readPipe,
        AnonymousPipe*& writePipe)
    {
        PEG_METHOD_ENTER(TRC_SERVER,"ExecutorLoopbackImpl::startProviderAgent");

#if !defined(PEGASUS_ENABLE_PRIVILEGE_SEPARATION)

        // Resolve full path of "cimprovagt" program.

        String path = FileSystem::getAbsolutePath(
            pegasusHome.getCString(), PEGASUS_PROVIDER_AGENT_PROC_NAME);

        // Create CString handles for cimprovagt arguments

        CString agentProgramPath = path.getCString();
        CString userNameCString = userName.getCString();

# if defined(PEGASUS_DISABLE_PROV_USERCTXT)
        const char* setUserContextFlag = "0";    // False
# else
        const char* setUserContextFlag = "1";    // True
# endif

# if defined(PEGASUS_OS_TYPE_WINDOWS)

        AutoMutex autoMutex(_mutex);

        // Set output parameters in case of failure.

        pid = 0;
        readPipe = 0;
        writePipe = 0;

        // Create pipes. Export handles to string.

        AutoPtr<AnonymousPipe> pipeFromAgent(new AnonymousPipe());
        AutoPtr<AnonymousPipe> pipeToAgent(new AnonymousPipe());

        char readHandle[32];
        char writeHandle[32];
        pipeToAgent->exportReadHandle(readHandle);
        pipeFromAgent->exportWriteHandle(writeHandle);

        // Initialize PROCESS_INFORMATION.

        PROCESS_INFORMATION piProcInfo;
        ZeroMemory(&piProcInfo, sizeof (PROCESS_INFORMATION));

        // Initialize STARTUPINFO.

        STARTUPINFO siStartInfo;
        ZeroMemory(&siStartInfo, sizeof (STARTUPINFO));
        siStartInfo.cb = sizeof (STARTUPINFO);

        // Format command line.

        char cmdLine[2048];

        sprintf(cmdLine, "\"%s\" %s %s %s \"%s\" \"%s\"",
            (const char*)agentProgramPath,
            setUserContextFlag,
            readHandle,
            writeHandle,
            (const char*)userNameCString,
            module);

        //  Create provider agent proess.

        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_METHOD_EXIT();
            return -1;
        }

        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);

        // Close our copies of the agent's ends of the pipes

        pipeToAgent->closeReadHandle();
        pipeFromAgent->closeWriteHandle();

        readPipe = pipeFromAgent.release();
        writePipe = pipeToAgent.release();

        PEG_METHOD_EXIT();
        return 0;

# else /* POSIX CASE FOLLOWS */
        
        AutoMutex autoMutex(_mutex);

        // Initialize output parameters in case of error.

        pid = -1;
        readPipe = 0;
        writePipe = 0;

        // Pipes:

        int to[2];
        int from[2];
        char toPipeArg[32];
        char fromPipeArg[32];

        do
        {
            // Create "to-agent" pipe:

            if (pipe(to) != 0)
            {
                PEG_METHOD_EXIT();
                return -1;
            }
                
            // Create "from-agent" pipe:

            if (pipe(from) != 0)
            {
                PEG_METHOD_EXIT();
                return -1;
            }

            // Initialize the cimprovagt pipe arguments:

            sprintf(toPipeArg, "%d", to[0]);
            sprintf(fromPipeArg, "%d", from[1]);

            // Start provider agent:

#  if defined(PEGASUS_OS_ZOS)
            // zOS uses __spawn2() instead of fork() to start provider agent

            struct __inheritance inherit;
            const char *c_argv[7];

            c_argv[0] = agentProgramPath;
            c_argv[1] = setUserContextFlag;
            c_argv[2] = toPipeArg;
            c_argv[3] = fromPipeArg;
            c_argv[4] = userNameCString;
            c_argv[5] = module; 
            c_argv[6] = NULL;

            // reset the inherit structure
            memset(&inherit,0,sizeof(inherit));

            // The provider agent should get a defined JobName.
            inherit.flags=SPAWN_SETJOBNAME;
            memcpy( inherit.jobname,"CFZOOPA ",
                    sizeof(inherit.jobname));
            
            PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
                "Starting provider agent: %s %s %s %s %s %s %s",
                (const char*)agentProgramPath,
                c_argv[0],
                c_argv[1],
                c_argv[2],
                c_argv[3],
                c_argv[4],
                c_argv[5]));

            pid = __spawn2(agentProgramPath,0,NULL,&inherit,
                           c_argv,(const char **)environ);

            if (pid < 0)
            {
                PEG_TRACE((TRC_SERVER, Tracer::LEVEL1,
                    "Spawn of provider agent fails:%s "
                        "( errno %d , reason code %08X )", 
                    strerror(errno) ,errno,__errno2()));
                PEG_METHOD_EXIT();
                return -1;
            }

#  else    // !defined(PEGASUS_OS_ZOS)

#   if defined(PEGASUS_OS_VMS)
            pid = (int)vfork();
#   elif defined(PEGASUS_OS_PASE)
            pid = (int)fork400("QUMEPRVAGT",0);
#   else
            pid = (int)fork();
#   endif

            if (pid < 0)
            {
                PEG_TRACE((TRC_SERVER, Tracer::LEVEL1,
                     "Fork for provider agent fails: errno = %d",errno)); 
                PEG_METHOD_EXIT();
                return -1;
            }
                
            if (pid == 0)
            {
                // Child process

#   if !defined(PEGASUS_OS_VMS)
                // Close unused pipe descriptors:

                close(to[1]);
                close(from[0]);

                // Close unused descriptors. Leave stdin, stdout, stderr,
                // and the child's pipe descriptors open.
                //
                // Honor rlimit (rlim_cur) unless it's too large; this can be a
                // 64-bit number on some platforms, causing us to stop responding

                struct rlimit rlim;
                int fdLimit = 0;

                if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
                {
                    fdLimit = int(rlim.rlim_cur);
                    if (fdLimit > 2500)
                    {
                        fdLimit = 2500;
                    }
                }
                else
                {
                    fdLimit = 2500;
                }

                for (int i = 3; i < fdLimit; i++)
                {
                    if (i != to[0] && i != from[1])
                        close(i);
                }
#   endif /* !defined(PEGASUS_OS_VMS) */

                // Exec the cimprovagt program.

                {
                    if (execl(
                            agentProgramPath,
                            agentProgramPath,
                            setUserContextFlag,
                            toPipeArg,
                            fromPipeArg,
                            (const char*)userNameCString,
                            module,
                            (char*)0) == -1)
                    {
                        PEG_TRACE((TRC_SERVER, Tracer::LEVEL1,
                            "execl() failed.  errno = %d.", errno));
                        _exit(1);
                    }
                }
            }
#  endif /* PEGASUS_OS_ZOS */
        }
        while (0);

        PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
            "Provider agent started: pid(%d).", pid));

        // Close unused pipe descriptors.

        close(to[0]);
        close(from[1]);

        // Set output parameters.

        int readFd = from[0];
        int writeFd = to[1];

        // Create to and from AnonymousPipe instances to correspond to the pipe
        // descriptors created above.

        char readFdStr[32];
        char writeFdStr[32];
        sprintf(readFdStr, "%d", readFd);
        sprintf(writeFdStr, "%d", writeFd);

        readPipe = new AnonymousPipe(readFdStr, 0);
        writePipe = new AnonymousPipe(0, writeFdStr);

#  if defined(PEGASUS_HAS_SIGNALS)
#   if !defined(PEGASUS_DISABLE_PROV_USERCTXT) && !defined(PEGASUS_OS_ZOS)
        // The cimprovagt forks and returns right away.  Clean up the zombie
        // process now instead of in reapProviderAgent().
        int status = 0;
        while ((status = waitpid(pid, 0, 0)) == -1 && errno == EINTR)
            ;
#   endif
#  endif

        PEG_METHOD_EXIT();
        return 0;

# endif /* POSIX CASE */

#else /* PEGASUS_ENABLE_PRIVILEGE_SEPARATION is defined */

        // Out-of-Process providers are never started by the cimserver process
        // when Privilege Separation is enabled.
        return -1;

#endif
    }
Example #6
0
static I_32
createSharedMemory (HyPortLibrary * portLibrary,
                    struct hyshmem_handle **handle, const char *controlFile,
                    I_32 size, I_32 perm)
{
  I_32 projid = 1;
  key_t fkey;
  I_32 shmid;
  IDATA rc;

  int group_perm = portLibrary->portGlobals->control.shmem_group_perm;
  int shmflags = group_perm ? SHMFLAGS_GROUP : SHMFLAGS;

  Trc_PRT_shmem_createSharedMemory_Entry ();

  /* Control file doesn't exist, so we create it along with shared memory region.
   * If the control file exists we might be in a creation race, return to the top
   */
  rc = createFile (portLibrary, controlFile);
  if (HYPORT_ERROR_FILE_EXIST == rc)
    {
      Trc_PRT_shmem_createSharedMemory_Exit1 ();
      return RETRY;
    }
  else if (CREATE_ERROR == rc)
    {
      Trc_PRT_shmem_createSharedMemory_Exit2 ();
      return FAILED;
    }

  /*created control file, now create shared memory */
  while (1)
    {
      /* first ftok to get key */

      Trc_PRT_shmem_createSharedMemory_ftok (controlFile, projid);
      fkey = ftok (controlFile, projid);
      if (-1 == fkey)
        {
          if (errno == ENOENT || errno == ENOTDIR)
            {
              /* TODO: Someone removed our directory!
               * We will need a new return code here and tell user
               * of this lib to restart at top */
              Trc_PRT_shmem_createSharedMemory_Exit3 ();
              return RETRY;
            }
          /* any other error code is is bad */
          Trc_PRT_shmem_createSharedMemory_Exit4 ();
          return FAILED;
        }

      /* now we do semget */
      /* TODO: we need to round up size to nearest M */
      Trc_PRT_shmem_createSharedMemory_shmget (fkey, size, SHMFLAGS);
      shmid = shmget (fkey, size, shmflags);

      if (-1 == shmid)
        {
          if (EEXIST == errno)
            {
              if (projid >= HYSH_MAX_PROJ_ID)
                {
                  portLibrary->error_set_last_error (portLibrary, errno,
                                                     findError_shmget (errno,
                                                                       __errno2
                                                                       ()));
                  Trc_PRT_shmem_createSharedMemory_Exit5 (HYSH_MAX_PROJ_ID);
                  return FAILED;
                }
              else
                {
                  Trc_PRT_shmem_createSharedMemory_shmget_Event1 (projid);
                  projid++;
                  continue;
                }
            }

          /* If we get here it means some OS error stop us getting shm segments */
          /* Here we would want to capture the zOS errno2 - in order to see whether
             We are trying to create in different storage key */
          portLibrary->error_set_last_error (portLibrary, errno,
                                             findError_shmget (errno,
                                                               __errno2 ()));
          portLibrary->file_unlink (portLibrary, controlFile);
          Trc_PRT_shmem_createSharedMemory_Exit6 (errno, __errno2 ());
          return FAILED;
        }
      else
        {
          /* shmid is good, we can stop loop */
          break;
        }
    }

  Trc_PRT_shmem_createSharedMemory_Event1 (shmid);

  if (writeControlFile (portLibrary, controlFile, projid, fkey, size, shmid)
      == CREATE_ERROR)
    {
      Trc_PRT_shmem_createSharedMemory_Exit7 ();
      portLibrary->file_unlink (portLibrary, controlFile);
      return FAILED;
    }

  *handle = createshmHandle (portLibrary, shmid, controlFile);
  if (NULL == *handle)
    {
      Trc_PRT_shmem_createSharedMemory_Exit8 ();
      return FAILED;
    }

  (*handle)->timestamp = portLibrary->file_lastmod (portLibrary, controlFile);

  Trc_PRT_shmem_createSharedMemory_Exit ();
  return HYPORT_INFO_SHMEM_CREATED;
}
//
// z/OS console interface waiting for operator stop command
//
void* ZOSConsoleManager::_consoleCommandWatchThread(void*)
{
    PEG_METHOD_ENTER(TRC_SERVER,
                     "ZOSConsoleManager::_consoleCommandWatchThread");

    struct __cons_msg    cons;
    int                  concmd=0;
    char                 modstr[128];
    int                  rc;

    memset(&cons,0,sizeof(cons));
    memset(modstr,0,sizeof(modstr));

    do
    {
        rc = __console(&cons, modstr, &concmd);

        if (rc != 0)
        {
            int errornumber = errno;
            char str_errno2[10];
            sprintf(str_errno2,"%08X",__errno2());

            Logger::put_l(
                Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
                MessageLoaderParms(
                    "Server.ConsoleManager_zOS.CONSOLE_ERROR.PEGASUS_OS_ZOS",
                    "Console Communication Service failed:"
                    "$0 ( errno $1, reason code 0x$2 ).",
                    strerror(errornumber),
                    errornumber,
                    str_errno2));

            break;
        }

        // Check if we received a stop command from the console
        if (concmd == _CC_modify)
        {
            // Ensure the command we received from the console is
            // null terminated.
            modstr[127] = '\0';

            PEG_TRACE((TRC_SERVER, Tracer::LEVEL4,
                       "Received MODIFY command: %s", modstr));

            processModifyCommand(modstr);
        }
        else if (concmd != _CC_stop)
        {
            // Just issue a console message that the command was
            // not recognized and wait again for the stop command.
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                MessageLoaderParms(
                    "Server.ConsoleManager_zOS.CONSOLE_NO_MODIFY."
                    "PEGASUS_OS_ZOS",
                    "Command not recognized by CIM server."));
        }
        else
        {
            Logger::put_l(
                Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
                MessageLoaderParms(
                    "Server.ConsoleManager_zOS.CONSOLE_STOP.PEGASUS_OS_ZOS",
                    "STOP command received from z/OS console,"
                    " initiating shutdown."));
        }

        // keep on until we encounter an error or received a STOP
    } while ( (concmd != _CC_stop) && (rc == 0) );

    CIMServer::shutdownSignal();

    PEG_METHOD_EXIT();
    pthread_exit(0);

    return NULL;
}