]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/operational.c
Converted ch_malloc, ch_calloc and ch_realloc calls to SLAP_MALLOC,
[openldap] / servers / slapd / back-bdb / operational.c
1 /* operational.c - bdb backend operational attributes function */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/string.h>
12 #include <ac/socket.h>
13
14 #include "slap.h"
15 #include "back-bdb.h"
16 #include "proto-bdb.h"
17
18 /*
19  * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE
20  * if the entry has children or not.
21  */
22 int
23 bdb_hasSubordinates(
24         BackendDB       *be,
25         Connection      *conn, 
26         Operation       *op,
27         Entry           *e,
28         int             *hasSubordinates )
29 {
30         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
31         int             rc;
32         DB_TXN          *ltid = NULL;
33         struct bdb_op_info opinfo;
34         
35         assert( e );
36         assert( hasSubordinates );
37
38         if( 0 ) {
39 retry:  /* transaction retry */
40 #if 0
41                 if( e != NULL ) {
42                         bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
43                 }
44 #endif
45 #ifdef NEW_LOGGING
46                 LDAP_LOG ( OPERATION, DETAIL1, 
47                         "=> bdb_hasSubordinates: retrying...\n", 0, 0, 0 );
48 #else
49                 Debug( LDAP_DEBUG_TRACE, "==> bdb_hasSubordinates: retrying...\n", 
50                                 0, 0, 0 );
51 #endif
52                 rc = TXN_ABORT( ltid );
53                 ltid = NULL;
54                 op->o_private = NULL;
55                 if( rc != 0 ) {
56                         rc = LDAP_OTHER;
57                         goto return_results;
58                 }
59                 ldap_pvt_thread_yield();
60         }
61
62         /* begin transaction */
63         rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, bdb->bi_db_opflags );
64         if ( rc != 0 ) {
65 #ifdef NEW_LOGGING
66                 LDAP_LOG ( OPERATION, ERR, 
67                         "=> bdb_hasSubordinates: txn_begin failed: %s (%d)\n",
68                         db_strerror(rc), rc, 0 );
69 #else
70                 Debug( LDAP_DEBUG_TRACE,
71                         "bdb_hasSubordinates: txn_begin failed: %s (%d)\n",
72                         db_strerror( rc ), rc, 0 );
73 #endif
74                 rc = LDAP_OTHER;
75                 return rc;
76         }
77
78         opinfo.boi_bdb = be;
79         opinfo.boi_txn = ltid;
80         opinfo.boi_err = 0;
81         op->o_private = &opinfo;
82
83         rc = bdb_dn2id_children( be, ltid, &e->e_nname, 0 );
84         
85         switch( rc ) {
86         case DB_LOCK_DEADLOCK:
87         case DB_LOCK_NOTGRANTED:
88                 goto retry;
89
90         case 0:
91                 *hasSubordinates = LDAP_COMPARE_TRUE;
92                 break;
93
94         case DB_NOTFOUND:
95                 *hasSubordinates = LDAP_COMPARE_FALSE;
96                 rc = LDAP_SUCCESS;
97                 break;
98
99         default:
100 #ifdef NEW_LOGGING
101                 LDAP_LOG ( OPERATION, ERR, 
102                         "=> bdb_hasSubordinates: has_children failed: %s (%d)\n",
103                         db_strerror(rc), rc, 0 );
104 #else
105                 Debug(LDAP_DEBUG_ARGS, 
106                         "<=- bdb_hasSubordinates: has_children failed: %s (%d)\n", 
107                         db_strerror(rc), rc, 0 );
108 #endif
109                 rc = LDAP_OTHER;
110         }
111
112 return_results:
113         if ( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
114                 ldap_pvt_thread_yield();
115                 TXN_CHECKPOINT( bdb->bi_dbenv,
116                         bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
117         }
118
119         if ( ltid != NULL ) {
120                 TXN_ABORT( ltid );
121                 op->o_private = NULL;
122         }
123
124         return rc;
125 }
126
127 /*
128  * sets the supported operational attributes (if required)
129  */
130 int
131 bdb_operational(
132         BackendDB       *be,
133         Connection      *conn, 
134         Operation       *op,
135         Entry           *e,
136         AttributeName           *attrs,
137         int             opattrs,
138         Attribute       **a )
139 {
140         Attribute       **aa = a;
141         int             rc = 0;
142         
143         assert( e );
144
145         if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
146                 int     hasSubordinates;
147
148                 rc = bdb_hasSubordinates( be, conn, op, e, &hasSubordinates );
149                 if ( rc == LDAP_SUCCESS ) {
150                         *aa = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
151                         if ( *aa != NULL ) {
152                                 aa = &(*aa)->a_next;
153                         }
154                 }
155         }
156
157         return rc;
158 }
159