]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/nextid.c
ae61be9e5a5440be37d5801f133e1b87d4b2c5ad
[openldap] / servers / slapd / back-bdb / nextid.c
1 /* init.c - initialize bdb backend */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12
13 #include "back-bdb.h"
14
15 int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out )
16 {
17         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
18         int rc;
19         ID kid = NOID;
20         ID id;
21         DBT key, data;
22         DB_TXN  *ltid;
23
24         DBTzero( &key );
25         key.data = (char *) &kid;
26         key.size = sizeof( kid );
27
28         DBTzero( &data );
29         data.data = (char *) &id;
30         data.ulen = sizeof( id );
31         data.flags = DB_DBT_USERMEM;
32
33         if( 0 ) {
34 retry:  if( tid != NULL ) {
35                         /* nested transaction, abort and return */
36                         (void) txn_abort( ltid );
37                         Debug( LDAP_DEBUG_ANY,
38                                 "=> bdb_next_id: aborted!\n",
39                                 0, 0, 0 );
40                         return rc;
41                 }
42                 rc = txn_abort( ltid );
43                 if( rc != 0 ) {
44                         Debug( LDAP_DEBUG_ANY,
45                                 "=> bdb_next_id: txn_abort failed: %s (%d)\n",
46                                 db_strerror(rc), rc, 0 );
47                         return rc;
48                 }
49         }
50
51         rc = txn_begin( bdb->bi_dbenv, tid, &ltid, 0 );
52         if( rc != 0 ) {
53                 Debug( LDAP_DEBUG_ANY,
54                         "=> bdb_next_id: txn_begin failed: %s (%d)\n",
55                         db_strerror(rc), rc, 0 );
56                 return rc;
57         }
58
59         /* get existing value for read/modify/write */
60         rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
61                 ltid, &key, &data, DB_RMW );
62
63         switch(rc) {
64         case DB_LOCK_DEADLOCK:
65         case DB_LOCK_NOTGRANTED:
66                 goto retry;
67
68         case DB_NOTFOUND:
69                 id = 0;
70                 break;
71
72         case 0:
73                 if ( data.size != sizeof(ID) ) {
74                         Debug( LDAP_DEBUG_ANY,
75                                 "=> bdb_next_id: get size mismatch: expected %ld, got %ld\n",
76                                 (long) sizeof( ID ), (long) data.size, 0 );
77                         rc = -1;
78                         goto done;
79                 }
80                 break;
81
82         default:
83                 Debug( LDAP_DEBUG_ANY,
84                         "=> bdb_next_id: get failed: %s (%d)\n",
85                         db_strerror(rc), rc, 0 );
86                 goto done;
87         }
88
89         id++;
90
91         /* put new value */
92         rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
93                 ltid, &key, &data, 0 );
94
95         switch(rc) {
96         case DB_LOCK_DEADLOCK:
97         case DB_LOCK_NOTGRANTED:
98                 goto retry;
99
100         case 0:
101                 *out = id;
102                 rc = txn_commit( ltid, 0 );
103
104                 if( rc != 0 ) {
105                         Debug( LDAP_DEBUG_ANY,
106                                 "=> bdb_next_id: commit failed: %s (%d)\n",
107                                 db_strerror(rc), rc, 0 );
108                 }
109                 break;
110
111         default:
112                 Debug( LDAP_DEBUG_ANY,
113                         "=> bdb_next_id: put failed: %s (%d)\n",
114                         db_strerror(rc), rc, 0 );
115 done:   (void) txn_abort( ltid );
116         }
117
118         return rc;
119 }