/** * 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(); }
/** * 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; }
void printError() { printf("errno = %d \n", errno); printf("_errno2() = %08x %s", __errno2(), errnojr); }
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 }
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; }