mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-04 14:10:39 -05:00
implement per-target, per-operation timeouts
This commit is contained in:
parent
c172a20c49
commit
54a0c02c3d
6 changed files with 221 additions and 22 deletions
|
|
@ -43,6 +43,7 @@ meta_back_add( Operation *op, SlapReply *rs )
|
|||
LDAPMod **attrs;
|
||||
struct berval mdn = BER_BVNULL, mapped;
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
|
||||
Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",
|
||||
|
|
@ -163,20 +164,49 @@ meta_back_add( Operation *op, SlapReply *rs )
|
|||
attrs[ i ] = NULL;
|
||||
|
||||
retry:;
|
||||
#if 0
|
||||
rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
attrs, op->o_ctrls, NULL, &msgid );
|
||||
rs->sr_err = meta_back_op_result( op, rs, &mc->mc_conns[ candidate ], msgid, LDAP_BACK_SENDERR );
|
||||
#endif
|
||||
rs->sr_err = ldap_add_ext_s( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
attrs, op->o_ctrls, NULL );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
|
||||
if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, LDAP_MSG_ONE, tvp, &res );
|
||||
switch ( rs->sr_err ) {
|
||||
case -1:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
||||
case 0:
|
||||
ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, NULL, NULL );
|
||||
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
|
||||
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
||||
default:
|
||||
ldap_msgfree( res );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(void)meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
cleanup:;
|
||||
for ( --i; i >= 0; --i ) {
|
||||
free( attrs[ i ]->mod_bvalues );
|
||||
free( attrs[ i ] );
|
||||
|
|
@ -187,8 +217,6 @@ retry:;
|
|||
BER_BVZERO( &mdn );
|
||||
}
|
||||
|
||||
(void)meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
done:;
|
||||
meta_back_release_conn( op, mc );
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,14 @@ typedef struct metaconn_t {
|
|||
* in one block with the metaconn_t structure */
|
||||
} metaconn_t;
|
||||
|
||||
enum {
|
||||
META_OP_ADD = 0,
|
||||
META_OP_DELETE,
|
||||
META_OP_MODIFY,
|
||||
META_OP_MODRDN,
|
||||
META_OP_LAST
|
||||
};
|
||||
|
||||
typedef struct metatarget_t {
|
||||
char *mt_uri;
|
||||
|
||||
|
|
@ -215,6 +223,7 @@ typedef struct metatarget_t {
|
|||
|
||||
unsigned mt_flags;
|
||||
int mt_version;
|
||||
time_t mt_timeout[ META_OP_LAST ];
|
||||
} metatarget_t;
|
||||
|
||||
typedef struct metadncache_t {
|
||||
|
|
@ -253,6 +262,7 @@ typedef struct metainfo_t {
|
|||
#define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) )
|
||||
|
||||
int mi_version;
|
||||
time_t mi_timeout[ META_OP_LAST ];
|
||||
} metainfo_t;
|
||||
|
||||
typedef enum meta_op_type {
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ meta_back_db_config(
|
|||
LDAPURLDesc *ludp, *tmpludp;
|
||||
struct berval dn;
|
||||
int rc;
|
||||
int c;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
fprintf( stderr,
|
||||
|
|
@ -129,6 +130,10 @@ meta_back_db_config(
|
|||
mi->mi_targets[ i ].mt_flags = mi->flags;
|
||||
mi->mi_targets[ i ].mt_version = mi->mi_version;
|
||||
|
||||
for ( c = 0; c < META_OP_LAST; c++ ) {
|
||||
mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
|
||||
}
|
||||
|
||||
/*
|
||||
* uri MUST be legal!
|
||||
*/
|
||||
|
|
@ -492,6 +497,67 @@ meta_back_db_config(
|
|||
return 1;
|
||||
}
|
||||
|
||||
} else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
|
||||
char *sep, *next;
|
||||
time_t *tv = mi->mi_ntargets ?
|
||||
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
|
||||
: &mi->mi_timeout;
|
||||
int c;
|
||||
|
||||
if ( argc < 2 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
for ( c = 1; c < argc; c++ ) {
|
||||
time_t *t = NULL, val;
|
||||
|
||||
sep = strchr( argv[ c ], '=' );
|
||||
if ( sep != NULL ) {
|
||||
size_t len = sep - argv[ c ];
|
||||
|
||||
if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
|
||||
t = &tv[ META_OP_ADD ];
|
||||
} else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
|
||||
t = &tv[ META_OP_DELETE ];
|
||||
} else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
|
||||
t = &tv[ META_OP_MODIFY ];
|
||||
} else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
|
||||
t = &tv[ META_OP_MODRDN ];
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: unknown operation \"%s\" for timeout #%d.\n",
|
||||
fname, lineno, argv[ c ], c );
|
||||
return 1;
|
||||
}
|
||||
sep++;
|
||||
|
||||
} else {
|
||||
sep = argv[ c ];
|
||||
}
|
||||
|
||||
val = strtoul( sep, &next, 10 );
|
||||
if ( next == sep || next[ 0 ] != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: unable to parse value \"%s\" for timeout.\n",
|
||||
fname, lineno, sep );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( t ) {
|
||||
*t = val;
|
||||
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < META_OP_LAST; i++ ) {
|
||||
tv[ i ] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* name to use as pseudo-root dn */
|
||||
} else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
|
||||
int i = mi->mi_ntargets - 1;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
|||
int candidate = -1;
|
||||
struct berval mdn = BER_BVNULL;
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
|
|
@ -62,22 +63,54 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_delete_ext_s( mc->mc_conns[ candidate ].msc_ld,
|
||||
mdn.bv_val, op->o_ctrls, NULL );
|
||||
rs->sr_err = ldap_delete_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
mdn.bv_val, op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
|
||||
if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, LDAP_MSG_ONE, tvp, &res );
|
||||
switch ( rs->sr_err ) {
|
||||
case -1:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
||||
case 0:
|
||||
ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, NULL, NULL );
|
||||
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
|
||||
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
|
||||
send_ldap_result( op, rs );
|
||||
goto cleanup;
|
||||
|
||||
default:
|
||||
ldap_msgfree( res );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
cleanup:;
|
||||
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
|
||||
free( mdn.bv_val );
|
||||
BER_BVZERO( &mdn );
|
||||
}
|
||||
|
||||
rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
done:;
|
||||
meta_back_release_conn( op, mc );
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
|||
struct berval mdn = BER_BVNULL;
|
||||
struct berval mapped;
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
|
|
@ -172,13 +173,44 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
|||
modv[ i ] = 0;
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_modify_ext_s( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
modv, op->o_ctrls, NULL );
|
||||
rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
|
||||
modv, op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
|
||||
if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, LDAP_MSG_ONE, tvp, &res );
|
||||
switch ( rs->sr_err ) {
|
||||
case -1:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rc = -1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, NULL, NULL );
|
||||
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
|
||||
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
|
||||
rc = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ldap_msgfree( res );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
|
|
|
|||
|
|
@ -34,13 +34,14 @@
|
|||
int
|
||||
meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metaconn_t *mc;
|
||||
int candidate = -1;
|
||||
struct berval mdn = BER_BVNULL,
|
||||
mnewSuperior = BER_BVNULL;
|
||||
dncookie dc;
|
||||
int do_retry = 1;
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metaconn_t *mc;
|
||||
int candidate = -1;
|
||||
struct berval mdn = BER_BVNULL,
|
||||
mnewSuperior = BER_BVNULL;
|
||||
dncookie dc;
|
||||
int msgid;
|
||||
int do_retry = 1;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
|
|
@ -101,15 +102,44 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
retry:;
|
||||
rs->sr_err = ldap_rename_s( mc->mc_conns[ candidate ].msc_ld,
|
||||
rs->sr_err = ldap_rename( mc->mc_conns[ candidate ].msc_ld,
|
||||
mdn.bv_val, op->orr_newrdn.bv_val,
|
||||
mnewSuperior.bv_val, op->orr_deleteoldrdn,
|
||||
op->o_ctrls, NULL );
|
||||
op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
|
||||
if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ] != 0 ) {
|
||||
tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ];
|
||||
tv.tv_usec = 0;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, LDAP_MSG_ONE, tvp, &res );
|
||||
switch ( rs->sr_err ) {
|
||||
case -1:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
|
||||
msgid, NULL, NULL );
|
||||
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
|
||||
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
|
||||
break;
|
||||
|
||||
default:
|
||||
ldap_msgfree( res );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
|
|
|
|||
Loading…
Reference in a new issue