Esempio n. 1
0
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);
	}
}
Esempio n. 2
0
/*
  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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
/*
  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);
	}
}
Esempio n. 5
0
/*
  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);
}
Esempio n. 6
0
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;
	}
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
/*
  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);
	}
Esempio n. 9
0
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"));
	}
}
Esempio n. 10
0
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;
		}
	}
}
Esempio n. 11
0
/*
  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);
}
Esempio n. 12
0
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));
	}
}
Esempio n. 13
0
/*
  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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
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);
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
/*
  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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
/*
  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);
}
Esempio n. 21
0
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"));
	}
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
/*
 * 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);
}
Esempio n. 24
0
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;
	}
}
Esempio n. 25
0
/*
  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);
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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);
}
Esempio n. 28
0
/*
  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);
	}
}
Esempio n. 29
0
/*
  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;
}
Esempio n. 30
0
/*
  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);
}