Example #1
0
bool GlusterBackend::put(const SyncEvent* _putEvent) {
  if(_putEvent == nullptr || _putEvent->fullPathBuffer.empty())
      return false;

  FileNode* node = FileSystem::getInstance().findAndOpenNode(_putEvent->fullPathBuffer);
  if(node == nullptr){
    LOG(ERROR)<<_putEvent->fullPathBuffer<<" Does not exist! So can't upload it.";
    return false;
  }
  uint64_t inodeNum = FileSystem::getInstance().assignINodeNum((intptr_t)node);

  //Double check if not already uploaded
  if(node->flushed()){
    node->close(inodeNum);
    return true;
  }

  //CheckEvent validity
  if(!UploadQueue::getInstance().checkEventValidity(*_putEvent)) {
    //release file delete lock, so they can delete it
    node->close(inodeNum);
    return true;//going to be deletes so anyway say it's synced!
  }

  if(node->mustBeDeleted()){
    node->close(inodeNum);
    return true;
  }

  //Create necessary directories
  //Traverse FileSystem Hierarchies
  Poco::StringTokenizer tokenizer(_putEvent->fullPathBuffer,
      FileSystem::delimiter,Poco::StringTokenizer::TOK_TRIM |
      Poco::StringTokenizer::TOK_IGNORE_EMPTY);
  //Nested directories
  if(tokenizer.count()>=2){
    for(unsigned int i=0;i<tokenizer.count()-1;i++){
      string path = FileSystem::delimiter;
      for(unsigned int j=0;j<=i;j++){
        path += tokenizer[j];
        path += FileSystem::delimiter;
      }
      if(!createDirectory(path.c_str())){
        LOG(ERROR)<<"Failed to create parent directory("<<tokenizer[i]<<") for:"<<_putEvent->fullPathBuffer;
        node->close(inodeNum);
        return false;
      }
    }
  }
  //Create the file! (overwrite or create)
  glfs_fd_t *fd = glfs_creat((glfs_t*)fs, _putEvent->fullPathBuffer.c_str(), O_RDWR, 0644);
  //glfs_fd_t *fd = glfs_open(,O_RDWR| O_CREAT | O_TRUNC);
  if(!fd){
    LOG(ERROR)<<"Error in creating file:"<<_putEvent->fullPathBuffer<<" in GlusterFS. errno:"<<errno;
    return false;
  }

  //Ready to write (write each time a blocksize)
  uint64_t buffSize = 1024ll*1024ll*10ll;
  char *buff = new char[buffSize];//10MB buffer
  size_t offset = 0;
  long read = 0;
  //FileNode *node = _putEvent->node;
  do {
    //CheckEvent validity
    if(!UploadQueue::getInstance().checkEventValidity(*_putEvent)){
      glfs_close(fd);
      delete []buff;
      buff = nullptr;
      node->close(inodeNum);
      return true;
    }

    if(node->mustBeDeleted()){//Check Delete
      glfs_close(fd);
      delete []buff;
      buff = nullptr;
      node->close(inodeNum);
      return true;
    }

    //get lock delete so file won't be deleted
    read = node->read(buff,offset,buffSize);


    offset += read;
    int64_t written = glfs_write(fd,buff,read,0);
    if(written!=read){
      LOG(ERROR)<<"Error while writing to:"<<_putEvent->fullPathBuffer<<
          ". Asked to write:"<<read<<" but wrote:"<<written;
      glfs_close(fd);
      return false;
    }
  }
  while(read > 0);

  delete []buff;
  buff = nullptr;

  if(node->mustBeDeleted()){//Check Delete
    glfs_close(fd);
    node->close(inodeNum);
    return true;
  }

  //Now sync
  if(glfs_close(fd)!=0){
    LOG(ERROR)<<"Error in closing:"<<_putEvent->fullPathBuffer<<" errorNo:"<<errno;
    node->close(inodeNum);
    return false;
  }

  node->close(inodeNum);
  return true;
}
Example #2
0
bool GlusterBackend::get(const SyncEvent* _getEvent) {
  if(_getEvent == nullptr || _getEvent->fullPathBuffer.empty())
    return false;

  //Try to find file
  /**
   * RETURN VALUES
   * NULL   : Failure. @errno will be set with the type of failure.
   * Others : Pointer to the opened glfs_fd_t.
   */
  glfs_fd_t *fd = glfs_open((glfs_t*)fs, _getEvent->fullPathBuffer.c_str(), O_RDONLY);
  if(!fd){
    LOG(ERROR)<<"Error while openeing a handle to:"<<_getEvent->fullPathBuffer;
    return false;
  }

  FileNode* fileNode = FileSystem::getInstance().findAndOpenNode(_getEvent->fullPathBuffer);
  //If File exist then we won't download it!
  if(fileNode!=nullptr){
    LOG(DEBUG)<<"File "<<fileNode->getFullPath()<<" already exist! no need to download.";
    //Close it! so it can be removed if needed
    uint64_t inodeNum = FileSystem::getInstance().assignINodeNum((intptr_t)fileNode);
    fileNode->close(inodeNum);
    glfs_close(fd);
    return false;
  }

  //Now create a file in FS
  //handle directories
  //FileSystem::getInstance().createHierarchy(_getEvent->fullPathBuffer,false);
  //FileNode *newFile = FileSystem::getInstance().mkFile(_getEvent->fullPathBuffer,false,true);//open
  string name = FileSystem::getInstance().getFileNameFromPath(_getEvent->fullPathBuffer);
  FileNode* newFile = new FileNode(name,_getEvent->fullPathBuffer, false,false);
  if(newFile == nullptr){
    LOG(ERROR)<<"Failed to create a newNode:"<<_getEvent->fullPathBuffer;
    glfs_close(fd);
    return false;
  }

  //and write the content
  uint64_t bufSize = 64ll*1024ll*1024ll;
  char *buff = new char[bufSize];//64MB buffer
  size_t offset = 0;
  int64_t read = 0;
  do {

    //No need to download it anymore.
    if(newFile->mustBeDeleted()){
      delete newFile;
      glfs_close(fd);
      return true;
    }

    read = glfs_pread(fd,buff,bufSize,offset,0);

    if(read < 0){
      LOG(ERROR)<<"Error while reading: "<<_getEvent->fullPathBuffer;
      glfs_close(fd);
      return false;
    }

    if(read>0){
      FileNode* afterMove = nullptr;
      long retCode = newFile->writeHandler(buff,offset,read,afterMove,true);

      while(retCode == -1)//-1 means moving
        retCode = newFile->writeHandler(buff,offset,read,afterMove,true);

      if(afterMove){
        newFile = afterMove;
        FileSystem::getInstance().replaceAllInodesByNewNode((intptr_t)newFile,(intptr_t)afterMove);
      }
      //Check space availability
      if(retCode < 0) {
        LOG(ERROR)<<"Error in writing file:"<<newFile->getFullPath()<<", probably no diskspace, Code:"<<retCode;
        delete newFile;
        glfs_close(fd);
        delete []buff;
        return false;
      }
    }

    offset += read;
  }while(read);

  newFile->setNeedSync(false);//We have just created this file so it's upload flag false
  glfs_close(fd);
  delete []buff;
  //Add it to File system
  if(FileSystem::getInstance().createHierarchy(_getEvent->fullPathBuffer,false)==nullptr){
    LOG(ERROR)<<"Error in creating hierarchy for newly downloaded file:"<<newFile->getFullPath();
    delete newFile;
    return false;
  }
  if(!FileSystem::getInstance().addFile(newFile)){
    LOG(ERROR)<<"Error in adding newly downloaded file:"<<newFile->getFullPath();
    delete newFile;
    return false;
  }
  //Gone well
  return true;
}