コード例 #1
0
  /// \brief Delete a name and possibly the file that it refers to
  int
  STFSLIB_unlink (const char *pp_Path)
  {
    const char     *WHERE = "STFSLIB_unlink";
    STFS_ScopeTrace lv_st(WHERE);
    int             lv_Ret = 0;


    //Check that the pathname passed is not longer than our MAX
    ASSERT(strlen(pp_Path) <= STFS_PATH_MAX);

    STFS_ExternalFileMetadata *lp_Efm = STFS_ExternalFileMetadata::GetFromContainer((char *) pp_Path);

    if (lp_Efm) {
      lp_Efm->Unlink();
      if (lv_Ret < 0) {
	return -1;
      }
    }

#ifdef SQ_PACK
    lv_Ret = SendToSTFSd_unlink((char *) pp_Path,
				STFS_util::GetMyNodeId(),
				STFS_util::GetMyPID());
#else
    lv_Ret = STFSd_unlink((char *) pp_Path);
#endif

    return lv_Ret;
  }
コード例 #2
0
  bool 
  LibRead_GetMoreFragments (STFS_ExternalFileHandle *pp_Efh) {
    const char       *WHERE = "LibRead_GetMoreFragments ";
    STFS_ScopeTrace   lv_st(WHERE,2);

    /////////////////////////////
    ///    Check Parameters
    ////////////////////////////
    if (pp_Efh == NULL) {
      ASSERT (false);
      return false;
    }

    //Will the order of the ffh's match in the vector between daemon and lib?
    //How can we tell which one to put... Can add logic to compare
    
    //int lv_Ret = 0;
    //For now just work on grabbing the efm from the daemon

    /////////////////////////////
    /// Setup and Housekeeping
    /////////////////////////////
    bool lv_newFragmentsFound = false;

    /////////////////////////////
    /// Finis!
    /////////////////////////////

    return lv_newFragmentsFound;
  }
コード例 #3
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_read
///
/// \brief  Reads from an STFS file
///
///////////////////////////////////////////////////////////////////////////////
ssize_t
STFSd_read(STFS_OpenIdentifier *pp_OpenId,
           void                *pp_Buf,
           size_t               pv_Count)
{
  const char     *WHERE = "STFSd_read";
  STFS_ScopeTrace lv_st(WHERE);
  STFS_Session *lp_Session = STFS_Session::GetSession();

  if(!lp_Session) {
    return -1;
  }

  if(!pp_OpenId || !pp_Buf) {
    //Invalid argument errno
    return -1;
  }

  if (pv_Count > (size_t)STFS_SSIZE_MAX) {
    return -1;
  }

  //If count is > buffer size then what? Handle this at the send.cpp level

  //Lookup Open file,  Need to have added check to see if node matches
  STFS_ExternalFileOpenerContainer *lp_EfoContainer = STFS_ExternalFileOpenerContainer::GetInstance();
  if (!lp_EfoContainer) {
    TRACE_PRINTF2(1,"%s\n", "Null EFO Container");
    return -1;
  }

  STFS_ExternalFileOpenerInfo *lp_Efoi = lp_EfoContainer->Get(pp_OpenId);
  if (!lp_Efoi) {
    TRACE_PRINTF3(1,
                  "Open Id: %d,%ld not found in the EFO Container\n",
                  pp_OpenId->sqOwningDaemonNodeId,
                  pp_OpenId->openIdentifier
                  );
    return -1;
  }
  STFS_ExternalFileMetadata *lp_Efm = lp_Efoi->efm_;
  if (!lp_Efm) {
    TRACE_PRINTF1(1,"Null EFM Found in the lp_Efoi Entry\n");
    return -1;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);
  

  //Check to see if the file is local

  //If not local then Don't do anything. Return 0.

  //Do Read


  return 0;
}
コード例 #4
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_close
///
/// \brief  Processes a file close request given the open identifier
///
/// \param  STFS_OpenIdentifier *pp_OpenId
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_close(STFS_OpenIdentifier *pp_OpenId)
{
  const char     *WHERE = "STFSd_close";
  STFS_ScopeTrace lv_st(WHERE);

  if (!pp_OpenId) {
    return -1;
  }

  STFS_ExternalFileOpenerContainer *lp_EfoContainer = STFS_ExternalFileOpenerContainer::GetInstance();
  if (!lp_EfoContainer) {
    TRACE_PRINTF2(1,"%s\n", "Null EFO Container");
    return -1;
  }

  STFS_ExternalFileOpenerInfo *lp_Efoi = lp_EfoContainer->Get(pp_OpenId);
  if (!lp_Efoi) {
    TRACE_PRINTF3(1,
                  "Open Id: %d,%ld not found in the EFO Container\n",
                  pp_OpenId->sqOwningDaemonNodeId,
                  pp_OpenId->openIdentifier
                  );
    return -1;
  }
  STFS_ExternalFileMetadata *lp_Efm = lp_Efoi->efm_;
  if (!lp_Efm) {
    TRACE_PRINTF1(1,"Null EFM Found in the Efoi Entry\n");
    return -1;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);
  
  int lv_Ret = lp_Efm->Close(true);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  lv_Ret = lp_EfoContainer->Delete(pp_OpenId);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  TraceOpeners(lp_EfoContainer,
               lp_Efm);

  lv_Ret = STFS_ExternalFileMetadata::DeleteFromContainer(lp_Efm);
  if (lv_Ret < 0) {
    return lv_Ret;
  }

  return lv_Ret;
}
コード例 #5
0
  ///////////////////////////////////////////////////////////////////////////////
  ///
  //          STSFSLIB_error()
  ///
  ///  \brief The actual implementation of an STFS_write
  ///
  ///  This method is the driver for an STFS_write() function call.
  ///  it also implements the protocol for determining whether or not
  ///  to create a new fragment.  Only STFSLIB can make this call, not
  ///  STFS-d, so the logic is put here.  We could put a lot of "if
  ///  !ExecutingInDaemon" escape clauses, but there's no need to put
  ///  those in the mainline remote write path.  
  ///  
  ///
  /// \param  pv_Offset  byte offset count based on whence
  /// \param  pv_Whence  values are as follow: \n
  ///                         SEEK_SET - The offset is set to offset bytes. \n
  ///                         SEEK_CUR - The offset is set to its current
  ///                                    location plus offset bytes. \n
  ///                         SEEK_END - The offset is set to the size of the 
  ///                                    file plus offset bytes. 
  /// 
  /// \retval off_t SUCCESS: The resulting offset location from beginning
  ///                        of current fragment file.\n
  ///               FAILURE: -1 
  ///
  ///////////////////////////////////////////////////////////////////////////////
  int
  STFSLIB_error ( stfs_fhndl_t     pv_Fhandle,
		  int             *pp_error,
		  int             *pp_addlError, 
		  char            *pp_context,
		  size_t           pv_contextMaxLen, 
		  size_t          *pp_contextLen )  {

    const char     *WHERE = "STFSLIB_error";
    STFS_ScopeTrace lv_st(WHERE);

    //////////////////////////////////
    /// Validate parameters
    //////////////////////////////////

    if (pv_Fhandle == 0 || 
	pv_Fhandle == -1 ) {
      // Can't rollerskate without wheels, can't get the error without a handle...
      return -1;
    }

    if (pv_contextMaxLen > 0 && pp_context == NULL) {
      // said the buffer had a non-zero length, but didn't pass it
      return -1;
    }

    if (pp_context != NULL && pp_contextLen == NULL) {
      // we need to tell you how long the buffer is...
      return -1;
    }

    //////////////////////////////////
    /// Get efh
    //////////////////////////////////

    STFS_ExternalFileHandle *lp_Efh
                     = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);

    //////////////////////////////////
    /// Extract error from efh
    //////////////////////////////////
    bool lv_RetBool = lp_Efh->GetError ( pp_error,
					 pp_addlError,
					 pp_context,
					 pv_contextMaxLen,
					 pp_contextLen);

    if (lv_RetBool == false) {
      // no more errors found
      return -1;
    }

    return 0;
  }
コード例 #6
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_stat
///
/// \brief  Processes a stat request
///
/// \param  stfs_nodeid_t            pv_Nid
/// \param  char                    *pp_Path
/// \param  Stfs_StatSet            *pp_StatSet
/// \param  stfs_statmask_t          pv_Mask
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_stat (stfs_nodeid_t            pv_Nid,
            char                    *pp_Path,
            struct STFS_StatSet     *pp_StatSet,
            stfs_statmask_t          pv_Mask)
{
  const char       *WHERE = "STFSd_stat";
  STFS_ScopeTrace   lv_st(WHERE,2);

  int lv_Count = 0;
  int lv_OpenRet = 0;
  long *lp_PrevIndex = new long(0);

  while((lv_Count < STFS_MAX_OPENERS) && (lv_OpenRet == 0)) {

    strcpy(pp_StatSet->Path[*lp_PrevIndex], pp_Path);

    lv_OpenRet = STFS_util::STFS_stat(pv_Nid,
                                      pp_StatSet->Path[*lp_PrevIndex],
                                      lp_PrevIndex,
                                      pv_Mask,
                                     &pp_StatSet->Stat[*lp_PrevIndex]);
    
    if(lv_OpenRet < 0) {
      //TODO: Error Checking
      return -1;
    }
    if(lv_OpenRet != 1) {
      lv_Count++;
    }
  }

  TRACE_PRINTF2(4,"Number of files found by STFS_stat: %d\n", lv_Count);
  pp_StatSet->Count = lv_Count;

  return 0;
}
コード例 #7
0
ssize_t
STFSLIB_lseek( stfs_fhndl_t  pv_Fhandle,
               off_t         pv_Offset,
               int           pv_Whence)
{
    const char     *WHERE = "STFSLIB_lseek";
    STFS_ScopeTrace lv_st(WHERE);

    STFS_ExternalFileHandle *lp_Efh = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);
    if (! lp_Efh) {
        TRACE_PRINTF2(1, "Error in obtaining External File Handle for %ld\n", pv_Fhandle);
        return -1;
    }

    lp_Efh->ResetErrors();

    ssize_t lv_Stat = lp_Efh->Lseek(pv_Offset,
                                    pv_Whence);
    if (lv_Stat < 0) {
        return -1;
    }

    return lv_Stat;
}
コード例 #8
0
  ///////////////////////////////////////////////////////////////////////////////
  ///
  //          STSFSLIB_write()
  ///
  ///  \brief The actual implementation of an STFS_write
  ///
  ///  This method is the driver for an STFS_write() function call.
  ///  it also implements the protocol for determining whether or not
  ///  to create a new fragment.  Only STFSLIB can make this call, not
  ///  STFS-d, so the logic is put here.  We could put a lot of "if
  ///  !ExecutingInDaemon" escape clauses, but there's no need to put
  ///  those in the mainline remote write path.  
  ///  
  ///
  /// \param  pv_Offset  byte offset count based on whence
  /// \param  pv_Whence  values are as follow: \n
  ///                         SEEK_SET - The offset is set to offset bytes. \n
  ///                         SEEK_CUR - The offset is set to its current
  ///                                    location plus offset bytes. \n
  ///                         SEEK_END - The offset is set to the size of the 
  ///                                    file plus offset bytes. 
  /// 
  /// \retval off_t SUCCESS: The resulting offset location from beginning
  ///                        of current fragment file.\n
  ///               FAILURE: -1 
  ///
  ///////////////////////////////////////////////////////////////////////////////
  ssize_t 
  STFSLIB_write( stfs_fhndl_t  pv_Fhandle,
		 const void   *pp_Buf,
		 size_t        pv_Count)
  {
    const char     *WHERE = "STFSLIB_write";
    STFS_ScopeTrace lv_st(WHERE);

    if (!pp_Buf) {
      errno = EINVAL;
      return -1;
    }

    STFS_ExternalFileHandle *lp_Efh
                     = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);
    if (! lp_Efh) {
      TRACE_PRINTF2(1, "Error in obtaining External File Handle for %ld\n", pv_Fhandle);
      return -1;
    }

    lp_Efh->ResetErrors();

    bool lv_WriteCompleted = false;
    ssize_t lv_totalCountWritten = 0;

    void *lp_currBuffPtr = (void *) pp_Buf;
    ssize_t lv_writeSize = pv_Count;

    while (!lv_WriteCompleted)
      {
	lp_Efh->SetCurrentFragmentBasedOnCurrOffset();
	      
	ssize_t lv_Stat = lp_Efh->Write( lp_currBuffPtr,
					 lv_writeSize);

	if (lv_Stat == lv_writeSize) {
	  // The usual case: we wrote everything as expected.  Prepare
	  // to exit the loop and go home for the day!

	  lv_totalCountWritten += lv_writeSize;
	  lv_WriteCompleted = true;

	}

	else if (lv_Stat < 0) {
	  // Hmm, do we need to create a new fragment?
	  
	  if (errno == ENOSPC) {
	    //gotcha!  Create a new fragment and continue writing the
	    //buffer

	    STFS_ExternalFileMetadata *lp_EFM = lp_Efh->EfmGet();

	    // make sure that the lib has the same opinion as the
	    // daemon on the new fragment's offset 

	    size_t lv_newFragExpectedOffset = lp_Efh->CurrentOffsetGet();

#ifdef SQ_PACK

	    STFS_OpenIdentifier lp_openIdentifier = lp_Efh->OpenIdentifierGet();

	    lv_Stat = SendToSTFSd_createFrag(lp_EFM,
					     STFS_util::GetMyNodeId(),
					     STFS_util::GetMyPID(),
					     &lp_openIdentifier);
#else
	    lv_Stat = STFSd_createFragment(lp_EFM,
					  STFS_util::GetMyNodeId(),
					  STFS_util::GetMyPID(),
					  lp_Efh->CurrentOffsetGet());
#endif

	    if (lv_Stat < 0) {
	      // Fragment not created.  Treat it like a normal ENOSPC
	      // error after all.  If the error on the createFrag was
	      // something else, then we'll hope that it was put in
	      // the open error structure...

	      errno = ENOSPC; 
	    }
	    else {
	      // open the new fragment

	      lv_Stat = lp_Efh->OpenNewFragments();

	      if (lv_Stat < 0) {
		errno=ENOSPC;
	      }

	      // Now check to see if the new fragment has the correct
	      // starting offset.  The new fragment isn't yet the
	      // current one, so we have to extract the current number
	      // of fragments, use it as the index to get the last
	      // fragment's FFM, and call OffsetGet on that fragment.

	      size_t lv_newFragRealStartOffset =  lp_Efh->GetLastFFMStartOffset();

	      if (lv_newFragRealStartOffset != lv_newFragExpectedOffset) {
		
		// Something's wrong because the daemon has a
		// different opinion on the previous fragment's
		// size or our calculations are out of sync. This
		// is a data integrity problem

		//  This code should really be fixed to change the
		//  if condition to be a Permassert or the
		//  following Assert (false) to kill the library
		//  process.

		STFS_util::SoftwareFailureHandler (WHERE);
	      }
	    }
	  }

	  if (lv_Stat < 0) {

	    // we've got a real, live error here!
	    // before we just return this error, check to see if we've
	    // written anything!  If so, we want to return that
	    // value.  It's up to the library caller to decide whether
	    // to retry the I/O in that case.

	    if (lv_totalCountWritten >  0) {

	      return lv_totalCountWritten;

	    }
	    else {

	      // a real error! Make sure errno wasn't overwritten by
	      // this point! Any additional information or subsequent
	      // errors should be stuffed in the error structure by
	      // lower calls.

	      return -1;

	    }

	  }  // Not ENOSPC check

	}  // lv_Stat < 0 check

	else  {

          //Rev. Following line is comparing signed vs unsigned. 
	  ASSERT ((size_t)(lv_totalCountWritten+lv_Stat) < pv_Count);

	  // partial write!  Hmmmmm, might mean we need a new fragment
	  // (or it might mean there was partial write).  We need to
	  // save the number of bytes we wrote and then try again to
	  // write the data.  We also have to save our current
	  // location in the buffer and calculate the new number of
	  // bytes to write.

	  // Careful here:  it's possible that a single large write
	  // might create more than one fragment! Make sure that
	  // whatever code gets added uses lv_CountWritten and lv_Stat
	  // with the proper context.

	  lv_totalCountWritten += lv_Stat;
	  lp_currBuffPtr = (char *)lp_currBuffPtr + lv_Stat;
	  lv_writeSize -= lv_Stat;

	}
      } // While !lv_WriteCompleted

    return lv_totalCountWritten;
  }
コード例 #9
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_open
///
/// \brief  Opens an existing STFS file
///
/// \param const char                *pp_Path, 
/// \param int                        pv_OFlag, 
/// \param                            pv_OpenerNodeId,
/// \param                            pv_OpenerPID,
/// \param STFS_ExternalFileMetadata *&pp_Efm,
/// \param STFS_FragmentFileMetadata *&pp_Ffm,
/// \param STFS_OpenIdentifier       *&pp_OpenId)
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_open(const char                 *pp_Path, 
           int                         pv_OFlag, 
           int                         pv_OpenerNodeId,
           int                         pv_OpenerPID,
           STFS_ExternalFileMetadata *&pp_Efm,
           STFS_FragmentFileMetadata *&pp_Ffm,
           STFS_OpenIdentifier       *&pp_OpenId)
{
  const char     *WHERE = "STFSd_open";
  STFS_ScopeTrace lv_st(WHERE);
  STFS_Session *lp_Session = STFS_Session::GetSession();

  int  lv_Ret = 0;

  if (!pp_Path) {
    errno = EINVAL;
    char lp_ErrMess[] = "Error Path is NULL";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -1;
  }

  char lp_Path[STFS_PATH_MAX];
  strcpy(lp_Path, pp_Path);
  STFS_ExternalFileMetadata *lp_Efm = STFS_ExternalFileMetadata::GetFromContainer(lp_Path);
  if(!lp_Efm) {
    TRACE_PRINTF2(1,"%s\n", "Error getting lp_Efm");

    errno = EINVAL;
    char lp_ErrMess[] = "Error getting lp_Efm";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -2;
  }
  
  TRACE_PRINTF4(2,
                "FileName: %s, Opener Node Id: %d, Opener SQ PID: %d\n",
                lp_Efm->ExternalFileNameGet(),
                pv_OpenerNodeId,
                pv_OpenerPID);

  STFS_util::ValidateEFM(lp_Efm);

  if(!lp_Efm->FileAvailableGet()) {
    TRACE_PRINTF2(1, "File: %s is no longer available\n", pp_Path);
    errno = ENOENT;
    char lp_ErrMess[] = "Error file is no longer available";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -1;
  }

  int lv_FragmentOffset = 0;
  //If O_APPEND, last fragment will be set open,
  if((pv_OFlag & O_APPEND) == O_APPEND) {
    lv_FragmentOffset = lp_Efm->GetNumFragments();
    if(lv_FragmentOffset == 0) {
      TRACE_PRINTF2(1,"%s\n", "Error Number of Fragments returned is 0");
      errno = ENOENT;
      char lp_ErrMess[] = "Error number of fragments returned is 0";
      lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
      return -3;
    }
    lv_FragmentOffset -= 1;
  }

  STFS_FragmentFileMetadata *lp_Ffm = lp_Efm->GetFragment(lv_FragmentOffset);
  if(!lp_Ffm) {
    errno = ENOENT;
    char lp_ErrMess[] = "Error obtaining fragment";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -4;
  }

  STFS_ExternalFileHandle *lp_Efh = lp_Efm->Open(true);
  if (!lp_Efh) {
    // TBD cleanup
    errno = ENOENT;
    char lp_ErrMess[] = "Error allocating EFH";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -5;
  }

  lv_Ret = StoreOpenerInfo(lp_Efm,
                           pv_OpenerNodeId,
                           pv_OpenerPID,
                           pp_OpenId);
  if (lv_Ret < 0) {
    //TBD cleanup
    errno = ENOENT;
    char lp_ErrMess[] = "Error storing opener information";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -6;
  }

  pp_Efm = lp_Efm;
  pp_Ffm = lp_Ffm;
  
  //Build Success Reply
  return 0;
}
コード例 #10
0
  int
  STFSLIB_close(stfs_fhndl_t pv_Fhandle)
  {
    const char     *WHERE = "STFSLIB_close";
    STFS_ScopeTrace lv_st(WHERE);

    STFS_ExternalFileHandle *lp_Efh = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);
    if (! lp_Efh) {
      errno = EBADF;
      TRACE_PRINTF2(1, "Error in obtaining External File Handle for %ld\n", pv_Fhandle);
      return -1;
    }
    
    lp_Efh->ResetErrors();

    /// Rev: Do we close . Set the state. Continue on errors. 

    // Closes the fragments
    int lv_Ret = lp_Efh->Close();
    if (lv_Ret < 0) {
      TRACE_PRINTF3(1, "Error %d while closing handle: %ld\n",
		   lv_Ret,
		   pv_Fhandle);
      // continue on error when closing
    }

    STFS_ExternalFileMetadata *lp_Efm = lp_Efh->EfmGet();
    if (!lp_Efm) {
      // corruption in some STFS maintained data structures. 
      STFS_util::SoftwareFailureHandler(WHERE);
      return -1;
    }

    lv_Ret = lp_Efm->Close(false);
    if (lv_Ret < 0) {
      TRACE_PRINTF3(1,"Error %d while closing handle: %ld\n",
		   lv_Ret,
		   pv_Fhandle);
      return -1;
    }

    lv_Ret = STFS_ExternalFileMetadata::DeleteFromContainer(lp_Efm);
    if (lv_Ret < 0) {
      STFS_util::SoftwareFailureHandler(WHERE);
      return lv_Ret;
    }

    // send message to the STFS daemon
#ifdef SQ_PACK
    lv_Ret = SendToSTFSd_close(&(lp_Efh->OpenIdentifierGet()),
                               STFS_util::GetMyNodeId(),
                               STFS_util::GetMyPID());
    if (lv_Ret < 0) {
      // 'errno' should be set here
      return lv_Ret;
    }
#else
    lv_Ret = STFSd_close(&(lp_Efh->OpenIdentifierGet()));
    if (lv_Ret < 0) {
      return lv_Ret;
    }
#endif

    // remove Efh from the Container
    lv_Ret = STFS_ExternalFileHandle::DeleteFromContainer(lp_Efh);
    if (lv_Ret < 0) {
      STFS_util::SoftwareFailureHandler(WHERE);
      return lv_Ret;
    }

    return 0;
  }
コード例 #11
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_createFragment
///
/// \brief  Creates a file fragment
///         - Figures out the node of the file fragment 
///            (Currently it is the current node. TBD - check for the node)
///         - Creates a directory
///         - Creates a file in the created directory 
///         - opens the file (controlling open)
///
/// \param STFS_ExternalFileMetadata  *pp_Efm
/// \param int                         pv_OpenerNodeId,
/// \param int                         pv_OpenerPID,
/// \param long                        pv_FragmentFileOffset
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_createFragment(STFS_ExternalFileMetadata  *pp_Efm,
                     int                         pv_OpenerNodeId,
                     int                         pv_OpenerPID,
                     long                        pv_FragmentFileOffset)
{
  const char     *WHERE = "STFSd_createFragment";
  STFS_ScopeTrace lv_st(WHERE);

  /// housekeeping
  int lv_Ret = 0;

  if (!pp_Efm) {
    return -1;
  }

  TRACE_PRINTF5(2,
                "FileName: %s, Opener NodeId: %d, Opener SQ PID: %d, FragmentFileOffset: %ld\n",
                pp_Efm->ExternalFileNameGet(),
                pv_OpenerNodeId,
                pv_OpenerPID,
                pv_FragmentFileOffset);

  /// loop over all possible storage locations
  bool lv_moreStorageLocations = false;
  bool lv_fragmentCreated = false;

  while ((lv_moreStorageLocations != true) && (lv_fragmentCreated == false) ) {


    /// pick a storage location if one is available

    char lp_StorageLocationDir[STFS_PATH_MAX];
    bool lv_stgIsLocal = false;

    lv_Ret = STFS_fragment::GetStorageLocation (lp_StorageLocationDir,
                                                &lv_stgIsLocal);

    if (lv_Ret < 0) {
      lv_moreStorageLocations = false;         
    }

    else {

      if (lv_stgIsLocal == true){

        /// Local storage location:  Create the fragment!

        char lv_DirName[STFS_DIRNAME_MAX+1];

        bool lv_MountPointExists
                    = STFS_util::GetMountPointName(lv_DirName, 
                                                lp_StorageLocationDir); 
        ASSERT (lv_MountPointExists == true);


        /// Set up the filename
        char fragmentFilename[STFS_DIRNAME_MAX+STFS_NAME_MAX];
        STFS_fs *lp_Fs = new STFS_ext2();
        if (!lp_Fs) {
          TRACE_PRINTF1(1, "Unable to construct STFS_ext2\n");
          return -1;
        }

        size_t lv_NumFragments = pp_Efm->GetNumFragments();
        sprintf(fragmentFilename, "%s%s/f%d_", 
                lv_DirName, 
                pp_Efm->ExternalFileNameGet(),
                (short) lv_NumFragments);


        ///  Issue the mkstemp

        long lv_fsErr = lp_Fs->mkstemp(fragmentFilename);
        if (lv_fsErr < 0) {
          TRACE_PRINTF1 (1, "createFragment:FS_mkstemp is unable to create a tempfile\n");
          return lv_fsErr;
        }

        ///  Init/link the FFM  
        lv_fsErr = STFS_fragment::InitFrag (pp_Efm,
                                            lp_Fs->FilenameGet(),
                                            lp_StorageLocationDir,
                                            pv_FragmentFileOffset);
        if (lv_fsErr<0) {
          //TBD cleanup
          return -1;
        }


        /// Get the EFH for the controlling open  

        // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
        //
        // This code doesn't work for remote fragments, remote accessors of
        // local fragments, or local accessors of remote files with remote
        // fragments!  They'll need their own EFHs and this doesn't link this
        // fragment to them.  Further, the check to determin whether we're
        // creating the controlling open doesn't work if there are multiple
        // fragments but this is the first fragment on this node.
        //
        // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING



        // Get the efh for the controlling open
        STFS_ExternalFileHandle *lp_Efh = NULL;
        if ( (pp_Efm->GetNumFragments()) == 1) {
          // create the controlling open

          lp_Efh= pp_Efm->Open(true);
        }
        else {
          // get the controling open from the efm

          lp_Efh = pp_Efm->EFHGet();
        }

        if (!lp_Efh) {
          // TBD cleanup
          return -1;
        }

        /// Logically open the fragment

        lv_fsErr = STFS_fragment::Open (lp_Efh, (pp_Efm->GetNumFragments()-1), lp_Fs);

        if (lv_fsErr<0) {
          //TBD cleanup
          return -1;
        }

        lv_fragmentCreated = true;

      } // if local fragment
      else {

        /// remote fragment:  Send the request to the remote daemon
        // TBD!
        ASSERT (false);
        return -1;
      }
    }
  } // while more possible places to create frag and frag not created
  
  return lv_Ret;
}
コード例 #12
0
///////////////////////////////////////////////////////////////////////////////
///
//          STFSd_mkstemp
///
/// \brief  Processes an mkstemp request
///         - Generates an external file name
///         
/// \param int                        *pp_Ctemplate,
/// \param int                         pv_OpenerNodeId,
/// \param int                         pv_OpenerPID,
/// \param STFS_ExternalFileMetadata *&pp_Efm,
/// \param STFS_OpenIdentifier       *&pp_OpenId)
///
/// 
///////////////////////////////////////////////////////////////////////////////
int
STFSd_mkstemp(char                       *pp_Ctemplate,
              int                         pv_OpenerNodeId,
              int                         pv_OpenerPID,
              STFS_ExternalFileMetadata *&pp_Efm,
              STFS_OpenIdentifier       *&pp_OpenId)
{

  /////////////////////////////////
  /// parameter checking and housekeeping
  /////////////////////////////////

  const char     *WHERE = "STFSd_mkstemp";
  STFS_ScopeTrace lv_st(WHERE);
  STFS_Session *lp_Session = STFS_Session::GetSession();

  int  lv_Ret = 0;

  if (!pp_Ctemplate) {
    errno = EFAULT;
    lp_Session->SetError(true, errno, 0, NULL, 0);
    return -1;
  }

  /// Generate the file name
  lv_Ret = STFS_util::GenerateExternalFilename(pp_Ctemplate);
  if (lv_Ret < 0) {
    errno = EINVAL;
    char lp_ErrMess[] = "Error generating external file name";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -2;
  }

  /////////////////////////////////
  /// Reserve the name
  /////////////////////////////////

  // We're the owning daemon process, so we need to reserve the name
  lv_Ret =  STFS_File::ReserveName (pp_Ctemplate);

  if (lv_Ret<0) {
    errno = EIO;

    char lp_ErrMess[] = "Error while reserving name";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    
    //name exists?  Couldn't talk to the disk?  WhatEVer...  Hope that
    //ReserveName packed the error correctly...
    return -6;

  }

  /////////////////////////////////
  /// Create the EFM for the file
  /////////////////////////////////

  STFS_ExternalFileMetadata *lp_Efm = new STFS_ExternalFileMetadata(pp_Ctemplate,
                                                                    STFS_util::GetMyNodeId());

  if (lp_Efm == NULL) {

    //Could not find/allocate EFM, probably doesn't exist
    errno = ENOENT;
    char lp_ErrMess[] = "Error allocating EFM";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));

    //UhOh, couldn't allocate an EFM!  Gotta free the directory we created
    STFS_File::ReleaseName (pp_Ctemplate); // 
    return -7;
  }

  TRACE_PRINTF4(2,
                "FileName: %s, Opener Node Id: %d, Opener SQ PID: %d\n",
                lp_Efm->ExternalFileNameGet(),
                pv_OpenerNodeId,
                pv_OpenerPID);

  /////////////////////////////////
  ///insert EFM in a global map
  /////////////////////////////////

  lv_Ret = STFS_ExternalFileMetadata::InsertIntoContainer(lp_Efm);
  if (lv_Ret < 0) {
    //TBD cleanup
    //Could not insert into EFM Container... 
    errno = ENOMEM;
    char lp_ErrMess[] = "Error Insertnig EFM into EFM Container";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -4;
  }

  /////////////////////////////////
  /// Store the opener info in the EFM
  /////////////////////////////////

  lv_Ret = StoreOpenerInfo(lp_Efm,
                           pv_OpenerNodeId,
                           pv_OpenerPID,
                           pp_OpenId);
  if (lv_Ret < 0) {
    //TBD cleanup
    //Could not store opener information
    errno = ENOMEM;
    char lp_ErrMess[] = "Error storing opener information";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -5;
  }

  /////////////////////////////////
  /// Create the fragment
  /////////////////////////////////

  if (STFSd_createFragment(lp_Efm,
                           pv_OpenerNodeId,
                           pv_OpenerPID,
                           0) < 0) {
    //Could not create fragment
    errno = EIO;
    char lp_ErrMess[] = "Error creating fragment";
    lp_Session->SetError(true, errno, 0, lp_ErrMess, strlen(lp_ErrMess));
    return -3;
  }


  STFS_util::ValidateEFM(lp_Efm);


  pp_Efm = lp_Efm;
  return 0;
}
コード例 #13
0
  // Rev: Missing doxygen hdr
  stfs_fhndl_t
  STFSLIB_mkstemp(char *pp_Ctemplate)
  {
    const char      *WHERE = "STFSLIB_mkstemp";
    STFS_ScopeTrace lv_st(WHERE);

    // Rev: Add an ASSERT for pp_Ctemplate
    if (!pp_Ctemplate) {
      return -1;
    }

    STFS_ExternalFileMetadata *lp_Efm = 0;
    STFS_FragmentFileMetadata *lp_Ffm = 0;
    STFS_OpenIdentifier       *lp_OpenId = 0;
    int lv_ret = 0;

#ifdef SQ_PACK
    lv_ret = SendToSTFSd_mkstemp(pp_Ctemplate,
				 STFS_util::GetMyNodeId(),
				 STFS_util::GetMyPID(),
				 lp_Efm,
				 lp_OpenId);
#else
    lv_ret = STFSd_mkstemp(pp_Ctemplate,
			   STFS_util::GetMyNodeId(),
			   STFS_util::GetMyPID(),
			   lp_Efm,
			   lp_OpenId);
#endif

    // lp_OpenID was NEW'd in SendToSTFSd_mkstemp.  We need to free it
    // here after we're done.  Really, we should allocate and free at
    // the same level...

    // Rev: Check for (!= 0)
    if (lv_ret < 0) {
      // Rev: Add ASSERTs to check that lp_Efm, lp_OpenId are NULL
      delete lp_OpenId;
      return lv_ret;
    }

    // Rev: Remove this and add ASSERTs for lp_Efm/lp_OpenId being not NULL
    if (!lp_Efm) {
      delete lp_OpenId;
      return -1;
    }

    if (!lp_Efm->IsEyeCatcherValid()) {
      delete lp_OpenId;
      STFS_util::SoftwareFailureHandler(WHERE);
      return -1;
    }

    // Rev: Remove this 
    STFS_util::ValidateEFM(lp_Efm);

    STFS_ExternalFileHandle *lp_Efh = lp_Efm->Open(false);
    if (!lp_Efh) {
      //TBD cleanup
      // Rev: Send a message to the STFSd to cleanup/ delete directories
      delete lp_OpenId;
      return -1;
    }
    lp_Efh->OpenFlagsSet(O_RDWR);
    lp_Efh->OpenIdentifierSet(*lp_OpenId);

    //Rev: Valgrind shows that there is a memory leak here.  However if the following 'delete'
    //       is uncommented then our tests fail with SQ_PACK=0; and SQ_STFSD=0.  Need to figure 
    //       out what is the cause of the tests failing in order to allow this memory leak fix.
    //delete lp_OpenId;

    lp_Ffm = lp_Efm->GetFragment (0);  // This is mkstemp, so there's only one fragment!
    // Rev: Check for lp_Ffm

    STFS_FragmentFileHandle *lp_Ffh = new STFS_FragmentFileHandle(lp_Ffm);
    // Rev: Check for lp_Ffh
    lp_Efh->InsertFFH(lp_Ffh);
    //Rev: Did the Insert work?

    return (stfs_fhndl_t) lp_Efh;
  }
コード例 #14
0
  //////////////////////////////////////////////////////////////////////////////
  ///
  //              STFSLIB_read
  ///
  /// \brief  Driver code for an STFS_read() library call
  ///
  //////////////////////////////////////////////////////////////////////////////
  ssize_t 
  STFSLIB_read( stfs_fhndl_t  pv_Fhandle,
                void         *pp_Buf,
                size_t        pv_Count)
  {
    const char     *WHERE = "STFSLIB_read";
    STFS_ScopeTrace lv_st(WHERE);

    if (!pp_Buf) {
      errno = EFAULT;
      return -1;
    }


    STFS_ExternalFileHandle *lp_Efh = STFS_ExternalFileHandle::GetExternalFileHandle(pv_Fhandle);
    if (! lp_Efh) {
      TRACE_PRINTF2(1, "Error in obtaining External File Handle for %ld\n", pv_Fhandle);
      return -1;
    }

    lp_Efh->ResetErrors();


    size_t lv_totalBytesRead = 0;
    bool lv_readCompleted = false;

    char * lp_currBufPtr = (char *) pp_Buf;
    size_t lv_readSize = pv_Count;

    while (!lv_readCompleted) {

      ssize_t lv_Stat = 0;
      int     lv_Ret  = 0;

      //Check if the current fragment is local.  If not, then send req to daemon
      lv_Ret =  lp_Efh->IsCurrFragmentLocal();
      if(lv_Ret < 0) {
        //error evaluating fragment
        return -1;
      }   
      else if(lv_Ret == 1) {
        lv_Stat = lp_Efh->Read((char *)lp_currBufPtr,
                                       lv_readSize);
      }
      else {
#ifdef SQ_PACK
        lv_Stat= SendToSTFSd_read();
#else
        lv_Stat = STFSd_read(&(lp_Efh->OpenIdentifierGet()),
                             (char *)lp_currBufPtr,
                             lv_readSize);
#endif
        //The currentFFH_ is not local so we will need to read 
        //  through remote daemon
      }

      if (( (size_t)lv_Stat + lv_totalBytesRead) == pv_Count) {

        // the usual case; we read everything as expected.  Prepare to exit our
        // read-loop 

        lv_totalBytesRead += lv_Stat;
        lv_readCompleted = true;

      }
      else if (lv_Stat == 0) {

        // Didn't read anything else in this fragment.  Can we roll to another?

        // Gotcha!  There might be a new fragment here!  Check to see if there
        // are any new fragments then loop around and read again.

        // If we're moving to a new FFH that's already in our list, the
        // reposition at the top of the loop should move to it automatically,
        // so we just skip ahead.
        //
        // But if this is the last FFH, we need to see if either this process
        // or the owning STFSd knows about any more fragments.  We take a lazy
        // approach to doing this, hoping that somewhere along the way,
        // someone has already retrieved this information for us:  
        //
        //   1) See if the EFM already knows about other fragments. Occurs
        //      this process owns read access to the file in another open, or
        //      another opener in this process already got an updated list of
        //      FFMs.
        //
        //   2) If the number of FFHs matches the number of FFMs and we're in
        //      the last FFM, check with the owning daemon to update the
        //      metadata for this file.


        if (lp_Efh->CurrentFFHIsLast() == true) {

          if (lp_Efh->NewFFHsNeeded() == true) {

            // Someone else found fragments for us.  Logically open them for
            // this efh and try the read again.

            lv_Stat = lp_Efh ->OpenNewFragments();
            if (lv_Stat < 0) {
              return (lv_totalBytesRead>0 ? lv_totalBytesRead : lv_Stat);
            }
          }

          else {

            // We have all the FFHs that this lib process knows about,
            // check to see if new fragments available

            bool lv_newFragsDetected = LibRead_GetMoreFragments (lp_Efh);
              
            if (lv_newFragsDetected == false) {
              // a real EOF! Clean up errno after all the calls we've made

              errno = 0;
              return lv_totalBytesRead;
            }

            // We found new fragments.  Open them and try to read the rest of
            // the data.

            lv_Stat = lp_Efh ->OpenNewFragments();

            if (lv_Stat < 0) {
              // hope that any error was set below
              return (lv_totalBytesRead>0 ? lv_totalBytesRead : -1);
            }
          } // else
        }

      } // 0 count error handling

      else if (lv_Stat<0) {

        // Error!  We might be done here.  We can't just return this error
        // though.  We have to check to see if we read anything.  If so, return
        // that value and when the caller comes back, the error might (or might
        // not) happen again.
          
        return (lv_totalBytesRead>0 ? lv_totalBytesRead : -1);

      }

      else {

        // partial read!  Adjust our counters and try again
        // find out...

        ASSERT ( (size_t) lv_Stat < pv_Count);

        lv_totalBytesRead += lv_Stat;
        lp_currBufPtr = (char *)lp_currBufPtr + lv_Stat;
        lv_readSize -= lv_Stat;

      }

      if (lp_Efh->SetCurrentFragmentBasedOnCurrOffset() == true) {
        // switched frags!  We're reading sequentially, so we need to do an
        // explicit lseek in case this fragment's FD was previously used for
        // some other I/O operation.

        lv_Stat = lp_Efh->SeekToCurrFragmentStart();

        if (lv_Stat < 0) {
          // physical position failed!
          return (lv_totalBytesRead>0 ? lv_totalBytesRead : lv_Stat);
        }
      }

    } //while !readcompleted

    return lv_totalBytesRead;
  }