void mp_subthread_locate(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { mp_locate_arg_t * args = (mp_locate_arg_t*) pt; storage_t * st = 0; static mp_locate_ret_t ret; START_PROFILING(locate); /* ** Use received buffer for the response */ req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; if ((st = get_storage(args->cid, args->sid, req_ctx_p->socketRef)) == 0) { goto error; } if (storaged_sub_thread_intf_send_req(MP_LOCATE,req_ctx_p,st,tic)==0) { return; } error: ret.status = MP_FAILURE; ret.mp_locate_ret_t_u.error = errno; rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(locate); }
void sp_null_1_svc_nb(void *args, rozorpc_srv_ctx_t *req_ctx_p) { DEBUG_FUNCTION; static void *result = NULL; req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; rozorpc_srv_forward_reply(req_ctx_p,(char*)&result); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); return ; }
void sp_write_1_svc_nb(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { sp_write_arg_t * args = (sp_write_arg_t *) pt; static sp_write_ret_t ret; storage_t *st = 0; // Variable to be used in a later version. uint8_t version = 0; char *buf_bins; /* ** put the pointer to the bins (still in received buffer */ int position = storage_get_position_of_first_byte2write_from_write_req(); buf_bins = (char*)ruc_buf_getPayload(req_ctx_p->recv_buf); buf_bins+= position; DEBUG_FUNCTION; START_PROFILING_IO(write, args->nb_proj * rozofs_get_max_psize(args->layout) * sizeof (bin_t)); ret.status = SP_FAILURE; // Get the storage for the couple (cid;sid) if ((st = storaged_lookup(args->cid, args->sid)) == 0) { ret.sp_write_ret_t_u.error = errno; goto out; } // Write projections if (storage_write(st, args->layout, (sid_t *) args->dist_set, args->spare, (unsigned char *) args->fid, args->bid, args->nb_proj, version, &ret.sp_write_ret_t_u.file_size, (bin_t *) buf_bins) <= 0) { ret.sp_write_ret_t_u.error = errno; goto out; } ret.status = SP_SUCCESS; out: req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(write); return ; }
/** 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); }
void sp_truncate_1_svc_nb(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { sp_truncate_arg_t * args = (sp_truncate_arg_t *) pt; static sp_status_ret_t ret; storage_t *st = 0; // Variable to be used in a later version. uint8_t version = 0; DEBUG_FUNCTION; START_PROFILING(truncate); ret.status = SP_FAILURE; // Get the storage for the couple (cid;sid) if ((st = storaged_lookup(args->cid, args->sid)) == 0) { ret.sp_status_ret_t_u.error = errno; goto out; } // Truncate bins file if (storage_truncate(st, args->layout, (sid_t *) args->dist_set, args->spare, (unsigned char *) args->fid, args->proj_id, args->bid,version,args->last_seg,args->last_timestamp, args->bins.bins_len, args->bins.bins_val) != 0) { ret.sp_status_ret_t_u.error = errno; goto out; } ret.status = SP_SUCCESS; out: req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(truncate); return ; }
void sp_read_1_svc_disk_thread(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { static sp_read_ret_t ret; START_PROFILING(read); /* ** allocate a buffer for the response */ req_ctx_p->xmitBuf = ruc_buf_getBuffer(storage_xmit_buffer_pool_p); if (req_ctx_p->xmitBuf == NULL) { severe("sp_read_1_svc_disk_thread Out of memory STORAGE_NORTH_LARGE_POOL"); errno = ENOMEM; req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; goto error; } /* ** Set the position where the data have to be written in the xmit buffer */ req_ctx_p->position = storage_get_position_of_first_byte2write_from_read_req(); if (storio_disk_thread_intf_send(STORIO_DISK_THREAD_READ, req_ctx_p, tic) == 0) { return; } severe("storio_disk_thread_intf_send %s", strerror(errno)); error: ret.status = SP_FAILURE; ret.sp_read_ret_t_u.error = errno; rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(read); return ; }
void sp_write_1_svc_disk_thread(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { static sp_write_ret_t ret; START_PROFILING(write); if (storio_disk_thread_intf_send(STORIO_DISK_THREAD_WRITE, req_ctx_p,tic) == 0) { return; } severe("sp_write_1_svc_disk_thread storio_disk_thread_intf_send %s", strerror(errno)); ret.status = SP_FAILURE; ret.sp_write_ret_t_u.error = errno; rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(write); return ; }
void sp_read_1_svc_nb(void * pt, rozorpc_srv_ctx_t *req_ctx_p) { sp_read_arg_t * args = (sp_read_arg_t *) pt; static sp_read_ret_t ret; storage_t *st = 0; START_PROFILING_IO(read, args->nb_proj * rozofs_get_max_psize(args->layout) * sizeof (bin_t)); ret.status = SP_FAILURE; /* ** allocate a buffer for the response */ req_ctx_p->xmitBuf = ruc_buf_getBuffer(storage_xmit_buffer_pool_p); if (req_ctx_p->xmitBuf == NULL) { severe("Out of memory STORAGE_NORTH_LARGE_POOL"); ret.sp_read_ret_t_u.error = ENOMEM; req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; goto error; } // Get the storage for the couple (cid;sid) if ((st = storaged_lookup(args->cid, args->sid)) == 0) { ret.sp_read_ret_t_u.error = errno; goto error; } /* ** set the pointer to the bins */ int position = storage_get_position_of_first_byte2write_from_read_req(); uint8_t *pbuf = (uint8_t*)ruc_buf_getPayload(req_ctx_p->xmitBuf); /* ** clear the length of the bins and set the pointer where data must be returned */ ret.sp_read_ret_t_u.rsp.bins.bins_val =(char *)(pbuf+position); ; ret.sp_read_ret_t_u.rsp.bins.bins_len = 0; #if 0 // for future usage with distributed cache /* ** clear the optimization array */ ret.sp_read_ret_t_u.rsp.optim.optim_val = (char*)sp_optim; ret.sp_read_ret_t_u.rsp.optim.optim_len = 0; #endif // Read projections if (storage_read(st, args->layout, (sid_t *) args->dist_set, args->spare, (unsigned char *) args->fid, args->bid, args->nb_proj, (bin_t *) ret.sp_read_ret_t_u.rsp.bins.bins_val, (size_t *) & ret.sp_read_ret_t_u.rsp.bins.bins_len, &ret.sp_read_ret_t_u.rsp.file_size) != 0) { ret.sp_read_ret_t_u.error = errno; goto error; } ret.status = SP_SUCCESS; storaged_srv_forward_read_success(req_ctx_p,&ret); /* ** check the case of the readahead */ storage_check_readahead(); goto out; error: rozorpc_srv_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ out: rozorpc_srv_release_context(req_ctx_p); STOP_PROFILING(read); return ; }
/** Server callback for GW_PROGRAM protocol: GW_INVALIDATE_SECTIONS GW_INVALIDATE_ALL GW_CONFIGURATION GW_POLL That callback is called upon receiving a GW_PROGRAM message from the master exportd @param socket_ctx_p: pointer to the af unix socket @param socketId: reference of the socket (not used) @retval : TRUE-> xmit ready event expected @retval : FALSE-> xmit ready event not expected */ void storio_req_rcv_cbk(void *userRef,uint32_t socket_ctx_idx, void *recv_buf) { uint32_t *com_hdr_p; rozofs_rpc_call_hdr_t hdr; sp_status_ret_t arg_err; char * arguments; int size = 0; rozorpc_srv_ctx_t *rozorpc_srv_ctx_p = NULL; com_hdr_p = (uint32_t*) ruc_buf_getPayload(recv_buf); com_hdr_p +=1; /* skip the size of the rpc message */ memcpy(&hdr,com_hdr_p,sizeof(rozofs_rpc_call_hdr_t)); scv_call_hdr_ntoh(&hdr); /* ** allocate a context for the duration of the transaction since it might be possible ** that the gateway needs to interrogate the exportd and thus needs to save the current ** request until receiving the response from the exportd */ rozorpc_srv_ctx_p = rozorpc_srv_alloc_context(); if (rozorpc_srv_ctx_p == NULL) { fatal(" Out of rpc context"); } /* ** save the initial transaction id, received buffer and reference of the connection */ rozorpc_srv_ctx_p->src_transaction_id = hdr.hdr.xid; rozorpc_srv_ctx_p->recv_buf = recv_buf; rozorpc_srv_ctx_p->socketRef = socket_ctx_idx; /* ** Allocate buffer for decoded aeguments */ rozorpc_srv_ctx_p->decoded_arg = ruc_buf_getBuffer(decoded_rpc_buffer_pool); if (rozorpc_srv_ctx_p->decoded_arg == NULL) { rozorpc_srv_ctx_p->xmitBuf = rozorpc_srv_ctx_p->recv_buf; rozorpc_srv_ctx_p->recv_buf = NULL; rozorpc_srv_ctx_p->xdr_result =(xdrproc_t) xdr_sp_status_ret_t; arg_err.status = SP_FAILURE; arg_err.sp_status_ret_t_u.error = ENOMEM; rozorpc_srv_forward_reply(rozorpc_srv_ctx_p,(char*)&arg_err); rozorpc_srv_release_context(rozorpc_srv_ctx_p); return; } arguments = ruc_buf_getPayload(rozorpc_srv_ctx_p->decoded_arg); void (*local)(void *, rozorpc_srv_ctx_t *); switch (hdr.proc) { case SP_NULL: rozorpc_srv_ctx_p->arg_decoder = (xdrproc_t) xdr_void; rozorpc_srv_ctx_p->xdr_result = (xdrproc_t) xdr_void; local = sp_null_1_svc_nb; break; case SP_WRITE: rozorpc_srv_ctx_p->arg_decoder = (xdrproc_t) xdr_sp_write_arg_no_bins_t; rozorpc_srv_ctx_p->xdr_result = (xdrproc_t) xdr_sp_write_ret_t; // local = sp_write_1_svc_nb; local = sp_write_1_svc_disk_thread; size = sizeof (sp_write_arg_no_bins_t); break; case SP_READ: rozorpc_srv_ctx_p->arg_decoder = (xdrproc_t) xdr_sp_read_arg_t; rozorpc_srv_ctx_p->xdr_result = (xdrproc_t) xdr_sp_read_ret_t; // local = sp_read_1_svc_nb; local = sp_read_1_svc_disk_thread; size = sizeof (sp_read_arg_t); break; case SP_TRUNCATE: rozorpc_srv_ctx_p->arg_decoder = (xdrproc_t) xdr_sp_truncate_arg_t; rozorpc_srv_ctx_p->xdr_result = (xdrproc_t) xdr_sp_status_ret_t; // local = sp_truncate_1_svc_nb; local = sp_truncate_1_svc_disk_thread; size = sizeof (sp_truncate_arg_t); break; default: rozorpc_srv_ctx_p->xmitBuf = rozorpc_srv_ctx_p->recv_buf; rozorpc_srv_ctx_p->recv_buf = NULL; rozorpc_srv_ctx_p->xdr_result =(xdrproc_t) xdr_sp_status_ret_t; arg_err.status = SP_FAILURE; arg_err.sp_status_ret_t_u.error = EPROTO; rozorpc_srv_forward_reply(rozorpc_srv_ctx_p,(char*)&arg_err); rozorpc_srv_release_context(rozorpc_srv_ctx_p); return; } memset(arguments,0, size); ruc_buf_setPayloadLen(rozorpc_srv_ctx_p->decoded_arg,size); // for debug /* ** decode the payload of the rpc message */ if (!rozorpc_srv_getargs_with_position (recv_buf, (xdrproc_t) rozorpc_srv_ctx_p->arg_decoder, (caddr_t) arguments, &rozorpc_srv_ctx_p->position)) { rozorpc_srv_ctx_p->xmitBuf = rozorpc_srv_ctx_p->recv_buf; rozorpc_srv_ctx_p->recv_buf = NULL; rozorpc_srv_ctx_p->xdr_result = (xdrproc_t)xdr_sp_status_ret_t; arg_err.status = SP_FAILURE; arg_err.sp_status_ret_t_u.error = errno; rozorpc_srv_forward_reply(rozorpc_srv_ctx_p,(char*)&arg_err); /* ** release the context */ rozorpc_srv_release_context(rozorpc_srv_ctx_p); return; } /* ** call the user call-back */ (*local)(arguments, rozorpc_srv_ctx_p); }