]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/operational.c
Add start of discussion of strings in LDAP/X.500 and OpenLDAP.
[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 the supported operational attributes (if required)
20  */
21
22 int
23 bdb_operational(
24         BackendDB       *be,
25         Connection      *conn, 
26         Operation       *op,
27         Entry           *e,
28         AttributeName           *attrs,
29         int             opattrs,
30         Attribute       **a )
31 {
32         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
33         Attribute       **aa = a;
34         int             rc;
35         DB_TXN          *ltid = NULL;
36     struct bdb_op_info opinfo;
37         
38         assert( e );
39
40         if ( !opattrs && !ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
41                 return 0;
42         }
43
44
45         if( 0 ) {
46 retry:  /* transaction retry */
47 #if 0
48                 if( e != NULL ) {
49                         bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
50                 }
51 #endif
52 #ifdef NEW_LOGGING
53                 LDAP_LOG ( OPERATION, DETAIL1, 
54                         "=> bdb_operational: retrying...\n", 0, 0, 0 );
55 #else
56                 Debug( LDAP_DEBUG_TRACE, "==> bdb_operational: retrying...\n", 
57                                 0, 0, 0 );
58 #endif
59                 rc = TXN_ABORT( ltid );
60                 ltid = NULL;
61                 op->o_private = NULL;
62                 if( rc != 0 ) {
63                         rc = LDAP_OTHER;
64                         goto return_results;
65                 }
66                 ldap_pvt_thread_yield();
67         }
68
69         /* begin transaction */
70         rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &ltid, bdb->bi_db_opflags );
71         if ( rc != 0 ) {
72 #ifdef NEW_LOGGING
73                 LDAP_LOG ( OPERATION, ERR, 
74                         "=> bdb_operational: txn_begin failed: %s (%d)\n",
75                         db_strerror(rc), rc, 0 );
76 #else
77                 Debug( LDAP_DEBUG_TRACE,
78                         "bdb_operational: txn_begin failed: %s (%d)\n",
79                         db_strerror( rc ), rc, 0 );
80 #endif
81                 rc = LDAP_OTHER;
82                 return rc;
83         }
84
85         opinfo.boi_bdb = be;
86         opinfo.boi_txn = ltid;
87         opinfo.boi_err = 0;
88         op->o_private = &opinfo;
89
90         rc = bdb_dn2id_children( be, ltid, &e->e_nname, 0 );
91         
92         switch( rc ) {
93         case DB_LOCK_DEADLOCK:
94         case DB_LOCK_NOTGRANTED:
95                 goto retry;
96
97         case 0:
98         case DB_NOTFOUND:
99                 *aa = slap_operational_hasSubordinate( rc == 0 );
100                 if ( *aa != NULL ) {
101                         aa = &(*aa)->a_next;
102                 }
103                 break;
104
105         default:
106 #ifdef NEW_LOGGING
107                 LDAP_LOG ( OPERATION, ERR, 
108                         "=> bdb_operational: has_children failed: %s (%d)\n",
109                         db_strerror(rc), rc, 0 );
110 #else
111                 Debug(LDAP_DEBUG_ARGS, 
112                         "<=- bdb_operational: has_children failed: %s (%d)\n", 
113                         db_strerror(rc), rc, 0 );
114 #endif
115                 rc = LDAP_OTHER;
116         }
117
118 return_results:
119         if ( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
120                 ldap_pvt_thread_yield();
121                 TXN_CHECKPOINT( bdb->bi_dbenv,
122                         bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
123         }
124
125         if ( ltid != NULL ) {
126                 TXN_ABORT( ltid );
127                 op->o_private = NULL;
128         }
129
130         return rc;
131 }
132