openldap/servers/slapd/back-bdb/nextid.c

181 lines
3.4 KiB
C
Raw Normal View History

2000-09-20 04:13:41 +08:00
/* init.c - initialize bdb backend */
/* $OpenLDAP$ */
/*
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "back-bdb.h"
int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int rc;
ID kid = NOID;
ID id;
DBT key, data;
DB_TXN *ltid = NULL;
2000-09-22 09:40:57 +08:00
2000-09-20 04:13:41 +08:00
DBTzero( &key );
key.data = (char *) &kid;
key.size = sizeof( kid );
DBTzero( &data );
data.data = (char *) &id;
data.ulen = sizeof( id );
data.flags = DB_DBT_USERMEM;
if( 0 ) {
retry: if( tid != NULL ) {
/* nested transaction, abort and return */
(void) txn_abort( ltid );
2000-09-26 08:43:00 +08:00
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: aborted!\n",
0, 0, 0 );
return rc;
}
rc = txn_abort( ltid );
if( rc != 0 ) {
2000-09-26 08:43:00 +08:00
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: txn_abort failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
return rc;
}
}
2001-11-27 11:41:03 +08:00
if( bdb->bi_txn ) {
rc = txn_begin( bdb->bi_dbenv, tid, &ltid, 0 );
if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: txn_begin failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
return rc;
}
}
/* get existing value for read/modify/write */
2000-09-22 14:46:32 +08:00
rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
2000-09-22 09:40:57 +08:00
ltid, &key, &data, DB_RMW );
2000-09-20 04:13:41 +08:00
switch(rc) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
case DB_NOTFOUND:
2000-09-26 02:59:15 +08:00
id = 0;
break;
2000-09-20 04:13:41 +08:00
case 0:
2000-09-26 08:56:33 +08:00
if ( data.size != sizeof( id ) ) {
2000-09-26 08:43:00 +08:00
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: get size mismatch: expected %ld, got %ld\n",
2000-09-26 08:56:33 +08:00
(long) sizeof( id ), (long) data.size, 0 );
rc = -1;
goto done;
}
break;
2000-09-20 04:13:41 +08:00
default:
2000-09-26 08:43:00 +08:00
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: get failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
2000-09-22 09:40:57 +08:00
goto done;
2000-09-20 04:13:41 +08:00
}
2001-07-31 15:53:21 +08:00
if( bdb->bi_lastid > id ) id = bdb->bi_lastid;
2001-07-31 12:55:14 +08:00
2000-09-20 04:13:41 +08:00
id++;
2000-09-26 08:56:33 +08:00
data.size = sizeof( id );
2000-09-20 04:13:41 +08:00
/* put new value */
2000-09-22 14:46:32 +08:00
rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
2000-09-22 09:40:57 +08:00
ltid, &key, &data, 0 );
2000-09-20 04:13:41 +08:00
switch(rc) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
2000-09-22 09:40:57 +08:00
case 0:
*out = id;
2001-06-15 15:08:37 +08:00
bdb->bi_lastid = id;
2001-11-27 11:41:03 +08:00
if (bdb->bi_txn) {
rc = txn_commit( ltid, 0 );
ltid = NULL;
}
2000-09-26 08:43:00 +08:00
if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: commit failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
}
break;
default:
2000-09-26 08:43:00 +08:00
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: put failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
done: (void) txn_abort( ltid );
2000-09-22 09:40:57 +08:00
}
2000-09-20 04:13:41 +08:00
return rc;
}
2001-07-31 12:24:29 +08:00
int bdb_last_id( BackendDB *be, DB_TXN *tid )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int rc;
ID kid = NOID;
ID id;
DBT key, data;
DBTzero( &key );
key.data = (char *) &kid;
key.size = sizeof( kid );
DBTzero( &data );
data.data = (char *) &id;
data.ulen = sizeof( id );
data.flags = DB_DBT_USERMEM;
/* get existing value for read/modify/write */
rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
tid, &key, &data, 0 );
switch(rc) {
case DB_NOTFOUND:
id = 0;
rc = 0;
break;
case 0:
if ( data.size != sizeof( id ) ) {
Debug( LDAP_DEBUG_ANY,
"=> bdb_last_id: get size mismatch: expected %ld, got %ld\n",
(long) sizeof( id ), (long) data.size, 0 );
rc = -1;
goto done;
}
break;
default:
Debug( LDAP_DEBUG_ANY,
"=> bdb_next_id: get failed: %s (%d)\n",
db_strerror(rc), rc, 0 );
goto done;
}
bdb->bi_lastid = id;
done:
return rc;
}