]> git.sur5r.net Git - openldap/commitdiff
improve timeout support (ITS#4157, ITS#4663)
authorPierangelo Masarati <ando@openldap.org>
Mon, 4 Sep 2006 08:26:09 +0000 (08:26 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 4 Sep 2006 08:26:09 +0000 (08:26 +0000)
doc/man/man5/slapd-meta.5
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/delete.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/modrdn.c

index 58d67604391382d490469c6c9835bf25705d9105..95a1603552570ae2740d197350ae268e5b7112d6 100644 (file)
@@ -68,17 +68,16 @@ lastmod  off
 .fi
 .RE
 .LP
-for every
+for 
 .B ldap
 and
 .B meta
-database.
-This is because operational attributes related to entry creation and
-modification should not be proxied, as they could be mistakenly written
+databases.
+This was required because operational attributes related to entry creation 
+and modification should not be proxied, as they could be mistakenly written
 to the target server(s), generating an error.
-The current implementation automatically sets lastmod to off, so its use
-is redundant and should be omitted, because the lastmod directive will
-be deprecated in the future.
+The current implementation automatically sets lastmod to \fBoff\fP, 
+so its use is redundant and should be omitted.
 
 .SH SPECIAL CONFIGURATION DIRECTIVES
 Target configuration starts with the "uri" directive.
index 311b6d2f041e9e6e400b311d0ecaf3a886f4a53c..66afd66e11aa6e209199c9d9f8acff1c3b0d36f3 100644 (file)
@@ -179,7 +179,7 @@ retry:;
        rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
                              attrs, ctrls, NULL, &msgid );
        rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
-               mt->mt_timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
+               mt->mt_timeout[ SLAP_OP_ADD ], LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
index c752a7d8d69205197ddf6c02ef857c0fa8b49007..f337ea551afe8c394accfec1d7687f366c183023 100644 (file)
@@ -273,7 +273,7 @@ typedef struct metatarget_t {
        time_t                  mt_network_timeout;
        struct timeval          mt_bind_timeout;
 #define META_BIND_TIMEOUT      LDAP_BACK_RESULT_UTIMEOUT
-       time_t                  mt_timeout[ LDAP_BACK_OP_LAST ];
+       time_t                  mt_timeout[ SLAP_OP_LAST ];
 } metatarget_t;
 
 typedef struct metadncache_t {
@@ -334,7 +334,7 @@ typedef struct metainfo_t {
        time_t                  mi_conn_ttl;
        time_t                  mi_idle_timeout;
        struct timeval          mi_bind_timeout;
-       time_t                  mi_timeout[ LDAP_BACK_OP_LAST ];
+       time_t                  mi_timeout[ SLAP_OP_LAST ];
 } metainfo_t;
 
 typedef enum meta_op_type {
index ca85a9202c51a0dbeba9cf95682a7fd79c37c30b..6d2f75d739d77da054e61f78b19d08f4934b59cb 100644 (file)
@@ -319,6 +319,43 @@ meta_back_bind_op_result(
                op->o_log_prefix, candidate, 0 );
 
        if ( rs->sr_err == LDAP_SUCCESS ) {
+               time_t          stoptime = (time_t)(-1),
+                               timeout;
+               int             timeout_err = op->o_protocol >= LDAP_VERSION3 ?
+                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
+               const char      *timeout_text = "Operation timed out";
+               slap_op_t       opidx = slap_req2op( op->o_tag );
+
+               /* since timeout is not specified, compute and use
+                * the one specific to the ongoing operation */
+               if ( opidx == LDAP_REQ_SEARCH ) {
+                       if ( op->ors_tlimit <= 0 ) {
+                               timeout = 0;
+
+                       } else {
+                               timeout = op->ors_tlimit;
+                               timeout_err = LDAP_TIMELIMIT_EXCEEDED;
+                               timeout_text = NULL;
+                       }
+
+               } else {
+                       timeout = mt->mt_timeout[ opidx ];
+               }
+
+               /* better than nothing :) */
+               if ( timeout == 0 ) {
+                       if ( mi->mi_idle_timeout ) {
+                               timeout = mi->mi_idle_timeout;
+
+                       } else if ( mi->mi_conn_ttl ) {
+                               timeout = mi->mi_conn_ttl;
+                       }
+               }
+
+               if ( timeout ) {
+                       stoptime = op->o_time + timeout;
+               }
+
                LDAP_BACK_TV_SET( &tv );
 
                /*
@@ -328,11 +365,15 @@ retry:;
                rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
                switch ( rc ) {
                case 0:
+#if 0
                        Debug( LDAP_DEBUG_ANY,
                                "%s meta_back_bind_op_result[%d]: ldap_result=0 nretries=%d.\n",
                                op->o_log_prefix, candidate, nretries );
+#endif
 
-                       if ( nretries != META_RETRY_NEVER ) {
+                       if ( nretries != META_RETRY_NEVER 
+                               || ( timeout && slap_get_time() <= stoptime ) )
+                       {
                                ldap_pvt_thread_yield();
                                if ( nretries > 0 ) {
                                        nretries--;
@@ -341,16 +382,17 @@ retry:;
                                goto retry;
                        }
 
-                       /* FIXME: binds cannot be abandoned */
                        /* don't let anyone else use this handler,
                         * because there's a pending bind that will not
                         * be acknowledged */
                        ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
                        ldap_unbind_ext( msc->msc_ld, NULL, NULL );
                        msc->msc_ld = NULL;
-                       rs->sr_err = LDAP_BUSY;
                        LDAP_BACK_CONN_BINDING_CLEAR( msc );
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+
+                       rs->sr_err = timeout_err;
+                       rs->sr_text = timeout_text;
                        break;
 
                case -1:
@@ -876,24 +918,55 @@ meta_back_op_result(
                        int             rc;
                        struct timeval  tv;
                        LDAPMessage     *res = NULL;
+                       time_t          stoptime = (time_t)(-1);
+                       int             timeout_err = op->o_protocol >= LDAP_VERSION3 ?
+                                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
+                       const char      *timeout_text = "Operation timed out";
 
-                       if ( timeout ) {
-                               tv.tv_sec = timeout;
-                               tv.tv_usec = 0;
+                       /* if timeout is not specified, compute and use
+                        * the one specific to the ongoing operation */
+                       if ( timeout == (time_t)(-1) ) {
+                               slap_op_t       opidx = slap_req2op( op->o_tag );
 
-                       } else {
-                               LDAP_BACK_TV_SET( &tv );
+                               if ( opidx == SLAP_OP_SEARCH ) {
+                                       if ( op->ors_tlimit <= 0 ) {
+                                               timeout = 0;
+
+                                       } else {
+                                               timeout = op->ors_tlimit;
+                                               timeout_err = LDAP_TIMELIMIT_EXCEEDED;
+                                               timeout_text = NULL;
+                                       }
+
+                               } else {
+                                       timeout = mt->mt_timeout[ opidx ];
+                               }
                        }
 
+                       /* better than nothing :) */
+                       if ( timeout == 0 ) {
+                               if ( mi->mi_idle_timeout ) {
+                                       timeout = mi->mi_idle_timeout;
+
+                               } else if ( mi->mi_conn_ttl ) {
+                                       timeout = mi->mi_conn_ttl;
+                               }
+                       }
+
+                       if ( timeout ) {
+                               stoptime = op->o_time + timeout;
+                       }
+
+                       LDAP_BACK_TV_SET( &tv );
+
 retry:;
                        rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
                        switch ( rc ) {
                        case 0:
-                               if ( timeout ) {
+                               if ( timeout && slap_get_time() > stoptime ) {
                                        (void)meta_back_cancel( mc, op, rs, msgid, candidate, sendok );
-                                       rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
-                                               LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
-                                       rs->sr_text = "Operation timed out";
+                                       rs->sr_err = timeout_err;
+                                       rs->sr_text = timeout_text;
                                        break;
                                }
 
index 3fd0b2dbed0dc0688305768ca34339135403c5f8..70d6a179a8f74ea3a7b4c4f1f2166c0a338db311 100644 (file)
@@ -186,7 +186,7 @@ meta_back_db_config(
                mt->mt_version = mi->mi_version;
                mt->mt_network_timeout = mi->mi_network_timeout;
                mt->mt_bind_timeout = mi->mi_bind_timeout;
-               for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
+               for ( c = 0; c < SLAP_OP_LAST; c++ ) {
                        mt->mt_timeout[ c ] = mi->mi_timeout[ c ];
                }
 
@@ -890,7 +890,7 @@ meta_back_db_config(
 
                if ( argc < 2 ) {
                        Debug( LDAP_DEBUG_ANY,
-       "%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
+       "%s: line %d: \"timeout [{add|bind|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
                                fname, lineno, 0 );
                        return( 1 );
                }
@@ -903,19 +903,33 @@ meta_back_db_config(
                        if ( sep != NULL ) {
                                size_t  len = sep - argv[ c ];
 
-                               if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
-                                       t = &tv[ LDAP_BACK_OP_ADD ];
+                               if ( strncasecmp( argv[ c ], "bind", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_BIND ];
+                               /* unbind makes little sense */
+                               } else if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_ADD ];
                                } else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
-                                       t = &tv[ LDAP_BACK_OP_DELETE ];
-                               } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
-                                       t = &tv[ LDAP_BACK_OP_MODIFY ];
+                                       t = &tv[ SLAP_OP_DELETE ];
                                } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
-                                       t = &tv[ LDAP_BACK_OP_MODRDN ];
+                                       t = &tv[ SLAP_OP_MODRDN ];
+                               } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_MODIFY ];
+                               } else if ( strncasecmp( argv[ c ], "compare", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_COMPARE ];
+#if 0                          /* uses timelimit instead */
+                               } else if ( strncasecmp( argv[ c ], "search", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_SEARCH ];
+#endif
+                               /* abandon makes little sense */
+#if 0                          /* not implemented yet */
+                               } else if ( strncasecmp( argv[ c ], "extended", len ) == 0 ) {
+                                       t = &tv[ SLAP_OP_EXTENDED ];
+#endif
                                } else {
                                        char    buf[ SLAP_TEXT_BUFLEN ];
                                        snprintf( buf, sizeof( buf ),
-                                               "unknown operation \"%s\" for timeout #%d",
-                                               argv[ c ], c );
+                                               "unknown/unhandled operation \"%s\" for timeout #%d",
+                                               argv[ c ], c - 1 );
                                        Debug( LDAP_DEBUG_ANY,
                                                "%s: line %d: %s.\n",
                                                fname, lineno, buf );
@@ -940,7 +954,7 @@ meta_back_db_config(
                        } else {
                                int     i;
        
-                               for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
+                               for ( i = 0; i < SLAP_OP_LAST; i++ ) {
                                        tv[ i ] = (time_t)val;
                                }
                        }
index 2d7ee6745496dd382f7912929f1988f910babc2a..586f4bcffe997a6387daf6de3a4ffc5814df9db5 100644 (file)
@@ -77,7 +77,7 @@ retry:;
        rs->sr_err = ldap_delete_ext( mc->mc_conns[ candidate ].msc_ld,
                        mdn.bv_val, ctrls, NULL, &msgid );
        rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
-               mt->mt_timeout[ LDAP_BACK_OP_DELETE ], LDAP_BACK_SENDRESULT );
+               mt->mt_timeout[ SLAP_OP_DELETE ], LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
index bde4dd220a9f0c122a7c2dadfce4d10831b1e66c..437d744c92b3f3e214544ff637ccd8980f392add 100644 (file)
@@ -188,7 +188,7 @@ retry:;
        rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
                        modv, ctrls, NULL, &msgid );
        rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
-               mt->mt_timeout[ LDAP_BACK_OP_MODIFY ], LDAP_BACK_SENDRESULT );
+               mt->mt_timeout[ SLAP_OP_MODIFY ], LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
index 1ec273a9bb8dac32abca6699c65761df1643b6c8..c009afc84c205d7448a8881b185f153d12e4b144 100644 (file)
@@ -132,7 +132,7 @@ retry:;
                        mnewSuperior.bv_val, op->orr_deleteoldrdn,
                        ctrls, NULL, &msgid );
        rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
-               mt->mt_timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
+               mt->mt_timeout[ SLAP_OP_MODRDN ], LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {