From abbdb1a06c2e58302b12a35e0a2dbff7f05c1760 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sat, 5 Nov 2005 00:08:34 +0000 Subject: [PATCH] Sync with HEAD --- doc/man/man5/slapd.conf.5 | 64 +++++++++++++++----- servers/slapd/add.c | 6 +- servers/slapd/back-bdb/add.c | 3 + servers/slapd/back-bdb/tools.c | 8 +-- servers/slapd/back-ldap/chain.c | 63 ++++++++++++------- servers/slapd/back-meta/search.c | 14 ++--- servers/slapd/controls.c | 2 +- servers/slapd/overlays/syncprov.c | 5 +- tests/progs/slapd-addel.c | 65 ++++++++++++++++---- tests/progs/slapd-modify.c | 64 +++++++++++++++----- tests/progs/slapd-modrdn.c | 67 ++++++++++++++++----- tests/progs/slapd-tester.c | 21 ++++++- tests/scripts/test036-meta-concurrency | 3 +- tests/scripts/test039-glue-ldap-concurrency | 3 +- 14 files changed, 288 insertions(+), 100 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 2ff81bbcbc..33d1f406a2 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -506,68 +506,92 @@ option description. The default is 71. Specify the level at which debugging statements and operation statistics should be syslogged (currently logged to the .BR syslogd (8) -LOG_LOCAL4 facility). Log levels are additive, and available levels -are: +LOG_LOCAL4 facility). +They must be considered subsystems rather than increasingly verbose +log levels. +Some messages with higher priority are logged regardless +of the configured loglevel as soon as some logging is configured, +otherwise anything is logged at all. +Log levels are additive, and available levels are: .RS .RS .PD 0 .TP .B 1 -.B (trace) +.B (0x1 trace) trace function calls .TP .B 2 -.B (packet) +.B (0x2 packet) debug packet handling .TP .B 4 -.B (args) -heavy trace debugging +.B (0x4 args) +heavy trace debugging (function args) .TP .B 8 -.B (conns) +.B (0x8 conns) connection management .TP .B 16 -.B (BER) +.B (0x10 BER) print out packets sent and received .TP .B 32 -.B (filter) +.B (0x20 filter) search filter processing .TP .B 64 -.B (config) +.B (0x40 config) configuration file processing .TP .B 128 -.B (ACL) +.B (0x80 ACL) access control list processing .TP .B 256 -.B (stats) +.B (0x100 stats) stats log connections/operations/results .TP .B 512 -.B (stats2) +.B (0x200 stats2) stats log entries sent .TP .B 1024 -.B (shell) +.B (0x400 shell) print communication with shell backends .TP .B 2048 -.B (parse) +.B (0x800 parse) entry parsing +.TP +.B 4096 +.B (0x1000 cache) +caching (unused) +.TP +.B 8192 +.B (0x2000 index) +data indexing (unused) +.TP +.B 16384 +.B (0x4000 sync) +LDAPSync replication +.TP +.B 32768 +.B (0x8000 none) +only messages that get logged whatever log level is set .PD .RE The desired log level can be input as a single integer that combines -the (ORed) desired levels, as a list of integers (that are ORed internally), +the (ORed) desired levels, both in decimal or in hexadecimal notation, +as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that .LP .nf loglevel 129 + loglevel 0x81 loglevel 128 1 + loglevel 0x80 0x1 loglevel acl trace .fi .LP @@ -575,6 +599,14 @@ are equivalent. The keyword .B any can be used as a shortcut to enable logging at all levels (equivalent to -1). +The keyword +.BR none , +or the equivalent integer representation, causes those messages +that are logged regardless of the configured loglevel to be logged. +In fact, if no loglevel (or a 0 level) is defined, no logging occurs, +so at least the +.B none +level is required to have high priority messages logged. .RE .TP .B moduleload diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 250da6093a..552a0e6245 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -47,6 +47,7 @@ do_add( Operation *op, SlapReply *rs ) char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); int rc = 0; + int freevals = 1; Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 ); /* @@ -175,6 +176,8 @@ do_add( Operation *op, SlapReply *rs ) goto done; } + freevals = 0; + op->o_bd = frontendDB; rc = frontendDB->be_add( op, rs ); if ( rc == 0 ) { @@ -194,7 +197,8 @@ do_add( Operation *op, SlapReply *rs ) done:; if ( modlist != NULL ) { - slap_mods_free( modlist, 0 ); + /* in case of error, free the values as well */ + slap_mods_free( modlist, freevals ); } if ( op->ora_e != NULL ) { diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 6cf4e58f1d..a7273ef7c7 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -51,6 +51,8 @@ bdb_add(Operation *op, SlapReply *rs ) ctrls[num_ctrls] = 0; + /* add opattrs to shadow as well, only missing attrs will actually + * be added; helps compatibility with older OL versions */ slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); /* check entry's schema */ @@ -386,6 +388,7 @@ retry: /* transaction retry */ struct berval nrdn; Entry *e = entry_dup( op->ora_e ); + /* pick the RDN if not suffix; otherwise pick the entire DN */ if (pdn.bv_len) { nrdn.bv_val = e->e_nname.bv_val; nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1; diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c index d3701e1593..9dbb549afc 100644 --- a/servers/slapd/back-bdb/tools.c +++ b/servers/slapd/back-bdb/tools.c @@ -93,10 +93,10 @@ int bdb_tool_entry_open( } } - /* Set up for slapindex */ - if ( !(slapMode & SLAP_TOOL_READONLY )) { - int i; - if ( !bdb_tool_info && ( slapMode & SLAP_TOOL_QUICK )) { + /* Set up for threaded slapindex */ + if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK) { + if ( !bdb_tool_info ) { + int i; ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex ); ldap_pvt_thread_cond_init( &bdb_tool_index_cond ); bdb_tool_index_threads = ch_malloc( slap_tool_thread_max * sizeof( int )); diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c index 8f702c85b9..a0dbb581c2 100644 --- a/servers/slapd/back-ldap/chain.c +++ b/servers/slapd/back-ldap/chain.c @@ -69,6 +69,8 @@ typedef struct ldap_chain_t { #define LDAP_CHAIN_F_NONE 0x00U #define LDAP_CHAIN_F_CHAINING 0x01U + ldap_pvt_thread_mutex_t lc_mutex; + #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl lc_chaining_ctrl; char lc_chaining_ctrlflag; @@ -259,7 +261,10 @@ ldap_chain_op( { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - struct ldapinfo li, *lip = lc->lc_li; + + struct ldapinfo *lip = lc->lc_li; + char *save_url = NULL; + SlapReply rs2 = { 0 }; /* NOTE: returned if ref is empty... */ int rc = LDAP_OTHER; @@ -272,12 +277,14 @@ ldap_chain_op( if ( lip->url != NULL ) { op->o_bd->be_private = lip; - rc = ( *op_f )( op, rs ); + rc = ( *op_f )( op, &rs2 ); + rs->sr_err = rs2.sr_err; goto done; } - li = *lip; - op->o_bd->be_private = &li; + save_url = lip->url; + lip->url = NULL; + op->o_bd->be_private = lip; /* if we parse the URI then by no means * we can cache stuff or reuse connections, @@ -321,26 +328,29 @@ Document: draft-ietf-ldapbis-protocol-27.txt save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.url = ldap_url_desc2str( srv ); + lip->url = ldap_url_desc2str( srv ); srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( li.url == NULL ) { + if ( lip->url == NULL ) { /* try next */ rc = LDAP_OTHER; continue; } - rc = ( *op_f )( op, rs ); + rc = ( *op_f )( op, &rs2 ); + rs->sr_err = rs2.sr_err; - ldap_memfree( li.url ); - li.url = NULL; + ldap_memfree( lip->url ); + lip->url = NULL; if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) { break; } } + lip->url = save_url; + done:; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR (void)chaining_control_remove( op, &ctrls ); @@ -362,7 +372,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) struct berval ndn = op->o_ndn; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; - struct ldapinfo li, *lip = lc->lc_li; + struct ldapinfo *lip = lc->lc_li; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR int sr_err = rs->sr_err; @@ -402,6 +412,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) } #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + ldap_pvt_thread_mutex_lock( &lc->lc_mutex ); + /* * TODO: add checks on who/when chain operations; e.g.: * a) what identities are authorized @@ -441,8 +453,6 @@ ldap_chain_response( Operation *op, SlapReply *rs ) } break; case LDAP_REQ_ADD: - /* slap_mods2entry () should be called in do_add() */ - assert( op->ora_e->e_attrs != NULL ); rc = ldap_chain_op( op, rs, lback->bi_op_add, ref ); break; case LDAP_REQ_DELETE: @@ -462,6 +472,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) struct berval *curr = ref, odn = op->o_req_dn, ondn = op->o_req_ndn; + char *save_url = NULL; + SlapReply rs2 = { 0 }; #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR LDAPControl **ctrls = NULL; @@ -473,9 +485,9 @@ ldap_chain_response( Operation *op, SlapReply *rs ) sc2.sc_response = ldap_chain_cb_search_response; - li = *lip; - li.url = NULL; - op->o_bd->be_private = &li; + save_url = lip->url; + lip->url = NULL; + op->o_bd->be_private = lip; /* if we parse the URI then by no means * we can cache stuff or reuse connections, @@ -504,8 +516,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) save_dn = srv->lud_dn; srv->lud_dn = ""; srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.url = ldap_url_desc2str( srv ); - if ( li.url != NULL ) { + lip->url = ldap_url_desc2str( srv ); + if ( lip->url != NULL ) { ber_str2bv_x( save_dn, 0, 1, &op->o_req_dn, op->o_tmpmemctx ); ber_dupbv_x( &op->o_req_ndn, &op->o_req_dn, @@ -515,7 +527,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) srv->lud_dn = save_dn; ldap_free_urldesc( srv ); - if ( li.url == NULL ) { + if ( lip->url == NULL ) { /* try next */ rs->sr_err = LDAP_OTHER; continue; @@ -524,10 +536,11 @@ ldap_chain_response( Operation *op, SlapReply *rs ) /* FIXME: should we also copy filter and scope? * according to RFC3296, no */ - rc = lback->bi_op_search( op, rs ); + rc = lback->bi_op_search( op, &rs2 ); + rs->sr_err = rs2.sr_err; - ldap_memfree( li.url ); - li.url = NULL; + ldap_memfree( lip->url ); + lip->url = NULL; op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); @@ -545,6 +558,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) (void)chaining_control_remove( op, &ctrls ); #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ + lip->url = save_url; + op->o_req_dn = odn; op->o_req_ndn = ondn; rs->sr_type = REP_SEARCHREF; @@ -613,6 +628,8 @@ dont_chain:; op->o_ndn = ndn; rs->sr_ref = ref; + ldap_pvt_thread_mutex_unlock( &lc->lc_mutex ); + return rc; } @@ -1074,6 +1091,8 @@ ldap_chain_db_init( lc = ch_malloc( sizeof( ldap_chain_t ) ); memset( lc, 0, sizeof( ldap_chain_t ) ); + ldap_pvt_thread_mutex_init( &lc->lc_mutex ); + bd.be_private = NULL; rc = lback->bi_db_init( &bd ); lc->lc_li = (struct ldapinfo *)bd.be_private; @@ -1108,7 +1127,7 @@ ldap_chain_db_destroy( be->be_private = (void *)lc->lc_li; rc = lback->bi_db_destroy( be ); - lc->lc_li = be->be_private; + ldap_pvt_thread_mutex_destroy( &lc->lc_mutex ); ch_free( lc ); on->on_bi.bi_private = NULL; be->be_private = private; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index ccd058c2a4..d621b43307 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -61,19 +61,17 @@ meta_back_search_start( struct berval mfilter = BER_BVNULL; char **mapped_attrs = NULL; int rc; + struct timeval tv, *tvp = NULL; /* should we check return values? */ if ( op->ors_deref != -1 ) { ldap_set_option( msc->msc_ld, LDAP_OPT_DEREF, - ( void * )&op->ors_deref); + ( void * )&op->ors_deref ); } + if ( op->ors_tlimit != SLAP_NO_LIMIT ) { - ldap_set_option( msc->msc_ld, LDAP_OPT_TIMELIMIT, - ( void * )&op->ors_tlimit); - } - if ( op->ors_slimit != SLAP_NO_LIMIT ) { - ldap_set_option( msc->msc_ld, LDAP_OPT_SIZELIMIT, - ( void * )&op->ors_slimit); + tv.tv_sec = op->ors_tlimit > 0 ? op->ors_tlimit : 1; + tvp = &tv; } dc->target = &mi->mi_targets[ candidate ]; @@ -210,7 +208,7 @@ meta_back_search_start( rc = ldap_search_ext( msc->msc_ld, mbase.bv_val, realscope, mfilter.bv_val, mapped_attrs, op->ors_attrsonly, - op->o_ctrls, NULL, NULL, op->ors_slimit, + op->o_ctrls, NULL, tvp, op->ors_slimit, &candidates[ candidate ].sr_msgid ); if ( rc == LDAP_SUCCESS ) { rc = 1; diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 4eddc8310b..942749519c 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -162,7 +162,7 @@ static struct slap_control control_defs[] = { #ifdef LDAP_DEVEL { LDAP_CONTROL_MANAGEDIT, (int)offsetof(struct slap_control_ids, sc_manageDIT), - SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE, NULL, + SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL, parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) }, #endif { LDAP_CONTROL_MANAGEDSAIT, diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 561b5b2fd1..10ce96d7c5 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1222,7 +1222,6 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on ) Operation opm; struct berval bv[2]; slap_callback cb = {0}; - int manage = get_manageDSAit(op); mod.sml_values = bv; bv[1].bv_val = NULL; @@ -1243,7 +1242,9 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on ) opm.o_bd->bd_info = on->on_info->oi_orig; opm.o_managedsait = SLAP_CONTROL_NONCRITICAL; opm.o_bd->be_modify( &opm, rs ); - opm.o_managedsait = manage; + if ( mod.sml_next != NULL ) { + slap_mods_free( mod.sml_next, 1 ); + } } static void diff --git a/tests/progs/slapd-addel.c b/tests/progs/slapd-addel.c index 082a7aa3d5..456bb78475 100644 --- a/tests/progs/slapd-addel.c +++ b/tests/progs/slapd-addel.c @@ -41,7 +41,8 @@ get_add_entry( char *filename, LDAPMod ***mods ); static void do_addel( char *uri, char *host, int port, char *manager, char *passwd, - char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay ); + char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay, + int friendly ); static void usage( char *name ) @@ -73,10 +74,15 @@ main( int argc, char **argv ) int loops = LOOPS; int retries = RETRIES; int delay = 0; + int friendly = 0; LDAPMod **attrs = NULL; - while ( (i = getopt( argc, argv, "H:h:p:D:w:f:l:r:t:" )) != EOF ) { + while ( (i = getopt( argc, argv, "FH:h:p:D:w:f:l:r:t:" )) != EOF ) { switch( i ) { + case 'F': + friendly++; + break; + case 'H': /* the server's URI */ uri = strdup( optarg ); break; @@ -141,7 +147,7 @@ main( int argc, char **argv ) } do_addel( uri, host, port, manager, passwd, entry, attrs, - loops, retries, delay ); + loops, retries, delay, friendly ); exit( EXIT_SUCCESS ); } @@ -272,7 +278,8 @@ do_addel( LDAPMod **attrs, int maxloop, int maxretries, - int delay + int delay, + int friendly ) { LDAP *ld = NULL; @@ -328,12 +335,27 @@ retry:; rc = ldap_add_s( ld, entry, attrs ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_add" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; - } - break; + switch ( rc ) { + case LDAP_ALREADY_EXISTS: + /* NOTE: this likely means + * the delete failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + default: + goto done; + } } #if 0 @@ -346,14 +368,31 @@ retry:; rc = ldap_delete_s( ld, entry ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_delete" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; + switch ( rc ) { + case LDAP_NO_SUCH_OBJECT: + /* NOTE: this likely means + * the add failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + + default: + goto done; } - break; } } +done:; fprintf( stderr, " PID=%ld - Add/Delete done (%d).\n", (long) pid, rc ); ldap_unbind( ld ); diff --git a/tests/progs/slapd-modify.c b/tests/progs/slapd-modify.c index c0484dbc5c..03ac37549d 100644 --- a/tests/progs/slapd-modify.c +++ b/tests/progs/slapd-modify.c @@ -35,7 +35,7 @@ static void do_modify( char *uri, char *host, int port, char *manager, char *passwd, char *entry, char *attr, char *value, int maxloop, - int maxretries, int delay ); + int maxretries, int delay, int friendly ); static void @@ -69,9 +69,14 @@ main( int argc, char **argv ) int loops = LOOPS; int retries = RETRIES; int delay = 0; + int friendly = 0; - while ( (i = getopt( argc, argv, "H:h:p:D:w:e:a:l:r:t:" )) != EOF ) { + while ( (i = getopt( argc, argv, "FH:h:p:D:w:e:a:l:r:t:" )) != EOF ) { switch( i ) { + case 'F': + friendly++; + break; + case 'H': /* the server uri */ uri = strdup( optarg ); break; @@ -144,7 +149,7 @@ main( int argc, char **argv ) value++; do_modify( uri, host, port, manager, passwd, entry, ava, value, - loops, retries, delay ); + loops, retries, delay, friendly ); exit( EXIT_SUCCESS ); } @@ -152,7 +157,7 @@ main( int argc, char **argv ) static void do_modify( char *uri, char *host, int port, char *manager, char *passwd, char *entry, char* attr, char* value, - int maxloop, int maxretries, int delay ) + int maxloop, int maxretries, int delay, int friendly ) { LDAP *ld = NULL; int i = 0, do_retry = maxretries; @@ -220,28 +225,59 @@ retry:; rc = ldap_modify_s( ld, entry, mods ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modify" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; + switch ( rc ) { + case LDAP_TYPE_OR_VALUE_EXISTS: + /* NOTE: this likely means + * the second modify failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + + default: + goto done; } - if ( rc != LDAP_NO_SUCH_OBJECT ) break; - continue; } mod.mod_op = LDAP_MOD_DELETE; rc = ldap_modify_s( ld, entry, mods ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modify" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; + switch ( rc ) { + case LDAP_NO_SUCH_ATTRIBUTE: + /* NOTE: this likely means + * the first modify failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + + default: + goto done; } - if ( rc != LDAP_NO_SUCH_OBJECT ) break; - continue; } } +done:; fprintf( stderr, " PID=%ld - Modify done (%d).\n", (long) pid, rc ); ldap_unbind( ld ); diff --git a/tests/progs/slapd-modrdn.c b/tests/progs/slapd-modrdn.c index 06b5130442..1522b864f3 100644 --- a/tests/progs/slapd-modrdn.c +++ b/tests/progs/slapd-modrdn.c @@ -38,7 +38,8 @@ static void do_modrdn( char *uri, char *host, int port, char *manager, char *passwd, - char *entry, int maxloop, int maxretries, int delay ); + char *entry, int maxloop, int maxretries, int delay, + int friendly ); static void usage( char *name ) @@ -69,9 +70,14 @@ main( int argc, char **argv ) int loops = LOOPS; int retries = RETRIES; int delay = 0; + int friendly = 0; - while ( (i = getopt( argc, argv, "H:h:p:D:w:e:l:r:t:" )) != EOF ) { + while ( (i = getopt( argc, argv, "FH:h:p:D:w:e:l:r:t:" )) != EOF ) { switch( i ) { + case 'F': + friendly++; + break; + case 'H': /* the server uri */ uri = strdup( optarg ); break; @@ -125,14 +131,16 @@ main( int argc, char **argv ) } - do_modrdn( uri, host, port, manager, passwd, entry, loops, retries, delay ); + do_modrdn( uri, host, port, manager, passwd, entry, + loops, retries, delay, friendly ); exit( EXIT_SUCCESS ); } static void do_modrdn( char *uri, char *host, int port, char *manager, - char *passwd, char *entry, int maxloop, int maxretries, int delay ) + char *passwd, char *entry, int maxloop, int maxretries, int delay, + int friendly ) { LDAP *ld = NULL; int i = 0, do_retry = maxretries; @@ -211,25 +219,56 @@ retry:; rc = ldap_modrdn2_s( ld, DNs[0], rdns[0], 0 ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; + switch ( rc ) { + case LDAP_NO_SUCH_OBJECT: + /* NOTE: this likely means + * the second modrdn failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + + default: + goto done; } - if ( rc != LDAP_NO_SUCH_OBJECT ) break; - continue; } rc = ldap_modrdn2_s( ld, DNs[1], rdns[1], 1 ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); - if ( rc == LDAP_BUSY && do_retry > 0 ) { - do_retry--; - goto retry; + switch ( rc ) { + case LDAP_NO_SUCH_OBJECT: + /* NOTE: this likely means + * the first modrdn failed + * during the previous round... */ + if ( !friendly ) { + goto done; + } + break; + + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + if ( do_retry > 0 ) { + do_retry--; + goto retry; + } + /* fall thru */ + + default: + goto done; } - if ( rc != LDAP_NO_SUCH_OBJECT ) break; - continue; } } +done:; fprintf( stderr, " PID=%ld - Modrdn done (%d).\n", (long) pid, rc ); ldap_unbind( ld ); diff --git a/tests/progs/slapd-tester.c b/tests/progs/slapd-tester.c index c8d4d57f25..e49947198b 100644 --- a/tests/progs/slapd-tester.c +++ b/tests/progs/slapd-tester.c @@ -80,8 +80,9 @@ usage( char *name ) "[-j ] " "[-l ] " "-P " - "[-r ]" - "[-t ]\n", + "[-r ] " + "[-t ] " + "[-F]\n", name ); exit( EXIT_FAILURE ); } @@ -133,8 +134,9 @@ main( int argc, char **argv ) char *modreqs[MAXREQS]; char *moddn[MAXREQS]; int modnum = 0; + int friendly = 0; - while ( (i = getopt( argc, argv, "D:d:H:h:j:l:P:p:r:t:w:" )) != EOF ) { + while ( (i = getopt( argc, argv, "D:d:FH:h:j:l:P:p:r:t:w:" )) != EOF ) { switch( i ) { case 'D': /* slapd manager */ manager = ArgDup( optarg ); @@ -144,6 +146,10 @@ main( int argc, char **argv ) dirname = strdup( optarg ); break; + case 'F': + friendly++; + break; + case 'H': /* slapd uri */ uri = strdup( optarg ); break; @@ -332,6 +338,9 @@ main( int argc, char **argv ) margs[manum++] = retries; margs[manum++] = "-t"; margs[manum++] = delay; + if ( friendly ) { + margs[manum++] = "-F"; + } margs[manum++] = "-e"; margs[manum++] = NULL; /* will hold the modrdn entry */ margs[manum++] = NULL; @@ -363,6 +372,9 @@ main( int argc, char **argv ) modargs[modanum++] = retries; modargs[modanum++] = "-t"; modargs[modanum++] = delay; + if ( friendly ) { + modargs[modanum++] = "-F"; + } modargs[modanum++] = "-e"; modargs[modanum++] = NULL; /* will hold the modify entry */ modargs[modanum++] = "-a";; @@ -396,6 +408,9 @@ main( int argc, char **argv ) aargs[aanum++] = retries; aargs[aanum++] = "-t"; aargs[aanum++] = delay; + if ( friendly ) { + aargs[aanum++] = "-F"; + } aargs[aanum++] = "-f"; aargs[aanum++] = NULL; /* will hold the add data file */ aargs[aanum++] = NULL; diff --git a/tests/scripts/test036-meta-concurrency b/tests/scripts/test036-meta-concurrency index 1aeaa205a3..a75253a514 100755 --- a/tests/scripts/test036-meta-concurrency +++ b/tests/scripts/test036-meta-concurrency @@ -185,7 +185,8 @@ for f in $TESTDIR/$DATADIR/do_read.* ; do done echo "Using tester for concurrent server access..." -$SLAPDTESTER -P "$PROGDIR" -d "$TESTDIR/$DATADIR" -h $LOCALHOST -p $PORT3 -D "cn=Manager,$METABASEDN" -w $PASSWD -l 50 # -r 20 +$SLAPDTESTER -P "$PROGDIR" -d "$TESTDIR/$DATADIR" -h $LOCALHOST -p $PORT3 \ + -D "cn=Manager,$METABASEDN" -w $PASSWD -l 50 -r 20 -F RC=$? if test $RC != 0 ; then diff --git a/tests/scripts/test039-glue-ldap-concurrency b/tests/scripts/test039-glue-ldap-concurrency index d395d6b59a..24f022167f 100755 --- a/tests/scripts/test039-glue-ldap-concurrency +++ b/tests/scripts/test039-glue-ldap-concurrency @@ -162,7 +162,8 @@ for f in $TESTDIR/$DATADIR/do_read.* ; do done echo "Using tester for concurrent server access..." -$SLAPDTESTER -P "$PROGDIR" -d "$TESTDIR/$DATADIR" -h $LOCALHOST -p $PORT3 -D "cn=Manager,$METABASEDN" -w $PASSWD -l 50 # -r 20 +$SLAPDTESTER -P "$PROGDIR" -d "$TESTDIR/$DATADIR" -h $LOCALHOST -p $PORT3 \ + -D "cn=Manager,$METABASEDN" -w $PASSWD -l 50 -r 20 -F RC=$? if test $RC != 0 ; then -- 2.39.5