| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include <stdio.h> |
| #include <regex.h> |
| #include "reqqueue.h" |
| #include "montrace.h" |
| #include "monsonar.h" |
| #include "monlogging.h" |
| #include "nameserver.h" |
| |
| extern CMonStats *MonStats; |
| #ifndef NAMESERVER_PROCESS |
| extern CNode *MyNode; |
| #endif |
| extern CNodeContainer *Nodes; |
| extern bool NameServerEnabled; |
| #ifndef NAMESERVER_PROCESS |
| extern CNameServer *NameServer; |
| #endif |
| |
| // Copy information for a specific process into the reply message buffer. |
| void CExtProcInfoBase::ProcessInfo_CopyData(CProcess *process, ProcessInfoState &procState) |
| { |
| const char method_name[] = "CExtProcInfoBase::ProcessInfo_CopyData"; |
| CProcess *parent; |
| |
| TRACE_ENTRY; |
| |
| procState.nid = process->GetNid(); |
| procState.pid = process->GetPid(); |
| procState.verifier = process->GetVerifier(); |
| procState.type = process->GetType(); |
| strncpy (procState.process_name, process->GetName(), MAX_PROCESS_NAME); |
| strncpy (procState.program, process->program(), MAX_PROCESS_PATH); |
| procState.os_pid = process->GetPid(); |
| procState.priority = process->GetPriority(); |
| procState.pending_delete = process->IsDeletePending(); |
| procState.pending_replication = false; // obsolete field |
| procState.state = process->GetState(); |
| procState.event_messages = process->IsEventMessages(); |
| procState.system_messages = process->IsSystemMessages(); |
| procState.paired = process->IsPaired(); |
| procState.waiting_startup = !process->IsStartupCompleted(); |
| procState.opened = process->IsOpened(); |
| procState.backup = process->IsBackup(); |
| procState.creation_time = process->GetCreationTime(); |
| parent = (process->GetParentNid() == -1 ? |
| NULL : |
| Nodes->GetLNode(process->GetParentNid()) |
| ->GetProcessL(process->GetParentPid())); |
| if (parent) |
| { |
| procState.parent_nid = parent->GetNid(); |
| procState.parent_pid = parent->GetPid(); |
| procState.parent_verifier = parent->GetVerifier(); |
| strcpy (procState.parent_name, parent->GetName()); |
| } |
| else |
| { |
| procState.parent_nid = -1; |
| procState.parent_pid = -1; |
| procState.parent_verifier = -1; |
| procState.parent_name[0] = '\0'; |
| } |
| |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| char desc[2048]; |
| char* descp = desc; |
| sprintf( desc, |
| "ProcessInfo reply:\n" |
| " procState.process_name=%s\n" |
| " procState.nid=%d\n" |
| " procState.pid=%d\n" |
| " procState.verifier=%d\n" |
| " procState.type=%d\n" |
| " procState.os_pid=%d\n" |
| " procState.parent_name=%s\n" |
| " procState.parent_nid=%d\n" |
| " procState.parent_pid=%d\n" |
| " procState.parent_verifier=%d\n" |
| " procState.priority=%d\n" |
| " procState.state=%d\n" |
| " procState.pending_delete=%d\n" |
| " procState.event_messages=%d\n" |
| " procState.system_messages=%d\n" |
| " procState.paired=%d\n" |
| " procState.waiting_startup=%d\n" |
| " procState.opened=%d\n" |
| " procState.backup=%d\n" |
| " procState.program=%s\n" |
| , procState.process_name |
| , procState.nid |
| , procState.pid |
| , procState.verifier |
| , procState.type |
| , procState.os_pid |
| , procState.parent_name |
| , procState.parent_nid |
| , procState.parent_pid |
| , procState.parent_verifier |
| , procState.priority |
| , procState.state |
| , procState.pending_delete |
| , procState.event_messages |
| , procState.system_messages |
| , procState.paired |
| , procState.waiting_startup |
| , procState.opened |
| , procState.backup |
| , procState.program ); |
| trace_printf( "%s@%d - %s\n" |
| , method_name, __LINE__, descp ); |
| } |
| |
| TRACE_EXIT; |
| } |
| |
| |
| void CExtProcInfoBase::ProcessInfo_CopyPairData( CProcess *process |
| , ProcessInfoState &procState ) |
| { |
| CProcess *parent = (process->GetParentNid() == -1 ? |
| NULL : |
| Nodes->GetLNode(process->GetParentNid()) |
| ->GetProcessL(process->GetParentPid())); |
| if ( parent ) |
| { |
| if ( process->IsBackup() || parent->IsBackup()) |
| { |
| if ( parent->IsBackup()) |
| { |
| ProcessInfo_CopyData( process, procState ); |
| } |
| else |
| { |
| ProcessInfo_CopyData( parent, procState ); |
| } |
| } |
| else |
| { |
| ProcessInfo_CopyData( process, procState ); |
| } |
| } |
| else |
| { |
| ProcessInfo_CopyData( process, procState ); |
| } |
| } |
| |
| // Get a pointer to the first process object for node specified by |
| // "nid". If there are no processes on that node and |
| // "getDataForAllNodes" is true, advance to subsequent nodes until |
| // find a process or run out of nodes. Note thar parameter "nid" |
| // is a reference parameter because this method may change its value |
| // and the caller will need the new value. |
| CProcess * CExtProcInfoBase::ProcessInfo_GetProcess (int &nid, bool getDataForAllNodes) |
| { |
| CProcess * process; |
| CLNode *lnode = NULL; |
| |
| lnode = Nodes->GetLNode( nid ); |
| do |
| { |
| if (lnode) |
| { |
| #ifdef NAMESERVER_PROCESS // ignore node state |
| process = lnode->GetFirstProcess(); |
| if (process != 0) |
| { |
| return process; |
| } |
| #else |
| if (lnode->GetState() == State_Up || |
| lnode->GetState() == State_Shutdown) |
| { |
| process = lnode->GetFirstProcess(); |
| if (process != 0) |
| { |
| return process; |
| } |
| } |
| #endif |
| lnode = lnode->GetNext(); |
| nid = lnode ? lnode->GetNid() : nid; |
| } |
| } while (getDataForAllNodes && lnode); |
| |
| return(NULL); |
| } |
| |
| // Information for more than one process is being requested. Iterate |
| // through the process list and return process information for processes |
| // meeting the requested criteria. |
| int CExtProcInfoBase::ProcessInfo_BuildReply(CProcess *process, |
| struct message_def * msg, |
| PROCESSTYPE type, |
| bool getDataForAllNodes, |
| char *pattern) |
| { |
| int currentIndex = (process != 0) |
| ? Nodes->GetNidIndex( process->GetNid() ) |
| : Nodes->GetLNodesCount(); |
| bool moreToRetrieve; |
| bool copy = true; |
| bool reg = false; |
| int count = 0; |
| int rerr; |
| char *process_pattern = pattern; |
| regex_t regex; |
| |
| if (strlen( pattern ) > 0) |
| { |
| if (*process_pattern == '$') |
| { |
| process_pattern++; |
| } |
| // Compile pattern regex |
| rerr = regcomp( ®ex, process_pattern, REG_EXTENDED ); |
| if (rerr == 0) |
| { |
| copy = false; |
| reg = true; |
| } |
| } |
| do |
| { |
| // Retrieve process data for processes on current node |
| while ( process ) |
| { |
| if (type == ProcessType_Undefined || type == process->GetType()) |
| { |
| if (reg) |
| { |
| // Check for regex match |
| rerr = regexec( ®ex, process->GetName(), 0 , NULL, 0 ); |
| copy = (rerr == 0) ? true : false; |
| } |
| if (copy) |
| { |
| ProcessInfo_CopyData(process, |
| msg->u.reply.u.process_info.process[count]); |
| count++; |
| } |
| } |
| process = process->GetNextL(); |
| if ( count == MAX_PROCINFO_LIST ) |
| { |
| // Ran out of room to store data. Give caller and indication |
| // of whether there is more data remaining. |
| msg->u.reply.u.process_info.more_data |
| = (process != 0) |
| || (++currentIndex < Nodes->GetLNodesCount()); |
| return count; |
| } |
| } |
| |
| moreToRetrieve = false; |
| if (getDataForAllNodes && ++currentIndex < Nodes->GetLNodesCount()) |
| { // Start retrieving process data for next node. We ask |
| // ProcessInfo_GetProcess for the first process on lnode of |
| // "currentIndex" which has just been incremented. Note |
| // that it is possible there are no processes on that node |
| // so ProcessInfo_GetProcess will return a process on the |
| // first node it finds and "currentIndex" will be updated |
| // to be the node index number where the process resides. |
| |
| int nid = Nodes->GetNidByMap( currentIndex ); |
| if (nid == -1) break; |
| process = ProcessInfo_GetProcess( nid, getDataForAllNodes); |
| currentIndex = Nodes->GetNidIndex( nid ); |
| moreToRetrieve = true; |
| } |
| } while (moreToRetrieve); |
| |
| if (reg) |
| { |
| regfree( ®ex ); |
| } |
| |
| msg->u.reply.u.process_info.more_data = false; |
| return count; |
| } |
| |
| CExtProcInfoReq::CExtProcInfoReq (reqQueueMsg_t msgType, |
| int nid, int pid, int sockFd, |
| struct message_def *msg ) |
| : CExtProcInfoBase(msgType, nid, pid, sockFd, msg) |
| { |
| // Add eyecatcher sequence as a debugging aid |
| memcpy(&eyecatcher_, "RQEO", 4); |
| } |
| |
| CExtProcInfoReq::~CExtProcInfoReq() |
| { |
| // Alter eyecatcher sequence as a debugging aid to identify deleted object |
| memcpy(&eyecatcher_, "rqeo", 4); |
| } |
| |
| void CExtProcInfoReq::populateRequestString( void ) |
| { |
| char strBuf[MON_STRING_BUF_SIZE] = { 0 }; |
| |
| snprintf( strBuf, sizeof(strBuf), |
| "ExtReq(%s) req #=%ld " |
| "requester(name=%s/nid=%d/pid=%d/os_pid=%d/verifier=%d) " |
| "target(name=%s/nid=%d/pid=%d/verifier=%d) pattern(name=%s)" |
| , CReqQueue::svcReqType[reqType_], getId() |
| , msg_->u.request.u.process_info.process_name |
| , msg_->u.request.u.process_info.nid |
| , msg_->u.request.u.process_info.pid |
| , pid_ |
| , msg_->u.request.u.process_info.verifier |
| , msg_->u.request.u.process_info.target_process_name |
| , msg_->u.request.u.process_info.target_nid |
| , msg_->u.request.u.process_info.target_pid |
| , msg_->u.request.u.process_info.target_verifier |
| , msg_->u.request.u.process_info.target_process_pattern ); |
| requestString_.assign( strBuf ); |
| } |
| |
| void CExtProcInfoReq::performRequest() |
| { |
| const char method_name[] = "CExtProcInfoReq::performRequest"; |
| TRACE_ENTRY; |
| |
| #ifndef NAMESERVER_PROCESS |
| bool getMonitorInfo = false; |
| if (strcasecmp(msg_->u.request.u.process_info.target_process_name, "MONITOR") == 0) |
| { |
| getMonitorInfo = true; |
| msg_->u.request.u.process_info.target_process_name[0] = 0; |
| } |
| |
| if ( NameServerEnabled && !getMonitorInfo ) |
| { |
| int rc = NameServer->ProcessInfo(msg_); // in reqQueue thread (CExternalReq) |
| if (rc) |
| { |
| char la_buf[MON_STRING_BUF_SIZE]; |
| snprintf( la_buf, sizeof(la_buf) |
| , "[%s] - Process info request to Name Server failed\n" |
| , method_name ); |
| mon_log_write(MON_REQ_PROCINFO_1, SQ_LOG_ERR, la_buf); |
| } |
| } |
| #endif |
| |
| #ifndef NAMESERVER_PROCESS |
| if ( NameServerEnabled && !getMonitorInfo ) |
| { |
| // Send reply to requester |
| lioreply(msg_, pid_); |
| } |
| else |
| { |
| #endif |
| int count = 0; |
| |
| // Record statistics (sonar counters) |
| if (sonar_verify_state(SONAR_ENABLED | SONAR_MONITOR_ENABLED)) |
| MonStats->req_type_processinfo_Incr(); |
| |
| nid_ = msg_->u.request.u.process_info.nid; |
| verifier_ = msg_->u.request.u.process_info.verifier; |
| processName_ = msg_->u.request.u.process_info.process_name; |
| |
| int target_nid = -1; |
| int target_pid = -1; |
| string target_process_name; |
| Verifier_t target_verifier = -1; |
| CProcess *requester = NULL; |
| |
| target_nid = msg_->u.request.u.process_info.target_nid; |
| target_pid = msg_->u.request.u.process_info.target_pid; |
| target_process_name = (const char *) msg_->u.request.u.process_info.target_process_name; |
| target_verifier = msg_->u.request.u.process_info.target_verifier; |
| |
| if ( processName_.size() ) |
| { // find by name |
| #ifdef NAMESERVER_PROCESS |
| // (check node state, check process state, not backup) |
| requester = Nodes->GetProcess( processName_.c_str() |
| , verifier_ ); |
| #else |
| requester = MyNode->GetProcess( processName_.c_str() |
| , verifier_ ); |
| #endif |
| } |
| else |
| { // find by pid |
| #ifdef NAMESERVER_PROCESS |
| // (don't check node state, don't check process state, backup is Ok) |
| requester = |
| Nodes->GetProcess( nid_ , pid_ , verifier_ |
| , false, false, true ); |
| #else |
| requester = MyNode->GetProcess( pid_ |
| , verifier_ ); |
| #endif |
| } |
| |
| #ifdef NAMESERVER_PROCESS |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf( "%s@%d tnid=%d, tpid=%d, tver=%d, tpname=%s, requester=%p\n" |
| , method_name, __LINE__ |
| , target_nid, target_pid, target_verifier, target_process_name.c_str() |
| , (void *) requester ); |
| } |
| #endif |
| |
| #ifdef NAMESERVER_PROCESS |
| if ( requester || ( nid_ == -1 && pid_ == -1 && verifier_ == -1 ) ) |
| #else |
| if ( requester ) |
| #endif |
| { |
| msg_->u.reply.u.process_info.more_data = false; |
| |
| // setup for type of status request |
| if ( target_process_name.size() ) |
| { // find by name |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf( "%s@%d request #%ld: ProcessInfo from %s (%d, %d:%d) " |
| "by name for %s:%d, process type=%d\n" |
| , method_name, __LINE__, id_ |
| , requester?requester->GetName():"" |
| , requester?requester->GetNid():-1 |
| , requester?requester->GetPid():-1 |
| , requester?requester->GetVerifier():-1 |
| , target_process_name.c_str(), target_verifier |
| , msg_->u.request.u.process_info.type); |
| } |
| |
| //if requester is requesting info for itself, return local process info |
| if ( requester && strcmp( requester->GetName() |
| , msg_->u.request.u.process_info.target_process_name) == 0 ) |
| { |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf("%s@%d request #%ld: ProcessInfo, for " |
| "requester\n", method_name, __LINE__, id_); |
| } |
| ProcessInfo_CopyData(requester, |
| msg_->u.reply.u.process_info.process[0]); |
| count = 1; |
| } |
| else |
| { |
| #ifdef NAMESERVER_PROCESS |
| // find by name (don't check node state, don't check process state, |
| // if verifier is -1, backup is NOT Ok, else is Ok) |
| CProcess *process = Nodes->GetProcess( target_process_name.c_str() |
| , target_verifier |
| , false, false |
| , target_verifier == -1 ? false : true ); |
| #else |
| CProcess *process = NULL; |
| // find by name (check node state, don't check process state, |
| // if verifier is -1, backup is NOT Ok, else is Ok) |
| if (msg_->u.request.u.process_info.target_process_name[0] == '$' ) |
| { |
| process = Nodes->GetProcess( target_process_name.c_str() |
| , target_verifier |
| , true, false |
| , target_verifier == -1 ? false : true ); |
| } |
| #endif |
| if (process) |
| { |
| if ( target_verifier == -1 ) |
| { // the name may represent process pair, return primary only |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf("%s@%d request #%ld: ProcessInfo, for " |
| "process pair\n", method_name, __LINE__, id_); |
| } |
| ProcessInfo_CopyPairData( process |
| , msg_->u.reply.u.process_info.process[0] ); |
| count = 1; |
| |
| } |
| else |
| { |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf("%s@%d request #%ld: ProcessInfo, for " |
| "process\n", method_name, __LINE__, id_); |
| } |
| ProcessInfo_CopyData( process |
| , msg_->u.reply.u.process_info.process[0] ); |
| count = 1; |
| } |
| } |
| } |
| } |
| else if (msg_->u.request.u.process_info.target_nid == -1) |
| { |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf("%s@%d request #%ld: ProcessInfo, for all " |
| "processes\n", method_name, __LINE__, id_); |
| } |
| |
| // get info for all processes in all nodes |
| int nid = Nodes->GetFirstNid(); |
| count = ProcessInfo_BuildReply( ProcessInfo_GetProcess(nid, true) |
| , msg_ |
| , msg_->u.request.u.process_info.type |
| , true |
| , msg_->u.request.u.process_info.target_process_pattern ); |
| } |
| else |
| { |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf( "%s@%d request #%ld: ProcessInfo, for (%d, %d:%d), " |
| "process type=%d\n" |
| , method_name, __LINE__, id_ |
| , target_nid, target_pid, target_verifier |
| , msg_->u.request.u.process_info.type); |
| } |
| |
| if (target_pid == -1) |
| { |
| // get info for all processes in node |
| if (target_nid >= 0 && target_nid < Nodes->GetLNodesConfigMax()) |
| { |
| count = ProcessInfo_BuildReply(Nodes->GetNode(target_nid)->GetFirstProcess(), |
| msg_, |
| msg_->u.request.u.process_info.type, |
| false, |
| msg_->u.request.u.process_info.target_process_pattern); |
| } |
| } |
| else |
| { |
| // get info for single process in node |
| if (requester && |
| (requester->GetType() == ProcessType_TSE || |
| requester->GetType() == ProcessType_ASE || |
| requester->GetType() == ProcessType_AMP) && |
| (requester->GetNid() == target_nid && |
| requester->GetPid() == target_pid)) |
| { |
| ProcessInfo_CopyData(requester, |
| msg_->u.reply.u.process_info.process[0]); |
| count = 1; |
| } |
| else if (target_nid >= 0 && target_nid < Nodes->GetLNodesConfigMax()) |
| { // find by nid/pid (check node state, don't check process state, backup is Ok) |
| CProcess *process = Nodes->GetProcess( target_nid |
| , target_pid |
| , target_verifier |
| , true, false, true ); |
| if (process) |
| { |
| ProcessInfo_CopyData(process, |
| msg_->u.reply.u.process_info.process[0]); |
| count = 1; |
| } |
| } |
| } |
| } |
| |
| msg_->u.reply.type = ReplyType_ProcessInfo; |
| msg_->u.reply.u.process_info.num_processes = count; |
| msg_->u.reply.u.process_info.return_code = MPI_SUCCESS; |
| |
| #ifdef NAMESERVER_PROCESS |
| monreply(msg_, sockFd_); |
| #else |
| // Send reply to requester |
| lioreply(msg_, pid_); |
| #endif |
| } |
| else |
| { // Reply to requester so it can release the buffer. |
| // We don't know about this process. |
| errorReply( MPI_ERR_EXITED ); |
| } |
| #ifndef NAMESERVER_PROCESS |
| } |
| #endif |
| |
| TRACE_EXIT; |
| } |
| |
| CExtProcInfoContReq::CExtProcInfoContReq (reqQueueMsg_t msgType, |
| int nid, int pid, int sockFd, |
| struct message_def *msg ) |
| : CExtProcInfoBase(msgType, nid, pid, sockFd, msg) |
| { |
| // Add eyecatcher sequence as a debugging aid |
| memcpy(&eyecatcher_, "RQEP", 4); |
| } |
| |
| CExtProcInfoContReq:: ~CExtProcInfoContReq() |
| { |
| // Alter eyecatcher sequence as a debugging aid to identify deleted object |
| memcpy(&eyecatcher_, "rqep", 4); |
| } |
| |
| void CExtProcInfoContReq::populateRequestString( void ) |
| { |
| char strBuf[MON_STRING_BUF_SIZE/2] = { 0 }; |
| |
| snprintf( strBuf, sizeof(strBuf), |
| "ExtReq(%s) req #=%ld requester(pid=%d)" |
| , CReqQueue::svcReqType[reqType_], getId(), pid_ ); |
| } |
| |
| |
| // An earlier ProcessInfo request returned as much data as would |
| // fit into the reply message. Caller is now continuing the request |
| // to get additional data.void CExtProcInfoContReq::performRequest() |
| void CExtProcInfoContReq::performRequest() |
| { |
| const char method_name[] = "CExtProcInfoContReq::performRequest"; |
| TRACE_ENTRY; |
| |
| #ifndef NAMESERVER_PROCESS |
| bool getMonitorInfo = false; |
| if (strcasecmp(msg_->u.request.u.process_info.target_process_name, "MONITOR") == 0) |
| { |
| getMonitorInfo = true; |
| msg_->u.request.u.process_info.target_process_name[0] = 0; |
| } |
| |
| if ( NameServerEnabled && !getMonitorInfo ) |
| { |
| int rc = NameServer->ProcessInfoCont(msg_); // in reqQueue thread (CExternalReq) |
| if (rc) |
| { |
| char la_buf[MON_STRING_BUF_SIZE]; |
| snprintf( la_buf, sizeof(la_buf) |
| , "[%s] - Process info continue request to Name Server failed\n" |
| , method_name ); |
| mon_log_write(MON_REQ_PROCINFOCONT_1, SQ_LOG_ERR, la_buf); |
| } |
| } |
| #endif |
| |
| #ifndef NAMESERVER_PROCESS |
| if ( NameServerEnabled && !getMonitorInfo ) |
| { |
| // Send reply to requester |
| lioreply(msg_, pid_); |
| } |
| else |
| { |
| #endif |
| int count = 0; |
| int nid; |
| int pid; |
| |
| // Record statistics (sonar counters) |
| if (sonar_verify_state(SONAR_ENABLED | SONAR_MONITOR_ENABLED)) |
| MonStats->req_type_processinfocont_Incr(); |
| |
| if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS)) |
| { |
| trace_printf("%s@%d request #%ld: ProcessInfoCont, context (%d, %d), " |
| "process type=%d, allnodes=%d\n", method_name, __LINE__, |
| id_, |
| msg_->u.request.u.process_info_cont.context[0].nid, |
| msg_->u.request.u.process_info_cont.context[0].pid, |
| msg_->u.request.u.process_info_cont.type, |
| msg_->u.request.u.process_info_cont.allNodes); |
| } |
| |
| msg_->u.reply.u.process_info.more_data = false; |
| |
| // Using context from the last reply, locate next process. |
| // Generally the final process in the last reply will still exist |
| // so we locate its CProcess object for continuation. If that |
| // process no longer exists we try to find other processes in the |
| // context list until we find the CProcess object or run out of |
| // context. |
| int i = -1; |
| CProcess *process = 0; |
| |
| while (!process && ++i < MAX_PROC_CONTEXT) |
| { |
| nid = msg_->u.request.u.process_info_cont.context[i].nid; |
| pid = msg_->u.request.u.process_info_cont.context[i].pid; |
| if (nid >= 0 && nid < Nodes->GetLNodesConfigMax()) |
| { |
| process = Nodes->GetLNode(nid)->GetProcessL(pid); |
| } |
| } |
| |
| |
| if (!process) |
| { // Could not locate any process in the context list. So |
| // begin with the first process in the node. |
| nid = msg_->u.request.u.process_info_cont.context[0].nid; |
| if (trace_settings & TRACE_REQUEST) |
| trace_printf("%s@%d" " could not find context process, restarting for node=" "%d" "\n", method_name, __LINE__, nid); |
| if (nid >= 0 && nid < Nodes->GetLNodesConfigMax()) |
| { |
| process = ProcessInfo_GetProcess (nid, msg_->u.request.u.process_info_cont.allNodes); |
| } |
| } |
| |
| // Assuming we found a CProcess object resume returning data with |
| // the subsequent process. |
| if (process) |
| { |
| process = process->GetNextL(); |
| if (!process) |
| { // We were at the last process on the node. Get first process |
| // on the next node (if there is a next node). |
| if (++nid < Nodes->GetLNodesConfigMax()) |
| { |
| process = ProcessInfo_GetProcess(nid, |
| msg_->u.request.u.process_info_cont.allNodes); |
| } |
| } |
| |
| if (process) |
| { |
| count = ProcessInfo_BuildReply( |
| process, |
| msg_, |
| msg_->u.request.u.process_info_cont.type, |
| msg_->u.request.u.process_info_cont.allNodes, |
| (char *) ""); |
| |
| } |
| } |
| |
| msg_->u.reply.type = ReplyType_ProcessInfo; |
| msg_->u.reply.u.process_info.num_processes = count; |
| msg_->u.reply.u.process_info.return_code = MPI_SUCCESS; |
| |
| #ifdef NAMESERVER_PROCESS |
| monreply(msg_, sockFd_); |
| #else |
| // Send reply to requester |
| lioreply(msg_, pid_); |
| #endif |
| #ifndef NAMESERVER_PROCESS |
| } |
| #endif |
| |
| TRACE_EXIT; |
| } |