int as_proxy_send_ops_response(cf_node dst, msg *m, cf_dyn_buf *db) { uint32_t tid; msg_get_uint32(m, PROXY_FIELD_TID, &tid); #ifdef DEBUG cf_debug(AS_PROXY, "proxy send response: message %p bytearray %p tid %d", m, result_code, tid); #endif msg_reset(m); msg_set_uint32(m, PROXY_FIELD_OP, PROXY_OP_RESPONSE); msg_set_uint32(m, PROXY_FIELD_TID, tid); uint8_t *msgp = db->buf; size_t msg_sz = db->used_sz; if (db->is_stack) { msg_set_buf(m, PROXY_FIELD_AS_PROTO, msgp, msg_sz, MSG_SET_COPY); } else { msg_set_buf(m, PROXY_FIELD_AS_PROTO, msgp, msg_sz, MSG_SET_HANDOFF_MALLOC); db->buf = NULL; // the fabric owns the buffer now } int rv = as_fabric_send(dst, m, AS_FABRIC_PRIORITY_MEDIUM); if (rv != 0) { cf_debug(AS_PROXY, "sending proxy response: fabric send err %d, catch you on the retry", rv); as_fabric_msg_put(m); } return 0; } // end as_proxy_send_ops_response()
// Looked up the message in the store. Time to send the response value back to // the requester. The CF_BYTEARRAY is handed off in this case. If you want to // keep a reference, then keep the reference yourself. int as_proxy_send_response(cf_node dst, msg *m, uint32_t result_code, uint32_t generation, uint32_t void_time, as_msg_op **ops, as_bin **bins, uint16_t bin_count, as_namespace *ns, uint64_t trid, const char *setname) { uint32_t tid; msg_get_uint32(m, PROXY_FIELD_TID, &tid); #ifdef DEBUG cf_debug(AS_PROXY, "proxy send response: message %p bytearray %p tid %d", m, result_code, tid); #endif msg_reset(m); msg_set_uint32(m, PROXY_FIELD_OP, PROXY_OP_RESPONSE); msg_set_uint32(m, PROXY_FIELD_TID, tid); size_t msg_sz = 0; cl_msg * msgp = as_msg_make_response_msg(result_code, generation, void_time, ops, bins, bin_count, ns, 0, &msg_sz, trid, setname); msg_set_buf(m, PROXY_FIELD_AS_PROTO, (byte *) msgp, msg_sz, MSG_SET_HANDOFF_MALLOC); int rv = as_fabric_send(dst, m, AS_FABRIC_PRIORITY_MEDIUM); if (rv != 0) { cf_debug(AS_PROXY, "sending proxy response: fabric send err %d, catch you on the retry", rv); as_fabric_msg_put(m); } return 0; } // end as_proxy_send_response()
// Send a redirection message - consumes the message. int as_proxy_send_redirect(cf_node dst, msg *m, cf_node rdst) { int rv; uint32_t tid; msg_get_uint32(m, PROXY_FIELD_TID, &tid); msg_reset(m); msg_set_uint32(m, PROXY_FIELD_OP, PROXY_OP_REDIRECT); msg_set_uint32(m, PROXY_FIELD_TID, tid); msg_set_uint64(m, PROXY_FIELD_REDIRECT, rdst); if (0 != (rv = as_fabric_send(dst, m, AS_FABRIC_PRIORITY_MEDIUM))) { cf_debug(AS_PROXY, "sending redirection failed: fabric send error %d", rv); as_fabric_msg_put(m); } return 0; } // end as_proxy_send_redirect()
/*---------------------------------------------------------------------------*/ static int raio_handle_submit(void *prv_session_data, void *prv_portal_data, struct raio_command *cmd, char *cmd_data, struct xio_msg *req) { struct raio_io_portal_data *pd = prv_portal_data; struct raio_io_session_data *sd = prv_session_data; struct raio_io_u *io_u; struct raio_iocb iocb; struct raio_answer ans; int retval; uint32_t is_last_in_batch; uint32_t msg_sz = SUBMIT_BLOCK_SIZE + sizeof(uint32_t); io_u = TAILQ_FIRST(&pd->io_u_free_list); if (!io_u) { printf("io_u_free_list empty\n"); errno = ENOSR; return -1; } TAILQ_REMOVE(&pd->io_u_free_list, io_u, io_u_list); msg_reset(io_u->rsp); pd->io_u_free_nr--; if (msg_sz != cmd->data_len) { retval = EINVAL; printf("io submit request rejected\n"); goto reject; } unpack_iocb(&iocb, unpack_u32(&is_last_in_batch, cmd_data)); io_u->iocmd.fd = iocb.raio_fildes; io_u->iocmd.op = iocb.raio_lio_opcode; io_u->iocmd.bcount = iocb.u.c.nbytes; io_u->iocmd.buf = io_u->rsp->out.data_iov[0].iov_base; io_u->iocmd.mr = io_u->rsp->out.data_iov[0].mr; io_u->iocmd.fsize = sd->fsize; io_u->iocmd.offset = iocb.u.c.offset; io_u->iocmd.is_last_in_batch = is_last_in_batch; io_u->iocmd.res = 0; io_u->iocmd.res2 = 0; io_u->iocmd.user_context = io_u; io_u->iocmd.comp_cb = on_cmd_submit_comp; io_u->rsp->request = req; io_u->rsp->user_context = io_u; io_u->rsp->out.data_iovlen = 1; /* issues request to bs */ retval = -raio_bs_cmd_submit(pd->bs_dev, &io_u->iocmd); if (retval) goto reject; return 0; reject: TAILQ_INSERT_TAIL(&pd->io_u_free_list, io_u, io_u_list); pd->io_u_free_nr++; msg_reset(&pd->rsp); ans.command = RAIO_CMD_IO_SUBMIT; ans.data_len = 0; ans.ret = -1; ans.ret_errno = retval; pack_u32((uint32_t *)&ans.ret_errno, pack_u32((uint32_t *)&ans.ret, pack_u32(&ans.data_len, pack_u32(&ans.command, pd->rsp_hdr)))); pd->rsp.out.header.iov_len = sizeof(struct raio_answer); pd->rsp.request = req; xio_send_response(&pd->rsp); return 0; }
bool repl_write_make_message(rw_request* rw, as_transaction* tr) { if (rw->dest_msg) { msg_reset(rw->dest_msg); } else if (! (rw->dest_msg = as_fabric_msg_get(M_TYPE_RW))) { return false; } as_namespace* ns = tr->rsv.ns; msg* m = rw->dest_msg; msg_set_uint32(m, RW_FIELD_OP, rw->is_multiop ? RW_OP_MULTI : RW_OP_WRITE); msg_set_buf(m, RW_FIELD_NAMESPACE, (uint8_t*)ns->name, strlen(ns->name), MSG_SET_COPY); msg_set_uint32(m, RW_FIELD_NS_ID, ns->id); msg_set_buf(m, RW_FIELD_DIGEST, (void*)&tr->keyd, sizeof(cf_digest), MSG_SET_COPY); msg_set_uint64(m, RW_FIELD_CLUSTER_KEY, tr->rsv.cluster_key); msg_set_uint32(m, RW_FIELD_TID, rw->tid); msg_set_uint32(m, RW_FIELD_GENERATION, tr->generation); msg_set_uint32(m, RW_FIELD_VOID_TIME, tr->void_time); msg_set_uint64(m, RW_FIELD_LAST_UPDATE_TIME, tr->last_update_time); // TODO - do we really intend to send this if the record is non-LDT? if (ns->ldt_enabled) { msg_set_buf(m, RW_FIELD_VINFOSET, (uint8_t*)&tr->rsv.p->version_info, sizeof(as_partition_vinfo), MSG_SET_COPY); if (tr->rsv.p->current_outgoing_ldt_version != 0) { msg_set_uint64(m, RW_FIELD_LDT_VERSION, tr->rsv.p->current_outgoing_ldt_version); } } if (rw->is_multiop) { msg_set_uint32(m, RW_FIELD_INFO, RW_INFO_LDT); msg_set_buf(m, RW_FIELD_MULTIOP, (void*)rw->pickled_buf, rw->pickled_sz, MSG_SET_HANDOFF_MALLOC); // Make sure destructor doesn't free this. rw->pickled_buf = NULL; return true; } uint32_t info = pack_info_bits(tr, rw->has_udf); if (rw->pickled_buf) { // Replica writes. bool is_sub; bool is_parent; as_ldt_get_property(&rw->pickled_rec_props, &is_parent, &is_sub); info |= pack_ldt_info_bits(tr, is_parent, is_sub); msg_set_buf(m, RW_FIELD_RECORD, (void*)rw->pickled_buf, rw->pickled_sz, MSG_SET_HANDOFF_MALLOC); // Make sure destructor doesn't free this. rw->pickled_buf = NULL; if (rw->pickled_rec_props.p_data) { msg_set_buf(m, RW_FIELD_REC_PROPS, rw->pickled_rec_props.p_data, rw->pickled_rec_props.size, MSG_SET_HANDOFF_MALLOC); // Make sure destructor doesn't free the data. as_rec_props_clear(&rw->pickled_rec_props); } } else { // Replica deletes. msg_set_buf(m, RW_FIELD_AS_MSG, (void*)tr->msgp, as_proto_size_get(&tr->msgp->proto), MSG_SET_COPY); info |= pack_ldt_info_bits(tr, false, false); } msg_set_uint32(m, RW_FIELD_INFO, info); return true; }