static void ctdb_run_startup(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); int ret; /* This is necessary to avoid the "startup" event colliding * with the "ipreallocated" event from the takeover run * following the first recovery. We might as well serialise * these things if we can. */ if (ctdb->runstate < CTDB_RUNSTATE_STARTUP) { DEBUG(DEBUG_NOTICE, ("Not yet in startup runstate. Wait one more second\n")); event_add_timed(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(1, 0), ctdb_run_startup, ctdb); return; } DEBUG(DEBUG_NOTICE,("Running the \"startup\" event.\n")); ret = ctdb_event_script_callback(ctdb, ctdb->monitor->monitor_context, ctdb_startup_callback, ctdb, CTDB_EVENT_STARTUP, "%s", ""); if (ret != 0) { DEBUG(DEBUG_ERR,("Unable to launch startup event script\n")); event_add_timed(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(5, 0), ctdb_run_startup, ctdb); } }
/* main program */ int main(int argc, const char *argv[]) { struct ctdb_context *ctdb; struct ctdb_db_context *ctdb_db; struct poptOption popt_options[] = { POPT_AUTOHELP POPT_CTDB_CMDLINE { "num-records", 'r', POPT_ARG_INT, &num_records, 0, "num_records", "integer" }, { "base-rec", 'b', POPT_ARG_INT, &base_rec, 0, "base_rec", "integer" }, { "delete-pct", 'p', POPT_ARG_INT, &delete_pct, 0, "delete_pct", "integer" }, POPT_TABLEEND }; int opt; const char **extra_argv; int extra_argc = 0; poptContext pc; struct event_context *ev; pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "Invalid option %s: %s\n", poptBadOption(pc, 0), poptStrerror(opt)); exit(1); } } /* setup the remaining options for the main program to use */ extra_argv = poptGetArgs(pc); if (extra_argv) { extra_argv++; while (extra_argv[extra_argc]) extra_argc++; } ev = event_context_init(NULL); ctdb = ctdb_cmdline_client(ev, timeval_current_ofs(3, 0)); if (ctdb == NULL) { printf("failed to connect to daemon\n"); exit(1); } /* attach to a specific database */ ctdb_db = ctdb_attach(ctdb, timeval_current_ofs(2, 0), "test.tdb", false, 0); if (!ctdb_db) { printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb)); exit(1); } store_records(ctdb, ev); return 0; }
static bool ldapsrv_call_read_next(struct ldapsrv_connection *conn) { struct tevent_req *subreq; if (timeval_is_zero(&conn->limits.endtime)) { conn->limits.endtime = timeval_current_ofs(conn->limits.initial_timeout, 0); } else { conn->limits.endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0); } /* * The minimun size of a LDAP pdu is 7 bytes * * dumpasn1 -hh ldap-unbind-min.dat * * <30 05 02 01 09 42 00> * 0 5: SEQUENCE { * <02 01 09> * 2 1: INTEGER 9 * <42 00> * 5 0: [APPLICATION 2] * : Error: Object has zero length. * : } * * dumpasn1 -hh ldap-unbind-windows.dat * * <30 84 00 00 00 05 02 01 09 42 00> * 0 5: SEQUENCE { * <02 01 09> * 6 1: INTEGER 9 * <42 00> * 9 0: [APPLICATION 2] * : Error: Object has zero length. * : } * * This means using an initial read size * of 7 is ok. */ subreq = tstream_read_pdu_blob_send(conn, conn->connection->event.ctx, conn->sockets.active, 7, /* initial_read_size */ ldap_full_packet, conn); if (subreq == NULL) { ldapsrv_terminate_connection(conn, "ldapsrv_call_read_next: " "no memory for tstream_read_pdu_blob_send"); return false; } tevent_req_set_endtime(subreq, conn->connection->event.ctx, conn->limits.endtime); tevent_req_set_callback(subreq, ldapsrv_call_read_done, conn); return true; }
/* see if the event scripts think we are healthy */ static void ctdb_check_health(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); int ret = 0; if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL || (ctdb->monitor->monitoring_mode == CTDB_MONITORING_DISABLED && ctdb->done_startup)) { event_add_timed(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(ctdb->monitor->next_interval, 0), ctdb_check_health, ctdb); return; } if (!ctdb->done_startup) { ret = ctdb_event_script_callback(ctdb, ctdb->monitor->monitor_context, ctdb_startup_callback, ctdb, false, CTDB_EVENT_STARTUP, "%s", ""); } else { int i; int skip_monitoring = 0; if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) { skip_monitoring = 1; DEBUG(DEBUG_ERR,("Skip monitoring during recovery\n")); } for (i=1; i<=NUM_DB_PRIORITIES; i++) { if (ctdb->freeze_handles[i] != NULL) { DEBUG(DEBUG_ERR,("Skip monitoring since databases are frozen\n")); skip_monitoring = 1; break; } } if (skip_monitoring != 0) { event_add_timed(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(ctdb->monitor->next_interval, 0), ctdb_check_health, ctdb); return; } else { ret = ctdb_event_script_callback(ctdb, ctdb->monitor->monitor_context, ctdb_health_callback, ctdb, false, CTDB_EVENT_MONITOR, "%s", ""); } } if (ret != 0) { DEBUG(DEBUG_ERR,("Unable to launch monitor event script\n")); ctdb->monitor->next_interval = 5; event_add_timed(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(5, 0), ctdb_check_health, ctdb); } }
/* complete an async reconnect */ static void reopen_connection_complete(struct composite_context *ctx) { struct benchopen_state *state = (struct benchopen_state *)ctx->async.private_data; NTSTATUS status; struct smb_composite_connect *io = &state->reconnect; status = smb_composite_connect_recv(ctx, state->mem_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(state->te); state->te = event_add_timed(state->ev, state->mem_ctx, timeval_current_ofs(1,0), reopen_connection, state); return; } state->tree = io->out.tree; num_connected++; DEBUG(0,("[%u] reconnect to %s finished (%u connected)\n", state->client_num, state->dest_host, num_connected)); state->open_fnum = -1; state->close_fnum = -1; next_open(state); }
static void report_rate(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct benchopen_state *state = talloc_get_type(private_data, struct benchopen_state); int i; for (i=0;i<nprocs;i++) { printf("%5u ", (unsigned)(state[i].count - state[i].lastcount)); state[i].lastcount = state[i].count; } printf("\r"); fflush(stdout); report_te = event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state); /* send an echo on each interface to ensure it stays alive - this helps with IP takeover */ for (i=0;i<nprocs;i++) { struct smb_echo p; struct smbcli_request *req; if (!state[i].tree) { continue; } p.in.repeat_count = 1; p.in.size = 0; p.in.data = NULL; req = smb_raw_echo_send(state[i].tree->session->transport, &p); req->async.private_data = &state[i]; req->async.fn = echo_completion; } }
static void aio_linux_housekeeping(struct tevent_context *event_ctx, struct tevent_timer *te, struct timeval now, void *private_data) { /* Remove this timed event handler. */ TALLOC_FREE(te); if ((num_busy != 0) || used) { used = false; /* Still busy. Look again in 30 seconds. */ (void)tevent_add_timer(event_ctx, NULL, timeval_current_ofs(30, 0), aio_linux_housekeeping, NULL); return; } /* No activity for 30 seconds. Close out kernel resources. */ io_queue_release(io_ctx); memset(&io_ctx, '\0', sizeof(io_ctx)); if (event_fd != -1) { close(event_fd); event_fd = -1; } TALLOC_FREE(aio_read_event); }
/* handle a socket write event */ static void messaging_send_handler(struct messaging_context *msg) { while (msg->pending) { struct messaging_rec *rec = msg->pending; NTSTATUS status; status = try_send(rec); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { rec->retries++; if (rec->retries > 3) { /* we're getting continuous write errors - backoff this record */ DLIST_REMOVE(msg->pending, rec); DLIST_ADD_END(msg->retry_queue, rec, struct messaging_rec *); if (msg->retry_te == NULL) { msg->retry_te = event_add_timed(msg->event.ev, msg, timeval_current_ofs(1, 0), msg_retry_timer, msg); } } break; } rec->retries = 0; if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("messaging: Lost message from %s to %s of type %u - %s\n", cluster_id_string(debug_ctx(), rec->header->from), cluster_id_string(debug_ctx(), rec->header->to), rec->header->msg_type, nt_errstr(status))); } DLIST_REMOVE(msg->pending, rec); talloc_free(rec); }
static void add_oplock_timeout_handler(files_struct *fsp) { struct smbd_server_connection *sconn = fsp->conn->sconn; struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops; /* * If kernel oplocks already notifies smbds when an oplock break times * out, just return. */ if (koplocks && (koplocks->flags & KOPLOCKS_TIMEOUT_NOTIFICATION)) { return; } if (fsp->oplock_timeout != NULL) { DEBUG(0, ("Logic problem -- have an oplock event hanging " "around\n")); } fsp->oplock_timeout = tevent_add_timer(fsp->conn->sconn->ev_ctx, fsp, timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0), oplock_timeout_handler, fsp); if (fsp->oplock_timeout == NULL) { DEBUG(0, ("Could not add oplock timeout handler\n")); } }
static void wait_replies(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, bool multiple_replies) { struct tevent_timer *te; bool timed_out = False; te = tevent_add_timer(ev_ctx, NULL, timeval_current_ofs(timeout, 0), smbcontrol_timeout, (void *)&timed_out); if (te == NULL) { DEBUG(0, ("tevent_add_timer failed\n")); return; } while (!timed_out) { int ret; if (num_replies > 0 && !multiple_replies) break; ret = tevent_loop_once(ev_ctx); if (ret != 0) { break; } } }
/* establish a new connection to the web server */ static void websrv_accept(struct stream_connection *conn) { struct web_server_data *wdata = talloc_get_type(conn->private_data, struct web_server_data); struct websrv_context *web; struct socket_context *tls_socket; web = talloc_zero(conn, struct websrv_context); if (web == NULL) goto failed; web->task = wdata->task; web->conn = conn; conn->private_data = web; talloc_set_destructor(web, websrv_destructor); event_add_timed(conn->event.ctx, web, timeval_current_ofs(HTTP_TIMEOUT, 0), websrv_timeout, web); /* Overwrite the socket with a (possibly) TLS socket */ tls_socket = tls_init_server(wdata->tls_params, conn->socket, conn->event.fde, "GPHO"); /* We might not have TLS, or it might not have initilised */ if (tls_socket) { talloc_unlink(conn, conn->socket); talloc_steal(conn, tls_socket); conn->socket = tls_socket; } else { DEBUG(3, ("TLS not available for web_server connections\n")); } return; failed: talloc_free(conn); }
static void remove_child_pid(struct smbd_parent_context *parent, pid_t pid, bool unclean_shutdown) { struct smbd_child_pid *child; struct server_id child_id; int ret; child_id = pid_to_procid(pid); ret = messaging_cleanup(parent->msg_ctx, pid); if ((ret != 0) && (ret != ENOENT)) { DEBUG(10, ("%s: messaging_cleanup returned %s\n", __func__, strerror(ret))); } smbprofile_cleanup(pid); for (child = parent->children; child != NULL; child = child->next) { if (child->pid == pid) { struct smbd_child_pid *tmp = child; DLIST_REMOVE(parent->children, child); TALLOC_FREE(tmp); parent->num_children -= 1; break; } } if (child == NULL) { /* not all forked child processes are added to the children list */ DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid)); return; } if (unclean_shutdown) { /* a child terminated uncleanly so tickle all processes to see if they can grab any of the pending locks */ DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid)); if (parent->cleanup_te == NULL) { /* call the cleanup timer, but not too often */ int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20); parent->cleanup_te = tevent_add_timer(parent->ev_ctx, parent, timeval_current_ofs(cleanup_time, 0), cleanup_timeout_fn, parent); DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n")); } } if (!serverid_deregister(child_id)) { DEBUG(1, ("Could not remove pid %d from serverid.tdb\n", (int)pid)); } }
/* perform the send side of a async dcerpc request */ static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p, const struct GUID *object, uint16_t opnum, bool async, DATA_BLOB *stub_data) { struct rpc_request *req; p->conn->transport.recv_data = dcerpc_recv_data; req = talloc(p, struct rpc_request); if (req == NULL) { return NULL; } req->p = p; req->call_id = next_call_id(p->conn); req->status = NT_STATUS_OK; req->state = RPC_REQUEST_QUEUED; req->payload = data_blob(NULL, 0); req->flags = 0; req->fault_code = 0; req->async_call = async; req->ignore_timeout = false; req->async.callback = NULL; req->async.private_data = NULL; req->recv_handler = NULL; if (object != NULL) { req->object = (struct GUID *)talloc_memdup(req, (const void *)object, sizeof(*object)); if (req->object == NULL) { talloc_free(req); return NULL; } } else { req->object = NULL; } req->opnum = opnum; req->request_data.length = stub_data->length; req->request_data.data = talloc_reference(req, stub_data->data); if (req->request_data.length && req->request_data.data == NULL) { return NULL; } DLIST_ADD_END(p->conn->request_queue, req, struct rpc_request *); talloc_set_destructor(req, dcerpc_req_dequeue); dcerpc_ship_next_request(p->conn); if (p->request_timeout) { event_add_timed(dcerpc_event_context(p), req, timeval_current_ofs(p->request_timeout, 0), dcerpc_timeout_handler, req); } return req; }
int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) { struct ctdb_ban_time *bantime = (struct ctdb_ban_time *)indata.dptr; DEBUG(DEBUG_INFO,("SET BAN STATE\n")); if (bantime->pnn != ctdb->pnn) { if (bantime->pnn < 0 || bantime->pnn >= ctdb->num_nodes) { DEBUG(DEBUG_ERR,(__location__ " ERROR: Invalid ban request. PNN:%d is invalid. Max nodes %d\n", bantime->pnn, ctdb->num_nodes)); return -1; } if (bantime->time == 0) { DEBUG(DEBUG_INFO,("unbanning node %d\n", bantime->pnn)); ctdb->nodes[bantime->pnn]->flags &= ~NODE_FLAGS_BANNED; } else { DEBUG(DEBUG_INFO,("banning node %d\n", bantime->pnn)); if (ctdb->tunable.enable_bans == 0) { DEBUG(DEBUG_INFO,("Bans are disabled - ignoring ban of node %u\n", bantime->pnn)); return 0; } ctdb->nodes[bantime->pnn]->flags |= NODE_FLAGS_BANNED; } return 0; } if (ctdb->banning_ctx != NULL) { talloc_free(ctdb->banning_ctx); ctdb->banning_ctx = NULL; } if (bantime->time == 0) { DEBUG(DEBUG_ERR,("Unbanning this node\n")); ctdb->nodes[bantime->pnn]->flags &= ~NODE_FLAGS_BANNED; return 0; } if (ctdb->tunable.enable_bans == 0) { DEBUG(DEBUG_ERR,("Bans are disabled - ignoring ban of node %u\n", bantime->pnn)); return 0; } ctdb->banning_ctx = talloc(ctdb, struct ctdb_ban_time); if (ctdb->banning_ctx == NULL) { DEBUG(DEBUG_CRIT,(__location__ " ERROR Failed to allocate new banning state\n")); return -1; } *((struct ctdb_ban_time *)(ctdb->banning_ctx)) = *bantime; DEBUG(DEBUG_ERR,("Banning this node for %d seconds\n", bantime->time)); ctdb->nodes[bantime->pnn]->flags |= NODE_FLAGS_BANNED; event_add_timed(ctdb->ev, ctdb->banning_ctx, timeval_current_ofs(bantime->time,0), ctdb_ban_node_event, ctdb); return 0; }
/* called when a wins name register has completed */ static void nbtd_wins_register_handler(struct composite_context *c) { NTSTATUS status; struct nbt_name_register_wins io; struct nbtd_iface_name *iname = talloc_get_type(c->async.private_data, struct nbtd_iface_name); TALLOC_CTX *tmp_ctx = talloc_new(iname); status = nbt_name_register_wins_recv(c, tmp_ctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { /* none of the WINS servers responded - try again periodically */ int wins_retry_time = lp_parm_int(iname->iface->nbtsrv->task->lp_ctx, NULL, "nbtd", "wins_retry", 300); event_add_timed(iname->iface->nbtsrv->task->event_ctx, iname, timeval_current_ofs(wins_retry_time, 0), nbtd_wins_register_retry, iname); talloc_free(tmp_ctx); return; } if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("Name register failure with WINS for %s - %s\n", nbt_name_string(tmp_ctx, &iname->name), nt_errstr(status))); talloc_free(tmp_ctx); return; } if (io.out.rcode != 0) { DEBUG(1,("WINS server %s rejected name register of %s - %s\n", io.out.wins_server, nbt_name_string(tmp_ctx, &iname->name), nt_errstr(nbt_rcode_to_ntstatus(io.out.rcode)))); iname->nb_flags |= NBT_NM_CONFLICT; talloc_free(tmp_ctx); return; } /* success - start a periodic name refresh */ iname->nb_flags |= NBT_NM_ACTIVE; if (iname->wins_server) { /* * talloc_free() would generate a warning, * so steal it into the tmp context */ talloc_steal(tmp_ctx, iname->wins_server); } iname->wins_server = talloc_steal(iname, io.out.wins_server); iname->registration_time = timeval_current(); nbtd_wins_start_refresh_timer(iname); DEBUG(3,("Registered %s with WINS server %s\n", nbt_name_string(tmp_ctx, &iname->name), iname->wins_server)); talloc_free(tmp_ctx); }
static void each_second(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); print_counters(); event_add_timed(ev, ctdb, timeval_current_ofs(1, 0), each_second, ctdb); }
static bool init_aio_linux(struct vfs_handle_struct *handle) { struct tevent_timer *te = NULL; if (event_fd != -1) { /* Already initialized. */ return true; } /* Schedule a shutdown event for 30 seconds from now. */ te = tevent_add_timer(handle->conn->sconn->ev_ctx, NULL, timeval_current_ofs(30, 0), aio_linux_housekeeping, NULL); if (te == NULL) { goto fail; } event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); if (event_fd == -1) { goto fail; } aio_read_event = tevent_add_fd(server_event_context(), NULL, event_fd, TEVENT_FD_READ, aio_linux_done, NULL); if (aio_read_event == NULL) { goto fail; } if (io_queue_init(lp_aio_max_threads(), &io_ctx)) { goto fail; } DEBUG(10,("init_aio_linux: initialized with up to %d events\n", (int)lp_aio_max_threads())); return true; fail: DEBUG(10,("init_aio_linux: initialization failed\n")); TALLOC_FREE(te); TALLOC_FREE(aio_read_event); if (event_fd != -1) { close(event_fd); event_fd = -1; } memset(&io_ctx, '\0', sizeof(io_ctx)); return false; }
/* setup a timer to destroy a open search after a inactivity period */ static void pvfs_search_setup_timer(struct pvfs_search_state *search) { struct tevent_context *ev = search->pvfs->ntvfs->ctx->event_ctx; if (search->handle == INVALID_SEARCH_HANDLE) return; talloc_free(search->te); search->te = event_add_timed(ev, search, timeval_current_ofs(search->pvfs->search.inactivity_time, 0), pvfs_search_timer, search); }
bool fsp_lease_update(struct share_mode_lock *lck, const struct GUID *client_guid, struct fsp_lease *lease) { struct share_mode_data *d = lck->data; int idx; struct share_mode_lease *l = NULL; idx = find_share_mode_lease(d, client_guid, &lease->lease.lease_key); if (idx != -1) { l = &d->leases[idx]; } if (l == NULL) { DEBUG(1, ("%s: Could not find lease entry\n", __func__)); TALLOC_FREE(lease->timeout); lease->lease.lease_state = SMB2_LEASE_NONE; lease->lease.lease_epoch += 1; lease->lease.lease_flags = 0; return false; } DEBUG(10,("%s: refresh lease state\n", __func__)); /* Ensure we're in sync with current lease state. */ if (lease->lease.lease_epoch != l->epoch) { DEBUG(10,("%s: cancel outdated timeout\n", __func__)); TALLOC_FREE(lease->timeout); } lease->lease.lease_epoch = l->epoch; lease->lease.lease_state = l->current_state; if (l->breaking) { lease->lease.lease_flags |= SMB2_LEASE_FLAG_BREAK_IN_PROGRESS; if (lease->timeout == NULL) { struct timeval t = timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0); DEBUG(10,("%s: setup timeout handler\n", __func__)); lease->timeout = tevent_add_timer(lease->sconn->ev_ctx, lease, t, lease_timeout_handler, lease); if (lease->timeout == NULL) { DEBUG(0, ("%s: Could not add lease timeout handler\n", __func__)); } } } else { lease->lease.lease_flags &= ~SMB2_LEASE_FLAG_BREAK_IN_PROGRESS; TALLOC_FREE(lease->timeout); } return true; }
/* see if any nodes are dead */ static void ctdb_check_for_dead_nodes(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); int i; /* send a keepalive to all other nodes, unless */ for (i=0;i<ctdb->num_nodes;i++) { struct ctdb_node *node = ctdb->nodes[i]; if (node->flags & NODE_FLAGS_DELETED) { continue; } if (node->pnn == ctdb->pnn) { continue; } if (node->flags & NODE_FLAGS_DISCONNECTED) { /* it might have come alive again */ if (node->rx_cnt != 0) { ctdb_node_connected(node); } continue; } if (node->rx_cnt == 0) { node->dead_count++; } else { node->dead_count = 0; } node->rx_cnt = 0; if (node->dead_count >= ctdb->tunable.keepalive_limit) { DEBUG(DEBUG_NOTICE,("dead count reached for node %u\n", node->pnn)); ctdb_node_dead(node); ctdb_send_keepalive(ctdb, node->pnn); /* maybe tell the transport layer to kill the sockets as well? */ continue; } DEBUG(DEBUG_DEBUG,("sending keepalive to %u\n", node->pnn)); ctdb_send_keepalive(ctdb, node->pnn); node->tx_cnt = 0; } tevent_add_timer(ctdb->ev, ctdb->keepalive_ctx, timeval_current_ofs(ctdb->tunable.keepalive_interval, 0), ctdb_check_for_dead_nodes, ctdb); }
static void wreplsrv_out_pull_reschedule(struct wreplsrv_partner *partner, uint32_t interval) { NTSTATUS status; partner->pull.next_run = timeval_current_ofs(interval, 0); status = wreplsrv_periodic_schedule(partner->service, interval); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("wreplsrv_periodic_schedule() failed\n")); } }
static bool recalc_brl_timeout(void) { struct blocking_lock_record *blr; struct timeval next_timeout; TALLOC_FREE(brl_timeout); next_timeout = timeval_zero(); for (blr = blocking_lock_queue; blr; blr = blr->next) { if (timeval_is_zero(&blr->expire_time)) { /* * If we're blocked on pid 0xFFFFFFFF this is * a POSIX lock, so calculate a timeout of * 10 seconds into the future. */ if (blr->blocking_pid == 0xFFFFFFFF) { struct timeval psx_to = timeval_current_ofs(10, 0); next_timeout = timeval_min(&next_timeout, &psx_to); } continue; } if (timeval_is_zero(&next_timeout)) { next_timeout = blr->expire_time; } else { next_timeout = timeval_min(&next_timeout, &blr->expire_time); } } if (timeval_is_zero(&next_timeout)) { DEBUG(10, ("Next timeout = Infinite.\n")); return True; } if (DEBUGLVL(10)) { struct timeval cur, from_now; cur = timeval_current(); from_now = timeval_until(&cur, &next_timeout); DEBUG(10, ("Next timeout = %d.%d seconds from now.\n", (int)from_now.tv_sec, (int)from_now.tv_usec)); } if (!(brl_timeout = event_add_timed(smbd_event_context(), NULL, next_timeout, brl_timeout_fn, NULL))) { return False; } return True; }
/* * Callback routine when required locks are not obtained within timeout * Called from parent context */ static void ctdb_lock_timeout_handler(struct tevent_context *ev, struct tevent_timer *ttimer, struct timeval current_time, void *private_data) { static const char * debug_locks = NULL; struct lock_context *lock_ctx; struct ctdb_context *ctdb; pid_t pid; lock_ctx = talloc_get_type_abort(private_data, struct lock_context); ctdb = lock_ctx->ctdb; if (lock_ctx->type == LOCK_RECORD || lock_ctx->type == LOCK_DB) { DEBUG(DEBUG_WARNING, ("Unable to get %s lock on database %s for %.0lf seconds\n", (lock_ctx->type == LOCK_RECORD ? "RECORD" : "DB"), lock_ctx->ctdb_db->db_name, timeval_elapsed(&lock_ctx->start_time))); } else { DEBUG(DEBUG_WARNING, ("Unable to get ALLDB locks for %.0lf seconds\n", timeval_elapsed(&lock_ctx->start_time))); } /* Fire a child process to find the blocking process. */ if (debug_locks == NULL) { debug_locks = getenv("CTDB_DEBUG_LOCKS"); if (debug_locks == NULL) { debug_locks = talloc_asprintf(ctdb, "%s/debug_locks.sh", getenv("CTDB_BASE")); } } if (debug_locks != NULL) { pid = vfork(); if (pid == 0) { execl(debug_locks, debug_locks, NULL); _exit(0); } ctdb_track_child(ctdb, pid); } else { DEBUG(DEBUG_WARNING, (__location__ " Unable to setup lock debugging - no memory?\n")); } /* reset the timeout timer */ // talloc_free(lock_ctx->ttimer); lock_ctx->ttimer = tevent_add_timer(ctdb->ev, lock_ctx, timeval_current_ofs(10, 0), ctdb_lock_timeout_handler, (void *)lock_ctx); }
static void report_rate(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct offline_state *state = talloc_get_type(private_data, struct offline_state); int i; uint32_t total=0, total_offline=0, total_online=0; for (i=0;i<numstates;i++) { total += state[i].count - state[i].lastcount; if (timeval_elapsed(&state[i].tv_start) > latencies[state[i].op]) { latencies[state[i].op] = timeval_elapsed(&state[i].tv_start); } state[i].lastcount = state[i].count; total_online += state[i].online_count; total_offline += state[i].offline_count; } printf("ops/s=%4u offline=%5u online=%4u set_lat=%.1f/%.1f get_lat=%.1f/%.1f save_lat=%.1f/%.1f load_lat=%.1f/%.1f\n", total, total_offline, total_online, latencies[OP_SETOFFLINE], worst_latencies[OP_SETOFFLINE], latencies[OP_GETOFFLINE], worst_latencies[OP_GETOFFLINE], latencies[OP_SAVEFILE], worst_latencies[OP_SAVEFILE], latencies[OP_LOADFILE], worst_latencies[OP_LOADFILE]); fflush(stdout); event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state); for (i=0;i<OP_ENDOFLIST;i++) { if (latencies[i] > worst_latencies[i]) { worst_latencies[i] = latencies[i]; } latencies[i] = 0; } /* send an echo on each interface to ensure it stays alive - this helps with IP takeover */ for (i=0;i<numstates;i++) { struct smb_echo p; struct smbcli_request *req; if (!state[i].tree) { continue; } p.in.repeat_count = 1; p.in.size = 0; p.in.data = NULL; req = smb_raw_echo_send(state[i].tree->session->transport, &p); req->async.private_data = &state[i]; req->async.fn = echo_completion; } }
/* called when the startup event script finishes */ static void ctdb_startup_callback(struct ctdb_context *ctdb, int status, void *p) { if (status != 0) { DEBUG(DEBUG_ERR,("startup event failed\n")); tevent_add_timer(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(5, 0), ctdb_run_startup, ctdb); return; } DEBUG(DEBUG_NOTICE,("startup event OK - enabling monitoring\n")); ctdb_set_runstate(ctdb, CTDB_RUNSTATE_RUNNING); ctdb->monitor->next_interval = 2; ctdb_run_notification_script(ctdb, "startup"); ctdb->monitor->monitoring_mode = CTDB_MONITORING_ACTIVE; tevent_add_timer(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(ctdb->monitor->next_interval, 0), ctdb_check_health, ctdb); }
static bool test_event_context_threaded(struct torture_context *test, const void *test_data) { struct tevent_context *ev; struct tevent_timer *te; struct tevent_fd *fde; pthread_t poll_thread; int fds[2]; int ret; char c = 0; ev = tevent_context_init_byname(test, "poll_mt"); torture_assert(test, ev != NULL, "poll_mt not supported"); tevent_set_trace_callback(ev, test_event_threaded_trace, NULL); te = tevent_add_timer(ev, ev, timeval_current_ofs(5, 0), test_event_threaded_timer, NULL); torture_assert(test, te != NULL, "Could not add timer"); ret = pthread_create(&poll_thread, NULL, test_event_poll_thread, ev); torture_assert(test, ret == 0, "Could not create poll thread"); ret = pipe(fds); torture_assert(test, ret == 0, "Could not create pipe"); poll(NULL, 0, 100); test_event_threaded_lock(); fde = tevent_add_fd(ev, ev, fds[0], TEVENT_FD_READ, test_event_threaded_read_handler, &fds[0]); torture_assert(test, fde != NULL, "Could not add fd event"); test_event_threaded_unlock(); poll(NULL, 0, 100); write(fds[1], &c, 1); poll(NULL, 0, 100); test_event_threaded_lock(); do_shutdown = true; test_event_threaded_unlock(); write(fds[1], &c, 1); ret = pthread_join(poll_thread, NULL); torture_assert(test, ret == 0, "pthread_join failed"); return true; }
static void ctdb_time_tick(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); if (getpid() != ctdb->ctdbd_pid) { return; } event_add_timed(ctdb->ev, ctdb, timeval_current_ofs(1, 0), ctdb_time_tick, ctdb); }
/* see if the event scripts think we are healthy */ static void ctdb_check_health(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); bool skip_monitoring = false; int ret = 0; if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL || ctdb->monitor->monitoring_mode == CTDB_MONITORING_DISABLED) { skip_monitoring = true; } else { if (ctdb_db_all_frozen(ctdb)) { DEBUG(DEBUG_ERR, ("Skip monitoring since databases are frozen\n")); skip_monitoring = true; } } if (skip_monitoring) { tevent_add_timer(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(ctdb->monitor->next_interval, 0), ctdb_check_health, ctdb); return; } ret = ctdb_event_script_callback(ctdb, ctdb->monitor->monitor_context, ctdb_health_callback, ctdb, CTDB_EVENT_MONITOR, "%s", ""); if (ret != 0) { DEBUG(DEBUG_ERR,("Unable to launch monitor event script\n")); ctdb->monitor->next_interval = 5; tevent_add_timer(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(5, 0), ctdb_check_health, ctdb); } }
/* startup a client only ctdb context */ struct ctdb_context *ctdb_cmdline_client(struct event_context *ev) { struct ctdb_context *ctdb; char *socket_name; int ret; /* initialise ctdb */ ctdb = ctdb_init(ev); if (ctdb == NULL) { fprintf(stderr, "Failed to init ctdb\n"); exit(1); } /* tell ctdb the socket address */ socket_name = getenv("CTDB_SOCKET"); if (socket_name != NULL) { ret = ctdb_set_socketname(ctdb, socket_name); if (ret == -1) { printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb)); exit(1); } } if (ctdb_cmdline.socketname != NULL) { ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname); if (ret == -1) { fprintf(stderr, "ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb)); exit(1); } } ret = ctdb_socket_connect(ctdb); if (ret != 0) { fprintf(stderr, __location__ " Failed to connect to daemon\n"); talloc_free(ctdb); return NULL; } /* get our pnn */ ctdb->pnn = ctdb_ctrl_getpnn(ctdb, timeval_current_ofs(3, 0), CTDB_CURRENT_NODE); if (ctdb->pnn == (uint32_t)-1) { DEBUG(DEBUG_CRIT,(__location__ " Failed to get ctdb pnn\n")); talloc_free(ctdb); return NULL; } return ctdb; }
/* start watching for nodes that might be dead */ void ctdb_wait_for_first_recovery(struct ctdb_context *ctdb) { ctdb_set_runstate(ctdb, CTDB_RUNSTATE_FIRST_RECOVERY); ctdb->monitor = talloc(ctdb, struct ctdb_monitor_state); CTDB_NO_MEMORY_FATAL(ctdb, ctdb->monitor); ctdb->monitor->monitor_context = talloc_new(ctdb->monitor); CTDB_NO_MEMORY_FATAL(ctdb, ctdb->monitor->monitor_context); tevent_add_timer(ctdb->ev, ctdb->monitor->monitor_context, timeval_current_ofs(1, 0), ctdb_wait_until_recovered, ctdb); }