Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}