Example #1
0
static meta_search_candidate_t
asyncmeta_send_pending_op(bm_context_t *bc, int candidate)
{
	meta_search_candidate_t	retcode;
	switch (bc->op->o_tag) {
		case LDAP_REQ_SEARCH:
			retcode = asyncmeta_back_search_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate,  NULL, 0 , 0);
			break;
		case LDAP_REQ_ADD:
			retcode = asyncmeta_back_add_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0);
			break;
		case LDAP_REQ_MODIFY:
			retcode = asyncmeta_back_modify_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0);
			break;
		case LDAP_REQ_MODRDN:
			retcode = asyncmeta_back_modrdn_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0);
			break;
		case LDAP_REQ_COMPARE:
			retcode = asyncmeta_back_compare_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0);
			break;
		case LDAP_REQ_DELETE:
			retcode = asyncmeta_back_delete_start( &bc->copy_op, &bc->rs, bc->bc_mc, bc, candidate, 0);
			break;
		default:
			retcode = META_SEARCH_NOT_CANDIDATE;
		}
	return retcode;
}
Example #2
0
int
asyncmeta_back_add( Operation *op, SlapReply *rs )
{
	a_metainfo_t	*mi = ( a_metainfo_t * )op->o_bd->be_private;
	a_metatarget_t	*mt;
	a_metaconn_t	*mc;
	int		rc, candidate = -1;
	OperationBuffer opbuf;
	bm_context_t *bc;
	SlapReply *candidates;
	slap_callback *cb = op->o_callback;

	Debug(LDAP_DEBUG_ARGS, "==> asyncmeta_back_add: %s\n",
	      op->o_req_dn.bv_val, 0, 0 );

	asyncmeta_new_bm_context(op, rs, &bc, mi->mi_ntargets );
	if (bc == NULL) {
		rs->sr_err = LDAP_OTHER;
		asyncmeta_sender_error(op, rs, cb);
		return rs->sr_err;
	}

	candidates = bc->candidates;
	mc = asyncmeta_getconn( op, rs, candidates, &candidate, LDAP_BACK_DONTSEND, 0);
	if ( !mc || rs->sr_err != LDAP_SUCCESS) {
		asyncmeta_sender_error(op, rs, cb);
		asyncmeta_clear_bm_context(bc);
		return rs->sr_err;
	}

	mt = mi->mi_targets[ candidate ];
	bc->timeout = mt->mt_timeout[ SLAP_OP_ADD ];
	bc->retrying = LDAP_BACK_RETRYING;
	bc->sendok = ( LDAP_BACK_SENDRESULT | bc->retrying );
	bc->stoptime = op->o_time + bc->timeout;

	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
	rc = asyncmeta_add_message_queue(mc, bc);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);

	if (rc != LDAP_SUCCESS) {
		rs->sr_err = LDAP_BUSY;
		rs->sr_text = "Maximum pending ops limit exceeded";
		asyncmeta_clear_bm_context(bc);
		asyncmeta_sender_error(op, rs, cb);
		goto finish;
	}

	rc = asyncmeta_dobind_init_with_retry(op, rs, bc, mc, candidate);
	switch (rc)
	{
	case META_SEARCH_CANDIDATE:
		/* target is already bound, just send the request */
		Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add:  "
		       "cnd=\"%ld\"\n", op->o_log_prefix, candidate , 0);

		rc = asyncmeta_back_add_start( op, rs, mc, bc, candidate);
		if (rc == META_SEARCH_ERR) {
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_drop_bc(mc, bc);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			asyncmeta_sender_error(op, rs, cb);
			asyncmeta_clear_bm_context(bc);
			goto finish;

		}
			break;
	case META_SEARCH_NOT_CANDIDATE:
		Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: NOT_CANDIDATE "
		       "cnd=\"%ld\"\n", op->o_log_prefix, candidate , 0);
		candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
		ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
		asyncmeta_drop_bc(mc, bc);
		ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
		asyncmeta_sender_error(op, rs, cb);
		asyncmeta_clear_bm_context(bc);
		goto finish;

	case META_SEARCH_NEED_BIND:
	case META_SEARCH_CONNECTING:
		Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: NEED_BIND "
		       "cnd=\"%ld\" %p\n", op->o_log_prefix, candidate , &mc->mc_conns[candidate]);
		rc = asyncmeta_dobind_init(op, rs, bc, mc, candidate);
		if (rc == META_SEARCH_ERR) {
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_drop_bc(mc, bc);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			asyncmeta_sender_error(op, rs, cb);
			asyncmeta_clear_bm_context(bc);
			goto finish;
		}
		break;
	case META_SEARCH_BINDING:
			Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: BINDING "
			       "cnd=\"%ld\" %p\n", op->o_log_prefix, candidate , &mc->mc_conns[candidate]);
			/* Todo add the context to the message queue but do not send the request
			   the receiver must send this when we are done binding */
			/* question - how would do receiver know to which targets??? */
			break;

	case META_SEARCH_ERR:
			Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_back_add: ERR "
			       "cnd=\"%ldd\"\n", op->o_log_prefix, candidate , 0);
			candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
			candidates[ candidate ].sr_type = REP_RESULT;
			ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
			asyncmeta_drop_bc(mc, bc);
			ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
			asyncmeta_sender_error(op, rs, cb);
			asyncmeta_clear_bm_context(bc);
			goto finish;
		default:
			assert( 0 );
			break;
		}

	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex);
	asyncmeta_start_one_listener(mc, candidates, bc, candidate);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex);
finish:
	return rs->sr_err;
}