X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fbackglue.c;h=b7bff32748e4029029f57192a522b27dd96e548b;hb=e229b7c3984c026a8b5b84dfe8355801d21f4a3b;hp=c12d4de4e1fe63b408b9d1b8b30c8ff2f13e394f;hpb=294da7ed11a9a5721b15d0ed81682f123e20cbb0;p=openldap diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index c12d4de4e1..b7bff32748 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2001-2008 The OpenLDAP Foundation. + * Copyright 2001-2009 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,8 @@ static slap_overinst glue; static int glueMode; static BackendDB *glueBack; +static BackendDB glueBackDone; +#define GLUEBACK_DONE (&glueBackDone) static slap_response glue_op_response; @@ -435,16 +437,19 @@ glue_op_search ( Operation *op, SlapReply *rs ) if (scope0 == LDAP_SCOPE_ONELEVEL && dn_match(pdn, &ndn)) { + struct berval mdn, mndn; op->ors_scope = LDAP_SCOPE_BASE; - op->o_req_dn = op->o_bd->be_suffix[0]; - op->o_req_ndn = op->o_bd->be_nsuffix[0]; + mdn = op->o_req_dn = op->o_bd->be_suffix[0]; + mndn = op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search(op, rs); if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) { gs.err = LDAP_SUCCESS; } op->ors_scope = LDAP_SCOPE_ONELEVEL; - op->o_req_dn = dn; - op->o_req_ndn = ndn; + if ( op->o_req_dn.bv_val == mdn.bv_val ) + op->o_req_dn = dn; + if ( op->o_req_ndn.bv_val == mndn.bv_val ) + op->o_req_ndn = ndn; } else if (scope0 == LDAP_SCOPE_SUBTREE && dn_match(&op->o_bd->be_nsuffix[0], &ndn)) @@ -454,14 +459,17 @@ glue_op_search ( Operation *op, SlapReply *rs ) } else if (scope0 == LDAP_SCOPE_SUBTREE && dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn)) { - op->o_req_dn = op->o_bd->be_suffix[0]; - op->o_req_ndn = op->o_bd->be_nsuffix[0]; + struct berval mdn, mndn; + mdn = op->o_req_dn = op->o_bd->be_suffix[0]; + mndn = op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = glue_sub_search( op, rs, b0, on ); if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) { gs.err = LDAP_SUCCESS; } - op->o_req_dn = dn; - op->o_req_ndn = ndn; + if ( op->o_req_dn.bv_val == mdn.bv_val ) + op->o_req_dn = dn; + if ( op->o_req_ndn.bv_val == mndn.bv_val ) + op->o_req_ndn = ndn; } else if (dnIsSuffix(&ndn, &op->o_bd->be_nsuffix[0])) { rs->sr_err = glue_sub_search( op, rs, b0, on ); @@ -524,22 +532,21 @@ end_of_loop:; op->ors_scope = scope0; op->ors_tlimit = tlimit0; op->o_time = starttime; - op->o_req_dn = dn; - op->o_req_ndn = ndn; break; } + + op->o_callback = cb.sc_next; if ( op->o_abandon ) { rs->sr_err = SLAPD_ABANDON; } else { - op->o_callback = cb.sc_next; rs->sr_err = gs.err; rs->sr_matched = gs.matched; rs->sr_ref = gs.refs; - rs->sr_ctrls = gs.ctrls; - - send_ldap_result( op, rs ); } + rs->sr_ctrls = gs.ctrls; + + send_ldap_result( op, rs ); op->o_bd = b0; op->o_bd->bd_info = bi0; @@ -587,7 +594,7 @@ glue_tool_entry_close ( { int rc = 0; - if (glueBack) { + if (glueBack && glueBack != GLUEBACK_DONE) { if (!glueBack->be_entry_close) return 0; rc = glueBack->be_entry_close (glueBack); @@ -736,6 +743,7 @@ glue_tool_entry_first ( slap_overinst *on = glue_tool_inst( b0->bd_info ); glueinfo *gi = on->on_bi.bi_private; int i; + ID rc; /* If we're starting from scratch, start at the most general */ if (!glueBack) { @@ -755,7 +763,26 @@ glue_tool_entry_first ( glueBack->be_entry_open (glueBack, glueMode) != 0) return NOID; - return glueBack->be_entry_first (glueBack); + rc = glueBack->be_entry_first (glueBack); + while ( rc == NOID ) { + if ( glueBack && glueBack->be_entry_close ) + glueBack->be_entry_close (glueBack); + for (i=0; igi_nodes; i++) { + if (gi->gi_n[i].gn_be == glueBack) + break; + } + if (i == 0) { + glueBack = GLUEBACK_DONE; + break; + } else { + glueBack = gi->gi_n[i-1].gn_be; + rc = glue_tool_entry_first (b0); + if ( glueBack == GLUEBACK_DONE ) { + break; + } + } + } + return rc; } static ID @@ -782,16 +809,62 @@ glue_tool_entry_next ( break; } if (i == 0) { - glueBack = NULL; + glueBack = GLUEBACK_DONE; break; } else { glueBack = gi->gi_n[i-1].gn_be; rc = glue_tool_entry_first (b0); + if ( glueBack == GLUEBACK_DONE ) { + break; + } } } return rc; } +static ID +glue_tool_dn2id_get ( + BackendDB *b0, + struct berval *dn +) +{ + BackendDB *be, b2; + int rc = -1; + + b2 = *b0; + b2.bd_info = (BackendInfo *)glue_tool_inst( b0->bd_info ); + be = glue_back_select (&b2, dn); + if ( be == &b2 ) be = &toolDB; + + if (!be->be_dn2id_get) + return NOID; + + if (!glueBack) { + if ( be->be_entry_open ) { + rc = be->be_entry_open (be, glueMode); + } + if (rc != 0) { + return NOID; + } + } else if (be != glueBack) { + /* If this entry belongs in a different branch than the + * previous one, close the current database and open the + * new one. + */ + if ( glueBack->be_entry_close ) { + glueBack->be_entry_close (glueBack); + } + if ( be->be_entry_open ) { + rc = be->be_entry_open (be, glueMode); + } + if (rc != 0) { + return NOID; + } + } + glueBack = be; + return be->be_dn2id_get (be, dn); +} + static Entry * glue_tool_entry_get ( BackendDB *b0, @@ -848,6 +921,19 @@ glue_tool_entry_put ( return be->be_entry_put (be, e, text); } +static ID +glue_tool_entry_modify ( + BackendDB *b0, + Entry *e, + struct berval *text +) +{ + if (!glueBack || !glueBack->be_entry_modify) + return NOID; + + return glueBack->be_entry_modify (glueBack, e, text); +} + static int glue_tool_entry_reindex ( BackendDB *b0, @@ -882,6 +968,15 @@ glue_tool_sync ( return 0; } +typedef struct glue_Addrec { + struct glue_Addrec *ga_next; + BackendDB *ga_be; +} glue_Addrec; + +/* List of added subordinates */ +static glue_Addrec *ga_list; +static int ga_adding; + static int glue_db_init( BackendDB *be, @@ -921,19 +1016,24 @@ glue_db_init( oi->oi_bi.bi_tool_entry_next = glue_tool_entry_next; if ( bi->bi_tool_entry_get ) oi->oi_bi.bi_tool_entry_get = glue_tool_entry_get; + if ( bi->bi_tool_dn2id_get ) + oi->oi_bi.bi_tool_dn2id_get = glue_tool_dn2id_get; if ( bi->bi_tool_entry_put ) oi->oi_bi.bi_tool_entry_put = glue_tool_entry_put; if ( bi->bi_tool_entry_reindex ) oi->oi_bi.bi_tool_entry_reindex = glue_tool_entry_reindex; + if ( bi->bi_tool_entry_modify ) + oi->oi_bi.bi_tool_entry_modify = glue_tool_entry_modify; if ( bi->bi_tool_sync ) oi->oi_bi.bi_tool_sync = glue_tool_sync; - /*FIXME : need to add support */ - oi->oi_bi.bi_tool_dn2id_get = 0; - oi->oi_bi.bi_tool_entry_modify = 0; - SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE; + if ( ga_list ) { + be->bd_info = (BackendInfo *)oi; + glue_sub_attach( 1 ); + } + return 0; } @@ -1008,21 +1108,19 @@ glue_sub_del( BackendDB *b0 ) return rc; } -typedef struct glue_Addrec { - struct glue_Addrec *ga_next; - BackendDB *ga_be; -} glue_Addrec; - -/* List of added subordinates */ -static glue_Addrec *ga_list; /* Attach all the subordinate backends to their superior */ int -glue_sub_attach() +glue_sub_attach( int online ) { glue_Addrec *ga, *gnext = NULL; int rc = 0; + if ( ga_adding ) + return 0; + + ga_adding = 1; + /* For all the subordinate backends */ for ( ga=ga_list; ga != NULL; ga = gnext ) { BackendDB *be; @@ -1043,7 +1141,7 @@ glue_sub_attach() /* If it's not already configured, set up the overlay */ if ( !SLAP_GLUE_INSTANCE( be )) { - rc = overlay_config( be, glue.on_bi.bi_type, -1, NULL ); + rc = overlay_config( be, glue.on_bi.bi_type, -1, NULL, NULL); if ( rc ) break; } @@ -1062,11 +1160,20 @@ glue_sub_attach() &gi->gi_n[gi->gi_nodes].gn_pdn ); gi->gi_nodes++; on->on_bi.bi_private = gi; + ga->ga_be->be_flags |= SLAP_DBFLAG_GLUE_LINKED; break; } if ( !be ) { Debug( LDAP_DEBUG_ANY, "glue: no superior found for sub %s!\n", ga->ga_be->be_suffix[0].bv_val, 0, 0 ); + /* allow this for now, assume a superior will + * be added later + */ + if ( online ) { + rc = 0; + gnext = ga_list; + break; + } rc = LDAP_NO_SUCH_OBJECT; } ch_free( ga ); @@ -1075,6 +1182,8 @@ glue_sub_attach() ga_list = gnext; + ga_adding = 0; + return rc; } @@ -1100,7 +1209,7 @@ glue_sub_add( BackendDB *be, int advert, int online ) ga_list = ga; if ( online ) - rc = glue_sub_attach(); + rc = glue_sub_attach( online ); return rc; }