示例#1
0
void north_lbg_poll_xmit_queue(north_lbg_ctx_t  *lbg_p, north_lbg_entry_ctx_t  *entry_p,int xmit_credit)
{
   ruc_obj_desc_t *pnext;
   int ret;
   int i;
   void *buf_p;

   pnext = (ruc_obj_desc_t*)NULL;
   for (i = 0; i < xmit_credit; i++)
   {
   while ((buf_p = (void*) ruc_objGetNext((ruc_obj_desc_t*)&lbg_p->xmitList[0],
                                        &pnext))
               !=NULL) 
   {         
     ruc_objRemove((ruc_obj_desc_t*)buf_p);
     lbg_p->stats.xmitQueuelen--;
     ret = af_unix_generic_send_stream_with_idx(entry_p->sock_ctx_ref,buf_p);  
     if (ret ==  0)
     {
       lbg_p->stats.totalXmit++;
       entry_p->stats.totalXmit++; 
       continue;
     } 
     /*
     ** there is an error, the interface is down again, so requeue the buffer at the head
     ** do we need to udpate the retry counter of the buffer ??
     */  
     lbg_p->stats.totalXmitError++; 
     lbg_p->stats.xmitQueuelen++;
     ruc_objInsert(&lbg_p->xmitList[0],(ruc_obj_desc_t*) buf_p);
     return;   
   }
   return; 
   }
 }
示例#2
0
/**
  Processes a disk response

   Called from the socket controller when there is a response from a disk thread
   the response is either for a disk read or write
    
  @param msg: pointer to disk response message
 
  @retval :none
*/
void af_unix_disk_response(storio_disk_thread_msg_t *msg) 
{

  storio_disk_thread_request_e   opcode;
  rozorpc_srv_ctx_t            * rpcCtx;
  int                            ret;
  uint64_t                       tic, toc;  
  struct timeval                 tv;  
  
  rpcCtx = msg->rpcCtx;
  opcode = msg->opcode;
  tic    = msg->timeStart;

  switch (opcode) {
    case STORIO_DISK_THREAD_READ:
      STOP_PROFILING_IO(read,msg->size);
      update_read_detailed_counters(toc - tic);      
      break;
    case STORIO_DISK_THREAD_WRITE:
      STOP_PROFILING_IO(write,msg->size);
      update_write_detailed_counters(toc - tic);            
      break;     
    case STORIO_DISK_THREAD_TRUNCATE:
      STOP_PROFILING(truncate);
      break;   
    default:
      severe("Unexpected opcode %d", opcode);
  }
  /*
  ** send the response towards the storcli process that initiates the disk operation
  */
  ret = af_unix_generic_send_stream_with_idx((int)rpcCtx->socketRef,rpcCtx->xmitBuf);  
  if (ret == 0) {
    /**
    * success so remove the reference of the xmit buffer since it is up to the called
    * function to release it
    */
    ROZORPC_SRV_STATS(ROZORPC_SRV_SEND);
    rpcCtx->xmitBuf = NULL;
  }
  else {
    ROZORPC_SRV_STATS(ROZORPC_SRV_SEND_ERROR);
  }
    
  rozorpc_srv_release_context(rpcCtx);          
}
示例#3
0
int north_lbg_send_from_shaper(int  lbg_idx,void *buf_p)
{

  north_lbg_ctx_t  *lbg_p;
  int entry_idx;
  int ret = 0;
  /*
  ** remove the buffer from any pending list
  */
  ruc_objRemove((ruc_obj_desc_t*)buf_p);
  
  lbg_p = north_lbg_getObjCtx_p(lbg_idx);
  if (lbg_p == NULL) 
  {
    severe("north_lbg_send: no such instance %d ",lbg_idx);
    return -1;
  }
  /*
  ** OK there is at least one entry that is free, so get the next valid entry
  */
reloop:
  entry_idx = north_lbg_get_next_valid_entry(lbg_p);
  if (entry_idx < 0)
  {
    /*
    ** that situation must not occur since there is at leat one entry that is UP!!!!
    */
//    RUC_WARNING(-1);
    return -1;    
  }
  /*
  ** That's fine, get the pointer to the entry in order to get its socket context reference
  */
  north_lbg_entry_ctx_t  *entry_p = &lbg_p->entry_tb[entry_idx];
  NORTH_LBG_START_PROF((&entry_p->stats));
  ret = af_unix_generic_send_stream_with_idx(entry_p->sock_ctx_ref,buf_p); 
  NORTH_LBG_STOP_PROF((&entry_p->stats));
  if (ret == 0)
  {
    /*
    ** set the timer to supervise the connection (it only affects client connections)
    */
    if (lbg_p->userPollingCallBack != NULL)
    {
      af_unix_ctx_generic_t *this = af_unix_getObjCtx_p(entry_p->sock_ctx_ref);
      af_inet_enable_cnx_supervision(this);
      af_inet_set_cnx_tmo(this,lbg_p->tmo_supervision_in_sec*10*5);
    }
    lbg_p->stats.totalXmit++; 
    entry_p->stats.totalXmit++;     
    return 0; 
  } 
  /*
  ** retry on a next entry
  ** we might need to update the retry counter of the buffer ??
  */
  lbg_p->stats.totalXmitError++; 
  goto reloop;
  
  return 0;
}
示例#4
0
/**
*  create a north load balancing object with AF_INET

  @param lbg_idx : reference of the load balancing group
  @param buf_p: pointer to the buffer to send
  
  retval 0 : success
  retval -1 : error
*/
int north_lbg_send(int  lbg_idx,void *buf_p)
{                             
  north_lbg_ctx_t  *lbg_p;
  int entry_idx;
  int ret = 0;

  /*
  ** remove the buffer from any pending list
  */
  ruc_objRemove((ruc_obj_desc_t*)buf_p);
  
  lbg_p = north_lbg_getObjCtx_p(lbg_idx);
  if (lbg_p == NULL) 
  {
    severe("north_lbg_send: no such instance %d ",lbg_idx);
    return -1;
  }
  if ((lbg_p->state == NORTH_LBG_SHUTTING_DOWN) || (lbg_p->free == TRUE))
  {
     return -1;
  }
reloop:
  /*
  ** we have the context, search for a valid entry
  */
  if (lbg_p->state == NORTH_LBG_DOWN)
  {
    /*
    ** Insert the buffer in the global pending list of the load balancing froup
    */
    ruc_objInsertTail((ruc_obj_desc_t*)&lbg_p->xmitList[0],(ruc_obj_desc_t*)buf_p);  
    /*
    ** update statistics
    */
    lbg_p->stats.xmitQueuelen++;     
    return 0;  
  }
  /*
  ** check if the main queue is empty if the queue is not empty just queue our message
  ** at the tail of the load balancer main queue
  */
  if (!ruc_objIsEmptyList((ruc_obj_desc_t*)&lbg_p->xmitList[0]))
  {
     /*
     ** queue the message at the tail
     */
     ruc_objInsertTail((ruc_obj_desc_t*)&lbg_p->xmitList[0],(ruc_obj_desc_t*)buf_p);  
    /*
    ** update statistics
    */
    lbg_p->stats.xmitQueuelen++;     
    return 0;  
  }
  
  
  /*
  ** Check whether this LBG is in active/standby mode
  ** in this case send the message on the active connection
  */
  if (lbg_p->active_standby_mode == 1) {
  
    /*
    ** No actibve entry elected. The LBG should nbe down !!!
    */
    if (lbg_p->active_lbg_entry < 0) {
      /*
      ** queue the message at the tail
      */
      ruc_objInsertTail((ruc_obj_desc_t*)&lbg_p->xmitList[0],(ruc_obj_desc_t*)buf_p);  
      /*
      ** update statistics
      */
      lbg_p->stats.xmitQueuelen++;     
      return 0;  
    }
    
    /*
    ** Get the active socket to send on
    */
    entry_idx = lbg_p->active_lbg_entry;
  }
  
  else {

     /*
     ** OK there is at least one entry that is free, so get the next valid entry
     */
     entry_idx = north_lbg_get_next_valid_entry(lbg_p);
     if (entry_idx < 0)
     {
       /*
       ** that situation must not occur since there is at leat one entry that is UP!!!!
       */
   //    RUC_WARNING(-1);
       return -1;    
     }
     
  }   
  /*
  ** That's fine, get the pointer to the entry in order to get its socket context reference
  */
  north_lbg_entry_ctx_t  *entry_p = &lbg_p->entry_tb[entry_idx];
  NORTH_LBG_START_PROF((&entry_p->stats));
  ret = af_unix_generic_send_stream_with_idx(entry_p->sock_ctx_ref,buf_p); 
  NORTH_LBG_STOP_PROF((&entry_p->stats));
  if (ret == 0)
  {
    /*
    ** set the timer to supervise the connection (it only affects client connections)
    */
    if (lbg_p->userPollingCallBack != NULL)
    {
      af_unix_ctx_generic_t *this = af_unix_getObjCtx_p(entry_p->sock_ctx_ref);
      af_inet_enable_cnx_supervision(this);
      af_inet_set_cnx_tmo(this,lbg_p->tmo_supervision_in_sec*10*5);
    }
    lbg_p->stats.totalXmit++; 
    entry_p->stats.totalXmit++;     
    return 0; 
  } 
  /*
  ** retry on a next entry
  ** we might need to update the retry counter of the buffer ??
  */
  lbg_p->stats.totalXmitError++; 
  goto reloop;
  
  return 0;
}
示例#5
0
/**
* send a rpc reply: the encoding function MUST be found in xdr_result 
 of the gateway context

  It is assumed that the xmitBuf MUST be found in xmitBuf field
  
  In case of a success it is up to the called function to release the xmit buffer
  
  @param p : pointer to the root transaction context used for the read
  @param arg_ret : returned argument to encode 
  
  @retval none

*/
void storaged_srv_forward_read_success (rozorpc_srv_ctx_t *p,sp_read_ret_t * arg_ret)
{
   int ret;
   uint8_t *pbuf;           /* pointer to the part that follows the header length */
   uint32_t *header_len_p;  /* pointer to the array that contains the length of the rpc message*/
   XDR xdrs;
   int len;
   int cur_len;

   if (p->xmitBuf == NULL)
   {
      ROZORPC_SRV_STATS(ROZORPC_SRV_NO_BUFFER_ERROR);
      severe("no xmit buffer");
      goto error;
   } 
    /*
    ** create xdr structure on top of the buffer that will be used for sending the response
    */
    header_len_p = (uint32_t*)ruc_buf_getPayload(p->xmitBuf); 
    pbuf = (uint8_t*) (header_len_p+1);            
    len = (int)ruc_buf_getMaxPayloadLen(p->xmitBuf);
    len -= sizeof(uint32_t);
    xdrmem_create(&xdrs,(char*)pbuf,len,XDR_ENCODE); 
    /*
    ** just encode the header
    */
    if (rozofs_encode_rpc_reply(&xdrs,(xdrproc_t)NULL,(caddr_t)NULL,p->src_transaction_id) != TRUE)
    {
      ROZORPC_SRV_STATS(ROZORPC_SRV_ENCODING_ERROR);
      severe("rpc reply encoding error");
      goto error;     
    }
    /*
    ** OK now starts encoding the response
    */
    xdr_sp_status_t (&xdrs, &arg_ret->status);
    xdr_uint32_t (&xdrs, &arg_ret->sp_read_ret_t_u.rsp.filler);          
    xdr_uint32_t (&xdrs, &arg_ret->sp_read_ret_t_u.rsp.bins.bins_len); 
    /*
    ** skip the bins
    */
    cur_len =  xdr_getpos(&xdrs) ;     
    cur_len +=  arg_ret->sp_read_ret_t_u.rsp.bins.bins_len;
    xdr_setpos(&xdrs,cur_len);
    /*
    ** encode the length of the file
    */
    xdr_uint64_t (&xdrs, &arg_ret->sp_read_ret_t_u.rsp.file_size);
#if 0 // for future usage with distributed cache 
    /*
    ** encode the optim array
    */
    xdr_bytes (&xdrs, (char **)&arg_ret->sp_read_ret_t_u.rsp.optim.optim_val, 
                       (u_int *) &arg_ret->sp_read_ret_t_u.rsp.optim.optim_len, ~0);  
#endif
    /*
    ** compute the total length of the message for the rpc header and add 4 bytes more bytes for
    ** the ruc buffer to take care of the header length of the rpc message.
    */
    int total_len = xdr_getpos(&xdrs) ;
    *header_len_p = htonl(0x80000000 | total_len);
    total_len +=sizeof(uint32_t);
    ruc_buf_setPayloadLen(p->xmitBuf,total_len);

    /*
    ** Get the callback for sending back the response:
    ** A callback is needed since the request for read might be local or remote
    */
    ret =  af_unix_generic_send_stream_with_idx((int)p->socketRef,p->xmitBuf);  
    if (ret == 0)
    {
      /**
      * success so remove the reference of the xmit buffer since it is up to the called
      * function to release it
      */
      ROZORPC_SRV_STATS(ROZORPC_SRV_SEND);
      p->xmitBuf = NULL;
    }
    else
    {
      ROZORPC_SRV_STATS(ROZORPC_SRV_SEND_ERROR);
    }
error:
    return;
}