int citrusleaf_info(char *hostname, short port, char *names, char **values, int timeout_ms) { int rv = -1; cf_vector sockaddr_in_v; cf_vector_init(&sockaddr_in_v, sizeof( struct sockaddr_in ), 5, 0); if (0 != cl_lookup(NULL, hostname, port, &sockaddr_in_v)) { cf_debug("Could not find host %s", hostname); goto Done; } for (uint i=0; i < cf_vector_size(&sockaddr_in_v) ; i++) { struct sockaddr_in sa_in; cf_vector_get(&sockaddr_in_v, i, &sa_in); if (0 == citrusleaf_info_host(&sa_in, names, values, timeout_ms, false)) { rv = 0; goto Done; } } Done: cf_vector_destroy( &sockaddr_in_v ); return(rv); }
/* * Calls a scan on a particular node in the cluster with the given parameters and then applies * the udf on the results. It returns values from the udf. The callback is then applied on those values at the client. */ cl_rv citrusleaf_udf_scan_node(cl_cluster *asc, cl_scan *scan, char *node_name, int( *callback)(as_val *, void *), void * udata) { scan->udf.type = CL_SCAN_UDF_CLIENT_RECORD; cl_node_response resp; cl_rv rv = CITRUSLEAF_FAIL_CLIENT; // If cl_scan_execute returns a non null vector, return the value in the vector, else return a failure cf_vector *v = cl_scan_execute(asc, scan, node_name, &rv, callback, udata); if (v) { cf_vector_get(v, 0, &resp); rv = resp.node_response; cf_vector_destroy(v); } return rv; }
/* * Calls a scan on a specified node in the cluster. This function initializes a background scan. * The udf return values are not returned back to the client. */ cl_rv citrusleaf_udf_scan_node_background(cl_cluster * asc, cl_scan * scan, char *node_name) { scan->udf.type = CL_SCAN_UDF_BACKGROUND; cl_node_response resp; cl_rv rv = CITRUSLEAF_OK; // Call cl_scan_execute with a NULL node_name. cf_vector * v = cl_scan_execute(asc, scan, node_name, &rv, NULL, NULL); if (v) { cf_vector_get(v, 0, &resp); rv = resp.node_response; cf_vector_destroy(v); } return rv; }
static as_status process_node_response(cf_vector *v, as_error *err) { as_status rc = AEROSPIKE_OK; // This returns a vector of return values, the size of which is the size of the cluster int sz = cf_vector_size(v); cl_node_response resp; for(int i=0; i < sz; i++) { cf_vector_get(v, i, &resp); // Even if one of the node responded with an error, set the overall status as error if (resp.node_response != CITRUSLEAF_OK) { rc = as_error_fromrc(err, resp.node_response); } // Set the resp back to zero memset(&resp, 0, sizeof(cl_node_response)); } // Free the result vector cf_vector_destroy(v); return rc; }
int as_msg_make_response_bufbuilder(as_record *r, as_storage_rd *rd, cf_buf_builder **bb_r, bool nobindata, char *nsname, bool use_sets, bool include_key, cf_vector *binlist) { // Sanity checks. Either rd should be there or nobindata and nsname should be present. if (!(rd || (nobindata && nsname))) { cf_detail(AS_PROTO, "Neither storage record nor nobindata is set. Skipping the record."); return 0; } // figure out the size of the entire buffer int set_name_len = 0; const char *set_name = NULL; int ns_len = rd ? strlen(rd->ns->name) : strlen(nsname); if (use_sets && as_index_get_set_id(r) != INVALID_SET_ID) { as_namespace *ns = NULL; if (rd) { ns = rd->ns; } else if (nsname) { ns = as_namespace_get_byname(nsname); } if (!ns) { cf_info(AS_PROTO, "Cannot get namespace, needed to get set information. Skipping record."); return -1; } set_name = as_index_get_set_name(r, ns); if (set_name) { set_name_len = strlen(set_name); } } uint8_t* key = NULL; uint32_t key_size = 0; if (include_key && as_index_is_flag_set(r, AS_INDEX_FLAG_KEY_STORED)) { if (! as_storage_record_get_key(rd)) { cf_info(AS_PROTO, "can't get key - skipping record"); return -1; } key = rd->key; key_size = rd->key_size; } uint16_t n_fields = 2; int msg_sz = sizeof(as_msg); msg_sz += sizeof(as_msg_field) + sizeof(cf_digest); msg_sz += sizeof(as_msg_field) + ns_len; if (set_name) { n_fields++; msg_sz += sizeof(as_msg_field) + set_name_len; } if (key) { n_fields++; msg_sz += sizeof(as_msg_field) + key_size; } int list_bins = 0; int in_use_bins = 0; if (rd) { in_use_bins = as_bin_inuse_count(rd); } if (nobindata == false) { if(binlist) { int binlist_sz = cf_vector_size(binlist); for(uint16_t i = 0; i < binlist_sz; i++) { char binname[AS_ID_BIN_SZ]; cf_vector_get(binlist, i, (void*)&binname); cf_debug(AS_PROTO, " Binname projected inside is |%s| \n", binname); as_bin *p_bin = as_bin_get (rd, (uint8_t*)binname, strlen(binname)); if (!p_bin) { cf_debug(AS_PROTO, "To be projected bin |%s| not found \n", binname); continue; } cf_debug(AS_PROTO, "Adding bin |%s| to projected bins |%s| \n", binname); list_bins++; msg_sz += sizeof(as_msg_op); msg_sz += rd->ns->single_bin ? 0 : strlen(binname); uint32_t psz; if (as_bin_is_hidden(p_bin)) { psz = 0; } else { as_particle_tobuf(p_bin, 0, &psz); // get size } msg_sz += psz; } } else { msg_sz += sizeof(as_msg_op) * in_use_bins; // the bin headers for (uint16_t i = 0; i < in_use_bins; i++) { as_bin *p_bin = &rd->bins[i]; msg_sz += rd->ns->single_bin ? 0 : strlen(as_bin_get_name_from_id(rd->ns, p_bin->id)); uint32_t psz; if (as_bin_is_hidden(p_bin)) { psz = 0; } else { as_particle_tobuf(p_bin, 0, &psz); // get size } msg_sz += psz; } } } uint8_t *b; cf_buf_builder_reserve(bb_r, msg_sz, &b); // set up the header uint8_t *buf = b; as_msg *msgp = (as_msg *) buf; msgp->header_sz = sizeof(as_msg); msgp->info1 = (nobindata ? AS_MSG_INFO1_GET_NOBINDATA : 0); msgp->info2 = 0; msgp->info3 = 0; msgp->unused = 0; msgp->result_code = 0; msgp->generation = r->generation; msgp->record_ttl = r->void_time; msgp->transaction_ttl = 0; msgp->n_fields = n_fields; if (rd) { if (binlist) msgp->n_ops = list_bins; else msgp->n_ops = in_use_bins; } else { msgp->n_ops = 0; } as_msg_swap_header(msgp); buf += sizeof(as_msg); as_msg_field *mf = (as_msg_field *) buf; mf->field_sz = sizeof(cf_digest) + 1; mf->type = AS_MSG_FIELD_TYPE_DIGEST_RIPE; if (rd) { memcpy(mf->data, &rd->keyd, sizeof(cf_digest)); } else { memcpy(mf->data, &r->key, sizeof(cf_digest)); } as_msg_swap_field(mf); buf += sizeof(as_msg_field) + sizeof(cf_digest); mf = (as_msg_field *) buf; mf->field_sz = ns_len + 1; mf->type = AS_MSG_FIELD_TYPE_NAMESPACE; if (rd) { memcpy(mf->data, rd->ns->name, ns_len); } else { memcpy(mf->data, nsname, ns_len); } as_msg_swap_field(mf); buf += sizeof(as_msg_field) + ns_len; if (set_name) { mf = (as_msg_field *) buf; mf->field_sz = set_name_len + 1; mf->type = AS_MSG_FIELD_TYPE_SET; memcpy(mf->data, set_name, set_name_len); as_msg_swap_field(mf); buf += sizeof(as_msg_field) + set_name_len; } if (key) { mf = (as_msg_field *) buf; mf->field_sz = key_size + 1; mf->type = AS_MSG_FIELD_TYPE_KEY; memcpy(mf->data, key, key_size); as_msg_swap_field(mf); buf += sizeof(as_msg_field) + key_size; } if (nobindata) { goto Out; } if(binlist) { int binlist_sz = cf_vector_size(binlist); for(uint16_t i = 0; i < binlist_sz; i++) { char binname[AS_ID_BIN_SZ]; cf_vector_get(binlist, i, (void*)&binname); cf_debug(AS_PROTO, " Binname projected inside is |%s| \n", binname); as_bin *p_bin = as_bin_get (rd, (uint8_t*)binname, strlen(binname)); if (!p_bin) // should it be checked before ??? continue; as_msg_op *op = (as_msg_op *)buf; buf += sizeof(as_msg_op); op->op = AS_MSG_OP_READ; op->name_sz = as_bin_memcpy_name(rd->ns, op->name, p_bin); buf += op->name_sz; // Since there are two variable bits, the size is everything after // the data bytes - and this is only the head, we're patching up // the rest in a minute. op->op_sz = 4 + op->name_sz; if (as_bin_inuse(p_bin)) { op->particle_type = as_particle_type_convert(as_bin_get_particle_type(p_bin)); op->version = as_bin_get_version(p_bin, rd->ns->single_bin); uint32_t psz = msg_sz - (buf - b); // size remaining in buffer, for safety if (as_bin_is_hidden(p_bin)) { op->particle_type = AS_PARTICLE_TYPE_NULL; psz = 0; } else { if (0 != as_particle_tobuf(p_bin, buf, &psz)) { cf_warning(AS_PROTO, "particle to buf: could not copy data!"); } } buf += psz; op->op_sz += psz; } else { cf_debug(AS_PROTO, "Whoops !! bin not in use"); op->particle_type = AS_PARTICLE_TYPE_NULL; } as_msg_swap_op(op); } } else { // over all bins, copy into the buffer for (uint16_t i = 0; i < in_use_bins; i++) { as_msg_op *op = (as_msg_op *)buf; buf += sizeof(as_msg_op); op->op = AS_MSG_OP_READ; op->name_sz = as_bin_memcpy_name(rd->ns, op->name, &rd->bins[i]); buf += op->name_sz; // Since there are two variable bits, the size is everything after // the data bytes - and this is only the head, we're patching up // the rest in a minute. op->op_sz = 4 + op->name_sz; if (as_bin_inuse(&rd->bins[i])) { op->particle_type = as_particle_type_convert(as_bin_get_particle_type(&rd->bins[i])); op->version = as_bin_get_version(&rd->bins[i], rd->ns->single_bin); uint32_t psz = msg_sz - (buf - b); // size remaining in buffer, for safety if (as_bin_is_hidden(&rd->bins[i])) { op->particle_type = AS_PARTICLE_TYPE_NULL; psz = 0; } else { if (0 != as_particle_tobuf(&rd->bins[i], buf, &psz)) { cf_warning(AS_PROTO, "particle to buf: could not copy data!"); } } buf += psz; op->op_sz += psz; } else { op->particle_type = AS_PARTICLE_TYPE_NULL; } as_msg_swap_op(op); } } Out: return(0); }
// NB: this uses the same logic as the bufbuild function // as_msg_make_response_bufbuilder() but does not build a buffer and simply // returns sizing information. This is required for query runtime memory // accounting. // returns -1 in case of error // otherwise returns resize value size_t as_msg_response_msgsize(as_record *r, as_storage_rd *rd, bool nobindata, char *nsname, bool use_sets, cf_vector *binlist) { // Sanity checks. Either rd should be there or nobindata and nsname should be present. if (!(rd || (nobindata && nsname))) { cf_detail(AS_PROTO, "Neither storage record nor nobindata is set. Skipping the record."); return -1; } // figure out the size of the entire buffer int set_name_len = 0; const char *set_name = NULL; int ns_len = rd ? strlen(rd->ns->name) : strlen(nsname); if (use_sets && as_index_get_set_id(r) != INVALID_SET_ID) { as_namespace *ns = NULL; if (rd) { ns = rd->ns; } else if (nsname) { ns = as_namespace_get_byname(nsname); } if (!ns) { cf_info(AS_PROTO, "Cannot get namespace, needed to get set information. Skipping record."); return -1; } set_name = as_index_get_set_name(r, ns); if (set_name) { set_name_len = strlen(set_name); } } int msg_sz = sizeof(as_msg); msg_sz += sizeof(as_msg_field) + sizeof(cf_digest); msg_sz += sizeof(as_msg_field) + ns_len; if (set_name) { msg_sz += sizeof(as_msg_field) + set_name_len; } int in_use_bins = as_bin_inuse_count(rd); int list_bins = 0; if (nobindata == false) { if(binlist) { int binlist_sz = cf_vector_size(binlist); for(uint16_t i = 0; i < binlist_sz; i++) { char binname[AS_ID_BIN_SZ]; cf_vector_get(binlist, i, (void*)&binname); cf_debug(AS_PROTO, " Binname projected inside is |%s| \n", binname); as_bin *p_bin = as_bin_get (rd, (uint8_t*)binname, strlen(binname)); if (!p_bin) { cf_debug(AS_PROTO, "To be projected bin |%s| not found \n", binname); continue; } cf_debug(AS_PROTO, "Adding bin |%s| to projected bins |%s| \n", binname); list_bins++; msg_sz += sizeof(as_msg_op); msg_sz += rd->ns->single_bin ? 0 : strlen(binname); uint32_t psz; as_particle_tobuf(p_bin, 0, &psz); // get size msg_sz += psz; } } else { msg_sz += sizeof(as_msg_op) * in_use_bins; // the bin headers for (uint16_t i = 0; i < in_use_bins; i++) { as_bin *p_bin = &rd->bins[i]; msg_sz += rd->ns->single_bin ? 0 : strlen(as_bin_get_name_from_id(rd->ns, p_bin->id)); uint32_t psz; as_particle_tobuf(p_bin, 0, &psz); // get size msg_sz += psz; } } } return msg_sz; }
int as_msg_make_response_bufbuilder(as_record *r, as_storage_rd *rd, cf_buf_builder **bb_r, bool nobindata, char *nsname, bool include_ldt_data, bool include_key, bool skip_empty_records, cf_vector *binlist) { // Sanity checks. Either rd should be there or nobindata and nsname should be present. if (!(rd || (nobindata && nsname))) { cf_detail(AS_PROTO, "Neither storage record nor nobindata is set. Skipping the record."); return 0; } // figure out the size of the entire buffer int set_name_len = 0; const char *set_name = NULL; int ns_len = rd ? strlen(rd->ns->name) : strlen(nsname); if (as_index_get_set_id(r) != INVALID_SET_ID) { as_namespace *ns = NULL; if (rd) { ns = rd->ns; } else if (nsname) { ns = as_namespace_get_byname(nsname); } if (!ns) { cf_info(AS_PROTO, "Cannot get namespace, needed to get set information. Skipping record."); return -1; } set_name = as_index_get_set_name(r, ns); if (set_name) { set_name_len = strlen(set_name); } } uint8_t* key = NULL; uint32_t key_size = 0; if (include_key && as_index_is_flag_set(r, AS_INDEX_FLAG_KEY_STORED)) { if (! as_storage_record_get_key(rd)) { cf_info(AS_PROTO, "can't get key - skipping record"); return -1; } key = rd->key; key_size = rd->key_size; } uint16_t n_fields = 2; int msg_sz = sizeof(as_msg); msg_sz += sizeof(as_msg_field) + sizeof(cf_digest); msg_sz += sizeof(as_msg_field) + ns_len; if (set_name) { n_fields++; msg_sz += sizeof(as_msg_field) + set_name_len; } if (key) { n_fields++; msg_sz += sizeof(as_msg_field) + key_size; } int list_bins = 0; int in_use_bins = rd ? (int)as_bin_inuse_count(rd) : 0; as_val *ldt_bin_vals[in_use_bins]; if (! nobindata) { if (binlist) { int binlist_sz = cf_vector_size(binlist); for (uint16_t i = 0; i < binlist_sz; i++) { char binname[AS_ID_BIN_SZ]; cf_vector_get(binlist, i, (void*)&binname); as_bin *p_bin = as_bin_get(rd, binname); if (! p_bin) { continue; } msg_sz += sizeof(as_msg_op); msg_sz += rd->ns->single_bin ? 0 : strlen(binname); if (as_bin_is_hidden(p_bin)) { if (include_ldt_data) { msg_sz += (int)as_ldt_particle_client_value_size(rd, p_bin, &ldt_bin_vals[list_bins]); } else { ldt_bin_vals[list_bins] = NULL; } } else { msg_sz += (int)as_bin_particle_client_value_size(p_bin); } list_bins++; } // Don't return an empty record. if (skip_empty_records && list_bins == 0) { return 0; } } else { msg_sz += sizeof(as_msg_op) * in_use_bins; for (uint16_t i = 0; i < in_use_bins; i++) { as_bin *p_bin = &rd->bins[i]; msg_sz += rd->ns->single_bin ? 0 : strlen(as_bin_get_name_from_id(rd->ns, p_bin->id)); if (as_bin_is_hidden(p_bin)) { if (include_ldt_data) { msg_sz += (int)as_ldt_particle_client_value_size(rd, p_bin, &ldt_bin_vals[i]); } else { ldt_bin_vals[i] = NULL; } } else { msg_sz += (int)as_bin_particle_client_value_size(p_bin); } } } } uint8_t *b; cf_buf_builder_reserve(bb_r, msg_sz, &b); // set up the header uint8_t *buf = b; as_msg *msgp = (as_msg *) buf; msgp->header_sz = sizeof(as_msg); msgp->info1 = (nobindata ? AS_MSG_INFO1_GET_NOBINDATA : 0); msgp->info2 = 0; msgp->info3 = 0; msgp->unused = 0; msgp->result_code = 0; msgp->generation = r->generation; msgp->record_ttl = r->void_time; msgp->transaction_ttl = 0; msgp->n_fields = n_fields; if (rd) { if (binlist) msgp->n_ops = list_bins; else msgp->n_ops = in_use_bins; } else { msgp->n_ops = 0; } as_msg_swap_header(msgp); buf += sizeof(as_msg); as_msg_field *mf = (as_msg_field *) buf; mf->field_sz = sizeof(cf_digest) + 1; mf->type = AS_MSG_FIELD_TYPE_DIGEST_RIPE; if (rd) { memcpy(mf->data, &rd->keyd, sizeof(cf_digest)); } else { memcpy(mf->data, &r->key, sizeof(cf_digest)); } as_msg_swap_field(mf); buf += sizeof(as_msg_field) + sizeof(cf_digest); mf = (as_msg_field *) buf; mf->field_sz = ns_len + 1; mf->type = AS_MSG_FIELD_TYPE_NAMESPACE; if (rd) { memcpy(mf->data, rd->ns->name, ns_len); } else { memcpy(mf->data, nsname, ns_len); } as_msg_swap_field(mf); buf += sizeof(as_msg_field) + ns_len; if (set_name) { mf = (as_msg_field *) buf; mf->field_sz = set_name_len + 1; mf->type = AS_MSG_FIELD_TYPE_SET; memcpy(mf->data, set_name, set_name_len); as_msg_swap_field(mf); buf += sizeof(as_msg_field) + set_name_len; } if (key) { mf = (as_msg_field *) buf; mf->field_sz = key_size + 1; mf->type = AS_MSG_FIELD_TYPE_KEY; memcpy(mf->data, key, key_size); as_msg_swap_field(mf); buf += sizeof(as_msg_field) + key_size; } if (nobindata) { return 0; } if (binlist) { list_bins = 0; int binlist_sz = cf_vector_size(binlist); for (uint16_t i = 0; i < binlist_sz; i++) { char binname[AS_ID_BIN_SZ]; cf_vector_get(binlist, i, (void*)&binname); as_bin *p_bin = as_bin_get(rd, binname); if (! p_bin) { continue; } as_msg_op *op = (as_msg_op *)buf; op->op = AS_MSG_OP_READ; op->version = 0; op->name_sz = as_bin_memcpy_name(rd->ns, op->name, p_bin); op->op_sz = 4 + op->name_sz; buf += sizeof(as_msg_op) + op->name_sz; if (as_bin_is_hidden(p_bin)) { buf += as_ldt_particle_to_client(ldt_bin_vals[list_bins], op); } else { buf += as_bin_particle_to_client(p_bin, op); } list_bins++; as_msg_swap_op(op); } } else { for (uint16_t i = 0; i < in_use_bins; i++) { as_msg_op *op = (as_msg_op *)buf; op->op = AS_MSG_OP_READ; op->version = 0; op->name_sz = as_bin_memcpy_name(rd->ns, op->name, &rd->bins[i]); op->op_sz = 4 + op->name_sz; buf += sizeof(as_msg_op) + op->name_sz; if (as_bin_is_hidden(&rd->bins[i])) { buf += as_ldt_particle_to_client(ldt_bin_vals[i], op); } else { buf += as_bin_particle_to_client(&rd->bins[i], op); } as_msg_swap_op(op); } } return 0; }