]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/nextid.c
dbbbfb26332883c6c1c99c19e6810c04a423368c
[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                         return rc;
38                 }
39                 rc = txn_abort( ltid );
40                 if( rc != 0 ) {
41                         return rc;
42                 }
43         }
44
45         rc = txn_begin( bdb->bi_dbenv, tid, &ltid, 0 );
46         if( rc != 0 ) {
47                 return rc;
48         }
49
50         /* get existing value for read/modify/write */
51         rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
52                 ltid, &key, &data, DB_RMW );
53
54         switch(rc) {
55         case DB_LOCK_DEADLOCK:
56         case DB_LOCK_NOTGRANTED:
57                 goto retry;
58
59         case DB_NOTFOUND:
60                 id = NOID;
61                 break;
62
63         case 0:
64                 if ( data.size != sizeof(ID) ) {
65                         /* size mismatch! */
66                         rc = -1;
67                         goto done;
68                 }
69                 break;
70
71         default:
72                 goto done;
73         }
74
75         id++;
76
77         /* put new value */
78         rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
79                 ltid, &key, &data, 0 );
80
81         switch(rc) {
82         case DB_LOCK_DEADLOCK:
83         case DB_LOCK_NOTGRANTED:
84                 goto retry;
85
86         case 0:
87                 *out = id;
88                 rc = txn_commit( ltid, 0 );
89                 break;
90
91         default:
92 done:   (void) txn_abort( ltid );
93         }
94
95         return rc;
96 }