mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-15 16:47:56 -05:00
one more round of cached connections fixes/improvements
This commit is contained in:
parent
26a47e7bd0
commit
ee2370bf42
11 changed files with 101 additions and 57 deletions
|
|
@ -1080,7 +1080,8 @@ retry_lock:
|
|||
|
||||
snprintf( buf, sizeof( buf ),
|
||||
"conn %p fetched refcnt=%u%s",
|
||||
(void *)lc, refcnt, expiring ? " expiring" : "" );
|
||||
(void *)lc, refcnt,
|
||||
expiring ? " expiring" : "" );
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_getconn: %s.\n", buf, 0, 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ cleanup:;
|
|||
|
||||
done:;
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
|
|
@ -375,14 +375,18 @@ typedef struct metainfo_t {
|
|||
#define META_BACK_F_ONERR_REPORT (0x00200000U)
|
||||
#define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT)
|
||||
#define META_BACK_F_DEFER_ROOTDN_BIND (0x00400000U)
|
||||
#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U)
|
||||
#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U) /* users always proxyauthz */
|
||||
#define META_BACK_F_PROXYAUTHZ_ANON (0x01000000U) /* anonymous always proxyauthz */
|
||||
#define META_BACK_F_PROXYAUTHZ_NOANON (0x02000000U) /* anonymous remains anonymous */
|
||||
|
||||
#define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
|
||||
#define META_BACK_ONERR_REPORT(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_REPORT )
|
||||
#define META_BACK_ONERR_CONTINUE(mi) ( !( (mi)->mi_flags & META_BACK_F_ONERR_MASK ) )
|
||||
#define META_BACK_ONERR_STOP(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_STOP )
|
||||
#define META_BACK_ONERR_REPORT(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_REPORT )
|
||||
#define META_BACK_ONERR_CONTINUE(mi) ( !LDAP_BACK_ISSET( (mi), META_BACK_F_ONERR_MASK ) )
|
||||
|
||||
#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
|
||||
#define META_BACK_PROXYAUTHZ_ALWAYS(mi) ( (mi)->mi_flags & META_BACK_F_PROXYAUTHZ_ALWAYS )
|
||||
#define META_BACK_DEFER_ROOTDN_BIND(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_DEFER_ROOTDN_BIND )
|
||||
#define META_BACK_PROXYAUTHZ_ALWAYS(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ALWAYS )
|
||||
#define META_BACK_PROXYAUTHZ_ANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_ANON )
|
||||
#define META_BACK_PROXYAUTHZ_NOANON(mi) LDAP_BACK_ISSET( (mi), META_BACK_F_PROXYAUTHZ_NOANON )
|
||||
|
||||
int mi_version;
|
||||
time_t mi_network_timeout;
|
||||
|
|
@ -410,10 +414,10 @@ meta_back_getconn(
|
|||
|
||||
extern void
|
||||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metainfo_t *mi,
|
||||
metaconn_t *mc,
|
||||
int dolock );
|
||||
#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 )
|
||||
#define meta_back_release_conn(mi, mc) meta_back_release_conn_lock( (mi), (mc), 1 )
|
||||
|
||||
extern int
|
||||
meta_back_retry(
|
||||
|
|
|
|||
|
|
@ -205,7 +205,9 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
|||
ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ) );
|
||||
}
|
||||
|
||||
if ( !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) {
|
||||
if ( !LDAP_BACK_PCONN_ISPRIV( mc )
|
||||
&& !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) )
|
||||
{
|
||||
metaconn_t *tmpmc;
|
||||
int lerr;
|
||||
|
||||
|
|
@ -271,7 +273,7 @@ retry_lock:;
|
|||
}
|
||||
|
||||
if ( mc != NULL ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -603,7 +605,7 @@ meta_back_single_dobind(
|
|||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
meta_back_release_conn_lock( mi, mc, 0 );
|
||||
*mcp = NULL;
|
||||
}
|
||||
if ( dolock ) {
|
||||
|
|
@ -720,7 +722,7 @@ retry_binding:;
|
|||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -779,7 +781,7 @@ done:;
|
|||
op->o_log_prefix, LDAP_BACK_PCONN_ID( mc ), bound );
|
||||
|
||||
if ( bound == 0 ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
|
||||
send_err:;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
|
|
@ -1278,7 +1280,10 @@ meta_back_proxy_authz_cred(
|
|||
|
||||
default:
|
||||
/* NOTE: rootdn can always idassert */
|
||||
if ( BER_BVISNULL( &ndn ) && mt->mt_idassert_authz == NULL ) {
|
||||
if ( BER_BVISNULL( &ndn )
|
||||
&& mt->mt_idassert_authz == NULL
|
||||
&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
|
||||
{
|
||||
if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
|
||||
rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ cleanup:;
|
|||
}
|
||||
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
|
|
@ -735,7 +735,7 @@ meta_back_retry(
|
|||
* let the caller do what's best before
|
||||
* releasing */
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
meta_back_release_conn_lock( mi, mc, 0 );
|
||||
*mcp = NULL;
|
||||
|
||||
} else {
|
||||
|
|
@ -751,8 +751,7 @@ meta_back_retry(
|
|||
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
|
||||
mc, mc_q );
|
||||
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
|
||||
mc->mc_q.tqe_prev = NULL;
|
||||
mc->mc_q.tqe_next = NULL;
|
||||
LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
|
||||
|
||||
} else {
|
||||
assert( !LDAP_BACK_CONN_CACHED( mc ) );
|
||||
|
|
@ -1018,17 +1017,28 @@ meta_back_getconn(
|
|||
SlapReply *candidates = meta_back_candidates_get( op );
|
||||
|
||||
/* Internal searches are privileged and shared. So is root. */
|
||||
/* FIXME: there seems to be concurrency issues */
|
||||
if ( META_BACK_PROXYAUTHZ_ALWAYS( mi ) || op->o_do_not_cache || be_isroot( op ) ) {
|
||||
mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
|
||||
if ( ( !BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ALWAYS( mi ) )
|
||||
|| ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ANON( mi ) )
|
||||
|| op->o_do_not_cache || be_isroot( op ) )
|
||||
{
|
||||
LDAP_BACK_CONN_ISPRIV_SET( &mc_curr );
|
||||
mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
|
||||
LDAP_BACK_PCONN_ROOTDN_SET( &mc_curr, op );
|
||||
|
||||
} else if ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_NOANON( mi ) )
|
||||
{
|
||||
LDAP_BACK_CONN_ISANON_SET( &mc_curr );
|
||||
BER_BVSTR( &mc_curr.mc_local_ndn, "" );
|
||||
LDAP_BACK_PCONN_ANON_SET( &mc_curr, op );
|
||||
|
||||
} else {
|
||||
mc_curr.mc_local_ndn = op->o_ndn;
|
||||
|
||||
/* Explicit binds must not be shared */
|
||||
if ( op->o_tag == LDAP_REQ_BIND || SLAP_IS_AUTHZ_BACKEND( op ) ) {
|
||||
if ( !BER_BVISEMPTY( &op->o_ndn )
|
||||
|| op->o_tag == LDAP_REQ_BIND
|
||||
|| SLAP_IS_AUTHZ_BACKEND( op ) )
|
||||
{
|
||||
mc_curr.mc_conn = op->o_conn;
|
||||
|
||||
} else {
|
||||
|
|
@ -1038,7 +1048,10 @@ meta_back_getconn(
|
|||
}
|
||||
|
||||
/* Explicit Bind requests always get their own conn */
|
||||
if ( !( sendok & LDAP_BACK_BINDING ) ) {
|
||||
if ( sendok & LDAP_BACK_BINDING ) {
|
||||
mc_curr.mc_conn = op->o_conn;
|
||||
|
||||
} else {
|
||||
/* Searches for a metaconn in the avl tree */
|
||||
retry_lock:;
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
|
|
@ -1059,8 +1072,7 @@ retry_lock:;
|
|||
{
|
||||
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
|
||||
mc, mc_q );
|
||||
mc->mc_q.tqe_prev = NULL;
|
||||
mc->mc_q.tqe_next = NULL;
|
||||
LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
|
||||
LDAP_TAILQ_INSERT_TAIL( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
|
||||
mc, mc_q );
|
||||
}
|
||||
|
|
@ -1111,8 +1123,7 @@ retry_lock:;
|
|||
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
|
||||
mc, mc_q );
|
||||
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
|
||||
mc->mc_q.tqe_prev = NULL;
|
||||
mc->mc_q.tqe_next = NULL;
|
||||
LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
|
||||
|
||||
} else {
|
||||
assert( !LDAP_BACK_CONN_CACHED( mc ) );
|
||||
|
|
@ -1238,7 +1249,7 @@ retry_lock:;
|
|||
meta_back_conn_free( mc );
|
||||
|
||||
} else {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
rs->sr_err = LDAP_NO_SUCH_OBJECT;
|
||||
|
|
@ -1289,7 +1300,7 @@ retry_lock:;
|
|||
|
||||
if ( i < 0 || rs->sr_err != LDAP_SUCCESS ) {
|
||||
if ( mc != NULL ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
|
|
@ -1308,7 +1319,7 @@ retry_lock:;
|
|||
if ( dn_type == META_DNTYPE_NEWPARENT && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
|
||||
{
|
||||
if ( mc != NULL ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
|
|
@ -1403,7 +1414,7 @@ retry_lock2:;
|
|||
meta_back_conn_free( mc );
|
||||
|
||||
} else {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1500,7 +1511,7 @@ retry_lock2:;
|
|||
meta_back_conn_free( mc );
|
||||
|
||||
} else {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
@ -1523,7 +1534,7 @@ retry_lock2:;
|
|||
meta_back_conn_free( mc );
|
||||
|
||||
} else {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
|
|
@ -1648,12 +1659,10 @@ done:;
|
|||
|
||||
void
|
||||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metainfo_t *mi,
|
||||
metaconn_t *mc,
|
||||
int dolock )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
|
||||
assert( mc != NULL );
|
||||
|
||||
if ( dolock ) {
|
||||
|
|
@ -1668,8 +1677,6 @@ meta_back_release_conn_lock(
|
|||
* the connection space (and eat up resources). Maybe this
|
||||
* should be configurable... */
|
||||
if ( LDAP_BACK_CONN_TAINTED( mc ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld tainted.\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi, ">>> meta_back_release_conn" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
|
|
@ -1678,14 +1685,13 @@ meta_back_release_conn_lock(
|
|||
if ( mc->mc_q.tqe_prev != NULL ) {
|
||||
assert( LDAP_BACK_CONN_CACHED( mc ) );
|
||||
assert( mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num > 0 );
|
||||
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
|
||||
LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv, mc, mc_q );
|
||||
mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_num--;
|
||||
LDAP_TAILQ_ENTRY_INIT( mc, mc_q );
|
||||
|
||||
} else {
|
||||
assert( !LDAP_BACK_CONN_CACHED( mc ) );
|
||||
}
|
||||
mc->mc_q.tqe_prev = NULL;
|
||||
mc->mc_q.tqe_next = NULL;
|
||||
|
||||
} else {
|
||||
metaconn_t *tmpmc;
|
||||
|
|
@ -1693,12 +1699,7 @@ meta_back_release_conn_lock(
|
|||
tmpmc = avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
( caddr_t )mc, meta_back_conndnmc_cmp );
|
||||
|
||||
if ( tmpmc == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "%s: meta_back_release_conn: unable to find mc=%p\n",
|
||||
op->o_log_prefix, (void *)mc, 0 );
|
||||
} else {
|
||||
assert( tmpmc == mc );
|
||||
}
|
||||
assert( tmpmc == NULL && tmpmc == mc );
|
||||
}
|
||||
|
||||
LDAP_BACK_CONN_CACHED_CLEAR( mc );
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ cleanup:;
|
|||
}
|
||||
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ meta_back_db_open(
|
|||
|
||||
int i,
|
||||
not_always = 0,
|
||||
not_always_anon_proxyauthz = 0,
|
||||
not_always_anon_non_prescriptive = 0,
|
||||
rc;
|
||||
|
||||
for ( i = 0; i < mi->mi_ntargets; i++ ) {
|
||||
|
|
@ -165,17 +167,48 @@ meta_back_db_open(
|
|||
|
||||
if ( not_always == 0 ) {
|
||||
if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
|
||||
|| !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
|
||||
|| mt->mt_idassert_authz != NULL )
|
||||
{
|
||||
not_always = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
|
||||
&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
|
||||
"target #%d inconsistent idassert configuration "
|
||||
"(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
|
||||
be->be_suffix[ 0 ].bv_val, i, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( not_always_anon_proxyauthz == 0 ) {
|
||||
if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
|
||||
{
|
||||
not_always_anon_proxyauthz = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( not_always_anon_non_prescriptive == 0 ) {
|
||||
if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
|
||||
{
|
||||
not_always_anon_non_prescriptive = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( not_always == 0 ) {
|
||||
mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
|
||||
}
|
||||
|
||||
if ( not_always_anon_proxyauthz == 0 ) {
|
||||
mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;
|
||||
|
||||
} else if ( not_always_anon_non_prescriptive == 0 ) {
|
||||
mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ cleanup:;
|
|||
free( modv );
|
||||
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ cleanup:;
|
|||
}
|
||||
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ other:;
|
|||
candidates[ candidate ].sr_err = rc;
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
meta_back_release_conn_lock( mi, mc, 0 );
|
||||
*mcp = NULL;
|
||||
rs->sr_err = rc;
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ meta_search_dobind_result(
|
|||
candidates[ candidate ].sr_err = rc;
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
meta_back_release_conn_lock( mi, mc, 0 );
|
||||
*mcp = NULL;
|
||||
retcode = META_SEARCH_ERR;
|
||||
rs->sr_err = rc;
|
||||
|
|
@ -780,7 +780,7 @@ getconn:;
|
|||
op->o_log_prefix, (void *)mc, 0 );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
mc = NULL;
|
||||
|
||||
needbind = 0;
|
||||
|
|
@ -1668,7 +1668,7 @@ finish:;
|
|||
}
|
||||
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
|
|
|
|||
Loading…
Reference in a new issue