Пример #1
0
void GridFTP_Commands::data_connect_store_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  logger.msg(Arc::VERBOSE, "data_connect_store_callback");
  globus_thread_blocking_will_block();
  globus_mutex_lock(&(it->data_lock));
  it->time_spent_disc=0;
  it->time_spent_network=0;
  it->last_action_time=time(NULL);
  logger.msg(Arc::VERBOSE, "Data channel connected (store)");
  if(it->check_abort(error)) {
    it->froot.close(false);
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->data_eof = false;
  /* make buffers */
  it->compute_data_buffer();
  if(!(it->allocate_data_buffer())) {
    it->froot.close(false);
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  /* register all available buffers */
  it->data_callbacks=0;
  globus_result_t res = GLOBUS_SUCCESS;
  for(unsigned int i = 0;i<it->data_buffer_num;i++) {
    if(!((it->data_buffer)[i].data)) continue;
    struct timezone tz;
    gettimeofday(&(it->data_buffer[i].time_last),&tz);
    res=globus_ftp_control_data_read(&(it->handle),
            (globus_byte_t*)(it->data_buffer[i].data),
            it->data_buffer_size,
            &data_store_callback,it);
    if(res==GLOBUS_SUCCESS) { it->data_callbacks++; }
    else { break; };
  };
  if(it->data_callbacks==0) {
    logger.msg(Arc::ERROR, "Failed to register any buffer");
    if(res != GLOBUS_SUCCESS) {
      logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str());
    };
    it->froot.close(false);
    it->free_data_buffer();
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  globus_mutex_unlock(&(it->data_lock)); return;
}
Пример #2
0
/* *** list transfer callbacks *** */
void GridFTP_Commands::list_retrieve_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t* /* buffer */,globus_size_t /* length */,globus_off_t /* offset */,globus_bool_t /* eof */) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  if(it->check_abort(error)) {
    it->free_data_buffer();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_bool_t eodf;
  globus_size_t size;
  if(it->dir_list_pointer == it->dir_list.end()) {
    it->virt_offset=0;
    it->transfer_mode=false;
    it->free_data_buffer();
    logger.msg(Arc::VERBOSE, "Closing channel (list)");
    it->send_response("226 Transfer completed.\r\n");
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE);
  ++(it->dir_list_pointer);
  if(it->dir_list_pointer == it->dir_list.end()) {
    size=0; eodf=GLOBUS_TRUE;
  }
  else {
    size=make_list_string(*(it->dir_list_pointer),it->list_mode,
                        it->data_buffer[0].data,it->data_buffer_size,
                        it->list_name_prefix.c_str());
    eodf=GLOBUS_FALSE;
  };
  globus_result_t res;
  res=globus_ftp_control_data_write(&(it->handle),
                   (globus_byte_t*)(it->data_buffer[0].data),
                   size,it->list_offset,eodf,
                   &list_retrieve_callback,it);
  if(res != GLOBUS_SUCCESS) {
    it->free_data_buffer();
    it->force_abort();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  globus_mutex_unlock(&(it->data_lock));
}
Пример #3
0
void GridFTP_Commands::list_connect_retrieve_callback(void* arg,globus_ftp_control_handle_t*,unsigned int /* stripendx */,globus_bool_t /* reused */,globus_object_t *error) {
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  if(it->check_abort(error)) {
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  it->data_buffer_size=4096;
  it->data_buffer_num=1;
  if(!it->allocate_data_buffer()) {
    it->force_abort(); globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->dir_list_pointer=it->dir_list.begin();
  globus_size_t size;
  globus_bool_t eodf;
  if(it->dir_list_pointer == it->dir_list.end()) {
    size=0; eodf=GLOBUS_TRUE;
  }
  else {
    size=make_list_string(*(it->dir_list_pointer),it->list_mode,
                         it->data_buffer[0].data,it->data_buffer_size,
                        it->list_name_prefix.c_str());
    eodf=GLOBUS_FALSE;
  };
  it->list_offset = 0;
  logger.msg(Arc::VERBOSE, "Data channel connected (list)");
  globus_ftp_control_local_send_eof(&(it->handle),GLOBUS_TRUE);
  globus_result_t res;
  res=globus_ftp_control_data_write(&(it->handle),
                   (globus_byte_t*)(it->data_buffer[0].data),
                   size,it->list_offset,eodf,
                   &list_retrieve_callback,it);
  if(res != GLOBUS_SUCCESS) {
    it->free_data_buffer();
    it->force_abort();
    globus_mutex_unlock(&(it->data_lock));
    return;
  };
  it->list_offset+=size;
  globus_mutex_unlock(&(it->data_lock));
}
Пример #4
0
void GridFTP_Commands::data_store_callback(void* arg,globus_ftp_control_handle_t*,globus_object_t *error,globus_byte_t *buffer,globus_size_t length,globus_off_t offset,globus_bool_t eof) {
  globus_thread_blocking_will_block();
  GridFTP_Commands *it = (GridFTP_Commands*)arg;
  struct timezone tz;
  struct timeval tv;
  gettimeofday(&tv,&tz);
  globus_mutex_lock(&(it->data_lock));
  it->last_action_time=time(NULL);
  logger.msg(Arc::VERBOSE, "Data channel (store) %i %i %i", (int)offset, (int)length, (int)eof);
  it->data_callbacks--;
  if(it->check_abort(error)) {
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  if(eof) it->data_eof=true;
  /* find this buffer */
  unsigned int i;
  for(i = 0;i<it->data_buffer_num;i++) {
    if((it->data_buffer)[i].data == (unsigned char*)buffer) break;
  };
  if(i >= it->data_buffer_num) { /* lost buffer - probably memory corruption */
    logger.msg(Arc::ERROR, "data_store_callback: lost buffer");
    it->force_abort();
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  unsigned long long int time_diff = 
     (tv.tv_sec-(it->data_buffer[i].time_last.tv_sec))*1000000+
     (tv.tv_usec-(it->data_buffer[i].time_last.tv_usec));
  it->time_spent_network+=time_diff;
  /* write data to file 
     NOTE: it->data_lock is not unlocked here because it->froot.write 
     is not thread safe */
  struct timeval tv_last;
  gettimeofday(&tv_last,&tz);
  if(it->froot.write(it->data_buffer[i].data,
                (it->virt_offset)+offset,length) != 0) {
    logger.msg(Arc::ERROR, "Closing channel (store) due to error: %s", it->froot.error);
    it->force_abort();
    if(it->data_callbacks==0){it->free_data_buffer();it->froot.close(false);};
    globus_mutex_unlock(&(it->data_lock)); return;
  }; 
  gettimeofday(&tv,&tz);
  time_diff=(tv.tv_sec-tv_last.tv_sec)*1000000+(tv.tv_usec-tv_last.tv_usec);
  it->time_spent_disc+=time_diff;
  if(it->data_eof) {
    if(it->data_callbacks==0) {
      logger.msg(Arc::VERBOSE, "Closing channel (store)");
      it->free_data_buffer();
      it->virt_offset=0;
      it->virt_restrict=false;
      it->transfer_mode=false;
      if(it->froot.close() != 0) {
        if(it->froot.error.length()) {
          it->send_response("451 "+it->froot.error+"\r\n");
        } else {
          it->send_response("451 Local error\r\n");
        };
      }
      else {
        logger.msg(Arc::VERBOSE, "Time spent waiting for network: %.3f ms", (float)(it->time_spent_network/1000.0));
        logger.msg(Arc::VERBOSE, "Time spent waiting for disc: %.3f ms", (float)(it->time_spent_disc/1000.0));
        it->send_response("226 Requested file transfer completed\r\n");
      };
    };
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  /* register buffer */
  globus_result_t res;
  gettimeofday(&(it->data_buffer[i].time_last),&tz);
  res=globus_ftp_control_data_read(&(it->handle),
            (globus_byte_t*)(it->data_buffer[i].data),
            it->data_buffer_size,
            &data_store_callback,it);
  if(res != GLOBUS_SUCCESS) {
    /* Because this error can be caused by EOF, abort should not be
       called unless this is last buffer */
    if(it->data_callbacks==0) {
      logger.msg(Arc::ERROR, "Globus error: %s", Arc::GlobusResult(res).str());
      it->force_abort();
      it->free_data_buffer();it->froot.close(false);
    };
    globus_mutex_unlock(&(it->data_lock)); return;
  };
  it->data_callbacks++;
  globus_mutex_unlock(&(it->data_lock)); return;
}