Fix out-of-order slapadd

This commit is contained in:
Howard Chu 2011-09-09 22:00:34 -07:00
parent c5beffc94f
commit 802a2ad4b2
2 changed files with 37 additions and 14 deletions

View File

@ -33,7 +33,7 @@ static int mdb_id2entry_put(
{ {
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
MDB_dbi dbi = mdb->mi_id2entry; MDB_dbi dbi = mdb->mi_id2entry;
MDB_val key, data; MDB_val key, data, d2;
int rc; int rc;
/* We only store rdns, and they go in the dn2id database. */ /* We only store rdns, and they go in the dn2id database. */
@ -41,20 +41,27 @@ static int mdb_id2entry_put(
key.mv_data = &e->e_id; key.mv_data = &e->e_id;
key.mv_size = sizeof(ID); key.mv_size = sizeof(ID);
rc = mdb_entry_encode( op, tid, e, &data ); rc = mdb_entry_encode( op, tid, e, &d2 );
if( rc != LDAP_SUCCESS ) { if( rc != LDAP_SUCCESS ) {
return LDAP_OTHER; return LDAP_OTHER;
} }
again:
data = d2;
rc = mdb_put( tid, dbi, &key, &data, flag ); rc = mdb_put( tid, dbi, &key, &data, flag );
op->o_tmpfree( data.mv_data, op->o_tmpmemctx );
if (rc) { if (rc) {
/* Was there a hole from slapadd? */
if ( flag == MDB_NOOVERWRITE && data.mv_size == 0 ) {
flag = 0;
goto again;
}
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"mdb_id2entry_put: mdb_put failed: %s(%d) \"%s\"\n", "mdb_id2entry_put: mdb_put failed: %s(%d) \"%s\"\n",
mdb_strerror(rc), rc, mdb_strerror(rc), rc,
e->e_nname.bv_val ); e->e_nname.bv_val );
rc = LDAP_OTHER; rc = LDAP_OTHER;
} }
op->o_tmpfree( d2.mv_data, op->o_tmpmemctx );
return rc; return rc;
} }

View File

@ -154,7 +154,7 @@ int mdb_tool_entry_close(
nholes = 0; nholes = 0;
return -1; return -1;
} }
return 0; return 0;
} }
@ -168,7 +168,7 @@ mdb_tool_entry_first_x(
tool_base = base; tool_base = base;
tool_scope = scope; tool_scope = scope;
tool_filter = f; tool_filter = f;
return mdb_tool_entry_next( be ); return mdb_tool_entry_next( be );
} }
@ -269,7 +269,7 @@ ID mdb_tool_dn2id_get(
rc = mdb_dn2id( &op, txn, dn, &id, NULL, NULL ); rc = mdb_dn2id( &op, txn, dn, &id, NULL, NULL );
if ( rc == MDB_NOTFOUND ) if ( rc == MDB_NOTFOUND )
return NOID; return NOID;
return id; return id;
} }
@ -356,6 +356,7 @@ static int mdb_tool_next_id(
struct berval *text, struct berval *text,
int hole ) int hole )
{ {
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
struct berval dn = e->e_name; struct berval dn = e->e_name;
struct berval ndn = e->e_nname; struct berval ndn = e->e_nname;
struct berval pdn, npdn, nmatched; struct berval pdn, npdn, nmatched;
@ -404,12 +405,13 @@ static int mdb_tool_next_id(
} }
rc = mdb_dn2id_add( op, tid, pid, e ); rc = mdb_dn2id_add( op, tid, pid, e );
if ( rc ) { if ( rc ) {
snprintf( text->bv_val, text->bv_len, snprintf( text->bv_val, text->bv_len,
"dn2id_add failed: %s (%d)", "dn2id_add failed: %s (%d)",
mdb_strerror(rc), rc ); mdb_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"=> mdb_tool_next_id: %s\n", text->bv_val, 0, 0 ); "=> mdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
} else if ( hole ) { } else if ( hole ) {
MDB_val key, data;
if ( nholes == nhmax - 1 ) { if ( nholes == nhmax - 1 ) {
if ( holes == hbuf ) { if ( holes == hbuf ) {
holes = ch_malloc( nhmax * sizeof(dn_id) * 2 ); holes = ch_malloc( nhmax * sizeof(dn_id) * 2 );
@ -421,6 +423,20 @@ static int mdb_tool_next_id(
} }
ber_dupbv( &holes[nholes].dn, &ndn ); ber_dupbv( &holes[nholes].dn, &ndn );
holes[nholes++].id = e->e_id; holes[nholes++].id = e->e_id;
key.mv_size = sizeof(ID);
key.mv_data = &e->e_id;
data.mv_size = 0;
data.mv_data = NULL;
rc = mdb_put( tid, mdb->mi_id2entry, &key, &data, MDB_NOOVERWRITE );
if ( rc == MDB_KEYEXIST )
rc = 0;
if ( rc ) {
snprintf( text->bv_val, text->bv_len,
"dummy id2entry add failed: %s (%d)",
mdb_strerror(rc), rc );
Debug( LDAP_DEBUG_ANY,
"=> mdb_tool_next_id: %s\n", text->bv_val, 0, 0 );
}
} }
} else if ( !hole ) { } else if ( !hole ) {
unsigned i, j; unsigned i, j;
@ -458,12 +474,12 @@ mdb_tool_index_add(
IndexRec *ir; IndexRec *ir;
int i, rc; int i, rc;
Attribute *a; Attribute *a;
ir = mdb_tool_index_rec; ir = mdb_tool_index_rec;
memset(ir, 0, mdb->bi_nattrs * sizeof( IndexRec )); memset(ir, 0, mdb->bi_nattrs * sizeof( IndexRec ));
for ( a = e->e_attrs; a != NULL; a = a->a_next ) { for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
rc = mdb_index_recset( mdb, a, a->a_desc->ad_type, rc = mdb_index_recset( mdb, a, a->a_desc->ad_type,
&a->a_desc->ad_tags, ir ); &a->a_desc->ad_tags, ir );
if ( rc ) if ( rc )
return rc; return rc;
@ -473,7 +489,7 @@ mdb_tool_index_add(
ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex );
/* Wait for all threads to be ready */ /* Wait for all threads to be ready */
while ( mdb_tool_index_tcount ) { while ( mdb_tool_index_tcount ) {
ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main,
&mdb_tool_index_mutex ); &mdb_tool_index_mutex );
} }
for ( i=1; i<slap_tool_thread_max; i++ ) for ( i=1; i<slap_tool_thread_max; i++ )
@ -487,7 +503,7 @@ mdb_tool_index_add(
ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex ); ldap_pvt_thread_mutex_lock( &mdb_tool_index_mutex );
for ( i=1; i<slap_tool_thread_max; i++ ) { for ( i=1; i<slap_tool_thread_max; i++ ) {
if ( mdb_tool_index_threads[i] == LDAP_BUSY ) { if ( mdb_tool_index_threads[i] == LDAP_BUSY ) {
ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main, ldap_pvt_thread_cond_wait( &mdb_tool_index_cond_main,
&mdb_tool_index_mutex ); &mdb_tool_index_mutex );
i--; i--;
continue; continue;
@ -693,7 +709,7 @@ int mdb_tool_entry_reindex(
goto done; goto done;
} }
} }
/* /*
* just (re)add them for now * just (re)add them for now
* assume that some other routine (not yet implemented) * assume that some other routine (not yet implemented)