/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2001-2009 The OpenLDAP Foundation.
+ * Copyright 2001-2010 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static int glueMode;
static BackendDB *glueBack;
+static BackendDB glueBackDone;
+#define GLUEBACK_DONE (&glueBackDone)
static slap_response glue_op_response;
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;
{
int rc = 0;
- if (glueBack) {
+ if (glueBack && glueBack != GLUEBACK_DONE) {
if (!glueBack->be_entry_close)
return 0;
rc = glueBack->be_entry_close (glueBack);
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) {
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; i<gi->gi_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
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;
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,
SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_GLUE_INSTANCE;
+ if ( ga_list ) {
+ be->bd_info = (BackendInfo *)oi;
+ glue_sub_attach( 1 );
+ }
+
return 0;
}
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;
&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 );
ga_list = gnext;
+ ga_adding = 0;
+
return rc;
}
ga_list = ga;
if ( online )
- rc = glue_sub_attach();
+ rc = glue_sub_attach( online );
return rc;
}