// Authenticate connection and request the info of a particular sockaddr_in. // Return 0 on success. int citrusleaf_info_host_auth(as_cluster* cluster, struct sockaddr_in *sa_in, char *names, char **values, int timeout_ms, bool send_asis, bool check_bounds) { int fd = cf_socket_create_and_connect_nb(sa_in); if (fd == -1) { return CITRUSLEAF_FAIL_UNAVAILABLE; } if (cluster->user) { int status = as_authenticate(fd, cluster->user, cluster->password, timeout_ms); if (status) { cf_error("Authentication failed for %s", cluster->user); cf_close(fd); return status; } } int rv = citrusleaf_info_host_limit(fd, names, values, timeout_ms, send_asis, 0, check_bounds); shutdown(fd, SHUT_RDWR); cf_close(fd); if (rv == 0 && strncmp(*values, "security error", 14) == 0) { cf_error("%s", *values); free(*values); return CITRUSLEAF_NOT_AUTHENTICATED; } return rv; }
void as_node_destroy(as_node* node) { // Drain out the queue and close the FDs int rv; do { int fd; rv = cf_queue_pop(node->conn_q, &fd, CF_QUEUE_NOWAIT); if (rv == CF_QUEUE_OK) cf_close(fd); } while (rv == CF_QUEUE_OK); /* do { int fd; rv = cf_queue_pop(node->conn_q_asyncfd, &fd, CF_QUEUE_NOWAIT); if (rv == CF_QUEUE_OK) cf_close(fd); } while (rv == CF_QUEUE_OK); */ /* do { //When we reach this point, ideally there should not be any workitems. cl_async_work *aw; rv = cf_queue_pop(node->asyncwork_q, &aw, CF_QUEUE_NOWAIT); if (rv == CF_QUEUE_OK) { free(aw); } } while (rv == CF_QUEUE_OK); //We want to delete all the workitems of this node if (g_cl_async_hashtab) { shash_reduce_delete(g_cl_async_hashtab, cl_del_node_asyncworkitems, node); } */ as_vector_destroy(&node->addresses); cf_queue_destroy(node->conn_q); //cf_queue_destroy(node->conn_q_asyncfd); //cf_queue_destroy(node->asyncwork_q); if (node->info_fd >= 0) { cf_close(node->info_fd); } cf_free(node); }
static void as_node_close_info_connection(as_node* node) { shutdown(node->info_fd, SHUT_RDWR); cf_close(node->info_fd); node->info_fd = -1; }
static void readTrace(struct tr *tr, char *names, value * covPtr) { struct cfile *cf; int nSelect; T_TESTLIST *selectList; int i; value cov; nSelect = 0; /* No tests seen so far. */ /* * Read trace data and create selectList. */ cf = (struct cfile *) cf_openIn(tr->traces[0]); if (cf == NULL) { fprintf(stderr, "can't open %s\n", tr->traces[0]); exit(1); } selectList = NULL; trace_data(cf, tr->traces[0], tr->mod, tr->n_static, tr->covCount, tr->options, names, &selectList, &nSelect); cf_close(cf); if (nSelect == 1) { covThreshold(selectList[0].cov, tr->covCount, tr->threshold); if (tr->weaker) { covWeaker(tr->mod, tr->n_static, selectList[0].cov, tr->options); } *covPtr = selectList[0].cov; free(selectList); } else { if (nSelect > 1) { fprintf(stderr, "%d: Huh? nSelect should be 1\n", nSelect); exit(1); } if (selectList != NULL) { fprintf(stderr, "Warning: selectList not NULL\n"); selectList = NULL; } cov = (value) malloc((size_t) tr->covCount * sizeof *cov); if (cov == NULL) { fprintf(stderr, "Can't malloc\n"); exit(1); } for (i = 0; i < tr->covCount; ++i) cov[i] = 0; *covPtr = cov; } return; }
cf_void SetProcessDaemon() { cf_int i,fd0,fd1,fd2; pid_t pid; struct rlimit rl; cf_umask(0); if(cf_getrlimit(RLIMIT_NOFILE,&rl)<0) { printf("Can't get file limit! errno=%d.file:%s,function:%s,line:%d.\n", cf_int(errno),__FILE__,__PRETTY_FUNCTION__,__LINE__); cf_exit(1); } if ((pid=cf_fork())<0) { printf("Can't fork! errno=%d.file:%s,function:%s,line:%d.\n",cf_int(errno), __FILE__,__PRETTY_FUNCTION__,__LINE__); cf_exit(1); } else if(pid != 0) // parent will exit normally. { cf_exit(0); } cf_setsid(); if ((pid=cf_fork())<0) { printf("Can't fork!! errno=%d.file:%s,function:%s,line:%d.\n",cf_int(errno), __FILE__,__PRETTY_FUNCTION__,__LINE__); exit(1); } else if (pid!=0) { cf_exit(0); } if (cf_chdir("/tmp")<0) { printf("Can't change directory to /tmp! errno=%d.file:%s,function:%s,line:%d.\n", cf_int(errno),__FILE__,__PRETTY_FUNCTION__,__LINE__); cf_exit(1); } if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max =1024; for (i=0; i < cf_int(rl.rlim_max); i++) cf_close(i); fd0 =cf_open("/dev/null",O_RDWR,0); fd1 =cf_dup(0); fd2 =cf_dup(0); }
static int as_read_users(aerospike* as, const as_policy_admin* policy, uint8_t* buffer, uint8_t* end, as_vector* /*<as_user_roles*>*/ users) { int timeout_ms = (policy)? policy->timeout : as->config.policies.admin.timeout; if (timeout_ms <= 0) { timeout_ms = DEFAULT_TIMEOUT; } uint64_t deadline_ms = cf_getms() + timeout_ms; as_node* node = as_node_get_random(as->cluster); if (! node) { return CITRUSLEAF_FAIL_CLIENT; } int fd; int status = as_node_get_connection(node, &fd); if (status) { as_node_release(node); return status; } if (as_send(fd, buffer, end, deadline_ms, timeout_ms)) { cf_close(fd); as_node_release(node); return CITRUSLEAF_FAIL_TIMEOUT; } status = as_read_user_blocks(fd, buffer, deadline_ms, timeout_ms, users); if (status >= 0) { as_node_put_connection(node, fd); } else { cf_close(fd); } as_node_release(node); return status; }
PosixShM::~PosixShM() { if(_autoUnlink) { if( 0!=cf_shm_unlink(_name.c_str()) ) ;//_THROW(SyscallExecuteError, "Failed to execute cf_shm_unlink !") } if(_autoClose) { if( 0!=cf_close(_fd) ) ;//_THROW(SyscallExecuteError, "Failed to execute cf_close !") } }
static int as_execute(aerospike* as, const as_policy_admin* policy, uint8_t* buffer, uint8_t* end) { int timeout_ms = (policy)? policy->timeout : as->config.policies.admin.timeout; if (timeout_ms <= 0) { timeout_ms = DEFAULT_TIMEOUT; } uint64_t deadline_ms = cf_getms() + timeout_ms; as_node* node = as_node_get_random(as->cluster); if (! node) { return CITRUSLEAF_FAIL_CLIENT; } int fd; int status = as_node_get_connection(node, &fd); if (status) { as_node_release(node); return status; } if (as_send(fd, buffer, end, deadline_ms, timeout_ms)) { cf_close(fd); as_node_release(node); return CITRUSLEAF_FAIL_TIMEOUT; } if (cf_socket_read_timeout(fd, buffer, HEADER_SIZE, deadline_ms, timeout_ms)) { cf_close(fd); as_node_release(node); return CITRUSLEAF_FAIL_TIMEOUT; } as_node_put_connection(node, fd); as_node_release(node); return buffer[RESULT_CODE]; }
static void dnd_merge_files(int in_file_count, char **in_filenames) { char *tmpname; cf_status_t merge_status; int err; /* merge the files in chonological order */ tmpname = NULL; merge_status = cf_merge_files(&tmpname, in_file_count, in_filenames, WTAP_FILE_PCAP, FALSE); if (merge_status != CF_OK) { /* merge failed */ g_free(tmpname); return; } cf_close(&cfile); /* Try to open the merged capture file. */ if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) { /* We couldn't open it; don't dismiss the open dialog box, just leave it around so that the user can, after they dismiss the alert box popped up for the open error, try again. */ g_free(tmpname); return; } g_free(tmpname); switch (cf_read(&cfile, FALSE)) { case CF_READ_OK: case CF_READ_ERROR: /* Just because we got an error, that doesn't mean we were unable to read any of the file; we handle what we could get from the file. */ break; case CF_READ_ABORTED: /* The user bailed out of re-reading the capture file; the capture file has been closed - just free the capture file name string and return (without changing the last containing directory). */ return; } }
static int as_node_authenticate_connection(as_node* node, int* fd) { as_cluster* cluster = node->cluster; if (cluster->user) { int status = as_authenticate(*fd, cluster->user, cluster->password, cluster->conn_timeout_ms); if (status) { cf_debug("Authentication failed for %s", cluster->user); cf_close(*fd); *fd = -1; return status; } } return 0; }
// Request the info of a particular sockaddr_in. // Used internally for host-crawling as well as supporting the external interface. // Return 0 on success and -1 on error. int citrusleaf_info_host(struct sockaddr_in *sa_in, char *names, char **values, int timeout_ms, bool send_asis, bool check_bounds) { // Actually doing a non-blocking connect int fd = cf_socket_create_and_connect_nb(sa_in); if (fd == -1) { return -1; } int rv = citrusleaf_info_host_limit(fd, names, values, timeout_ms, send_asis, 0, check_bounds); shutdown(fd, SHUT_RDWR); cf_close(fd); return rv; }
/* open the file corresponding to the given fileset entry */ static void fs_open_entry(fileset_entry *entry) { char *fname; int err; /* make a copy of the filename (cf_close will indirectly destroy it right now) */ fname = g_strdup(entry->fullname); /* close the old and open the new file */ cf_close(&cfile); if (cf_open(&cfile, fname, FALSE, &err) == CF_OK) { cf_read(&cfile, FALSE); } g_free(fname); }
/* ask the user to save current unsaved file, before opening the dnd file */ static void dnd_save_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data) { switch(btn) { case(ESD_BTN_SAVE): /* save file first */ file_save_as_cmd(after_save_open_dnd_file, data, FALSE); break; case(ESD_BTN_DONT_SAVE): cf_close(&cfile); dnd_open_file_cmd(data); break; case(ESD_BTN_CANCEL): break; default: g_assert_not_reached(); } }
static int as_node_create_connection(as_node* node, int* fd) { // Create a non-blocking socket. *fd = cf_socket_create_nb(); if (*fd == -1) { // Local problem - socket create failed. cf_debug("Socket create failed for %s", node->name); return CITRUSLEAF_FAIL_CLIENT; } // Try primary address. as_address* primary = as_vector_get(&node->addresses, node->address_index); if (cf_socket_start_connect_nb(*fd, &primary->addr) == 0) { // Connection started ok - we have our socket. return as_node_authenticate_connection(node, fd); } // Try other addresses. as_vector* addresses = &node->addresses; for (uint32_t i = 0; i < addresses->size; i++) { as_address* address = as_vector_get(addresses, i); // Address points into alias array, so pointer comparison is sufficient. if (address != primary) { if (cf_socket_start_connect_nb(*fd, &address->addr) == 0) { // Replace invalid primary address with valid alias. // Other threads may not see this change immediately. // It's just a hint, not a requirement to try this new address first. cf_debug("Change node address %s %s:%d", node->name, address->name, (int)cf_swap_from_be16(address->addr.sin_port)); ck_pr_store_32(&node->address_index, i); return as_node_authenticate_connection(node, fd); } } } // Couldn't start a connection on any socket address - close the socket. cf_info("Failed to connect: %s %s:%d", node->name, primary->name, (int)cf_swap_from_be16(primary->addr.sin_port)); cf_close(*fd); *fd = -1; return CITRUSLEAF_FAIL_UNAVAILABLE; }
int as_node_get_connection(as_node* node, int* fd) { //cf_queue* q = asyncfd ? node->conn_q_asyncfd : node->conn_q; cf_queue* q = node->conn_q; while (1) { int rv = cf_queue_pop(q, fd, CF_QUEUE_NOWAIT); if (rv == CF_QUEUE_OK) { int rv2 = is_connected(*fd); switch (rv2) { case CONNECTED: // It's still good. return 0; case CONNECTED_BADFD: // Local problem, don't try closing. cf_warn("Found bad file descriptor in queue: fd %d", *fd); break; case CONNECTED_NOT: // Can't use it - the remote end closed it. case CONNECTED_ERROR: // Some other problem, could have to do with remote end. default: cf_close(*fd); break; } } else if (rv == CF_QUEUE_EMPTY) { // We exhausted the queue. Try creating a fresh socket. return as_node_create_connection(node, fd); } else { cf_error("Bad return value from cf_queue_pop"); *fd = -1; return CITRUSLEAF_FAIL_CLIENT; } } }
void as_node_put_connection(as_node* node, int fd) { cf_queue *q = node->conn_q; if (! cf_queue_push_limit(q, &fd, 300)) { cf_close(fd); } /* if (asyncfd == true) { q = cn->conn_q_asyncfd; // Async queue is used by XDS. It can open lot of connections // depending on batch-size. Dont worry about limiting the pool. cf_queue_push(q, &fd); } else { q = cn->conn_q; if (! cf_queue_push_limit(q, &fd, 300)) { cf_close(fd); } }*/ }
/* capture child closed its side of the pipe, do the required cleanup */ void capture_input_closed(capture_session *cap_session, gchar *msg) { capture_options *capture_opts = cap_session->capture_opts; int err; int packet_count_save; g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture stopped!"); g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING); if (msg != NULL) simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", msg); if(cap_session->state == CAPTURE_PREPARING) { /* We didn't start a capture; note that the attempt to start it failed. */ capture_callback_invoke(capture_cb_capture_failed, cap_session); } else { /* We started a capture; process what's left of the capture file if we were in "update list of packets in real time" mode, or process all of it if we weren't. */ if(capture_opts->real_time_mode) { cf_read_status_t status; /* Read what remains of the capture file. */ status = cf_finish_tail((capture_file *)cap_session->cf, &err); /* XXX: If -Q (quit-after-cap) then cf->count clr'd below so save it first */ packet_count_save = cf_get_packet_count((capture_file *)cap_session->cf); /* Tell the GUI we are not doing a capture any more. Must be done after the cf_finish_tail(), so file lengths are correctly displayed */ capture_callback_invoke(capture_cb_capture_update_finished, cap_session); /* Finish the capture. */ switch (status) { case CF_READ_OK: if ((packet_count_save == 0) && !capture_opts->restart) { simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "%sNo packets captured!%s\n" "\n" "As no data was captured, closing the %scapture file!\n" "\n" "\n" "Help about capturing can be found at:\n" "\n" " http://wiki.wireshark.org/CaptureSetup" #ifdef _WIN32 "\n\n" "Wireless (Wi-Fi/WLAN):\n" "Try to switch off promiscuous mode in the Capture Options!" #endif "", simple_dialog_primary_start(), simple_dialog_primary_end(), cf_is_tempfile((capture_file *)cap_session->cf) ? "temporary " : ""); cf_close((capture_file *)cap_session->cf); } break; case CF_READ_ERROR: /* Just because we got an error, that doesn't mean we were unable to read any of the file; we handle what we could get from the file. */ break; case CF_READ_ABORTED: /* Exit by leaving the main loop, so that any quit functions we registered get called. */ main_window_quit(); break; } } else { /* first of all, we are not doing a capture any more */ capture_callback_invoke(capture_cb_capture_fixed_finished, cap_session); /* this is a normal mode capture and if no error happened, read in the capture file data */ if(capture_opts->save_file != NULL) { capture_input_read_all(cap_session, cf_is_tempfile((capture_file *)cap_session->cf), cf_get_drops_known((capture_file *)cap_session->cf), cf_get_drops((capture_file *)cap_session->cf)); } } } if(capture_opts->show_info) capture_info_close(); cap_session->state = CAPTURE_STOPPED; /* if we couldn't open a capture file, there's nothing more for us to do */ if(capture_opts->save_file == NULL) { cf_close((capture_file *)cap_session->cf); return; } /* does the user wants to restart the current capture? */ if(capture_opts->restart) { capture_opts->restart = FALSE; ws_unlink(capture_opts->save_file); /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */ if(cf_is_tempfile((capture_file *)cap_session->cf)) { g_free(capture_opts->save_file); capture_opts->save_file = NULL; } /* ... and start the capture again */ if (capture_opts->ifaces->len == 0) { collect_ifaces(capture_opts); } /* close the currently loaded capture file */ cf_close((capture_file *)cap_session->cf); capture_start(capture_opts, cap_session); } else { /* We're not doing a capture any more, so we don't have a save file. */ g_free(capture_opts->save_file); capture_opts->save_file = NULL; } }
/* capture child tells us we have a new (or the first) capture file */ gboolean capture_input_new_file(capture_session *cap_session, gchar *new_file) { capture_options *capture_opts = cap_session->capture_opts; gboolean is_tempfile; int err; if(cap_session->state == CAPTURE_PREPARING) { g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "Capture started!"); } g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_MESSAGE, "File: \"%s\"", new_file); g_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING); /* free the old filename */ if(capture_opts->save_file != NULL) { /* we start a new capture file, close the old one (if we had one before). */ /* (we can only have an open capture file in real_time_mode!) */ if( ((capture_file *) cap_session->cf)->state != FILE_CLOSED) { if(capture_opts->real_time_mode) { capture_callback_invoke(capture_cb_capture_update_finished, cap_session); cf_finish_tail((capture_file *)cap_session->cf, &err); cf_close((capture_file *)cap_session->cf); } else { capture_callback_invoke(capture_cb_capture_fixed_finished, cap_session); } } g_free(capture_opts->save_file); is_tempfile = FALSE; cf_set_tempfile((capture_file *)cap_session->cf, FALSE); } else { /* we didn't have a save_file before; must be a tempfile */ is_tempfile = TRUE; cf_set_tempfile((capture_file *)cap_session->cf, TRUE); } /* save the new filename */ capture_opts->save_file = g_strdup(new_file); /* if we are in real-time mode, open the new file now */ if(capture_opts->real_time_mode) { /* Attempt to open the capture file and set up to read from it. */ switch(cf_start_tail((capture_file *)cap_session->cf, capture_opts->save_file, is_tempfile, &err)) { case CF_OK: break; case CF_ERROR: /* Don't unlink (delete) the save file - leave it around, for debugging purposes. */ g_free(capture_opts->save_file); capture_opts->save_file = NULL; return FALSE; } } else { capture_callback_invoke(capture_cb_capture_prepared, cap_session); } if(capture_opts->show_info) { if (!capture_info_new_file(new_file)) return FALSE; } if(capture_opts->real_time_mode) { capture_callback_invoke(capture_cb_capture_update_started, cap_session); } else { capture_callback_invoke(capture_cb_capture_fixed_started, cap_session); } cap_session->state = CAPTURE_RUNNING; return TRUE; }
/* We've succeeded in doing a (non real-time) capture; try to read it into a new capture file */ static gboolean capture_input_read_all(capture_session *cap_session, gboolean is_tempfile, gboolean drops_known, guint32 drops) { capture_options *capture_opts = cap_session->capture_opts; int err; /* Capture succeeded; attempt to open the capture file. */ if (cf_open((capture_file *)cap_session->cf, capture_opts->save_file, is_tempfile, &err) != CF_OK) { /* We're not doing a capture any more, so we don't have a save file. */ return FALSE; } /* Set the read filter to NULL. */ /* XXX - this is odd here; try to put it somewhere where it fits better */ cf_set_rfcode((capture_file *)cap_session->cf, NULL); /* Get the packet-drop statistics. XXX - there are currently no packet-drop statistics stored in libpcap captures, and that's what we're reading. At some point, we will add support in Wiretap to return packet-drop statistics for capture file formats that store it, and will make "cf_read()" get those statistics from Wiretap. We clear the statistics (marking them as "not known") in "cf_open()", and "cf_read()" will only fetch them and mark them as known if Wiretap supplies them, so if we get the statistics now, after calling "cf_open()" but before calling "cf_read()", the values we store will be used by "cf_read()". If a future libpcap capture file format stores the statistics, we'll put them into the capture file that we write, and will thus not have to set them here - "cf_read()" will get them from the file and use them. */ if (drops_known) { cf_set_drops_known((capture_file *)cap_session->cf, TRUE); /* XXX - on some systems, libpcap doesn't bother filling in "ps_ifdrop" - it doesn't even set it to zero - so we don't bother looking at it. Ideally, libpcap would have an interface that gave us several statistics - perhaps including various interface error statistics - and would tell us which of them it supplies, allowing us to display only the ones it does. */ cf_set_drops((capture_file *)cap_session->cf, drops); } /* read in the packet data */ switch (cf_read((capture_file *)cap_session->cf, FALSE)) { case CF_READ_OK: case CF_READ_ERROR: /* Just because we got an error, that doesn't mean we were unable to read any of the file; we handle what we could get from the file. */ break; case CF_READ_ABORTED: /* User wants to quit program. Exit by leaving the main loop, so that any quit functions we registered get called. */ main_window_nested_quit(); return FALSE; } /* if we didn't capture even a single packet, close the file again */ if(cf_get_packet_count((capture_file *)cap_session->cf) == 0 && !capture_opts->restart) { simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "%sNo packets captured!%s\n" "\n" "As no data was captured, closing the %scapture file!\n" "\n" "\n" "Help about capturing can be found at:\n" "\n" " http://wiki.wireshark.org/CaptureSetup" #ifdef _WIN32 "\n\n" "Wireless (Wi-Fi/WLAN):\n" "Try to switch off promiscuous mode in the Capture Options!" #endif "", simple_dialog_primary_start(), simple_dialog_primary_end(), (cf_is_tempfile((capture_file *)cap_session->cf)) ? "temporary " : ""); cf_close((capture_file *)cap_session->cf); } return TRUE; }
cf_void Clean() { cf_fsync(_fd); cf_close(_fd); cf_unlink(_filePathName.c_str()); }
//Same as do_the_full_monte, but only till the command is sent to the node. //Most of the code is duplicated. Bad. int cl_do_async_monte(cl_cluster *asc, int info1, int info2, const char *ns, const char *set, const cl_object *key, const cf_digest *digest, cl_bin **values, cl_operator operator, cl_operation **operations, int *n_values, uint32_t *cl_gen, const cl_write_parameters *cl_w_p, uint64_t *trid, void *udata) { cl_async_work *workitem = NULL; uint8_t wr_stack_buf[STACK_BUF_SZ]; uint8_t *wr_buf = wr_stack_buf; size_t wr_buf_sz = sizeof(wr_stack_buf); int progress_timeout_ms; uint64_t deadline_ms; uint64_t starttime, endtime; bool network_error; int fd = -1; int rv = CITRUSLEAF_FAIL_CLIENT; //Assume that this is a failure; // as_msg msg; cf_digest d_ret; cl_cluster_node *node = 0; #if ONEASYNCFD if (shash_get_size(g_cl_async_hashtab) >= g_async_h_szlimit) { //cf_error("Async hashtab is full. Cannot insert any more elements"); return CITRUSLEAF_FAIL_ASYNCQ_FULL; } #else //If the async buffer is at the max limit, do not entertain more requests. if (cf_queue_sz(g_cl_async_q) >= cf_atomic32_get(g_async_q_szlimit)) { //cf_error("Async buffer is full. Cannot insert any more elements"); return CITRUSLEAF_FAIL_ASYNCQ_FULL; } #endif //Allocate memory for work item that will be added to the async work list if (cf_queue_sz(g_cl_workitems_freepool_q) > 0) { cf_queue_pop(g_cl_workitems_freepool_q, &workitem, CF_QUEUE_FOREVER); } else { workitem = malloc(sizeof(cl_async_work)); if (workitem == NULL) { return CITRUSLEAF_FAIL_CLIENT; } } //Compile the write buffer to be sent to the cluster if (n_values && ( values || operations) ){ cl_compile(info1, info2, 0, ns, set, key, digest, values?*values:NULL, operator, operations?*operations:NULL, *n_values , &wr_buf, &wr_buf_sz, cl_w_p, &d_ret, *trid,NULL,NULL, 0 /*udf_type*/); }else{ cl_compile(info1, info2, 0, ns, set, key, digest, 0, 0, 0, 0, &wr_buf, &wr_buf_sz, cl_w_p, &d_ret, *trid,NULL,NULL, 0 /*udf_type*/); } deadline_ms = 0; progress_timeout_ms = 0; if (cl_w_p && cl_w_p->timeout_ms) { deadline_ms = cf_getms() + cl_w_p->timeout_ms; // policy: if asking for a long timeout, give enough time to try twice if (cl_w_p->timeout_ms > 700) { progress_timeout_ms = cl_w_p->timeout_ms / 2; } else { progress_timeout_ms = cl_w_p->timeout_ms; } } else { progress_timeout_ms = g_async_nw_progress_timeout; } //Initialize the async work unit workitem->trid = *trid; workitem->deadline = deadline_ms; workitem->starttime = cf_getms(); workitem->udata = udata; as_msg *msgp; // Hate special cases, but we have to clear the verify bit on delete verify if ( (info2 & CL_MSG_INFO2_DELETE) && (info1 & CL_MSG_INFO1_VERIFY)) { msgp = (as_msg *)wr_buf; msgp->m.info1 &= ~CL_MSG_INFO1_VERIFY; } if (asc->compression_stat.compression_threshold > 0 && wr_buf_sz > (size_t)asc->compression_stat.compression_threshold) { /* Compression is enabled. * Packet size is above threshold. * Compress the data */ uint8_t *compressed_buf = NULL; size_t compressed_buf_sz = 0; // Contstruct packet for compressed data. cf_packet_compression (wr_buf, wr_buf_sz, &compressed_buf, &compressed_buf_sz); if (compressed_buf) { // If original packet size is > 16k, cl_compile had allocated memory for it. // Free that memory. // cf_packet_compression will allocate memory for compressed packet if (wr_buf != wr_stack_buf) { free(wr_buf); } // Update stats. citrusleaf_cluster_put_compression_stat(asc, wr_buf_sz, compressed_buf_sz); wr_buf = compressed_buf; wr_buf_sz = compressed_buf_sz; //memcpy (wr_buf, compressed_buf, compressed_buf_sz); //wr_buf_sz = compressed_buf_sz; //free (compressed_buf); } //else compression failed, continue with uncompressed packet else { // Set compression stat citrusleaf_cluster_put_compression_stat(asc, wr_buf_sz, wr_buf_sz); } } int try = 0; // retry request based on the write_policy do { network_error = false; try++; #ifdef DEBUG if (try > 1) { cf_debug("request retrying try %d tid %zu", try, (uint64_t)pthread_self()); } #endif // Get an FD from a cluster. First get the probable node for the given digest. node = cl_cluster_node_get(asc, ns, &d_ret, info2 & CL_MSG_INFO2_WRITE ? true : false); if (!node) { #ifdef DEBUG cf_debug("warning: no healthy nodes in cluster, retrying"); #endif usleep(10000); //Sleep for 10ms goto Retry; } // Now get the dedicated async FD of this node starttime = cf_getms(); fd = cl_cluster_node_fd_get(node, true); endtime = cf_getms(); if ((endtime - starttime) > 10) { cf_debug("Time to get FD for a node (>10ms)=%"PRIu64, (endtime - starttime)); } if (fd == -1) { #ifdef DEBUG cf_debug("warning: node %s has no async file descriptors, retrying transaction (tid %zu)",node->name,(uint64_t)pthread_self() ); #endif usleep(1000); goto Retry; } // Send the command to the node starttime = cf_getms(); rv = cf_socket_write_timeout(fd, wr_buf, wr_buf_sz, deadline_ms, progress_timeout_ms); endtime = cf_getms(); if ((endtime - starttime) > 10) { cf_debug("Time to write to the socket (>10ms)=%"PRIu64, (endtime - starttime)); } if (rv != 0) { cf_debug("Citrusleaf: write timeout or error when writing header to server - %d fd %d errno %d (tid %zu)", rv,fd,errno,(uint64_t)pthread_self()); if (rv != ETIMEDOUT) network_error = true; goto Retry; } goto Ok; Retry: if (network_error == true) { /* * In case of Async work (for XDS), it may be extreme to * dun a node in case of network error. We just cleanup * things and retry to connect to the remote cluster. * The network error may be a transient one. As this is a * network error, its is better to wait for some significant * time before retrying. */ sleep(1); //Sleep for 1sec #if ONEASYNCFD //Do not close the FD #else cf_error("async sender: Closing the fd %d because of network error", fd); cf_close(fd); fd = -1; #endif } if (fd != -1) { cf_error("async sender: Closing the fd %d because of retry", fd); cf_close(fd); fd = -1; } if (node) { cl_cluster_node_put(node); node = 0; } if (deadline_ms && (deadline_ms < cf_getms() ) ) { #ifdef DEBUG cf_debug("async sender: out of time : deadline %"PRIu64" now %"PRIu64, deadline_ms, cf_getms()); #endif rv = CITRUSLEAF_FAIL_TIMEOUT; goto Error; } } while ( (cl_w_p == 0) || (cl_w_p->w_pol == CL_WRITE_RETRY) ); Error: #ifdef DEBUG cf_debug("exiting with failure: network_error %d wpol %d timeleft %d rv %d", (int)network_error, (int)(cl_w_p ? cl_w_p->w_pol : 0), (int)(deadline_ms - cf_getms() ), rv ); #endif if (wr_buf != wr_stack_buf) { free(wr_buf); } #if ONEASYNCFD //Do not close the FD #else //If it is a network error, the fd would be closed and set to -1. //So, we reach this place with a valid FD in case of timeout. if (fd != -1) { cf_error("async sender: Closing the fd %d because of timeout", fd); cf_close(fd); } #endif return(rv); Ok: /* * We cannot release the node here as the asyc FD associated * with this node may get closed. We should do it only when * we got back the ack for the async command that we just did. */ //As we sent the command successfully, add it to the async work list workitem->node = node; workitem->fd = fd; //We are storing only the pointer to the workitem #if ONEASYNCFD if (shash_put_unique(g_cl_async_hashtab, trid, &workitem) != SHASH_OK) { //This should always succeed. cf_error("Unable to add unique entry into the hash table"); } cf_queue_push(node->asyncwork_q, &workitem); //Also put in the node's q #else cf_queue_push(g_cl_async_q, &workitem); #endif if (wr_buf != wr_stack_buf) { free(wr_buf); } rv = CITRUSLEAF_OK; return rv; } int citrusleaf_async_reinit(int size_limit, unsigned int num_receiver_threads) { // int num_threads; if (0 == cf_atomic32_get(g_async_initialized)) { cf_error("Async client not initialized cannot reinit"); return -1; } if (num_receiver_threads > MAX_ASYNC_RECEIVER_THREADS) { //Limit the threads to the max value even if caller asks for it num_receiver_threads = MAX_ASYNC_RECEIVER_THREADS; } // If number of thread is increased create more threads if (num_receiver_threads > g_async_num_threads) { unsigned int i; for (i = g_async_num_threads; i < num_receiver_threads; i++) { pthread_create(&g_async_reciever[i], 0, async_receiver_fn, NULL); } } else { // else just reset the number the async threads will kill themselves cf_atomic32_set(&g_async_num_threads, num_receiver_threads); } cf_atomic32_set(&g_async_q_szlimit , size_limit); return ( 0 ); } int citrusleaf_async_init(int size_limit, int num_receiver_threads, cl_async_fail_cb fail_cb_fn, cl_async_success_cb success_cb_fn) { int i, num_threads; //Make sure that we do the initialization only once if (1 == cf_atomic32_incr(&g_async_initialized)) { // Start the receiver threads num_threads = num_receiver_threads; if (num_threads > MAX_ASYNC_RECEIVER_THREADS) { //Limit the threads to the max value even if caller asks for it num_threads = MAX_ASYNC_RECEIVER_THREADS; } #if ONEASYNCFD g_async_h_szlimit = size_limit * 3; //Max number of elements in the hash table g_async_h_buckets = g_async_h_szlimit/10;//Number of buckets in the hash table if (shash_create(&g_cl_async_hashtab, async_trid_hash, sizeof(uint64_t), sizeof(cl_async_work *), g_async_h_buckets, SHASH_CR_MT_BIGLOCK) != SHASH_OK) { cf_error("Failed to initialize the async work hastable"); cf_atomic32_decr(&g_async_initialized); return -1; } #else // create work queue g_async_q_szlimit = size_limit; if ((g_cl_async_q = cf_queue_create(sizeof(cl_async_work *), true)) == NULL) { cf_error("Failed to initialize the async work queue"); cf_atomic32_decr(&g_async_initialized); return -1; } for (i=0; i<num_threads; i++) { pthread_create(&g_async_reciever[i], 0, async_receiver_fn, NULL); } g_async_num_threads = num_threads; #endif if ((g_cl_workitems_freepool_q = cf_queue_create(sizeof(cl_async_work *), true)) == NULL) { cf_error("Failed to create memory pool for workitems"); return -1; } g_fail_cb_fn = fail_cb_fn; g_success_cb_fn = success_cb_fn; // Initialize the stats g_async_stats.retries = 0; g_async_stats.dropouts = 0; } return(0); }
cf_void PosixShM::Close() { if( 0!=cf_close(_fd) ) _THROW(SyscallExecuteError, "Failed to execute cf_close !"); }
static void* async_receiver_fn(void *thdata) { int rv = -1; bool network_error = false; cl_async_work *workitem = NULL; // cl_async_work *tmpworkitem = NULL; as_msg msg; cf_queue *q_to_use = NULL; cl_cluster_node *thisnode = NULL; uint8_t rd_stack_buf[STACK_BUF_SZ]; uint8_t *rd_buf = rd_stack_buf; size_t rd_buf_sz = 0; uint64_t acktrid; // uint64_t starttime, endtime; int progress_timeout_ms; unsigned int thread_id = cf_atomic32_incr(&g_thread_count); if (thdata == NULL) { q_to_use = g_cl_async_q; } else { thisnode = (cl_cluster_node *)thdata; q_to_use = thisnode->asyncwork_q; } //Infinite loop which keeps picking work items from the list and try to find the end result while(1) { network_error = false; #if ONEASYNCFD if(thisnode->dunned == true) { do { rv = cf_queue_pop(thisnode->asyncwork_q, &workitem, CF_QUEUE_NOWAIT); if (rv == CF_QUEUE_OK) { cl_cluster_node_put(thisnode); free(workitem); } } while (rv == CF_QUEUE_OK); //We want to delete all the workitems of this node shash_reduce_delete(g_cl_async_hashtab, cl_del_node_asyncworkitems, thisnode); break; } #endif //This call will block if there is no element in the queue cf_queue_pop(q_to_use, &workitem, CF_QUEUE_FOREVER); //TODO: What if the node gets dunned while this pop call is blocked ? #if ONEASYNCFD //cf_debug("Elements remaining in this node's queue=%d, Hash table size=%d", // cf_queue_sz(thisnode->asyncwork_q), shash_get_size(g_cl_async_hashtab)); #endif // If we have no progress in 50ms, we should move to the next workitem // and revisit this workitem at a later stage progress_timeout_ms = DEFAULT_PROGRESS_TIMEOUT; // Read into this fine cl_msg, which is the short header rv = cf_socket_read_timeout(workitem->fd, (uint8_t *) &msg, sizeof(as_msg), workitem->deadline, progress_timeout_ms); if (rv) { #if DEBUG cf_debug("Citrusleaf: error when reading header from server - rv %d fd %d", rv, workitem->fd); #endif if (rv != ETIMEDOUT) { cf_error("Citrusleaf: error when reading header from server - rv %d fd %d",rv,workitem->fd); network_error = true; goto Error; } else { goto Retry; } } #ifdef DEBUG_VERBOSE dump_buf("read header from cluster", (uint8_t *) &msg, sizeof(cl_msg)); #endif cl_proto_swap(&msg.proto); cl_msg_swap_header(&msg.m); // second read for the remainder of the message rd_buf_sz = msg.proto.sz - msg.m.header_sz; if (rd_buf_sz > 0) { if (rd_buf_sz > sizeof(rd_stack_buf)) { rd_buf = malloc(rd_buf_sz); if (!rd_buf) { cf_error("malloc fail: trying %zu",rd_buf_sz); rv = -1; goto Error; } } rv = cf_socket_read_timeout(workitem->fd, rd_buf, rd_buf_sz, workitem->deadline, progress_timeout_ms); if (rv) { //We already read some part of the message before but failed to read the //remaining data for whatever reason (network error or timeout). We cannot //reread as we already read partial data. Declare this as error. cf_error("Timeout after reading the header but before reading the body"); goto Error; } #ifdef DEBUG_VERBOSE dump_buf("read body from cluster", rd_buf, rd_buf_sz); #endif } rv = CITRUSLEAF_OK; goto Ok; Retry: //We are trying to postpone the reading if (workitem->deadline && workitem->deadline < cf_getms()) { cf_error("async receiver: out of time : deadline %"PRIu64" now %"PRIu64, workitem->deadline, cf_getms()); //cf_error("async receiver: Workitem missed the final deadline"); rv = CITRUSLEAF_FAIL_TIMEOUT; goto Error; } else { //We have time. Push the element back to the queue to be considered later cf_queue_push(q_to_use, &workitem); } //If we allocated memory in this loop, release it. if (rd_buf && (rd_buf != rd_stack_buf)) { free(rd_buf); } cf_atomic_int_incr(&g_async_stats.retries); continue; Error: if (network_error == true) { /* * In case of Async work (for XDS), it may be extreme to * dun a node in case of network error. We just cleanup * things and retry to connect to the remote cluster. * The network error may be a transient one. */ } #if ONEASYNCFD //Do not close FD #else //We do not know the state of FD. It may have pending data to be read. //We cannot reuse the FD. So, close it to be on safe side. cf_error("async receiver: Closing the fd %d because of error", workitem->fd); cf_close(workitem->fd); workitem->fd = -1; #endif cf_atomic_int_incr(&g_async_stats.dropouts); //Continue down with what we do during an Ok //Inform the caller that there is no response from the server for this workitem. //No response does not mean that the work is not done. The work might be //successfully completed on the server side, we just didnt get response for it. if (g_fail_cb_fn) { g_fail_cb_fn(workitem->udata, rv, workitem->starttime); } Ok: //rd_buf may not be there during an error condition. if (rd_buf && (rv == CITRUSLEAF_OK)) { //As of now, async functionality is there only for put call. //In put call, we do not get anything back other than the trid field. //So, just pass variable to get back the trid and ignore others. if (0 != cl_parse(&msg.m, rd_buf, rd_buf_sz, NULL, NULL, NULL, &acktrid, NULL)) { rv = CITRUSLEAF_FAIL_UNKNOWN; } else { rv = msg.m.result_code; if (workitem->trid != acktrid) { #if ONEASYNCFD //It is likely that we may get response for a different trid. //Just delete the correct one from the queue //put back the current workitem back in the queue. shash_get(g_cl_async_hashtab, &acktrid, &tmpworkitem); cf_queue_delete(q_to_use, &tmpworkitem, true); cf_queue_push(q_to_use, &workitem); //From now on workitem will be the one for which we got ack workitem = tmpworkitem; #endif #ifdef DEBUG cf_debug("Got reply for a different trid. Expected=%"PRIu64" Got=%"PRIu64" FD=%d", workitem->trid, acktrid, workitem->fd); #endif } } if (g_success_cb_fn) { g_success_cb_fn(workitem->udata, rv, workitem->starttime); } } //Remember to put back the FD into the pool, if it is re-usable. if (workitem->fd != -1) { cl_cluster_node_fd_put(workitem->node, workitem->fd, true); } //Also decrement the reference count for this node cl_cluster_node_put(workitem->node); #if ONEASYNCFD //Delete the item from the global hashtable if (shash_delete(g_cl_async_hashtab, &workitem->trid) != SHASH_OK) { #if DEBUG cf_debug("Failure while trying to delete trid=%"PRIu64" from hashtable", workitem->trid); #endif } #endif //Push it back into the free pool. If the attempt fails, free it. if (cf_queue_push(g_cl_workitems_freepool_q, &workitem) == -1) { free(workitem); } //If we allocated memory in this loop, release it. if (rd_buf && (rd_buf != rd_stack_buf)) { free(rd_buf); } // Kick this thread out if its ID is greater than total if (thread_id > cf_atomic32_get(g_async_num_threads)) { cf_atomic32_decr(&g_thread_count); return NULL; } }//The infnite loop return NULL; }
/* open/merge the dnd file */ void dnd_open_file_cmd(gchar *cf_names_freeme) { int err; gchar *cf_name; int in_file_count; int files_work; char **in_filenames; char *tmpname; if (cf_names_freeme == NULL) return; /* DND_TARGET_URL: * The cf_name_freeme is a single string, containing one or more URI's, * terminated by CR/NL chars. The length of the whole field can be found * in the selection_data->length field. If it contains one file, simply open it, * If it contains more than one file, ask to merge these files. */ /* count the number of input files */ cf_name = cf_names_freeme; for(in_file_count = 0; (cf_name = strstr(cf_name, "\r\n")) != NULL; ) { cf_name += 2; in_file_count++; } if (in_file_count == 0) { g_free(cf_names_freeme); return; } in_filenames = (char **)g_malloc(sizeof(char*) * in_file_count); /* store the starts of the file entries in a gchar array */ cf_name = cf_names_freeme; in_filenames[0] = cf_name; for(files_work = 1; (cf_name = strstr(cf_name, "\r\n")) != NULL && files_work < in_file_count; ) { cf_name += 2; in_filenames[files_work] = cf_name; files_work++; } /* replace trailing CR NL simply with zeroes (in place), so we get valid terminated strings */ cf_name = cf_names_freeme; g_strdelimit(cf_name, "\r\n", '\0'); /* convert all filenames from URI to local filename (in place) */ for(files_work = 0; files_work < in_file_count; files_work++) { in_filenames[files_work] = dnd_uri2filename(in_filenames[files_work]); } if (in_file_count == 1) { /* open and read the capture file (this will close an existing file) */ if (cf_open(&cfile, in_filenames[0], FALSE, &err) == CF_OK) { /* XXX - add this to the menu if the read fails? */ cf_read(&cfile, FALSE); add_menu_recent_capture_file(in_filenames[0]); } else { /* the capture file couldn't be read (doesn't exist, file format unknown, ...) */ } } else { /* merge the files in chronological order */ tmpname = NULL; if (cf_merge_files(&tmpname, in_file_count, in_filenames, WTAP_FILE_TYPE_SUBTYPE_PCAP, FALSE) == CF_OK) { /* Merge succeeded; close the currently-open file and try to open the merged capture file. */ cf_close(&cfile); if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) == CF_OK) { g_free(tmpname); cf_read(&cfile, FALSE); } else { /* The merged file couldn't be read. */ g_free(tmpname); } } else { /* merge failed */ g_free(tmpname); } } g_free(in_filenames); g_free(cf_names_freeme); }
cf_pvoid Run(void * p) { CF_PRINT_FUNC; int index =*((int *)p); cf_fd sockfd=g_vecSock[index]; // printf("index=%d,sockfd=%d \n",index,sockfd); ssize_t hasSent =0; ssize_t hasRecv =0; ssize_t shouldRecv =0; bool peerClosedWhenRead =false; cf_uint64 seconds =0; cf_uint32 useconds =0; cf::Gettimeofday(seconds, useconds); for(int k=0; k<g_times; k++) // send times { std::string & body =g_vecStr[k]; hasSent =0; bool succ =cf::SendSegmentSync(sockfd,body.c_str(), body.size(),hasSent,8000, body.size()); if(succ) { #if 1 fprintf(stderr,"tid=%u,Sent succeeded ! hasSent=%d ,k=%d ",TID,int(hasSent),k); fprintf(stderr,"tid=%u,buff=%s \n",TID,body.c_str()+HEADER_LEN); #endif } else fprintf(stderr,"tid=%u,Warning,Send timeout ! \n",TID); if(hasSent!=(cf_uint32)body.size()) fprintf(stderr,"tid=%u,Warning,Recved len{%u}!=body.size(){%u}! \n",TID, (cf_uint32)hasSent,(cf_uint32)(body.size())); peerClosedWhenRead =false; hasRecv =0; shouldRecv =hasSent-HEADER_LEN; succ =cf::RecvSegmentSync(sockfd,&g_bufrecv[0], shouldRecv,hasRecv, peerClosedWhenRead,8000); if(succ) { #if 1 fprintf(stderr,"tid=%u,Recv succeeded ! hasRecv=%d ,k=%d ,",TID,int(hasRecv),k); fprintf(stderr,"tid=%u,buff=%s \n",TID,g_bufrecv.c_str()); #endif } else fprintf(stderr,"tid=%u,Warning,Recv timeout ! \n",TID); if(hasRecv!=shouldRecv) fprintf(stderr, "tid=%u,Warning,Recved hasRecv{%u}!=shouldRecv{%u}! peerClosedWhenRead=%u \n", TID, (cf_uint32)hasRecv,(cf_uint32)shouldRecv,cf_uint32(peerClosedWhenRead)); } #if 1 fprintf(stderr,"tid=%u,cf_close!\n",TID); #endif cf_close(sockfd); return NULL; }