Exemplo n.º 1
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;
}
Exemplo n.º 2
0
struct timeval *get_timed_events_timeout(struct timeval *to_ret)
{
    struct timeval now;

    if (timed_events == NULL) {
        return NULL;
    }

    now = timeval_current();
    *to_ret = timeval_until(&now, &timed_events->when);

    DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
               (int)to_ret->tv_usec));

    return to_ret;
}
Exemplo n.º 3
0
static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
{
	struct blocking_lock_record *blr;
	struct timeval next_timeout;
	int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5);

	TALLOC_FREE(sconn->smb1.locks.brl_timeout);

	next_timeout = timeval_zero();

	for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
		if (timeval_is_zero(&blr->expire_time)) {
			/*
			 * If we're blocked on pid 0xFFFFFFFFFFFFFFFFLL this is
			 * a POSIX lock, so calculate a timeout of
			 * 10 seconds into the future.
			 */
                        if (blr->blocking_smblctx == 0xFFFFFFFFFFFFFFFFLL) {
				struct timeval psx_to = timeval_current_ofs(10, 0);
				next_timeout = timeval_brl_min(&next_timeout, &psx_to);
                        }

			continue;
		}

		next_timeout = timeval_brl_min(&next_timeout, &blr->expire_time);
	}

	if (timeval_is_zero(&next_timeout)) {
		DEBUG(10, ("Next timeout = Infinite.\n"));
		return True;
	}

	/*
	 to account for unclean shutdowns by clients we need a
	 maximum timeout that we use for checking pending locks. If
	 we have any pending locks at all, then check if the pending
	 lock can continue at least every brl:recalctime seconds
	 (default 5 seconds).

	 This saves us needing to do a message_send_all() in the
	 SIGCHLD handler in the parent daemon. That
	 message_send_all() caused O(n^2) work to be done when IP
	 failovers happened in clustered Samba, which could make the
	 entire system unusable for many minutes.
	*/

	if (max_brl_timeout > 0) {
		struct timeval min_to = timeval_current_ofs(max_brl_timeout, 0);
		next_timeout = timeval_min(&next_timeout, &min_to);
	}

	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));
	}

	sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->ev_ctx,
							 NULL, next_timeout,
							 brl_timeout_fn, sconn);
	if (sconn->smb1.locks.brl_timeout == NULL) {
		return False;
	}

	return True;
}
Exemplo n.º 4
0
/*
  test the TestSleep interface
*/
static bool test_sleep(struct torture_context *tctx,
						  struct dcerpc_pipe *p)
{
	int i;
	NTSTATUS status;
#define ASYNC_COUNT 3
	struct rpc_request *req[ASYNC_COUNT];
	struct echo_TestSleep r[ASYNC_COUNT];
	bool done[ASYNC_COUNT];
	struct timeval snd[ASYNC_COUNT];
	struct timeval rcv[ASYNC_COUNT];
	struct timeval diff[ASYNC_COUNT];
	struct tevent_context *ctx;
	int total_done = 0;

	if (torture_setting_bool(tctx, "quick", false)) {
		torture_skip(tctx, "TestSleep disabled - use \"torture:quick=no\" to enable\n");
	}
	torture_comment(tctx, "Testing TestSleep - use \"torture:quick=yes\" to disable\n");

	for (i=0;i<ASYNC_COUNT;i++) {
		done[i]		= false;
		snd[i]		= timeval_current();
		rcv[i]		= timeval_zero();
		r[i].in.seconds = ASYNC_COUNT-i;
		req[i] = dcerpc_echo_TestSleep_send(p, tctx, &r[i]);
		torture_assert(tctx, req[i], "Failed to send async sleep request\n");
	}

	ctx = dcerpc_event_context(p);
	while (total_done < ASYNC_COUNT) {
		torture_assert(tctx, event_loop_once(ctx) == 0, 
					   "Event context loop failed");
		for (i=0;i<ASYNC_COUNT;i++) {
			if (done[i] == false && req[i]->state == RPC_REQUEST_DONE) {
				int rounded_tdiff;
				total_done++;
				done[i] = true;
				rcv[i]	= timeval_current();
				diff[i]	= timeval_until(&snd[i], &rcv[i]);
				rounded_tdiff = (int)(0.5 + diff[i].tv_sec + (1.0e-6*diff[i].tv_usec));
				status	= dcerpc_ndr_request_recv(req[i]);
				torture_comment(tctx, "rounded_tdiff=%d\n", rounded_tdiff);
				torture_assert_ntstatus_ok(tctx, status, 
							talloc_asprintf(tctx, "TestSleep(%d) failed", i));
				torture_assert(tctx, r[i].out.result == r[i].in.seconds,
					talloc_asprintf(tctx, "Failed - Asked to sleep for %u seconds (server replied with %u seconds and the reply takes only %u seconds)", 
						r[i].out.result, r[i].in.seconds, (unsigned int)diff[i].tv_sec));
				torture_assert(tctx, r[i].out.result <= rounded_tdiff, 
					talloc_asprintf(tctx, "Failed - Slept for %u seconds (but reply takes only %u.%06u seconds)", 
						r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec));
				if (r[i].out.result+1 == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (but reply takes %u.%06u seconds - busy server?)\n", 
							r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
				} else if (r[i].out.result == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (reply takes %u.%06u seconds - ok)\n", 
							r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
				} else {
						torture_comment(tctx, "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)", 
							r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
					/* TODO: let the test fail here, when we support async rpc on ncacn_np */
				}
			}
		}
	}
	torture_comment(tctx, "\n");
	return true;
}
Exemplo n.º 5
0
/*
  test the TestSleep interface
*/
static bool test_sleep(struct torture_context *tctx,
		       struct dcerpc_pipe *p)
{
	int i;
#define ASYNC_COUNT 3
	struct tevent_req *req[ASYNC_COUNT];
	struct echo_TestSleep r[ASYNC_COUNT];
	bool done1[ASYNC_COUNT];
	bool done2[ASYNC_COUNT];
	struct timeval snd[ASYNC_COUNT];
	struct timeval rcv[ASYNC_COUNT];
	struct timeval diff[ASYNC_COUNT];
	int total_done = 0;
	struct dcerpc_binding_handle *b = p->binding_handle;
	enum dcerpc_transport_t transport;
	uint32_t assoc_group_id;
	struct dcerpc_pipe *p2 = NULL;
	NTSTATUS status;

	if (torture_setting_bool(tctx, "quick", false)) {
		torture_skip(tctx, "TestSleep disabled - use \"torture:quick=no\" to enable\n");
	}
	torture_comment(tctx, "Testing TestSleep - use \"torture:quick=yes\" to disable\n");

	transport	= dcerpc_binding_get_transport(p->binding);
	assoc_group_id	= dcerpc_binding_get_assoc_group_id(p->binding);

	torture_comment(tctx, "connect echo connection 2 with "
			"DCERPC_CONCURRENT_MULTIPLEX\n");
	status = torture_rpc_connection_transport(tctx, &p2,
						  &ndr_table_rpcecho,
						  transport,
						  assoc_group_id,
						  DCERPC_CONCURRENT_MULTIPLEX);
	torture_assert_ntstatus_ok(tctx, status, "opening echo connection 2");
	b = p2->binding_handle;

	for (i=0;i<ASYNC_COUNT;i++) {
		done1[i]	= false;
		done2[i]	= false;
		snd[i]		= timeval_current();
		rcv[i]		= timeval_zero();
		r[i].in.seconds = ASYNC_COUNT-i;
		req[i] = dcerpc_echo_TestSleep_r_send(tctx, tctx->ev, b, &r[i]);
		torture_assert(tctx, req[i], "Failed to send async sleep request\n");
		tevent_req_set_callback(req[i], test_sleep_done, &done1[i]);
	}

	while (total_done < ASYNC_COUNT) {
		torture_assert(tctx, tevent_loop_once(tctx->ev) == 0,
					   "Event context loop failed");
		for (i=0;i<ASYNC_COUNT;i++) {
			if (done2[i] == false && done1[i] == true) {
				int rounded_tdiff;
				total_done++;
				done2[i] = true;
				rcv[i]	= timeval_current();
				diff[i]	= timeval_until(&snd[i], &rcv[i]);
				rounded_tdiff = (int)(0.5 + diff[i].tv_sec + (1.0e-6*diff[i].tv_usec));
				torture_comment(tctx, "rounded_tdiff=%d\n", rounded_tdiff);
				torture_assert_ntstatus_ok(tctx,
					dcerpc_echo_TestSleep_r_recv(req[i], tctx),
					talloc_asprintf(tctx, "TestSleep(%d) failed", i));
				torture_assert(tctx, r[i].out.result == r[i].in.seconds,
					talloc_asprintf(tctx, "Failed - Asked to sleep for %u seconds (server replied with %u seconds and the reply takes only %u seconds)", 
						r[i].out.result, r[i].in.seconds, (unsigned int)diff[i].tv_sec));
				torture_assert(tctx, r[i].out.result <= rounded_tdiff, 
					talloc_asprintf(tctx, "Failed - Slept for %u seconds (but reply takes only %u.%06u seconds)", 
						r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec));
				if (r[i].out.result+1 == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (but reply takes %u.%06u seconds - busy server?)\n", 
							r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
				} else if (r[i].out.result == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (reply takes %u.%06u seconds - ok)\n", 
							r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec);
				} else {
					torture_fail(tctx, talloc_asprintf(tctx,
						     "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)\n",
						     r[i].out.result, (unsigned int)diff[i].tv_sec, (unsigned int)diff[i].tv_usec));
				}
			}
		}
	}
	torture_comment(tctx, "\n");
	return true;
}