]> git.sur5r.net Git - openldap/commitdiff
add "report" to "onerr" modes: continue a search in case one target returns an error...
authorPierangelo Masarati <ando@openldap.org>
Thu, 23 Nov 2006 23:50:36 +0000 (23:50 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 23 Nov 2006 23:50:36 +0000 (23:50 +0000)
doc/man/man5/slapd-meta.5
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/config.c
servers/slapd/back-meta/search.c

index 02b8ce635b8eac42ed3527d94227bb20f3a4d164..fd15479b0cb1587e4dd4a4b25697f4bbf031ac41 100644 (file)
@@ -115,14 +115,17 @@ illustrated for the
 directive.
 
 .TP
-.B onerr {CONTINUE|stop}
+.B onerr {CONTINUE|report|stop}
 This directive allows to select the behavior in case an error is returned
 by one target during a search.
 The default, \fBcontinue\fP, consists in continuing the operation, 
 trying to return as much data as possible.
-If this statement is set to \fBstop\fP, the search is terminated as soon 
+If the value is set to \fBstop\fP, the search is terminated as soon 
 as an error is returned by one target, and the error is immediately 
 propagated to the client.
+If the value is set to \fBreport\fP, the search is continuated to the end
+but, in case at least one target returned an error code, the first
+non-success error code is returned.
 
 .TP
 .B protocol\-version {0,2,3}
index b7a8079d5ba1ac4202d88709c593a082d515d81a..4d367674fc84cea279a460fbee5ca51edcc94045 100644 (file)
@@ -330,10 +330,13 @@ typedef struct metainfo_t {
 #define        li_flags                mi_flags
 /* uses flags as defined in <back-ldap/back-ldap.h> */
 #define        META_BACK_F_ONERR_STOP          (0x00010000U)
-#define        META_BACK_F_DEFER_ROOTDN_BIND   (0x00020000U)
+#define        META_BACK_F_ONERR_REPORT        (0x00020000U)
+#define        META_BACK_F_ONERR_MASK          (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT)
+#define        META_BACK_F_DEFER_ROOTDN_BIND   (0x00040000U)
 
 #define        META_BACK_ONERR_STOP(mi)        ( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
-#define        META_BACK_ONERR_CONTINUE(mi)    ( !META_BACK_ONERR_CONTINUE( (mi) ) )
+#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_DEFER_ROOTDN_BIND(mi)        ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
 
index 70d6a179a8f74ea3a7b4c4f1f2166c0a338db311..6ae4b3ba5fb21091eb3e43e8010a66921abcf377 100644 (file)
@@ -769,20 +769,23 @@ meta_back_db_config(
        } else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
                if ( argc != 2 ) {
                        Debug( LDAP_DEBUG_ANY,
-       "%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n",
+       "%s: line %d: \"onerr {CONTINUE|report|stop}\" takes 1 argument\n",
                                fname, lineno, 0 );
                        return( 1 );
                }
 
                if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
-                       mi->mi_flags &= ~META_BACK_F_ONERR_STOP;
+                       mi->mi_flags &= ~META_BACK_F_ONERR_MASK;
 
                } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
                        mi->mi_flags |= META_BACK_F_ONERR_STOP;
 
+               } else if ( strcasecmp( argv[ 1 ], "report" ) == 0 ) {
+                       mi->mi_flags |= META_BACK_F_ONERR_REPORT;
+
                } else {
                        Debug( LDAP_DEBUG_ANY,
-       "%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n",
+       "%s: line %d: \"onerr {CONTINUE|report|stop}\": invalid arg \"%s\".\n",
                                fname, lineno, argv[ 1 ] );
                        return 1;
                }
index c3c0eb01e15673d269ccbe2eb0dbd22e9f86631b..39e886b8222f3c8f56c0002df976026e407e0185 100644 (file)
@@ -277,6 +277,10 @@ other:;
                        retcode = META_SEARCH_ERR;
 
                } else {
+                       if ( META_BACK_ONERR_REPORT( mi ) ) {
+                               candidates[ candidate ].sr_err = rc;
+                       }
+
                        retcode = META_SEARCH_NOT_CANDIDATE;
                }
                candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
@@ -322,6 +326,9 @@ meta_search_dobind_result(
                        meta_back_release_conn( op, mc );
                        *mcp = NULL;
                        retcode = META_SEARCH_ERR;
+
+               } else if ( META_BACK_ONERR_REPORT( mi ) ) {
+                       candidates[ candidate ].sr_err = rc;
                }
 
        } else {
@@ -377,6 +384,9 @@ meta_back_search_start(
                if ( META_BACK_ONERR_STOP( mi ) ) {
                        return META_SEARCH_ERR;
                }
+               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                       candidates[ candidate ].sr_err = LDAP_OTHER;
+               }
                candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
                return META_SEARCH_NOT_CANDIDATE;
        }
@@ -837,6 +847,9 @@ getconn:;
                                                op->o_private = savepriv;
                                                goto finish;
                                        }
+                                       if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                               candidates[ i ].sr_err = rs->sr_err;
+                                       }
                                        /* fallthru */
 
                                case META_SEARCH_NOT_CANDIDATE:
@@ -865,6 +878,9 @@ getconn:;
                                                        op->o_private = savepriv;
                                                        goto finish;
                                                }
+                                               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                                       candidates[ i ].sr_err = rs->sr_err;
+                                               }
                                                /* fallthru */
 
                                        case META_SEARCH_NOT_CANDIDATE:
@@ -954,6 +970,9 @@ really_bad:;
                                                                op->o_private = savepriv;
                                                                goto finish;
                                                        }
+                                                       if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                                               candidates[ i ].sr_err = rs->sr_err;
+                                                       }
                                                        break;
 
                                                case META_SEARCH_BINDING:
@@ -975,6 +994,9 @@ really_bad:;
                                                op->o_private = savepriv;
                                                goto finish;
                                        }
+                                       if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                               candidates[ i ].sr_err = rs->sr_err;
+                                       }
                                }
 
                                /*
@@ -1131,7 +1153,7 @@ really_bad:;
                                                0 );
                                        if ( rs->sr_err != LDAP_SUCCESS ) {
                                                ldap_get_option( msc->msc_ld,
-                                                       LDAP_OPT_RESULT_CODE,
+                                                       LDAP_OPT_ERROR_NUMBER,
                                                        &rs->sr_err );
                                                sres = slap_map_api2result( rs );
                                                candidates[ i ].sr_type = REP_RESULT;
@@ -1252,6 +1274,9 @@ really_bad:;
                                                        res = NULL;
                                                        goto finish;
                                                }
+                                               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                                       candidates[ i ].sr_err = rs->sr_err;
+                                               }
                                                break;
        
                                        default:
@@ -1264,6 +1289,9 @@ really_bad:;
                                                        res = NULL;
                                                        goto finish;
                                                }
+                                               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                                       candidates[ i ].sr_err = rs->sr_err;
+                                               }
                                                break;
                                        }
        
@@ -1305,6 +1333,9 @@ really_bad:;
                                                        res = NULL;
                                                        goto finish;
                                                }
+                                               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                                                       candidates[ i ].sr_err = rs->sr_err;
+                                               }
                                                break;
        
                                        default:
@@ -1526,14 +1557,35 @@ really_bad:;
        /*
         * In case we returned at least one entry, we return LDAP_SUCCESS
         * otherwise, the latter error code we got
-        *
-        * FIXME: we should handle error codes and return the more 
-        * important/reasonable
         */
 
-       if ( sres == LDAP_SUCCESS && rs->sr_v2ref ) {
-               sres = LDAP_REFERRAL;
+       if ( sres == LDAP_SUCCESS ) {
+               if ( rs->sr_v2ref ) {
+                       sres = LDAP_REFERRAL;
+               }
+
+               if ( META_BACK_ONERR_REPORT( mi ) ) {
+                       /*
+                        * Report errors, if any
+                        *
+                        * FIXME: we should handle error codes and return the more 
+                        * important/reasonable
+                        */
+                       for ( i = 0; i < mi->mi_ntargets; i++ ) {
+                               if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) {
+                                       continue;
+                               }
+
+                               if ( candidates[ i ].sr_err != LDAP_SUCCESS
+                                       && candidates[ i ].sr_err != LDAP_NO_SUCH_OBJECT )
+                               {
+                                       sres = candidates[ i ].sr_err;
+                                       break;
+                               }
+                       }
+               }
        }
+
        rs->sr_err = sres;
        rs->sr_matched = matched;
        rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL );