bool LookupIntentMsgEx::processIncoming(struct sockaddr_in* fromAddr, Socket* sock, char* respBuf, size_t bufLen, HighResolutionStats* stats) { #ifdef BEEGFS_DEBUG const char* msgInContext = "LookupIntentMsg incoming"; std::string peer = fromAddr ? Socket::ipaddrToStr(&fromAddr->sin_addr) : sock->getPeername(); LOG_DEBUG(msgInContext, 4, std::string("Received a LookupIntentMsg from: ") + peer); #endif App* app = Program::getApp(); std::string parentEntryID = getParentInfo()->getEntryID(); FhgfsOpsErr lookupRes = FhgfsOpsErr_INTERNAL; FhgfsOpsErr createRes = FhgfsOpsErr_INTERNAL; std::string entryName = getEntryName(); const char* logContext = "LookupIntentMsg"; LOG_DEBUG(logContext, 5, "parentID: '" + parentEntryID + "' " + "entryName: '" + entryName + "'"); // (note: following objects must be at the top-level stack frame for response serialization) std::string fileHandleID; Raid0Pattern dummyPattern(1, UInt16Vector() ); EntryInfo diskEntryInfo; int createFlag = getIntentFlags() & LOOKUPINTENTMSG_FLAG_CREATE; FileInodeStoreData inodeData; bool inodeDataOutdated = false; // true if the file/inode is currently open (referenced) LookupIntentRespMsg respMsg(FhgfsOpsErr_INTERNAL); PathInfo pathInfo; /* Added to NetMessage as ref-pointer, so object needs to exist until * the NetMessage got serialized! */ // sanity checks if (unlikely (parentEntryID.empty() || entryName.empty() ) ) { LogContext(logContext).log(3, "Sanity check failed: parentEntryID: '" + parentEntryID + "'" + "entryName: '" + entryName + "'"); // something entirely wrong, fail immediately, error already set above goto send_response; } /* Note: Actually we should first do a lookup. However, a successful create also implies a failed Lookup, so we can take a shortcut. */ // lookup-create if (createFlag) { LOG_DEBUG(logContext, Log_SPAM, "Lookup: create"); // checks in create() if lookup already found the entry createRes = create(this->getParentInfo(), entryName, &diskEntryInfo, &inodeData); FhgfsOpsErr sendCreateRes; if (createRes == FhgfsOpsErr_SUCCESS) { sendCreateRes = FhgfsOpsErr_SUCCESS; // Successful Create, which implies Lookup-before-create would have been failed. respMsg.setLookupResult(FhgfsOpsErr_PATHNOTEXISTS); respMsg.setEntryInfo(&diskEntryInfo); } else { if (createRes == FhgfsOpsErr_EXISTS) { // NOTE: we need to do a Lookup to get required lookup data if (getIntentFlags() & LOOKUPINTENTMSG_FLAG_CREATEEXCLUSIVE) sendCreateRes = FhgfsOpsErr_EXISTS; else sendCreateRes = FhgfsOpsErr_SUCCESS; } else sendCreateRes = FhgfsOpsErr_INTERNAL; } respMsg.addResponseCreate(sendCreateRes); // note: don't quit here on error because caller might still have requested stat info } // lookup if ((!createFlag) || (createRes == FhgfsOpsErr_EXISTS) ) { LOG_DEBUG(logContext, Log_SPAM, "Lookup: lookup"); lookupRes = lookup(parentEntryID, entryName, &diskEntryInfo, &inodeData, inodeDataOutdated); respMsg.setLookupResult(lookupRes); if (lookupRes == FhgfsOpsErr_SUCCESS) respMsg.setEntryInfo(&diskEntryInfo); if(unlikely( (lookupRes != FhgfsOpsErr_SUCCESS) && createFlag) ) { // so createFlag is set, so createRes is either Success or Exists, but now lookup fails // create/unlink race? // we need to set something here, as sendCreateRes = FhgfsOpsErr_SUCCESS respMsg.setEntryInfo(&diskEntryInfo); StatData statData; statData.setAllFake(); // set arbitrary stat values (receiver won't use the values) respMsg.addResponseStat(lookupRes, &statData); goto send_response; } } // lookup-revalidate if(getIntentFlags() & LOOKUPINTENTMSG_FLAG_REVALIDATE) { LOG_DEBUG(logContext, Log_SPAM, "Lookup: revalidate"); FhgfsOpsErr revalidateRes = revalidate(&diskEntryInfo); respMsg.addResponseRevalidate(revalidateRes); if(revalidateRes != FhgfsOpsErr_SUCCESS) goto send_response; } /* lookup-stat note: we do stat before open to avoid the dyn attribs refresh if the file is not opened by someone else currently. */ if ( (getIntentFlags() & LOOKUPINTENTMSG_FLAG_STAT) && (lookupRes == FhgfsOpsErr_SUCCESS || createRes == FhgfsOpsErr_SUCCESS) ) { LOG_DEBUG(logContext, Log_SPAM, "Lookup: stat"); // check if lookup and create failed (we don't have an entryID to stat then) if(diskEntryInfo.getEntryID().empty() ) goto send_response; if ( (diskEntryInfo.getFlags() & ENTRYINFO_FEATURE_INLINED) && !inodeDataOutdated) { // stat-data from the dentry StatData* dentryStatData = inodeData.getInodeStatData(); respMsg.addResponseStat(FhgfsOpsErr_SUCCESS, dentryStatData); } else { // read stat data separately StatData statData; FhgfsOpsErr statRes = stat(&diskEntryInfo, true, statData); respMsg.addResponseStat(statRes, &statData); if(statRes != FhgfsOpsErr_SUCCESS) goto send_response; } } // lookup-open if(getIntentFlags() & LOOKUPINTENTMSG_FLAG_OPEN) { LOG_DEBUG(logContext, Log_SPAM, "Lookup: open"); // don't open if create failed if ((createRes != FhgfsOpsErr_SUCCESS) && (getIntentFlags() & LOOKUPINTENTMSG_FLAG_CREATE) ) goto send_response; if (!DirEntryType_ISREGULARFILE(diskEntryInfo.getEntryType() ) ) goto send_response; // not a regular file, we don't open that // check if lookup and/or create failed (we don't have an entryID to open then) if(diskEntryInfo.getEntryID().empty() ) goto send_response; StripePattern* pattern = NULL; FhgfsOpsErr openRes = open(&diskEntryInfo, &fileHandleID, &pattern, &pathInfo); if(openRes != FhgfsOpsErr_SUCCESS) { // open failed => use dummy pattern for response respMsg.addResponseOpen(openRes, fileHandleID, &dummyPattern, &pathInfo); goto send_response; } respMsg.addResponseOpen(openRes, fileHandleID, pattern, &pathInfo); } send_response: respMsg.serialize(respBuf, bufLen); sock->sendto(respBuf, respMsg.getMsgLength(), 0, (struct sockaddr*)fromAddr, sizeof(struct sockaddr_in) ); app->getNodeOpStats()->updateNodeOp(sock->getPeerIP(), this->getOpCounterType(), getMsgHeaderUserID() ); return true; }
void* BackendThreadMain( void* arg ) { info_t* rinfo = (info_t*)arg; int32_t recv_int=0; int tag; Packet_t* p; Stream_t* stream; Network_t * net = NULL; const char* fmt_str = "%d"; char parHostname[64], parPort[10], parRank[10], myRank[10]; Rank mRank = rinfo->mrnet_rank; sprintf(myRank, "%d", mRank); if( getParentInfo(connfile, rinfo->mpi_rank, parHostname, parPort, parRank) != 0 ) { fprintf(stderr, "Failed to parse connections file\n"); return NULL; } assert( rinfo->argc == 6 ); fprintf( stdout, "BE[%d] on %s connecting to %s:%s[%s]\n", mRank, rinfo->argv[4], parHostname, parPort, parRank ); rinfo->argv[1] = parHostname; rinfo->argv[2] = parPort; rinfo->argv[3] = parRank; rinfo->argv[5] = myRank; net = Network_CreateNetworkBE( rinfo->argc, rinfo->argv ); p = (Packet_t*) calloc( (size_t)1, sizeof(Packet_t) ); do { if( Network_recv(net, &tag, p, &stream) != 1 ) { printf("net->recv() failure\n"); tag = PROT_EXIT; } switch( tag ) { case PROT_INT: if( Packet_unpack( p, fmt_str, &recv_int) == -1 ) { printf("Packet_unpack() failure\n"); return NULL; } fprintf(stdout, "BE[%d]: received int = %d\n", mRank, recv_int); if( (Stream_send(stream, PROT_INT, fmt_str, recv_int) == -1) || (Stream_flush(stream) == -1 ) ) { printf("Stream_send() failure\n"); return NULL; } break; case PROT_EXIT: fprintf(stdout, "BE[%d]: received PROT_EXIT\n", mRank); break; default: fprintf(stdout, "BE[%d]: Unknown Protocol %d\n", mRank, tag); tag = PROT_EXIT; break; } fflush(stdout); fflush(stderr); } while ( tag != PROT_EXIT ); // FE delete of the network will cause us to exit, wait for it Network_waitfor_ShutDown(net); delete_Network_t(net); return NULL; }