]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/operational.c
ca87a6c7277d8df465513073ab2c3b0d67aa1a41
[openldap] / servers / slapd / back-bdb / operational.c
1 /* operational.c - bdb backend operational attributes function */
2 /*
3  * Copyright 1998-2003 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_locker = TXN_ID ( ltid );
81         opinfo.boi_err = 0;
82         op->o_private = &opinfo;
83
84         rc = bdb_dn2id_children( be, ltid, &e->e_nname, 0 );
85         
86         switch( rc ) {
87         case DB_LOCK_DEADLOCK:
88         case DB_LOCK_NOTGRANTED:
89                 goto retry;
90
91         case 0:
92                 *hasSubordinates = LDAP_COMPARE_TRUE;
93                 break;
94
95         case DB_NOTFOUND:
96                 *hasSubordinates = LDAP_COMPARE_FALSE;
97                 rc = LDAP_SUCCESS;
98                 break;
99
100         default:
101 #ifdef NEW_LOGGING
102                 LDAP_LOG ( OPERATION, ERR, 
103                         "=> bdb_hasSubordinates: has_children failed: %s (%d)\n",
104                         db_strerror(rc), rc, 0 );
105 #else
106                 Debug(LDAP_DEBUG_ARGS, 
107                         "<=- bdb_hasSubordinates: has_children failed: %s (%d)\n", 
108                         db_strerror(rc), rc, 0 );
109 #endif
110                 rc = LDAP_OTHER;
111         }
112
113 return_results:
114         if ( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
115                 ldap_pvt_thread_yield();
116                 TXN_CHECKPOINT( bdb->bi_dbenv,
117                         bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
118         }
119
120         if ( ltid != NULL ) {
121                 TXN_ABORT( ltid );
122                 op->o_private = NULL;
123         }
124
125         return rc;
126 }
127
128 /*
129  * sets the supported operational attributes (if required)
130  */
131 int
132 bdb_operational(
133         BackendDB       *be,
134         Connection      *conn, 
135         Operation       *op,
136         Entry           *e,
137         AttributeName           *attrs,
138         int             opattrs,
139         Attribute       **a )
140 {
141         Attribute       **aa = a;
142         int             rc = 0;
143         
144         assert( e );
145
146         if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
147                 int     hasSubordinates;
148
149                 rc = bdb_hasSubordinates( be, conn, op, e, &hasSubordinates );
150                 if ( rc == LDAP_SUCCESS ) {
151                         *aa = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
152                         if ( *aa != NULL ) {
153                                 aa = &(*aa)->a_next;
154                         }
155                 }
156         }
157
158         return rc;
159 }
160